KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > base > QueryHintsHandler


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.internal.ejb.cmp3.base;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import oracle.toplink.essentials.config.*;
29
30 import oracle.toplink.essentials.queryframework.DatabaseQuery;
31 import oracle.toplink.essentials.queryframework.ObjectLevelReadQuery;
32 import oracle.toplink.essentials.internal.localization.ExceptionLocalization;
33 import oracle.toplink.essentials.internal.sessions.AbstractSession;
34 import oracle.toplink.essentials.logging.SessionLog;
35
36 /**
37  *
38  * The class processes query hints.
39  *
40  * TopLink query hints and their values defined in oracle.toplink.essentials.config package.
41  *
42  * To add a new query hint:
43  * Define a new hint in TopLinkQueryHints;
44  * Add a class containing hint's values if required to config package (like CacheUsage);
45  * Alternatively values defined in HintValues may be used - Refresh and BindParameters hints do that.
46  * Add an inner class to this class extending Hint corresponding to the new hint (like CacheUsageHint);
47  * The first constructor parameter is hint name; the second is default value;
48  * In constructor
49  * provide 2-dimensional value array in case the values should be translated (currently all Hint classes do that);
50  * in case translation is not required provide a single-dimension array (no such examples yet).
51  * In inner class Hint static initializer addHint an instance of the new hint class (like addHint(new CacheUsageHint())).
52  *
53  * @see TopLinkQueryHints
54  * @see HintValues
55  * @see CacheUsage
56  * @see PessimisticLock
57  *
58  */

59 public class QueryHintsHandler {
60     
61     /**
62      * INTERNAL:
63      * Verifies the hints.
64      *
65      * If session != null then logs a FINEST message for each hint.
66      * queryName parameter used only for identifying the query in messages,
67      * if it's null then "null" will be used.
68      * Throws IllegalArgumentException in case the hint value is illegal.
69      */

70     public static void verify(Map JavaDoc hints, String JavaDoc queryName, AbstractSession session) {
71         if(hints == null) {
72             return;
73         }
74         Iterator JavaDoc it = hints.entrySet().iterator();
75         while(it.hasNext()) {
76             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
77             String JavaDoc hintName = (String JavaDoc)entry.getKey();
78             verify(hintName, entry.getValue(), queryName, session);
79         }
80     }
81     
82     /**
83      * INTERNAL:
84      * Verifies the hint.
85      *
86      * If session != null then logs a FINEST message.
87      * queryName parameter used only for identifying the query in messages,
88      * if it's null then "null" will be used.
89      * Throws IllegalArgumentException in case the hint value is illegal.
90      */

91     public static void verify(String JavaDoc hintName, Object JavaDoc hintValue, String JavaDoc queryName, AbstractSession session) {
92         Hint.verify(hintName, shouldUseDefault(hintValue), hintValue, queryName, session);
93     }
94     
95     /**
96      * INTERNAL:
97      * Applies the hints to the query.
98      * Throws IllegalArgumentException in case the hint value is illegal.
99      */

100     public static void apply(Map JavaDoc hints, DatabaseQuery query) {
101         if(hints == null) {
102             return;
103         }
104         Iterator JavaDoc it = hints.entrySet().iterator();
105         while(it.hasNext()) {
106             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
107             String JavaDoc hintName = (String JavaDoc)entry.getKey();
108             apply(hintName, entry.getValue(), query);
109         }
110     }
111     
112     /**
113      * INTERNAL:
114      * Applies the hint to the query.
115      * Throws IllegalArgumentException in case the hint value is illegal.
116      */

117     public static void apply(String JavaDoc hintName, Object JavaDoc hintValue, DatabaseQuery query) {
118         Hint.apply(hintName, shouldUseDefault(hintValue), hintValue, query);
119     }
120     
121     /**
122      * INTERNAL:
123      * Empty String hintValue indicates that the default hint value
124      * should be used.
125      */

126     protected static boolean shouldUseDefault(Object JavaDoc hintValue) {
127         return (hintValue != null) && (hintValue instanceof String JavaDoc) && (((String JavaDoc)hintValue).length() == 0);
128     }
129     
130     protected static abstract class Hint {
131         static HashMap JavaDoc mainMap = new HashMap JavaDoc();
132         Object JavaDoc[] valueArray;
133         HashMap JavaDoc valueMap;
134         String JavaDoc name;
135         String JavaDoc defaultValue;
136         Object JavaDoc defaultValueToApply;
137         boolean valueToApplyMayBeNull;
138         
139         static {
140             addHint(new BindParametersHint());
141             addHint(new CacheUsageHint());
142             addHint(new PessimisticLockHint());
143             addHint(new RefreshHint());
144         }
145         
146         Hint(String JavaDoc name, String JavaDoc defaultValue) {
147             this.name = name;
148             this.defaultValue = defaultValue;
149         }
150
151         abstract void applyToDatabaseQuery(Object JavaDoc valueToApply, DatabaseQuery query);
152                 
153         static void verify(String JavaDoc hintName, boolean shouldUseDefault, Object JavaDoc hintValue, String JavaDoc queryName, AbstractSession session) {
154             Hint hint = (Hint)mainMap.get(hintName);
155             if(hint == null) {
156                 if(session != null) {
157                     session.log(SessionLog.FINEST, SessionLog.QUERY, "unknown_query_hint", new Object JavaDoc[]{getPrintValue(queryName), hintName});
158                 }
159                 return;
160             }
161                                     
162             hint.verify(hintValue, shouldUseDefault, queryName, session);
163         }
164         
165         void verify(Object JavaDoc hintValue, boolean shouldUseDefault, String JavaDoc queryName, AbstractSession session) {
166             if(shouldUseDefault) {
167                 hintValue = defaultValue;
168             }
169             if(session != null) {
170                 session.log(SessionLog.FINEST, SessionLog.QUERY, "query_hint", new Object JavaDoc[]{getPrintValue(queryName), name, getPrintValue(hintValue)});
171             }
172             if(!shouldUseDefault && valueMap != null && !valueMap.containsKey(getUpperCaseString(hintValue))) {
173                 throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object JavaDoc[]{getPrintValue(queryName), name, getPrintValue(hintValue)}));
174             }
175         }
176         
177         static void apply(String JavaDoc hintName, boolean shouldUseDefault, Object JavaDoc hintValue, DatabaseQuery query) {
178             Hint hint = (Hint)mainMap.get(hintName);
179             if(hint == null) {
180                 // unknown hint name - silently ignored.
181
return;
182             }
183             
184             hint.apply(hintValue, shouldUseDefault, query);
185         }
186         
187         void apply(Object JavaDoc hintValue, boolean shouldUseDefault, DatabaseQuery query) {
188             Object JavaDoc valueToApply = hintValue;
189             if(shouldUseDefault) {
190                 valueToApply = defaultValueToApply;
191             } else {
192                 if(valueMap != null) {
193                     String JavaDoc key = getUpperCaseString(hintValue);
194                     valueToApply = valueMap.get(key);
195                     if(valueToApply == null) {
196                         boolean wrongKey = true;
197                         if(valueToApplyMayBeNull) {
198                             wrongKey = !valueMap.containsKey(key);
199                         }
200                         if(wrongKey) {
201                             throw new IllegalArgumentException JavaDoc(ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object JavaDoc[]{getQueryId(query), name, getPrintValue(hintValue)}));
202                         }
203                     }
204                 }
205             }
206             applyToDatabaseQuery(valueToApply, query);
207         }
208
209         static String JavaDoc getQueryId(DatabaseQuery query) {
210             String JavaDoc queryId = query.getName();
211             if(queryId == null) {
212                 queryId = query.getEJBQLString();
213             }
214             return getPrintValue(queryId);
215         }
216         
217         static String JavaDoc getPrintValue(Object JavaDoc hintValue) {
218             return hintValue != null ? hintValue.toString() : "null";
219         }
220     
221         static String JavaDoc getUpperCaseString(Object JavaDoc hintValue) {
222             return hintValue != null ? hintValue.toString().toUpperCase() : null;
223         }
224
225         void initialize() {
226             if(valueArray != null) {
227                 valueMap = new HashMap JavaDoc(valueArray.length);
228                 if(valueArray instanceof Object JavaDoc[][]) {
229                     Object JavaDoc[][] valueArray2 = (Object JavaDoc[][])valueArray;
230                     for(int i=0; i<valueArray2.length; i++) {
231                         valueMap.put(getUpperCaseString(valueArray2[i][0]), valueArray2[i][1]);
232                         if(valueArray2[i][1] == null) {
233                             valueToApplyMayBeNull = true;
234                         }
235                     }
236                 } else {
237                     for(int i=0; i<valueArray.length; i++) {
238                         valueMap.put(getUpperCaseString(valueArray[i]), valueArray[i]);
239                         if(valueArray[i] == null) {
240                             valueToApplyMayBeNull = true;
241                         }
242                     }
243                 }
244                 defaultValueToApply = valueMap.get(defaultValue.toUpperCase());
245             }
246         }
247         static void addHint(Hint hint) {
248             hint.initialize();
249             mainMap.put(hint.name, hint);
250         }
251     }
252
253     protected static class BindParametersHint extends Hint {
254         BindParametersHint() {
255             super(TopLinkQueryHints.BIND_PARAMETERS, HintValues.PERSISTENCE_UNIT_DEFAULT);
256             valueArray = new Object JavaDoc[][] {
257                 {HintValues.PERSISTENCE_UNIT_DEFAULT, null},
258                 {HintValues.TRUE, Boolean.TRUE},
259                 {HintValues.FALSE, Boolean.FALSE}
260             };
261         }
262     
263         void applyToDatabaseQuery(Object JavaDoc valueToApply, DatabaseQuery query) {
264             if(valueToApply == null) {
265                 query.ignoreBindAllParameters();
266             } else {
267                 query.setShouldBindAllParameters(((Boolean JavaDoc)valueToApply).booleanValue());
268             }
269         }
270     }
271
272     protected static class CacheUsageHint extends Hint {
273         CacheUsageHint() {
274             super(TopLinkQueryHints.CACHE_USAGE, CacheUsage.DEFAULT);
275             valueArray = new Object JavaDoc[][] {
276                 {CacheUsage.UseEntityDefault, ObjectLevelReadQuery.UseDescriptorSetting},
277                 {CacheUsage.DoNotCheckCache, ObjectLevelReadQuery.DoNotCheckCache},
278                 {CacheUsage.CheckCacheByExactPrimaryKey, ObjectLevelReadQuery.CheckCacheByExactPrimaryKey},
279                 {CacheUsage.CheckCacheByPrimaryKey, ObjectLevelReadQuery.CheckCacheByPrimaryKey},
280                 {CacheUsage.CheckCacheThenDatabase, ObjectLevelReadQuery.CheckCacheThenDatabase},
281                 {CacheUsage.CheckCacheOnly, ObjectLevelReadQuery.CheckCacheOnly},
282                 {CacheUsage.ConformResultsInUnitOfWork, ObjectLevelReadQuery.ConformResultsInUnitOfWork}
283             };
284         }
285     
286         void applyToDatabaseQuery(Object JavaDoc valueToApply, DatabaseQuery query) {
287             if (query.isObjectLevelReadQuery()) {
288                 ((ObjectLevelReadQuery)query).setCacheUsage(((Integer JavaDoc)valueToApply).intValue());
289             }
290         }
291     }
292
293     protected static class PessimisticLockHint extends Hint {
294         PessimisticLockHint() {
295             super(TopLinkQueryHints.PESSIMISTIC_LOCK, PessimisticLock.DEFAULT);
296             valueArray = new Object JavaDoc[][] {
297                 {PessimisticLock.NoLock, ObjectLevelReadQuery.NO_LOCK},
298                 {PessimisticLock.Lock, ObjectLevelReadQuery.LOCK},
299                 {PessimisticLock.LockNoWait, ObjectLevelReadQuery.LOCK_NOWAIT}
300             };
301         }
302     
303         void applyToDatabaseQuery(Object JavaDoc valueToApply, DatabaseQuery query) {
304             if (query.isObjectLevelReadQuery()) {
305                 ((ObjectLevelReadQuery)query).setLockMode(((Short JavaDoc)valueToApply).shortValue());
306             }
307         }
308     }
309
310     protected static class RefreshHint extends Hint {
311         RefreshHint() {
312             super(TopLinkQueryHints.REFRESH, HintValues.FALSE);
313             valueArray = new Object JavaDoc[][] {
314                 {HintValues.FALSE, Boolean.FALSE},
315                 {HintValues.TRUE, Boolean.TRUE}
316             };
317         }
318     
319         void applyToDatabaseQuery(Object JavaDoc valueToApply, DatabaseQuery query) {
320             if (query.isObjectLevelReadQuery()) {
321                 ((ObjectLevelReadQuery)query).setShouldRefreshIdentityMapResult(((Boolean JavaDoc)valueToApply).booleanValue());
322             }
323         }
324     }
325
326 }
327
Popular Tags