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: package org.mmbase.storage.search.implementation;
011:
012: import java.util.*;
013:
014: import org.mmbase.cache.CachePolicy;
015: import org.mmbase.storage.search.*;
016:
017: /**
018: * A <code>ModifiedQuery</code> enables a modifiable lightweight copy of a
019: * {@link org.mmbase.storage.search.SearchQuery SearchQuery} to be created
020: * by wrapping the original query.
021: * <p>
022: * This class is provided primarily for use by core-, security- and
023: * storage layer classes, in those rare cases where modifications may be
024: * appropriate to a query before processing it.
025: * <p>
026: * The <code>ModifiedQuery</code> wraps the original query, and can be modified
027: * without affecting the original query. Modifications are not validated, and
028: * may lead to inconsistent data in the query (e.g. sorting on fields
029: * that are not in the query), resulting in a query that can not be processed
030: * by the storage.
031: * Avoiding such inconsistencies is the responsibility of the user.
032: *
033: * @author Rob van Maris
034: * @version $Id: ModifiableQuery.java,v 1.8 2007/03/31 17:12:58 nklasens Exp $
035: * @since MMBase-1.7
036: */
037: public class ModifiableQuery implements SearchQuery {
038:
039: private SearchQuery query = null;
040:
041: /**
042: * The value of the maxNumber property, -1 means: use
043: * <code>query.getMaxNumber()</code>.
044: */
045: private int maxNumber = -1;
046:
047: /**
048: * The value of the offset property, -1 means: use
049: * <code>query.getOffset()</code>.
050: */
051: private int offset = -1;
052:
053: /**
054: * The constraint, <code>null</code> means: use
055: * <code>query.getConstraint()</code>.
056: */
057: private Constraint constraint = null;
058:
059: /**
060: * The fields, <code>null</code> means: use
061: * <code>query.getFields()</code>.
062: */
063: private List<StepField> fields = null;
064:
065: /**
066: * The sortorders, <code>null</code> means: use
067: * <code>query.getSortOrders()</code>.
068: */
069: private List<SortOrder> sortOrders = null;
070:
071: /**
072: * The steps, <code>null</code> means: use
073: * <code>query.getSteps()</code.
074: */
075: private List<Step> steps = null;
076:
077: /**
078: * The value of the distinct property, <code>null</code> means: use
079: * <code>query.isDistinct()</code>.
080: */
081: private Boolean distinct = null;
082:
083: /**
084: * The value of the aggregating property, <code>null</code> means: use
085: * <code>query.isAggregating()</code>.
086: */
087: private Boolean aggregating = null;
088:
089: /**
090: * Whether this Query is cacheable.
091: */
092: private CachePolicy cachePolicy = null;
093:
094: /** Creates a new instance of ModifiedQuery */
095: public ModifiableQuery(SearchQuery query) {
096: this .query = query;
097: }
098:
099: /**
100: * Sets the maxNumber property.
101: *
102: * @param maxNumber The maxNumber value, -1 means: use
103: * <code>query.getMaxNumber()</code>.
104: * @return This <code>ModifiableQuery</code> instance.
105: */
106: public ModifiableQuery setMaxNumber(int maxNumber) {
107: this .maxNumber = maxNumber;
108: return this ;
109: }
110:
111: /**
112: * Sets the offset property.
113: *
114: * @param offset The offset value, -1 means: use
115: * <code>query.getOffset()</code>.
116: * @return This <code>ModifiableQuery</code> instance.
117: */
118: public ModifiableQuery setOffset(int offset) {
119: this .offset = offset;
120: return this ;
121: }
122:
123: /**
124: * Sets the constraint property.
125: *
126: * @param constraint The constraint, <code>null</code> means: use
127: * <code>query.getConstraint()</code>.
128: * @return This <code>ModifiableQuery</code> instance.
129: */
130: public ModifiableQuery setConstraint(Constraint constraint) {
131: this .constraint = constraint;
132: return this ;
133: }
134:
135: /**
136: * Sets the fields property.
137: *
138: * @param fields The fields, <code>null</code> means: use
139: * <code>query.getFields()</code>.
140: * @return This <code>ModifiableQuery</code> instance.
141: */
142: public ModifiableQuery setFields(List<StepField> fields) {
143: this .fields = fields;
144: return this ;
145: }
146:
147: /**
148: * Sets the sortOrders property.
149: *
150: * @param sortOrders The sortorders, <code>null</code> means: use
151: * <code>query.getSortOrders()</code>.
152: * @return This <code>ModifiableQuery</code> instance.
153: */
154: public ModifiableQuery setSortOrders(List<SortOrder> sortOrders) {
155: this .sortOrders = sortOrders;
156: return this ;
157: }
158:
159: /**
160: * Sets the steps property.
161: *
162: * @param steps The steps, <code>null</code> means: use
163: * <code>query.getSteps()</code.
164: * @return This <code>ModifiableQuery</code> instance.
165: */
166: public ModifiableQuery setSteps(List<Step> steps) {
167: this .steps = steps;
168: return this ;
169: }
170:
171: /**
172: * Sets the distinct property.
173: *
174: * @param distinct The value of the distinct property,
175: * <code>null</code> means: use <code>query.isDistinct()</code>.
176: * @return This <code>ModifiableQuery</code> instance.
177: */
178: public ModifiableQuery setDistinct(Boolean distinct) {
179: this .distinct = distinct;
180: return this ;
181: }
182:
183: /**
184: * Sets the aggregating property.
185: *
186: * @param aggregating The value of the aggregating property,
187: * <code>null</code> means: use <code>query.isAggregating()</code>.
188: * @return This <code>ModifiableQuery</code> instance.
189: */
190: public ModifiableQuery setAggregating(Boolean aggregating) {
191: this .aggregating = aggregating;
192: return this ;
193: }
194:
195: // javadoc is inherited
196: public int getMaxNumber() {
197: if (maxNumber != -1) {
198: return maxNumber;
199: } else {
200: return query.getMaxNumber();
201: }
202: }
203:
204: // javadoc is inherited
205: public int getOffset() {
206: if (offset != -1) {
207: return offset;
208: } else {
209: return query.getOffset();
210: }
211: }
212:
213: // javadoc is inherited
214: public Constraint getConstraint() {
215: if (constraint != null) {
216: return constraint;
217: } else {
218: return query.getConstraint();
219: }
220: }
221:
222: // javadoc is inherited
223: public List<StepField> getFields() {
224: if (fields != null) {
225: return fields;
226: } else {
227: return query.getFields();
228: }
229: }
230:
231: // javadoc is inherited
232: public List<SortOrder> getSortOrders() {
233: if (sortOrders != null) {
234: return sortOrders;
235: } else {
236: return query.getSortOrders();
237: }
238: }
239:
240: // javadoc is inherited
241: public List<Step> getSteps() {
242: if (steps != null) {
243: return steps;
244: } else {
245: return query.getSteps();
246: }
247: }
248:
249: // javadoc is inherited
250: public boolean isDistinct() {
251: if (distinct != null) {
252: return distinct.booleanValue();
253: } else {
254: return query.isDistinct();
255: }
256: }
257:
258: // javadoc is inherited
259: public boolean isAggregating() {
260: if (aggregating != null) {
261: return aggregating.booleanValue();
262: } else {
263: return query.isAggregating();
264: }
265: }
266:
267: public CachePolicy getCachePolicy() {
268: if (cachePolicy != null) {
269: return cachePolicy;
270: } else {
271: return query.getCachePolicy();
272: }
273: }
274:
275: public void setCachePolicy(CachePolicy policy) {
276: this .cachePolicy = policy;
277: }
278:
279: /**
280: * {@inheritDoc}
281: * Should correspond to {@link BasicSearchQuery#equals}
282: */
283: public boolean equals(Object obj) {
284: if (obj == this ) {
285: return true;
286: }
287: if (obj instanceof SearchQuery) {
288: SearchQuery query = (SearchQuery) obj;
289: Constraint constraint = getConstraint();
290: return isDistinct() == query.isDistinct()
291: && getMaxNumber() == query.getMaxNumber()
292: && getOffset() == query.getOffset()
293: && getSteps().equals(query.getSteps())
294: && getFields().equals(query.getFields())
295: && getSortOrders().equals(query.getSortOrders())
296: && (constraint == null ? query.getConstraint() == null
297: : constraint.equals(query.getConstraint()));
298: } else {
299: return false;
300: }
301: }
302:
303: /**
304: * {@inheritDoc}
305: * Should correspond to {@link BasicSearchQuery#hashCode}
306: */
307: public int hashCode() {
308: Constraint constraint = getConstraint();
309: return (isDistinct() ? 0 : 101) + getMaxNumber() * 17
310: + getOffset() * 19 + 23 * getSteps().hashCode() + 29
311: * getFields().hashCode() + 31
312: * getSortOrders().hashCode() + 37
313: * (constraint == null ? 0 : constraint.hashCode());
314: }
315:
316: // javadoc is inherited
317: public String toString() {
318: StringBuilder sb = new StringBuilder(
319: "ModifiableSearchQuery(distinct:").append(isDistinct())
320: .append(", steps:").append(getSteps()).append(
321: ", fields:").append(getFields()).append(
322: ", constraint:").append(getConstraint())
323: .append(", sortorders:").append(getSortOrders())
324: .append(", max:").append(getMaxNumber()).append(
325: ", offset:").append(getOffset()).append(")");
326: return sb.toString();
327: }
328:
329: }
|