1 19 20 package org.apache.cayenne.wocompat; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import org.apache.cayenne.exp.Expression; 30 import org.apache.cayenne.exp.ExpressionException; 31 import org.apache.cayenne.exp.ExpressionFactory; 32 import org.apache.cayenne.exp.ExpressionParameter; 33 import org.apache.cayenne.exp.parser.ASTObjPath; 34 import org.apache.cayenne.map.Entity; 35 import org.apache.cayenne.map.ObjAttribute; 36 import org.apache.cayenne.map.ObjEntity; 37 import org.apache.cayenne.map.ObjRelationship; 38 import org.apache.cayenne.query.SelectQuery; 39 40 48 public class EOQuery extends SelectQuery { 49 50 protected Map plistMap; 51 protected Map bindings; 52 53 public EOQuery(ObjEntity root, Map plistMap) { 54 super(root); 55 this.plistMap = plistMap; 56 initFromPlist(plistMap); 57 } 58 59 protected void initFromPlist(Map plistMap) { 60 61 setResolvingInherited("YES".equalsIgnoreCase((String ) plistMap.get("isDeep"))); 62 setRefreshingObjects("YES".equalsIgnoreCase((String ) plistMap 63 .get("refreshesRefetchedObjects"))); 64 65 setDistinct("YES".equalsIgnoreCase((String ) plistMap.get("usesDistinct"))); 66 67 Object fetchLimit = plistMap.get("fetchLimit"); 68 if (fetchLimit != null) { 69 try { 70 if (fetchLimit instanceof Number ) { 71 setFetchLimit(((Number ) fetchLimit).intValue()); 72 } 73 else { 74 setFetchLimit(Integer.parseInt(fetchLimit.toString())); 75 } 76 } 77 catch (NumberFormatException nfex) { 78 } 80 } 81 82 List orderings = (List ) plistMap.get("sortOrderings"); 84 if (orderings != null && !orderings.isEmpty()) { 85 Iterator it = orderings.iterator(); 86 while (it.hasNext()) { 87 Map ordering = (Map ) it.next(); 88 boolean asc = !"compareDescending:".equals(ordering.get("selectorName")); 89 String key = (String ) ordering.get("key"); 90 if (key != null) { 91 addOrdering(key, asc); 92 } 93 } 94 } 95 96 Map qualifierMap = (Map ) plistMap.get("qualifier"); 98 if (qualifierMap != null && !qualifierMap.isEmpty()) { 99 this.setQualifier(makeQualifier(qualifierMap)); 100 } 101 102 List prefetches = (List ) plistMap.get("prefetchingRelationshipKeyPaths"); 104 if (prefetches != null && !prefetches.isEmpty()) { 105 Iterator it = prefetches.iterator(); 106 while (it.hasNext()) { 107 addPrefetch((String ) it.next()); 108 } 109 } 110 111 if(plistMap.containsKey("rawRowKeyPaths")) { 114 setFetchingDataRows(true); 115 } 116 } 117 118 public String getEOName() { 119 if (root instanceof EOObjEntity) { 120 return ((EOObjEntity) root).localQueryName(getName()); 121 } 122 else { 123 return getName(); 124 } 125 } 126 127 public Collection getBindingNames() { 128 if (bindings == null) { 129 initBindings(); 130 } 131 132 return bindings.keySet(); 133 } 134 135 public String bindingClass(String name) { 136 if (bindings == null) { 137 initBindings(); 138 } 139 140 return (String ) bindings.get(name); 141 } 142 143 private synchronized void initBindings() { 144 if (bindings != null) { 145 return; 146 } 147 148 bindings = new HashMap (); 149 150 if (!(root instanceof Entity)) { 151 return; 152 } 153 154 Map qualifier = (Map ) plistMap.get("qualifier"); 155 initBindings(bindings, (Entity) root, qualifier); 156 } 157 158 private void initBindings(Map bindings, Entity entity, Map qualifier) { 159 if (qualifier == null) { 160 return; 161 } 162 163 if ("EOKeyValueQualifier".equals(qualifier.get("class"))) { 164 String key = (String ) qualifier.get("key"); 165 if (key == null) { 166 return; 167 } 168 169 Object value = qualifier.get("value"); 170 if (!(value instanceof Map )) { 171 return; 172 } 173 174 Map valueMap = (Map ) value; 175 if (!"EOQualifierVariable".equals(valueMap.get("class")) 176 || !valueMap.containsKey("_key")) { 177 return; 178 } 179 180 String name = (String ) valueMap.get("_key"); 181 String className = null; 182 183 try { 188 Object lastObject = new ASTObjPath(key).evaluate(entity); 189 190 if (lastObject instanceof ObjAttribute) { 191 className = ((ObjAttribute) lastObject).getType(); 192 } 193 else if (lastObject instanceof ObjRelationship) { 194 ObjEntity target = (ObjEntity) ((ObjRelationship) lastObject) 195 .getTargetEntity(); 196 if (target != null) { 197 className = target.getClassName(); 198 } 199 } 200 } 201 catch (ExpressionException ex) { 202 className = "java.lang.Object"; 203 } 204 205 if (className == null) { 206 className = "java.lang.Object"; 207 } 208 209 bindings.put(name, className); 210 211 return; 212 } 213 214 List children = (List ) qualifier.get("qualifiers"); 215 if (children != null) { 216 Iterator it = children.iterator(); 217 while (it.hasNext()) { 218 initBindings(bindings, entity, (Map ) it.next()); 219 } 220 } 221 } 222 223 230 public synchronized Expression makeQualifier(Map qualifierMap) { 231 if (qualifierMap == null) { 232 return null; 233 } 234 235 return EOFetchSpecificationParser.makeQualifier( 236 (EOObjEntity) getRoot(), 237 qualifierMap); 238 } 239 240 247 static class EOFetchSpecificationParser { 248 249 static final String IS_EQUAL_TO = "isEqualTo:"; 251 static final String IS_NOT_EQUAL_TO = "isNotEqualTo:"; 252 static final String IS_LIKE = "isLike:"; 253 static final String CASE_INSENSITIVE_LIKE = "isCaseInsensitiveLike:"; 254 static final String IS_LESS_THAN = "isLessThan:"; 255 static final String IS_LESS_THAN_OR_EQUAL_TO = "isLessThanOrEqualTo:"; 256 static final String IS_GREATER_THAN = "isGreaterThan:"; 257 static final String IS_GREATER_THAN_OR_EQUAL_TO = "isGreaterThanOrEqualTo:"; 258 259 private static HashMap selectorToExpressionBridge; 260 261 267 static HashMap selectorToExpressionBridge() { 268 if (null == selectorToExpressionBridge) { 269 selectorToExpressionBridge = new HashMap (8); 271 selectorToExpressionBridge.put(IS_EQUAL_TO, new Integer ( 272 Expression.EQUAL_TO)); 273 selectorToExpressionBridge.put(IS_NOT_EQUAL_TO, new Integer ( 274 Expression.NOT_EQUAL_TO)); 275 selectorToExpressionBridge.put(IS_LIKE, new Integer (Expression.LIKE)); 276 selectorToExpressionBridge.put(CASE_INSENSITIVE_LIKE, new Integer ( 277 Expression.LIKE_IGNORE_CASE)); 278 selectorToExpressionBridge.put(IS_LESS_THAN, new Integer ( 279 Expression.LESS_THAN)); 280 selectorToExpressionBridge.put(IS_LESS_THAN_OR_EQUAL_TO, new Integer ( 281 Expression.LESS_THAN_EQUAL_TO)); 282 selectorToExpressionBridge.put(IS_GREATER_THAN, new Integer ( 283 Expression.GREATER_THAN)); 284 selectorToExpressionBridge.put(IS_GREATER_THAN_OR_EQUAL_TO, new Integer ( 285 Expression.GREATER_THAN_EQUAL_TO)); 286 } 287 return selectorToExpressionBridge; 288 } 289 290 297 static boolean isAggregate(Map qualifier) { 298 boolean result = true; 299 300 String theClass = (String ) qualifier.get("class"); 301 if (theClass == null) { 302 return false; } 304 if (theClass.equalsIgnoreCase("EOKeyValueQualifier") 305 || theClass.equalsIgnoreCase("EOKeyComparisonQualifier")) { 306 result = false; 307 } 308 309 return result; 310 } 311 312 320 static int expressionTypeForQualifier(Map qualifierMap) { 321 String selector = (String ) qualifierMap.get("selectorName"); 323 return expressionTypeForSelector(selector); 324 } 325 326 333 static int expressionTypeForSelector(String selector) { 334 Integer expType = (Integer ) selectorToExpressionBridge().get(selector); 335 return (expType != null ? expType.intValue() : -1); 336 } 337 338 345 static int aggregateExpressionClassForQualifier(Map qualifierMap) { 346 String qualifierClass = (String ) qualifierMap.get("class"); 347 if (qualifierClass != null) { 348 if (qualifierClass.equalsIgnoreCase("EOAndQualifier")) { 349 return Expression.AND; 350 } 351 else if (qualifierClass.equalsIgnoreCase("EOOrQualifier")) { 352 return Expression.OR; 353 } 354 else if (qualifierClass.equalsIgnoreCase("EONotQualifier")) { 355 return Expression.NOT; 356 } 357 } 358 359 return -1; } 361 362 370 static Expression makeQualifier(EOObjEntity entity, Map qualifierMap) { 371 if (isAggregate(qualifierMap)) { 372 int aggregateClass = aggregateExpressionClassForQualifier(qualifierMap); 377 if (aggregateClass == Expression.NOT) { 378 Map child = (Map ) qualifierMap.get("qualifier"); 380 Expression childExp = makeQualifier(entity, child); 382 383 return childExp.notExp(); } 386 else { 387 List children = (List ) qualifierMap.get("qualifiers"); 391 if (children != null) { 392 ArrayList childExpressions = new ArrayList (); 393 Iterator it = children.iterator(); 395 while (it.hasNext()) { 396 Expression childExp = makeQualifier(entity, (Map ) it.next()); 397 childExpressions.add(childExp); 398 } 399 return ExpressionFactory 401 .joinExp(aggregateClass, childExpressions); 402 } 403 } 404 405 } 407 String qualifierClass = (String ) qualifierMap.get("class"); 410 411 String key = null; 413 Object comparisonValue = null; 416 417 if ("EOKeyComparisonQualifier".equals(qualifierClass)) { 418 key = (String ) qualifierMap.get("leftValue"); 420 comparisonValue = (String ) qualifierMap.get("rightValue"); 421 422 return null; 425 } 426 else if ("EOKeyValueQualifier".equals(qualifierClass)) { 427 key = (String ) qualifierMap.get("key"); 429 Object value = qualifierMap.get("value"); 430 431 if (value instanceof Map ) { 432 Map valueMap = (Map ) value; 433 String objClass = (String ) valueMap.get("class"); 437 if ("EOQualifierVariable".equals(objClass) 438 && valueMap.containsKey("_key")) { 439 String paramName = (String ) valueMap.get("_key"); 441 comparisonValue = new ExpressionParameter(paramName); 442 } 443 else { 444 Object queryVal = valueMap.get("value"); 445 if ("NSNumber".equals(objClass)) { 446 comparisonValue = (Number ) queryVal; 448 } 449 else if ("EONull".equals(objClass)) { 450 comparisonValue = null; 452 } 453 else { comparisonValue = queryVal; 456 } 457 } 458 459 } 460 else if (value instanceof String ) { 461 comparisonValue = value; 463 } } 465 466 469 Expression keyExp = Expression.fromString(key); 470 try { 471 entity.lastPathComponent(keyExp); 472 } 473 catch (ExpressionException e) { 474 keyExp = entity.translateToDbPath(keyExp); 475 } 476 477 try { 478 Expression exp = ExpressionFactory 479 .expressionOfType(expressionTypeForQualifier(qualifierMap)); 480 481 exp.setOperand(0, keyExp); 482 exp.setOperand(1, comparisonValue); 483 return exp; 484 } 485 catch (ExpressionException e) { 486 return null; 487 } 488 } 489 } 490 } 491 | Popular Tags |