KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > jpa > JpaQuery


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19 package org.apache.cayenne.jpa;
20
21 import java.util.Calendar JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import javax.persistence.FlushModeType;
28 import javax.persistence.NoResultException;
29 import javax.persistence.NonUniqueResultException;
30 import javax.persistence.Query;
31 import javax.persistence.TemporalType;
32 import javax.persistence.TransactionRequiredException;
33
34 import org.apache.cayenne.ObjectContext;
35 import org.apache.cayenne.QueryResponse;
36 import org.apache.cayenne.query.ParameterizedQuery;
37 import org.apache.cayenne.query.ProcedureQuery;
38 import org.apache.cayenne.query.SQLTemplate;
39 import org.apache.cayenne.query.SelectQuery;
40
41 /**
42  * A JPA Query that wraps a Cayenne Query.
43  */

44 public class JpaQuery implements Query {
45
46     protected Map JavaDoc<String JavaDoc, Object JavaDoc> parameters = new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
47     protected org.apache.cayenne.query.Query cayenneQuery;
48     protected ObjectContext context;
49
50     public JpaQuery(ObjectContext ctxt) {
51         this.context = ctxt;
52     }
53
54     /**
55      * Construct a named query.
56      */

57     public JpaQuery(ObjectContext context, String JavaDoc name) {
58         this(context);
59
60         org.apache.cayenne.query.Query q = context.getEntityResolver().lookupQuery(name);
61
62         if (q == null) {
63             throw new IllegalArgumentException JavaDoc("Non-existing query: " + name);
64         }
65
66         setQuery(q);
67     }
68
69     protected void setQuery(org.apache.cayenne.query.Query q) {
70         this.cayenneQuery = q;
71     }
72
73     protected org.apache.cayenne.query.Query getQuery() {
74         return cayenneQuery;
75     }
76
77     /**
78      * Return the same query with parameters set.
79      */

80     private org.apache.cayenne.query.Query queryWithParameters() {
81         if (parameters.size() == 0) {
82             return cayenneQuery;
83         }
84
85         return ((ParameterizedQuery) cayenneQuery).createQuery(parameters);
86     }
87
88     /**
89      * Execute a SELECT query and return the query results as a List.
90      *
91      * @return a list of the results
92      * @throws IllegalStateException if called for an EJB QL UPDATE or DELETE statement
93      */

94     public List JavaDoc getResultList() {
95         return context.performQuery(queryWithParameters());
96     }
97
98     /**
99      * Execute an update or delete statement.
100      *
101      * @return the number of entities updated or deleted
102      * @throws IllegalStateException if called for an EJB QL SELECT statement
103      * @throws TransactionRequiredException if there is no transaction
104      */

105     public int executeUpdate() {
106         // TODO: check transaction
107

108         QueryResponse response = context.performGenericQuery(queryWithParameters());
109         int[] res = response.firstUpdateCount();
110
111         if (res == null) {
112             return -1;
113         }
114
115         int num = 0;
116         for (int i = 0; i < res.length; i++) {
117             num = num + res[i];
118         }
119         return num;
120     }
121
122     /**
123      * Execute a SELECT query that returns a single result.
124      *
125      * @return the result
126      * @throws NoResultException if there is no result
127      * @throws NonUniqueResultException if more than one result
128      * @throws IllegalStateException if called for an EJB QL UPDATE or DELETE statement
129      */

130     public Object JavaDoc getSingleResult() {
131         List JavaDoc rows = getResultList();
132         if (rows.size() == 0) {
133             throw new NoResultException();
134         }
135         if (rows.size() > 1) {
136             throw new NonUniqueResultException();
137         }
138
139         return rows.get(0);
140     }
141
142     /**
143      * Set the maximum number of results to retrieve.
144      *
145      * @param maxResult
146      * @return the same query instance
147      * @throws IllegalArgumentException if argument is negative
148      */

149     public Query setMaxResults(int maxResult) {
150         if (maxResult < 0) {
151             throw new IllegalArgumentException JavaDoc("Invalid max results value: " + maxResult);
152         }
153
154         // TODO: use QueryMetadata?
155
if (getQuery() instanceof SelectQuery) {
156             ((SelectQuery) getQuery()).setFetchLimit(maxResult);
157         }
158         else if (getQuery() instanceof SQLTemplate) {
159             ((SQLTemplate) getQuery()).setFetchLimit(maxResult);
160         }
161         else if (getQuery() instanceof ProcedureQuery) {
162             ((ProcedureQuery) getQuery()).setFetchLimit(maxResult);
163         }
164
165         throw new IllegalArgumentException JavaDoc("query does not support maxResult");
166     }
167
168     public Query setFlushMode(FlushModeType flushModeType) {
169         return this;
170     }
171
172     /**
173      * Set an implementation-specific hint. If the hint name is not recognized, it is
174      * silently ignored.
175      *
176      * @param hintName
177      * @param value
178      * @return the same query instance
179      * @throws IllegalArgumentException if the second argument is not valid for the
180      * implementation
181      */

182     public Query setHint(String JavaDoc hintName, Object JavaDoc value) {
183         return this;
184     }
185
186     /**
187      * Set the position of the first result to retrieve.
188      *
189      * @param startPosition position of the first result, numbered from 0
190      * @return the same query instance
191      * @throws IllegalArgumentException if argument is negative
192      */

193     public Query setFirstResult(int startPosition) {
194         if (startPosition < 0) {
195             throw new IllegalArgumentException JavaDoc("Invalid first result value: "
196                     + startPosition);
197         }
198         // TODO: support in core like fetchLimit?
199
// TODO: hack a temp solution here based on sub-list?
200
throw new UnsupportedOperationException JavaDoc("TODO");
201     }
202
203     /**
204      * Bind an argument to a named parameter.
205      *
206      * @param name the parameter name
207      * @param value
208      * @return the same query instance
209      * @throws IllegalArgumentException if parameter name does not correspond to parameter
210      * in query string or argument is of incorrect type
211      */

212     public Query setParameter(String JavaDoc name, Object JavaDoc value) {
213         if (!(cayenneQuery instanceof ParameterizedQuery)) {
214             throw new IllegalArgumentException JavaDoc("query does not accept parameters");
215         }
216
217         // TODO: check for valid parameter. should probably be built in to
218
// all ParameterizedQuerys
219

220         parameters.put(name, value);
221         return this;
222     }
223
224     /**
225      * Bind an instance of java.util.Date to a named parameter.
226      *
227      * @param name
228      * @param value
229      * @param temporalType
230      * @return the same query instance
231      * @throws IllegalArgumentException if parameter name does not correspond to parameter
232      * in query string
233      */

234     public Query setParameter(String JavaDoc name, Date JavaDoc value, TemporalType temporalType) {
235         // handled by cayenne.
236
return setParameter(name, value);
237     }
238
239     /**
240      * Bind an instance of java.util.Calendar to a named parameter.
241      *
242      * @param name
243      * @param value
244      * @param temporalType
245      * @return the same query instance
246      * @throws IllegalArgumentException if parameter name does not correspond to parameter
247      * in query string
248      */

249     public Query setParameter(String JavaDoc name, Calendar JavaDoc value, TemporalType temporalType) {
250         // handled by cayenne.
251
return setParameter(name, value);
252     }
253
254     /**
255      * Bind an argument to a positional parameter.
256      *
257      * @param position
258      * @param value
259      * @return the same query instance
260      * @throws IllegalArgumentException if position does not correspond to positional
261      * parameter of query or argument is of incorrect type
262      */

263     public Query setParameter(int position, Object JavaDoc value) {
264         // TODO: implement
265
throw new UnsupportedOperationException JavaDoc("TODO");
266     }
267
268     /**
269      * Bind an instance of java.util.Date to a positional parameter.
270      *
271      * @param position
272      * @param value
273      * @param temporalType
274      * @return the same query instance
275      * @throws IllegalArgumentException if position does not correspond to positional
276      * parameter of query
277      */

278     public Query setParameter(int position, Date JavaDoc value, TemporalType temporalType) {
279         // handled by cayenne.
280
return setParameter(position, value);
281     }
282
283     /**
284      * Bind an instance of java.util.Calendar to a positional parameter.
285      *
286      * @param position
287      * @param value
288      * @param temporalType
289      * @return the same query instance
290      * @throws IllegalArgumentException if position does not correspond to positional
291      * parameter of query
292      */

293     public Query setParameter(int position, Calendar JavaDoc value, TemporalType temporalType) {
294         // handled by cayenne.
295
return setParameter(position, value);
296     }
297
298 }
299
Popular Tags