KickJava   Java API By Example, From Geeks To Geeks.

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


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 package org.mmbase.bridge.implementation;
11
12 import java.util.*;
13
14 import org.mmbase.bridge.*;
15 import org.mmbase.storage.search.*;
16 import org.mmbase.storage.search.implementation.*;
17 import org.mmbase.util.logging.*;
18
19 /**
20  * 'Basic' implementation of bridge NodeQuery. Wraps a Query with all and only fields of one
21  * Step. If there is only one step, this can wrap NodeSearchQuery of core.
22  *
23  * Often, queries with more steps are sensible nodequeries, because sorting (e.g. posrel.pos) or
24  * filtering can be done on those steps (e.g. publishtimes).
25  *
26  * Nodes of this type can be used as an argument to function which do return 'real' nodes (so not clusternodes).
27  *
28  * @todo perhaps it would be nice to have the possibllity to query also two complete steps (also one of the neigbouring 'relation' steps).
29  * this would give nice efficient implementations of things like mm:relatednode (of mm:listrelations)
30  *
31  * @todo This kind of functionality should perhaps be present in NodeSearchQuery itself because you can then use it 'under' the bridge too.
32  *
33  * @author Michiel Meeuwissen
34  * @version $Id: BasicNodeQuery.java,v 1.29 2006/07/25 20:05:46 michiel Exp $
35  * @since MMBase-1.7
36  * @see org.mmbase.storage.search.implementation.NodeSearchQuery
37  */

38 public class BasicNodeQuery extends BasicQuery implements NodeQuery {
39
40     private static final Logger log = Logging.getLoggerInstance(BasicNodeQuery.class);
41     protected Step step = null;
42
43     BasicNodeQuery(Cloud c) {
44         super(c);
45     }
46
47     /**
48      * node query.
49      */

50     BasicNodeQuery(BasicNodeManager nodeManager) {
51         super(nodeManager.cloud);
52         query = new NodeSearchQuery(nodeManager.getMMObjectBuilder());
53         this.step = (Step) getSteps().get(0); // the only step
54
}
55     BasicNodeQuery(BasicNodeManager nodeManager, NodeSearchQuery q) {
56         super(nodeManager.cloud);
57         query = q;
58         this.step = (Step) getSteps().get(0); // the only step
59
}
60
61     /**
62      * Makes a multi-step node-query, based on a normal query. As a default, all fields of last steps are added (if at least there are steps already)
63      *
64      */

65     BasicNodeQuery(Cloud cloud, SearchQuery q) {
66         super(cloud);
67         query = new BasicSearchQuery(q);
68         List steps = query.getSteps();
69         if (steps.size() > 0) {
70             setNodeStep((Step) (steps.get(steps.size() -1 )));
71         }
72     }
73
74     public NodeManager getNodeManager() {
75         if (step == null) return null;
76         if (step instanceof RelationStep) {
77             RelationStep rs = (RelationStep) step;
78             int role = -1;
79             Integer JavaDoc roleValue = rs.getRole();
80             if (roleValue != null) {
81                 role = roleValue.intValue();
82             }
83             String JavaDoc roleName = role > 0 ? cloud.getNode(role).getStringValue("sname") : null;
84             NodeManager previous = cloud.getNodeManager(rs.getPrevious().getTableName());
85             NodeManager next = cloud.getNodeManager(rs.getNext().getTableName());
86             if (cloud.hasRelationManager(previous, next, roleName)) {
87                 return cloud.getRelationManager(previous, next, roleName);
88             } else {
89                 if (roleName == null) {
90                     return cloud.getNodeManager("insrel"); // not a relation manager, no role known
91
} else {
92                     return cloud.getRelationManager(roleName);
93                 }
94             }
95         } else {
96             return cloud.getNodeManager(step.getTableName());
97         }
98     }
99
100     public Step getNodeStep() {
101         return step;
102     }
103
104     // overridden from BasicQuery (a node query does not have '.' in its field names)
105
public StepField createStepField(String JavaDoc fieldName) {
106         if (fieldName.indexOf('.') == -1) {
107             BasicStepField stepField = (BasicStepField) getStepField(getNodeManager().getField(fieldName));
108             // stepField.setAlias(fieldName);
109
if (stepField == null) throw new NotFoundException("No field '" + fieldName + "' found in " + getSteps());
110             return stepField;
111         } else {
112             // It does contain dot? Perhaps one of the other steps.
113
return super.createStepField(fieldName);
114         }
115     }
116
117     public StepField getStepField(Field field) {
118         if (query instanceof NodeSearchQuery) {
119             BasicStepField stepField = ((NodeSearchQuery) query).getField(((BasicField)field).coreField);
120             return stepField;
121         } else {
122             Iterator fields = query.getFields().iterator();
123             while(fields.hasNext()) {
124                 StepField stepField = (StepField) fields.next();
125                 if (stepField.getStep().equals(step)) {
126                     if (stepField.getFieldName().equals(field.getName())) {
127                         return stepField;
128                     }
129                 }
130
131             }
132         }
133         //throw new NotFoundException("Could not find field '" + field + "' in " + this);
134
return null; // hmm.
135
}
136
137
138     public void removeFields() {
139         explicitFields.clear();
140         setNodeStep(step);
141     }
142
143
144     public List getExtraFields() {
145         return Collections.unmodifiableList(explicitFields);
146     }
147
148
149     /**
150      * Adds all fields of the gives collection, unless it is a field of the 'step' itself
151      */

152     protected void addFields(Collection c) {
153         Iterator i = c.iterator();
154         while (i.hasNext()) {
155             BasicStepField sf = (BasicStepField) i.next();
156             Step addedStep = sf.getStep();
157             if (addedStep.equals(step)) continue; // these are among the node-fields already
158
query.addField(addedStep, sf.getField());
159         }
160     }
161
162     // overrides setDistinct of super, because it should consider 'step' Fields.
163
public Query setDistinct(boolean distinct) {
164         if (used) throw new BridgeException("Query was used already");
165         query.setDistinct(distinct);
166         if (distinct) { // in that case, make sure only the 'explicitely' added fields remain.
167
query.removeFields();
168             query.addFields(step);
169             implicitFields.clear();
170             addFields(explicitFields);
171         }
172         return this;
173     }
174
175     public Step setNodeStep(Step step) {
176         assert query.getSteps().contains(step);
177         if (this.step == null && step == null) return null;
178         if (this.step != null && this.step.equals(step)) return this.step; // already this step.
179
// Make sure the query _starts_ with the Node-fields.
180
// otherwise BasicQueryHandler.getNodes could do it wrong...
181
query.removeFields();
182         query.addFields(step);
183         addFields(explicitFields);
184         Step prevStep = this.step;
185         this.step = step;
186         if (! isDistinct() ) {
187             addFields(implicitFields);
188         }
189         return prevStep;
190     }
191
192     public Query cloneWithoutFields() {
193         BasicSearchQuery bsq = new BasicSearchQuery(query, BasicSearchQuery.COPY_WITHOUTFIELDS);
194         if (queryCheck != null) {
195             removeSecurityConstraintFromClone(bsq);
196         }
197         BasicNodeQuery clone = new BasicNodeQuery(cloud, bsq);
198         clone.used = false;
199         clone.aggregating = false;
200         return clone;
201     }
202
203     public NodeList getList() {
204         return getNodeManager().getList(this);
205     }
206
207
208 }
209
Popular Tags