KickJava   Java API By Example, From Geeks To Geeks.

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


1 //$Id: PersistentIdentifierBag.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.HashMap JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.ListIterator JavaDoc;
13
14 import org.hibernate.EntityMode;
15 import org.hibernate.HibernateException;
16 import org.hibernate.loader.CollectionAliases;
17 import org.hibernate.engine.SessionImplementor;
18 import org.hibernate.persister.collection.CollectionPersister;
19 import org.hibernate.type.Type;
20
21 /**
22  * An <tt>IdentifierBag</tt> implements "bag" semantics more efficiently than
23  * a regular <tt>Bag</tt> by adding a synthetic identifier column to the
24  * table. This identifier is unique for all rows in the table, allowing very
25  * efficient updates and deletes. The value of the identifier is never exposed
26  * to the application.<br>
27  * <br>
28  * <tt>IdentifierBag</tt>s may not be used for a many-to-one association.
29  * Furthermore, there is no reason to use <tt>inverse="true"</tt>.
30  *
31  * @author Gavin King
32  */

33 public class PersistentIdentifierBag extends AbstractPersistentCollection implements java.util.List JavaDoc {
34
35     protected java.util.List JavaDoc values; //element
36
protected java.util.Map JavaDoc identifiers; //index -> id
37

38     public PersistentIdentifierBag(SessionImplementor session) {
39         super(session);
40     }
41
42     public PersistentIdentifierBag() {} //needed for SOAP libraries, etc
43

44     public PersistentIdentifierBag(SessionImplementor session, java.util.Collection JavaDoc coll) {
45         super(session);
46         if (coll instanceof java.util.List JavaDoc) {
47             values = (java.util.List JavaDoc) coll;
48         }
49         else {
50             values = new ArrayList JavaDoc();
51             Iterator JavaDoc iter = coll.iterator();
52             while ( iter.hasNext() ) {
53                 values.add( iter.next() );
54             }
55         }
56         setInitialized();
57         setDirectlyAccessible(true);
58         identifiers = new HashMap JavaDoc();
59     }
60
61     public void initializeFromCache(CollectionPersister persister, Serializable JavaDoc disassembled, Object JavaDoc owner)
62     throws HibernateException {
63         beforeInitialize(persister);
64         Serializable JavaDoc[] array = (Serializable JavaDoc[]) disassembled;
65         for ( int i=0; i<array.length; i+=2 ) {
66             identifiers.put(
67                 new Integer JavaDoc(i/2),
68                 persister.getIdentifierType().assemble( array[i], getSession(), owner )
69             );
70             values.add( persister.getElementType().assemble( array[i+1], getSession(), owner ) );
71         }
72     }
73
74     public Object JavaDoc getIdentifier(Object JavaDoc entry, int i) {
75         return identifiers.get( new Integer JavaDoc(i) );
76     }
77     
78     public boolean isWrapper(Object JavaDoc collection) {
79         return values==collection;
80     }
81     
82     public boolean add(Object JavaDoc o) {
83         write();
84         values.add(o);
85         return true;
86     }
87
88     public void clear() {
89         write();
90         values.clear();
91         identifiers.clear();
92     }
93
94     public boolean contains(Object JavaDoc o) {
95         read();
96         return values.contains(o);
97     }
98
99     public boolean containsAll(Collection JavaDoc c) {
100         read();
101         return values.containsAll(c);
102     }
103
104     public boolean isEmpty() {
105         read();
106         return values.isEmpty();
107     }
108
109     public Iterator JavaDoc iterator() {
110         read();
111         return new IteratorProxy( values.iterator() );
112     }
113
114     public boolean remove(Object JavaDoc o) {
115         write();
116         int index = values.indexOf(o);
117         if (index>=0) {
118             beforeRemove(index);
119             values.remove(index);
120             return true;
121         }
122         else {
123             return false;
124         }
125     }
126
127     public boolean removeAll(Collection JavaDoc c) {
128         if ( c.size()>0 ) {
129             //write();
130
//return values.removeAll(c);
131
boolean result = false;
132             Iterator JavaDoc iter = c.iterator();
133             while ( iter.hasNext() ) {
134                 if ( remove( iter.next() ) ) result=true;
135             }
136             return result;
137         }
138         else {
139             return false;
140         }
141     }
142
143     public boolean retainAll(Collection JavaDoc c) {
144         write();
145         return values.retainAll(c);
146     }
147
148     public int size() {
149         read();
150         return values.size();
151     }
152
153     public Object JavaDoc[] toArray() {
154         read();
155         return values.toArray();
156     }
157
158     public Object JavaDoc[] toArray(Object JavaDoc[] a) {
159         read();
160         return values.toArray(a);
161     }
162
163     public void beforeInitialize(CollectionPersister persister) {
164         identifiers = new HashMap JavaDoc();
165         values = new ArrayList JavaDoc();
166     }
167
168     public Serializable JavaDoc disassemble(CollectionPersister persister)
169     throws HibernateException {
170
171         Serializable JavaDoc[] result = new Serializable JavaDoc[ values.size() * 2 ];
172         int i=0;
173         for (int j=0; j< values.size(); j++) {
174             Object JavaDoc value = values.get(j);
175             result[i++] = persister.getIdentifierType().disassemble( identifiers.get( new Integer JavaDoc(j) ), getSession(), null );
176             result[i++] = persister.getElementType().disassemble( value, getSession(), null );
177         }
178         return result;
179     }
180
181     public boolean empty() {
182         return values.isEmpty();
183     }
184
185     public Iterator JavaDoc entries(CollectionPersister persister) {
186         return values.iterator();
187     }
188
189     public boolean entryExists(Object JavaDoc entry, int i) {
190         return entry!=null;
191     }
192
193     public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
194         Type elementType = persister.getElementType();
195         java.util.Map JavaDoc snap = (java.util.Map JavaDoc) getSnapshot();
196         if ( snap.size()!= values.size() ) return false;
197         for ( int i=0; i<values.size(); i++ ) {
198             Object JavaDoc value = values.get(i);
199             Object JavaDoc id = identifiers.get( new Integer JavaDoc(i) );
200             if (id==null) return false;
201             Object JavaDoc old = snap.get(id);
202             if ( elementType.isDirty( old, value, getSession() ) ) return false;
203         }
204         return true;
205     }
206
207     public boolean isSnapshotEmpty(Serializable JavaDoc snapshot) {
208         return ( (java.util.Map JavaDoc) snapshot ).isEmpty();
209     }
210     
211     public Iterator JavaDoc getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
212         java.util.Map JavaDoc snap = (java.util.Map JavaDoc) getSnapshot();
213         java.util.List JavaDoc deletes = new ArrayList JavaDoc( snap.keySet() );
214         for ( int i=0; i<values.size(); i++ ) {
215             if ( values.get(i)!=null ) deletes.remove( identifiers.get( new Integer JavaDoc(i) ) );
216         }
217         return deletes.iterator();
218     }
219
220     public Object JavaDoc getIndex(Object JavaDoc entry, int i, CollectionPersister persister) {
221         throw new UnsupportedOperationException JavaDoc("Bags don't have indexes");
222     }
223
224     public Object JavaDoc getElement(Object JavaDoc entry) {
225         return entry;
226     }
227
228     public Object JavaDoc getSnapshotElement(Object JavaDoc entry, int i) {
229         java.util.Map JavaDoc snap = (java.util.Map JavaDoc) getSnapshot();
230         Object JavaDoc id = identifiers.get( new Integer JavaDoc(i) );
231         return snap.get(id);
232     }
233
234     public boolean needsInserting(Object JavaDoc entry, int i, Type elemType)
235         throws HibernateException {
236
237         java.util.Map JavaDoc snap = (java.util.Map JavaDoc) getSnapshot();
238         Object JavaDoc id = identifiers.get( new Integer JavaDoc(i) );
239         return entry!=null && ( id==null || snap.get(id)==null );
240     }
241
242     public boolean needsUpdating(Object JavaDoc entry, int i, Type elemType) throws HibernateException {
243
244         if (entry==null) return false;
245         java.util.Map JavaDoc snap = (java.util.Map JavaDoc) getSnapshot();
246         Object JavaDoc id = identifiers.get( new Integer JavaDoc(i) );
247         if (id==null) return false;
248         Object JavaDoc old = snap.get(id);
249         return old!=null && elemType.isDirty( old, entry, getSession() );
250     }
251
252
253     public Object JavaDoc readFrom(
254         ResultSet JavaDoc rs,
255         CollectionPersister persister,
256         CollectionAliases descriptor,
257         Object JavaDoc owner)
258         throws HibernateException, SQLException JavaDoc {
259
260         Object JavaDoc element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
261         Object JavaDoc old = identifiers.put(
262             new Integer JavaDoc( values.size() ),
263             persister.readIdentifier( rs, descriptor.getSuffixedIdentifierAlias(), getSession() )
264         );
265         if ( old==null ) values.add(element); //maintain correct duplication if loaded in a cartesian product
266
return element;
267     }
268
269     public Serializable JavaDoc getSnapshot(CollectionPersister persister)
270         throws HibernateException {
271         
272         EntityMode entityMode = getSession().getEntityMode();
273         
274         HashMap JavaDoc map = new HashMap JavaDoc( values.size() );
275         Iterator JavaDoc iter = values.iterator();
276         int i=0;
277         while ( iter.hasNext() ) {
278             Object JavaDoc value = iter.next();
279             map.put(
280                 identifiers.get( new Integer JavaDoc(i++) ),
281                 persister.getElementType().deepCopy(value, entityMode, persister.getFactory())
282             );
283         }
284         return map;
285     }
286
287     public Collection JavaDoc getOrphans(Serializable JavaDoc snapshot, String JavaDoc entityName) throws HibernateException {
288         java.util.Map JavaDoc sn = (java.util.Map JavaDoc) snapshot;
289         return getOrphans( sn.values(), values, entityName, getSession() );
290     }
291
292     public void preInsert(CollectionPersister persister) throws HibernateException {
293         Iterator JavaDoc iter = values.iterator();
294         int i=0;
295         while ( iter.hasNext() ) {
296             Object JavaDoc entry = iter.next();
297             Integer JavaDoc loc = new Integer JavaDoc(i++);
298             if ( !identifiers.containsKey(loc) ) { //TODO: native ids
299
Serializable JavaDoc id = persister.getIdentifierGenerator().generate( getSession(), entry );
300                 identifiers.put(loc, id);
301             }
302         }
303     }
304
305     public void add(int index, Object JavaDoc element) {
306         write();
307         beforeAdd(index);
308         values.add(index, element);
309     }
310
311     public boolean addAll(int index, Collection JavaDoc c) {
312         if ( c.size()>0 ) {
313             //write();
314
//return values.addAll(index, c);
315
Iterator JavaDoc iter = c.iterator();
316             while ( iter.hasNext() ) add( index++, iter.next() );
317             return true;
318         }
319         else {
320             return false;
321         }
322     }
323
324     public Object JavaDoc get(int index) {
325         read();
326         return values.get(index);
327     }
328
329     public int indexOf(Object JavaDoc o) {
330         read();
331         return values.indexOf(o);
332     }
333
334     public int lastIndexOf(Object JavaDoc o) {
335         read();
336         return values.lastIndexOf(o);
337     }
338
339     public ListIterator JavaDoc listIterator() {
340         read();
341         return new ListIteratorProxy( values.listIterator() );
342     }
343
344     public ListIterator JavaDoc listIterator(int index) {
345         read();
346         return new ListIteratorProxy( values.listIterator(index) );
347     }
348
349     private void beforeRemove(int index) {
350         Object JavaDoc removedId = identifiers.get( new Integer JavaDoc(index) );
351         int last = values.size()-1;
352         for ( int i=index; i<last; i++ ) {
353             Object JavaDoc id = identifiers.get( new Integer JavaDoc(i+1) );
354             if ( id==null ) {
355                 identifiers.remove( new Integer JavaDoc(i) );
356             }
357             else {
358                 identifiers.put( new Integer JavaDoc(i), id );
359             }
360         }
361         identifiers.put( new Integer JavaDoc(last), removedId );
362     }
363
364     private void beforeAdd(int index) {
365         for ( int i=index; i<values.size(); i++ ) {
366             identifiers.put( new Integer JavaDoc(i+1), identifiers.get( new Integer JavaDoc(i) ) );
367         }
368         identifiers.remove( new Integer JavaDoc(index) );
369     }
370
371     public Object JavaDoc remove(int index) {
372         write();
373         beforeRemove(index);
374         return values.remove(index);
375     }
376
377     public Object JavaDoc set(int index, Object JavaDoc element) {
378         write();
379         return values.set(index, element);
380     }
381
382     public List JavaDoc subList(int fromIndex, int toIndex) {
383         read();
384         return new ListProxy( values.subList(fromIndex, toIndex) );
385     }
386
387     public boolean addAll(Collection JavaDoc c) {
388         if ( c.size()> 0 ) {
389             write();
390             return values.addAll(c);
391         }
392         else {
393             return false;
394         }
395     }
396
397     public void afterRowInsert(
398         CollectionPersister persister,
399         Object JavaDoc entry,
400         int i)
401         throws HibernateException {
402         //TODO: if we are using identity columns, fetch the identifier
403
}
404
405 }
406
Popular Tags