KickJava   Java API By Example, From Geeks To Geeks.

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


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.*;
21
22 import com.versant.core.common.BindingSupportImpl;
23 import com.versant.core.common.PersistenceContext;
24
25 /**
26  * A SCO implementation of a Vector.
27  */

28 public final class SCOVector extends Vector implements VersantManagedSCOCollection, VersantAdvancedSCO {
29
30     private transient PersistenceCapable owner;
31     private final transient VersantFieldMetaData fmd;
32     private transient VersantStateManager stateManager;
33     private final transient boolean isMaster;
34     private final transient boolean isMany;
35     private final transient int inverseFieldNo;
36     private transient Object JavaDoc[] originalData;
37     private transient boolean beenReset;
38
39     public SCOVector(PersistenceCapable owner, VersantStateManager stateManager,
40                      VersantFieldMetaData fmd, Object JavaDoc[] originalData) {
41         this.owner = owner;
42         this.fmd = fmd;
43         this.isMaster = fmd.isManaged() && fmd.isMaster();
44         this.isMany = fmd.isManaged() && fmd.isManyToMany();
45         this.stateManager = stateManager;
46         this.inverseFieldNo = fmd.getInverseFieldNo();
47         this.originalData = originalData;
48         int n = originalData == null ? 0 : originalData.length;
49         if (n > 0) ensureCapacity(n);
50         if (!owner.jdoIsNew()) {
51             for (int i = 0; i < n; i++) {
52                 Object JavaDoc o = originalData[i];
53                 super.add(o);
54             }
55         } else if (isMaster) {
56             for (int i = 0; i < n; i++) {
57                 Object JavaDoc o = originalData[i];
58                 super.add(o);
59                 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
60             }
61         } else if (isMany) {
62             for (int i = 0; i < n; i++) {
63                 Object JavaDoc o = originalData[i];
64                 super.add(o);
65                 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
66             }
67         } else {
68             for (int i = 0; i < n; i++) {
69                 Object JavaDoc o = originalData[i];
70                 super.add(o);
71             }
72         }
73     }
74
75     public synchronized void setSize(int newSize) {
76         if (newSize > elementCount) {
77             throw BindingSupportImpl.getInstance().nullElement("setSize called with " + newSize + " > " + elementCount + " and " +
78                     "null elements are not allowed: " + fmd.getQName());
79         }
80         if (isMaster) {
81             for (int i = newSize; i < elementCount; i++) {
82                 SCOInverseUtil.removeMasterOnDetail(elementData[i], owner, inverseFieldNo);
83             }
84             super.setSize(newSize);
85             makeDirty();
86         } else if (isMany) {
87             for (int i = newSize; i < elementCount; i++) {
88                 SCOInverseUtil.removeFromOtherSideOfManyToMany(elementData[i], inverseFieldNo, owner);
89             }
90             super.setSize(newSize);
91             makeDirty();
92         } else {
93             super.setSize(newSize);
94             makeDirty();
95         }
96
97     }
98
99     public synchronized void setElementAt(Object JavaDoc obj, int index) {
100         if (isMaster) {
101             if (index >= elementCount) {
102                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index + " >= " +
103                         elementCount);
104             }
105             if (elementData[index] != null) {
106                 SCOInverseUtil.removeMasterOnDetail(elementData[index], owner, inverseFieldNo);
107             }
108             SCOInverseUtil.addMasterOnDetail(obj, owner, inverseFieldNo);
109             super.setElementAt(obj, index);
110             makeDirty();
111         } else if (isMany) {
112             if (index >= elementCount) {
113                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index + " >= " +
114                         elementCount);
115             }
116             if (elementData[index] != null) {
117                 SCOInverseUtil.removeFromOtherSideOfManyToMany(elementData[index], inverseFieldNo, owner);
118             }
119             SCOInverseUtil.addToOtherSideOfManyToMany(obj, inverseFieldNo, owner);
120             super.setElementAt(obj, index);
121             makeDirty();
122         } else {
123             super.setElementAt(obj, index);
124             makeDirty();
125         }
126
127     }
128
129     public synchronized void removeElementAt(int index) {
130
131         if (isMaster) {
132             if (index >= elementCount) {
133                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index + " >= " +
134                         elementCount);
135             } else if (index < 0) {
136                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index);
137             }
138             SCOInverseUtil.removeMasterOnDetail(elementData[index], owner, inverseFieldNo);
139         } else if (isMany) {
140             if (index >= elementCount) {
141                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index + " >= " +
142                         elementCount);
143             } else if (index < 0) {
144                 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds(index);
145             }
146             SCOInverseUtil.removeFromOtherSideOfManyToMany(elementData[index], inverseFieldNo, owner);
147         }
148         super.removeElementAt(index);
149
150         makeDirty();
151     }
152
153     public synchronized void insertElementAt(Object JavaDoc obj, int index) {
154         if (isMaster) {
155             super.insertElementAt(obj, index);
156             SCOInverseUtil.addMasterOnDetail(obj, owner, inverseFieldNo);
157             makeDirty();
158         } else if (isMany) {
159             super.insertElementAt(obj, index);
160             SCOInverseUtil.addToOtherSideOfManyToMany(obj, inverseFieldNo, owner);
161             makeDirty();
162         } else {
163             makeDirty();
164             super.insertElementAt(obj, index);
165         }
166     }
167
168     public synchronized void addElement(Object JavaDoc obj) {
169         if (isMaster) {
170             super.addElement(obj);
171             makeDirty();
172             SCOInverseUtil.addMasterOnDetail(obj, owner, inverseFieldNo);
173         } else if (isMany) {
174             super.addElement(obj);
175             makeDirty();
176             SCOInverseUtil.addToOtherSideOfManyToMany(obj, inverseFieldNo, owner);
177         } else {
178             super.addElement(obj);
179             makeDirty();
180         }
181     }
182
183     public synchronized void removeAllElements() {
184
185         modCount++;
186         // Let gc do its work
187
for (int i = 0; i < elementCount; i++) {
188             if (isMaster) {
189                 SCOInverseUtil.removeMasterOnDetail(elementData[i], owner, inverseFieldNo);
190             } else if (isMany) {
191                 SCOInverseUtil.removeFromOtherSideOfManyToMany(elementData[i], inverseFieldNo, owner);
192             }
193             elementData[i] = null;
194         }
195
196         elementCount = 0;
197         makeDirty();
198     }
199
200     public synchronized Object JavaDoc set(int index, Object JavaDoc element) {
201         if (isMaster) {
202             Object JavaDoc obj = super.set(index, element);
203             if (obj != null) {
204                 SCOInverseUtil.removeMasterOnDetail(obj, owner, inverseFieldNo);
205             }
206             SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo);
207             makeDirty();
208             return obj;
209         } else if (isMany) {
210             Object JavaDoc obj = super.set(index, element);
211             if (obj != null) {
212                 SCOInverseUtil.removeFromOtherSideOfManyToMany(obj, inverseFieldNo, owner);
213             }
214             SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner);
215             makeDirty();
216             return obj;
217         } else {
218             Object JavaDoc obj = super.set(index, element);
219             makeDirty();
220             return obj;
221         }
222     }
223
224     public synchronized boolean add(Object JavaDoc o) {
225         if (isMaster) {
226             super.add(o);
227             makeDirty();
228             SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
229             return true;
230         } else if (isMany) {
231             super.add(o);
232             makeDirty();
233             SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
234             return true;
235         } else {
236             super.add(o);
237             makeDirty();
238             return true;
239         }
240     }
241
242     public synchronized Object JavaDoc remove(int index) {
243         Object JavaDoc obj = super.remove(index);
244         if (isMaster) {
245             SCOInverseUtil.removeMasterOnDetail(obj, owner, inverseFieldNo);
246         } else if (isMany) {
247             SCOInverseUtil.removeFromOtherSideOfManyToMany(obj, inverseFieldNo, owner);
248         }
249         makeDirty();
250         return obj;
251     }
252
253     public synchronized boolean addAll(Collection c) {
254         if (isMaster) {
255             boolean added = false;
256             ensureCapacity(elementCount + c.size());
257             for (Iterator iter = c.iterator(); iter.hasNext();) {
258                 Object JavaDoc o = iter.next();
259                 if (o == null) {
260                 } else {
261                     added = super.add(o);
262                     SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
263                 }
264             }
265             if (added) {
266                 makeDirty();
267             }
268             return added;
269         } else if (isMany) {
270             boolean added = false;
271             ensureCapacity(elementCount + c.size());
272             for (Iterator iter = c.iterator(); iter.hasNext();) {
273                 Object JavaDoc o = iter.next();
274                 if (o == null) {
275                 } else {
276                     added = super.add(o);
277                     SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
278                 }
279             }
280             if (added) {
281                 makeDirty();
282             }
283             return added;
284         } else if (super.addAll(c)) {
285             makeDirty();
286             return true;
287         }
288         return false;
289     }
290
291     public synchronized boolean removeAll(Collection c) {
292         boolean modified = false;
293         Iterator e = super.iterator();
294         Object JavaDoc o = null;
295         while (e.hasNext()) {
296             o = e.next();
297             if (c.contains(o)) {
298                 e.remove();
299                 modified = true;
300                 if (isMaster) {
301                     SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
302                 } else if (isMany) {
303                     SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
304                 }
305             }
306         }
307         if (modified) makeDirty();
308         return modified;
309     }
310
311     public synchronized boolean retainAll(Collection c) {
312         boolean modified = false;
313         Iterator e = super.iterator();
314         Object JavaDoc o = null;
315         while (e.hasNext()) {
316             o = e.next();
317             if (!c.contains(o)) {
318                 e.remove();
319                 modified = true;
320                 if (isMaster) {
321                     SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
322                 } else if (isMany) {
323                     SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
324                 }
325             }
326         }
327
328         if (modified) {
329             makeDirty();
330         }
331         return modified;
332     }
333
334     public synchronized boolean addAll(int index, Collection c) {
335         if (isMaster) {
336             boolean added = false;
337             ensureCapacity(elementCount + c.size());
338             for (Iterator iter = c.iterator(); iter.hasNext();) {
339                 Object JavaDoc o = iter.next();
340                 if (o == null) {
341                 } else {
342                     super.insertElementAt(o, index++);
343                     SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
344                     added = true;
345                 }
346             }
347             if (added) {
348                 makeDirty();
349             }
350             return added;
351         } else if (isMany) {
352             boolean added = false;
353             ensureCapacity(elementCount + c.size());
354             for (Iterator iter = c.iterator(); iter.hasNext();) {
355                 Object JavaDoc o = iter.next();
356                 if (o == null) {
357                 } else {
358                     super.insertElementAt(o, index++);
359                     SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
360                     added = true;
361                 }
362             }
363             if (added) {
364                 makeDirty();
365             }
366             return added;
367         } else if (super.addAll(index, c)) {
368             makeDirty();
369             return true;
370         }
371         return false;
372     }
373
374     protected void removeRange(int fromIndex, int toIndex) {
375         if (isMaster) {
376             List removeList = super.subList(fromIndex, toIndex);
377             for (int i = 0; i < removeList.size(); i++) {
378                 SCOInverseUtil.removeMasterOnDetail(get(i), owner, inverseFieldNo);
379             }
380         } else if (isMany) {
381             List removeList = super.subList(fromIndex, toIndex);
382             for (int i = 0; i < removeList.size(); i++) {
383                 SCOInverseUtil.removeFromOtherSideOfManyToMany(get(i), inverseFieldNo, owner);
384             }
385         }
386
387         super.removeRange(fromIndex, toIndex);
388         makeDirty();
389     }
390
391     public ListIterator listIterator() {
392         return new SCOListIterator(super.listIterator(), stateManager, owner, fmd.getManagedFieldNo());
393     }
394
395     public ListIterator listIterator(int index) {
396         return new SCOListIterator(super.listIterator(index), stateManager, owner, fmd.getManagedFieldNo());
397     }
398
399     public Iterator iterator() {
400         return new SCOIterator(super.iterator(), stateManager, owner, fmd.getManagedFieldNo());
401     }
402
403     public CollectionDiff getCollectionDiff(PersistenceContext pm) {
404         Object JavaDoc[] data = toArray();
405         if (fmd.isOrdered()) {
406             return CollectionDiffUtil.getOrderedCollectionDiff(fmd, pm,
407                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
408         } else {
409             return CollectionDiffUtil.getUnorderedCollectionDiff(fmd, pm,
410                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
411         }
412     }
413
414     public Object JavaDoc getOwner() {
415         return owner;
416     }
417
418     public void makeTransient() {
419         owner = null;
420         stateManager = null;
421     }
422
423     public void makeDirty() {
424         if (stateManager != null) {
425             stateManager.makeDirty(owner, fmd.getManagedFieldNo());
426         }
427     }
428
429     public void reset() {
430         beenReset = true;
431         originalData = toArray();
432     }
433
434     public void manyToManyAdd(Object JavaDoc o) {
435         super.add(o);
436         makeDirty();
437     }
438
439     public void manyToManyRemove(Object JavaDoc o) {
440         if (super.removeElement(o)) {
441             makeDirty();
442         }
443     }
444
445     /**
446      * Is the collection ordered.
447      */

448     public boolean isOrdered() {
449         return fmd.isOrdered();
450     }
451
452     /**
453      * Put references to all the values into collectionData. If the
454      * values are PC instances then the instances themselves or their
455      * OIDs may be stored in collectionData.
456      */

457     public CollectionData fillCollectionData(CollectionData collectionData) {
458         int size = size();
459         collectionData.valueCount = size;
460         Object JavaDoc[] newData;
461         Object JavaDoc[] values = collectionData.values;
462         if (values == null || values.length < size) {
463             newData = new Object JavaDoc[size];
464         } else {
465             newData = values;
466         }
467         for (int i = 0; i < size; i++) {
468             newData[i] = get(i);
469         }
470         collectionData.values = newData;
471         return collectionData;
472     }
473 }
474
Popular Tags