KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > queryframework > DatabaseQuery


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.queryframework;
23
24 import java.util.*;
25 import java.io.*;
26 import oracle.toplink.essentials.internal.helper.*;
27 import oracle.toplink.essentials.expressions.*;
28 import oracle.toplink.essentials.internal.expressions.*;
29 import oracle.toplink.essentials.internal.databaseaccess.*;
30 import oracle.toplink.essentials.internal.queryframework.*;
31 import oracle.toplink.essentials.exceptions.*;
32 import oracle.toplink.essentials.sessions.Record;
33 import oracle.toplink.essentials.sessions.DatabaseRecord;
34 import oracle.toplink.essentials.internal.parsing.ejbql.EJBQLCallQueryMechanism;
35 import oracle.toplink.essentials.sessions.SessionProfiler;
36 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
37 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
38 import oracle.toplink.essentials.internal.sessions.AbstractSession;
39 import oracle.toplink.essentials.descriptors.ClassDescriptor;
40
41 /**
42  * <p><b>Purpose</b>:
43  * Abstract class for all database query objects.
44  * DatabaseQuery is a visible class to the TopLink user. Users create an appropriate
45  * query by creating an instance of a concrete subclasses of DatabaseQuery.
46  *
47  * <p><b>Responsibilities</b>:
48  * <ul>
49  * <li> Provide a common protocol for query objects.
50  * <li> Defines a generic execution interface.
51  * <li> Provides query property values
52  * <li> Holds arguments to the query
53  * </ul>
54  *
55  * @author Yvon Lavoie
56  * @since TOPLink/Java 1.0
57  */

58 public abstract class DatabaseQuery implements Cloneable JavaDoc, Serializable, FalseUndefinedTrue {
59
60     /** Queries can be given a name and registered with a descriptor to allow common queries to be reused. */
61     protected String JavaDoc name;
62
63     /** Arguments can be given and specified to predefined queries to allow reuse. */
64     protected Vector arguments;
65
66     /** Arguments values can be given and specified to predefined queries to allow reuse. */
67     protected Vector argumentValues;
68
69     /** Needed to differentiate queries with the same name. */
70     protected Vector argumentTypes;
71
72     /** Used to build a list of argumentTypes by name pre-initialization */
73     protected Vector argumentTypeNames;
74
75     /** The descriptor cached on the prepare for object level queries. */
76     protected transient ClassDescriptor descriptor;
77
78     /** The query mechanism determines the mechanism on how the database will be accessed. */
79     protected DatabaseQueryMechanism queryMechanism;
80     
81     /** Flag used for a query to bypass the identitymap and unit of work. */
82     // Bug#3476483 - Restore shouldMaintainCache to previous state after reverse of bug fix 3240668
83
protected boolean shouldMaintainCache;
84
85     /** Internallay used by the mappings as a temporary store. */
86     protected Hashtable properties;
87
88     /** Only used after the query is prepared to store the session under which the query was executed. */
89     protected transient AbstractSession session;
90
91     /** Connection to use for database access, required for server session connection pooling. */
92     protected transient Accessor accessor;
93
94     /** Mappings and the descriptor use parameterized mechanisms that will be translated with the data from the row. */
95     protected AbstractRecord translationRow;
96
97     /** Internal flag used to bypass user define queries when executing one for custom sql/query support. */
98     protected boolean isUserDefined;
99
100     /** Policy that determines how the query will cascade to its object's parts. */
101     protected int cascadePolicy;
102
103     /** Used to override the default session in the session broker. */
104     protected String JavaDoc sessionName;
105
106     /** Queries prepare common stated in themselves. */
107     protected boolean isPrepared;
108
109     /** Allow for the prepare of queries to be turned off, this allow for dynamic non-pre SQL generated queries. */
110     protected boolean shouldPrepare;
111
112     /** Bind all arguments to the SQL statement. */
113
114     // Has False, Underfined or True value. In case of Undefined -
115
// Session's shouldBindAllParameters() defines whether to bind or not.
116
protected int shouldBindAllParameters;
117
118     /** Cache the prepared statement, this requires full parameter binding as well. */
119
120     // Has False, Underfined or True value. In case of Undefined -
121
// Session's shouldCacheAllStatements() defines whether to cache or not.
122
protected int shouldCacheStatement;
123
124     /** Use the WrapperPolicy for the objects returned by the query */
125     protected boolean shouldUseWrapperPolicy;
126
127     /* Used as default for read, means shallow write for modify. */
128     public static final int NoCascading = 1;
129
130     /* Used as default for write, used for refreshing to refresh the whole object. */
131     public static final int CascadePrivateParts = 2;
132
133     /* Currently not supported, used for deep write/refreshes/reads in the future. */
134     public static final int CascadeAllParts = 3;
135
136     /* Used by the unit of work. */
137     public static final int CascadeDependentParts = 4;
138
139     /* Used by aggregate Collections: As aggregates delete at update time, cascaded deletes
140      * must know to stop when entering postDelete for a particular mapping. Only used by the
141      * aggregate collection when update is occuring in a UnitOfWork
142      * CR 2811
143      */

144     public static final int CascadeAggregateDelete = 5;
145
146     /*
147      * Used when refreshing should check the mappings to determin if a particular
148      * mapping should be cascaded.
149      */

150     public static final int CascadeByMapping = 6;
151     
152     /*
153      * Stores the FlushMode of this Query. This is only applicable when executed
154      * in a flushable UnitOfWork and will be ignored otherwise.
155      */

156     protected Boolean JavaDoc flushOnExecute;
157
158     /**
159      * PUBLIC:
160      * Initialize the state of the query
161      */

162     public DatabaseQuery() {
163         this.shouldMaintainCache = true;
164         // bug 3524620: lazy-init query mechanism
165
//this.queryMechanism = new ExpressionQueryMechanism(this);
166
this.isUserDefined = false;
167         this.cascadePolicy = NoCascading;
168         this.isPrepared = false;
169         this.shouldUseWrapperPolicy = true;
170         this.shouldPrepare = true;
171         this.shouldBindAllParameters = Undefined;
172         this.shouldCacheStatement = Undefined;
173     }
174
175     /**
176      * PUBLIC:
177      * Add the argument named argumentName.
178      * This will cause the translation of references of argumentName in the receiver's expression,
179      * with the value of the argument as supplied to the query in order from executeQuery()
180      */

181     public void addArgument(String JavaDoc argumentName) {
182         // CR#3545 - Changed the default argument type to make argument types work more consistently
183
// with the SDK
184
addArgument(argumentName, java.lang.Object JavaDoc.class);
185     }
186
187     /**
188      * PUBLIC:
189      * Add the argument named argumentName and its class type.
190      * This will cause the translation of references of argumentName in the receiver's expression,
191      * with the value of the argument as supplied to the query in order from executeQuery().
192      * Specifying the class type is important if identically named queries are used but with
193      * different argument lists.
194      */

195     public void addArgument(String JavaDoc argumentName, Class JavaDoc type) {
196         getArguments().addElement(argumentName);
197         getArgumentTypes().addElement(type);
198         getArgumentTypeNames().addElement(type.getName());
199     }
200
201     /**
202      * PUBLIC:
203      * Add the argument named argumentName and its class type.
204      * This will cause the translation of references of argumentName in the receiver's expression,
205      * with the value of the argument as supplied to the query in order from executeQuery().
206      * Specifying the class type is important if identically named queries are used but with
207      * different argument lists.
208      */

209     public void addArgument(String JavaDoc argumentName, String JavaDoc typeAsString) {
210         getArguments().addElement(argumentName);
211         //bug 3197587
212
getArgumentTypes().addElement(Helper.getObjectClass(ConversionManager.loadClass(typeAsString)));
213         getArgumentTypeNames().addElement(typeAsString);
214     }
215
216     /**
217      * INTERNAL:
218      * Add an argument to the query, but do not resovle the class yet.
219      * This is useful for building a query without putting the domain classes
220      * on the classpath for the Mapping Workbench.
221      */

222     public void addArgumentByTypeName(String JavaDoc argumentName, String JavaDoc typeAsString) {
223         getArguments().addElement(argumentName);
224         getArgumentTypeNames().addElement(typeAsString);
225     }
226
227     /**
228      * PUBLIC:
229      * Add the argumentValue.
230      * Argument values must be added in the same order the arguments are defined.
231      */

232     public void addArgumentValue(Object JavaDoc argumentValue) {
233         getArgumentValues().addElement(argumentValue);
234     }
235
236     /**
237      * PUBLIC:
238      * Add the argumentValues to the query.
239      * Argument values must be added in the same order the arguments are defined.
240      */

241     public void addArgumentValues(Vector theArgumentValues) {
242         setArgumentValues(theArgumentValues);
243     }
244
245     /**
246      * PUBLIC:
247      * Used to define a store procedure or SQL query.
248      * This may be used for multiple SQL executions to be mapped to a single query.
249      * This cannot be used for cursored selects, delete alls or does exists.
250      */

251     public void addCall(Call call) {
252         setQueryMechanism(call.buildQueryMechanism(this, getQueryMechanism()));
253         // Must un-prepare is prepare as the SQL may change.
254
setIsPrepared(false);
255     }
256
257     /**
258      * PUBLIC:
259      * Used to define a statement level query.
260      * This may be used for multiple SQL executions to be mapped to a single query.
261      * This cannot be used for cursored selects, delete alls or does exists.
262      */

263     public void addStatement(SQLStatement statement) {
264         // bug 3524620: lazy-init query mechanism
265
if (!hasQueryMechanism()) {
266             setQueryMechanism(new StatementQueryMechanism(this));
267         } else if (!getQueryMechanism().isStatementQueryMechanism()) {
268             setQueryMechanism(new StatementQueryMechanism(this));
269         }
270         ((StatementQueryMechanism)getQueryMechanism()).getSQLStatements().addElement(statement);
271         // Must un-prepare is prepare as the SQL may change.
272
setIsPrepared(false);
273     }
274
275     /**
276      * PUBLIC:
277      * Bind all arguments to any SQL statement.
278      */

279     public void bindAllParameters() {
280         setShouldBindAllParameters(true);
281     }
282
283     /**
284      * INTERNAL:
285      * In the case of EJBQL, an expression needs to be generated. Build the required expression.
286      */

287     protected void buildSelectionCriteria(AbstractSession session) {
288         this.getQueryMechanism().buildSelectionCriteria(session);
289     }
290
291     /**
292      * PUBLIC:
293      * Cache the prepared statements, this requires full parameter binding as well.
294      */

295     public void cacheStatement() {
296         setShouldCacheStatement(true);
297     }
298
299     /**
300      * PUBLIC:
301      * Cascade the query and its properties on the queries object(s) and all objects related to the queries object(s).
302      * This includes private and independent relationships, but not read-only relationships.
303      * This will still stop on uninstantiated indirection objects except for deletion.
304      * Great caution should be used in using the property as the query may effect a large number of objects.
305      * This policy is used by the unit of work to ensure persistence by reachability.
306      */

307     public void cascadeAllParts() {
308         setCascadePolicy(CascadeAllParts);
309     }
310
311     /**
312      * PUBLIC:
313      * Cascade the query and its properties on the queries object(s) and all related objects where the mapping has
314      * been set to cascade the merge.
315      */

316     public void cascadeByMapping() {
317         setCascadePolicy(CascadeByMapping);
318     }
319
320     /**
321      * INTERNAL:
322      * Used by unit of work, only cascades constraint dependecies.
323      */

324     public void cascadeOnlyDependentParts() {
325         setCascadePolicy(CascadeDependentParts);
326     }
327
328     /**
329      * PUBLIC:
330      * Cascade the query and its properties on the queries object(s)
331      * and all privately owned objects related to the queries object(s).
332      * This is the default for write and delete queries.
333      * This policy should normally be used for refreshing, otherwise you could refresh half of any object.
334      */

335     public void cascadePrivateParts() {
336         setCascadePolicy(CascadePrivateParts);
337     }
338
339     /**
340      * INTERNAL:
341      * Ensure that the descriptor has been set.
342      */

343     public void checkDescriptor(AbstractSession session) throws QueryException {
344     }
345
346     /**
347      * INTERNAL:
348      * Check to see if this query already knows the return vale without preforming any further work.
349      */

350     public Object JavaDoc checkEarlyReturn(AbstractSession session, AbstractRecord translationRow) {
351         return null;
352     }
353
354     /**
355      * INTERNAL:
356      * Check to see if a custom query should be used for this query.
357      * This is done before the query is copied and prepared/executed.
358      * null means there is none.
359      */

360     protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
361         return null;
362     }
363
364     /**
365      * INTERNAL:
366      * Check to see if this query needs to be prepare and prepare it.
367      * The prepare is done on the original query to ensure that the work is not repeated.
368      */

369     public void checkPrepare(AbstractSession session, AbstractRecord translationRow) {
370         // This query is first prepared for global common state, this must be synced.
371
if (!isPrepared()) {// Avoid the monitor is already prepare, must check again for concurrency.
372
// Prepared queries cannot be custom as then they would never have been prepared.
373
synchronized (this) {
374                 if (!isPrepared()) {
375                     // When custom SQL is used there is a possibility that the SQL contains the # token.
376
// Avoid this by telling the call if this is custom SQL with parameters.
377
// This must not be called for SDK calls.
378
if ((isReadQuery() || isDataModifyQuery()) && isCallQuery() && (getQueryMechanism() instanceof CallQueryMechanism) && ((translationRow == null) || translationRow.isEmpty())) {
379                         // Must check for read object queries as the row will be empty until the prepare.
380
if (isReadObjectQuery() || isUserDefined()) {
381                             ((CallQueryMechanism)getQueryMechanism()).setCallHasCustomSQLArguments();
382                         }
383                     } else if (isCallQuery() && (getQueryMechanism() instanceof CallQueryMechanism)) {
384                         ((CallQueryMechanism)getQueryMechanism()).setCallHasCustomSQLArguments();
385                     }
386                     setSession(session);// Session is required for some init stuff.
387
prepare();
388                     setSession(null);
389                     setIsPrepared(true);// MUST not set prepare until done as other thread may hit before finihsing the prepare.
390
}
391             }
392         }
393     }
394
395     /**
396      * INTERNAL:
397      * Clone the query
398      */

399     public Object JavaDoc clone() {
400         try {
401             DatabaseQuery cloneQuery = (DatabaseQuery)super.clone();
402
403             // partial fix for 3054240
404
// need to pay attention to other components of the query, too MWN
405
if (cloneQuery.properties != null) {
406                 if (cloneQuery.properties.isEmpty()) {
407                     cloneQuery.setProperties(null);
408                 } else {
409                     cloneQuery.setProperties((Hashtable)getProperties().clone());
410                 }
411             }
412
413             // bug 3524620: now that the query mechanism is lazy-init'd,
414
// only clone the query mechanism if we have one.
415
if (hasQueryMechanism()) {
416                 cloneQuery.setQueryMechanism(getQueryMechanism().clone(cloneQuery));
417             }
418             cloneQuery.setIsPrepared(isPrepared());// Setting some things will trigger unprepare.
419
return cloneQuery;
420         } catch (CloneNotSupportedException JavaDoc e) {
421             return null;
422         }
423     }
424
425     /**
426      * INTERNAL
427      * Used to give the subclasses oportunity to copy aspects of the cloned query
428      * to the original query.
429      */

430     protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
431         //no-op for this class
432
}
433
434     /**
435      * INTERNAL:
436      * Convert all the class-name-based settings in this query to actual class-based
437      * settings
438      * This method is implemented by subclasses as necessary.
439      * @param classLoader
440      */

441     public void convertClassNamesToClasses(ClassLoader JavaDoc classLoader){
442         // note: normally we would fix the argument types here, but they are already
443
// lazily instantiated
444
};
445
446     /**
447      * INTERNAL:
448      * Added for backwards compatibility. shouldMaintainCache used to be tri-state and was converted to boolean.
449      * This method is used by deployment XML to properly convert the tri-state variable to a boolean
450      * Added for Bug 4034159
451      */

452     public void deploymentSetShouldMaintainCache(int maintainCache) {
453         // FalseUndefinedTrue.Undefined is intentionally left ignored so it will map to the default.
454
if (maintainCache == FalseUndefinedTrue.True) {
455             setShouldMaintainCache(true);
456         } else if (maintainCache == FalseUndefinedTrue.False) {
457             setShouldMaintainCache(false);
458         }
459     }
460
461     /**
462      * INTERNAL:
463      * Added for backwards compatibility. shouldMaintainCache used to be tri-state and was converted to boolean.
464      * This method is used by deployment XML to properly convert the tri-state variable to a boolean
465      * Added for Bug 4034159
466      */

467     public int deploymentShouldMaintainCache() {
468         if (shouldMaintainCache()) {
469             return FalseUndefinedTrue.True;
470         } else {
471             return FalseUndefinedTrue.False;
472         }
473     }
474
475     /**
476      * PUBLIC:
477      * Do not Bind all arguments to any SQL statement.
478      */

479     public void dontBindAllParameters() {
480         setShouldBindAllParameters(false);
481     }
482
483     /**
484      * PUBLIC:
485      * Dont cache the prepared statements, this requires full parameter binding as well.
486      */

487     public void dontCacheStatement() {
488         setShouldCacheStatement(false);
489     }
490
491     /**
492      * PUBLIC:
493      * Do not cascade the query and its properties on the queries object(s) relationships.
494      * This does not effect the queries private parts but only the object(s) direct row-level attributes.
495      * This is the default for read queries and can be used in writting if it is known that only
496      * row-level attributes changed, or to resolve circular foreign key dependencies.
497      */

498     public void dontCascadeParts() {
499         setCascadePolicy(NoCascading);
500     }
501
502     /**
503      * PUBLIC:
504      * Set for the identity map (cache) to be ignored completely.
505      * The cache check will be skipped and the result will not be put into the identity map.
506      * This can be used to retreive the exact state of an object on the database.
507      * By default the identity map is always maintained.
508      */

509     public void dontMaintainCache() {
510         setShouldMaintainCache(false);
511     }
512
513     /**
514      * INTERNAL:
515      * Execute the query
516      *
517      * @exception DatabaseException - an error has occurred on the database.
518      * @exception OptimisticLockException - an error has occurred using the optimistic lock feature.
519      * @return - the result of executing the query.
520      */

521     public abstract Object JavaDoc executeDatabaseQuery() throws DatabaseException, OptimisticLockException;
522
523     /**
524      * INTERNAL:
525      * Override query execution where Session is a UnitOfWork.
526      * <p>
527      * If there are objects in the cache return the results of the cache lookup.
528      *
529      * @param unitOfWork - the session in which the receiver will be executed.
530      * @param translationRow - the arguments
531      * @exception DatabaseException - an error has occurred on the database.
532      * @exception OptimisticLockException - an error has occurred using the optimistic lock feature.
533      * @return An object, the result of executing the query.
534      */

535     public Object JavaDoc executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
536         return execute(unitOfWork, translationRow);
537     }
538     
539     /**
540      * INTERNAL:
541      * Execute the query. If there are objects in the cache return the results
542      * of the cache lookup.
543      *
544      * @param session - the session in which the receiver will be executed.
545      * @exception DatabaseException - an error has occurred on the database.
546      * @exception OptimisticLockException - an error has occurred using the optimistic lock feature.
547      * @return An object, the result of executing the query.
548      */

549     public Object JavaDoc execute(AbstractSession session, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
550         DatabaseQuery queryToExecute = this;
551
552         // Profile the query preparation time.
553
session.startOperationProfile(SessionProfiler.QUERY_PREPARE);
554
555         // This allows the query to check the cache or return early without doing any work.
556
Object JavaDoc earlyReturn = queryToExecute.checkEarlyReturn(session, translationRow);
557         if ((earlyReturn != null) || (isReadObjectQuery() && ((ReadObjectQuery)this).shouldCheckCacheOnly())) {
558             // Profile the query preparation time.
559
session.endOperationProfile(SessionProfiler.QUERY_PREPARE);
560             return earlyReturn;
561         }
562
563         boolean hasCustomQuery = false;
564         if (!isPrepared() && shouldPrepare()) {
565             // Prepared queries cannot be custom as then they would never have been prepared.
566
DatabaseQuery customQuery = checkForCustomQuery(session, translationRow);
567             if (customQuery != null) {
568                 hasCustomQuery = true;
569                 // The custom query will be used not the original.
570
queryToExecute = customQuery;
571             }
572         }
573
574         // Sometimes a session will clone the query and mutate the clone. If so
575
// don't need to clone again.
576
// All queries on a HistoricalSession become historical queries.
577
// On a ServerSession bean-level pessimistic locking queries need to
578
// be replaced with non-locking versions.
579
boolean alreadyClonedQuery = false;
580         DatabaseQuery sessionPreparedQuery = session.prepareDatabaseQuery(queryToExecute);
581         if (sessionPreparedQuery != queryToExecute) {
582             queryToExecute = sessionPreparedQuery;
583             alreadyClonedQuery = true;
584         }
585
586         if (queryToExecute.shouldPrepare()) {
587             queryToExecute.checkPrepare(session, translationRow);
588         }
589
590         // Then cloned for concurrency and repeatable execution.
591
if (!alreadyClonedQuery) {
592             queryToExecute = (DatabaseQuery)queryToExecute.clone();
593         }
594         queryToExecute.setTranslationRow(translationRow);
595         // If the prepare has been disbale the clone is prepare dynamically to not parameterize the SQL.
596
if (!queryToExecute.shouldPrepare()) {
597             queryToExecute.checkPrepare(session, translationRow);
598         }
599         queryToExecute.setSession(session);
600         if (hasCustomQuery) {
601             prepareCustomQuery(queryToExecute);
602         }
603         queryToExecute.prepareForExecution();
604
605         // Profile the query preparation time.
606
session.endOperationProfile(SessionProfiler.QUERY_PREPARE);
607
608         // Then executed.
609
Object JavaDoc result = queryToExecute.executeDatabaseQuery();
610
611         //give the subclasses the oportunity to retreive aspects of the cloned query
612
clonedQueryExecutionComplete(queryToExecute, session);
613         return result;
614     }
615
616     /**
617      * INTERNAL:
618      * Return the accessor.
619      */

620     public Accessor getAccessor() {
621         return accessor;
622     }
623
624     /**
625      * INTERNAL:
626      * Return the arguments for use with the pre-defined query option
627      */

628     public Vector getArguments() {
629         if (arguments == null) {
630             arguments = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
631         }
632         return arguments;
633     }
634
635     /**
636      * INTERNAL:
637      * Return the argumentTypes for use with the pre-defined query option
638      */

639     public Vector getArgumentTypes() {
640         if ((argumentTypes == null) || argumentTypes.isEmpty()) {
641             argumentTypes = new Vector();
642             // Bug 3256198 - lazily initialize the argument types from their class names
643
if (argumentTypeNames != null) {
644                 Iterator args = argumentTypeNames.iterator();
645                 while (args.hasNext()) {
646                     String JavaDoc argumentTypeName = (String JavaDoc)args.next();
647                     argumentTypes.addElement(Helper.getObjectClass(ConversionManager.loadClass(argumentTypeName)));
648                 }
649             }
650         }
651         return argumentTypes;
652     }
653
654     /**
655      * INTERNAL:
656      * Return the argumentTypeNames for use with the pre-defined query option
657      * These are used pre-initialization to construct the argumentTypes list.
658      */

659     public Vector getArgumentTypeNames() {
660         if (argumentTypeNames == null) {
661             argumentTypeNames = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
662         }
663         return argumentTypeNames;
664     }
665
666     /**
667      * INTERNAL:
668      * Set the argumentTypes for use with the pre-defined query option
669      */

670     public void setArgumentTypes(Vector argumentTypes) {
671         this.argumentTypes = argumentTypes;
672         // bug 3256198 - ensure the list of type names matches the argument types.
673
getArgumentTypeNames().clear();
674         Iterator types = argumentTypes.iterator();
675         while (types.hasNext()) {
676             argumentTypeNames.addElement(((Class JavaDoc)types.next()).getName());
677         }
678     }
679
680     /**
681      * INTERNAL:
682      * Set the argumentTypes for use with the pre-defined query option
683      */

684     public void setArgumentTypeNames(Vector argumentTypeNames) {
685         this.argumentTypeNames = argumentTypeNames;
686     }
687
688     /**
689      * INTERNAL:
690      * Set the arguments for use with the pre-defined query option.
691      * Maintain the argumentTypes as well.
692      */

693     public void setArguments(Vector arguments) {
694         for (Enumeration enumtr = arguments.elements(); enumtr.hasMoreElements();) {
695             // Maintain the argumentTypes as well
696
addArgument((String JavaDoc)enumtr.nextElement());
697         }
698     }
699
700     /**
701      * INTERNAL:
702      * Return the argumentValues for use with the
703      * pre-defined query option
704      */

705     public Vector getArgumentValues() {
706         if (argumentValues == null) {
707             argumentValues = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
708         }
709         return argumentValues;
710     }
711
712     /**
713      * INTERNAL:
714      * Return the argumentValues for use with the
715      * pre-defined query option
716      */

717     public void setArgumentValues(Vector theArgumentValues) {
718         argumentValues = theArgumentValues;
719     }
720
721     /**
722      * INTERNAL:
723      * Return the call for this query.
724      * This call contains the SQL and argument list.
725      * @see #getDatasourceCall()
726      */

727     public DatabaseCall getCall() {
728         Call call = getDatasourceCall();
729         if (call instanceof DatabaseCall) {
730             return (DatabaseCall)call;
731         } else {
732             return null;
733         }
734     }
735
736     /**
737      * ADVANCED:
738      * Return the call for this query.
739      * This call contains the SQL and argument list.
740      * @see #prepareCall(Session, DatabaseRow);
741      */

742     public Call getDatasourceCall() {
743         Call call = null;
744         if (getQueryMechanism() instanceof DatasourceCallQueryMechanism) {
745             DatasourceCallQueryMechanism mechanism = (DatasourceCallQueryMechanism)getQueryMechanism();
746             call = mechanism.getCall();
747             // If has multiple calls return the first one.
748
if (mechanism.hasMultipleCalls()) {
749                 call = (Call)mechanism.getCalls().get(0);
750             }
751         }
752         if ((call == null) && getQueryMechanism().isEJBQLCallQueryMechanism()) {
753             call = ((EJBQLCallQueryMechanism)getQueryMechanism()).getEJBQLCall();
754         }
755         return call;
756     }
757
758     /**
759      * ADVANCED:
760      * Return the calls for this query. This method can be called for queries with multiple calls
761      * This call contains the SQL and argument list.
762      * @see #prepareCall(Session, DatabaseRow);
763      */

764     public List getDatasourceCalls() {
765         List calls = new Vector();
766         if (getQueryMechanism() instanceof DatasourceCallQueryMechanism) {
767             DatasourceCallQueryMechanism mechanism = (DatasourceCallQueryMechanism)getQueryMechanism();
768
769             // If has multiple calls return the first one.
770
if (mechanism.hasMultipleCalls()) {
771                 calls = mechanism.getCalls();
772             } else {
773                 calls.add(mechanism.getCall());
774             }
775         }
776         if ((calls.isEmpty()) && getQueryMechanism().isEJBQLCallQueryMechanism()) {
777             calls.add(((EJBQLCallQueryMechanism)getQueryMechanism()).getEJBQLCall());
778         }
779         return calls;
780     }
781
782     /**
783      * INTERNAL:
784      * Return the cascade policy.
785      */

786     public int getCascadePolicy() {
787         return cascadePolicy;
788     }
789
790     /**
791      * INTERNAL:
792      * Return the descriptor assigned with the reference class
793      */

794     public ClassDescriptor getDescriptor() {
795         return descriptor;
796     }
797
798     /**
799      * PUBLIC:
800      * Return the name of the query
801      */

802     public String JavaDoc getName() {
803         return name;
804     }
805
806     /**
807      * INTERNAL:
808      * Property support for use by mappings.
809      */

810     public Hashtable getProperties() {
811         if (properties == null) {//Lazy initialize to conserve space and allocation time.
812
properties = new Hashtable(5);
813         }
814         return properties;
815     }
816
817     /**
818      * INTERNAL:
819      * Property support used by mappings to stach temporary stuff in the query.
820      */

821     public synchronized Object JavaDoc getProperty(Object JavaDoc property) {
822         if (properties == null) {
823             return null;
824         }
825         return getProperties().get(property);
826     }
827
828     /**
829      * INTERNAL:
830      * Return the mechanism assigned to the query
831      */

832     public DatabaseQueryMechanism getQueryMechanism() {
833         // Bug 3524620 - lazy init
834
if (queryMechanism == null) {
835             queryMechanism = new ExpressionQueryMechanism(this);
836         }
837         return queryMechanism;
838     }
839
840     /**
841      * INTERNAL:
842      * Check if the mechanism has been set yet, used for lazy init.
843      */

844     public boolean hasQueryMechanism() {
845         return (queryMechanism != null);
846     }
847
848     /**
849      * PUBLIC:
850      * Return the domain class associated with this query.
851      * By default this is null, but should be overridden in subclasses.
852      */

853     public Class JavaDoc getReferenceClass() {
854         return null;
855     }
856
857     /**
858      * INTERNAL:
859      * return the name of the reference class. Added for Mapping Workbench removal
860      * of classpath dependancy. Overriden by subclasses.
861      */

862     public String JavaDoc getReferenceClassName() {
863         return null;
864     }
865
866     /**
867      * PUBLIC:
868      * Return the selection criteria of the query.
869      * This should only be used with expression queries, null will be returned for others.
870      */

871     public Expression getSelectionCriteria() {
872         return getQueryMechanism().getSelectionCriteria();
873     }
874
875     /**
876      * INTERNAL:
877      * Return the current session.
878      */

879     public AbstractSession getSession() {
880         return session;
881     }
882
883     /**
884      * PUBLIC:
885      * Return the name of the session that the query should be executed under.
886      * This can be with the session broker to override the default session.
887      */

888     public String JavaDoc getSessionName() {
889         return sessionName;
890     }
891
892     /**
893      * PUBLIC:
894      * Return the SQL statement of the query.
895      * This can only be used with statement queries.
896      */

897     public SQLStatement getSQLStatement() {
898         return ((StatementQueryMechanism)getQueryMechanism()).getSQLStatement();
899     }
900
901     /**
902      * PUBLIC:
903      * Return the SQL string of the query.
904      * This can be used for SQL queries.
905      * ADVANCED:
906      * This can also be used for normal queries if they have been prepared, (i.e. query.prepareCall()).
907      * @see #prepareCall(Session, DatabaseRow)
908      */

909     public String JavaDoc getEJBQLString() {
910         if (!(getQueryMechanism().isEJBQLCallQueryMechanism())) {
911             return null;
912         }
913         EJBQLCall call = (EJBQLCall)((EJBQLCallQueryMechanism)getQueryMechanism()).getEJBQLCall();
914         return call.getEjbqlString();
915     }
916
917     /**
918      * PUBLIC:
919      * Return the SQL string of the query.
920      * This can be used for SQL queries.
921      * ADVANCED:
922      * This can also be used for normal queries if they have been prepared, (i.e. query.prepareCall()).
923      * @see #prepareCall(Session, DatabaseRow)
924      */

925     public String JavaDoc getSQLString() {
926         Call call = getDatasourceCall();
927         if (call == null) {
928             return null;
929         }
930         if (!(call instanceof SQLCall)) {
931             return null;
932         }
933
934         return ((SQLCall)call).getSQLString();
935     }
936
937     /**
938      * PUBLIC:
939      * Return the SQL strings of the query. Used for queries with multiple calls
940      * This can be used for SQL queries.
941      * ADVANCED:
942      * This can also be used for normal queries if they have been prepared, (i.e. query.prepareCall()).
943      * @see #prepareCall(Session, DatabaseRow)
944      */

945     public List getSQLStrings() {
946         List calls = getDatasourceCalls();
947         if ((calls == null) || calls.isEmpty()) {
948             return null;
949         }
950         Vector returnSQL = new Vector(calls.size());
951         Iterator iterator = calls.iterator();
952         while (iterator.hasNext()) {
953             Call call = (Call)iterator.next();
954             if (!(call instanceof SQLCall)) {
955                 return null;
956             }
957             returnSQL.addElement(((SQLCall)call).getSQLString());
958         }
959         return returnSQL;
960     }
961
962     /**
963      * INTERNAL:
964      * Returns the internal tri-state calue of shouldBindParameters
965      * used far cascading these settings
966      */

967     public int getShouldBindAllParameters() {
968         return this.shouldBindAllParameters;
969     }
970
971     /**
972      * ADVANCED:
973      * This can be used to access a queries translated SQL if they have been prepared, (i.e. query.prepareCall()).
974      * The Record argument is one of (DatabaseRow, XMLRecord) that contains the query arguments.
975      * @see #prepareCall(oracle.toplink.essentials.sessions.Session, Record)
976      */

977     public String JavaDoc getTranslatedSQLString(oracle.toplink.essentials.sessions.Session session, Record translationRow) {
978         //CR#2859559 fix to use Session and Record interfaces not impl classes.
979
CallQueryMechanism queryMechanism = (CallQueryMechanism)getQueryMechanism();
980         if (queryMechanism.getCall() == null) {
981             return null;
982         }
983         SQLCall call = (SQLCall)queryMechanism.getCall().clone();
984         call.translate((AbstractRecord)translationRow, queryMechanism.getModifyRow(), (AbstractSession)session);
985         return call.getSQLString();
986     }
987
988     /**
989      * ADVANCED:
990      * This can be used to access a queries translated SQL if they have been prepared, (i.e. query.prepareCall()).
991      * This method can be used for queries with multiple calls.
992      * @see #prepareCall(Session, DatabaseRow)
993      */

994     public List getTranslatedSQLStrings(oracle.toplink.essentials.sessions.Session session, Record translationRow) {
995         CallQueryMechanism queryMechanism = (CallQueryMechanism)getQueryMechanism();
996         if ((queryMechanism.getCalls() == null) || queryMechanism.getCalls().isEmpty()) {
997             return null;
998         }
999         Vector calls = new Vector(queryMechanism.getCalls().size());
1000        Iterator iterator = queryMechanism.getCalls().iterator();
1001        while (iterator.hasNext()) {
1002            SQLCall call = (SQLCall)iterator.next();
1003            call = (SQLCall)call.clone();
1004            call.translate((AbstractRecord)translationRow, queryMechanism.getModifyRow(), (AbstractSession)session);
1005            calls.addElement(call.getSQLString());
1006        }
1007        return calls;
1008    }
1009
1010    /**
1011     * INTERNAL:
1012     * Return the row for translation
1013     */

1014    public AbstractRecord getTranslationRow() {
1015        return translationRow;
1016    }
1017
1018    /**
1019     * INTERNAL:
1020     * returns true if the accessor has already been set. The getAccessor() will attempt to
1021     * lazily initialzie it.
1022     */

1023    public boolean hasAccessor() {
1024        return accessor != null;
1025    }
1026
1027    /**
1028     * INTERNAL:
1029     * Return if any properties exist in the query.
1030     */

1031    public boolean hasProperties() {
1032        return (properties != null) && (!properties.isEmpty());
1033    }
1034
1035    /**
1036     * PUBLIC:
1037     * Return if a name of the session that the query should be executed under has been specified.
1038     * This can be with the session broker to override the default session.
1039     */

1040    public boolean hasSessionName() {
1041        return sessionName != null;
1042    }
1043
1044    /**
1045     * PUBLIC:
1046     * Session's shouldBindAllParameters() defines whether to bind or not
1047     * (default setting)
1048     */

1049    public void ignoreBindAllParameters() {
1050        this.shouldBindAllParameters = Undefined;
1051    }
1052
1053    /**
1054     * PUBLIC:
1055     * Session's shouldCacheAllStatements() defines whether to cache or not
1056     * (default setting)
1057     */

1058    public void ignoreCacheStatement() {
1059        this.shouldCacheStatement = Undefined;
1060    }
1061
1062    /**
1063     * PUBLIC:
1064     * Return true if this query uses an SQL or stored procedure, or SDK call.
1065     */

1066    public boolean isCallQuery() {
1067        return getQueryMechanism().isCallQueryMechanism();
1068    }
1069
1070    /**
1071     * INTERNAL:
1072     * Returns true if this query has been created as the result of cascading a delete of an aggregate collection
1073     * in a UnitOfWork
1074     * CR 2811
1075     */

1076    public boolean isCascadeOfAggregateDelete() {
1077        return getCascadePolicy() == CascadeAggregateDelete;
1078    }
1079
1080    /**
1081     * PUBLIC:
1082     * Return if this is a data modify query.
1083     */

1084    public boolean isDataModifyQuery() {
1085        return false;
1086    }
1087
1088    /**
1089     * PUBLIC:
1090     * Return if this is a data read query.
1091     */

1092    public boolean isDataReadQuery() {
1093        return false;
1094    }
1095
1096    /**
1097     * PUBLIC:
1098     * Return if this is a delete all query.
1099     */

1100    public boolean isDeleteAllQuery() {
1101        return false;
1102    }
1103
1104    /**
1105     * PUBLIC:
1106     * Return if this is a delete object query.
1107     */

1108    public boolean isDeleteObjectQuery() {
1109        return false;
1110    }
1111
1112    /**
1113     * PUBLIC:
1114     * Return true if this query uses an expression query mechanism
1115     */

1116    public boolean isExpressionQuery() {
1117        return getQueryMechanism().isExpressionQueryMechanism();
1118    }
1119
1120    /**
1121     * PUBLIC:
1122     * Return true if this is a modify all query.
1123     */

1124    public boolean isModifyAllQuery() {
1125        return false;
1126    }
1127
1128    /**
1129     * PUBLIC:
1130     * Return true if this is a modify query.
1131     */

1132    public boolean isModifyQuery() {
1133        return false;
1134    }
1135
1136    /**
1137       * PUBLIC:
1138       * Return true if this is an update all query.
1139       */

1140    public boolean isUpdateAllQuery() {
1141        return false;
1142    }
1143
1144    /**
1145     * PUBLIC:
1146     * Return true if this is an update object query.
1147     */

1148    public boolean isUpdateObjectQuery() {
1149        return false;
1150    }
1151
1152    /**
1153     * PUBLIC:
1154     * If executed against a RepeatableWriteUnitOfWork if this attribute is true
1155     * TopLink will write changes to the database before executing the query.
1156     */

1157    public Boolean JavaDoc getFlushOnExecute(){
1158        return this.flushOnExecute;
1159    }
1160    
1161    /**
1162     * PUBLIC:
1163     * Return true if this is an insert object query.
1164     */

1165    public boolean isInsertObjectQuery() {
1166        return false;
1167    }
1168
1169    /**
1170     * PUBLIC:
1171     * Return true if this is an object level modify query.
1172     */

1173    public boolean isObjectLevelModifyQuery() {
1174        return false;
1175    }
1176
1177    /**
1178     * PUBLIC:
1179     * Return true if this is an object level read query.
1180     */

1181    public boolean isObjectLevelReadQuery() {
1182        return false;
1183    }
1184
1185    /**
1186     * PUBLIC:
1187     * Return if this is an object building query.
1188     */

1189    public boolean isObjectBuildingQuery() {
1190        return true;
1191    }
1192
1193    /**
1194     * INTERNAL:
1195     * Queries are prepared when they are executed and then do not need to be
1196     * prepared on subsequent executions. This method returns true if this
1197     * query has been prepared. Updating the settings on a query will 'un-prepare'
1198     * the query.
1199     */

1200    public boolean isPrepared() {
1201        return isPrepared;
1202    }
1203
1204    /**
1205     * PUBLIC:
1206     * Return true if this is a read all query.
1207     */

1208    public boolean isReadAllQuery() {
1209        return false;
1210    }
1211
1212    /**
1213     * PUBLIC:
1214     * Return ture if this is a read object query.
1215     */

1216    public boolean isReadObjectQuery() {
1217        return false;
1218    }
1219
1220    /**
1221     * PUBLIC:
1222     * Return true if this is a read query.
1223     */

1224    public boolean isReadQuery() {
1225        return false;
1226    }
1227
1228    /**
1229     * PUBLIC:
1230     * Return true if this is a report query.
1231     */

1232    public boolean isReportQuery() {
1233        return false;
1234    }
1235
1236    /**
1237     * PUBLIC:
1238     * Return true if this query uses an SQL query mechanism .
1239     */

1240    public boolean isSQLCallQuery() {
1241        // BUG#2669342 CallQueryMechanism and isCallQueryMechanism have different meaning as SDK return true but isn't.
1242
Call call = getDatasourceCall();
1243        return (call != null) && (call instanceof SQLCall);
1244    }
1245
1246    /**
1247     * INTERNAL:
1248     * Return true if the query is a custom user defined query.
1249     */

1250    public boolean isUserDefined() {
1251        return isUserDefined;
1252    }
1253
1254    /**
1255     * PUBLIC:
1256     * Return true if this is a write object query.
1257     */

1258    public boolean isWriteObjectQuery() {
1259        return false;
1260    }
1261
1262    /**
1263     * PUBLIC:
1264     * Set for the identity map (cache) to be maintained.
1265     * This is the default.
1266     */

1267    public void maintainCache() {
1268        setShouldMaintainCache(true);
1269    }
1270
1271    /**
1272     * INTERNAL:
1273     * This is different from 'prepareForExecution' in that this is called on the original query,
1274     * and the other is called on the copy of the query.
1275     * This query is copied for concurrency so this prepare can only setup things that
1276     * will apply to any future execution of this query.
1277     *
1278     * Resolve the queryTimeout using the DescriptorQueryManager if required.
1279     */

1280    protected void prepare() throws QueryException {
1281         getQueryMechanism().prepare();
1282    }
1283
1284    /**
1285     * ADVANCED:
1286     * Pre-generate the call/SQL for the query.
1287     * This method takes a Session and an implementor of Record (DatebaseRow or XMLRecord).
1288     * This can be used to access the SQL for a query without executing it.
1289     * To access the call use, query.getCall(), or query.getSQLString() for the SQL.
1290     * Note the SQL will have argument markers in it (i.e. "?").
1291     * To translate these use query.getTranslatedSQLString(session, translationRow).
1292     * @see #getCall()
1293     * @see #getSQLString()
1294     * @see #getTranslatedSQLString(oracle.toplink.essentials.sessions.Session, Record)
1295     */

1296    public void prepareCall(oracle.toplink.essentials.sessions.Session session, Record translationRow) throws QueryException {
1297        //CR#2859559 fix to use Session and Record interfaces not impl classes.
1298
checkPrepare((AbstractSession)session, (AbstractRecord)translationRow);
1299    }
1300
1301    /**
1302     * INTERNAL:
1303     * Set the properties needed to be cascaded into the custom query.
1304     */

1305    protected void prepareCustomQuery(DatabaseQuery customQuery) {
1306        // Nothing by default.
1307
}
1308
1309    /**
1310     * INTERNAL:
1311     * Prepare the receiver for execution in a session. In particular,
1312     * set the descriptor of the receiver to the Descriptor for the
1313     * appropriate class for the receiver's object.
1314     */

1315    public void prepareForExecution() throws QueryException {
1316        getQueryMechanism().prepareForExecution();
1317    }
1318
1319    protected void prepareForRemoteExecution() {
1320        ;
1321    }
1322
1323    /**
1324     * INTERNAL:
1325     * Property support used by mappings.
1326     */

1327    public void removeProperty(Object JavaDoc property) {
1328        getProperties().remove(property);
1329    }
1330
1331    /**
1332     * INTERNAL:
1333     * Translate argumentValues into a database row.
1334     */

1335    public AbstractRecord rowFromArguments(Vector argumentValues) throws QueryException {
1336        Vector argumentNames = getArguments();
1337
1338        if (argumentNames.size() != argumentValues.size()) {
1339            throw QueryException.argumentSizeMismatchInQueryAndQueryDefinition(this);
1340        }
1341
1342        AbstractRecord row = new DatabaseRecord();
1343        for (int index = 0; index < argumentNames.size(); index++) {
1344            String JavaDoc argumentName = (String JavaDoc)argumentNames.elementAt(index);
1345            Object JavaDoc argumentValue = argumentValues.elementAt(index);
1346            row.put(new DatabaseField(argumentName), argumentValue);
1347        }
1348
1349        return row;
1350    }
1351
1352    /**
1353     * INTERNAL:
1354     * Set the accessor, the query must always use the same accessor for database access.
1355     * This is required to support connection pooling.
1356     */

1357    public void setAccessor(Accessor accessor) {
1358        this.accessor = accessor;
1359    }
1360
1361    /**
1362     * PUBLIC:
1363     * Used to define a store procedure or SQL query.
1364     */

1365    public void setDatasourceCall(Call call) {
1366        if (call == null) {
1367            return;
1368        }
1369        setQueryMechanism(call.buildNewQueryMechanism(this));
1370    }
1371
1372    /**
1373     * PUBLIC:
1374     * Used to define a store procedure or SQL query.
1375     */

1376    public void setCall(Call call) {
1377        setDatasourceCall(call);
1378    }
1379
1380    /**
1381     * INTERNAL:
1382     * Set the cascade policy.
1383     */

1384    public void setCascadePolicy(int policyConstant) {
1385        cascadePolicy = policyConstant;
1386    }
1387
1388    /**
1389     * INTERNAL:
1390     * Set the descriptor for the query.
1391     */

1392    public void setDescriptor(ClassDescriptor descriptor) {
1393        // If the descriptor changed must unprepare as the SQL may change.
1394
if (this.descriptor != descriptor) {
1395            setIsPrepared(false);
1396        }
1397        this.descriptor = descriptor;
1398    }
1399
1400    /**
1401     * PUBLIC:
1402     * To any user of this object. Set the EJBQL string of the query.
1403     * If arguments are required in the string they will be preceeded by "?" then the argument number.
1404     */

1405    public void setEJBQLString(String JavaDoc ejbqlString) {
1406        //Added the check for when we are building the query from the deployment XML
1407
if ((ejbqlString != null) && (!ejbqlString.equals(""))) {
1408            EJBQLCallQueryMechanism mechanism = new EJBQLCallQueryMechanism(this, new EJBQLCall(ejbqlString));
1409            setQueryMechanism(mechanism);
1410        }
1411    }
1412
1413    /**
1414     * PUBLIC:
1415     * If executed against a RepeatableWriteUnitOfWork if this attribute is true
1416     * TopLink will write changes to the database before executing the query.
1417     */

1418    public void setFlushOnExecute(Boolean JavaDoc flushMode){
1419        this.flushOnExecute = flushMode;
1420    }
1421    
1422    /**
1423     * INTERNAL:
1424     * If changes are made to the query that affect the derived SQL or Call
1425     * parameters the query needs to be prepared again.
1426     * <p>
1427     * Automatically called internally.
1428     */

1429    public void setIsPrepared(boolean isPrepared) {
1430        this.isPrepared = isPrepared;
1431    }
1432
1433    /**
1434     * INTERNAL:
1435     * Set if the query is a custom user defined query.
1436     */

1437    public void setIsUserDefined(boolean isUserDefined) {
1438        this.isUserDefined = isUserDefined;
1439    }
1440
1441    /**
1442     * PUBLIC:
1443     * Set the query's name.
1444     * Queries can be named and added to a descriptor or the session and then referenced by name.
1445     */

1446    public void setName(String JavaDoc queryName) {
1447        name = queryName;
1448    }
1449
1450    /**
1451     * INTERNAL:
1452     * Property support used by mappings.
1453     */

1454    public void setProperties(Hashtable properties) {
1455        this.properties = properties;
1456    }
1457
1458    /**
1459     * INTERNAL:
1460     * Property support used by mappings to stache temporary stuff.
1461     */

1462    public synchronized void setProperty(Object JavaDoc property, Object JavaDoc value) {
1463        getProperties().put(property, value);
1464    }
1465
1466    /**
1467     * Set the query mechanism for the query.
1468     */

1469    protected void setQueryMechanism(DatabaseQueryMechanism queryMechanism) {
1470        this.queryMechanism = queryMechanism;
1471        // Must un-prepare is prepare as the SQL may change.
1472
setIsPrepared(false);
1473    }
1474
1475    /**
1476     * PUBLIC:
1477     * To any user of this object. Set the selection criteria of the query.
1478     * This method be used when dealing with expressions.
1479     */

1480    public void setSelectionCriteria(Expression expression) {
1481        // Do not overwrite the call if the expression is null.
1482
if ((expression == null) && (!getQueryMechanism().isExpressionQueryMechanism())) {
1483            return;
1484        }
1485        if (!getQueryMechanism().isExpressionQueryMechanism()) {
1486            setQueryMechanism(new ExpressionQueryMechanism(this, expression));
1487        } else {
1488            ((ExpressionQueryMechanism)getQueryMechanism()).setSelectionCriteria(expression);
1489        }
1490
1491        // Must un-prepare is prepare as the SQL may change.
1492
setIsPrepared(false);
1493    }
1494
1495    /**
1496     * INTERNAL:
1497     * Set the session for the query
1498     */

1499    public void setSession(AbstractSession session) {
1500        this.session = session;
1501    }
1502
1503    /**
1504     * PUBLIC:
1505     * Set the name of the session that the query should be executed under.
1506     * This can be with the session broker to override the default session.
1507     */

1508    public void setSessionName(String JavaDoc sessionName) {
1509        this.sessionName = sessionName;
1510    }
1511
1512    /**
1513     * PUBLIC:
1514     * Bind all arguments to any SQL statement.
1515     */

1516    public void setShouldBindAllParameters(boolean shouldBindAllParameters) {
1517        if (shouldBindAllParameters) {
1518            this.shouldBindAllParameters = True;
1519        } else {
1520            this.shouldBindAllParameters = False;
1521        }
1522        setIsPrepared(false);
1523    }
1524
1525    /**
1526     * INTERNAL:
1527     * Sets the internal tri-state value of shouldBindAllParams
1528     * Used to cascade this value to alther queries
1529     */

1530    public void setShouldBindAllParameters(int bindAllParams) {
1531        this.shouldBindAllParameters = bindAllParams;
1532    }
1533
1534    /**
1535     * PUBLIC:
1536     * Cache the prepared statements, this requires full parameter binding as well.
1537     */

1538    public void setShouldCacheStatement(boolean shouldCacheStatement) {
1539        if (shouldCacheStatement) {
1540            this.shouldCacheStatement = True;
1541        } else {
1542            this.shouldCacheStatement = False;
1543        }
1544        setIsPrepared(false);
1545    }
1546
1547    /**
1548     * PUBLIC:
1549     * Set if the identity map (cache) should be used or not.
1550     * If not the cache check will be skipped and the result will not be put into the identity map.
1551     * By default the identity map is always maintained.
1552     */

1553    public void setShouldMaintainCache(boolean shouldMaintainCache) {
1554        this.shouldMaintainCache = shouldMaintainCache;
1555    }
1556
1557    /**
1558     * PUBLIC:
1559     * Set if the query should be prepared.
1560     * TopLink automatically prepares queries to generate their SQL only once,
1561     * one each execution of the query the SQL does not need to be generated again only the arguments need to be translated.
1562     * This option is provide to disable this optimization as in can cause problems with certain types of queries that require dynamic SQL basd on their arguments.
1563     * <p>These queries include:
1564     * <ul>
1565     * <li> Expressions that make use of 'equal' where the argument value has the potential to be null, this can cause problems on databases that require IS NULL, instead of = NULL.
1566     * <li> Expressions that make use of 'in' and that use parameter binding, this will cause problems as the in values must be bound individually.
1567     * </ul>
1568     */

1569    public void setShouldPrepare(boolean shouldPrepare) {
1570        this.shouldPrepare = shouldPrepare;
1571        setIsPrepared(false);
1572    }
1573
1574    /**
1575     * ADVANCED:
1576     * The wrapper policy can be enable on a query.
1577     */

1578    public void setShouldUseWrapperPolicy(boolean shouldUseWrapperPolicy) {
1579        this.shouldUseWrapperPolicy = shouldUseWrapperPolicy;
1580    }
1581
1582    /**
1583     * PUBLIC:
1584     * To any user of this object. Set the SQL statement of the query.
1585     * This method should only be used when dealing with statement objects.
1586     */

1587    public void setSQLStatement(SQLStatement sqlStatement) {
1588        setQueryMechanism(new StatementQueryMechanism(this, sqlStatement));
1589    }
1590
1591    /**
1592     * PUBLIC:
1593     * To any user of this object. Set the SQL string of the query.
1594     * This method should only be used when dealing with user defined SQL strings.
1595     * If arguments are required in the string they will be preceeded by "#" then the argument name.
1596     */

1597    public void setSQLString(String JavaDoc sqlString) {
1598        //Added the check for when we are building the query from the deployment XML
1599
if ((sqlString != null) && (!sqlString.equals(""))) {
1600            setCall(new SQLCall(sqlString));
1601        }
1602    }
1603
1604    /**
1605     * INTERNAL:
1606     * Set the row for translation
1607     */

1608    public void setTranslationRow(AbstractRecord translationRow) {
1609        this.translationRow = translationRow;
1610    }
1611
1612    /**
1613     * PUBLIC:
1614     * Bind all arguments to any SQL statement.
1615     */

1616    public boolean shouldBindAllParameters() {
1617        return shouldBindAllParameters == True;
1618    }
1619
1620    /**
1621     * PUBLIC:
1622     * Cache the prepared statements, this requires full parameter binding as well.
1623     */

1624    public boolean shouldCacheStatement() {
1625        return shouldCacheStatement == True;
1626    }
1627
1628    /**
1629     * PUBLIC:
1630     * Flag used to determine if all parts should be cascaded
1631     */

1632    public boolean shouldCascadeAllParts() {
1633        return getCascadePolicy() == CascadeAllParts;
1634    }
1635
1636    /**
1637     * PUBLIC:
1638     * Mappings should be checked to determined if the current operation should be
1639     * cascaded to the objects referenced.
1640     */

1641    public boolean shouldCascadeByMapping() {
1642        return getCascadePolicy() == CascadeByMapping;
1643    }
1644
1645    /**
1646     * INTERNAL:
1647     * Flag used for unit of works cascade policy.
1648     */

1649    public boolean shouldCascadeOnlyDependentParts() {
1650        return getCascadePolicy() == CascadeDependentParts;
1651    }
1652
1653    /**
1654     * PUBLIC:
1655     * Flag used to determine if any parts should be cascaded
1656     */

1657    public boolean shouldCascadeParts() {
1658        return getCascadePolicy() != NoCascading;
1659    }
1660
1661    /**
1662     * PUBLIC:
1663     * Flag used to determine if any private parts should be cascaded
1664     */

1665    public boolean shouldCascadePrivateParts() {
1666        return (getCascadePolicy() == CascadePrivateParts) || (getCascadePolicy() == CascadeAllParts);
1667    }
1668
1669    /**
1670     * PUBLIC:
1671     * Local shouldBindAllParameters() should be ignored,
1672     * Session's shouldBindAllParameters() should be used.
1673     */

1674    public boolean shouldIgnoreBindAllParameters() {
1675        return shouldBindAllParameters == Undefined;
1676    }
1677
1678    /**
1679     * PUBLIC:
1680     * Local shouldCacheStatement() should be ignored,
1681     * Session's shouldCacheAllStatements() should be used.
1682     */

1683    public boolean shouldIgnoreCacheStatement() {
1684        return shouldCacheStatement == Undefined;
1685    }
1686
1687    /**
1688     * PUBLIC:
1689     * Return if the identity map (cache) should be used or not.
1690     * If not the cache check will be skipped and the result will not be put into the identity map.
1691     * By default the identity map is always maintained.
1692     */

1693    public boolean shouldMaintainCache() {
1694        return shouldMaintainCache;
1695    }
1696
1697    /**
1698     * PUBLIC:
1699     * Return if the query should be prepared.
1700     * TopLink automatically prepares queries to generate their SQL only once,
1701     * one each execution of the query the SQL does not need to be generated again only the arguments need to be translated.
1702     * This option is provide to disable this optimization as in can cause problems with certain types of queries that require dynamic SQL basd on their arguments.
1703     * <p>These queries include:
1704     * <ul>
1705     * <li> Expressions that make use of 'equal' where the argument value has the potential to be null, this can cause problems on databases that require IS NULL, instead of = NULL.
1706     * <li> Expressions that make use of 'in' and that use parameter binding, this will cause problems as the in values must be bound individually.
1707     * </ul>
1708     */

1709    public boolean shouldPrepare() {
1710        return shouldPrepare;
1711    }
1712
1713    /**
1714     * ADVANCED:
1715     * The wrapper policy can be enabled on a query.
1716     */

1717    public boolean shouldUseWrapperPolicy() {
1718        return shouldUseWrapperPolicy;
1719    }
1720
1721    public String JavaDoc toString() {
1722        return Helper.getShortClassName(getClass()) + "()";
1723    }
1724}
1725
Popular Tags