KickJava   Java API By Example, From Geeks To Geeks.

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


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.Collection JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.LinkedList JavaDoc;
23 import java.util.ListIterator JavaDoc;
24
25 import com.versant.core.common.BindingSupportImpl;
26 import com.versant.core.common.PersistenceContext;
27
28 /**
29  * LinkedList SCO implementation.
30  *
31  * @keep-all
32  */

33 public final class SCOLinkedList extends LinkedList JavaDoc implements VersantManagedSCOCollection, VersantAdvancedSCO {
34
35     private transient PersistenceCapable owner;
36     private final transient VersantFieldMetaData fmd;
37     private transient VersantStateManager stateManager;
38     private final transient boolean isMaster;
39     private final transient boolean isMany;
40     private final transient int inverseFieldNo;
41     private transient Object JavaDoc[] originalData;
42     private transient boolean beenReset;
43
44     public SCOLinkedList(PersistenceCapable owner, VersantStateManager stateManager,
45                          VersantFieldMetaData fmd, Object JavaDoc[] originalData) {
46         this.owner = owner;
47         this.isMaster = fmd.isManaged() && fmd.isMaster();
48         this.inverseFieldNo = fmd.getInverseFieldNo();
49         this.isMany = fmd.isManaged() && fmd.isManyToMany();
50         this.fmd = fmd;
51         this.stateManager = stateManager;
52         this.originalData = originalData;
53         int n = originalData == null ? 0 : originalData.length;
54         if (!owner.jdoIsNew()) {
55             for (int i = 0; i < n; i++) {
56                 Object JavaDoc o = originalData[i];
57
58                 super.add( o);
59             }
60         } else if (isMaster) {
61             for (int i = 0; i < n; i++) {
62                 Object JavaDoc o = originalData[i];
63                 super.add( o);
64                 SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
65             }
66         } else if (isMany) {
67             for (int i = 0; i < n; i++) {
68                 Object JavaDoc o = originalData[i];
69                 super.add( o);
70                 SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
71             }
72         } else {
73             for (int i = 0; i < n; i++) {
74                 Object JavaDoc o = originalData[i];
75                 super.add( o);
76             }
77         }
78     }
79
80     public Object JavaDoc removeFirst() {
81         Object JavaDoc result = super.removeFirst();
82         if (isMaster) {
83             SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
84         } else if (isMany) {
85             SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
86         }
87         makeDirty();
88         return result;
89     }
90
91     public Object JavaDoc removeLast() {
92         Object JavaDoc result = super.removeLast();
93         if (isMaster) {
94             SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
95         } else if (isMany) {
96             SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
97         }
98         makeDirty();
99         return result;
100     }
101
102     public void addFirst(Object JavaDoc o) {
103         if (isMaster) {
104             super.addFirst(o);
105             makeDirty();
106             SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
107         } else if (isMany) {
108             super.addFirst(o);
109             makeDirty();
110             SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
111         } else {
112             super.addFirst(o);
113             makeDirty();
114         }
115     }
116
117     public void addLast(Object JavaDoc o) {
118         if (isMaster) {
119             super.addLast(o);
120             makeDirty();
121             SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
122         } else if (isMany) {
123             super.addLast(o);
124             makeDirty();
125             SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
126         } else {
127             super.addLast(o);
128             makeDirty();
129         }
130
131     }
132
133     public boolean addAll(int index, Collection JavaDoc c) {
134         if (isMaster) {
135             boolean result = false;
136             c.size(); // call this because super calls this
137
for (Iterator JavaDoc iter = c.iterator(); iter.hasNext();) {
138                 Object JavaDoc o = iter.next();
139                 if (o == null) {
140                 } else {
141                     super.add(index++, o);
142                     SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
143                     result = true;
144                 }
145             }
146             if (result) {
147                 makeDirty();
148             }
149             return result;
150         } else if (isMany) {
151             boolean result = false;
152             c.size(); // call this because super calls this
153
for (Iterator JavaDoc iter = c.iterator(); iter.hasNext();) {
154                 Object JavaDoc o = iter.next();
155                 if (o == null) {
156                 } else {
157                     super.add(index++, o);
158                     SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
159                     result = true;
160                 }
161             }
162             if (result) {
163                 makeDirty();
164             }
165             return result;
166         } else {
167             if (super.addAll(index, c)) {
168                 makeDirty();
169                 return true;
170             }
171             return false;
172         }
173     }
174
175     protected void removeRange(int fromIndex, int toIndex) {
176         if (isMaster) {
177 // get unwrapped iterator from super so we can do remove
178
ListIterator JavaDoc iter = super.listIterator(fromIndex);
179             for (int i = 0, n = toIndex - fromIndex; i < n; i++) {
180                 SCOInverseUtil.removeMasterOnDetail(iter.next(), owner, inverseFieldNo);
181                 iter.remove();
182             }
183         } else if (isMany) {
184 // get unwrapped iterator from super so we can do remove
185
ListIterator JavaDoc iter = super.listIterator(fromIndex);
186             for (int i = 0, n = toIndex - fromIndex; i < n; i++) {
187                 SCOInverseUtil.removeFromOtherSideOfManyToMany(iter.next(), inverseFieldNo, owner);
188                 iter.remove();
189             }
190         } else {
191             super.removeRange(fromIndex, toIndex);
192         }
193         makeDirty();
194     }
195
196     public boolean removeAll(Collection JavaDoc c) {
197         boolean modified = false;
198 // get unwrapped iterator from super so we can do remove
199
Iterator JavaDoc e = super.listIterator(0);
200         while (e.hasNext()) {
201             Object JavaDoc o = e.next();
202             if (c.contains(o)) {
203                 e.remove();
204                 modified = true;
205                 if (isMaster) {
206                     SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
207                 } else if (isMany) {
208                     SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
209                 }
210             }
211         }
212         if (modified) makeDirty();
213         return modified;
214
215     }
216
217     public boolean retainAll(Collection JavaDoc c) {
218         boolean modified = false;
219         // get an unwrapped Iterator so we can call remove
220
Iterator JavaDoc e = super.listIterator(0);
221         while (e.hasNext()) {
222             Object JavaDoc o = e.next();
223             if (!c.contains(o)) {
224                 e.remove();
225                 modified = true;
226                 if (isMaster) {
227                     SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
228                 } else if (isMany) {
229                     SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
230                 }
231             }
232         }
233
234         if (modified) makeDirty();
235         return modified;
236     }
237
238     public Object JavaDoc set(int index, Object JavaDoc element) {
239         if (isMaster) {
240             Object JavaDoc result = super.set(index, element);
241             if (result != null) {
242                 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
243             }
244             SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo);
245             makeDirty();
246             return result;
247         } else if (isMany) {
248             Object JavaDoc result = super.set(index, element);
249             if (result != null) {
250                 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
251             }
252             SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner);
253             makeDirty();
254             return result;
255         } else {
256             Object JavaDoc result = super.set(index, element);
257             makeDirty();
258             return result;
259         }
260     }
261
262     public ListIterator JavaDoc listIterator(int index) {
263         return new ListIteratorImp(super.listIterator(index));
264     }
265
266     private boolean isManaged() {
267         return isMaster || isMany;
268     }
269
270     /**
271      * The set call in our superclass ListIterator is the only modification
272      * operation that does not delegate to the list. This is disallowed for
273      * managed relationships as there is no way for us to get at the current
274      * element.
275      */

276     private class ListIteratorImp implements ListIterator JavaDoc {
277
278         private ListIterator JavaDoc i;
279
280         public void set(Object JavaDoc o) {
281             if (SCOLinkedList.this.isManaged()) {
282                 throw BindingSupportImpl.getInstance().runtime("ListIterator.set(Object) is not supported for " +
283                         "managed relationships using LinkedList: " +
284                         SCOLinkedList.this.fmd.getQName());
285             }
286             i.set(o);
287             SCOLinkedList.this.makeDirty();
288         }
289
290         public void remove() {
291             if (SCOLinkedList.this.isManaged()) {
292                 throw BindingSupportImpl.getInstance().runtime("ListIterator.remove() is not supported for " +
293                         "managed relationships using LinkedList: " +
294                         SCOLinkedList.this.fmd.getQName());
295             }
296             i.remove();
297             SCOLinkedList.this.makeDirty();
298         }
299
300         public void add(Object JavaDoc o) {
301             if (SCOLinkedList.this.isManaged()) {
302                 throw BindingSupportImpl.getInstance().runtime("ListIterator.add(Object) is not supported for " +
303                         "managed relationships using LinkedList: " +
304                         SCOLinkedList.this.fmd.getQName());
305             }
306             i.add(o);
307             SCOLinkedList.this.makeDirty();
308         }
309
310         public ListIteratorImp(ListIterator JavaDoc i) {
311             this.i = i;
312         }
313
314         public boolean hasNext() {
315             return i.hasNext();
316         }
317
318         public Object JavaDoc next() {
319             return i.next();
320         }
321
322         public boolean hasPrevious() {
323             return i.hasPrevious();
324         }
325
326         public Object JavaDoc previous() {
327             return i.previous();
328         }
329
330         public int nextIndex() {
331             return i.nextIndex();
332         }
333
334         public int previousIndex() {
335             return i.previousIndex();
336         }
337     }
338
339     public boolean add(Object JavaDoc o) {
340         if (isMaster) {
341             super.add(o);
342             makeDirty();
343             SCOInverseUtil.addMasterOnDetail(o, owner, inverseFieldNo);
344             return true;
345         } else if (isMany) {
346             super.add(o);
347             makeDirty();
348             SCOInverseUtil.addToOtherSideOfManyToMany(o, inverseFieldNo, owner);
349             return true;
350         } else {
351             super.add(o);
352             makeDirty();
353             return true;
354         }
355     }
356
357     public void add(int index, Object JavaDoc element) {
358         if (isMaster) {
359             super.add(index, element);
360             makeDirty();
361             SCOInverseUtil.addMasterOnDetail(element, owner, inverseFieldNo);
362         } else if (isMany) {
363             super.add(index, element);
364             makeDirty();
365             SCOInverseUtil.addToOtherSideOfManyToMany(element, inverseFieldNo, owner);
366         } else {
367             super.add(index, element);
368             makeDirty();
369         }
370
371     }
372
373     public Object JavaDoc remove(int index) {
374         Object JavaDoc result = super.remove(index);
375         if (result != null) {
376             makeDirty();
377             if (isMaster) {
378                 SCOInverseUtil.removeMasterOnDetail(result, owner, inverseFieldNo);
379             } else if (isMany) {
380                 SCOInverseUtil.removeFromOtherSideOfManyToMany(result, inverseFieldNo, owner);
381             }
382         }
383         return result;
384     }
385
386     public boolean remove(Object JavaDoc o) {
387         if (super.remove(o)) {
388             makeDirty();
389
390             if (isMaster) {
391                 SCOInverseUtil.removeMasterOnDetail(o, owner, inverseFieldNo);
392             } else if (isMany) {
393                 SCOInverseUtil.removeFromOtherSideOfManyToMany(o, inverseFieldNo, owner);
394             }
395
396             return true;
397         }
398         return false;
399     }
400
401     public void clear() {
402         if (isMaster) {
403             for (Iterator JavaDoc iter = super.listIterator(0); iter.hasNext();) {
404                 SCOInverseUtil.removeMasterOnDetail(iter.next(), owner, inverseFieldNo);
405             }
406         } else if (isMany) {
407             for (Iterator JavaDoc iter = super.listIterator(0); iter.hasNext();) {
408                 SCOInverseUtil.removeFromOtherSideOfManyToMany(iter.next(), inverseFieldNo, owner);
409             }
410         }
411         super.clear();
412         makeDirty();
413     }
414
415     public CollectionDiff getCollectionDiff(PersistenceContext pm) {
416         Object JavaDoc[] data = toArray();
417         if (fmd.isOrdered()) {
418             return CollectionDiffUtil.getOrderedCollectionDiff(fmd, pm,
419                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
420         } else {
421             return CollectionDiffUtil.getUnorderedCollectionDiff(fmd, pm,
422                     data, data.length, (owner.jdoIsNew() && !beenReset) ? null : originalData);
423         }
424     }
425
426     public Object JavaDoc getOwner() {
427         return owner;
428     }
429
430     public void makeTransient() {
431         owner = null;
432         stateManager = null;
433     }
434
435     public void makeDirty() {
436         if (stateManager != null) {
437             stateManager.makeDirty(owner, fmd.getManagedFieldNo());
438         }
439     }
440
441     public void reset() {
442         beenReset = true;
443         originalData = toArray();
444     }
445
446     public void manyToManyAdd(Object JavaDoc o) {
447         super.add(o);
448         makeDirty();
449     }
450
451     public void manyToManyRemove(Object JavaDoc o) {
452         if (super.remove(o)) {
453             makeDirty();
454         }
455
456     }
457
458     /**
459      * Is the collection ordered.
460      */

461     public boolean isOrdered() {
462         return fmd.isOrdered();
463     }
464
465     /**
466      * Put references to all the values into collectionData. If the
467      * values are PC instances then the instances themselves or their
468      * OIDs may be stored in collectionData.
469      */

470     public CollectionData fillCollectionData(CollectionData collectionData) {
471         int size = size();
472         collectionData.valueCount = size;
473         Object JavaDoc[] newData;
474         Object JavaDoc[] values = collectionData.values;
475         if (values == null || values.length < size) {
476             newData = new Object JavaDoc[size];
477         } else {
478             newData = values;
479         }
480         for (int i = 0; i < size; i++) {
481             newData[i] = get(i);
482         }
483         collectionData.values = newData;
484         return collectionData;
485     }
486 }
487
Popular Tags