KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > QConObject


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o;
22
23 import com.db4o.config.*;
24 import com.db4o.foundation.*;
25 import com.db4o.inside.*;
26 import com.db4o.query.*;
27 import com.db4o.reflect.*;
28
29 /**
30  * Object constraint on queries
31  *
32  * @exclude
33  */

34 public class QConObject extends QCon {
35
36     // the constraining object
37
public Object JavaDoc i_object;
38
39     // cache for the db4o object ID
40
public int i_objectID;
41
42     // the YapClass
43
transient YapClass i_yapClass;
44
45     // needed for marshalling the request
46
public int i_yapClassID;
47
48     public QField i_field;
49
50     transient YapComparable i_comparator;
51
52     public ObjectAttribute i_attributeProvider;
53
54     private transient boolean i_selfComparison = false;
55
56     private transient boolean i_loadedFromIndex;
57
58     public QConObject() {
59         // C/S only
60
}
61
62     QConObject(Transaction a_trans, QCon a_parent, QField a_field,
63         Object JavaDoc a_object) {
64         super(a_trans);
65         i_parent = a_parent;
66         if (a_object instanceof Compare) {
67             a_object = ((Compare) a_object).compare();
68         }
69         i_object = a_object;
70         i_field = a_field;
71         associateYapClass(a_trans, a_object);
72     }
73
74     private void associateYapClass(Transaction a_trans, Object JavaDoc a_object) {
75         if (a_object == null) {
76             i_object = null;
77             i_comparator = Null.INSTANCE;
78             i_yapClass = null;
79             
80             // FIXME: Setting the YapClass to null will prevent index use
81
// If the field is typed we can guess the right one with the
82
// following line. However this does break some SODA test cases.
83
// Revisit!
84

85 // if(i_field != null){
86
// i_yapClass = i_field.getYapClass();
87
// }
88

89         } else {
90             i_yapClass = a_trans.stream()
91                 .produceYapClass(a_trans.reflector().forObject(a_object));
92             if (i_yapClass != null) {
93                 i_object = i_yapClass.getComparableObject(a_object);
94                 if (a_object != i_object) {
95                     i_attributeProvider = i_yapClass.i_config.queryAttributeProvider();
96                     i_yapClass = a_trans.stream().produceYapClass(a_trans.reflector().forObject(i_object));
97                 }
98                 if (i_yapClass != null) {
99                     i_yapClass.collectConstraints(a_trans, this, i_object,
100                         new Visitor4() {
101
102                             public void visit(Object JavaDoc obj) {
103                                 addConstraint((QCon) obj);
104                             }
105                         });
106                 } else {
107                     associateYapClass(a_trans, null);
108                 }
109             } else {
110                 associateYapClass(a_trans, null);
111             }
112         }
113     }
114     
115     public boolean canBeIndexLeaf(){
116         return (i_yapClass != null && i_yapClass.isPrimitive()) || evaluator().identity();
117     }
118     
119     public boolean canLoadByIndex(){
120         if(i_field == null){
121             return false;
122         }
123         if(i_field.i_yapField == null){
124             return false;
125         }
126         if(! i_field.i_yapField.hasIndex()){
127             return false;
128         }
129         if (!i_evaluator.supportsIndex()) {
130             return false;
131         }
132         
133         return i_field.i_yapField.canLoadByIndex();
134     }
135
136     void createCandidates(Collection4 a_candidateCollection) {
137         if (i_loadedFromIndex && ! hasChildren()) {
138             return;
139         }
140         super.createCandidates(a_candidateCollection);
141     }
142
143     boolean evaluate(QCandidate a_candidate) {
144         try {
145             return a_candidate.evaluate(this, i_evaluator);
146         } catch (Exception JavaDoc e) {
147             return false;
148         }
149     }
150
151     void evaluateEvaluationsExec(final QCandidates a_candidates,
152         boolean rereadObject) {
153         if (i_field.isSimple()) {
154             boolean hasEvaluation = false;
155             Iterator4 i = iterateChildren();
156             while (i.moveNext()) {
157                 if (i.current() instanceof QConEvaluation) {
158                     hasEvaluation = true;
159                     break;
160                 }
161             }
162             if (hasEvaluation) {
163                 a_candidates.traverse(i_field);
164                 Iterator4 j = iterateChildren();
165                 while (j.moveNext()) {
166                     ((QCon) j.current()).evaluateEvaluationsExec(a_candidates,false);
167                 }
168             }
169         }
170     }
171
172     void evaluateSelf() {
173         if(DTrace.enabled){
174             DTrace.EVALUATE_SELF.log(i_id);
175         }
176         if (i_yapClass != null) {
177             if (!(i_yapClass instanceof YapClassPrimitive)) {
178                 if (!i_evaluator.identity()) {
179                     if (i_yapClass == i_candidates.i_yapClass) {
180                         if (i_evaluator.isDefault() && (! hasJoins())) {
181                             return;
182                         }
183                     }
184                     i_selfComparison = true;
185                 }
186                 i_comparator = i_yapClass.prepareComparison(i_object);
187             }
188         }
189         super.evaluateSelf();
190         i_selfComparison = false;
191     }
192
193     void collect(QCandidates a_candidates) {
194         if (i_field.isClass()) {
195             a_candidates.traverse(i_field);
196             a_candidates.filter(i_candidates);
197         }
198     }
199
200     void evaluateSimpleExec(QCandidates a_candidates) {
201         if (i_orderID != 0 || !i_loadedFromIndex) {
202             if (i_field.isSimple() || isNullConstraint()) {
203                 a_candidates.traverse(i_field);
204                 prepareComparison(i_field);
205                 a_candidates.filter(this);
206             }
207         }
208     }
209     
210     YapComparable getComparator(QCandidate a_candidate) {
211         if (i_comparator == null) {
212             return a_candidate.prepareComparison(i_trans.stream(), i_object);
213         }
214         return i_comparator;
215     }
216
217     YapClass getYapClass() {
218         return i_yapClass;
219     }
220
221     public QField getField() {
222         return i_field;
223     }
224
225     int getObjectID() {
226         if (i_objectID == 0) {
227             i_objectID = i_trans.stream().getID1(i_object);
228             if (i_objectID == 0) {
229                 i_objectID = -1;
230             }
231         }
232         return i_objectID;
233     }
234
235     boolean hasObjectInParentPath(Object JavaDoc obj) {
236         if (obj == i_object) {
237             return true;
238         }
239         return super.hasObjectInParentPath(obj);
240     }
241
242     public int identityID() {
243         if (i_evaluator.identity()) {
244             int id = getObjectID();
245             if (id != 0) {
246                 if( !(i_evaluator instanceof QENot) ){
247                     return id;
248                 }
249             }
250         }
251         return 0;
252     }
253     
254     boolean isNullConstraint() {
255         return i_object == null;
256     }
257
258     void log(String JavaDoc indent) {
259         if (Debug.queries) {
260             super.log(indent);
261         }
262     }
263
264     String JavaDoc logObject() {
265         if (Debug.queries) {
266             if (i_object != null) {
267                 return i_object.toString();
268             }
269             return "[NULL]";
270         }
271         return "";
272     }
273
274     void marshall() {
275         super.marshall();
276         getObjectID();
277         if (i_yapClass != null) {
278             i_yapClassID = i_yapClass.getID();
279         }
280     }
281     
282     public boolean onSameFieldAs(QCon other){
283         if(! (other instanceof QConObject)){
284             return false;
285         }
286         return i_field == ((QConObject)other).i_field;
287     }
288
289     void prepareComparison(QField a_field) {
290         if (isNullConstraint() & !a_field.isArray()) {
291             i_comparator = Null.INSTANCE;
292         } else {
293             i_comparator = a_field.prepareComparison(i_object);
294         }
295     }
296
297     void removeChildrenJoins() {
298         super.removeChildrenJoins();
299         _children = null;
300     }
301
302     QCon shareParent(Object JavaDoc a_object, boolean[] removeExisting) {
303         if(i_parent == null){
304             return null;
305         }
306         Object JavaDoc obj = i_field.coerce(a_object);
307         if(obj == No4.INSTANCE){
308             return null;
309         }
310         return i_parent.addSharedConstraint(i_field, obj);
311     }
312
313     QConClass shareParentForClass(ReflectClass a_class, boolean[] removeExisting) {
314         if(i_parent == null){
315             return null;
316         }
317         if (! i_field.canHold(a_class)) {
318             return null;
319         }
320         QConClass newConstraint = new QConClass(i_trans, i_parent,i_field, a_class);
321         i_parent.addConstraint(newConstraint);
322         return newConstraint;
323     }
324
325     final Object JavaDoc translate(Object JavaDoc candidate) {
326         if (i_attributeProvider != null) {
327             i_candidates.i_trans.stream().activate1(i_candidates.i_trans,
328                 candidate);
329             return i_attributeProvider.attribute(candidate);
330         }
331         return candidate;
332     }
333
334     void unmarshall(Transaction a_trans) {
335         if (i_trans == null) {
336             super.unmarshall(a_trans);
337
338             if (i_object == null) {
339                 i_comparator = Null.INSTANCE;
340             }
341             if (i_yapClassID != 0) {
342                 i_yapClass = a_trans.stream().getYapClass(i_yapClassID);
343             }
344             if (i_field != null) {
345                 i_field.unmarshall(a_trans);
346             }
347             
348             if(i_objectID != 0){
349                 Object JavaDoc obj = a_trans.stream().getByID(i_objectID);
350                 if(obj != null){
351                     i_object = obj;
352                 }
353             }
354         }
355     }
356
357     public void visit(Object JavaDoc obj) {
358         QCandidate qc = (QCandidate) obj;
359         boolean res = true;
360         boolean processed = false;
361         if (i_selfComparison) {
362             YapClass yc = qc.readYapClass();
363             if (yc != null) {
364                 res = i_evaluator
365                     .not(i_yapClass.getHigherHierarchy(yc) == i_yapClass);
366                 processed = true;
367             }
368         }
369         if (!processed) {
370             res = evaluate(qc);
371         }
372         if (i_orderID != 0 && res) {
373             Object JavaDoc cmp = qc.value();
374             if (cmp != null && i_field != null) {
375                 YapComparable comparatorBackup = i_comparator;
376                 i_comparator = i_field.prepareComparison(qc.value());
377                 i_candidates.addOrder(new QOrder(this, qc));
378                 i_comparator = comparatorBackup.prepareComparison(i_object);
379             }
380         }
381         visit1(qc.getRoot(), this, res);
382     }
383
384     public Constraint contains() {
385         synchronized (streamLock()) {
386             i_evaluator = i_evaluator.add(new QEContains(true));
387             return this;
388         }
389     }
390
391     public Constraint equal() {
392         synchronized (streamLock()) {
393             i_evaluator = i_evaluator.add(new QEEqual());
394             return this;
395         }
396     }
397
398     public Object JavaDoc getObject() {
399         synchronized (streamLock()) {
400             return i_object;
401         }
402     }
403
404     public Constraint greater() {
405         synchronized (streamLock()) {
406             i_evaluator = i_evaluator.add(new QEGreater());
407             return this;
408         }
409     }
410
411     public Constraint identity() {
412         synchronized (streamLock()) {
413
414             int id = getObjectID();
415             if(! (id > 0)){
416                 i_objectID = 0;
417                 Exceptions4.throwRuntimeException(51);
418             }
419             
420             // TODO: this may not be correct for NOT
421
// It may be necessary to add an if(i_evaluator.identity())
422
removeChildrenJoins();
423             i_evaluator = i_evaluator.add(new QEIdentity());
424             return this;
425         }
426     }
427
428     public Constraint like() {
429         synchronized (streamLock()) {
430             i_evaluator = i_evaluator.add(new QEContains(false));
431             return this;
432         }
433     }
434
435     public Constraint smaller() {
436         synchronized (streamLock()) {
437             i_evaluator = i_evaluator.add(new QESmaller());
438             return this;
439         }
440     }
441
442     public Constraint startsWith(boolean caseSensitive) {
443         synchronized (streamLock()) {
444             i_evaluator = i_evaluator.add(new QEStartsWith(caseSensitive));
445             return this;
446         }
447     }
448
449     public Constraint endsWith(boolean caseSensitive) {
450         synchronized (streamLock()) {
451             i_evaluator = i_evaluator.add(new QEEndsWith(caseSensitive));
452             return this;
453         }
454     }
455
456     public String JavaDoc toString() {
457         if(! Debug4.prettyToStrings){
458             return super.toString();
459         }
460         String JavaDoc str = "QConObject ";
461         if (i_object != null) {
462             str += i_object.toString();
463         }
464         return str;
465     }
466 }
Popular Tags