KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > QueryWrapper


1 package com.sun.enterprise.util;
2
3 import java.util.Calendar JavaDoc;
4 import java.util.Date JavaDoc;
5 import java.util.List JavaDoc;
6 import java.util.LinkedList JavaDoc;
7 import java.util.Map JavaDoc;
8
9 import javax.persistence.EntityManager;
10 import javax.persistence.EntityManagerFactory;
11 import javax.persistence.FlushModeType;
12 import javax.persistence.Query;
13 import javax.persistence.TemporalType;
14 import javax.persistence.TransactionRequiredException;
15
16 /**
17  * Wrapper class for javax.persistence.Query objects returned from
18  * non-transactional access of a container-managed transactional
19  * EntityManager. Proxying the Query object prevents the
20  * EntityManagerWrapper from having to keep a physical EntityManager
21  * open when returning Query objects for non-transactional access.
22  *
23  * This results in a cleaner implementation of the non-transactional
24  * EntityManager behavior and minimizes the amount of time
25  * non-transactional EntityManager objects are left open. It is likely
26  * that physical EntityManager objects will have heavy-weight resources
27  * such as DB connections open even after clear() is called. This is
28  * one of the main reasons to minimize the number of open non-transactional
29  * EntityManager objects held internally within injected/looked-up
30  * container-managed EntityManagers.
31  *
32  * The EntityManager and Query delegate objects are provided at
33  * QueryWrapper creation time. These objects must exist in order
34  * for the EntityManagerWrapper to provide the correct exception
35  * behavior to the application when a Query is requested.
36  * Likewise, the actual delegates must be available
37  * to handle the majority of the Query API operations such as
38  * performing validation on the various setter parameters.
39  *
40  * The Query/EntityManager delegates
41  * are closed/discarded after each call to getSingleResult/getResultList.
42  * A new Query/EntityManager delegate pair is then created lazily
43  * the next time the Query delegate is needed. The QueryWrapper
44  * maintains a list of all setter operations invoked by the application.
45  * These are re-applied in the same order whenever a new Query delegate
46  * is created to ensure that the state of the Query delegate object matches
47  * what it would have been if there wasn't any QueryWrapper.
48  *
49  */

50 public class QueryWrapper implements Query {
51
52     // Holds current query/em delegates. These are cleared out after
53
// query execution to minimize potential entity manager resource leakage.
54
private Query queryDelegate;
55     private EntityManager entityManagerDelegate;
56
57     // Used if new query/em delegates need to be created.
58
private EntityManagerFactory entityMgrFactory;
59     private Map JavaDoc entityMgrProperties;
60
61     // State used to construct query delegate object itself.
62
private QueryType queryType;
63     private String JavaDoc queryString;
64     private Class JavaDoc queryResultClass;
65     private String JavaDoc queryResultSetMapping;
66
67     // State used to recreate sequence of setter methods applied to the
68
// QueryWrapper when a new Query delegate is created.
69
private List JavaDoc<SetterData> setterInvocations;
70
71
72     public static Query createQueryWrapper(EntityManagerFactory emf,
73                                            Map JavaDoc emProperties,
74                                            EntityManager emDelegate,
75                                            Query queryDelegate,
76                                            String JavaDoc ejbqlString) {
77
78         return new QueryWrapper(emf, emProperties, emDelegate,
79                                 queryDelegate, QueryType.EJBQL,
80                                 ejbqlString, null, null);
81     }
82
83     public static Query createNamedQueryWrapper(EntityManagerFactory emf,
84                                                 Map JavaDoc emProperties,
85                                                 EntityManager emDelegate,
86                                                 Query queryDelegate,
87                                                 String JavaDoc name) {
88         return new QueryWrapper(emf, emProperties, emDelegate,
89                                 queryDelegate, QueryType.NAMED,
90                                 name, null, null);
91     }
92
93     public static Query createNativeQueryWrapper(EntityManagerFactory emf,
94                                                  Map JavaDoc emProperties,
95                                                  EntityManager emDelegate,
96                                                  Query queryDelegate,
97                                                  String JavaDoc sqlString) {
98
99         return new QueryWrapper(emf, emProperties, emDelegate,
100                                 queryDelegate, QueryType.NATIVE,
101                                 sqlString, null, null);
102         
103     }
104
105     public static Query createNativeQueryWrapper(EntityManagerFactory emf,
106                                                  Map JavaDoc emProperties,
107                                                  EntityManager emDelegate,
108                                                  Query queryDelegate,
109                                                  String JavaDoc sqlString,
110                                                  Class JavaDoc resultClass) {
111
112         return new QueryWrapper(emf, emProperties, emDelegate,
113                                 queryDelegate, QueryType.NATIVE,
114                                 sqlString, resultClass, null);
115         
116     }
117
118     public static Query createNativeQueryWrapper(EntityManagerFactory emf,
119                                                  Map JavaDoc emProperties,
120                                                  EntityManager emDelegate,
121                                                  Query queryDelegate,
122                                                  String JavaDoc sqlString,
123                                                  String JavaDoc resultSetMapping) {
124
125         return new QueryWrapper(emf, emProperties, emDelegate,
126                                 queryDelegate, QueryType.NATIVE,
127                                 sqlString, null, resultSetMapping);
128         
129     }
130
131     private QueryWrapper(EntityManagerFactory emf, Map JavaDoc emProperties,
132                          EntityManager emDelegate, Query qDelegate,
133                          QueryType type, String JavaDoc query,
134                          Class JavaDoc resultClass, String JavaDoc resultSetMapping)
135     {
136         entityMgrFactory = emf;
137         entityMgrProperties = emProperties;
138
139         entityManagerDelegate = emDelegate;
140         queryDelegate = qDelegate;
141
142         queryType = type;
143         queryString = query;
144         queryResultClass = resultClass;
145         queryResultSetMapping = resultSetMapping;
146
147         setterInvocations = new LinkedList JavaDoc<SetterData>();
148     }
149
150     public List JavaDoc getResultList() {
151         try {
152
153             Query delegate = getQueryDelegate();
154             return delegate.getResultList();
155
156         } finally {
157             clearDelegates();
158         }
159     }
160
161     public Object JavaDoc getSingleResult() {
162         try {
163
164             Query delegate = getQueryDelegate();
165             return delegate.getSingleResult();
166
167         } finally {
168             clearDelegates();
169         }
170     }
171
172     public int executeUpdate() {
173         throw new TransactionRequiredException("executeUpdate is not supported for a Query object obtained through non-transactional access of a container-managed transactional EntityManager");
174     }
175
176     public Query setMaxResults(int maxResults) {
177         if( maxResults < 0 ) {
178             throw new IllegalArgumentException JavaDoc("maxResult cannot be negative");
179         }
180
181         Query delegate = getQueryDelegate();
182         delegate.setMaxResults(maxResults);
183
184         SetterData setterData = SetterData.createMaxResults(maxResults);
185         setterInvocations.add(setterData);
186
187         return this;
188     }
189
190     public Query setFirstResult(int startPosition) {
191         if( startPosition < 0 ) {
192             throw new IllegalArgumentException JavaDoc
193                 ("startPosition cannot be negative");
194         }
195
196         Query delegate = getQueryDelegate();
197         delegate.setFirstResult(startPosition);
198
199         SetterData setterData = SetterData.createFirstResult(startPosition);
200         setterInvocations.add(setterData);
201
202         return this;
203     }
204
205     public Query setHint(String JavaDoc hintName, Object JavaDoc value) {
206         Query delegate = getQueryDelegate();
207         delegate.setHint(hintName, value);
208
209         SetterData setterData = SetterData.createHint(hintName, value);
210         setterInvocations.add(setterData);
211
212         return this;
213     }
214
215     public Query setParameter(String JavaDoc name, Object JavaDoc value) {
216         Query delegate = getQueryDelegate();
217         delegate.setParameter(name, value);
218
219         SetterData setterData = SetterData.createParameter(name, value);
220         setterInvocations.add(setterData);
221
222         return this;
223     }
224
225     public Query setParameter(String JavaDoc name, Date JavaDoc value,
226                               TemporalType temporalType) {
227
228         Query delegate = getQueryDelegate();
229         delegate.setParameter(name, value, temporalType);
230
231         SetterData setterData = SetterData.createParameter(name, value,
232                                                            temporalType);
233         setterInvocations.add(setterData);
234
235         return this;
236     }
237
238     public Query setParameter(String JavaDoc name, Calendar JavaDoc value,
239                               TemporalType temporalType) {
240         
241         Query delegate = getQueryDelegate();
242         delegate.setParameter(name, value, temporalType);
243
244         SetterData setterData = SetterData.createParameter(name, value,
245                                                            temporalType);
246         setterInvocations.add(setterData);
247
248         return this;
249     }
250
251     public Query setParameter(int position, Object JavaDoc value) {
252
253         Query delegate = getQueryDelegate();
254         delegate.setParameter(position, value);
255
256         SetterData setterData = SetterData.createParameter(position, value);
257         setterInvocations.add(setterData);
258
259         return this;
260     }
261
262     public Query setParameter(int position, Date JavaDoc value,
263                               TemporalType temporalType) {
264
265         Query delegate = getQueryDelegate();
266         delegate.setParameter(position, value, temporalType);
267
268         SetterData setterData = SetterData.createParameter(position, value,
269                                                            temporalType);
270         setterInvocations.add(setterData);
271
272         return this;
273     }
274
275     public Query setParameter(int position, Calendar JavaDoc value,
276                               TemporalType temporalType) {
277
278         Query delegate = getQueryDelegate();
279         delegate.setParameter(position, value, temporalType);
280
281         SetterData setterData = SetterData.createParameter(position, value,
282                                                            temporalType);
283         setterInvocations.add(setterData);
284
285         return this;
286     }
287
288     public Query setFlushMode(FlushModeType flushMode) {
289
290         Query delegate = getQueryDelegate();
291         delegate.setFlushMode(flushMode);
292
293         SetterData setterData = SetterData.createFlushMode(flushMode);
294         setterInvocations.add(setterData);
295
296         return this;
297     }
298
299     private void clearDelegates() {
300
301         queryDelegate = null;
302
303         if( entityManagerDelegate != null ) {
304             entityManagerDelegate.close();
305             entityManagerDelegate = null;
306         }
307         
308     }
309
310     private Query getQueryDelegate() {
311
312         if( queryDelegate == null ) {
313
314             entityManagerDelegate =
315                 entityMgrFactory.createEntityManager(entityMgrProperties);
316
317             switch(queryType) {
318
319               case EJBQL :
320
321                   queryDelegate =
322                       entityManagerDelegate.createQuery(queryString);
323                   break;
324                   
325               case NAMED :
326
327                   queryDelegate =
328                       entityManagerDelegate.createNamedQuery(queryString);
329                   break;
330
331               case NATIVE :
332
333                   if( queryResultClass != null ) {
334
335                       queryDelegate = entityManagerDelegate.createNativeQuery
336                           (queryString, queryResultClass);
337
338                   } else if( queryResultSetMapping != null ) {
339
340                       queryDelegate = entityManagerDelegate.createNativeQuery
341                           (queryString, queryResultSetMapping);
342
343                   } else {
344
345                       queryDelegate = entityManagerDelegate.createNativeQuery
346                           (queryString);
347                   }
348
349                   break;
350             }
351
352             // Now recreate the sequence of valid setter invocations applied
353
// to this query.
354
for(SetterData setterData : setterInvocations) {
355                 setterData.apply(queryDelegate);
356             }
357
358         }
359
360
361         return queryDelegate;
362
363     }
364
365     private enum QueryType {
366
367         EJBQL,
368         NAMED,
369         NATIVE
370
371     }
372
373     private enum SetterType {
374
375         MAX_RESULTS,
376         FIRST_RESULT,
377         HINT,
378         PARAM_NAME_OBJECT,
379         PARAM_NAME_DATE_TEMPORAL,
380         PARAM_NAME_CAL_TEMPORAL,
381         PARAM_POSITION_OBJECT,
382         PARAM_POSITION_DATE_TEMPORAL,
383         PARAM_POSITION_CAL_TEMPORAL,
384         FLUSH_MODE
385
386     }
387
388     private static class SetterData {
389
390         SetterType type;
391
392         int int1;
393         String JavaDoc string1;
394         Object JavaDoc object1;
395
396         Date JavaDoc date;
397         Calendar JavaDoc calendar;
398         TemporalType temporalType;
399
400         FlushModeType flushMode;
401
402         static SetterData createMaxResults(int maxResults) {
403             SetterData data = new SetterData();
404             data.type = SetterType.MAX_RESULTS;
405             data.int1 = maxResults;
406             return data;
407         }
408
409         static SetterData createFirstResult(int firstResult) {
410             SetterData data = new SetterData();
411             data.type = SetterType.FIRST_RESULT;
412             data.int1 = firstResult;
413             return data;
414         }
415
416         static SetterData createHint(String JavaDoc hintName, Object JavaDoc value) {
417             SetterData data = new SetterData();
418             data.type = SetterType.HINT;
419             data.string1 = hintName;
420             data.object1 = value;
421             return data;
422         }
423
424         static SetterData createParameter(String JavaDoc name, Object JavaDoc value) {
425
426             SetterData data = new SetterData();
427             data.type = SetterType.PARAM_NAME_OBJECT;
428             data.string1 = name;
429             data.object1 = value;
430             return data;
431         }
432
433         static SetterData createParameter(String JavaDoc name, Date JavaDoc value,
434                                           TemporalType temporalType) {
435
436             SetterData data = new SetterData();
437             data.type = SetterType.PARAM_NAME_DATE_TEMPORAL;
438             data.string1 = name;
439             data.date = value;
440             data.temporalType = temporalType;
441             return data;
442         }
443
444         static SetterData createParameter(String JavaDoc name, Calendar JavaDoc value,
445                                           TemporalType temporalType) {
446
447             SetterData data = new SetterData();
448             data.type = SetterType.PARAM_NAME_CAL_TEMPORAL;
449             data.string1 = name;
450             data.calendar = value;
451             data.temporalType = temporalType;
452             return data;
453         }
454         
455         static SetterData createParameter(int position, Object JavaDoc value) {
456
457             SetterData data = new SetterData();
458             data.type = SetterType.PARAM_POSITION_OBJECT;
459             data.int1 = position;
460             data.object1 = value;
461             return data;
462         }
463
464         static SetterData createParameter(int position, Date JavaDoc value,
465                                           TemporalType temporalType) {
466             SetterData data = new SetterData();
467             data.type = SetterType.PARAM_POSITION_DATE_TEMPORAL;
468             data.int1 = position;
469             data.date = value;
470             data.temporalType = temporalType;
471             return data;
472         }
473
474        static SetterData createParameter(int position, Calendar JavaDoc value,
475                                           TemporalType temporalType) {
476             SetterData data = new SetterData();
477             data.type = SetterType.PARAM_POSITION_CAL_TEMPORAL;
478             data.int1 = position;
479             data.calendar = value;
480             data.temporalType = temporalType;
481             return data;
482         }
483         
484         static SetterData createFlushMode(FlushModeType flushMode) {
485
486             SetterData data = new SetterData();
487             data.type = SetterType.FLUSH_MODE;
488             data.flushMode = flushMode;
489             return data;
490
491         }
492         
493         void apply(Query query) {
494
495             switch(type) {
496
497             case MAX_RESULTS :
498                 
499                 query.setMaxResults(int1);
500                 break;
501
502             case FIRST_RESULT :
503                 
504                 query.setFirstResult(int1);
505                 break;
506
507             case HINT :
508                 
509                 query.setHint(string1, object1);
510                 break;
511
512             case PARAM_NAME_OBJECT :
513                 
514                 query.setParameter(string1, object1);
515                 break;
516
517             case PARAM_NAME_DATE_TEMPORAL :
518                 
519                 query.setParameter(string1, date, temporalType);
520                 break;
521
522             case PARAM_NAME_CAL_TEMPORAL :
523                 
524                 query.setParameter(string1, calendar, temporalType);
525                 break;
526
527             case PARAM_POSITION_OBJECT :
528                 
529                 query.setParameter(int1, object1);
530                 break;
531
532             case PARAM_POSITION_DATE_TEMPORAL :
533                 
534                 query.setParameter(int1, date, temporalType);
535                 break;
536
537             case PARAM_POSITION_CAL_TEMPORAL :
538                 
539                 query.setParameter(int1, calendar, temporalType);
540                 break;
541
542             case FLUSH_MODE :
543                 
544                 query.setFlushMode(flushMode);
545                 break;
546
547             }
548         }
549         
550     }
551     
552
553 }
554
Popular Tags