KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > implementation > BasicQuery


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10
11 package org.mmbase.bridge.implementation;
12
13 import java.util.*;
14 import org.mmbase.bridge.util.Queries;
15 import org.mmbase.cache.CachePolicy;
16 import org.mmbase.module.core.*;
17 import org.mmbase.module.corebuilders.*;
18 import org.mmbase.storage.search.*;
19 import org.mmbase.storage.search.implementation.*;
20 import org.mmbase.storage.search.implementation.database.BasicSqlHandler;
21 import org.mmbase.bridge.*;
22 import org.mmbase.util.logging.*;
23 import org.mmbase.security.Authorization;
24
25 /**
26  * 'Basic' implementation of bridge Query. Wraps a 'BasicSearchQuery' from core.
27  *
28  * This implementation is actually ussuable with other implementations of bridge too, because it has the public constructor:
29  * {@link #BasicQuery(Cloud, BasicSearchQuery)}.
30  *
31  * @author Michiel Meeuwissen
32  * @version $Id: BasicQuery.java,v 1.61 2006/07/27 13:12:40 michiel Exp $
33  * @since MMBase-1.7
34  * @see org.mmbase.storage.search.implementation.BasicSearchQuery
35  */

36 public class BasicQuery implements Query {
37
38     private static final Logger log = Logging.getLoggerInstance(BasicQuery.class);
39
40     /**
41      * Whether this Query was used already. If it is used, it may not be changed any more.
42      */

43     protected boolean used = false;
44
45     /**
46      * Whether this Query is aggregating.
47      * @todo this member is in BasicSearchQuery too (but private).
48      */

49     protected boolean aggregating = false; // ugly ugly, this member is in BasicSearchQuery too (but private).
50

51     /**
52      * Whether this Query is cacheable.
53      */

54     protected CachePolicy cachePolicy = CachePolicy.ALWAYS;
55
56     /**
57      * The QueryCheck object associated with this Query, or null if no such object was determined yet.
58      */

59     protected Authorization.QueryCheck queryCheck = null;
60
61     /**
62      * If a the contraint was made 'secure', in insecureConstraint the original Constraint is
63      * stored. This object is null if either the queryCheck object is not yet determined, or the
64      * orignal query did not have constraints.
65      */

66     protected Constraint insecureConstraint = null;
67
68
69     private HashMap aliasSequences = new HashMap(); // must be HashMap because cloneable
70
// to make unique table aliases. This is similar impl. as in core. Why should it be at all....
71

72
73     /**
74      * The core query which is 'wrapped'
75      */

76     protected BasicSearchQuery query;
77
78     /**
79      * reference to the cloud.
80      */

81     protected Cloud cloud;
82
83
84     /**
85      * The implicitely added 'extra' fields. These are removed if the query becomes 'distinct'. So,
86      * you can e.g. not do element= on a distinct query result.
87      */

88     protected List implicitFields = new ArrayList();
89
90     /**
91      * The explicitely added 'extra' fields. Because you explicitely added those, they will not be removed if the query becomes 'distinct'.
92      */

93     protected List explicitFields = new ArrayList();
94
95     BasicQuery(Cloud c) {
96         query = new BasicSearchQuery();
97         cloud = c;
98     }
99
100     BasicQuery(Cloud c, boolean aggregating) {
101         query = new BasicSearchQuery(aggregating);
102         this.aggregating = aggregating;
103         cloud = c;
104     }
105
106     public BasicQuery(Cloud c, BasicSearchQuery q) { // public for org.mmbase.bridge.util
107
query = q;
108         cloud = c;
109         this.aggregating = q.isAggregating();
110     }
111
112
113     public BasicSearchQuery getQuery() {
114         return query;
115     }
116
117     protected void createNewQuery() {
118         query = new BasicSearchQuery();
119     }
120
121
122     // SearchQuery impl:
123

124     public List getSteps() {
125         return query.getSteps();
126     }
127     public List getFields() {
128         return query.getFields();
129     }
130     public Constraint getConstraint() {
131         return query.getConstraint();
132     }
133
134     // bridge.Query impl
135
public Constraint getCleanConstraint() {
136         if (queryCheck != null) {
137             return insecureConstraint;
138         } else {
139             return query.getConstraint();
140         }
141     }
142
143     // more SearchQuery impl
144
public int getMaxNumber() {
145         return query.getMaxNumber();
146     }
147     public int getOffset() {
148         return query.getOffset();
149     }
150     public List getSortOrders() {
151         return query.getSortOrders();
152     }
153     public boolean isDistinct() {
154         return query.isDistinct();
155     }
156
157     // bridge.Query impl.:
158

159     public boolean isAggregating() {
160         return aggregating;
161     }
162
163     public CachePolicy getCachePolicy() {
164         return cachePolicy;
165     }
166
167     public void setCachePolicy(CachePolicy policy) {
168         this.cachePolicy = policy;
169     }
170
171     /**
172      * @since MMBase-1.7.1
173      */

174     protected void removeSecurityConstraintFromClone(BasicSearchQuery clone) {
175         if (log.isDebugEnabled()) {
176             log.debug("Removing " + queryCheck + " FROM " + clone);
177         }
178         if (queryCheck != null) {
179             Constraint secureConstraint = queryCheck.getConstraint();
180             if (secureConstraint != null) {
181                 Constraint constraint = clone.getConstraint();
182                 // remove it from clone (by modifying the 'cloned' constraint)
183
if (secureConstraint.equals(constraint)) {
184                     clone.setConstraint(null);
185                 } else { // must be part of the composite constraint
186
BasicCompositeConstraint compConstraint = (BasicCompositeConstraint) constraint;
187                     compConstraint.removeChild(secureConstraint); // remove it
188
if (compConstraint.getChilds().size() == 0) { // no need to let it then
189
clone.setConstraint(null);
190                     }
191                     if (compConstraint.getChilds().size() == 1) { // no need to let it composite then
192
Constraint newConstraint = (Constraint) compConstraint.getChilds().get(0);
193                         clone.setConstraint(newConstraint);
194                     }
195                 }
196             }
197         }
198
199     }
200
201     public Object JavaDoc clone() { // also works for descendants (NodeQuery)
202
try {
203             BasicQuery clone = (BasicQuery) super.clone();
204             clone.query = (BasicSearchQuery) query.clone();
205             clone.aliasSequences = (HashMap) aliasSequences.clone();
206             removeSecurityConstraintFromClone(clone.query);
207             clone.insecureConstraint = null;
208             clone.queryCheck = null;
209             clone.used = false;
210             return clone;
211         } catch (CloneNotSupportedException JavaDoc e) {
212             // cannot happen
213
throw new InternalError JavaDoc(e.toString());
214         }
215     }
216     public Query aggregatingClone() {
217         BasicSearchQuery bsq = new BasicSearchQuery(query, BasicSearchQuery.COPY_AGGREGATING);
218         removeSecurityConstraintFromClone(bsq);
219         BasicQuery clone = new BasicQuery(cloud, bsq);
220         clone.used = false;
221         clone.aggregating = true;
222         return clone;
223     }
224
225     public Query cloneWithoutFields() {
226         BasicSearchQuery bsq = new BasicSearchQuery(query, BasicSearchQuery.COPY_WITHOUTFIELDS);
227         removeSecurityConstraintFromClone(bsq);
228         BasicQuery clone = new BasicQuery(cloud, bsq);
229         clone.used = false;
230         clone.aggregating = false;
231         return clone;
232     }
233
234     /**
235      * Creates a unique alias for this Query based on a given base String
236      */

237     protected String JavaDoc createAlias(String JavaDoc name) {
238         if (used) throw new BridgeException("Query was used already");
239         Integer JavaDoc seq = (Integer JavaDoc) aliasSequences.get(name);
240         if (seq == null) {
241             seq = new Integer JavaDoc(0);
242         } else {
243             seq = new Integer JavaDoc(seq.intValue() + 1);
244         }
245         aliasSequences.put(name, seq);
246         return glueAlias(name, seq);
247     }
248
249     /**
250      * Glues a string and integer together to a new string.
251      */

252     protected String JavaDoc glueAlias(String JavaDoc aliasBase, Integer JavaDoc seq) {
253         if (seq == null) return aliasBase;
254         int s = seq.intValue();
255         if (s == 0) {
256             return aliasBase;
257         } else {
258             return aliasBase + s;
259         }
260     }
261
262
263     public Step addStep(NodeManager nm) {
264         if (used) throw new BridgeException("Query was used already");
265
266         removeSecurityConstraint(); // if present
267
MMObjectBuilder builder = MMBase.getMMBase().getBuilder(nm.getName());
268         if (builder == null) throw new BridgeException("No builder with name " + nm.getName() + " (perhaps " + nm + " is virtual?)");
269         BasicStep step = query.addStep(builder);
270         setAlias(step, ""); // "": generate alias
271
if (! aggregating) {
272             addFieldImplicit(step, nm.getField("number"));
273         }
274
275         return step;
276     }
277
278     public void setAlias(Step step, String JavaDoc alias) {
279         String JavaDoc currentAlias = step.getAlias();
280         String JavaDoc aliasBase = step.getTableName();
281
282         // check if it was the lastely 'automaticly' create alias, in which case we free the sequence number again
283
// (also to fix #6547)
284

285         Integer JavaDoc currentSeq = (Integer JavaDoc) aliasSequences.get(aliasBase);
286         if (currentSeq != null && glueAlias(aliasBase, currentSeq).equals(currentAlias)) {
287             if (currentSeq.intValue() == 0) {
288                 aliasSequences.put(aliasBase, null);
289             } else {
290                 aliasSequences.put(aliasBase, new Integer JavaDoc(currentSeq.intValue() - 1));
291             }
292         }
293         if ("".equals(alias)) {
294             alias = createAlias(aliasBase);
295         }
296
297         BasicStep basicStep = (BasicStep) step;
298         basicStep.setAlias(alias);
299     }
300
301     protected BasicRelationStep addRelationStep(InsRel insrel, NodeManager otherNodeManager, int direction) {
302         MMObjectBuilder otherBuilder = ((BasicNodeManager) otherNodeManager).builder;
303         BasicRelationStep relationStep = query.addRelationStep(insrel, otherBuilder);
304         relationStep.setDirectionality(direction);
305         relationStep.setAlias(createAlias(relationStep.getTableName()));
306         NodeManager relationManager = otherNodeManager.getCloud().getNodeManager(relationStep.getTableName());
307         BasicStep next = (BasicStep) relationStep.getNext();
308         next.setAlias(createAlias(next.getTableName()));
309         if (! aggregating) {
310             // the number fields must always be queried, otherwise the original node cannot be found back (e.g. <mm:node element=)
311
addFieldImplicit(relationStep, relationManager.getField("number")); // query relation node
312
addFieldImplicit(next, otherNodeManager.getField("number")); // and next node
313
// distinct?
314
}
315         return relationStep;
316     }
317     public RelationStep addRelationStep(NodeManager otherNodeManager) {
318         return addRelationStep(otherNodeManager, null, "BOTH");
319     }
320
321
322     public RelationStep addRelationStep(NodeManager otherNodeManager, String JavaDoc role, String JavaDoc direction) {
323         if ("".equals(role)) role = null;
324         return addRelationStep(otherNodeManager, role, direction, true);
325     }
326
327
328     protected RelationStep addRelationStep(NodeManager otherNodeManager, String JavaDoc role, String JavaDoc direction, boolean warnOnImpossibleStep) {
329         if (used) throw new BridgeException("Query was used already");
330
331         // a bit silly that two lookups are needed
332
int relationDir = Queries.getRelationStepDirection(direction);
333
334         TypeRel typeRel = BasicCloudContext.mmb.getTypeRel();
335         if (role == null) {
336             InsRel insrel = BasicCloudContext.mmb.getInsRel();
337             BasicRelationStep step = addRelationStep(insrel, otherNodeManager, relationDir);
338             if (!typeRel.optimizeRelationStep(step, cloud.getNodeManager(step.getPrevious().getTableName()).getNumber(), otherNodeManager.getNumber(), -1, relationDir)) {
339                 if (relationDir != RelationStep.DIRECTIONS_SOURCE &&
340                     relationDir != RelationStep.DIRECTIONS_DESTINATION &&
341                     warnOnImpossibleStep) {
342                     log.warn("Added an impossible relation step (" + step + " to " + otherNodeManager + ") to the query. The query-result will always be empty now (so you could as well not execute it).");
343                     log.warn(Logging.applicationStacktrace());
344                 }
345             }
346             return step;
347         } else {
348             RelDef relDef = BasicCloudContext.mmb.getRelDef();
349             int r = relDef.getNumberByName(role);
350             if (r == -1) {
351                 throw new NotFoundException("Role '" + role + "' does not exist.");
352             }
353             MMObjectNode relDefNode = relDef.getNode(r);
354             InsRel insrel = ((RelDef)relDefNode.getBuilder()).getBuilder(relDefNode.getNumber());
355             BasicRelationStep step = addRelationStep(insrel, otherNodeManager, relationDir);
356             step.setRole(new Integer JavaDoc(r));
357             if (! cloud.hasNodeManager(role)) {
358                 step.setAlias(createAlias(role));
359             }
360             if (! typeRel.optimizeRelationStep(step, cloud.getNodeManager(step.getPrevious().getTableName()).getNumber(), otherNodeManager.getNumber(), r, relationDir)) {
361                 if (relationDir != RelationStep.DIRECTIONS_SOURCE &&
362                     relationDir != RelationStep.DIRECTIONS_DESTINATION &&
363                     warnOnImpossibleStep) {
364                     // not fully specified, and nothing found, warn about that.
365
log.warn("Added an impossible relation step (" + step + " to " + otherNodeManager + ") to the query. The query-result will always be empty now (so you could as well not execute it). ");
366                     log.warn(Logging.applicationStacktrace());
367                 }
368             }
369             return step;
370         }
371     }
372
373     public void removeFields() {
374         query.removeFields();
375         explicitFields.clear();
376         Iterator i = implicitFields.iterator();
377         while (i.hasNext()) {
378             BasicStepField sf = (BasicStepField) i.next();
379             Step addedStep = sf.getStep();
380             query.addField(addedStep, sf.getField());
381         }
382
383     }
384
385
386     public StepField addField(Step step, Field field) {
387         if (used) throw new BridgeException("Query was used already");
388         BasicStepField sf = new BasicStepField(step, ((BasicField)field).coreField); /// XXX Casting is wrong
389
if (! implicitFields.remove(sf)) {; // it's explicitly added now
390
sf = query.addField(step, ((BasicField)field).coreField); // XXX Casting is wrong
391
}
392         explicitFields.add(sf);
393         return sf;
394     }
395     public StepField addField(String JavaDoc fieldIdentifier) {
396         // code copied from createStepField, should be centralized
397
if (used) throw new BridgeException("Query was used already");
398         int dot = fieldIdentifier.indexOf('.');
399         if (dot <= 0) throw new BridgeException("No step alias found in field identifier '" + fieldIdentifier + "'. Expected a dot in it.");
400         String JavaDoc stepAlias = fieldIdentifier.substring(0, dot);
401         String JavaDoc fieldName = fieldIdentifier.substring(dot + 1);
402         Step step = getStep(stepAlias);
403         if (step == null) throw new NotFoundException("No step with alias '" + stepAlias + "' found in " + getSteps());
404         NodeManager nm = cloud.getNodeManager(step.getTableName());
405         Field field = nm.getField(fieldName);
406         return addField(step, field);
407     }
408
409     /**
410      * Fields which are added 'implicity' should be added by this function.
411      */

412     protected void addFieldImplicit(Step step, Field field) {
413         if (used) throw new BridgeException("Query was used already");
414         if (! query.isDistinct()) {
415             org.mmbase.core.CoreField coreField = ((BasicField)field).coreField; /// XXX Casting is wrong
416
StepField sf = query.addFieldUnlessPresent(step, coreField);
417             if (! implicitFields.contains(sf)) {
418                 implicitFields.add(sf);
419             }
420         }
421     }
422
423     public StepField createStepField(Step step, Field field) {
424         if (field == null) throw new BridgeException("Field is null");
425         return
426             new BasicStepField(step, ((BasicField)field).coreField); /// XXX Casting is wrong
427
}
428
429     public StepField createStepField(Step step, String JavaDoc fieldName) {
430         return createStepField(step, cloud.getNodeManager(step.getTableName()).getField(fieldName));
431     }
432
433
434
435     public Step getStep(String JavaDoc stepAlias) {
436         return Queries.searchStep(getSteps(), stepAlias);
437     }
438
439     public StepField createStepField(String JavaDoc fieldIdentifier) {
440         // code copied from addField, should be centralized
441
int dot = fieldIdentifier.indexOf('.');
442         if (dot <= 0) throw new BridgeException("No step alias found in field identifier '" + fieldIdentifier + "'. Expected a dot in it.");
443         String JavaDoc stepAlias = fieldIdentifier.substring(0, dot);
444         String JavaDoc fieldName = fieldIdentifier.substring(dot + 1);
445         Step step = getStep(stepAlias);
446         if (step == null) throw new NotFoundException("No step with alias '" + stepAlias + "' found in " + getSteps());
447         NodeManager nm = cloud.getNodeManager(step.getTableName());
448         Field field = nm.getField(fieldName);
449         return createStepField(step, field);
450     }
451
452     public AggregatedField addAggregatedField(Step step, Field field, int aggregationType) {
453         if (used) throw new BridgeException("Query was used already");
454         BasicAggregatedField aggregatedField = query.addAggregatedField(step, ((BasicField)field).coreField, aggregationType); /// XXX Casting is wrong
455
// aggregatedField.setAlias(field.getName());
456

457         if (this instanceof NodeQuery) { // UGLY!
458
NodeQuery nodeQuery = (NodeQuery) this;
459             ((BasicStep) step).setAlias(nodeQuery.getNodeManager().getName());
460             // Step needs alias, because otherwise clusterbuilder chokes.
461
// And node-manager.getList is illogical, because a aggregated result is certainly not a 'real' node.
462
}
463
464         // TODO, think of something better. --> a good way to present aggregated results.
465

466         return aggregatedField;
467     }
468
469
470
471     public Query setDistinct(boolean distinct) {
472         if (used) throw new BridgeException("Query was used already");
473         query.setDistinct(distinct);
474         if (distinct) { // in that case, make sure only the 'explicitely' added fields remain.
475
query.removeFields();
476             implicitFields.clear();
477             Iterator i = explicitFields.iterator();
478             while (i.hasNext()) {
479                 BasicStepField sf = (BasicStepField) i.next();
480                 query.addField(sf.getStep(), sf.getField());
481             }
482         }
483         return this;
484     }
485
486     public Query setMaxNumber(int maxNumber) {
487         if (used) throw new BridgeException("Query was used already");
488         query.setMaxNumber(maxNumber);
489         return this;
490     }
491     public Query setOffset(int offset) {
492         if (used) throw new BridgeException("Query was used already");
493         query.setOffset(offset);
494         return this;
495
496     }
497
498     public LegacyConstraint createConstraint(String JavaDoc s) {
499         return new BasicLegacyConstraint(s);
500     }
501
502     public FieldNullConstraint createConstraint(StepField f) {
503         return new BasicFieldNullConstraint(f);
504     }
505
506     public FieldValueConstraint createConstraint(StepField f, Object JavaDoc v) {
507         return createConstraint(f, FieldCompareConstraint.EQUAL, v);
508     }
509
510     public FieldValueConstraint createConstraint(StepField f, int op, Object JavaDoc v, int part) {
511         BasicFieldValueConstraint c = new BasicFieldValueDateConstraint(f, v, part);
512         c.setOperator(op);
513         return c;
514     }
515
516     public FieldValueConstraint createConstraint(StepField f, int op, Object JavaDoc v) {
517         if (v instanceof Node) v = new Integer JavaDoc(((Node)v).getNumber());
518         BasicFieldValueConstraint c = new BasicFieldValueConstraint(f, v);
519         c.setOperator(op);
520         return c;
521     }
522
523     public CompareFieldsConstraint createConstraint(StepField f, int op, StepField v) {
524         BasicCompareFieldsConstraint c = new BasicCompareFieldsConstraint(f, v);
525         c.setOperator(op);
526         return c;
527     }
528
529     public FieldValueBetweenConstraint createConstraint(StepField f, Object JavaDoc o1, Object JavaDoc o2) {
530         return new BasicFieldValueBetweenConstraint(f, o1, o2);
531     }
532
533     public FieldValueInConstraint createConstraint(StepField f, SortedSet v) {
534         if (v.size() == 0) { // make sure the query becomes empty!
535
Step step = f.getStep();
536             StepField nf = createStepField(step, "number");
537             BasicFieldValueInConstraint c = new BasicFieldValueInConstraint(nf);
538             c.addValue(new Integer JavaDoc(-1));
539             return c;
540         } else {
541             BasicFieldValueInConstraint c = new BasicFieldValueInConstraint(f);
542             Iterator i = v.iterator();
543             while (i.hasNext()) {
544                 c.addValue(i.next());
545             }
546             return c;
547         }
548     }
549
550     public Constraint setInverse(Constraint c, boolean i) {
551         ((BasicConstraint) c).setInverse(i);
552         return c;
553     }
554
555     public FieldConstraint setCaseSensitive(FieldConstraint c, boolean s) {
556         ((BasicFieldConstraint) c).setCaseSensitive(s);
557         return c;
558
559     }
560     public CompositeConstraint createConstraint(Constraint c1, int operator, Constraint c2) {
561         if ((!used) && c1 instanceof BasicCompositeConstraint && ((CompositeConstraint) c1).getLogicalOperator() == operator) {
562             if (c2 != null) ((BasicCompositeConstraint) c1).addChild(c2);
563             return (CompositeConstraint) c1;
564         } else {
565             BasicCompositeConstraint c = new BasicCompositeConstraint(operator);
566             if (c1 != null) c.addChild(c1);
567             if (c2 != null) c.addChild(c2);
568             return c;
569         }
570     }
571
572     public void setConstraint(Constraint c) {
573         if (used) throw new BridgeException("Query was used already");
574         query.setConstraint(c);
575     }
576
577
578     public SortOrder addSortOrder(StepField f, int direction) {
579         return addSortOrder(f, direction, false);
580     }
581     public SortOrder addSortOrder(StepField f, int direction, boolean caseSensitive) {
582         if (used) throw new BridgeException("Query was used already");
583         if (f == null) throw new BridgeException("Cannot add sortorder on 'null' step field");
584         BasicSortOrder s = query.addSortOrder(f);
585         s.setDirection(direction);
586         s.setCaseSensitive(caseSensitive);
587         return s;
588     }
589
590     /**
591      * @since MMBase-1.7.1
592      */

593     public void addNode(Step s, int nodeNumber) {
594         if (used) throw new BridgeException("Query was used already");
595         BasicStep step = (BasicStep) s;
596         step.addNode(nodeNumber);
597         return;
598     }
599
600     public void addNode(Step s, Node node) {
601         addNode(s, node.getNumber());
602     }
603
604     public boolean isUsed() {
605         return used;
606     }
607
608     public boolean markUsed() {
609         boolean wasUsed = used;
610         if (queryCheck == null) { // if called manually
611
/// XXXX CASTING HERE. Is this really necessary!
612
// apply security constraints first, if not yet done, because the query gets unmodifiable from now on.
613
//((BasicCloud) cloud).setSecurityConstraint(this);
614
}
615         used = true;
616         return wasUsed;
617     }
618
619
620     boolean isSecure() {
621         return queryCheck != null && queryCheck.isChecked();
622     }
623
624     /**
625      * Applies a security-constraint to this Query. Such a constraint can be removed easily (needed
626      * before cloning a query and so on).
627      * @see #removeSecurityConstraint
628      */

629     void setSecurityConstraint(Authorization.QueryCheck c) {
630         if (queryCheck != null) {
631             throw new BridgeException("Already a security constraints set");
632         }
633         if (insecureConstraint != null) {
634             throw new BridgeException("Already a insecure constraint defined");
635         }
636         if (c == null) {
637             throw new BridgeException("QueryCheck may not be null");
638         }
639         if (log.isDebugEnabled()) {
640             log.debug("Setting security check " + c + " TO " + this);
641         }
642         queryCheck = c;
643
644         insecureConstraint = query.getConstraint(); // current constraint
645
Constraint secureConstraint = queryCheck.getConstraint();
646         if (secureConstraint != null) {
647             if (insecureConstraint != null) {
648                 BasicCompositeConstraint compConstraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
649                 compConstraint.addChild(insecureConstraint);
650                 compConstraint.addChild(secureConstraint);
651                 query.setConstraint(compConstraint);
652             } else {
653                 query.setConstraint(secureConstraint);
654             }
655         }
656     }
657
658     /**
659      * Remove a previously set security constraint (if set one)
660      * @see #setSecurityConstraint
661      */

662     void removeSecurityConstraint() {
663         if (log.isDebugEnabled()) {
664             log.debug("Removing " + queryCheck + " FROM " + this);
665         }
666         if (queryCheck != null) {
667             query.setConstraint(insecureConstraint);
668             insecureConstraint = null;
669         }
670         queryCheck = null;
671
672     }
673
674     public Cloud getCloud() {
675         return cloud;
676     }
677
678     public NodeList getList() {
679         return cloud.getList(this);
680     }
681
682     public boolean equals(Object JavaDoc obj) {
683         return query.equals(obj);
684     }
685
686     // javadoc is inherited
687
public int hashCode() {
688         return query.hashCode();
689     }
690
691
692     public String JavaDoc toString() {
693         return query.toString() + (used ? "(used)" : "") + "INSECURE: " + insecureConstraint + " QUERYCHECK: " + queryCheck;
694
695     }
696     private static final BasicSqlHandler sqlHandler = new BasicSqlHandler();
697     public String JavaDoc toSql() {
698         try {
699             return sqlHandler.toSql(this, sqlHandler);
700         } catch (org.mmbase.storage.search.SearchQueryException sqe) {
701             return sqe.getMessage() + ": " + toString();
702         } catch (Exception JavaDoc ise) {
703             return ise.getMessage() + ": " + toString();
704         }
705
706     }
707
708
709
710 }
711
Popular Tags