1 21 package oracle.toplink.essentials.internal.ejb.cmp3.base; 23 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Map ; 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 59 public class QueryHintsHandler { 60 61 70 public static void verify(Map hints, String queryName, AbstractSession session) { 71 if(hints == null) { 72 return; 73 } 74 Iterator it = hints.entrySet().iterator(); 75 while(it.hasNext()) { 76 Map.Entry entry = (Map.Entry )it.next(); 77 String hintName = (String )entry.getKey(); 78 verify(hintName, entry.getValue(), queryName, session); 79 } 80 } 81 82 91 public static void verify(String hintName, Object hintValue, String queryName, AbstractSession session) { 92 Hint.verify(hintName, shouldUseDefault(hintValue), hintValue, queryName, session); 93 } 94 95 100 public static void apply(Map hints, DatabaseQuery query) { 101 if(hints == null) { 102 return; 103 } 104 Iterator it = hints.entrySet().iterator(); 105 while(it.hasNext()) { 106 Map.Entry entry = (Map.Entry )it.next(); 107 String hintName = (String )entry.getKey(); 108 apply(hintName, entry.getValue(), query); 109 } 110 } 111 112 117 public static void apply(String hintName, Object hintValue, DatabaseQuery query) { 118 Hint.apply(hintName, shouldUseDefault(hintValue), hintValue, query); 119 } 120 121 126 protected static boolean shouldUseDefault(Object hintValue) { 127 return (hintValue != null) && (hintValue instanceof String ) && (((String )hintValue).length() == 0); 128 } 129 130 protected static abstract class Hint { 131 static HashMap mainMap = new HashMap (); 132 Object [] valueArray; 133 HashMap valueMap; 134 String name; 135 String defaultValue; 136 Object 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 name, String defaultValue) { 147 this.name = name; 148 this.defaultValue = defaultValue; 149 } 150 151 abstract void applyToDatabaseQuery(Object valueToApply, DatabaseQuery query); 152 153 static void verify(String hintName, boolean shouldUseDefault, Object hintValue, String 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 []{getPrintValue(queryName), hintName}); 158 } 159 return; 160 } 161 162 hint.verify(hintValue, shouldUseDefault, queryName, session); 163 } 164 165 void verify(Object hintValue, boolean shouldUseDefault, String 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 []{getPrintValue(queryName), name, getPrintValue(hintValue)}); 171 } 172 if(!shouldUseDefault && valueMap != null && !valueMap.containsKey(getUpperCaseString(hintValue))) { 173 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object []{getPrintValue(queryName), name, getPrintValue(hintValue)})); 174 } 175 } 176 177 static void apply(String hintName, boolean shouldUseDefault, Object hintValue, DatabaseQuery query) { 178 Hint hint = (Hint)mainMap.get(hintName); 179 if(hint == null) { 180 return; 182 } 183 184 hint.apply(hintValue, shouldUseDefault, query); 185 } 186 187 void apply(Object hintValue, boolean shouldUseDefault, DatabaseQuery query) { 188 Object valueToApply = hintValue; 189 if(shouldUseDefault) { 190 valueToApply = defaultValueToApply; 191 } else { 192 if(valueMap != null) { 193 String 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 (ExceptionLocalization.buildMessage("ejb30-wrong-query-hint-value",new Object []{getQueryId(query), name, getPrintValue(hintValue)})); 202 } 203 } 204 } 205 } 206 applyToDatabaseQuery(valueToApply, query); 207 } 208 209 static String getQueryId(DatabaseQuery query) { 210 String queryId = query.getName(); 211 if(queryId == null) { 212 queryId = query.getEJBQLString(); 213 } 214 return getPrintValue(queryId); 215 } 216 217 static String getPrintValue(Object hintValue) { 218 return hintValue != null ? hintValue.toString() : "null"; 219 } 220 221 static String getUpperCaseString(Object hintValue) { 222 return hintValue != null ? hintValue.toString().toUpperCase() : null; 223 } 224 225 void initialize() { 226 if(valueArray != null) { 227 valueMap = new HashMap (valueArray.length); 228 if(valueArray instanceof Object [][]) { 229 Object [][] valueArray2 = (Object [][])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 [][] { 257 {HintValues.PERSISTENCE_UNIT_DEFAULT, null}, 258 {HintValues.TRUE, Boolean.TRUE}, 259 {HintValues.FALSE, Boolean.FALSE} 260 }; 261 } 262 263 void applyToDatabaseQuery(Object valueToApply, DatabaseQuery query) { 264 if(valueToApply == null) { 265 query.ignoreBindAllParameters(); 266 } else { 267 query.setShouldBindAllParameters(((Boolean )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 [][] { 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 valueToApply, DatabaseQuery query) { 287 if (query.isObjectLevelReadQuery()) { 288 ((ObjectLevelReadQuery)query).setCacheUsage(((Integer )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 [][] { 297 {PessimisticLock.NoLock, ObjectLevelReadQuery.NO_LOCK}, 298 {PessimisticLock.Lock, ObjectLevelReadQuery.LOCK}, 299 {PessimisticLock.LockNoWait, ObjectLevelReadQuery.LOCK_NOWAIT} 300 }; 301 } 302 303 void applyToDatabaseQuery(Object valueToApply, DatabaseQuery query) { 304 if (query.isObjectLevelReadQuery()) { 305 ((ObjectLevelReadQuery)query).setLockMode(((Short )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 [][] { 314 {HintValues.FALSE, Boolean.FALSE}, 315 {HintValues.TRUE, Boolean.TRUE} 316 }; 317 } 318 319 void applyToDatabaseQuery(Object valueToApply, DatabaseQuery query) { 320 if (query.isObjectLevelReadQuery()) { 321 ((ObjectLevelReadQuery)query).setShouldRefreshIdentityMapResult(((Boolean )valueToApply).booleanValue()); 322 } 323 } 324 } 325 326 } 327 | Popular Tags |