001: /**
002: * Copyright (C) 2001-2004 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.query.jdo;
018:
019: import org.objectweb.speedo.query.api.QueryDefinition;
020:
021: import javax.jdo.Extent;
022:
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Collection;
026:
027: /**
028: * is a basic implementation of the QueryDefinition interface.
029: *
030: * @author S.Chassande-Barrioz
031: */
032: public class JDOQueryDefinitionImpl implements QueryDefinition {
033:
034: /**
035: *
036: */
037: protected short type = TYPE_SELECT;
038:
039: public static String queryType2string(short type) {
040: switch (type) {
041: case TYPE_DELETE:
042: return "SELECT";
043: case TYPE_UPDATE:
044: return "SELECT";
045: case TYPE_SELECT:
046: return "SELECT";
047: default:
048: return "UNKNOWN";
049: }
050: }
051:
052: /**
053: * IgnoreCache option.
054: * The ignoreCache option setting specifies whether the query should execute
055: * entirely in the back end, instead of in the cache. If this flag is set
056: * to true, an implementation might be able to optimize the query
057: * execution by ignoring changed values in the cache. For optimistic
058: * transactions, this can dramatically improve query response times.
059: */
060: protected boolean ignoreCache = true;
061:
062: /**
063: * Candidate classes or extent for the query.
064: */
065: protected Collection candidateInstances = null;
066: protected Extent extentClass = null;
067:
068: /**
069: * Class of candadate classes.
070: */
071: protected Class candidateClass = null;
072:
073: /**
074: * Query filter.
075: */
076: protected String filter = "true";
077:
078: /**
079: * Query parameters and variables declaration
080: */
081: protected String parameters = null;
082: protected String variables = null;
083:
084: /**
085: * the import statements is transformed into a simple vector
086: */
087: protected List importStatements = null;
088: protected List order = null;
089:
090: transient protected long indexFirst = 0;
091:
092: transient protected long indexLast = Long.MAX_VALUE;
093:
094: protected boolean unique;
095:
096: protected String result;
097:
098: protected Class resultClass;
099:
100: protected boolean withPrefetch;
101:
102: boolean includeSubClasses = true;
103:
104: protected String grouping;
105:
106: protected boolean fetchIdentifierOnly = false;
107:
108: public JDOQueryDefinitionImpl() {
109: }
110:
111: public JDOQueryDefinitionImpl(JDOQueryDefinitionImpl qd) {
112: defineWith(qd);
113: }
114:
115: public void defineWith(JDOQueryDefinitionImpl qd) {
116: if (qd == null) {
117: this .candidateClass = null;
118: this .candidateInstances = null;
119: this .extentClass = null;
120: this .filter = null;
121: this .order = null;
122: this .variables = null;
123: this .parameters = null;
124: this .importStatements = null;
125: this .ignoreCache = true;
126: this .indexFirst = 0;
127: this .indexLast = Long.MAX_VALUE;
128: this .withPrefetch = true;
129: this .grouping = null;
130: this .result = null;
131: this .resultClass = null;
132: this .includeSubClasses = true;
133: this .unique = false;
134: this .type = TYPE_SELECT;
135: this .fetchIdentifierOnly = false;
136: } else {
137: this .candidateClass = qd.getCandidateClass();
138: this .candidateInstances = qd.getCollection();
139: this .extentClass = qd.getExtent();
140: this .filter = qd.getFilter();
141: this .order = qd.getOrder();
142: this .variables = qd.getVariables();
143: this .parameters = qd.getParameters();
144: this .importStatements = qd.getImportStatements();
145: this .ignoreCache = qd.isIgnoreCache();
146: this .indexFirst = qd.getIndexFirst();
147: this .indexLast = qd.getIndexLast();
148: this .withPrefetch = qd.withPrefetch();
149: this .grouping = qd.getGrouping();
150: this .result = qd.getResult();
151: this .resultClass = qd.getResultClass();
152: this .includeSubClasses = qd.getIncludeSubClasses();
153: this .unique = qd.getUnique();
154: this .type = qd.getQueryType();
155: this .fetchIdentifierOnly = qd.fetchIdentifierOnly();
156: }
157: }
158:
159: public boolean fetchIdentifierOnly() {
160: return fetchIdentifierOnly;
161: }
162:
163: public short getQueryType() {
164: return type;
165: }
166:
167: public Class getCandidateClass() {
168: return candidateClass;
169: }
170:
171: public boolean isCollection() {
172: return candidateInstances != null;
173: }
174:
175: public Collection getCollection() {
176: return candidateInstances;
177: }
178:
179: public String getParameters() {
180: return parameters;
181: }
182:
183: public String getVariables() {
184: return variables;
185: }
186:
187: public String getFilter() {
188: return filter;
189: }
190:
191: public Extent getExtent() {
192: return extentClass;
193: }
194:
195: public List getImportStatements() {
196: return importStatements;
197: }
198:
199: public boolean isIgnoreCache() {
200: return ignoreCache;
201: }
202:
203: public List getOrder() {
204: return order;
205: }
206:
207: public long getIndexFirst() {
208: return indexFirst;
209: }
210:
211: public long getIndexLast() {
212: return indexLast;
213: }
214:
215: public boolean getUnique() {
216: return unique;
217: }
218:
219: public String getResult() {
220: return result;
221: }
222:
223: public Class getResultClass() {
224: return resultClass;
225: }
226:
227: public boolean getIncludeSubClasses() {
228: return includeSubClasses;
229: }
230:
231: public String getGrouping() {
232: return grouping;
233: }
234:
235: public boolean withPrefetch() {
236: return withPrefetch;
237: }
238:
239: public void withPrefetch(boolean withPrefetch) {
240: this .withPrefetch = withPrefetch;
241: }
242:
243: public String toString() {
244: return qdToString(true);
245: }
246:
247: public String qdToString(final boolean oneLine) {
248: final StringBuffer sb = new StringBuffer();
249: String sep = "";
250: final String sepNext = (oneLine ? ", " : "\n\t-");
251: sb.append(sep).append("type=").append(queryType2string(type));
252:
253: if (candidateClass != null) {
254: sb.append(sep).append("class=\"").append(
255: candidateClass.getName()).append("\"");
256: sep = sepNext;
257: }
258: if (parameters != null && parameters.length() > 0) {
259: sb.append(sep).append("parameters=\"").append(parameters)
260: .append("\"");
261: sep = sepNext;
262: }
263: if (variables != null && variables.length() > 0) {
264: sb.append(sep).append("variables=\"").append(variables)
265: .append("\"");
266: sep = sepNext;
267: }
268: if (filter != null && filter.length() > 0
269: && !filter.equals("true")) {
270: sb.append(sep).append("filter=\"").append(filter).append(
271: "\"");
272: sep = sepNext;
273: }
274: if (order != null && order.size() > 0) {
275: sb.append(sep).append("order=\"");
276: for (Iterator iter = order.iterator(); iter.hasNext();) {
277: sb.append(iter.next());
278: }
279: sb.append("\"");
280: sep = sepNext;
281: }
282: if (result != null) {
283: sb.append(sep).append("result=\"").append(result).append(
284: "\"");
285: sep = sepNext;
286: }
287: if (resultClass != null) {
288: sb.append(sep).append("resultClass=\"").append(resultClass)
289: .append("\"");
290: sep = sepNext;
291: }
292: if (grouping != null && grouping.length() > 0) {
293: sb.append(sep).append("grouping=\"").append(grouping)
294: .append("\"");
295: sep = sepNext;
296: }
297: if (unique) {
298: sb.append(sep).append("unique=\"").append(unique).append(
299: "\"");
300: sep = sepNext;
301: }
302: if (ignoreCache) {
303: sb.append(sep).append("ignoreCache=\"").append(ignoreCache)
304: .append("\"");
305: sep = sepNext;
306: }
307: if (!withPrefetch) {
308: sb.append(sep).append("withPrefetch=\"").append(
309: withPrefetch).append("\"");
310: sep = sepNext;
311: }
312: if (!includeSubClasses) {
313: sb.append(sep).append("includeSubClasses=\"").append(
314: includeSubClasses).append("\"");
315: sep = sepNext;
316: }
317: return sb.toString();
318: }
319:
320: public int hashCode() {
321: return candidateClass.hashCode();
322: }
323:
324: public boolean equals(Object obj) {
325: if (obj == null || !(obj instanceof JDOQueryDefinitionImpl)) {
326: return false;
327: }
328: JDOQueryDefinitionImpl qd = (JDOQueryDefinitionImpl) obj;
329: return (type == qd.getQueryType())
330: && (candidateClass == null ? qd.getCandidateClass() == null
331: : candidateClass.equals(qd.getCandidateClass()))
332: && (parameters == null ? qd.getParameters() == null
333: : parameters.equals(qd.getParameters()))
334: && (variables == null ? qd.getVariables() == null
335: : variables.equals(qd.getVariables()))
336: && (filter == null ? qd.getFilter() == null : filter
337: .equals(qd.getFilter()))
338: && (order == null ? qd.getOrder() == null : order
339: .equals(qd.getOrder()))
340: && (result == null ? qd.getResult() == null : result
341: .equals(qd.getResult()))
342: && (resultClass == null ? qd.getResultClass() == null
343: : resultClass.equals(qd.getResultClass()))
344: && (grouping == null ? qd.getGrouping() == null
345: : grouping.equals(qd.getGrouping()))
346: && (qd.isCollection() ? qd.getCollection().equals(
347: candidateInstances) : true)
348: && (qd.getUnique() == unique)
349: && (qd.withPrefetch() == withPrefetch)
350: && (qd.getIncludeSubClasses() == includeSubClasses)
351: && sameRangeCondition(qd);
352: }
353:
354: private boolean sameRangeCondition(QueryDefinition qd) {
355: //index of first must be the same thing 0 or not 0
356: if ((indexFirst == 0 && qd.getIndexFirst() != 0)
357: || (indexFirst != 0 && qd.getIndexFirst() == 0)) {
358: return false;
359: }
360: //index of the last must be the same thing Long.MAX_VALUE or not Long.MAX_VALUE
361: if ((indexLast == Long.MAX_VALUE && qd.getIndexLast() != Long.MAX_VALUE)
362: || (indexLast != Long.MAX_VALUE && qd.getIndexLast() == Long.MAX_VALUE)) {
363: return false;
364: }
365: return true;
366: }
367:
368: }
|