001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
005: *
006: *
007: * The contents of this file are subject to the terms of either the GNU
008: * General Public License Version 2 only ("GPL") or the Common Development
009: * and Distribution License("CDDL") (collectively, the "License"). You
010: * may not use this file except in compliance with the License. You can obtain
011: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
012: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
013: * language governing permissions and limitations under the License.
014: *
015: * When distributing the software, include this License Header Notice in each
016: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
017: * Sun designates this particular file as subject to the "Classpath" exception
018: * as provided by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the License
020: * Header, with the fields enclosed by brackets [] replaced by your own
021: * identifying information: "Portions Copyrighted [year]
022: * [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * If you wish your version of this file to be governed by only the CDDL or
027: * only the GPL Version 2, indicate your decision by adding "[Contributor]
028: * elects to include this software in this distribution under the [CDDL or GPL
029: * Version 2] license." If you don't indicate a single choice of license, a
030: * recipient has the option to distribute your version of this file under
031: * either the CDDL, the GPL Version 2 or to extend the choice of license to
032: * its licensees as provided above. However, if you add GPL Version 2 code
033: * and therefore, elected the GPL Version 2 license, then the option applies
034: * only if the new code is made subject to such option by the copyright
035: * holder.
036: */
037: package oracle.toplink.essentials.queryframework;
038:
039: import java.util.*;
040: import oracle.toplink.essentials.internal.helper.*;
041: import oracle.toplink.essentials.exceptions.*;
042: import oracle.toplink.essentials.internal.queryframework.*;
043: import oracle.toplink.essentials.internal.sessions.AbstractRecord;
044:
045: /**
046: * <p><b>Purpose</b>:
047: * Concrete class to perform read using raw SQL.
048: * <p>
049: * <p><b>Responsibilities</b>:
050: * Execute a selecting raw SQL string.
051: * This returns a Collection of the DatabaseRows representing the result set.
052: *
053: * @author Yvon Lavoie
054: * @since TOPLink/Java 1.0
055: */
056: public class DataReadQuery extends ReadQuery {
057: protected ContainerPolicy containerPolicy;
058:
059: //** For EJB 3 support returns results without using the AbstractRecord */
060: protected boolean useAbstractRecord = true;
061:
062: /**
063: * PUBLIC:
064: * Initialize the state of the query.
065: */
066: public DataReadQuery() {
067: super ();
068: this .shouldMaintainCache = false;
069: useAbstractRecord = true;
070: setContainerPolicy(ContainerPolicy
071: .buildPolicyFor(ClassConstants.Vector_class));
072: }
073:
074: /**
075: * PUBLIC:
076: * Initialize the query to use the specified SQL string.
077: */
078: public DataReadQuery(String sqlString) {
079: this ();
080: setSQLString(sqlString);
081: }
082:
083: /**
084: * PUBLIC:
085: * Initialize the query to use the specified call.
086: */
087: public DataReadQuery(Call call) {
088: this ();
089: setCall(call);
090: }
091:
092: /**
093: * INTERNAL:
094: * Clone the query.
095: */
096: public Object clone() {
097: DataReadQuery cloneQuery = (DataReadQuery) super .clone();
098: cloneQuery.setContainerPolicy(getContainerPolicy().clone(
099: cloneQuery));
100: return cloneQuery;
101: }
102:
103: /**
104: * INTERNAL:
105: * Execute the query.
106: * Perform the work to execute the SQL string.
107: * @exception DatabaseException an error has occurred on the database
108: * @return a collection or cursor of DatabaseRows representing the result set
109: */
110: public Object executeDatabaseQuery() throws DatabaseException {
111: if (getContainerPolicy().overridesRead()) {
112: return getContainerPolicy().execute();
113: }
114: return executeNonCursor();
115: }
116:
117: /**
118: * INTERNAL:
119: * The results are *not* in a cursor, build the collection.
120: */
121: protected Object executeNonCursor() throws DatabaseException {
122: Vector rows = getQueryMechanism().executeSelect();
123: if (useAbstractRecord) {
124: Object results = getContainerPolicy()
125: .buildContainerFromVector(rows, getSession());
126: return results;
127: }
128: ContainerPolicy containerPolicy = getContainerPolicy();
129: Object reportResults = containerPolicy.containerInstance(rows
130: .size());
131: for (Iterator rowsEnum = rows.iterator(); rowsEnum.hasNext();) {
132: containerPolicy.addInto(((AbstractRecord) rowsEnum.next())
133: .getValues(), reportResults, getSession());
134: }
135: return reportResults;
136: }
137:
138: /**
139: * PUBLIC:
140: * Return the query's ContainerPolicy.
141: * @return oracle.toplink.essentials.internal.queryframework.ContainerPolicy
142: */
143: public ContainerPolicy getContainerPolicy() {
144: return containerPolicy;
145: }
146:
147: /**
148: * PUBLIC:
149: * Return if this is a data read query.
150: */
151: public boolean isDataReadQuery() {
152: return true;
153: }
154:
155: /**
156: * INTERNAL:
157: * Prepare the receiver for execution in a session.
158: */
159: protected void prepare() {
160: super .prepare();
161: getContainerPolicy().prepare(this , getSession());
162: if (getContainerPolicy().overridesRead()) {
163: return;
164: }
165: getQueryMechanism().prepareExecuteSelect();
166: }
167:
168: /**
169: * INTERNAL:
170: * Prepare the receiver for execution in a session.
171: */
172: public void prepareForExecution() throws QueryException {
173: super .prepareForExecution();
174: getContainerPolicy().prepareForExecution();
175: }
176:
177: /**
178: * PUBLIC:
179: * Set the container policy.
180: */
181: public void setContainerPolicy(ContainerPolicy containerPolicy) {
182: // Fix for BUG 3337003 - TopLink OX will try to set this to null if
183: // it is not set in the deployment XML. So don't allow it to do that.
184: if (containerPolicy == null) {
185: return;
186: }
187:
188: this .containerPolicy = containerPolicy;
189: }
190:
191: /**
192: * PUBLIC:
193: * Configure the query to use an instance of the specified container class
194: * to hold the target objects.
195: * The container class must implement (directly or indirectly) the Collection interface.
196: */
197: public void useCollectionClass(Class concreteClass) {
198: setContainerPolicy(ContainerPolicy
199: .buildPolicyFor(concreteClass));
200: }
201:
202: /**
203: * INTERNAL:
204: * Allow changing the default behaviour so that AbstractRecords are not returned as query results.
205: */
206: public void setUseAbstractRecord(boolean useAbstractRecord) {
207: this.useAbstractRecord = useAbstractRecord;
208: }
209: }
|