KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > collection > PersistentBag


1 //$Id: PersistentBag.java,v 1.19 2005/06/28 08:59:06 maxcsaucdk Exp $
2
package org.hibernate.collection;
3
4 import java.io.Serializable JavaDoc;
5 import java.sql.ResultSet JavaDoc;
6 import java.sql.SQLException JavaDoc;
7 import java.util.ArrayList JavaDoc;
8 import java.util.Collection JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.ListIterator JavaDoc;
12
13 import org.hibernate.EntityMode;
14 import org.hibernate.HibernateException;
15 import org.hibernate.loader.CollectionAliases;
16 import org.hibernate.engine.SessionImplementor;
17 import org.hibernate.persister.collection.CollectionPersister;
18 import org.hibernate.type.Type;
19
20 /**
21  * An unordered, unkeyed collection that can contain the same element
22  * multiple times. The Java collections API, curiously, has no <tt>Bag</tt>.
23  * Most developers seem to use <tt>List</tt>s to represent bag semantics,
24  * so Hibernate follows this practice.
25  *
26  * @author Gavin King
27  */

28 public class PersistentBag extends AbstractPersistentCollection implements java.util.List JavaDoc {
29
30     protected java.util.List JavaDoc bag;
31
32     public PersistentBag(SessionImplementor session) {
33         super(session);
34     }
35
36     public PersistentBag(SessionImplementor session, java.util.Collection JavaDoc coll) {
37         super(session);
38         if (coll instanceof java.util.List JavaDoc) {
39             bag = (java.util.List JavaDoc) coll;
40         }
41         else {
42             bag = new ArrayList JavaDoc();
43             Iterator JavaDoc iter = coll.iterator();
44             while ( iter.hasNext() ) {
45                 bag.add( iter.next() );
46             }
47         }
48         setInitialized();
49         setDirectlyAccessible(true);
50     }
51
52     public PersistentBag() {} //needed for SOAP libraries, etc
53

54     public boolean isWrapper(Object JavaDoc collection) {
55         return bag==collection;
56     }
57     public boolean empty() {
58         return bag.isEmpty();
59     }
60     
61     public Iterator JavaDoc entries(CollectionPersister persister) {
62         return bag.iterator();
63     }
64
65     public Object JavaDoc readFrom(ResultSet JavaDoc rs, CollectionPersister persister, CollectionAliases descriptor, Object JavaDoc owner)
66     throws HibernateException, SQLException JavaDoc {
67         // note that if we load this collection from a cartesian product
68
// the multiplicity would be broken ... so use an idbag instead
69
Object JavaDoc element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
70         if (element!=null) bag.add(element);
71         return element;
72     }
73
74     public void beforeInitialize(CollectionPersister persister) {
75         this.bag = new ArrayList JavaDoc();
76     }
77
78     public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
79         Type elementType = persister.getElementType();
80         EntityMode entityMode = getSession().getEntityMode();
81         java.util.List JavaDoc sn = (java.util.List JavaDoc) getSnapshot();
82         if ( sn.size()!=bag.size() ) return false;
83         Iterator JavaDoc iter = bag.iterator();
84         while ( iter.hasNext() ) {
85             Object JavaDoc elt = iter.next();
86             final boolean unequal = countOccurrences(elt, bag, elementType, entityMode) !=
87                 countOccurrences(elt, sn, elementType, entityMode);
88             if ( unequal ) return false;
89         }
90         return true;
91     }
92
93     public boolean isSnapshotEmpty(Serializable JavaDoc snapshot) {
94         return ( (Collection JavaDoc) snapshot ).isEmpty();
95     }
96     
97     private int countOccurrences(Object JavaDoc element, java.util.List JavaDoc list, Type elementType, EntityMode entityMode)
98     throws HibernateException {
99         Iterator JavaDoc iter = list.iterator();
100         int result=0;
101         while ( iter.hasNext() ) {
102             if ( elementType.isSame( element, iter.next(), entityMode ) ) result++;
103         }
104         return result;
105     }
106
107     public Serializable JavaDoc getSnapshot(CollectionPersister persister)
108     throws HibernateException {
109         EntityMode entityMode = getSession().getEntityMode();
110         ArrayList JavaDoc clonedList = new ArrayList JavaDoc( bag.size() );
111         Iterator JavaDoc iter = bag.iterator();
112         while ( iter.hasNext() ) {
113             clonedList.add( persister.getElementType().deepCopy( iter.next(), entityMode, persister.getFactory() ) );
114         }
115         return clonedList;
116     }
117
118     public Collection JavaDoc getOrphans(Serializable JavaDoc snapshot, String JavaDoc entityName) throws HibernateException {
119         java.util.List JavaDoc sn = (java.util.List JavaDoc) snapshot;
120         return getOrphans( sn, bag, entityName, getSession() );
121     }
122
123
124     public Serializable JavaDoc disassemble(CollectionPersister persister)
125     throws HibernateException {
126
127         int length = bag.size();
128         Serializable JavaDoc[] result = new Serializable JavaDoc[length];
129         for ( int i=0; i<length; i++ ) {
130             result[i] = persister.getElementType().disassemble( bag.get(i), getSession(), null );
131         }
132         return result;
133     }
134
135     public void initializeFromCache(CollectionPersister persister, Serializable JavaDoc disassembled, Object JavaDoc owner)
136     throws HibernateException {
137         beforeInitialize(persister);
138         Serializable JavaDoc[] array = (Serializable JavaDoc[]) disassembled;
139         for ( int i=0; i<array.length; i++ ) {
140             Object JavaDoc element = persister.getElementType().assemble( array[i], getSession(), owner );
141             if ( element!=null ) bag.add( element );
142         }
143     }
144
145     public boolean needsRecreate(CollectionPersister persister) {
146         return !persister.isOneToMany();
147     }
148
149
150     // For a one-to-many, a <bag> is not really a bag;
151
// it is *really* a set, since it can't contain the
152
// same element twice. It could be considered a bug
153
// in the mapping dtd that <bag> allows <one-to-many>.
154

155     // Anyway, here we implement <set> semantics for a
156
// <one-to-many> <bag>!
157

158     public Iterator JavaDoc getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
159         //if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
160
Type elementType = persister.getElementType();
161         EntityMode entityMode = getSession().getEntityMode();
162         ArrayList JavaDoc deletes = new ArrayList JavaDoc();
163         java.util.List JavaDoc sn = (java.util.List JavaDoc) getSnapshot();
164         Iterator JavaDoc olditer = sn.iterator();
165         int i=0;
166         while ( olditer.hasNext() ) {
167             Object JavaDoc old = olditer.next();
168             Iterator JavaDoc newiter = bag.iterator();
169             boolean found = false;
170             if ( bag.size()>i && elementType.isSame( old, bag.get(i++), entityMode ) ) {
171             //a shortcut if its location didn't change!
172
found = true;
173             }
174             else {
175                 //search for it
176
//note that this code is incorrect for other than one-to-many
177
while ( newiter.hasNext() ) {
178                     if ( elementType.isSame( old, newiter.next(), entityMode ) ) {
179                         found = true;
180                         break;
181                     }
182                 }
183             }
184             if (!found) deletes.add(old);
185         }
186         return deletes.iterator();
187     }
188
189     public boolean needsInserting(Object JavaDoc entry, int i, Type elemType) throws HibernateException {
190         //if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
191
java.util.List JavaDoc sn = (java.util.List JavaDoc) getSnapshot();
192         final EntityMode entityMode = getSession().getEntityMode();
193         if ( sn.size()>i && elemType.isSame( sn.get(i), entry, entityMode ) ) {
194         //a shortcut if its location didn't change!
195
return false;
196         }
197         else {
198             //search for it
199
//note that this code is incorrect for other than one-to-many
200
Iterator JavaDoc olditer = sn.iterator();
201             while ( olditer.hasNext() ) {
202                 Object JavaDoc old = olditer.next();
203                 if ( elemType.isSame( old, entry, entityMode ) ) return false;
204             }
205             return true;
206         }
207     }
208     
209     public boolean isRowUpdatePossible() {
210         return false;
211     }
212
213     public boolean needsUpdating(Object JavaDoc entry, int i, Type elemType) {
214         //if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
215
return false;
216     }
217
218     /**
219      * @see java.util.Collection#size()
220      */

221     public int size() {
222         read();
223         return bag.size();
224     }
225
226     /**
227      * @see java.util.Collection#isEmpty()
228      */

229     public boolean isEmpty() {
230         read();
231         return bag.isEmpty();
232     }
233
234     /**
235      * @see java.util.Collection#contains(Object)
236      */

237     public boolean contains(Object JavaDoc o) {
238         read();
239         return bag.contains(o);
240     }
241
242     /**
243      * @see java.util.Collection#iterator()
244      */

245     public Iterator JavaDoc iterator() {
246         read();
247         return new IteratorProxy( bag.iterator() );
248     }
249
250     /**
251      * @see java.util.Collection#toArray()
252      */

253     public Object JavaDoc[] toArray() {
254         read();
255         return bag.toArray();
256     }
257
258     /**
259      * @see java.util.Collection#toArray(Object[])
260      */

261     public Object JavaDoc[] toArray(Object JavaDoc[] a) {
262         read();
263         return bag.toArray(a);
264     }
265
266     /**
267      * @see java.util.Collection#add(Object)
268      */

269     public boolean add(Object JavaDoc o) {
270         if ( !queueAdd(o) ) {
271             write();
272             return bag.add(o);
273         }
274         else {
275             return true;
276         }
277     }
278
279     /**
280      * @see java.util.Collection#remove(Object)
281      */

282     public boolean remove(Object JavaDoc o) {
283         write();
284         return bag.remove(o);
285     }
286
287     /**
288      * @see java.util.Collection#containsAll(Collection)
289      */

290     public boolean containsAll(Collection JavaDoc c) {
291         read();
292         return bag.containsAll(c);
293     }
294
295     /**
296      * @see java.util.Collection#addAll(Collection)
297      */

298     public boolean addAll(Collection JavaDoc c) {
299         if ( c.size()==0 ) return false;
300         if ( !queueAddAll(c) ) {
301             write();
302             return bag.addAll(c);
303         }
304         else {
305             return c.size()>0;
306         }
307     }
308
309     public void delayedAddAll(Collection JavaDoc c) {
310         bag.addAll(c);
311     }
312
313     /**
314      * @see java.util.Collection#removeAll(Collection)
315      */

316     public boolean removeAll(Collection JavaDoc c) {
317         if ( c.size()>0 ) {
318             write();
319             return bag.removeAll(c);
320         }
321         else {
322             return false;
323         }
324     }
325
326     /**
327      * @see java.util.Collection#retainAll(Collection)
328      */

329     public boolean retainAll(Collection JavaDoc c) {
330         write();
331         return bag.retainAll(c);
332     }
333
334     /**
335      * @see java.util.Collection#clear()
336      */

337     public void clear() {
338         write();
339         bag.clear();
340     }
341
342     public Object JavaDoc getIndex(Object JavaDoc entry, int i, CollectionPersister persister) {
343         throw new UnsupportedOperationException JavaDoc("Bags don't have indexes");
344     }
345
346     public Object JavaDoc getElement(Object JavaDoc entry) {
347         return entry;
348     }
349
350     public Object JavaDoc getSnapshotElement(Object JavaDoc entry, int i) {
351         java.util.List JavaDoc sn = (java.util.List JavaDoc) getSnapshot();
352         return sn.get(i);
353     }
354
355     public int occurrences(Object JavaDoc o) {
356         read();
357         Iterator JavaDoc iter = bag.iterator();
358         int result=0;
359         while ( iter.hasNext() ) {
360             if ( o.equals( iter.next() ) ) result++;
361         }
362         return result;
363     }
364
365     // List OPERATIONS:
366

367     /**
368      * @see java.util.List#add(int, Object)
369      */

370     public void add(int i, Object JavaDoc o) {
371         write();
372         bag.add(i, o);
373     }
374
375     /**
376      * @see java.util.List#addAll(int, Collection)
377      */

378     public boolean addAll(int i, Collection JavaDoc c) {
379         if ( c.size()>0 ) {
380             write();
381             return bag.addAll(i, c);
382         }
383         else {
384             return false;
385         }
386     }
387
388     /**
389      * @see java.util.List#get(int)
390      */

391     public Object JavaDoc get(int i) {
392         read();
393         return bag.get(i);
394     }
395
396     /**
397      * @see java.util.List#indexOf(Object)
398      */

399     public int indexOf(Object JavaDoc o) {
400         read();
401         return bag.indexOf(o);
402     }
403
404     /**
405      * @see java.util.List#lastIndexOf(Object)
406      */

407     public int lastIndexOf(Object JavaDoc o) {
408         read();
409         return bag.lastIndexOf(o);
410     }
411
412     /**
413      * @see java.util.List#listIterator()
414      */

415     public ListIterator JavaDoc listIterator() {
416         read();
417         return new ListIteratorProxy( bag.listIterator() );
418     }
419
420     /**
421      * @see java.util.List#listIterator(int)
422      */

423     public ListIterator JavaDoc listIterator(int i) {
424         read();
425         return new ListIteratorProxy( bag.listIterator(i) );
426     }
427
428     /**
429      * @see java.util.List#remove(int)
430      */

431     public Object JavaDoc remove(int i) {
432         write();
433         return bag.remove(i);
434     }
435
436     /**
437      * @see java.util.List#set(int, Object)
438      */

439     public Object JavaDoc set(int i, Object JavaDoc o) {
440         write();
441         return bag.set(i, o);
442     }
443
444     /**
445      * @see java.util.List#subList(int, int)
446      */

447     public List JavaDoc subList(int start, int end) {
448         read();
449         return new ListProxy( bag.subList(start, end) );
450     }
451
452     public String JavaDoc toString() {
453         read();
454         return bag.toString();
455     }
456
457     /*public boolean equals(Object other) {
458         read();
459         return bag.equals(other);
460     }
461
462     public int hashCode(Object other) {
463         read();
464         return bag.hashCode();
465     }*/

466
467     public boolean entryExists(Object JavaDoc entry, int i) {
468         return entry!=null;
469     }
470
471     /**
472      * Bag does not respect the collection API and do an
473      * JVM instance comparison to do the equals.
474      * The semantic is broken not to have to initialize a
475      * collection for a simple equals() operation.
476      * @see java.lang.Object#equals(java.lang.Object)
477      */

478     public boolean equals(Object JavaDoc obj) {
479         return super.equals(obj);
480     }
481
482     /**
483      * @see java.lang.Object#hashCode()
484      */

485     public int hashCode() {
486         return super.hashCode();
487     }
488
489 }
490
Popular Tags