1 25 package org.objectweb.jonas_ejb.lib; 26 27 import java.util.ArrayList ; 28 import java.util.Map ; 29 import java.util.Stack ; 30 31 import javax.ejb.EJBObject ; 32 33 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticExpression; 34 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticFactor; 35 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticLiteral; 36 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticTerm; 37 import org.objectweb.jonas_ejb.deployment.ejbql.ASTBetweenExpression; 38 import org.objectweb.jonas_ejb.deployment.ejbql.ASTBooleanExpression; 39 import org.objectweb.jonas_ejb.deployment.ejbql.ASTBooleanLiteral; 40 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCmpPathExpression; 41 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCollectionMemberExpression; 42 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCollectionValuedPathExpression; 43 import org.objectweb.jonas_ejb.deployment.ejbql.ASTComparisonExpression; 44 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalExpression; 45 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalFactor; 46 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalTerm; 47 import org.objectweb.jonas_ejb.deployment.ejbql.ASTDatetimeExpression; 48 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEJBQL; 49 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEmptyCollectionComparisonExpression; 50 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEntityBeanExpression; 51 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFloatingPointLiteral; 52 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFunctionsReturningNumerics; 53 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFunctionsReturningStrings; 54 import org.objectweb.jonas_ejb.deployment.ejbql.ASTIdentificationVariable; 55 import org.objectweb.jonas_ejb.deployment.ejbql.ASTInExpression; 56 import org.objectweb.jonas_ejb.deployment.ejbql.ASTInputParameter; 57 import org.objectweb.jonas_ejb.deployment.ejbql.ASTIntegerLiteral; 58 import org.objectweb.jonas_ejb.deployment.ejbql.ASTLikeExpression; 59 import org.objectweb.jonas_ejb.deployment.ejbql.ASTLiteral; 60 import org.objectweb.jonas_ejb.deployment.ejbql.ASTNullComparisonExpression; 61 import org.objectweb.jonas_ejb.deployment.ejbql.ASTPath; 62 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedCmrPathExpression; 63 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedPathExpression; 64 import org.objectweb.jonas_ejb.deployment.ejbql.ASTStringExpression; 65 import org.objectweb.jonas_ejb.deployment.ejbql.ASTStringLiteral; 66 import org.objectweb.jonas_ejb.deployment.ejbql.ASTWhereClause; 67 import org.objectweb.jonas_ejb.deployment.ejbql.EJBQLConstants; 68 import org.objectweb.jonas_ejb.deployment.ejbql.ParseException; 69 import org.objectweb.jonas_ejb.deployment.ejbql.SimpleNode; 70 import org.objectweb.jorm.api.PMapper; 71 import org.objectweb.jorm.lib.JormPathHelper; 72 import org.objectweb.jorm.naming.api.PName; 73 import org.objectweb.jorm.type.api.PType; 74 import org.objectweb.medor.api.Field; 75 import org.objectweb.medor.expression.api.MalformedExpressionException; 76 import org.objectweb.medor.expression.api.Expression; 77 import org.objectweb.medor.filter.api.FieldOperand; 78 import org.objectweb.medor.expression.api.Operand; 79 import org.objectweb.medor.filter.jorm.lib.IsNullPName; 80 import org.objectweb.medor.expression.lib.Abs; 81 import org.objectweb.medor.expression.lib.And; 82 import org.objectweb.medor.filter.lib.BasicFieldOperand; 83 import org.objectweb.medor.expression.lib.BasicOperand; 84 import org.objectweb.medor.expression.lib.BasicParameterOperand; 85 import org.objectweb.medor.filter.lib.CollectionOperand; 86 import org.objectweb.medor.expression.lib.Concat; 87 import org.objectweb.medor.expression.lib.DivideBy; 88 import org.objectweb.medor.expression.lib.Equal; 89 import org.objectweb.medor.expression.lib.FirstLocate; 90 import org.objectweb.medor.expression.lib.Greater; 91 import org.objectweb.medor.expression.lib.GreaterEqual; 92 import org.objectweb.medor.filter.lib.InCollection; 93 import org.objectweb.medor.expression.lib.IndexedLocate; 94 import org.objectweb.medor.filter.lib.IsEmpty; 95 import org.objectweb.medor.filter.lib.IsNull; 96 import org.objectweb.medor.expression.lib.Length; 97 import org.objectweb.medor.expression.lib.Like; 98 import org.objectweb.medor.expression.lib.Lower; 99 import org.objectweb.medor.expression.lib.LowerEqual; 100 import org.objectweb.medor.filter.lib.MemberOf; 101 import org.objectweb.medor.expression.lib.Minus; 102 import org.objectweb.medor.expression.lib.Mod; 103 import org.objectweb.medor.expression.lib.Mult; 104 import org.objectweb.medor.expression.lib.Not; 105 import org.objectweb.medor.expression.lib.NotEqual; 106 import org.objectweb.medor.expression.lib.Or; 107 import org.objectweb.medor.expression.lib.Plus; 108 import org.objectweb.medor.expression.lib.Sqrt; 109 import org.objectweb.medor.expression.lib.Substring; 110 import org.objectweb.medor.expression.lib.UMinus; 111 import org.objectweb.medor.query.api.PropagatedField; 112 import org.objectweb.medor.query.jorm.lib.PNameField; 113 import org.objectweb.medor.query.jorm.lib.QueryBuilder; 114 import org.objectweb.medor.type.lib.PTypeSpaceMedor; 115 import org.objectweb.medor.type.lib.QType; 116 117 139 public class EjbqlQueryFilterVisitor extends EjbqlAbstractVisitor { 140 141 Expression qf = null; 142 PMapper mapper = null; 143 Map fields = null; 144 Class [] parameterTypes; 145 QueryBuilder qb; 146 147 static final String OP_IGNORE = "ignore"; 148 149 158 public EjbqlQueryFilterVisitor(PMapper _mapper, 159 Map _fields, 160 Class [] parameterTypes, 161 ASTEJBQL ejbql, 162 QueryBuilder qb) throws Exception { 163 mapper = _mapper; 164 fields = _fields; 165 this.parameterTypes = parameterTypes; 166 this.qb = qb; 167 visit(ejbql); 168 } 169 170 173 public Expression getQueryFilter() { 174 return qf; 175 } 176 177 181 public Object visit(ASTWhereClause node, Object data) { 182 visit((SimpleNode) node, data); 183 if (OP_IGNORE.equals(((Stack ) data).peek())) { 184 qf = null; 185 } else { 186 qf = (Expression) ((Stack ) data).pop(); 187 } 188 return null; 189 } 190 191 197 public Object visit(ASTSingleValuedPathExpression node, Object data) { 198 visit((SimpleNode) node, data); 199 try { 200 String path = (String ) ((ASTPath) ((Stack ) data).pop()).value; 201 Field f = (Field) fields.get(path); 202 ((Stack ) data).push(new BasicFieldOperand(f)); 205 } catch (Exception e) { 206 throw new VisitorException(e); 207 } 208 return null; 209 } 210 211 217 public Object visit(ASTCmpPathExpression node, Object data) { 218 visit((SimpleNode) node, data); 219 try { 220 String path = (String ) ((ASTPath) ((Stack ) data).pop()).value; 221 Field f = (Field) fields.get(path); 222 ((Stack ) data).push(new BasicFieldOperand(f)); 224 } catch (Exception e) { 225 throw new VisitorException(e); 226 } 227 return null; 228 } 229 230 236 public Object visit(ASTSingleValuedCmrPathExpression node, Object data) { 237 visit((SimpleNode) node, data); 238 try { 239 String path = (String ) ((ASTPath) ((Stack ) data).pop()).value; 240 Field f = (Field) fields.get(path); 241 ((Stack ) data).push(new BasicFieldOperand(f)); 243 } catch (Exception e) { 244 throw new VisitorException(e); 245 } 246 return null; 247 } 248 249 255 public Object visit(ASTCollectionValuedPathExpression node, Object data) { 256 visit((SimpleNode) node, data); 257 try { 258 String path = (String ) ((ASTPath) ((Stack ) data).pop()).value; 260 String [] parts = splitPath(path); 261 String first = parts[0]; 262 String rest = mergePath(parts, 1, parts.length - 1); 263 QueryBuilder subquery = new QueryBuilder(qb); 264 subquery.define("", qb.navigate(first)); 265 Field f = subquery.project(subquery.navigate(rest)); 266 ((Stack ) data).push(new BasicFieldOperand(f)); 267 } catch (Exception e) { 268 throw new VisitorException(e); 269 } 270 return null; 271 } 272 273 277 public Object visit(ASTConditionalExpression node, Object data) { 278 visit((SimpleNode) node, data); 279 Object ret = ((Stack ) data).pop(); 280 for (int i = 1; i < node.jjtGetNumChildren(); i++) { 281 if (OP_IGNORE.equals(ret)) { 282 ret = ((Stack ) data).pop(); 283 } else if (OP_IGNORE.equals(((Stack ) data).peek())) { 284 ((Stack ) data).pop(); 285 } else { 286 ret = new Or((Expression) ((Stack ) data).pop(), (Expression) ret); 287 } 288 } 289 ((Stack ) data).push(ret); 291 return null; 292 } 293 294 298 public Object visit(ASTConditionalTerm node, Object data) { 299 visit((SimpleNode) node, data); 300 Object ret = ((Stack ) data).pop(); 301 for (int i = 1; i < node.jjtGetNumChildren(); i++) { 302 if (OP_IGNORE.equals(ret)) { 303 ret = ((Stack ) data).pop(); 304 } else if (OP_IGNORE.equals(((Stack ) data).peek())) { 305 ((Stack ) data).pop(); 306 } else { 307 ret = new And((Expression) ((Stack ) data).pop(), (Expression) ret); 308 } 309 } 310 ((Stack ) data).push(ret); 312 return null; 313 } 314 315 319 public Object visit(ASTConditionalFactor node, Object data) { 320 visit((SimpleNode) node, data); 321 if (node.not) { 322 if (!OP_IGNORE.equals(((Stack ) data).peek())) { 323 Expression ret = (Expression) ((Stack ) data).pop(); 324 ((Stack ) data).push(new Not(ret)); 326 } 327 } 328 return null; 329 } 330 331 335 public Object visit(ASTBetweenExpression node, Object data) { 336 visit((SimpleNode) node, data); 337 Expression[] terms = new Expression[3]; 338 terms[2] = (Expression) ((Stack ) data).pop(); 339 terms[1] = (Expression) ((Stack ) data).pop(); 340 terms[0] = (Expression) ((Stack ) data).pop(); 341 if (node.not) { 342 ((Stack ) data).push(new Or(new Lower(terms[0], terms[1]), new Greater(terms[0], terms[2]))); 343 } else { 344 ((Stack ) data).push(new And(new GreaterEqual(terms[0], terms[1]), new LowerEqual(terms[0], terms[2]))); 345 } 346 return null; 347 } 348 349 354 public Object visit(ASTInExpression node, Object data) { 355 visit((SimpleNode) node, data); 356 Stack s = (Stack ) data; 357 ArrayList c = new ArrayList (); 358 for (int i = 1; i <= node.eltnum; i++) { 359 c.add(s.pop()); 360 } 361 CollectionOperand co = new CollectionOperand(c); 362 FieldOperand f = (FieldOperand) s.pop(); 363 if (node.not) { 364 s.push(new Not(new InCollection(f, co, f.getField().getType()))); 365 } else { 366 s.push(new InCollection(f, co, f.getField().getType())); 367 } 368 return null; 369 } 370 371 376 public Object visit(ASTLikeExpression node, Object data) { 377 visit((SimpleNode) node, data); 378 Stack s = (Stack ) data; 379 Expression e1 = (Expression) s.pop(); 380 Expression e2 = (Expression) s.pop(); 381 Expression e3 = null; 382 if (node.third) { 383 e3 = (Expression) s.pop(); 385 } 386 if (e3 == null) { 387 s.push(new Like(e2, e1, node.not)); 388 } else { 389 s.push(new Like(e3, e2, e1, node.not)); 390 } 391 return null; 392 } 393 394 398 public Object visit(ASTNullComparisonExpression node, Object data) { 399 visit((SimpleNode) node, data); 400 Stack s = (Stack ) data; 401 Expression e1 = (Expression) s.pop(); 402 if ((e1 instanceof BasicParameterOperand) 403 && (e1.getType().getTypeCode() == QType.TYPECODE_PNAME)) { 404 if (node.not) { 406 s.push(new Not(new IsNullPName(((BasicParameterOperand)e1).getName()))); 407 } else { 408 s.push(new IsNullPName(((BasicParameterOperand)e1).getName())); 409 } 410 } else if (e1.getType().getTypeCode() == PType.TYPECODE_REFERENCE) { 411 Field f = ((FieldOperand) e1).getField(); 415 PNameField pnf = null; 416 if (f instanceof PNameField) { 417 pnf = (PNameField) f; 418 } else if (f instanceof PropagatedField) { 419 pnf = (PNameField)((PropagatedField) f).getOriginFields()[0]; 420 } else { 421 throw new Error ("Operand of IS NULL not valid !?"); 423 } 424 Operand op2; 425 if (mapper == null) { 426 op2 = new BasicOperand("pnamenull"); 428 } else { 429 PName pnamenull = JormPathHelper.getPNameCoder(pnf.getPNamingContextParameter(), 431 mapper).getNull(); 432 op2 = new BasicOperand(pnamenull, PTypeSpaceMedor.PNAME); 433 } 434 if (node.not) { 435 s.push(new Not(new Equal(e1, op2))); 436 } else { 437 s.push(new Equal(e1, op2)); 438 } 439 } else { 440 if (node.not) { 442 s.push(new Not(new IsNull(e1))); 443 } else { 444 s.push(new IsNull(e1)); 445 } 446 } 447 return null; 448 449 } 450 451 457 public Object visit(ASTEmptyCollectionComparisonExpression node, Object data) { 458 visit((SimpleNode) node, data); 459 Stack s = (Stack ) data; 460 Expression e = (Expression) s.pop(); 461 Expression res = new IsEmpty(e); 462 if (node.not) { 463 res = new Not(res); 464 } 465 s.push(res); 466 return null; 467 } 468 469 474 public Object visit(ASTCollectionMemberExpression node, Object data) { 475 visit((SimpleNode) node, data); 476 Stack s = (Stack ) data; 477 Expression e2 = (Expression) s.pop(); 478 Expression e1 = (Expression) s.pop(); 479 ArrayList le2 = new ArrayList (); le2.add(e2); 480 ArrayList le1 = new ArrayList (); le1.add(e1); 481 Expression res = null; 482 try { 483 res = new MemberOf(le1, le2); 484 } catch (MalformedExpressionException e) { 485 throw new Error ("Operand expression of MEMBER OF malformed: " 486 + e + e.getNestedException()); 487 } 488 if (node.not) { 489 s.push(new Not(res)); 490 } else { 491 s.push(res); 492 } 493 return null; 494 } 495 496 497 505 public Object visit(ASTComparisonExpression node, Object data) { 506 visit((SimpleNode) node, data); 507 Expression[] terms = new Expression[2]; 508 terms[1] = (Expression) ((Stack ) data).pop(); 509 terms[0] = (Expression) ((Stack ) data).pop(); 510 int op = ((Integer ) node.ops.get(0)).intValue(); 511 switch (op) { 512 case EJBQLConstants.EQ: 513 ((Stack ) data).push(new Equal(terms[0], terms[1])); 514 break; 515 case EJBQLConstants.NE: 516 ((Stack ) data).push(new NotEqual(terms[0], terms[1])); 517 break; 518 case EJBQLConstants.GT: 519 ((Stack ) data).push(new Greater(terms[0], terms[1])); 520 break; 521 case EJBQLConstants.GE: 522 ((Stack ) data).push(new GreaterEqual(terms[0], terms[1])); 523 break; 524 case EJBQLConstants.LT: 525 ((Stack ) data).push(new Lower(terms[0], terms[1])); 526 break; 527 case EJBQLConstants.LE: 528 ((Stack ) data).push(new LowerEqual(terms[0], terms[1])); 529 break; 530 } 531 return null; 532 } 533 534 538 public Object visit(ASTArithmeticExpression node, Object data) { 539 visit((SimpleNode) node, data); 540 Expression ret = (Expression) ((Stack ) data).pop(); 541 for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) { 542 switch (((Integer ) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue()) { 543 case EJBQLConstants.PLUS: 544 ret = new Plus((Expression) ((Stack ) data).pop(), ret); 545 break; 546 case EJBQLConstants.MINUS: 547 ret = new Minus((Expression) ((Stack ) data).pop(), ret); 548 break; 549 } 550 } 551 ((Stack ) data).push(ret); 553 return null; 554 } 555 556 560 public Object visit(ASTArithmeticTerm node, Object data) { 561 visit((SimpleNode) node, data); 562 Expression ret = (Expression) ((Stack ) data).pop(); 563 for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) { 564 switch (((Integer ) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue()) { 565 case EJBQLConstants.MULT: 566 ret = new Mult((Expression) ((Stack ) data).pop(), ret); 567 break; 568 case EJBQLConstants.DIV: 569 ret = new DivideBy((Expression) ((Stack ) data).pop(), ret); 570 break; 571 } 572 } 573 ((Stack ) data).push(ret); 575 return null; 576 } 577 578 582 public Object visit(ASTArithmeticFactor node, Object data) { 583 visit((SimpleNode) node, data); 584 Expression ret = (Expression) ((Stack ) data).pop(); 585 if (node.ops.size() > 0) { 586 if (((Integer ) node.ops.get(0)).intValue() == EJBQLConstants.MINUS) { 587 ret = new UMinus((Expression) ret); 588 } 589 } 590 ((Stack ) data).push(ret); 592 return null; 593 } 594 595 596 600 public Object visit(ASTStringExpression node, Object data) { 601 visit((SimpleNode) node, data); 602 return null; 604 } 605 606 610 public Object visit(ASTDatetimeExpression node, Object data) { 611 visit((SimpleNode) node, data); 612 return null; 614 } 615 616 620 public Object visit(ASTBooleanExpression node, Object data) { 621 visit((SimpleNode) node, data); 622 return null; 624 } 625 626 630 public Object visit(ASTEntityBeanExpression node, Object data) { 631 visit((SimpleNode) node, data); 632 return null; 634 } 635 636 642 public Object visit(ASTFunctionsReturningStrings node, Object data) { 643 visit((SimpleNode) node, data); 644 Stack s = (Stack ) data; 645 int op = ((Integer ) node.ops.get(0)).intValue(); 646 Expression ret = null; 647 Expression e1, e2; 648 switch (op) { 649 case EJBQLConstants.CONCAT: 650 e2 = (Expression) s.pop(); 652 e1 = (Expression) s.pop(); 653 ret = new Concat(e1, e2); 654 break; 655 case EJBQLConstants.SUBSTRING: 656 Expression e3 = (Expression) s.pop(); 658 e2 = (Expression) s.pop(); 659 e1 = (Expression) s.pop(); 660 ret = new Substring(e1, e2, e3); 661 break; 662 } 663 s.push(ret); 665 return null; 666 } 667 668 669 679 public Object visit(ASTFunctionsReturningNumerics node, Object data) { 680 visit((SimpleNode) node, data); 681 Stack s = (Stack ) data; 682 int op = ((Integer ) node.ops.get(0)).intValue(); 683 Expression e1, e2; 684 Expression ret = null; 685 switch (op) { 686 case EJBQLConstants.LENGTH: 687 e1 = (Expression) s.pop(); 688 ret = new Length(e1); 689 break; 690 case EJBQLConstants.LOCATE: 691 Expression e3 = null; 693 if (node.third) { 694 e3 = (Expression) s.pop(); 696 } 697 e2 = (Expression) s.pop(); 698 e1 = (Expression) s.pop(); 699 if (node.third) { 701 ret = new IndexedLocate(e2, e1, e3); 702 } else { 703 ret = new FirstLocate(e1, e2); 704 } 705 break; 706 case EJBQLConstants.ABS: 707 e1 = (Expression) s.pop(); 708 ret = new Abs(e1); 709 break; 710 case EJBQLConstants.SQRT: 711 e1 = (Expression) s.pop(); 712 ret = new Sqrt(e1); 713 break; 714 case EJBQLConstants.MOD: 715 e2 = (Expression) s.pop(); 716 e1 = (Expression) s.pop(); 717 ret = new Mod(e1, e2); 718 break; 719 } 720 s.push(ret); 722 return null; 723 } 724 725 729 public Object visit(ASTIdentificationVariable node, Object data) { 730 String fieldname = (String ) node.value + "." + Field.PNAMENAME; 731 Field f = (Field) fields.get(fieldname); 732 ((Stack ) data).push(new BasicFieldOperand(f)); 733 return null; 734 } 735 736 740 public Object visit(ASTLiteral node, Object data) { 741 visit((SimpleNode) node, data); 742 return null; 743 } 744 745 749 public Object visit(ASTStringLiteral node, Object data) { 750 ((Stack ) data).push(new BasicOperand((String ) node.value)); 751 return null; 752 } 753 754 758 public Object visit(ASTArithmeticLiteral node, Object data) { 759 visit((SimpleNode) node, data); 760 return null; 761 } 762 763 767 public Object visit(ASTIntegerLiteral node, Object data) { 768 ((Stack ) data).push(new BasicOperand(((Long ) node.value).longValue())); 769 return null; 770 } 771 772 776 public Object visit(ASTFloatingPointLiteral node, Object data) { 777 ((Stack ) data).push(new BasicOperand(((Double ) node.value).doubleValue())); 778 return null; 779 } 780 781 785 public Object visit(ASTBooleanLiteral node, Object data) { 786 ((Stack ) data).push(new BasicOperand(((Boolean ) node.value).booleanValue())); 787 return null; 788 } 789 790 794 public Object visit(ASTInputParameter node, Object data) { 795 try { 796 int pIndex = ((Integer ) node.value).intValue() - 1; 797 if (pIndex >= parameterTypes.length) { 798 throw new ParseException("Parameter ?" + (pIndex + 1) 799 + " is out of range (max = " 800 + parameterTypes.length + ")"); 801 } 802 if (EJBObject .class.isAssignableFrom(parameterTypes[pIndex])) { 803 throw new Error ("EJBObject params not implemented"); 806 } 807 Operand op = new BasicParameterOperand(JormType.getPType(parameterTypes[pIndex], false), 808 "?" + node.value); 809 ((Stack ) data).push(op); 810 return null; 811 } catch (ParseException e) { 812 throw new VisitorException(e); 813 } 814 } 815 816 819 public Object visit(ASTPath node, Object data) { 820 ((Stack ) data).push(node); 821 return null; 822 } 823 } 824 | Popular Tags |