1 56 57 package org.objectstyle.cayenne.exp; 58 59 import java.util.ArrayList ; 60 import java.util.Collection ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 import java.util.Map ; 64 65 import org.objectstyle.cayenne.exp.parser.ASTAdd; 66 import org.objectstyle.cayenne.exp.parser.ASTAnd; 67 import org.objectstyle.cayenne.exp.parser.ASTBetween; 68 import org.objectstyle.cayenne.exp.parser.ASTDbPath; 69 import org.objectstyle.cayenne.exp.parser.ASTDivide; 70 import org.objectstyle.cayenne.exp.parser.ASTEqual; 71 import org.objectstyle.cayenne.exp.parser.ASTGreater; 72 import org.objectstyle.cayenne.exp.parser.ASTGreaterOrEqual; 73 import org.objectstyle.cayenne.exp.parser.ASTIn; 74 import org.objectstyle.cayenne.exp.parser.ASTLess; 75 import org.objectstyle.cayenne.exp.parser.ASTLessOrEqual; 76 import org.objectstyle.cayenne.exp.parser.ASTLike; 77 import org.objectstyle.cayenne.exp.parser.ASTLikeIgnoreCase; 78 import org.objectstyle.cayenne.exp.parser.ASTList; 79 import org.objectstyle.cayenne.exp.parser.ASTMultiply; 80 import org.objectstyle.cayenne.exp.parser.ASTNegate; 81 import org.objectstyle.cayenne.exp.parser.ASTNot; 82 import org.objectstyle.cayenne.exp.parser.ASTNotBetween; 83 import org.objectstyle.cayenne.exp.parser.ASTNotEqual; 84 import org.objectstyle.cayenne.exp.parser.ASTNotIn; 85 import org.objectstyle.cayenne.exp.parser.ASTNotLike; 86 import org.objectstyle.cayenne.exp.parser.ASTNotLikeIgnoreCase; 87 import org.objectstyle.cayenne.exp.parser.ASTObjPath; 88 import org.objectstyle.cayenne.exp.parser.ASTOr; 89 import org.objectstyle.cayenne.exp.parser.ASTSubtract; 90 import org.objectstyle.cayenne.exp.parser.SimpleNode; 91 92 97 public class ExpressionFactory { 98 private static Class [] typeLookup; 99 100 static { 101 int[] allTypes = 104 new int[] { 105 Expression.AND, 106 Expression.OR, 107 Expression.NOT, 108 Expression.EQUAL_TO, 109 Expression.NOT_EQUAL_TO, 110 Expression.LESS_THAN, 111 Expression.GREATER_THAN, 112 Expression.LESS_THAN_EQUAL_TO, 113 Expression.GREATER_THAN_EQUAL_TO, 114 Expression.BETWEEN, 115 Expression.IN, 116 Expression.LIKE, 117 Expression.LIKE_IGNORE_CASE, 118 Expression.EXISTS, 119 Expression.ADD, 120 Expression.SUBTRACT, 121 Expression.MULTIPLY, 122 Expression.DIVIDE, 123 Expression.NEGATIVE, 124 Expression.POSITIVE, 125 Expression.ALL, 126 Expression.SOME, 127 Expression.ANY, 128 Expression.RAW_SQL, 129 Expression.OBJ_PATH, 130 Expression.DB_PATH, 131 Expression.LIST, 132 Expression.SUBQUERY, 133 Expression.COUNT, 134 Expression.SUM, 135 Expression.AVG, 136 Expression.MIN, 137 Expression.MAX, 138 Expression.NOT_BETWEEN, 139 Expression.NOT_IN, 140 Expression.NOT_LIKE, 141 Expression.NOT_LIKE_IGNORE_CASE }; 142 143 int max = 0; 144 int min = 0; 145 int allLen = allTypes.length; 146 for (int i = 0; i < allLen; i++) { 147 if (allTypes[i] > max) 148 max = allTypes[i]; 149 else if (allTypes[i] < min) 150 min = allTypes[i]; 151 } 152 153 if (max > 500) 155 throw new RuntimeException ("Types values are too big: " + max); 156 if (min < 0) 157 throw new RuntimeException ("Types values are too small: " + min); 158 159 162 typeLookup = new Class [max + 1]; 163 164 typeLookup[Expression.AND] = ASTAnd.class; 165 typeLookup[Expression.OR] = ASTOr.class; 166 typeLookup[Expression.BETWEEN] = ASTBetween.class; 167 typeLookup[Expression.NOT_BETWEEN] = ASTNotBetween.class; 168 169 typeLookup[Expression.EQUAL_TO] = ASTEqual.class; 171 typeLookup[Expression.NOT_EQUAL_TO] = ASTNotEqual.class; 172 typeLookup[Expression.LESS_THAN] = ASTLess.class; 173 typeLookup[Expression.GREATER_THAN] = ASTGreater.class; 174 typeLookup[Expression.LESS_THAN_EQUAL_TO] = ASTLessOrEqual.class; 175 typeLookup[Expression.GREATER_THAN_EQUAL_TO] = ASTGreaterOrEqual.class; 176 typeLookup[Expression.IN] = ASTIn.class; 177 typeLookup[Expression.NOT_IN] = ASTNotIn.class; 178 typeLookup[Expression.LIKE] = ASTLike.class; 179 typeLookup[Expression.LIKE_IGNORE_CASE] = ASTLikeIgnoreCase.class; 180 typeLookup[Expression.NOT_LIKE] = ASTNotLike.class; 181 typeLookup[Expression.NOT_LIKE_IGNORE_CASE] = ASTNotLikeIgnoreCase.class; 182 typeLookup[Expression.ADD] = ASTAdd.class; 183 typeLookup[Expression.SUBTRACT] = ASTSubtract.class; 184 typeLookup[Expression.MULTIPLY] = ASTMultiply.class; 185 typeLookup[Expression.DIVIDE] = ASTDivide.class; 186 187 typeLookup[Expression.NOT] = ASTNot.class; 188 typeLookup[Expression.NEGATIVE] = ASTNegate.class; 189 typeLookup[Expression.OBJ_PATH] = ASTObjPath.class; 190 typeLookup[Expression.DB_PATH] = ASTDbPath.class; 191 typeLookup[Expression.LIST] = ASTList.class; 192 193 typeLookup[Expression.EXISTS] = UnaryExpression.class; 195 typeLookup[Expression.POSITIVE] = UnaryExpression.class; 196 typeLookup[Expression.ALL] = UnaryExpression.class; 197 typeLookup[Expression.SOME] = UnaryExpression.class; 198 typeLookup[Expression.ANY] = UnaryExpression.class; 199 typeLookup[Expression.RAW_SQL] = UnaryExpression.class; 200 typeLookup[Expression.SUBQUERY] = UnaryExpression.class; 201 typeLookup[Expression.SUM] = UnaryExpression.class; 202 typeLookup[Expression.AVG] = UnaryExpression.class; 203 typeLookup[Expression.COUNT] = UnaryExpression.class; 204 typeLookup[Expression.MIN] = UnaryExpression.class; 205 typeLookup[Expression.MAX] = UnaryExpression.class; 206 } 207 208 212 public static Expression expressionOfType(int type) { 213 if (type < 0 || type >= typeLookup.length) { 214 throw new ExpressionException("Bad expression type: " + type); 215 } 216 217 if (typeLookup[type] == null) { 218 throw new ExpressionException("Bad expression type: " + type); 219 } 220 221 if (SimpleNode.class.isAssignableFrom(typeLookup[type])) { 223 try { 224 return (Expression) typeLookup[type].newInstance(); 225 } 226 catch (Exception ex) { 227 throw new ExpressionException("Error creating expression", ex); 228 } 229 } 230 231 if (BinaryExpression.class == typeLookup[type]) { 233 return new BinaryExpression(type); 234 } 235 236 if (UnaryExpression.class == typeLookup[type]) { 237 return new UnaryExpression(type); 238 } 239 240 if (TernaryExpression.class == typeLookup[type]) { 241 return new TernaryExpression(type); 242 } 243 244 if (ListExpression.class == typeLookup[type]) { 245 return new ListExpression(type); 246 } 247 248 throw new ExpressionException("Bad expression type: " + type); 249 } 250 251 256 protected static Object wrapPathOperand(Object op) { 257 if (op instanceof Collection ) { 258 return new ASTList((Collection ) op); 259 } 260 else if (op instanceof Object []) { 261 return new ASTList((Object []) op); 262 } 263 else { 264 return op; 265 } 266 } 267 268 272 public static Expression unaryExp(int type, Object operand) { 273 Expression exp = expressionOfType(type); 274 exp.setOperand(0, operand); 275 return exp; 276 } 277 278 282 public static Expression binaryExp( 283 int type, 284 Object leftOperand, 285 Object rightOperand) { 286 Expression exp = expressionOfType(type); 287 exp.setOperand(0, leftOperand); 288 exp.setOperand(1, rightOperand); 289 return exp; 290 } 291 292 296 public static Expression binaryPathExp(int type, String pathSpec, Object value) { 297 return binaryExp( 298 type, 299 unaryExp(Expression.OBJ_PATH, pathSpec), 300 wrapPathOperand(value)); 301 } 302 303 307 public static Expression binaryDbPathExp(int type, String pathSpec, Object value) { 308 return binaryExp( 309 type, 310 unaryExp(Expression.DB_PATH, pathSpec), 311 wrapPathOperand(value)); 312 } 313 314 321 public static Expression matchAnyDbExp(Map map, int pairType) { 322 List pairs = new ArrayList (); 323 324 Iterator it = map.entrySet().iterator(); 325 while (it.hasNext()) { 326 Map.Entry entry = (Map.Entry ) it.next(); 327 pairs.add( 328 binaryDbPathExp(pairType, (String ) entry.getKey(), entry.getValue())); 329 } 330 331 return joinExp(Expression.OR, pairs); 332 } 333 334 341 public static Expression matchAllDbExp(Map map, int pairType) { 342 List pairs = new ArrayList (); 343 344 Iterator it = map.entrySet().iterator(); 345 while (it.hasNext()) { 346 Map.Entry entry = (Map.Entry ) it.next(); 347 pairs.add( 348 binaryDbPathExp(pairType, (String ) entry.getKey(), entry.getValue())); 349 } 350 351 return joinExp(Expression.AND, pairs); 352 } 353 354 361 public static Expression matchAnyExp(Map map, int pairType) { 362 List pairs = new ArrayList (); 363 364 Iterator it = map.entrySet().iterator(); 365 while (it.hasNext()) { 366 Map.Entry entry = (Map.Entry ) it.next(); 367 pairs.add(binaryPathExp(pairType, (String ) entry.getKey(), entry.getValue())); 368 } 369 370 return joinExp(Expression.OR, pairs); 371 } 372 373 380 public static Expression matchAllExp(Map map, int pairType) { 381 List pairs = new ArrayList (); 382 383 Iterator it = map.entrySet().iterator(); 384 while (it.hasNext()) { 385 Map.Entry entry = (Map.Entry ) it.next(); 386 pairs.add(binaryPathExp(pairType, (String ) entry.getKey(), entry.getValue())); 387 } 388 389 return joinExp(Expression.AND, pairs); 390 } 391 392 395 public static Expression matchDbExp(String pathSpec, Object value) { 396 return new ASTEqual(new ASTDbPath(pathSpec), value); 397 } 398 399 402 public static Expression noMatchDbExp(String pathSpec, Object value) { 403 return new ASTNotEqual(new ASTDbPath(pathSpec), value); 404 } 405 406 409 public static Expression inDbExp(String pathSpec, Object [] values) { 410 return new ASTIn(new ASTDbPath(pathSpec), new ASTList(values)); 411 } 412 413 416 public static Expression inDbExp(String pathSpec, Collection values) { 417 return new ASTIn(new ASTDbPath(pathSpec), new ASTList(values)); 418 } 419 420 423 public static Expression matchExp(String pathSpec, Object value) { 424 return new ASTEqual(new ASTObjPath(pathSpec), value); 425 } 426 427 430 public static Expression noMatchExp(String pathSpec, Object value) { 431 return new ASTNotEqual(new ASTObjPath(pathSpec), value); 432 } 433 434 437 public static Expression lessExp(String pathSpec, Object value) { 438 return new ASTLess(new ASTObjPath(pathSpec), value); 439 } 440 441 444 public static Expression lessOrEqualExp(String pathSpec, Object value) { 445 return new ASTLessOrEqual(new ASTObjPath(pathSpec), value); 446 } 447 448 451 public static Expression greaterExp(String pathSpec, Object value) { 452 return new ASTGreater(new ASTObjPath(pathSpec), value); 453 } 454 455 458 public static Expression greaterOrEqualExp(String pathSpec, Object value) { 459 return new ASTGreaterOrEqual(new ASTObjPath(pathSpec), value); 460 } 461 462 465 public static Expression inExp(String pathSpec, Object [] values) { 466 return new ASTIn(new ASTObjPath(pathSpec), new ASTList(values)); 467 } 468 469 472 public static Expression inExp(String pathSpec, Collection values) { 473 return new ASTIn(new ASTObjPath(pathSpec), new ASTList(values)); 474 } 475 476 479 public static Expression notInExp(String pathSpec, Collection values) { 480 return new ASTNotIn(new ASTObjPath(pathSpec), new ASTList(values)); 481 } 482 483 487 public static Expression notInExp(String pathSpec, Object [] values) { 488 return new ASTNotIn(new ASTObjPath(pathSpec), new ASTList(values)); 489 } 490 491 494 public static Expression betweenExp(String pathSpec, Object value1, Object value2) { 495 return new ASTBetween(new ASTObjPath(pathSpec), value1, value2); 496 } 497 498 501 public static Expression notBetweenExp( 502 String pathSpec, 503 Object value1, 504 Object value2) { 505 return new ASTNotBetween(new ASTObjPath(pathSpec), value1, value2); 506 } 507 508 511 public static Expression likeExp(String pathSpec, Object value) { 512 return new ASTLike(new ASTObjPath(pathSpec), value); 513 } 514 515 518 public static Expression notLikeExp(String pathSpec, Object value) { 519 return new ASTNotLike(new ASTObjPath(pathSpec), value); 520 } 521 522 525 public static Expression likeIgnoreCaseExp(String pathSpec, Object value) { 526 return new ASTLikeIgnoreCase(new ASTObjPath(pathSpec), value); 527 } 528 529 532 public static Expression notLikeIgnoreCaseExp(String pathSpec, Object value) { 533 return new ASTNotLikeIgnoreCase(new ASTObjPath(pathSpec), value); 534 } 535 536 546 public static Expression joinExp(int type, List expressions) { 547 int len = expressions.size(); 548 if (len == 0) 549 return null; 550 551 Expression currentExp = (Expression) expressions.get(0); 552 if (len == 1) { 553 return currentExp; 554 } 555 556 Expression exp = expressionOfType(type); 557 for (int i = 0; i < len; i++) { 558 exp.setOperand(i, expressions.get(i)); 559 } 560 return exp; 561 } 562 } | Popular Tags |