Source Code Cross Referenced for BasicQuery.java in  » Database-ORM » MMBase » org » mmbase » bridge » implementation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » MMBase » org.mmbase.bridge.implementation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:
011:        package org.mmbase.bridge.implementation;
012:
013:        import java.util.*;
014:        import org.mmbase.bridge.util.Queries;
015:        import org.mmbase.cache.CachePolicy;
016:        import org.mmbase.module.core.*;
017:        import org.mmbase.module.corebuilders.*;
018:        import org.mmbase.storage.search.*;
019:        import org.mmbase.storage.search.implementation.*;
020:        import org.mmbase.bridge.*;
021:        import org.mmbase.util.logging.*;
022:        import org.mmbase.security.Authorization;
023:
024:        /**
025:         * 'Basic' implementation of bridge Query. Wraps a 'BasicSearchQuery' from core.
026:         *
027:         * This  implementation is actually ussuable with other implementations of bridge too, because it has the public constructor:
028:         * {@link #BasicQuery(Cloud, BasicSearchQuery)}.
029:         *
030:         * @author Michiel Meeuwissen
031:         * @version $Id: BasicQuery.java,v 1.71 2008/02/27 11:48:44 michiel Exp $
032:         * @since MMBase-1.7
033:         * @see org.mmbase.storage.search.implementation.BasicSearchQuery
034:         */
035:        public class BasicQuery implements  Query {
036:
037:            private static final Logger log = Logging
038:                    .getLoggerInstance(BasicQuery.class);
039:
040:            /**
041:             * Whether this Query was used already. If it is used, it may not be changed any more.
042:             */
043:            protected boolean used = false;
044:
045:            /**
046:             * Whether this Query is aggregating.
047:             * @todo this member is in BasicSearchQuery too (but private).
048:             */
049:            protected boolean aggregating = false; // ugly ugly, this member is in BasicSearchQuery too (but private).
050:
051:            /**
052:             * The QueryCheck object associated with this Query, or null if no such object was determined yet.
053:             */
054:            protected Authorization.QueryCheck queryCheck = null;
055:
056:            /**
057:             * If a the contraint was made 'secure', in insecureConstraint the original Constraint is
058:             * stored. This object is null if either the queryCheck object is not yet determined, or the
059:             * orignal query did not have constraints.
060:             */
061:            protected Constraint insecureConstraint = null;
062:
063:            private HashMap<String, Integer> aliasSequences = new HashMap<String, Integer>(); // must be HashMap because cloneable
064:            // to make unique table aliases. This is similar impl. as  in core. Why should it be at all....
065:
066:            /**
067:             * The core query which is 'wrapped'
068:             */
069:            protected BasicSearchQuery query;
070:
071:            /**
072:             * reference to the cloud.
073:             */
074:            protected Cloud cloud;
075:
076:            /**
077:             * The implicitely added 'extra' fields. These are removed if the query becomes 'distinct'. So,
078:             * you can e.g. not do element= on a distinct query result.
079:             */
080:            protected List<StepField> implicitFields = new ArrayList<StepField>();
081:
082:            /**
083:             * The explicitely added 'extra' fields. Because you explicitely added those, they will not be removed if the query becomes 'distinct'.
084:             */
085:            protected List<StepField> explicitFields = new ArrayList<StepField>();
086:
087:            BasicQuery(Cloud c) {
088:                query = new BasicSearchQuery();
089:                cloud = c;
090:            }
091:
092:            BasicQuery(Cloud c, boolean aggregating) {
093:                query = new BasicSearchQuery(aggregating);
094:                this .aggregating = aggregating;
095:                cloud = c;
096:            }
097:
098:            public BasicQuery(Cloud c, BasicSearchQuery q) { // public for org.mmbase.bridge.util
099:                query = q;
100:                cloud = c;
101:                this .aggregating = q.isAggregating();
102:            }
103:
104:            public BasicSearchQuery getQuery() {
105:                return query;
106:            }
107:
108:            protected void createNewQuery() {
109:                query = new BasicSearchQuery();
110:            }
111:
112:            // SearchQuery impl:
113:
114:            public List<Step> getSteps() {
115:                return query.getSteps();
116:            }
117:
118:            public List<StepField> getFields() {
119:                return query.getFields();
120:            }
121:
122:            public Constraint getConstraint() {
123:                return query.getConstraint();
124:            }
125:
126:            // bridge.Query impl
127:            public Constraint getCleanConstraint() {
128:                if (queryCheck != null) {
129:                    return insecureConstraint;
130:                } else {
131:                    return query.getConstraint();
132:                }
133:            }
134:
135:            // more SearchQuery impl
136:            public int getMaxNumber() {
137:                return query.getMaxNumber();
138:            }
139:
140:            public int getOffset() {
141:                return query.getOffset();
142:            }
143:
144:            public List<SortOrder> getSortOrders() {
145:                return query.getSortOrders();
146:            }
147:
148:            public boolean isDistinct() {
149:                return query.isDistinct();
150:            }
151:
152:            // bridge.Query impl.:
153:
154:            public boolean isAggregating() {
155:                return aggregating;
156:            }
157:
158:            public CachePolicy getCachePolicy() {
159:                return query.getCachePolicy();
160:            }
161:
162:            public void setCachePolicy(CachePolicy policy) {
163:                query.setCachePolicy(policy);
164:            }
165:
166:            /**
167:             * @since MMBase-1.7.1
168:             */
169:            protected void removeSecurityConstraintFromClone(
170:                    BasicSearchQuery clone) {
171:                if (log.isDebugEnabled()) {
172:                    log.debug("Removing " + queryCheck + " FROM " + clone);
173:                }
174:                if (queryCheck != null) {
175:                    Constraint secureConstraint = queryCheck.getConstraint();
176:                    if (secureConstraint != null) {
177:                        Constraint constraint = clone.getConstraint();
178:                        // remove it from clone (by modifying the 'cloned' constraint)
179:                        if (secureConstraint.equals(constraint)) {
180:                            clone.setConstraint(null);
181:                        } else { // must be part of the composite constraint
182:                            BasicCompositeConstraint compConstraint = (BasicCompositeConstraint) constraint;
183:                            compConstraint.removeChild(secureConstraint); // remove it
184:                            if (compConstraint.getChilds().size() == 0) { // no need to let it  then
185:                                clone.setConstraint(null);
186:                            }
187:                            if (compConstraint.getChilds().size() == 1) { // no need to let it composite then
188:                                Constraint newConstraint = compConstraint
189:                                        .getChilds().get(0);
190:                                clone.setConstraint(newConstraint);
191:                            }
192:                        }
193:                    }
194:                }
195:
196:            }
197:
198:            @Override
199:            public Object clone() { // also works for descendants (NodeQuery)
200:                try {
201:                    BasicQuery clone = (BasicQuery) super .clone();
202:                    clone.query = (BasicSearchQuery) query.clone();
203:                    clone.aliasSequences = (HashMap<String, Integer>) aliasSequences
204:                            .clone();
205:                    removeSecurityConstraintFromClone(clone.query);
206:                    clone.insecureConstraint = null;
207:                    clone.queryCheck = null;
208:                    clone.used = false;
209:                    return clone;
210:                } catch (CloneNotSupportedException e) {
211:                    // cannot happen
212:                    throw new InternalError(e.toString());
213:                }
214:            }
215:
216:            public Query aggregatingClone() {
217:                BasicSearchQuery bsq = new BasicSearchQuery(query,
218:                        BasicSearchQuery.COPY_AGGREGATING);
219:                removeSecurityConstraintFromClone(bsq);
220:                BasicQuery clone = new BasicQuery(cloud, bsq);
221:                clone.used = false;
222:                clone.aggregating = true;
223:                return clone;
224:            }
225:
226:            public Query cloneWithoutFields() {
227:                BasicSearchQuery bsq = new BasicSearchQuery(query,
228:                        BasicSearchQuery.COPY_WITHOUTFIELDS);
229:                removeSecurityConstraintFromClone(bsq);
230:                BasicQuery clone = new BasicQuery(cloud, bsq);
231:                clone.used = false;
232:                clone.aggregating = false;
233:                return clone;
234:            }
235:
236:            /**
237:             * Creates a unique alias for this Query based on a given base String
238:             */
239:            protected String createAlias(String name) {
240:                if (used)
241:                    throw new BridgeException("Query was used already");
242:                Integer seq = aliasSequences.get(name);
243:                if (seq == null) {
244:                    seq = Integer.valueOf(0);
245:                } else {
246:                    seq = Integer.valueOf(seq.intValue() + 1);
247:                }
248:                aliasSequences.put(name, seq);
249:                return glueAlias(name, seq);
250:            }
251:
252:            /**
253:             * Glues a string and integer together to a new string.
254:             */
255:            protected String glueAlias(String aliasBase, Integer seq) {
256:                if (seq == null)
257:                    return aliasBase;
258:                int s = seq.intValue();
259:                if (s == 0) {
260:                    return aliasBase;
261:                } else {
262:                    return aliasBase + s;
263:                }
264:            }
265:
266:            public Step addStep(NodeManager nm) {
267:                if (used)
268:                    throw new BridgeException("Query was used already");
269:
270:                removeSecurityConstraint(); // if present
271:                MMObjectBuilder builder = MMBase.getMMBase().getBuilder(
272:                        nm.getName());
273:                if (builder == null)
274:                    throw new BridgeException("No builder with name "
275:                            + nm.getName() + " (perhaps " + nm
276:                            + " is virtual?)");
277:                BasicStep step = query.addStep(builder);
278:                setAlias(step, ""); // "": generate alias
279:                if (!aggregating) {
280:                    addFieldImplicit(step, nm.getField("number"));
281:                }
282:
283:                return step;
284:            }
285:
286:            public void setAlias(Step step, String alias) {
287:                String currentAlias = step.getAlias();
288:                String aliasBase = step.getTableName();
289:
290:                // check if it was the lastely 'automaticly' create alias, in which case we free the sequence number again
291:                // (also to fix #6547)
292:
293:                Integer currentSeq = aliasSequences.get(aliasBase);
294:                if (currentSeq != null
295:                        && glueAlias(aliasBase, currentSeq)
296:                                .equals(currentAlias)) {
297:                    if (currentSeq.intValue() == 0) {
298:                        aliasSequences.put(aliasBase, null);
299:                    } else {
300:                        aliasSequences.put(aliasBase, Integer
301:                                .valueOf(currentSeq.intValue() - 1));
302:                    }
303:                }
304:                if ("".equals(alias)) {
305:                    alias = createAlias(aliasBase);
306:                }
307:
308:                BasicStep basicStep = (BasicStep) step;
309:                basicStep.setAlias(alias);
310:            }
311:
312:            protected BasicRelationStep addRelationStep(InsRel insrel,
313:                    NodeManager otherNodeManager, int direction) {
314:                MMObjectBuilder otherBuilder = ((BasicNodeManager) otherNodeManager).builder;
315:                BasicRelationStep relationStep = query.addRelationStep(insrel,
316:                        otherBuilder);
317:                relationStep.setDirectionality(direction);
318:                relationStep.setAlias(createAlias(relationStep.getTableName()));
319:                NodeManager relationManager = otherNodeManager.getCloud()
320:                        .getNodeManager(relationStep.getTableName());
321:                BasicStep next = (BasicStep) relationStep.getNext();
322:                next.setAlias(createAlias(next.getTableName()));
323:                if (!aggregating) {
324:                    // the number fields must always be queried, otherwise the original node cannot be found back (e.g. <mm:node element=)
325:                    addFieldImplicit(relationStep, relationManager
326:                            .getField("number")); // query relation node
327:                    addFieldImplicit(next, otherNodeManager.getField("number")); // and next node
328:                    // distinct?
329:                }
330:                return relationStep;
331:            }
332:
333:            public RelationStep addRelationStep(NodeManager otherNodeManager) {
334:                return addRelationStep(otherNodeManager, null, "BOTH");
335:            }
336:
337:            public RelationStep addRelationStep(NodeManager otherNodeManager,
338:                    String role, String direction) {
339:                if ("".equals(role))
340:                    role = null;
341:                return addRelationStep(otherNodeManager, role, direction, true);
342:            }
343:
344:            protected RelationStep addRelationStep(
345:                    NodeManager otherNodeManager, String role,
346:                    String direction, boolean warnOnImpossibleStep) {
347:                if (used)
348:                    throw new BridgeException("Query was used already");
349:
350:                // a bit silly that two lookups are needed
351:                int relationDir = Queries.getRelationStepDirection(direction);
352:
353:                TypeRel typeRel = BasicCloudContext.mmb.getTypeRel();
354:                if (role == null) {
355:                    InsRel insrel = BasicCloudContext.mmb.getInsRel();
356:                    BasicRelationStep step = addRelationStep(insrel,
357:                            otherNodeManager, relationDir);
358:                    if (!typeRel.optimizeRelationStep(step, cloud
359:                            .getNodeManager(step.getPrevious().getTableName())
360:                            .getNumber(), otherNodeManager.getNumber(), -1,
361:                            relationDir)) {
362:                        if (relationDir != RelationStep.DIRECTIONS_SOURCE
363:                                && relationDir != RelationStep.DIRECTIONS_DESTINATION
364:                                && warnOnImpossibleStep) {
365:                            log
366:                                    .warn("Added an impossible relation step ("
367:                                            + step
368:                                            + " to "
369:                                            + otherNodeManager
370:                                            + ") to the query. The query-result will always be empty now (so you could as well not execute it).");
371:                            log.warn(Logging.applicationStacktrace());
372:                        }
373:                    }
374:                    return step;
375:                } else {
376:                    RelDef relDef = BasicCloudContext.mmb.getRelDef();
377:                    int r = relDef.getNumberByName(role);
378:                    if (r == -1) {
379:                        throw new NotFoundException("Role '" + role
380:                                + "' does not exist.");
381:                    }
382:                    MMObjectNode relDefNode = relDef.getNode(r);
383:                    InsRel insrel = ((RelDef) relDefNode.getBuilder())
384:                            .getBuilder(relDefNode.getNumber());
385:                    BasicRelationStep step = addRelationStep(insrel,
386:                            otherNodeManager, relationDir);
387:                    step.setRole(Integer.valueOf(r));
388:                    if (!cloud.hasNodeManager(role)) {
389:                        step.setAlias(createAlias(role));
390:                    }
391:                    if (!typeRel.optimizeRelationStep(step, cloud
392:                            .getNodeManager(step.getPrevious().getTableName())
393:                            .getNumber(), otherNodeManager.getNumber(), r,
394:                            relationDir)) {
395:                        if (relationDir != RelationStep.DIRECTIONS_SOURCE
396:                                && relationDir != RelationStep.DIRECTIONS_DESTINATION
397:                                && warnOnImpossibleStep) {
398:                            // not fully specified, and nothing found, warn about that.
399:                            log
400:                                    .warn("Added an impossible relation step ("
401:                                            + step
402:                                            + " to "
403:                                            + otherNodeManager
404:                                            + ") to the query. The query-result will always be empty now (so you could as well not execute it). ");
405:                            log.warn(Logging.applicationStacktrace());
406:                        }
407:                    }
408:                    return step;
409:                }
410:            }
411:
412:            public void removeFields() {
413:                query.removeFields();
414:                explicitFields.clear();
415:                Iterator<StepField> i = implicitFields.iterator();
416:                while (i.hasNext()) {
417:                    BasicStepField sf = (BasicStepField) i.next();
418:                    Step addedStep = sf.getStep();
419:                    query.addField(addedStep, sf.getField());
420:                }
421:
422:            }
423:
424:            public StepField addField(Step step, Field field) {
425:                if (used)
426:                    throw new BridgeException("Query was used already");
427:                org.mmbase.core.CoreField cf = ((BasicField) field).coreField; /// XXX Casting is wrong
428:                BasicStepField sf = new BasicStepField(step, cf);
429:                if (!implicitFields.remove(sf)) {// it's explicitly added now
430:                    if (cf.inStorage()) {
431:                        sf = query.addField(step, cf);
432:                    } else {
433:                        log
434:                                .debug("Not adding the field "
435:                                        + field
436:                                        + " because it is not in storage (this is a virtual field)");
437:                    }
438:                }
439:                explicitFields.add(sf);
440:                return sf;
441:            }
442:
443:            public StepField addField(String fieldIdentifier) {
444:                // code copied from createStepField, should be centralized
445:                if (used)
446:                    throw new BridgeException("Query was used already");
447:                int dot = fieldIdentifier.indexOf('.');
448:                if (dot <= 0)
449:                    throw new BridgeException(
450:                            "No step alias found in field identifier '"
451:                                    + fieldIdentifier
452:                                    + "'. Expected a dot in it.");
453:                String stepAlias = fieldIdentifier.substring(0, dot);
454:                String fieldName = fieldIdentifier.substring(dot + 1);
455:                Step step = getStep(stepAlias);
456:                if (step == null)
457:                    throw new NotFoundException("No step with alias '"
458:                            + stepAlias + "' found in " + getSteps());
459:                NodeManager nm = cloud.getNodeManager(step.getTableName());
460:                Field field = nm.getField(fieldName);
461:                return addField(step, field);
462:            }
463:
464:            /**
465:             * Fields which are added 'implicity' should be added by this function.
466:             */
467:            protected void addFieldImplicit(Step step, Field field) {
468:                if (used)
469:                    throw new BridgeException("Query was used already");
470:                if (!query.isDistinct()) {
471:                    org.mmbase.core.CoreField coreField = ((BasicField) field).coreField; /// XXX Casting is wrong
472:                    StepField sf = query.addFieldUnlessPresent(step, coreField);
473:                    if (!implicitFields.contains(sf)) {
474:                        implicitFields.add(sf);
475:                    }
476:                }
477:            }
478:
479:            public StepField createStepField(Step step, Field field) {
480:                if (field == null)
481:                    throw new BridgeException("Field is null");
482:                return new BasicStepField(step, ((BasicField) field).coreField); /// XXX Casting is wrong
483:            }
484:
485:            public StepField createStepField(Step step, String fieldName) {
486:                return createStepField(step, cloud.getNodeManager(
487:                        step.getTableName()).getField(fieldName));
488:            }
489:
490:            public Step getStep(String stepAlias) {
491:                return Queries.searchStep(getSteps(), stepAlias);
492:            }
493:
494:            public StepField createStepField(String fieldIdentifier) {
495:                // code copied from addField, should be centralized
496:                int dot = fieldIdentifier.indexOf('.');
497:                if (dot <= 0)
498:                    throw new BridgeException(
499:                            "No step alias found in field identifier '"
500:                                    + fieldIdentifier
501:                                    + "'. Expected a dot in it.");
502:                String stepAlias = fieldIdentifier.substring(0, dot);
503:                String fieldName = fieldIdentifier.substring(dot + 1);
504:                Step step = getStep(stepAlias);
505:                if (step == null)
506:                    throw new NotFoundException("No step with alias '"
507:                            + stepAlias + "' found in " + getSteps());
508:                NodeManager nm = cloud.getNodeManager(step.getTableName());
509:                Field field = nm.getField(fieldName);
510:                return createStepField(step, field);
511:            }
512:
513:            public AggregatedField addAggregatedField(Step step, Field field,
514:                    int aggregationType) {
515:                if (used)
516:                    throw new BridgeException("Query was used already");
517:                BasicAggregatedField aggregatedField = query
518:                        .addAggregatedField(step,
519:                                ((BasicField) field).coreField, aggregationType); /// XXX Casting is wrong
520:                // aggregatedField.setAlias(field.getName());
521:
522:                if (this  instanceof  NodeQuery) { // UGLY!
523:                    NodeQuery nodeQuery = (NodeQuery) this ;
524:                    ((BasicStep) step).setAlias(nodeQuery.getNodeManager()
525:                            .getName());
526:                    // Step needs alias, because otherwise clusterbuilder chokes.
527:                    // And node-manager.getList is illogical, because a aggregated result is certainly not a 'real' node.
528:                }
529:
530:                // TODO, think of something better. --> a good way to present aggregated results.
531:
532:                return aggregatedField;
533:            }
534:
535:            public Query setDistinct(boolean distinct) {
536:                if (used)
537:                    throw new BridgeException("Query was used already");
538:                query.setDistinct(distinct);
539:                if (distinct) { // in that case, make sure only the 'explicitely' added fields remain.
540:                    query.removeFields();
541:                    implicitFields.clear();
542:                    Iterator<StepField> i = explicitFields.iterator();
543:                    while (i.hasNext()) {
544:                        BasicStepField sf = (BasicStepField) i.next();
545:                        query.addField(sf.getStep(), sf.getField());
546:                    }
547:                }
548:                return this ;
549:            }
550:
551:            public Query setMaxNumber(int maxNumber) {
552:                if (used)
553:                    throw new BridgeException("Query was used already");
554:                query.setMaxNumber(maxNumber);
555:                return this ;
556:            }
557:
558:            public Query setOffset(int offset) {
559:                if (used)
560:                    throw new BridgeException("Query was used already");
561:                query.setOffset(offset);
562:                return this ;
563:
564:            }
565:
566:            public LegacyConstraint createConstraint(String s) {
567:                return new BasicLegacyConstraint(s);
568:            }
569:
570:            public FieldNullConstraint createConstraint(StepField f) {
571:                return new BasicFieldNullConstraint(f);
572:            }
573:
574:            public FieldValueConstraint createConstraint(StepField f, Object v) {
575:                return createConstraint(f, FieldCompareConstraint.EQUAL, v);
576:            }
577:
578:            public FieldValueConstraint createConstraint(StepField f, int op,
579:                    Object v, int part) {
580:                BasicFieldValueConstraint c = new BasicFieldValueDateConstraint(
581:                        f, v, part);
582:                c.setOperator(op);
583:                return c;
584:            }
585:
586:            public FieldValueConstraint createConstraint(StepField f, int op,
587:                    Object v) {
588:                if (v instanceof  Node)
589:                    v = Integer.valueOf(((Node) v).getNumber());
590:                BasicFieldValueConstraint c = new BasicFieldValueConstraint(f,
591:                        v);
592:                c.setOperator(op);
593:                return c;
594:            }
595:
596:            public CompareFieldsConstraint createConstraint(StepField f,
597:                    int op, StepField v) {
598:                BasicCompareFieldsConstraint c = new BasicCompareFieldsConstraint(
599:                        f, v);
600:                c.setOperator(op);
601:                return c;
602:            }
603:
604:            public FieldValueBetweenConstraint createConstraint(StepField f,
605:                    Object o1, Object o2) {
606:                return new BasicFieldValueBetweenConstraint(f, o1, o2);
607:            }
608:
609:            public FieldValueInConstraint createConstraint(StepField f,
610:                    SortedSet<? extends Object> v) {
611:                if (v.size() == 0) { // make sure the query becomes empty!
612:                    Step step = f.getStep();
613:                    StepField nf = createStepField(step, "number");
614:                    BasicFieldValueInConstraint c = new BasicFieldValueInConstraint(
615:                            nf);
616:                    c.addValue(Integer.valueOf(-1));
617:                    return c;
618:                } else {
619:                    BasicFieldValueInConstraint c = new BasicFieldValueInConstraint(
620:                            f);
621:                    for (Object o : v) {
622:                        c.addValue(o);
623:                    }
624:                    return c;
625:                }
626:            }
627:
628:            public Constraint setInverse(Constraint c, boolean i) {
629:                ((BasicConstraint) c).setInverse(i);
630:                return c;
631:            }
632:
633:            public FieldConstraint setCaseSensitive(FieldConstraint c, boolean s) {
634:                ((BasicFieldConstraint) c).setCaseSensitive(s);
635:                return c;
636:
637:            }
638:
639:            public CompositeConstraint createConstraint(Constraint c1,
640:                    int operator, Constraint c2) {
641:                if ((!used)
642:                        && c1 instanceof  BasicCompositeConstraint
643:                        && ((CompositeConstraint) c1).getLogicalOperator() == operator) {
644:                    if (c2 != null)
645:                        ((BasicCompositeConstraint) c1).addChild(c2);
646:                    return (CompositeConstraint) c1;
647:                } else {
648:                    BasicCompositeConstraint c = new BasicCompositeConstraint(
649:                            operator);
650:                    if (c1 != null)
651:                        c.addChild(c1);
652:                    if (c2 != null)
653:                        c.addChild(c2);
654:                    return c;
655:                }
656:            }
657:
658:            public void setConstraint(Constraint c) {
659:                if (used)
660:                    throw new BridgeException("Query was used already");
661:                query.setConstraint(c);
662:            }
663:
664:            public SortOrder addSortOrder(StepField f, int direction) {
665:                return addSortOrder(f, direction, false);
666:            }
667:
668:            public SortOrder addSortOrder(StepField f, int direction,
669:                    boolean caseSensitive) {
670:                return addSortOrder(f, direction, caseSensitive, -1);
671:            }
672:
673:            public SortOrder addSortOrder(StepField f, int direction,
674:                    boolean caseSensitive, int part) {
675:                if (used)
676:                    throw new BridgeException("Query was used already");
677:                if (f == null)
678:                    throw new BridgeException(
679:                            "Cannot add sortorder on 'null' step field");
680:                BasicSortOrder o = query.addSortOrder(f);
681:                o.setDirection(direction);
682:                o.setCaseSensitive(caseSensitive);
683:                if (o instanceof  BasicDateSortOrder) {
684:                    ((BasicDateSortOrder) o).setPart(part);
685:                }
686:                return o;
687:            }
688:
689:            /**
690:             * @since MMBase-1.7.1
691:             */
692:            public void addNode(Step s, int nodeNumber) {
693:                if (used)
694:                    throw new BridgeException("Query was used already");
695:                BasicStep step = (BasicStep) s;
696:                if (step == null)
697:                    throw new IllegalArgumentException("Step may not be null");
698:                step.addNode(nodeNumber);
699:                return;
700:            }
701:
702:            public void addNode(Step s, Node node) {
703:                addNode(s, node.getNumber());
704:            }
705:
706:            public boolean isUsed() {
707:                return used;
708:            }
709:
710:            public boolean markUsed() {
711:                boolean wasUsed = used;
712:                if (queryCheck == null) { // if called manually
713:                    /// XXXX CASTING HERE. Is this really necessary!
714:                    // apply security constraints first, if not yet done, because the query gets unmodifiable from now on.
715:                    //((BasicCloud) cloud).setSecurityConstraint(this);
716:                }
717:                used = true;
718:                return wasUsed;
719:            }
720:
721:            boolean isSecure() {
722:                return queryCheck != null && queryCheck.isChecked();
723:            }
724:
725:            /**
726:             * Applies a security-constraint to this Query. Such a constraint can be removed easily (needed
727:             * before cloning a query and so on).
728:             * @see #removeSecurityConstraint
729:             */
730:            void setSecurityConstraint(Authorization.QueryCheck c) {
731:                if (queryCheck != null) {
732:                    throw new BridgeException(
733:                            "Already a security constraints set");
734:                }
735:                if (insecureConstraint != null) {
736:                    throw new BridgeException(
737:                            "Already a insecure constraint defined");
738:                }
739:                if (c == null) {
740:                    throw new BridgeException("QueryCheck may not be null");
741:                }
742:                if (log.isDebugEnabled()) {
743:                    log.debug("Setting security check " + c + " TO " + this );
744:                }
745:                queryCheck = c;
746:
747:                insecureConstraint = query.getConstraint(); // current constraint
748:                Constraint secureConstraint = queryCheck.getConstraint();
749:                if (secureConstraint != null) {
750:                    if (insecureConstraint != null) {
751:                        BasicCompositeConstraint compConstraint = new BasicCompositeConstraint(
752:                                CompositeConstraint.LOGICAL_AND);
753:                        compConstraint.addChild(insecureConstraint);
754:                        compConstraint.addChild(secureConstraint);
755:                        query.setConstraint(compConstraint);
756:                    } else {
757:                        query.setConstraint(secureConstraint);
758:                    }
759:                }
760:            }
761:
762:            /**
763:             * Remove a previously set security constraint (if set one)
764:             * @see #setSecurityConstraint
765:             */
766:            void removeSecurityConstraint() {
767:                if (log.isDebugEnabled()) {
768:                    log.debug("Removing " + queryCheck + " FROM " + this );
769:                }
770:                if (queryCheck != null) {
771:                    query.setConstraint(insecureConstraint);
772:                    insecureConstraint = null;
773:                }
774:                queryCheck = null;
775:
776:            }
777:
778:            public Cloud getCloud() {
779:                return cloud;
780:            }
781:
782:            public NodeList getList() {
783:                return cloud.getList(this );
784:            }
785:
786:            @Override
787:            public boolean equals(Object obj) {
788:                return query.equals(obj);
789:            }
790:
791:            // javadoc is inherited
792:            @Override
793:            public int hashCode() {
794:                return query.hashCode();
795:            }
796:
797:            @Override
798:            public String toString() {
799:                return query.toString() + (used ? "(used)" : "") + "INSECURE: "
800:                        + insecureConstraint + " QUERYCHECK: " + queryCheck;
801:
802:            }
803:
804:            public String toSql() {
805:                try {
806:                    return MMBase.getMMBase().getSearchQueryHandler()
807:                            .createSqlString(query);
808:                } catch (org.mmbase.storage.search.SearchQueryException sqe) {
809:                    return sqe.getMessage() + ": " + toString();
810:                } catch (Exception ise) {
811:                    return ise.getMessage() + ": " + toString();
812:                }
813:
814:            }
815:
816:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.