1 56 package org.objectstyle.cayenne.wocompat; 57 58 import java.util.Collection ; 59 import java.util.HashMap ; 60 import java.util.Iterator ; 61 import java.util.List ; 62 import java.util.Map ; 63 import java.util.ArrayList ; 64 65 import org.objectstyle.cayenne.exp.Expression; 66 import org.objectstyle.cayenne.exp.ExpressionFactory; 67 import org.objectstyle.cayenne.exp.ExpressionParameter; 68 import org.objectstyle.cayenne.exp.ExpressionException; 69 import org.objectstyle.cayenne.exp.parser.ASTObjPath; 70 import org.objectstyle.cayenne.map.Entity; 71 import org.objectstyle.cayenne.map.ObjAttribute; 72 import org.objectstyle.cayenne.map.ObjEntity; 73 import org.objectstyle.cayenne.map.ObjRelationship; 74 import org.objectstyle.cayenne.query.SelectQuery; 75 76 84 public class EOQuery extends SelectQuery { 85 86 protected Map plistMap; 87 protected Map bindings; 88 89 public EOQuery(ObjEntity root, Map plistMap) { 90 super(root); 91 this.plistMap = plistMap; 92 initFromPlist(plistMap); 93 } 94 95 protected void initFromPlist(Map plistMap) { 96 97 setResolvingInherited("YES".equalsIgnoreCase((String ) plistMap.get("isDeep"))); 98 setRefreshingObjects("YES".equalsIgnoreCase((String ) plistMap 99 .get("refreshesRefetchedObjects"))); 100 101 setDistinct("YES".equalsIgnoreCase((String ) plistMap.get("usesDistinct"))); 102 103 Object fetchLimit = plistMap.get("fetchLimit"); 104 if (fetchLimit != null) { 105 try { 106 if (fetchLimit instanceof Number ) { 107 setFetchLimit(((Number ) fetchLimit).intValue()); 108 } 109 else { 110 setFetchLimit(Integer.parseInt(fetchLimit.toString())); 111 } 112 } 113 catch (NumberFormatException nfex) { 114 } 116 } 117 118 List orderings = (List ) plistMap.get("sortOrderings"); 120 if (orderings != null && !orderings.isEmpty()) { 121 Iterator it = orderings.iterator(); 122 while (it.hasNext()) { 123 Map ordering = (Map ) it.next(); 124 boolean asc = !"compareDescending:".equals(ordering.get("selectorName")); 125 String key = (String ) ordering.get("key"); 126 if (key != null) { 127 addOrdering(key, asc); 128 } 129 } 130 } 131 132 Map qualifierMap = (Map ) plistMap.get("qualifier"); 134 if (qualifierMap != null && !qualifierMap.isEmpty()) { 135 this.setQualifier(makeQualifier(qualifierMap)); 136 } 137 } 138 139 public String getEOName() { 140 if (getRoot() instanceof EOObjEntity) { 141 return ((EOObjEntity) getRoot()).localQueryName(getName()); 142 } 143 else { 144 return getName(); 145 } 146 } 147 148 public Collection getBindingNames() { 149 if (bindings == null) { 150 initBindings(); 151 } 152 153 return bindings.keySet(); 154 } 155 156 public String bindingClass(String name) { 157 if (bindings == null) { 158 initBindings(); 159 } 160 161 return (String ) bindings.get(name); 162 } 163 164 private synchronized void initBindings() { 165 if (bindings != null) { 166 return; 167 } 168 169 bindings = new HashMap (); 170 171 if (!(getRoot() instanceof Entity)) { 172 return; 173 } 174 175 Map qualifier = (Map ) plistMap.get("qualifier"); 176 initBindings(bindings, (Entity) getRoot(), qualifier); 177 } 178 179 private void initBindings(Map bindings, Entity entity, Map qualifier) { 180 if (qualifier == null) { 181 return; 182 } 183 184 if ("EOKeyValueQualifier".equals(qualifier.get("class"))) { 185 String key = (String ) qualifier.get("key"); 186 if (key == null) { 187 return; 188 } 189 190 Object value = qualifier.get("value"); 191 if (!(value instanceof Map )) { 192 return; 193 } 194 195 Map valueMap = (Map ) value; 196 if (!"EOQualifierVariable".equals(valueMap.get("class")) 197 || !valueMap.containsKey("_key")) { 198 return; 199 } 200 201 String name = (String ) valueMap.get("_key"); 202 String className = null; 203 204 try { 209 Object lastObject = new ASTObjPath(key).evaluate(entity); 210 211 if (lastObject instanceof ObjAttribute) { 212 className = ((ObjAttribute) lastObject).getType(); 213 } 214 else if (lastObject instanceof ObjRelationship) { 215 ObjEntity target = (ObjEntity) ((ObjRelationship) lastObject) 216 .getTargetEntity(); 217 if (target != null) { 218 className = target.getClassName(); 219 } 220 } 221 } 222 catch (ExpressionException ex) { 223 className = "java.lang.Object"; 224 } 225 226 if (className == null) { 227 className = "java.lang.Object"; 228 } 229 230 bindings.put(name, className); 231 232 return; 233 } 234 235 List children = (List ) qualifier.get("qualifiers"); 236 if (children != null) { 237 Iterator it = children.iterator(); 238 while (it.hasNext()) { 239 initBindings(bindings, entity, (Map ) it.next()); 240 } 241 } 242 } 243 244 251 public synchronized Expression makeQualifier(Map qualifierMap) { 252 if (qualifierMap == null) { 253 return null; 254 } 255 256 return EOFetchSpecificationParser.makeQualifier(qualifierMap); 257 } 258 259 266 static class EOFetchSpecificationParser { 267 268 public static final String IS_EQUAL_TO = "isEqualTo:"; 270 public static final String IS_NOT_EQUAL_TO = "isNotEqualTo:"; 271 public static final String IS_LIKE = "isLike:"; 272 public static final String CASE_INSENSITIVE_LIKE = "isCaseInsensitiveLike:"; 273 public static final String IS_LESS_THAN = "isLessThan:"; 274 public static final String IS_LESS_THAN_OR_EQUAL_TO = "isLessThanOrEqualTo:"; 275 public static final String IS_GREATER_THAN = "isGreaterThan:"; 276 public static final String IS_GREATER_THAN_OR_EQUAL_TO = "isGreaterThanOrEqualTo:"; 277 278 private static HashMap selectorToExpressionBridge; 279 280 286 public static HashMap selectorToExpressionBridge() { 287 if (null == selectorToExpressionBridge) { 288 selectorToExpressionBridge = new HashMap (8); 290 selectorToExpressionBridge.put(IS_EQUAL_TO, new Integer ( 291 Expression.EQUAL_TO)); 292 selectorToExpressionBridge.put(IS_NOT_EQUAL_TO, new Integer ( 293 Expression.NOT_EQUAL_TO)); 294 selectorToExpressionBridge.put(IS_LIKE, new Integer (Expression.LIKE)); 295 selectorToExpressionBridge.put(CASE_INSENSITIVE_LIKE, new Integer ( 296 Expression.LIKE_IGNORE_CASE)); 297 selectorToExpressionBridge.put(IS_LESS_THAN, new Integer ( 298 Expression.LESS_THAN)); 299 selectorToExpressionBridge.put(IS_LESS_THAN_OR_EQUAL_TO, new Integer ( 300 Expression.LESS_THAN_EQUAL_TO)); 301 selectorToExpressionBridge.put(IS_GREATER_THAN, new Integer ( 302 Expression.GREATER_THAN)); 303 selectorToExpressionBridge.put(IS_GREATER_THAN_OR_EQUAL_TO, new Integer ( 304 Expression.GREATER_THAN_EQUAL_TO)); 305 } 306 return selectorToExpressionBridge; 307 } 308 309 316 public static boolean isAggregate(Map qualifier) { 317 boolean result = true; 318 319 String theClass = (String ) qualifier.get("class"); 320 if (theClass == null) { 321 return false; } 323 if (theClass.equalsIgnoreCase("EOKeyValueQualifier") 324 || theClass.equalsIgnoreCase("EOKeyComparisonQualifier")) { 325 result = false; 326 } 327 328 return result; 329 } 330 331 339 public static int expressionTypeForQualifier(Map qualifierMap) { 340 String selector = (String ) qualifierMap.get("selectorName"); 342 return expressionTypeForSelector(selector); 343 } 344 345 352 public static int expressionTypeForSelector(String selector) { 353 Integer expType = (Integer ) selectorToExpressionBridge().get(selector); 354 return (expType != null ? expType.intValue() : -1); 355 } 356 357 364 public static int aggregateExpressionClassForQualifier(Map qualifierMap) { 365 String qualifierClass = (String ) qualifierMap.get("class"); 366 if (qualifierClass != null) { 367 if (qualifierClass.equalsIgnoreCase("EOAndQualifier")) { 368 return Expression.AND; 369 } 370 else if (qualifierClass.equalsIgnoreCase("EOOrQualifier")) { 371 return Expression.OR; 372 } 373 else if (qualifierClass.equalsIgnoreCase("EONotQualifier")) { 374 return Expression.NOT; 375 } 376 } 377 378 return -1; } 380 381 389 public static Expression makeQualifier(Map qualifierMap) { 390 if (isAggregate(qualifierMap)) { 391 int aggregateClass = aggregateExpressionClassForQualifier(qualifierMap); 396 if (aggregateClass == Expression.NOT) { 397 Map child = (Map ) qualifierMap.get("qualifier"); 399 Expression childExp = makeQualifier(child); 401 402 return childExp.notExp(); 405 } 406 else { 407 List children = (List ) qualifierMap.get("qualifiers"); 411 if (children != null) { 412 ArrayList childExpressions = new ArrayList (); 413 Iterator it = children.iterator(); 415 while (it.hasNext()) { 416 Expression childExp = makeQualifier((Map ) it.next()); 417 childExpressions.add(childExp); 418 } 419 return ExpressionFactory 421 .joinExp(aggregateClass, childExpressions); 422 } 423 } 424 425 } 427 int expType = expressionTypeForQualifier(qualifierMap); String qualifierClass = (String ) qualifierMap.get("class"); 431 432 String key = null; 434 Object comparisonValue = null; 437 438 if ("EOKeyComparisonQualifier".equals(qualifierClass)) { 439 key = (String ) qualifierMap.get("leftValue"); 441 comparisonValue = (String ) qualifierMap.get("rightValue"); 442 443 return null; 446 } 447 else if ("EOKeyValueQualifier".equals(qualifierClass)) { 448 key = (String ) qualifierMap.get("key"); 450 Object value = qualifierMap.get("value"); 451 452 if (value instanceof Map ) { 453 Map valueMap = (Map ) value; 454 String objClass = (String ) valueMap.get("class"); 458 if ("EOQualifierVariable".equals(objClass) 459 && valueMap.containsKey("_key")) { 460 String paramName = (String ) valueMap.get("_key"); 462 comparisonValue = new ExpressionParameter(paramName); 463 } 464 else { 465 Object queryVal = valueMap.get("value"); 466 if ("NSNumber".equals(objClass)) { 467 comparisonValue = (Number ) queryVal; 469 } 470 else if ("EONull".equals(objClass)) { 471 comparisonValue = null; 473 } 474 else { comparisonValue = queryVal; 477 } 478 } 479 480 } 481 else if (value instanceof String ) { 482 comparisonValue = value; 484 } } 486 487 switch (expType) { 490 case Expression.EQUAL_TO: 491 return ExpressionFactory.matchExp(key, comparisonValue); 492 case Expression.NOT_EQUAL_TO: 493 return ExpressionFactory.noMatchExp(key, comparisonValue); 494 case Expression.LIKE: 495 return ExpressionFactory.likeExp(key, comparisonValue); 496 case Expression.LIKE_IGNORE_CASE: 497 return ExpressionFactory.likeIgnoreCaseExp(key, comparisonValue); 498 case Expression.LESS_THAN: 499 return ExpressionFactory.lessExp(key, comparisonValue); 500 case Expression.LESS_THAN_EQUAL_TO: 501 return ExpressionFactory.lessOrEqualExp(key, comparisonValue); 502 case Expression.GREATER_THAN: 503 return ExpressionFactory.greaterExp(key, comparisonValue); 504 case Expression.GREATER_THAN_EQUAL_TO: 505 return ExpressionFactory.greaterOrEqualExp(key, comparisonValue); 506 default: 507 return null; 508 } 509 } 510 } 511 } | Popular Tags |