KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > sco > SCOArrayList


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.sco;
13
14 import com.versant.core.jdo.VersantPersistenceManagerImp;
15 import com.versant.core.jdo.VersantStateManager;
16 import com.versant.core.common.CollectionDiff;
17 import com.versant.core.common.VersantFieldMetaData;
18
19 import javax.jdo.spi.PersistenceCapable;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import com.versant.core.common.BindingSupportImpl;
25 import com.versant.core.common.PersistenceContext;
26 import com.versant.core.jdo.VersantPersistenceManagerImp;
27 import com.versant.core.jdo.VersantStateManager;
28
29 /**
30  * SCO for ArrayList.
31  */

32 public final class SCOArrayList extends ArrayList JavaDoc implements VersantManagedSCOCollection, VersantAdvancedSCO {
33
34     private transient PersistenceCapable owner;
35     private final transient int managed;
36     private final transient int inverseFieldNo;
37     private final transient VersantFieldMetaData fmd;
38     private transient VersantStateManager stateManager;
39     private transient Object JavaDoc[] originalData;
40     private transient boolean beenReset;
41
42     public SCOArrayList(PersistenceCapable owner, VersantStateManager stateManager,
43                         VersantFieldMetaData fmd, Object JavaDoc[] originalData) {
44         this.owner = owner;
45         if (fmd.isManaged()) {
46             if (fmd.isMaster()) {
47                 managed = MANAGED_ONE_TO_MANY;
48             } else if (fmd.isManyToMany()) {
49                 managed = MANAGED_MANY_TO_MANY;
50             } else {
51                 managed = MANAGED_NONE;
52             }
53         } else {
54             managed = MANAGED_NONE;
55         }
56         this.inverseFieldNo = fmd.getInverseFieldNo();
57         this.stateManager = stateManager;
58         this.fmd = fmd;
59         this.originalData = originalData;
60         int n = originalData == null ? 0 : originalData.length;
61         if (n > 0) ensureCapacity(n);
62         if (!owner.jdoIsNew()) {
63             for (int i = 0; i < n; i++) {
64                 Object JavaDoc o = originalData[i];
65 // if (o == null) break;
66

67                 super.add( o);
68             }
69         } else {
70             switch (managed) {
71                 case MANAGED_ONE_TO_MANY:
72                     for (int i = 0; i < n; i++) {
73                         Object JavaDoc o = originalData[i];
74 // if (o == null) throw createNPE();
75
super.add( o);
76                         SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
77                     }
78                     break;
79                 case MANAGED_MANY_TO_MANY:
80                     for (int i = 0; i < n; i++) {
81                         Object JavaDoc o = originalData[i];
82 // if (o == null) throw createNPE();
83
super.add( o);
84                         SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
85                     }
86                     break;
87                 default:
88                     for (int i = 0; i < n; i++) {
89                         Object JavaDoc o = originalData[i];
90 // if (o == null) throw createNPE();
91
super.add( o);
92                     }
93             }
94             ;
95         }
96     }
97
98     private RuntimeException JavaDoc createNPE() {
99         return BindingSupportImpl.getInstance().nullElement("Null element not allowed: " + fmd.getQName());
100     }
101
102     public Object JavaDoc set(int index, Object JavaDoc element) {
103 // if (element == null) throw createNPE();
104
Object JavaDoc result;
105         switch (managed) {
106             case MANAGED_ONE_TO_MANY:
107                 result = super.set(index, element);
108                 makeDirty();
109                 if (result != null) {
110                     SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
111                 }
112                 SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo);
113                 return result;
114             case MANAGED_MANY_TO_MANY:
115                 result = super.set(index, element);
116                 makeDirty();
117                 if (result != null) {
118                     SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
119                 }
120                 SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner);
121                 return result;
122         }
123         result = super.set(index, element);
124         makeDirty();
125         return result;
126     }
127
128     public boolean add(Object JavaDoc o) {
129 // if (o == null) throw createNPE();
130
switch (managed) {
131             case MANAGED_ONE_TO_MANY:
132                 super.add(o);
133                 makeDirty();
134                 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
135                 return true;
136             case MANAGED_MANY_TO_MANY:
137                 super.add(o);
138                 makeDirty();
139                 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
140                 return true;
141         }
142         super.add(o);
143         makeDirty();
144         return true;
145     }
146
147     public void add(int index, Object JavaDoc element) {
148 // if (element == null) throw createNPE();
149
switch (managed) {
150             case MANAGED_ONE_TO_MANY:
151                 super.add(index, element);
152                 makeDirty();
153                 SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo);
154                 return;
155             case MANAGED_MANY_TO_MANY:
156                 super.add(index, element);
157                 makeDirty();
158                 SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner);
159                 return;
160         }
161         super.add(index, element);
162         makeDirty();
163     }
164
165     public Object JavaDoc remove(int index) {
166         Object JavaDoc result = super.remove(index);
167         if (result == null) return null; // ok as we do not allow nulls in list
168
makeDirty();
169         switch (managed) {
170             case MANAGED_ONE_TO_MANY:
171                 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
172                 break;
173             case MANAGED_MANY_TO_MANY:
174                 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
175                 break;
176         }
177         return result;
178     }
179
180     public boolean remove(Object JavaDoc o) {
181         // Finding the index and removing it is faster as ArrayList leaves this
182
// to AbstractCollection which creates an Iterator to search for the
183
// element and calls Iterator.remove when it is found. This in turn
184
// calls remove(index) on us. Braindead but true!
185
int i = indexOf(o);
186         if (i < 0) return false;
187         remove(i);
188         return true;
189     }
190
191     public boolean addAll(Collection JavaDoc c) {
192         Iterator JavaDoc i;
193         Object JavaDoc o;
194         switch (managed) {
195             case MANAGED_ONE_TO_MANY:
196                 i = c.iterator();
197                 if (!i.hasNext()) return false;
198                 ensureCapacity(c.size() + size());
199                 o = null;
200                 for (; ;) {
201                     o = i.next();
202 // if (o == null) {
203
// throw createNPE();
204
// } else {
205
super.add(o);
206                         SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
207 // }
208
if (!i.hasNext()) break;
209                 }
210                 makeDirty();
211                 return true;
212             case MANAGED_MANY_TO_MANY:
213                 i = c.iterator();
214                 if (!i.hasNext()) return false;
215                 ensureCapacity(c.size() + size());
216                 o = null;
217                 for (; ;) {
218                     o = i.next();
219 // if (o == null) {
220
// throw createNPE();
221
// } else {
222
super.add(o);
223                         SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
224 // }
225
if (!i.hasNext()) break;
226                 }
227                 makeDirty();
228                 return true;
229         }
230         ;
231         if (super.addAll(c)) {
232             makeDirty();
233             return true;
234         }
235         return false;
236     }
237
238     public void clear() {
239         int n;
240         switch (managed) {
241             case MANAGED_ONE_TO_MANY:
242                 n = size();
243                 for (int i = 0; i < n; i++) {
244                     SCOInverseUtil.removeMasterOnDetail(get(i), owner, inverseFieldNo);
245                 }
246                 break;
247             case MANAGED_MANY_TO_MANY:
248                 n = size();
249                 for (int i = 0; i < n; i++) {
250                     SCOInverseUtil.removeFromOtherSideOfManyToMany(get(i), inverseFieldNo, owner);
251                 }
252                 break;
253         }
254         super.clear();
255         makeDirty();
256     }
257
258     public boolean addAll(int index, Collection JavaDoc c) {
259         boolean result;
260         int colSize;
261         switch (managed) {
262             case MANAGED_ONE_TO_MANY:
263                 result = false;
264                 colSize = c.size();
265                 ensureCapacity(size() + colSize);
266                 for (Iterator JavaDoc iter = c.iterator(); iter.hasNext();) {
267                     Object JavaDoc o = iter.next();
268 // if (o == null) {
269
// throw createNPE();
270
// } else {
271
super.add(index++, o);
272                         SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
273                         result = true;
274 // }
275
}
276                 if (result) makeDirty();
277                 return result;
278             case MANAGED_MANY_TO_MANY:
279                 result = false;
280                 colSize = c.size();
281                 ensureCapacity(size() + colSize);
282                 for (Iterator JavaDoc iter = c.iterator(); iter.hasNext();) {
283                     Object JavaDoc o = iter.next();
284 // if (o == null) {
285
// throw createNPE();
286
// } else {
287
super.add(index++, o);
288                         SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
289                         result = true;
290 // }
291
}
292                 if (result) makeDirty();
293                 return result;
294         }
295         ;
296         result = super.addAll(index, c);
297         if (result) makeDirty();
298         return result;
299     }
300
301     protected void removeRange(int fromIndex, int toIndex) {
302         switch (managed) {
303             case MANAGED_ONE_TO_MANY:
304                 for (int i = fromIndex; i < toIndex; i++) {
305                     SCOInverseUtil.removeMasterOnDetail(get(i), owner, inverseFieldNo);
306                 }
307                 break;
308             case MANAGED_MANY_TO_MANY:
309                 for (int i = fromIndex; i < toIndex; i++) {
310                     SCOInverseUtil.removeFromOtherSideOfManyToMany(get(i), inverseFieldNo, owner);
311                 }
312                 break;
313         }
314         super.removeRange(fromIndex, toIndex);
315         makeDirty();
316     }
317
318     public boolean removeAll(Collection JavaDoc c) {
319         boolean modified;
320         Iterator JavaDoc e;
321         switch (managed) {
322             case MANAGED_ONE_TO_MANY:
323                 modified = false;
324                 e = super.iterator();
325                 while (e.hasNext()) {
326                     Object JavaDoc o = e.next();
327                     if (c.contains(o)) {
328                         e.remove();
329                         SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
330                         modified = true;
331                     }
332                 }
333                 if (modified) makeDirty();
334                 return modified;
335             case MANAGED_MANY_TO_MANY:
336                 modified = false;
337                 e = super.iterator();
338                 while (e.hasNext()) {
339                     Object JavaDoc o = e.next();
340                     if (c.contains(o)) {
341                         e.remove();
342                         SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
343                         modified = true;
344                     }
345                 }
346                 if (modified) makeDirty();
347                 return modified;
348         }
349         if (super.removeAll(c)) {
350             makeDirty();
351             return true;
352         }
353         return false;
354     }
355
356     public boolean retainAll(Collection JavaDoc c) {
357         boolean modified = false;
358         Iterator JavaDoc e = super.iterator();
359         while (e.hasNext()) {
360             Object JavaDoc o = e.next();
361             if (!c.contains(o)) {
362                 e.remove();
363                 modified = true;
364                 switch (managed) {
365                     case MANAGED_ONE_TO_MANY:
366                         SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
367                         break;
368                     case MANAGED_MANY_TO_MANY:
369                         SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
370                         break;
371                 }
372             }
373         }
374         if (modified) makeDirty();
375         return modified;
376     }
377
378     public CollectionDiff getCollectionDiff(PersistenceContext pm) {
379         Object JavaDoc[] data = toArray();
380         if (fmd.isOrdered()) {
381             return CollectionDiffUtil.getOrderedCollectionDiff(fmd, pm,
382                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
383         } else {
384             return CollectionDiffUtil.getUnorderedCollectionDiff(fmd, pm,
385                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
386         }
387     }
388
389     public Object JavaDoc getOwner() {
390         return owner;
391     }
392
393     public void makeTransient() {
394         owner = null;
395         stateManager = null;
396     }
397
398     public void makeDirty() {
399         if (stateManager != null) {
400             stateManager.makeDirty(owner, fmd.getManagedFieldNo());
401         }
402     }
403
404     public void reset() {
405         beenReset = true;
406         originalData = toArray();
407     }
408
409     public void manyToManyAdd(Object JavaDoc o) {
410         super.add(o);
411         makeDirty();
412     }
413
414     public void manyToManyRemove(Object JavaDoc o) {
415 // We cannot just call super.remove(o). ArrayList leaves this up to
416
// AbstractCollection which creates an Iterator to search for the
417
// element and calls Iterator.remove when it is found. This in turn
418
// calls remove(index) on us. Braindead but true!
419
int i = indexOf(o);
420         if (i < 0) return;
421         super.remove(i);
422         makeDirty();
423     }
424
425     /**
426      * Is the collection ordered.
427      */

428     public boolean isOrdered() {
429         return fmd.isOrdered();
430     }
431
432     /**
433      * Put references to all the values into collectionData. If the
434      * values are PC instances then the instances themselves or their
435      * OIDs may be stored in collectionData.
436      */

437     public CollectionData fillCollectionData(CollectionData collectionData) {
438         int size = size();
439         collectionData.valueCount = size;
440         Object JavaDoc[] newData;
441         Object JavaDoc[] values = collectionData.values;
442         if (values == null || values.length < size) {
443             newData = new Object JavaDoc[size];
444         } else {
445             newData = values;
446         }
447         for (int i = 0; i < size; i++) {
448             newData[i] = get(i);
449         }
450         collectionData.values = newData;
451         return collectionData;
452     }
453 }
454
Popular Tags