KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > odmg > collections > DSetImpl


1 package org.apache.ojb.odmg.collections;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.io.Serializable JavaDoc;
19 import java.util.AbstractSet JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Vector JavaDoc;
24 import java.util.Collection JavaDoc;
25
26 import org.apache.ojb.broker.PBKey;
27 import org.apache.ojb.broker.PersistenceBroker;
28 import org.apache.ojb.broker.PersistenceBrokerAware;
29 import org.apache.ojb.broker.PersistenceBrokerException;
30 import org.apache.ojb.broker.ManageableCollection;
31 import org.apache.ojb.broker.core.ValueContainer;
32 import org.apache.ojb.broker.metadata.ClassDescriptor;
33 import org.apache.ojb.broker.metadata.FieldDescriptor;
34 import org.apache.ojb.broker.query.Criteria;
35 import org.apache.ojb.broker.query.Query;
36 import org.apache.ojb.broker.query.QueryByCriteria;
37 import org.apache.ojb.broker.util.logging.Logger;
38 import org.apache.ojb.broker.util.logging.LoggerFactory;
39 import org.apache.ojb.odmg.PBCapsule;
40 import org.apache.ojb.odmg.TransactionImpl;
41 import org.apache.ojb.odmg.TxManagerFactory;
42 import org.apache.ojb.odmg.RuntimeObject;
43 import org.apache.ojb.odmg.oql.OQLQueryImpl;
44 import org.odmg.DCollection;
45 import org.odmg.DList;
46 import org.odmg.DSet;
47 import org.odmg.ODMGRuntimeException;
48 import org.odmg.OQLQuery;
49 import org.odmg.Transaction;
50
51
52 /**
53  *
54  */

55 public class DSetImpl extends AbstractSet JavaDoc implements DSet, Serializable JavaDoc, PersistenceBrokerAware, ManageableCollection
56 {
57     private static final long serialVersionUID = -4459673364598652639L;
58
59     private transient Logger log;
60
61     private Integer JavaDoc id;
62     private List JavaDoc elements;
63
64     private PBKey pbKey;
65
66     /**
67      * Used by PB-Kernel to instantiate ManageableCollections
68      * FOR INTERNAL USE ONLY
69      */

70     public DSetImpl()
71     {
72         super();
73         elements = new ArrayList JavaDoc();
74 // if(getTransaction() == null)
75
// {
76
// throw new TransactionNotInProgressException("Materialization of DCollection instances must be done" +
77
// " within a odmg-tx");
78
// }
79
getPBKey();
80     }
81
82     /**
83      * DSetImpl constructor comment.
84      */

85     public DSetImpl(PBKey pbKey)
86     {
87         this();
88         this.pbKey = pbKey;
89     }
90
91     protected Logger getLog()
92     {
93         if (log == null)
94         {
95             log = LoggerFactory.getLogger(DSetImpl.class);
96         }
97         return log;
98     }
99
100     private DSetEntry prepareEntry(Object JavaDoc obj)
101     {
102         return new DSetEntry(this, obj);
103     }
104
105     protected TransactionImpl getTransaction()
106     {
107         return TxManagerFactory.instance().getTransaction();
108     }
109
110     protected boolean checkForOpenTransaction(TransactionImpl tx)
111     {
112         boolean result = false;
113         if(tx != null && tx.isOpen())
114         {
115             result = true;
116         }
117         return result;
118     }
119
120     public PBKey getPBKey()
121     {
122         if(pbKey == null)
123         {
124             TransactionImpl tx = getTransaction();
125             if(tx != null && tx.isOpen())
126             {
127                 pbKey = tx.getBroker().getPBKey();
128             }
129         }
130         return pbKey;
131     }
132
133     public void setPBKey(PBKey pbKey)
134     {
135         this.pbKey = pbKey;
136     }
137
138     public boolean remove(Object JavaDoc o)
139     {
140         return super.remove(o);
141     }
142
143     public boolean removeAll(Collection JavaDoc c)
144     {
145         return super.removeAll(c);
146     }
147
148     public boolean add(Object JavaDoc o)
149     {
150         if (!this.contains(o))
151         {
152             DSetEntry entry = prepareEntry(o);
153             elements.add(entry);
154             // if we are in a transaction: get locks !
155
TransactionImpl tx = getTransaction();
156             if ((tx != null) && (tx.isOpen()))
157             {
158                 List JavaDoc regList = tx.getRegistrationList();
159                 RuntimeObject rt = new RuntimeObject(this, tx);
160                 tx.lockAndRegister(rt, Transaction.WRITE, false, regList);
161
162                 rt = new RuntimeObject(o, tx);
163                 tx.lockAndRegister(rt, Transaction.READ, regList);
164
165                 rt = new RuntimeObject(entry, tx, true);
166                 tx.lockAndRegister(rt, Transaction.WRITE, false, regList);
167             }
168             return true;
169         }
170         else
171         {
172             return false;
173         }
174     }
175
176     /**
177      * Create a new <code>DSet</code> object that contains the elements of this
178      * collection minus the elements in <code>otherSet</code>.
179      * @param otherSet A set containing elements that should not be in the result set.
180      * @return A newly created <code>DSet</code> instance that contains the elements
181      * of this set minus those elements in <code>otherSet</code>.
182      */

183     public DSet difference(DSet otherSet)
184     {
185         DSetImpl result = new DSetImpl(getPBKey());
186         Iterator JavaDoc iter = this.iterator();
187         while (iter.hasNext())
188         {
189             Object JavaDoc candidate = iter.next();
190             if (!otherSet.contains(candidate))
191             {
192                 result.add(candidate);
193             }
194         }
195         return result;
196     }
197
198     /**
199      * Determines whether there is an element of the collection that evaluates to true
200      * for the predicate.
201      * @param predicate An OQL boolean query predicate.
202      * @return True if there is an element of the collection that evaluates to true
203      * for the predicate, otherwise false.
204      * @exception org.odmg.QueryInvalidException The query predicate is invalid.
205      */

206     public boolean existsElement(String JavaDoc predicate) throws org.odmg.QueryInvalidException
207     {
208         DList results = (DList) this.query(predicate);
209         if (results == null || results.size() == 0)
210             return false;
211         else
212             return true;
213     }
214
215     public List JavaDoc getElements()
216     {
217         return elements;
218     }
219
220     public void setElements(List JavaDoc elements)
221     {
222         this.elements = elements;
223     }
224
225     public Integer JavaDoc getId()
226     {
227         return id;
228     }
229
230     /**
231      * Create a new <code>DSet</code> object that is the set intersection of this
232      * <code>DSet</code> object and the set referenced by <code>otherSet</code>.
233      * @param otherSet The other set to be used in the intersection operation.
234      * @return A newly created <code>DSet</code> instance that contains the
235      * intersection of the two sets.
236      */

237     public DSet intersection(DSet otherSet)
238     {
239         DSet union = this.union(otherSet);
240         DSetImpl result = new DSetImpl(getPBKey());
241         Iterator JavaDoc iter = union.iterator();
242         while (iter.hasNext())
243         {
244             Object JavaDoc candidate = iter.next();
245             if (this.contains(candidate) && otherSet.contains(candidate))
246             {
247                 result.add(candidate);
248             }
249         }
250         return result;
251     }
252
253     /**
254      * Returns an iterator over the elements in this collection. There are no
255      * guarantees concerning the order in which the elements are returned
256      * (unless this collection is an instance of some class that provides a
257      * guarantee).
258      *
259      * @return an <tt>Iterator</tt> over the elements in this collection
260      */

261     public Iterator JavaDoc iterator()
262     {
263         return new DSetIterator(this);
264     }
265
266     /**
267      * Determine whether this set is a proper subset of the set referenced by
268      * <code>otherSet</code>.
269      * @param otherSet Another set.
270      * @return True if this set is a proper subset of the set referenced by
271      * <code>otherSet</code>, otherwise false.
272      */

273     public boolean properSubsetOf(org.odmg.DSet otherSet)
274     {
275         return (this.size() > 0 && this.size() < otherSet.size() && this.subsetOf(otherSet));
276     }
277
278     /**
279      * Determine whether this set is a proper superset of the set referenced by
280      * <code>otherSet</code>.
281      * @param otherSet Another set.
282      * @return True if this set is a proper superset of the set referenced by
283      * <code>otherSet</code>, otherwise false.
284      */

285     public boolean properSupersetOf(org.odmg.DSet otherSet)
286     {
287         return (otherSet.size() > 0 && otherSet.size() < this.size() && this.supersetOf(otherSet));
288     }
289
290     /**
291      * Evaluate the boolean query predicate for each element of the collection and
292      * return a new collection that contains each element that evaluated to true.
293      * @param predicate An OQL boolean query predicate.
294      * @return A new collection containing the elements that evaluated true for the predicate.
295      * @exception org.odmg.QueryInvalidException The query predicate is invalid.
296      */

297     public DCollection query(String JavaDoc predicate) throws org.odmg.QueryInvalidException
298     {
299         // 1.build complete OQL statement
300
String JavaDoc oql = "select all from java.lang.Object where " + predicate;
301         TransactionImpl tx = getTransaction();
302
303         OQLQuery predicateQuery = tx.getImplementation().newOQLQuery();
304
305         PBCapsule capsule = new PBCapsule(tx.getImplementation().getCurrentPBKey(), tx);
306         PersistenceBroker broker = capsule.getBroker();
307
308         try
309         {
310             predicateQuery.create(oql);
311             Query pQ = ((OQLQueryImpl) predicateQuery).getQuery();
312             Criteria pCrit = pQ.getCriteria();
313
314             Criteria allElementsCriteria = this.getPkCriteriaForAllElements(broker);
315             // join selection of elements with predicate criteria:
316
pCrit.addAndCriteria(allElementsCriteria);
317             Class JavaDoc clazz = this.getElementsExtentClass(broker);
318             Query q = new QueryByCriteria(clazz, pCrit);
319             if (log.isDebugEnabled()) log.debug(q.toString());
320             // 2. perfom query
321
return (DSetImpl) broker.getCollectionByQuery(DSetImpl.class, q);
322         }
323         catch (PersistenceBrokerException e)
324         {
325             throw new ODMGRuntimeException(e.getMessage());
326         }
327         finally
328         {
329             capsule.destroy();
330         }
331     }
332
333     private Criteria getPkCriteriaForAllElements(PersistenceBroker broker)
334     {
335         try
336         {
337             Criteria crit = null;
338             for (int i = 0; i < elements.size(); i++)
339             {
340                 DListEntry entry = (DListEntry) elements.get(i);
341                 Object JavaDoc obj = entry.getRealSubject();
342                 ClassDescriptor cld = broker.getClassDescriptor(obj.getClass());
343
344                 FieldDescriptor[] pkFields = cld.getPkFields();
345                 ValueContainer[] pkValues = broker.serviceBrokerHelper().getKeyValues(cld, obj);
346
347                 Criteria criteria = new Criteria();
348                 for (int j = 0; j < pkFields.length; j++)
349                 {
350                     FieldDescriptor fld = pkFields[j];
351                     criteria.addEqualTo(fld.getPersistentField().getName(), pkValues[j].getValue());
352                 }
353
354                 if (crit == null)
355                     crit = criteria;
356                 else
357                     crit.addOrCriteria(criteria);
358             }
359             return crit;
360         }
361         catch (PersistenceBrokerException e)
362         {
363             log.error(e);
364             return null;
365         }
366     }
367
368     private Class JavaDoc getElementsExtentClass(PersistenceBroker broker) throws PersistenceBrokerException
369     {
370         // we ll have to compute the most general extent class here !!!
371
DListEntry entry = (DListEntry) elements.get(0);
372         Class JavaDoc elementsClass = entry.getRealSubject().getClass();
373         Class JavaDoc extentClass = broker.getTopLevelClass(elementsClass);
374         return extentClass;
375     }
376
377
378     /**
379      * Access all of the elements of the collection that evaluate to true for the
380      * provided query predicate.
381      * @param predicate An OQL boolean query predicate.
382      * @return An iterator used to iterate over the elements that evaluated true for the predicate.
383      * @exception org.odmg.QueryInvalidException The query predicate is invalid.
384      */

385     public Iterator JavaDoc select(String JavaDoc predicate) throws org.odmg.QueryInvalidException
386     {
387         return this.query(predicate).iterator();
388     }
389
390     /**
391      * Selects the single element of the collection for which the provided OQL query
392      * predicate is true.
393      * @param predicate An OQL boolean query predicate.
394      * @return The element that evaluates to true for the predicate. If no element
395      * evaluates to true, null is returned.
396      * @exception org.odmg.QueryInvalidException The query predicate is invalid.
397      */

398     public Object JavaDoc selectElement(String JavaDoc predicate) throws org.odmg.QueryInvalidException
399     {
400         return ((DList) this.query(predicate)).get(0);
401     }
402
403     /**
404      * Sets the elements.
405      * @param elements The elements to set
406      */

407     public void setElements(Vector JavaDoc elements)
408     {
409         this.elements = elements;
410     }
411
412     /**
413      * Sets the id.
414      * @param id The id to set
415      */

416     public void setId(Integer JavaDoc id)
417     {
418         this.id = id;
419     }
420
421     /**
422      * Returns the number of elements in this collection. If this collection
423      * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
424      * <tt>Integer.MAX_VALUE</tt>.
425      *
426      * @return the number of elements in this collection
427      */

428     public int size()
429     {
430         return elements.size();
431     }
432
433     /**
434      * Determine whether this set is a subset of the set referenced by <code>otherSet</code>.
435      * @param otherSet Another set.
436      * @return True if this set is a subset of the set referenced by <code>otherSet</code>,
437      * otherwise false.
438      */

439     public boolean subsetOf(DSet otherSet)
440     {
441         return otherSet.containsAll(this);
442     }
443
444     /**
445      * Determine whether this set is a superset of the set referenced by <code>otherSet</code>.
446      * @param otherSet Another set.
447      * @return True if this set is a superset of the set referenced by <code>otherSet</code>,
448      * otherwise false.
449      */

450     public boolean supersetOf(DSet otherSet)
451     {
452         return this.containsAll(otherSet);
453     }
454
455     /**
456      * Create a new <code>DSet</code> object that is the set union of this
457      * <code>DSet</code> object and the set referenced by <code>otherSet</code>.
458      * @param otherSet The other set to be used in the union operation.
459      * @return A newly created <code>DSet</code> instance that contains the union of the two sets.
460      */

461     public DSet union(DSet otherSet)
462     {
463         DSetImpl result = new DSetImpl(getPBKey());
464         result.addAll(this);
465         result.addAll(otherSet);
466         return result;
467     }
468
469
470     //***************************************************************
471
// ManageableCollection interface
472
//***************************************************************
473

474     /**
475      * add a single Object to the Collection. This method is used during reading Collection elements
476      * from the database. Thus it is is save to cast anObject to the underlying element type of the
477      * collection.
478      */

479     public void ojbAdd(Object JavaDoc anObject)
480     {
481         DSetEntry entry = prepareEntry(anObject);
482         entry.setPosition(elements.size());
483         elements.add(entry);
484     }
485
486     /**
487      * adds a Collection to this collection. Used in reading Extents from the Database.
488      * Thus it is save to cast otherCollection to this.getClass().
489      */

490     public void ojbAddAll(ManageableCollection otherCollection)
491     {
492         // don't use this to avoid locking
493
// this.addAll((DListImpl) otherCollection);
494
Iterator JavaDoc it = otherCollection.ojbIterator();
495         while (it.hasNext())
496         {
497             ojbAdd(it.next());
498         }
499     }
500
501     public void afterStore(PersistenceBroker broker) throws PersistenceBrokerException
502     {
503     }
504
505     /**
506      * returns an Iterator over all elements in the collection. Used during store and delete Operations.
507      * If the implementor does not return an iterator over ALL elements, OJB cannot store and delete all elements properly.
508      */

509     public Iterator JavaDoc ojbIterator()
510     {
511         return this.iterator();
512     }
513
514     //***************************************************************
515
// PersistenceBrokerAware interface
516
//***************************************************************
517

518     /**
519      * prepare itself for persistence. Each DList entry generates an
520      * {@link org.apache.ojb.broker.Identity} for the wrapped persistent
521      * object.
522      */

523     public void beforeInsert(PersistenceBroker broker) throws PersistenceBrokerException
524     {
525 // Iterator it = elements.iterator();
526
// DSetEntry entry;
527
// while (it.hasNext())
528
// {
529
// entry = (DSetEntry) it.next();
530
// entry.prepareForPersistency(broker);
531
// }
532
}
533
534     /**
535      * noop
536      */

537     public void beforeUpdate(PersistenceBroker broker) throws PersistenceBrokerException
538     {
539     }
540
541     /**
542      * noop
543      */

544     public void beforeDelete(PersistenceBroker broker) throws PersistenceBrokerException
545     {
546     }
547
548     /**
549      * noop
550      */

551     public void afterUpdate(PersistenceBroker broker) throws PersistenceBrokerException
552     {
553     }
554
555     /**
556      * noop
557      */

558     public void afterInsert(PersistenceBroker broker) throws PersistenceBrokerException
559     {
560     }
561
562     /**
563      * noop
564      */

565     public void afterDelete(PersistenceBroker broker) throws PersistenceBrokerException
566     {
567     }
568
569     /**
570      * noop
571      */

572     public void afterLookup(PersistenceBroker broker) throws PersistenceBrokerException
573     {
574     }
575 }
576
Popular Tags