1 23 24 package org.xquark.xquery.normalize; 25 26 import java.util.*; 28 29 import org.xml.sax.SAXException ; 30 import org.xquark.schema.Schema; 31 import org.xquark.xpath.Axis; 32 import org.xquark.xpath.NodeKind; 33 import org.xquark.xquery.parser.*; 34 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*; 35 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.FunctionSTRING; 36 import org.xquark.xquery.parser.util.Constants; 37 import org.xquark.xquery.typing.QType; 38 import org.xquark.xquery.typing.TypeException; 39 import org.xquark.xquery.typing.TypeVisitor; 40 41 48 49 52 53 public class ExpressionNormalizationVisitor extends org.xquark.xquery.parser.DefaultParserVisitor { 54 55 56 private static final String RCSRevision = "$Revision: 1.12 $"; 57 58 59 private static final String RCSName = "$Name: $"; 60 61 66 67 68 69 private final boolean reType = true; 70 71 72 protected TypeVisitor typeVisitor = null; 73 74 75 protected XQueryExpression expr = null; 76 77 78 protected VisitorContext context = null; 79 80 81 protected int depth = -1; 82 83 84 protected boolean normalized; 85 86 87 protected HashMap variablesDeclarations = null; 88 89 private AtomizeVisitor atomizeVisitor = new AtomizeVisitor(typeVisitor); 90 91 private String sourceName = null; 92 93 94 95 96 protected final String DEFAULT_XML_PREFIX = "xml"; 97 98 99 protected final String DEFAULT_XML_URL = "http://www.w3.org/XML/1998/namespace"; 100 101 102 protected final String DEFAULT_SCHEMA_PREFIX = "xs"; 103 104 105 protected final String DEFAULT_SCHEMA_URL = "http://www.w3.org/2001/XMLSchema"; 106 107 108 protected final String DEFAULT_SCHEMA_INSTANCE_PREFIX = "xsi"; 109 110 111 protected final String DEFAULT_SCHEMA_INSTANCE_URL = "http://www.w3.org/2001/XMLSchema-instance"; 112 113 114 protected final String DEFAULT_FUNCTION_PREFIX = "xf"; 115 116 117 protected final String DEFAULT_FUNCTION_URL = "http://www.w3.org/2002/08/xquery-functions"; 118 119 120 protected final String DEFAULT_OPERATOR_PREFIX = "op"; 121 122 123 protected final String DEFAULT_OPERATOR_URL = "http://www.w3.org/2002/08/xquery-operators"; 124 125 126 127 132 142 public ExpressionNormalizationVisitor(TypeVisitor typeVisitor, String sourceName) throws NormalizeException { 143 this(new VisitorContext(), -1, typeVisitor, sourceName); 144 } 145 146 153 165 protected ExpressionNormalizationVisitor(int depth, TypeVisitor typeVisitor, String sourceName) throws NormalizeException { 166 this(new VisitorContext(), depth, typeVisitor, sourceName); 167 } 168 169 180 protected ExpressionNormalizationVisitor(VisitorContext ctx, int depth, TypeVisitor typeVisitor, String sourceName) throws NormalizeException { 181 this.context = ctx; 182 this.expr = null; 183 this.depth = depth + 1; 184 this.normalized = false; 185 this.typeVisitor = typeVisitor; 186 this.sourceName = sourceName; 187 } 188 189 190 191 private FLWRExpression createDummyFLWR(XQueryExpression whereClause, XQueryExpression returnClause) throws XQueryException, TypeException { 192 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", returnClause.getParentModule()), Variable.NORM_CREATOR); 193 ArrayList vars = new ArrayList(1); 194 vars.add(var); 195 XQueryModule unit = returnClause.getParentModule(); 196 FLWRExpression flwr = new FLWRExpression(vars, null, whereClause, returnClause, returnClause.getParentModule()); 197 flwr.setParentModule(unit); 198 return flwr; 199 } 200 201 206 protected VisitorContext getContext() { 207 return this.context; 208 } 209 210 216 protected void setContext(VisitorContext ctx) { 217 this.context = ctx; 218 } 219 220 225 protected int getDepth() { 226 return this.depth; 227 } 228 229 230 231 236 public void reInit() throws NormalizeException { 237 this.context = new VisitorContext(); 238 this.expr = null; 239 this.depth = 0; 240 this.normalized = false; 241 } 242 243 248 public XQueryExpression getExpr() { 249 return this.expr; 250 } 251 252 257 public boolean wasNormalized() { 258 return this.normalized; 259 } 260 261 262 263 264 265 272 public void visit(XQueryModule arg) throws NormalizeException { 273 typeVisitor.setNoForce(false); 275 try { 277 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 278 int pass = 0; 279 boolean removed = false; 281 do { 283 normalized = false; 284 pass++; 285 289 293 ArrayList expressions = arg.getExpressions(); 295 if (expressions != null) { 296 int exprLen = expressions.size(); 297 for (int i = exprLen - 1; i >= 0; i--) { 298 recurseVisitor.reInit(); 299 XQueryExpression expri = (XQueryExpression) expressions.get(i); 300 expri.accept(recurseVisitor); 301 XQueryExpression newExpr = recurseVisitor.getExpr(); 302 if (newExpr == null) { 303 expressions.remove(i); 304 removed = true; 305 } else { 306 newExpr.setParentModule(arg); 308 expressions.set(i, newExpr); 309 } 310 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 312 } 313 } 314 if (pass > 32) 315 throw new NormalizeException(0, "Infinite loop on normalization of " + arg + "<==\n"); 316 } while (this.normalized && !removed); 317 318 } catch (XQueryException e) { 319 throw new NormalizeException(0, e.getMessage()); 320 } 321 typeVisitor.setNoForce(true); 323 } 325 326 332 public void visit(XQueryExpression arg) throws NormalizeException { 333 this.expr = arg; 334 } 335 336 337 338 351 352 364 public void visit(UnOpMinusExpression arg) throws NormalizeException { 365 try { 366 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 367 VisitorContext localCtx = new VisitorContext(); 368 localCtx.merge(this.context, false); 369 localCtx.filter(this.depth); 371 recurseVisitor.setContext(localCtx); 372 XQueryExpression anExpr = arg.getExpression(); 374 anExpr.accept(recurseVisitor); 375 localCtx.update(recurseVisitor.getContext()); 376 anExpr = recurseVisitor.getExpr(); 377 this.normalized = recurseVisitor.wasNormalized(); 379 if (this.normalized) { 381 if (anExpr != null) { 382 arg.setExpression(anExpr); 384 if (reType) { 386 arg.accept(typeVisitor); 387 } 388 } else { 389 arg = null; 390 } 391 } 392 this.expr = arg; 393 this.context.update(localCtx); 395 } catch (XQueryException e) { 396 throw new NormalizeException(0, e); 397 } 398 } 399 400 414 public void visit(BinOpANDExpression arg) throws NormalizeException { 415 try { 416 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 417 VisitorContext localCtx = new VisitorContext(); 418 localCtx.merge(this.context, false); 419 localCtx.filter(this.depth); 421 recurseVisitor.setContext(localCtx); 422 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 424 XQueryExpression expr1 = arg.getExpression1(); 426 expr1.accept(recurseVisitor); 427 localCtx.update(recurseVisitor.getContext()); 428 expr1 = recurseVisitor.getExpr(); 429 this.normalized = recurseVisitor.wasNormalized(); 431 if (this.normalized) { 433 if (expr1 != null) { 434 arg.setExpression1(expr1); 436 } else { 437 arg = null; 438 } 439 } 440 XQueryExpression expr2 = null; 442 if (arg != null) { 443 expr2 = arg.getExpression2(); 444 expr2.accept(recurseVisitor); 445 localCtx.update(recurseVisitor.getContext()); 446 expr2 = recurseVisitor.getExpr(); 447 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 449 if (recurseVisitor.wasNormalized()) { 451 if (expr2 != null) { 452 arg.setExpression2(expr2); 454 } else { 455 arg = null; 456 } 457 } 458 } 459 localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 461 if (arg == null) { 463 this.expr = new FunctionFALSE(null, arg.getParentModule()); 465 this.normalized = true; 466 } else if ((expr1 instanceof FunctionFALSE) || (expr2 instanceof FunctionFALSE)) { 467 this.expr = new FunctionFALSE(null, arg.getParentModule()); 469 this.normalized = true; 470 } else if ((expr1 instanceof FunctionTRUE) && (expr2 instanceof FunctionTRUE)) { 471 this.expr = new FunctionTRUE(null, arg.getParentModule()); 473 this.normalized = true; 474 } else if (expr1 instanceof FunctionTRUE) { 475 this.expr = expr2; 476 this.normalized = true; 477 } else if (expr2 instanceof FunctionTRUE) { 478 this.expr = expr1; 479 this.normalized = true; 480 } else { 481 this.expr = arg; 482 } 483 if (reType && this.normalized && (this.expr != null)) { 485 this.expr.accept(typeVisitor); 486 } 487 this.context.update(localCtx); 489 } catch (XQueryException e) { 490 throw new NormalizeException(0, e); 491 } 492 } 493 494 508 public void visit(BinOpORExpression arg) throws NormalizeException { 509 try { 510 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 511 VisitorContext localCtx = new VisitorContext(); 512 localCtx.merge(this.context, false); 513 localCtx.filter(this.depth); 515 recurseVisitor.setContext(localCtx); 516 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 518 XQueryExpression expr1 = arg.getExpression1(); 520 expr1.accept(recurseVisitor); 521 localCtx.update(recurseVisitor.getContext()); 522 expr1 = recurseVisitor.getExpr(); 523 this.normalized = recurseVisitor.wasNormalized(); 525 if ((this.normalized) && (expr1 != null)) { 526 arg.setExpression1(expr1); 527 } 528 XQueryExpression expr2 = arg.getExpression2(); 530 expr2.accept(recurseVisitor); 531 localCtx.update(recurseVisitor.getContext()); 532 expr2 = recurseVisitor.getExpr(); 533 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 535 if ((recurseVisitor.wasNormalized()) && (expr2 != null)) { 536 arg.setExpression2(expr2); 537 } 538 localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 540 if (expr1 == null) { 542 this.normalized = true; 543 if (expr2 == null) { 544 this.expr = new FunctionFALSE(null, arg.getParentModule()); 545 } else if (expr2 instanceof FunctionFALSE) { 546 this.expr = new FunctionFALSE(null, arg.getParentModule()); 547 } else if (expr2 instanceof FunctionTRUE) { 548 this.expr = new FunctionTRUE(null, arg.getParentModule()); 549 } else { 550 this.expr = expr2; 551 } 552 } else if (expr1 instanceof FunctionFALSE) { 553 this.normalized = true; 554 if (expr2 == null) { 555 this.expr = new FunctionFALSE(null, arg.getParentModule()); 556 } else if (expr2 instanceof FunctionFALSE) { 557 this.expr = new FunctionFALSE(null, arg.getParentModule()); 558 } else if (expr2 instanceof FunctionTRUE) { 559 this.expr = new FunctionTRUE(null, arg.getParentModule()); 560 } else { 561 this.expr = expr2; 562 } 563 } else if (expr1 instanceof FunctionTRUE) { 564 this.normalized = true; 565 this.expr = new FunctionTRUE(null, arg.getParentModule()); 566 } else { 567 if (expr2 == null) { 568 this.expr = expr1; 569 this.normalized = true; 570 } else if (expr2 instanceof FunctionFALSE) { 571 this.expr = expr1; 572 this.normalized = true; 573 } else if (expr2 instanceof FunctionTRUE) { 574 this.expr = new FunctionTRUE(null, arg.getParentModule()); 575 this.normalized = true; 576 } else { 577 this.expr = arg; 578 } 579 } 580 if (reType && this.normalized && this.expr != null) { 582 this.expr.accept(typeVisitor); 583 } 584 this.context.update(localCtx); 586 } catch (XQueryException e) { 587 throw new NormalizeException(0, e); 588 } 589 } 590 591 605 public void visit(ListOpArithExpression arg) throws NormalizeException { 606 try { 607 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 608 VisitorContext localCtx = new VisitorContext(); 609 localCtx.merge(this.context, false); 610 localCtx.filter(this.depth); 612 recurseVisitor.setContext(localCtx); 613 XQueryExpression expr1 = arg.getExpression1(); 615 expr1.accept(recurseVisitor); 616 localCtx.update(recurseVisitor.getContext()); 617 expr1 = recurseVisitor.getExpr(); 618 expr1.accept(atomizeVisitor); 619 expr1 = atomizeVisitor.getExpression(); 620 this.normalized = recurseVisitor.wasNormalized(); 622 if (this.normalized) { 623 if (expr1 != null) { 624 arg.setExpression1(expr1); 625 } else { 626 arg = null; 627 } 628 } 629 XQueryExpression expr2 = null; 631 if (arg != null) { 632 expr2 = arg.getExpression2(); 633 expr2.accept(recurseVisitor); 634 localCtx.update(recurseVisitor.getContext()); 635 expr2 = recurseVisitor.getExpr(); 636 expr2.accept(atomizeVisitor); 637 expr2 = atomizeVisitor.getExpression(); 638 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 640 if (recurseVisitor.wasNormalized()) { 641 if (expr2 != null) { 642 arg.setExpression2(expr2); 643 } else { 644 arg = null; 645 } 646 } 647 } 648 this.expr = arg; 649 if (reType && this.normalized && this.expr != null) { 651 this.expr.accept(typeVisitor); 652 } 653 this.context.update(localCtx); 655 } catch (XQueryException e) { 656 throw new NormalizeException(0, e); 657 } 658 } 659 660 674 675 public void visit(ListOpCompExpression arg) throws NormalizeException { 676 try { 677 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 678 VisitorContext localCtx = new VisitorContext(); 679 localCtx.merge(this.context, false); 680 localCtx.filter(this.depth); 682 recurseVisitor.setContext(localCtx); 683 XQueryExpression expr1 = arg.getExpression1(); 685 expr1.accept(recurseVisitor); 686 localCtx.update(recurseVisitor.getContext()); 687 expr1 = recurseVisitor.getExpr(); 688 expr1.accept(atomizeVisitor); 689 expr1 = atomizeVisitor.getExpression(); 690 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 692 if (this.normalized) { 693 if (expr1 != null) { 694 arg.setExpression1(expr1); 695 } else { 696 arg = null; 697 } 698 } 699 XQueryExpression expr2 = null; 701 if (arg != null) { 702 expr2 = arg.getExpression2(); 703 expr2.accept(recurseVisitor); 704 localCtx.update(recurseVisitor.getContext()); 705 expr2 = recurseVisitor.getExpr(); 706 expr2.accept(atomizeVisitor); 707 expr2 = atomizeVisitor.getExpression(); 708 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 710 if (recurseVisitor.wasNormalized()) { 711 if (expr2 != null) { 712 arg.setExpression2(expr2); 713 } else { 714 arg = null; 715 } 716 } 717 } 718 this.expr = arg; 719 if (reType && this.normalized && this.expr != null) { 721 this.expr.accept(typeVisitor); 722 } 723 this.context.update(localCtx); 725 } catch (XQueryException e) { 747 throw new NormalizeException(0, e); 748 } 749 } 750 751 765 public void visit(ListOpUNIONExpression arg) throws NormalizeException { 767 try { 768 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 769 VisitorContext localCtx = new VisitorContext(); 770 localCtx.merge(this.context, false); 771 localCtx.filter(this.depth); 773 recurseVisitor.setContext(localCtx); 774 XQueryExpression expr1 = arg.getExpression1(); 776 expr1.accept(recurseVisitor); 777 localCtx.update(recurseVisitor.getContext()); 778 expr1 = recurseVisitor.getExpr(); 779 this.normalized = recurseVisitor.wasNormalized(); 781 if ((this.normalized) && (expr1 != null)) { 782 arg.setExpression1(expr1); 783 } 784 XQueryExpression expr2 = arg.getExpression2(); 786 expr2.accept(recurseVisitor); 787 localCtx.update(recurseVisitor.getContext()); 788 expr2 = recurseVisitor.getExpr(); 789 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 791 if (recurseVisitor.wasNormalized() && (expr2 != null)) { 792 arg.setExpression2(expr2); 793 } 794 if (expr1 == null) { 795 this.expr = expr2; 796 } else if (expr2 == null) { 797 this.expr = expr1; 798 } else { 799 this.expr = arg; 800 } 801 if (reType && this.normalized && this.expr != null) { 803 this.expr.accept(typeVisitor); 804 } 805 808 this.context.update(localCtx); 810 } catch (XQueryException e) { 811 throw new NormalizeException(0, e); 812 } 813 } 814 815 830 public void visit(QuantifiedExpression arg) throws NormalizeException { 831 try { 832 if (arg.getKind() == Constants.EVERY_QUANTIFIER) { 834 arg.setKind(Constants.SOME_QUANTIFIER); 835 ArrayList args = new ArrayList(1); 836 args.add(arg.getConstraintExpresson()); 837 arg.setConstraintExpresson(new FunctionNOT(args, arg.getParentModule())); 838 args = new ArrayList(1); 839 args.add(arg); 840 this.expr = new FunctionNOT(args, arg.getParentModule()); 841 this.normalized = true; 842 return; 843 } 844 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 846 VisitorContext localCtx = new VisitorContext(); 847 localCtx.merge(this.context, false); 848 localCtx.filter(this.depth); 850 localCtx.setMemo(this.depth + 1, VisitorContext._VARIABLE_DECLARATION, null, true); 852 this.normalized = false; 853 localCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 855 localCtx.setMemo(this.depth + 2, VisitorContext._QUANTIFIED_INNERFLWR, null, true); 856 localCtx.setMemo(this.depth + 3, VisitorContext._QUANTIFIED_INNERFLWR, null, true); 857 int kind = arg.getKind(); 865 ArrayList variables = arg.getVariables(); 867 ArrayList newQEVariables = new ArrayList(); 868 ArrayList innerWhereClauses = new ArrayList(); 869 Variable currentVariable, newVariable; 870 HashMap toSubstitute = new HashMap(); 871 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED)) { 873 HashMap substToAdd = (HashMap) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED); 874 toSubstitute.putAll(substToAdd); 875 } 876 for (int i = 0; i < variables.size(); i++) { 878 currentVariable = (Variable) variables.get(i); 879 recurseVisitor.setContext(localCtx); 881 currentVariable.accept(recurseVisitor); 882 localCtx.update(recurseVisitor.getContext()); 883 newVariable = (Variable) recurseVisitor.getExpr(); 884 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 886 if (newVariable == null) { 887 toSubstitute.put(currentVariable.getVarName(), null); 888 } else { 889 if (localCtx.getMemo(this.depth + 2, VisitorContext._QUANTIFIED_INNERFLWR) != null || (localCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS) != null && localCtx.getMemo(this.depth + 3, VisitorContext._QUANTIFIED_INNERFLWR) != null)) { 897 boolean existSequence = (localCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS) != null); 898 FLWRExpression innerFLWR = (FLWRExpression) (existSequence ? localCtx.getMemo(this.depth + 3, VisitorContext._QUANTIFIED_INNERFLWR) : localCtx.getMemo(this.depth + 2, VisitorContext._QUANTIFIED_INNERFLWR)); 900 ArrayList innerVars = innerFLWR.getVariables(); 903 for (int j = 0; j < innerVars.size(); j++) 905 ((Variable) innerVars.get(j)).setBindingType(Constants.QUANTIFIER_BINDINGTYPE); 906 newQEVariables.addAll(innerVars); 907 XQueryExpression innerReturn = innerFLWR.getReturnClause(); 908 toSubstitute.put(currentVariable.getVarName(), innerReturn); 911 localCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED, toSubstitute, true); 912 XQueryExpression innerWhere = innerFLWR.getWhereClause(); 913 if (innerWhere != null) 916 innerWhereClauses.add(innerWhere); 917 localCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 919 if (existSequence) { 920 localCtx.setMemo(this.depth + 3, VisitorContext._QUANTIFIED_INNERFLWR, null, true); 921 } else { 922 localCtx.setMemo(this.depth + 2, VisitorContext._QUANTIFIED_INNERFLWR, null, true); 923 } 924 } else { 925 newQEVariables.add(newVariable); 926 } 927 } 928 } 929 localCtx.removeMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS); 931 localCtx.removeMemo(this.depth + 2, VisitorContext._QUANTIFIED_INNERFLWR); 932 localCtx.removeMemo(this.depth + 3, VisitorContext._QUANTIFIED_INNERFLWR); 933 localCtx.removeMemo(this.depth + 1, VisitorContext._VARIABLE_DECLARATION); 935 if (newQEVariables.size() == 0) { 937 if (kind == Constants.EVERY_QUANTIFIER) { 939 this.expr = new FunctionTRUE(null, arg.getParentModule()); 940 } else { this.expr = new FunctionFALSE(null, arg.getParentModule()); 942 } 943 } else { 944 arg.setVariables(newQEVariables); 946 recurseVisitor.setContext(localCtx); 949 XQueryExpression constraint = arg.getConstraintExpresson(); 951 if (innerWhereClauses.size() > 0) { 953 constraint.setParenthesis(true); 954 this.normalized = true; 955 do { 956 constraint = new BinOpANDExpression((XQueryExpression) innerWhereClauses.get(0), constraint, arg.getParentModule()); 957 constraint.setParenthesis(true); 958 innerWhereClauses.remove(0); 959 } while (innerWhereClauses.size() > 0); 960 } 961 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 963 constraint.accept(recurseVisitor); 965 localCtx.update(recurseVisitor.getContext()); 966 constraint = recurseVisitor.getExpr(); 967 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 969 localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 971 if (this.normalized) { 972 if (constraint == null) { 973 this.expr = new FunctionFALSE(null, arg.getParentModule()); 974 } else if ((constraint instanceof FunctionFALSE) || (constraint instanceof FunctionTRUE)) { 975 this.expr = constraint; 976 this.normalized = true; 977 } else { 978 arg.setExpression(constraint); 979 this.expr = arg; 980 } 981 } else { 982 this.expr = arg; 983 } 984 localCtx.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED); 986 } 987 if (reType && this.normalized && this.expr != null) { 989 this.expr.accept(typeVisitor); 990 } 991 this.context.update(localCtx); 993 } catch (XQueryException e) { 994 throw new NormalizeException(0, e); 995 } 996 } 997 998 999 1000 1001 1002 1015 public void visit(LibraryFunctionCall arg) throws NormalizeException { 1016 try { 1017 FunctionDeclaration funDecl = arg.getFunctionDefinition(); 1018 ArrayList params = arg.getArguments(); 1019 if (funDecl.getParameters() != null && funDecl.getParameters().size() != params.size()) 1022 throw new NormalizeException(0, "Invalid number of argument for function call " + arg.getFuncName().toString()); 1023 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 1025 VisitorContext localCtx = new VisitorContext(); 1026 localCtx.merge(this.context, false); 1027 localCtx.filter(this.depth); 1029 localCtx.setMemo(this.depth + 1, VisitorContext._INCLUDEINPARENTHESIS, null, true); 1031 recurseVisitor.setContext(localCtx); 1032 if ((params != null) && (params.size() > 0)) { 1034 int paramLen = params.size(); 1035 for (int i = paramLen - 1; i >= 0; i--) { 1036 XQueryExpression parami = (XQueryExpression) params.get(i); 1037 boolean isAtom = parami.getQType() != null && parami.getQType().isAtom(); 1038 parami.accept(recurseVisitor); 1039 localCtx.update(recurseVisitor.getContext()); 1040 parami = recurseVisitor.getExpr(); 1041 if (parami != null && isAtom) { 1042 parami.accept(atomizeVisitor); 1043 parami = atomizeVisitor.getExpression(); 1044 } 1045 if (parami != null) { 1046 params.set(i, parami); 1047 } else { 1048 XQueryVoid emptyExpr = new XQueryVoid(arg.getParentModule()); 1049 emptyExpr.setParenthesis(true); 1051 params.set(i, emptyExpr); 1052 } 1053 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1055 } 1056 if (this.normalized) { 1057 if (params.size() == 0) { 1058 arg = null; 1059 } else { 1060 arg.setArguments(params); 1061 if (reType) { 1063 arg.accept(typeVisitor); 1064 } 1065 } 1066 } 1067 } 1068 HashMap schemaMap = funDecl.getHomeModule().getImportSchemas(); 1070 if (schemaMap != null) { 1071 if (arg.getParentModule().getImportSchemas() == null) 1072 arg.getParentModule().setImportSchemas(new HashMap()); 1073 arg.getParentModule().getImportSchemas().putAll(schemaMap); 1074 for (Iterator it = schemaMap.keySet().iterator(); it.hasNext();) { 1075 String ns = (String ) it.next(); 1076 Schema schema = funDecl.getHomeModule().getStaticContext().getSchemaManager().getSchema(ns); 1077 try { 1078 arg.getParentModule().getStaticContext().getTypeVisitor().getSchemaManager().putSchema(schema); 1079 } catch (SAXException e) { 1080 throw new NormalizeException(e.getMessage()); 1081 } 1082 } 1083 } 1084 ArrayList schemaList = funDecl.getHomeModule().getSchemaList(); 1085 if (schemaList != null) { 1086 if (arg.getParentModule().getSchemaList() == null) 1087 arg.getParentModule().setSchemaList(new ArrayList()); 1088 arg.getParentModule().getSchemaList().addAll(schemaList); 1089 } 1090 ArrayList exprs = null; 1092 if (funDecl.getExpressions() != null && !funDecl.getExpressions().isEmpty()) { 1093 exprs = new ArrayList(funDecl.getExpressions().size()); 1094 for (int i = 0; i < funDecl.getExpressions().size(); i++) { 1095 exprs.add(((XQueryExpression) funDecl.getExpressions().get(i)).clone()); 1096 } 1097 } 1098 1099 ArrayList parameters = funDecl.getParameters(); 1100 if (exprs != null && params != null) { 1102 HashMap subMap = new HashMap(); 1103 for (int i = 0; i < params.size(); i++) { 1104 subMap.put(parameters.get(i), params.get(i)); 1105 } 1106 for (int i = 0; i < exprs.size(); i++) { 1107 ((XQueryExpression) exprs.get(i)).substitute(subMap, typeVisitor); 1108 } 1109 } 1110 if (exprs != null) { 1112 if (exprs.size() == 1) 1113 this.expr = (XQueryExpression) exprs.get(0); 1114 else 1115 this.expr = new XQueryExpressionSequence(exprs, arg.getParentModule()); 1116 this.normalized = true; 1117 } else 1118 this.expr = arg; 1119 this.context.update(localCtx); 1121 } catch (CloneNotSupportedException e) { 1122 throw new NormalizeException(0, e); 1123 } catch (XQueryException e) { 1124 throw new NormalizeException(0, e); 1125 } 1126 } 1127 1128 1129 1130 1139 protected ArrayList visitPrimitiveFunctionCall(PrimitiveFunctionCall arg, boolean aggregate) throws NormalizeException { 1140 try { 1141 ArrayList params = arg.getArguments(); 1143 if ((params != null) && (params.size() > 0)) { 1144 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 1145 VisitorContext localCtx = new VisitorContext(); 1146 localCtx.merge(this.context, false); 1147 localCtx.filter(this.depth); 1149 localCtx.setMemo(this.depth + 1, VisitorContext._INCLUDEINPARENTHESIS, null, true); 1151 if (aggregate) { 1152 localCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._INAGGREGATEFUNCTION, null, true); 1154 } 1155 recurseVisitor.setContext(localCtx); 1156 for (int i = params.size() - 1; i >= 0; i--) { 1157 XQueryExpression parami = (XQueryExpression) params.get(i); 1158 parami.accept(recurseVisitor); 1159 localCtx.update(recurseVisitor.getContext()); 1160 XQueryExpression expri = recurseVisitor.getExpr(); 1161 if (expri != null) { 1164 if (arg instanceof FunctionCOUNT || arg instanceof FunctionEMPTY || arg instanceof FunctionEXISTS) 1165 atomizeVisitor.isSpecial(); 1166 expri.accept(atomizeVisitor); 1167 expri = atomizeVisitor.getExpression(); 1168 } 1169 if (expri != null) { 1170 params.set(i, expri); 1171 } else { 1172 params.set(i, new XQueryVoid(arg.getParentModule())); 1173 } 1174 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1176 } 1177 this.context.update(localCtx); 1179 } 1180 return params; 1181 } catch (XQueryException e) { 1182 throw new NormalizeException(0, e); 1183 } 1184 } 1185 1186 public void visit(PrimitiveFunctionCall arg) throws NormalizeException { 1188 ArrayList params = this.visitPrimitiveFunctionCall(arg, arg instanceof AggregateFunctionCall); 1189 if (params != null) { 1190 try { 1191 boolean norm = false; 1192 for (int i = 0; i < params.size(); i++) { 1194 if (params.get(i) instanceof XQueryVoid) { 1195 norm = true; 1197 break; 1199 } 1200 } 1201 if (!norm && this.normalized) { 1202 arg.setArguments(params); 1205 if (reType) 1207 arg.accept(typeVisitor); 1208 this.expr = arg; 1209 } else { 1210 this.expr = arg; 1211 } 1212 } catch (XQueryException e) { 1213 throw new NormalizeException(0, e); 1214 } 1215 } else 1216 this.expr = arg; 1217 } 1218 1219 1222 public void visit(FunctionCOLLECTION arg) throws NormalizeException { 1223 try { 1224 if (arg.getSourceName().equals(sourceName)) 1225 arg.eraseSourceName(); 1226 } catch (XQueryException e) { 1227 throw new NormalizeException(0, e); 1228 } 1229 this.expr = arg; 1230 } 1231 1232 1245 public void visit(FunctionCONCAT arg) throws NormalizeException { 1246 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1247 try { 1248 if ((params.size() == 0) || ((params.size() == 1) && (params.get(0) instanceof XQueryVoid))) { 1250 this.normalized = true; 1251 this.expr = new ValueString("", arg.getParentModule()); 1252 } else if (this.normalized) { 1253 arg.setArguments(params); 1255 if (reType) 1257 arg.accept(typeVisitor); 1258 this.expr = arg; 1259 } else { 1260 this.expr = arg; 1261 } 1262 } catch (XQueryException e) { 1263 throw new NormalizeException(0, e); 1264 } 1265 } 1266 1267 1279 public void visit(FunctionEMPTY arg) throws NormalizeException { 1280 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1282 try { 1283 if (params.get(0) instanceof XQueryVoid) { 1285 this.normalized = true; 1286 this.expr = new FunctionTRUE(null, arg.getParentModule()); 1287 } else if (this.normalized) { 1288 arg.setArguments(params); 1290 if (reType) 1292 arg.accept(typeVisitor); 1293 this.expr = arg; 1294 } else { 1295 this.expr = arg; 1296 } 1297 } catch (XQueryException e) { 1298 throw new NormalizeException(0, e); 1299 } 1300 } 1302 1303 1315 1316 public void visit(FunctionEXISTS arg) throws NormalizeException { 1319 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1321 try { 1322 if (params.get(0) instanceof XQueryVoid) { 1324 this.normalized = true; 1325 this.expr = new FunctionFALSE(null, arg.getParentModule()); 1326 return; 1327 } 1328 if (params.get(0) instanceof Element || params.get(0) instanceof Value) { 1331 this.normalized = true; 1332 this.expr = new FunctionTRUE(null, arg.getParentModule()); 1333 return; 1334 } 1335 if (params.get(0) instanceof XQueryExpressionSequence) { 1338 ArrayList subExprs = ((XQueryExpressionSequence) params.get(0)).getSubExpressions(); 1339 if (subExprs == null || subExprs.isEmpty()) { 1340 this.normalized = true; 1341 this.expr = new FunctionFALSE(null, arg.getParentModule()); 1342 return; 1343 } 1344 } 1345 if (this.normalized) { 1353 arg.setArguments(params); 1355 if (reType) 1357 arg.accept(typeVisitor); 1358 this.expr = arg; 1359 } else { 1360 this.expr = arg; 1361 } 1362 } catch (XQueryException e) { 1363 throw new NormalizeException(0, e); 1364 } 1365 } 1367 1368 1380 public void visit(FunctionLOCAL_NAME arg) throws NormalizeException { 1381 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1383 try { 1384 if (params.get(0) instanceof XQueryVoid) { 1386 this.normalized = true; 1387 this.expr = new ValueString("", arg.getParentModule()); 1388 } else if (this.normalized) { 1389 arg.setArguments(params); 1391 if (reType) 1393 arg.accept(typeVisitor); 1394 this.expr = arg; 1395 } else { 1396 this.expr = arg; 1397 } 1398 } catch (XQueryException e) { 1399 throw new NormalizeException(0, e); 1400 } 1401 } 1403 1404 1417 public void visit(FunctionNOT arg) throws NormalizeException { 1418 this.context.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 1421 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1422 this.context.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 1424 try { 1426 if (this.normalized) { 1427 if ((params.get(0) == null) || (params.get(0) instanceof FunctionFALSE) || (params.get(0) instanceof XQueryVoid)) { 1428 this.expr = new FunctionTRUE(null, arg.getParentModule()); 1429 } else if (params.get(0) instanceof FunctionTRUE) { 1430 this.expr = new FunctionFALSE(null, arg.getParentModule()); 1431 } else { 1432 arg.setArguments(params); 1433 this.expr = arg; 1434 } 1435 if (reType) 1437 this.expr.accept(typeVisitor); 1438 } else { 1439 if ((params.get(0) instanceof FunctionFALSE) || (params.get(0) instanceof XQueryVoid)) { 1440 this.expr = new FunctionTRUE(null, arg.getParentModule()); 1441 this.normalized = true; 1442 } else if (params.get(0) instanceof FunctionTRUE) { 1443 this.expr = new FunctionFALSE(null, arg.getParentModule()); 1444 this.normalized = true; 1445 } else { 1446 this.expr = arg; 1447 } 1448 } 1449 } catch (XQueryException e) { 1450 throw new NormalizeException(0, e); 1451 } 1452 } 1454 1455 1467 public void visit(FunctionSTRING arg) throws NormalizeException { 1468 ArrayList params = this.visitPrimitiveFunctionCall(arg, false); 1470 try { 1471 if ((params.size() != 0) && (params.get(0) instanceof XQueryVoid)) { 1473 this.normalized = true; 1474 this.expr = new ValueString("", arg.getParentModule()); 1475 } else if (this.normalized) { 1476 arg.setArguments(params); 1478 if (reType) 1480 arg.accept(typeVisitor); 1481 this.expr = arg; 1482 } else { 1483 this.expr = arg; 1484 } 1485 } catch (XQueryException e) { 1486 throw new NormalizeException(0, e); 1487 } 1488 } 1490 1491 1503 public void visit(FunctionSUM arg) throws NormalizeException { 1504 ArrayList params = this.visitPrimitiveFunctionCall(arg, true); 1506 try { 1507 if (params.get(0) instanceof XQueryVoid) { 1509 this.normalized = true; 1510 this.expr = new ValueDouble("0", arg.getParentModule()); 1511 } else if (this.normalized) { 1512 arg.setArguments(params); 1514 if (reType) 1516 arg.accept(typeVisitor); 1517 this.expr = arg; 1518 } else { 1519 this.expr = arg; 1520 } 1521 } catch (XQueryException e) { 1522 throw new NormalizeException(0, e); 1523 } 1524 } 1526 1527 public void visit(FunctionDATA arg) throws NormalizeException { 1528 XQueryExpression argument = arg.getArgument(0); 1531 if ((!(argument instanceof LocatedExpression) || !((LocatedExpression) argument).isRelative()) && argument.getQType() != null && arg.getArgument(0).getQType().isMultiple()) { 1532 try { 1533 ArrayList vars = new ArrayList(1); 1534 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg.getArgument(0), Variable.NORM_CREATOR); 1535 arg.getArguments().set(0, var); 1536 if (reType) 1537 arg.accept(typeVisitor); 1538 vars.add(var); 1539 this.expr = new FLWRExpression(vars, null, null, arg, arg.getParentModule()); 1540 this.normalized = true; 1541 return; 1542 } catch (XQueryException e) { 1543 throw new NormalizeException(0, e); 1544 } 1545 } 1546 ArrayList params = this.visitPrimitiveFunctionCall(arg, true); 1547 try { 1548 if (params.get(0) instanceof XQueryVoid) { 1550 this.normalized = true; 1551 this.expr = new XQueryVoid(arg.getParentModule()); 1552 } else if (this.normalized) { 1553 arg.setArguments(params); 1555 if (reType) 1557 arg.accept(typeVisitor); 1558 this.expr = arg; 1559 } else { 1560 this.expr = arg; 1561 } 1562 } catch (XQueryException e) { 1563 throw new NormalizeException(0, e); 1564 } 1565 } 1567 1568 1569 1570 1583 public void visit(AttributeValuePair arg) throws NormalizeException { 1584 try { 1585 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 1587 VisitorContext localCtx = new VisitorContext(); 1588 localCtx.merge(this.context, false); 1589 localCtx.filter(this.depth); 1591 recurseVisitor.setContext(localCtx); 1592 XQueryExpression attrName = arg.getAttributeName(); 1594 attrName.accept(recurseVisitor); 1595 localCtx.update(recurseVisitor.getContext()); 1596 attrName = recurseVisitor.getExpr(); 1597 this.normalized = recurseVisitor.wasNormalized(); 1599 if (this.normalized) { 1600 if (attrName != null) { 1601 arg.setAttibuteName(attrName); 1603 } else { 1604 arg = null; 1605 } 1606 } 1607 if (arg != null) { 1608 XQueryExpression attrValue = arg.getAttributeValue(); 1610 attrValue.accept(recurseVisitor); 1611 localCtx.update(recurseVisitor.getContext()); 1612 attrValue = recurseVisitor.getExpr(); 1613 attrValue.accept(atomizeVisitor); 1614 attrValue = atomizeVisitor.getExpression(); 1615 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1617 if (recurseVisitor.wasNormalized()) { 1618 if (attrValue != null) { 1619 arg.setAttributeValue(attrValue); 1620 } else { 1621 arg.setAttributeValue(new ValueString("", arg.getParentModule())); 1622 } 1623 if (reType) 1625 arg.accept(typeVisitor); 1626 } 1627 } 1628 this.expr = arg; 1629 this.context.update(localCtx); 1631 } catch (XQueryException e) { 1633 throw new NormalizeException(0, e); 1634 } 1635 } 1636 1637 1650 public void visit(Element arg) throws NormalizeException { 1651 try { 1652 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 1654 VisitorContext localCtx = new VisitorContext(); 1655 localCtx.merge(this.context, false); 1656 localCtx.filter(this.depth); 1658 recurseVisitor.setContext(localCtx); 1659 XQueryExpression tagExpr = arg.getStartTag(); 1661 tagExpr.accept(recurseVisitor); 1662 localCtx.update(recurseVisitor.getContext()); 1663 tagExpr = recurseVisitor.getExpr(); 1664 this.normalized = recurseVisitor.wasNormalized(); 1666 if (this.normalized) { 1667 if (tagExpr != null) { 1668 if (tagExpr instanceof ValueText) { 1669 arg.setStartTag(tagExpr); 1671 } else { 1672 throw new NormalizeException(0, "Tag name of Element is not correctly defined. Its type is " + tagExpr.getClass().getName() + "."); 1673 } 1674 } else { 1675 arg = null; 1676 } 1677 } 1678 ArrayList expressions = null; 1679 ArrayList attributes = null; 1680 if (arg != null) { 1681 attributes = arg.getAttributes(); 1683 if (attributes != null) { 1684 int attrLen = attributes.size(); 1685 for (int i = attrLen - 1; i >= 0; i--) { 1686 ((AttributeValuePair) attributes.get(i)).accept(recurseVisitor); 1687 localCtx.update(recurseVisitor.getContext()); 1688 if (recurseVisitor.getExpr() != null) { 1689 attributes.set(i, recurseVisitor.getExpr()); 1690 } else { 1691 attributes.remove(i); 1692 } 1693 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1695 } 1696 if (this.normalized) { 1697 arg.setAttributes(attributes); 1698 } 1699 } 1700 expressions = arg.getSubExpressions(); 1702 if (expressions != null) { 1703 int exprLen = expressions.size(); 1705 for (int i = exprLen - 1; i >= 0; i--) { 1706 ((XQueryExpression) expressions.get(i)).accept(recurseVisitor); 1707 localCtx.update(recurseVisitor.getContext()); 1708 if (recurseVisitor.getExpr() != null) { 1709 expressions.set(i, recurseVisitor.getExpr()); 1710 } else { 1711 expressions.remove(i); 1712 } 1713 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1715 } 1716 if (expressions.size() > 0) { ArrayList newExpressions = new ArrayList(); 1720 for (int i = 0; i < expressions.size(); i++) { 1721 if (expressions.get(i) instanceof XQueryExpressionSequence) { 1722 ArrayList subExpr = ((XQueryExpressionSequence) expressions.get(i)).getSubExpressions(); 1723 for (int j = 0; j < subExpr.size(); j++) { 1724 if ((subExpr.get(j) instanceof Element) || (subExpr.get(j) instanceof Value)) { 1725 newExpressions.add(subExpr.get(j)); 1726 } else { 1727 ArrayList newSubExpr = new ArrayList(); 1728 newSubExpr.add(subExpr.get(j)); 1729 XQueryExpressionSequence aSeq = new XQueryExpressionSequence(newSubExpr, arg.getParentModule()); 1730 newExpressions.add(aSeq); 1732 } 1733 } 1734 } else { 1735 newExpressions.add(expressions.get(i)); 1736 } 1737 } 1738 arg.setSubExpressions(newExpressions); 1739 } else { 1740 arg.setSubExpressions(expressions); 1741 } 1742 } 1743 } 1744 this.expr = arg; 1745 if (reType && this.normalized && this.expr != null) { 1747 this.expr.accept(typeVisitor); 1748 } 1749 if (localCtx.existsMemo(this.depth, VisitorContext._ELEMENT_EXISTS)) { 1752 localCtx.setMemo(this.depth, VisitorContext._ELEMENT_EXISTS, Boolean.TRUE, true); 1753 } 1754 this.context.update(localCtx); 1756 } catch (XQueryException e) { 1758 throw new NormalizeException(0, e.getMessage()); 1759 } 1760 } 1761 1762 1787 public void visit(FLWRExpression arg) throws NormalizeException { 1788 try { 1789 this.expr = null; 1790 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 1791 VisitorContext localCtx = new VisitorContext(); 1792 ArrayList whereFLWRStack = null; 1794 if (this.context.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE)) { 1795 whereFLWRStack = (ArrayList) this.context.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE); 1796 this.context.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE); 1797 } 1798 localCtx.merge(this.context, false); 1799 localCtx.filter(this.depth); 1801 localCtx.setMemo(this.depth + 1, VisitorContext._VARIABLE_DECLARATION, null, true); 1803 localCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 1805 localCtx.setMemo(this.depth + 2, VisitorContext._ELEMENT_EXISTS, null, true); 1806 localCtx.setMemo(this.depth + 3, VisitorContext._ELEMENT_EXISTS, null, true); 1807 VisitorContext localForCtx = new VisitorContext(); 1809 localForCtx.setMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 1810 localForCtx.setMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 1811 localForCtx.setMemo(this.depth + 2, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS, null, true); 1812 localForCtx.setMemo(this.depth + 3, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS, null, true); 1813 localForCtx.merge(localCtx, false); 1814 VisitorContext localLetCtx = new VisitorContext(); 1816 localLetCtx.setMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_GETFLWR, null, true); 1819 localLetCtx.setMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_GETFLWR, null, true); 1820 localLetCtx.setMemo(this.depth + 2, VisitorContext._FLWR_RETURNS_TAG, null, true); 1821 localLetCtx.setMemo(this.depth + 3, VisitorContext._FLWR_RETURNS_TAG, null, true); 1822 localLetCtx.merge(localCtx, false); 1823 HashMap substFor = new HashMap(); 1825 ArrayList newWhere = new ArrayList(); 1826 HashMap exprUnion = new HashMap(); 1827 HashMap substLet = new HashMap(); 1828 HashMap substVarTmp = new HashMap(); 1829 boolean allVariablesAreEliminated = false; 1831 boolean eliminateThisFLWR = false; 1832 ArrayList variables = arg.getVariables(); 1834 Variable currentVar = null; 1838 for (int i = 0; (i < variables.size()) && !eliminateThisFLWR; i++) { 1840 currentVar = (Variable) variables.get(i); 1841 if (currentVar.getCreator() != Variable.NORM_CREATOR && currentVar.getBindingType() == Constants.FOR_BINDINGTYPE && !currentVar.isInput() && currentVar.getExpression().getQType().getOccurence() == QType.OCC_1_1 && (variables.size() != 1 || arg.getParentExpression() != null)) { 1844 currentVar.setBindingType(Constants.LET_BINDINGTYPE); 1845 } 1846 if (currentVar.getBindingType() == Constants.FOR_BINDINGTYPE) { 1848 recurseVisitor.setContext(localForCtx); 1850 currentVar.accept(recurseVisitor); 1852 localForCtx.update(recurseVisitor.getContext()); 1853 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1855 if (recurseVisitor.getExpr() == null) { 1856 eliminateThisFLWR = true; 1858 } else { boolean existSequence = (localForCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS) != null); 1860 if ((localForCtx.getMemo(this.depth + 2, VisitorContext._ELEMENT_EXISTS) != null) || ((localForCtx.getMemo(this.depth + 3, VisitorContext._ELEMENT_EXISTS) != null) && existSequence && (((Integer ) localForCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS)).intValue() <= 1))) { 1862 variables.remove(i); 1863 i--; 1864 substFor.put(currentVar.getVarName(), currentVar.getExpression()); 1867 substVarTmp.clear(); 1869 substVarTmp.putAll(substFor); 1870 substVarTmp.putAll(substLet); 1871 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substVarTmp, true); 1872 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substVarTmp, true); 1873 if (existSequence) { 1875 localForCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 1876 localForCtx.setMemo(this.depth + 3, VisitorContext._ELEMENT_EXISTS, null, true); 1877 } else { 1878 localForCtx.setMemo(this.depth + 2, VisitorContext._ELEMENT_EXISTS, null, true); 1879 } 1880 this.normalized = true; 1881 } else if ((localForCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR) != null) || ((localForCtx.getMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_INNERFLWR) != null) && existSequence)) { 1883 FLWRExpression innerFLWR = (FLWRExpression) (existSequence ? localForCtx.getMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_INNERFLWR) : localForCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR)); 1885 ArrayList innerOrderBy = innerFLWR.getOrderBy(); 1886 ArrayList outerOrderBy = arg.getOrderBy(); 1888 1889 ArrayList innerVars = innerFLWR.getVariables(); 1890 XQueryExpression innerWhere = innerFLWR.getWhereClause(); 1891 XQueryExpression innerReturn = innerFLWR.getReturnClause(); 1892 1893 if (innerOrderBy != null && !innerOrderBy.isEmpty()) { 1894 if (arg.getOrderBy() == null || arg.getOrderBy().isEmpty()) { 1895 for (int j = 0; j < i; j++) { 1896 Variable varj = (Variable) variables.get(j); 1897 if (varj.getBindingType() == Constants.FOR_BINDINGTYPE) { 1898 varj.setOrder(Constants.PLACE_ORDER); 1899 arg.addOrderBy(varj); 1900 } 1901 } 1902 } 1903 if (arg.getOrderBy() == null) 1904 arg.setOrderBy(innerOrderBy); 1905 else 1906 arg.getOrderBy().addAll(innerOrderBy); 1907 } 1908 1909 arg.addVariables(i, innerVars); 1911 i += innerVars.size(); 1912 if ((arg.getQType() == null) || (innerReturn.getQType().isMultiple())) { 1914 currentVar.setExpression(innerReturn, true); 1916 } else { 1917 variables.remove(i); 1918 i--; 1919 substFor.put(currentVar.getVarName(), innerReturn); 1921 substVarTmp.clear(); 1923 substVarTmp.putAll(substFor); 1924 substVarTmp.putAll(substLet); 1925 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substVarTmp, true); 1926 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substVarTmp, true); 1927 } 1928 if (innerWhere != null) { 1929 newWhere.add(innerWhere); 1930 } 1931 this.normalized = true; 1932 if (existSequence) { 1934 localForCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 1935 localForCtx.setMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 1936 } else { 1937 localForCtx.setMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 1938 } 1939 } else if ((localForCtx.getMemo(this.depth + 2, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS) != null) || ((localForCtx.getMemo(this.depth + 3, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS) != null) && existSequence)) { 1940 ArrayList innerUnionExpr = (ArrayList) (existSequence ? localForCtx.getMemo(this.depth + 3, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS) : localForCtx.getMemo(this.depth + 2, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS)); 1942 currentVar.setExpression((XQueryExpression) innerUnionExpr.get(0), true); 1943 exprUnion.put(currentVar.getVarName(), innerUnionExpr.get(1)); 1944 if (existSequence) { 1946 localForCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 1947 localForCtx.setMemo(this.depth + 3, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS, null, true); 1948 } else { 1949 localForCtx.setMemo(this.depth + 2, VisitorContext._LISTOPUNIONEXPRESSION_GETEXPRESSIONS, null, true); 1950 } 1951 this.normalized = true; 1952 } 1953 } 1954 } else if (currentVar.getBindingType() == Constants.LET_BINDINGTYPE) { 1955 ArrayList parents = currentVar.getParentExpression(); 1958 if (parents == null || parents.isEmpty()) { variables.remove(i); 1960 i--; 1961 substLet.put(currentVar.getVarName(), currentVar.getExpression()); 1963 continue; 1964 } 1965 recurseVisitor.setContext(localLetCtx); 1967 currentVar.accept(recurseVisitor); 1969 localLetCtx.update(recurseVisitor.getContext()); 1970 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 1972 if (recurseVisitor.getExpr() == null) { 1973 variables.remove(i); 1975 i--; 1976 substLet.put(currentVar.getVarName(), null); 1977 substVarTmp.clear(); 1979 substVarTmp.putAll(substLet); 1980 substVarTmp.putAll(substFor); 1981 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 1982 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 1983 this.normalized = true; 1984 } else { boolean existSequence = (localForCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS) != null); 1986 if ((localForCtx.getMemo(this.depth + 2, VisitorContext._ELEMENT_EXISTS) != null) || ((localForCtx.getMemo(this.depth + 3, VisitorContext._ELEMENT_EXISTS) != null) && existSequence && (((Integer ) localForCtx.getMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS)).intValue() <= 1))) { 1988 variables.remove(i); 1990 i--; 1991 substLet.put(currentVar.getVarName(), currentVar.getExpression()); 1994 substVarTmp.clear(); 1996 substVarTmp.putAll(substFor); 1997 substVarTmp.putAll(substLet); 1998 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 1999 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 2000 if (existSequence) { 2002 localForCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 2003 localForCtx.setMemo(this.depth + 3, VisitorContext._ELEMENT_EXISTS, null, true); 2004 } else { 2005 localForCtx.setMemo(this.depth + 2, VisitorContext._ELEMENT_EXISTS, null, true); 2006 } 2007 this.normalized = true; 2008 } else if (localLetCtx.getMemo(this.depth + 2, VisitorContext._FLWR_RETURNS_TAG) != null) { 2009 variables.remove(i); 2010 i--; 2011 substLet.put(currentVar.getVarName(), localLetCtx.getMemo(this.depth + 2, VisitorContext._FLWR_RETURNS_TAG)); 2012 substVarTmp.clear(); 2014 substVarTmp.putAll(substLet); 2015 substVarTmp.putAll(substFor); 2016 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 2017 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substVarTmp, true); 2018 this.normalized = true; 2019 localLetCtx.setMemo(this.depth + 2, VisitorContext._FLWR_RETURNS_TAG, null, true); 2021 } else if (localLetCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_GETFLWR) != null || (localLetCtx.getMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_GETFLWR) != null && existSequence)) { 2022 if (parents.size() == 1 && currentVar.getCreator() != Variable.NORM_CREATOR && !(currentVar.getExpression() instanceof AggregateFunctionCall)) { 2025 FLWRExpression innerFLWR = (FLWRExpression) (existSequence ? localLetCtx.getMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_GETFLWR) : localLetCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_GETFLWR)); 2028 variables.remove(i); 2031 i--; 2032 substLet.put(currentVar.getVarName(), innerFLWR); 2033 localForCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substLet, true); 2035 localLetCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substLet, true); 2036 this.normalized = true; 2037 } 2038 if (existSequence) { 2040 localLetCtx.setMemo(this.depth + 2, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 2041 localLetCtx.setMemo(this.depth + 3, VisitorContext._FLWREXPRESSION_GETFLWR, null, true); 2042 } else { 2043 localLetCtx.setMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_GETFLWR, null, true); 2044 } 2045 } else { 2046 } 2049 } 2050 } else { throw new NormalizeException("The variable \"" + currentVar + "\" in " + arg.toString() + " has not a valid binding type (" + currentVar.getBindingType() + ") !"); 2052 } 2053 } if (variables.size() > 0) { 2056 for (int j = 0; j < variables.size(); j++) { 2057 Variable tmpVar = (Variable) variables.get(j); 2058 XQueryExpression tmpVarExpr = tmpVar.getExpression(); 2059 int bindingtype = tmpVar.getBindingType(); 2060 if (tmpVar.getCreator() != Variable.NORM_CREATOR && ( tmpVarExpr instanceof Value || (bindingtype == Constants.LET_BINDINGTYPE && !tmpVarExpr.getQType().isMultiple() && !(tmpVarExpr instanceof LocatedExpression) && !(tmpVarExpr instanceof FunctionCall) && !(tmpVarExpr instanceof ListOpArithExpression) && !(tmpVarExpr instanceof FLWRExpression)) || (bindingtype == Constants.LET_BINDINGTYPE && tmpVarExpr instanceof LocatedExpression && ((LocatedExpression) tmpVarExpr).getSteps().size() != 1 && ((LocatedExpression) tmpVarExpr).getExpression() instanceof Variable && tmpVarExpr.getQType().isMultiple()))) { 2068 HashMap map = new HashMap(1); 2070 map.put(tmpVar, tmpVarExpr); 2071 for (int i = j + 1; i < variables.size(); i++) 2073 ((Variable) variables.get(i)).getExpression().substitute(map, typeVisitor); 2074 XQueryExpression tmpSubExpr = null; 2076 XQueryExpression whereClause = arg.getWhereClause(); 2077 if (whereClause != null) { 2078 if ((tmpSubExpr = (XQueryExpression) map.get(whereClause)) != null) 2079 arg.setWhereClause(tmpSubExpr); 2080 else 2081 whereClause.substitute(map, typeVisitor); 2082 } 2083 ArrayList orderBys = arg.getOrderBy(); 2085 if (orderBys != null) { 2086 for (int i = 0; i < orderBys.size(); i++) { 2087 XQueryExpression orderby = (XQueryExpression) orderBys.get(i); 2088 if ((tmpSubExpr = (XQueryExpression) map.get(orderby)) != null) 2089 orderBys.set(i, tmpSubExpr); 2090 else 2091 orderby.substitute(map, typeVisitor); 2092 } 2093 } 2094 XQueryExpression returnClause = arg.getReturnClause(); 2096 if ((tmpSubExpr = (XQueryExpression) map.get(returnClause)) != null) 2097 arg.setReturnClause(tmpSubExpr); 2098 else 2099 returnClause.substitute(map, typeVisitor); 2100 variables.remove(j); 2101 j--; 2102 } 2103 } 2104 if (variables.size() == 0) 2105 allVariablesAreEliminated = true; 2106 } 2107 if (eliminateThisFLWR) { 2109 arg = null; 2110 } else { 2111 2116 if (variables.size() == 0 && !allVariablesAreEliminated) { 2118 Object [] substForValues = substFor.values().toArray(); 2120 boolean substForValuesAllNull = true; 2121 for (int sfv = 0; (sfv < substForValues.length) && substForValuesAllNull; sfv++) { 2122 if (substForValues[sfv] != null) { 2123 substForValuesAllNull = false; 2124 } 2125 } 2126 Object [] substLetValues = substLet.values().toArray(); 2127 boolean substLetValuesAllNull = true; 2128 for (int slv = 0; (slv < substLetValues.length) && substForValuesAllNull && substLetValuesAllNull; slv++) { 2129 if (substLetValues[slv] != null) { 2130 substLetValuesAllNull = false; 2131 } 2132 } 2133 if (substForValuesAllNull && substLetValuesAllNull) { 2134 arg = null; 2136 } else { 2137 allVariablesAreEliminated = true; 2139 } 2140 } 2141 } 2142 if (arg != null) { 2143 XQueryExpression whereClause = arg.getWhereClause(); 2146 if (newWhere.size() > 0) { 2148 if (whereClause != null) { 2149 for (int iwc = 0; iwc < newWhere.size(); iwc++) { 2151 whereClause = new BinOpANDExpression(whereClause, (XQueryExpression) newWhere.get(iwc), arg.getParentModule()); 2152 whereClause.setParenthesis(true); 2153 } 2154 } else { 2155 whereClause = (XQueryExpression) newWhere.get(0); 2156 for (int iwc = 1; iwc < newWhere.size(); iwc++) { 2157 whereClause = new BinOpANDExpression(whereClause, (XQueryExpression) newWhere.get(iwc), arg.getParentModule()); 2158 whereClause.setParenthesis(true); 2159 } 2160 } 2161 } 2162 if (whereClause != null) { 2163 VisitorContext localWhereCtx = new VisitorContext(); 2164 boolean stop = false; 2167 XQueryExpression whereContent = whereClause; 2168 ArrayList subExpr = null; 2169 while ((whereContent instanceof XQueryExpressionSequence) && !stop) { 2171 subExpr = ((XQueryExpressionSequence) whereContent).getSubExpressions(); 2172 if (subExpr.size() != 1) { 2173 stop = true; 2174 } else { 2175 whereContent = (XQueryExpression) subExpr.get(0); 2176 } 2177 2178 } 2179 boolean buildWhereQuantified = false; 2182 Variable newQuantifiedVar = null; 2183 HashMap substLetClone = (HashMap) substLet.clone(); 2184 localWhereCtx.merge(this.context, false); 2210 if (!substLetClone.isEmpty()) { 2212 if (localWhereCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR)) { 2213 HashMap substToAdd = (HashMap) localWhereCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR); 2214 substLetClone.putAll(substToAdd); 2215 } 2216 localWhereCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substLetClone, true); 2217 } 2218 if (!substFor.isEmpty()) { 2219 if (localWhereCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR)) { 2220 HashMap substToAdd = (HashMap) localWhereCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR); 2221 substFor.putAll(substToAdd); 2222 } 2223 localWhereCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substFor, true); 2224 } 2225 localWhereCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 2227 localWhereCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE, new ArrayList(), true); 2229 recurseVisitor.setContext(localWhereCtx); 2230 whereClause.accept(recurseVisitor); 2232 this.context.update(recurseVisitor.getContext()); 2233 localWhereCtx.update(recurseVisitor.getContext()); 2234 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2236 localWhereCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 2238 ArrayList newLetVariables = (ArrayList) localWhereCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE); 2240 localWhereCtx.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE); 2241 while (!newLetVariables.isEmpty()) { 2244 arg.addVariable((Variable) newLetVariables.remove(0)); 2245 } 2246 if (recurseVisitor.getExpr() == null) { 2248 arg = null; 2249 } else { 2250 if (buildWhereQuantified) { 2252 if (((Boolean ) localWhereCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_WASSUBSTITUTELETFLWR)).booleanValue()) { 2253 ArrayList quantifiedVar = new ArrayList(); 2254 quantifiedVar.add(newQuantifiedVar); 2255 arg.setWhereClause(new QuantifiedExpression(Constants.SOME_QUANTIFIER, quantifiedVar, recurseVisitor.getExpr(), arg.getParentModule())); 2256 } 2257 } else { 2260 arg.setWhereClause(recurseVisitor.getExpr()); 2261 } 2262 } 2263 localWhereCtx = null; 2265 } 2266 if (arg != null) { 2267 ArrayList sortClauses = arg.getOrderBy(); 2269 if ((sortClauses != null) && (sortClauses.size() != 0)) { 2270 int sortClauseLen = sortClauses.size(); 2272 for (int i = sortClauseLen - 1; i >= 0; i--) { 2273 int[] direction = ((XQueryExpression) sortClauses.get(i)).getOrder(); 2275 VisitorContext localSortbyCtx = new VisitorContext(); 2277 localSortbyCtx.merge(this.context, false); 2278 if (!substLet.isEmpty()) { 2280 if (localSortbyCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR)) { 2281 HashMap substToAdd = (HashMap) localSortbyCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR); 2282 substLet.putAll(substToAdd); 2283 } 2284 localSortbyCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substLet, true); 2285 } 2286 if (!substFor.isEmpty()) { 2287 if (localSortbyCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR)) { 2288 HashMap substToAdd = (HashMap) localSortbyCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR); 2289 substFor.putAll(substToAdd); 2290 } 2291 localSortbyCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substFor, true); 2292 } 2293 recurseVisitor.setContext(localSortbyCtx); 2294 XQueryExpression expri = (XQueryExpression) sortClauses.get(i); 2295 expri.accept(recurseVisitor); 2296 localCtx.update(recurseVisitor.getContext()); 2297 expri = recurseVisitor.getExpr(); 2298 if (expri != null) { 2300 expri.accept(atomizeVisitor); 2301 expri = atomizeVisitor.getExpression(); 2302 } 2311 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2313 if (recurseVisitor.wasNormalized()) { 2314 if (expri != null) { 2315 expri.setOrder(direction); 2316 sortClauses.set(i, expri); 2317 } else { 2318 sortClauses.remove(i); 2319 } 2320 } 2321 } 2322 if (sortClauses.size() == 0) { 2323 arg.setOrderBy(null); 2324 } else { 2325 arg.setOrderBy(sortClauses); 2326 } 2327 } 2328 } 2329 if (arg != null) { 2330 XQueryExpression returnClause = arg.getReturnClause(); 2333 VisitorContext localReturnCtx = new VisitorContext(); 2334 localReturnCtx.merge(this.context, false); 2337 if (!substLet.isEmpty()) { 2339 if (localReturnCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR)) { 2340 HashMap substToAdd = (HashMap) localReturnCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR); 2341 substLet.putAll(substToAdd); 2342 } 2343 localReturnCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR, substLet, true); 2344 } 2345 if (!substFor.isEmpty()) { 2346 if (localReturnCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR)) { 2347 HashMap substToAdd = (HashMap) localReturnCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR); 2348 substFor.putAll(substToAdd); 2349 } 2350 localReturnCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR, substFor, true); 2351 } 2352 localReturnCtx.setMemo(this.depth + 1, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 2354 localReturnCtx.setMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR, null, true); 2359 localReturnCtx.setMemo(this.depth + 1, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, null, true); 2364 recurseVisitor.setContext(localReturnCtx); 2366 returnClause.accept(recurseVisitor); 2367 this.context.update(recurseVisitor.getContext()); 2368 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2370 if (recurseVisitor.getExpr() != null) { 2371 Integer cardSeqTmp = (Integer ) localReturnCtx.getMemo(this.depth + 1, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS); 2373 int cardSequence = 0; 2374 if (cardSeqTmp != null) { 2375 cardSequence = cardSeqTmp.intValue(); 2376 } 2377 if ((localReturnCtx.getMemo(this.depth + 1, VisitorContext._FLWREXPRESSION_INNERFLWR) != null) || ((localReturnCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR) != null) && (cardSequence == 1))) { 2379 FLWRExpression innerFLWR = (FLWRExpression) ((cardSequence == 1) ? localReturnCtx.getMemo(this.depth + 2, VisitorContext._FLWREXPRESSION_INNERFLWR) : localReturnCtx.getMemo(this.depth + 1, VisitorContext._FLWREXPRESSION_INNERFLWR)); 2381 ArrayList innerOrderBy = innerFLWR.getOrderBy(); 2382 ArrayList outerOrderBy = arg.getOrderBy(); 2384 2385 ArrayList innerVars = innerFLWR.getVariables(); 2386 XQueryExpression innerWhere = innerFLWR.getWhereClause(); 2387 XQueryExpression innerReturn = innerFLWR.getReturnClause(); 2388 arg.addWhereClause(innerWhere); 2390 if (innerOrderBy != null && !innerOrderBy.isEmpty()) { 2391 if (arg.getOrderBy() == null || arg.getOrderBy().isEmpty()) { 2392 for (int j = 0; j < variables.size(); j++) { 2393 Variable varj = (Variable) variables.get(j); 2394 if (varj.getBindingType() == Constants.FOR_BINDINGTYPE) { 2395 varj.setOrder(Constants.PLACE_ORDER); 2396 arg.addOrderBy(varj); 2397 } 2398 } 2399 } 2400 if (arg.getOrderBy() == null) 2401 arg.setOrderBy(innerOrderBy); 2402 else 2403 arg.getOrderBy().addAll(innerOrderBy); 2404 } 2405 arg.addVariables(innerVars); 2407 arg.setReturnClause(innerReturn); 2408 allVariablesAreEliminated = false; 2409 this.normalized = true; 2410 } else { 2411 arg.setReturnClause(recurseVisitor.getExpr()); 2412 } 2413 if (allVariablesAreEliminated) { 2415 if (arg.getWhereClause() == null) { 2417 this.expr = recurseVisitor.getExpr(); 2419 } else if (arg.getWhereClause() instanceof FunctionTRUE) { 2420 this.expr = recurseVisitor.getExpr(); 2422 } else if (arg.getWhereClause() instanceof FunctionFALSE) { 2423 arg = null; 2425 } else { this.expr = createDummyFLWR(arg.getWhereClause(), recurseVisitor.getExpr()); 2431 } 2433 } else { if (exprUnion.size() > 0) { 2435 Object [] keys = exprUnion.keySet().toArray(); 2437 for (int ik = 0; ik < keys.length; ik++) { 2438 FLWRExpression newFLWR = (FLWRExpression) arg.clone(); 2439 VisitorContext localUnionFLWRCtx = new VisitorContext(); 2441 Variable varSubstExpr = new Variable((QName) keys[ik], arg.getParentModule()); 2442 varSubstExpr.setExpression((XQueryExpression) exprUnion.get(keys[ik]), true); 2443 localUnionFLWRCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_CHANGEEXPRESSION4FLWR, varSubstExpr, true); 2444 localUnionFLWRCtx.merge(this.context, false); 2445 recurseVisitor.setContext(localUnionFLWRCtx); 2446 newFLWR.accept(recurseVisitor); 2448 this.context.update(recurseVisitor.getContext()); 2449 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2451 this.expr = arg; 2452 this.expr = new ListOpUNIONExpression(this.expr, newFLWR, arg.getParentModule()); 2453 } 2454 } 2455 else if (recurseVisitor.getExpr() instanceof Element) { 2457 this.context.setMemo(this.depth, VisitorContext._FLWR_RETURNS_TAG, arg, true); 2458 } 2460 } 2461 } else { arg = null; 2463 } 2464 if (this.expr == null) { 2465 this.expr = arg; 2466 } 2467 localReturnCtx = null; 2469 } else { 2470 this.expr = null; 2472 } 2473 } else { 2474 this.expr = null; 2476 } 2477 2478 2508 if (whereFLWRStack != null) { 2510 this.context.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE, whereFLWRStack, true); 2511 } 2512 if ((this.expr != null) && (this.expr instanceof FLWRExpression) && (this.expr.getParentExpression() == null || this.expr.getParentExpression().isEmpty() || !(this.expr.getParentExpression().get(0) instanceof Variable)) && (this.context.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE))) { 2514 ArrayList letVariables = (ArrayList) this.context.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE); 2516 Variable newLetVariable = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, expr, Variable.NORM_CREATOR); 2518 letVariables.add(newLetVariable); 2520 this.context.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._FLWREXPRESSION_GETANDREPLACEFLWRINWHERE, letVariables, true); 2521 this.expr = newLetVariable; 2523 this.normalized = true; 2524 } 2525 if ((this.expr != null) && (localCtx.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION))) { 2527 this.normalized = true; 2528 boolean parenthesis = this.expr.getParenthesis(); 2531 this.expr.setParenthesis(false); 2534 ArrayList parameter = new ArrayList(); 2535 parameter.add(this.expr); 2536 this.expr = new FunctionEXISTS(parameter, arg.getParentModule()); 2537 this.expr.setParenthesis(parenthesis); 2540 } 2541 if (reType && this.normalized && this.expr != null) { 2543 this.expr.accept(typeVisitor); 2544 } 2545 if ((this.expr != null) && (this.expr instanceof FLWRExpression)) { 2547 FLWRExpression thisFLWR = (FLWRExpression) this.expr; 2549 if (this.context.existsMemo(this.depth, VisitorContext._FLWREXPRESSION_INNERFLWR)) { 2552 this.context.setMemo(this.depth, VisitorContext._FLWREXPRESSION_INNERFLWR, thisFLWR, true); 2554 } 2555 if (this.context.existsMemo(this.depth, VisitorContext._FLWREXPRESSION_GETFLWR)) { 2557 this.context.setMemo(this.depth, VisitorContext._FLWREXPRESSION_GETFLWR, thisFLWR, true); 2559 } 2560 if (this.context.existsMemo(this.depth, VisitorContext._QUANTIFIED_INNERFLWR)) { 2565 this.context.setMemo(this.depth, VisitorContext._QUANTIFIED_INNERFLWR, thisFLWR, true); 2567 } 2568 } 2570 localCtx = null; 2572 localForCtx = null; 2573 localLetCtx = null; 2574 } catch (CloneNotSupportedException e) { 2580 throw new NormalizeException(0, e); 2581 } catch (XQueryException e) { 2582 throw new NormalizeException(0, e); 2583 } 2584 } 2585 2586 2599 public void visit(ITEExpression arg) throws NormalizeException { 2600 try { 2601 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 2603 VisitorContext localCtx = new VisitorContext(); 2604 localCtx.merge(this.context, false); 2605 localCtx.filter(this.depth); 2607 recurseVisitor.setContext(localCtx); 2608 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 2610 XQueryExpression ifClause = arg.getIfExpression(); 2612 ifClause.accept(recurseVisitor); 2613 localCtx.update(recurseVisitor.getContext()); 2614 ifClause = recurseVisitor.getExpr(); 2615 this.normalized = recurseVisitor.wasNormalized(); 2617 localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 2619 byte ifValue = 0; if (this.normalized) { 2621 if (ifClause != null) { 2622 arg.setIfExpression(ifClause); 2623 } else { 2624 ifValue = 2; 2625 } 2626 } 2627 if (ifClause instanceof FunctionTRUE) { 2629 ifValue = 1; 2630 } else if (ifClause instanceof FunctionFALSE) { 2631 ifValue = 2; 2632 } else if (ifClause instanceof XQueryExpressionSequence) { 2633 ArrayList subExpr = ((XQueryExpressionSequence) ifClause).getSubExpressions(); 2634 if (subExpr.size() == 1) { 2635 if (subExpr.get(0) instanceof FunctionTRUE) { 2636 ifValue = 1; 2637 } else if (subExpr.get(0) instanceof FunctionFALSE) { 2638 ifValue = 2; 2639 } 2640 } 2641 } 2642 XQueryExpression thenClause = arg.getThenExpression(); 2643 XQueryExpression elseClause = arg.getElseExpression(); 2644 if (ifValue <= 1) { 2645 if (!(thenClause instanceof XQueryVoid)) { 2647 thenClause.accept(recurseVisitor); 2648 localCtx.update(recurseVisitor.getContext()); 2649 thenClause = recurseVisitor.getExpr(); 2650 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2652 } 2653 } 2654 if ((ifValue == 0) || (ifValue == 2)) { 2655 if (!(elseClause instanceof XQueryVoid)) { 2657 elseClause.accept(recurseVisitor); 2658 localCtx.update(recurseVisitor.getContext()); 2659 elseClause = recurseVisitor.getExpr(); 2660 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2662 } 2663 } 2664 if (this.normalized || (ifValue >= 1)) { 2666 if (ifValue == 1) { 2667 this.expr = thenClause; 2668 } else if (ifValue == 2) { 2669 this.expr = elseClause; 2670 } else { 2671 arg.setIfExpression(ifClause); 2672 arg.setThenExpression(thenClause); 2673 arg.setElseExpression(elseClause); 2674 this.expr = arg; 2675 } 2676 this.normalized = true; 2677 } else { 2678 this.expr = arg; 2679 } 2680 if (reType && this.normalized && this.expr != null) { 2682 this.expr.accept(typeVisitor); 2683 } 2684 this.context.update(localCtx); 2686 } catch (XQueryException e) { 2688 throw new NormalizeException(0, e); 2689 } 2690 } 2691 2692 2720 2721 private LocatedExpressionReducer ler = new LocatedExpressionReducer(); 2722 2723 public void visit(LocatedExpression arg) throws NormalizeException { 2724 try { 2725 ArrayList steps = arg.getSteps(); 2727 if ((steps == null) || (steps.size() < 1)) 2728 throw new NormalizeException(0, "This located expression form \"" + arg + "\" is not supported !"); 2729 if (((Step) steps.get(0)).hasSeparator()) { 2730 throw new NormalizeException(0, "This located expression form \"" + arg + "\" is not supported : first step with separator !"); 2731 } 2732 if (!arg.getInPredicate() && steps.size() == 1 && !arg.hasPredicates() && (arg.getParentExpression() == null || arg.getParentExpression().isEmpty() || !(arg.getParentExpression().get(0) instanceof ListOpUNIONExpression))) { 2734 this.normalized = true; 2735 this.expr = ((Step) steps.get(0)).getExpression(); 2736 return; 2737 } 2738 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 2740 VisitorContext localCtx = new VisitorContext(); 2741 localCtx.merge(this.context, false); 2742 localCtx.filter(this.depth); 2744 recurseVisitor.setContext(localCtx); 2745 boolean parenthesis = arg.getParenthesis(); 2749 boolean eliminateThisLE = false; 2754 Variable newVar4LE_Predicate = null; 2759 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE)) { 2760 newVar4LE_Predicate = (Variable) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 2761 localCtx.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 2762 if (newVar4LE_Predicate != null && !arg.getStep(0).hasSeparator() && arg.getStep(0).getAxis() != Axis.NONE) { 2764 int stepindex = 0; 2766 if (arg.getExpression() instanceof NodeTest && ((NodeTest) arg.getExpression()).getKind() == NodeKind.NODE && arg.getStep(0).getAxis() == Axis.SELF) { 2767 steps.remove(0); 2768 } else { 2769 arg.getStepNum(0).setHasSeparator(true); 2771 } 2772 arg.addStepAt(0, new Step(false, Axis.NONE, newVar4LE_Predicate, null, null)); 2774 arg.setContext(false); 2775 } 2776 } 2778 ArrayList newLEVariables = new ArrayList(); 2779 XQueryExpression newWhereExpr = null; 2780 ArrayList expression4VariableBuffer = new ArrayList(); 2781 Variable parentVar = (arg.getParentExpression() != null && arg.getParentExpression().get(0) instanceof Variable && ((Variable) arg.getParentExpression().get(0)).getBindingType() == Constants.FOR_BINDINGTYPE) ? (Variable) arg.getParentExpression().get(0) : null; 2782 boolean firstPredicate = true; 2783 boolean hasPredicates = false; 2784 for (int i = 0; (i < steps.size()) && (!eliminateThisLE); i++) { 2786 localCtx.setMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE, expression4VariableBuffer, true); 2789 boolean hadPredicates = ((Step) steps.get(i)).hasPredicates(); 2792 hasPredicates = hasPredicates || hadPredicates; 2793 if (firstPredicate && hadPredicates && parentVar != null) { 2794 localCtx.setMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE_VAR, parentVar, true); 2795 } else { 2796 localCtx.setMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE_VAR, null, true); 2797 } 2798 recurseVisitor.setContext(localCtx); 2800 ((Step) steps.get(i)).accept(recurseVisitor); 2801 localCtx.update(recurseVisitor.getContext()); 2802 if (recurseVisitor.getExpr() != null) { 2803 steps.set(i, recurseVisitor.getExpr()); 2804 if (hadPredicates) { 2813 if (localCtx.getMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE) == null) { 2814 } else { ArrayList variableAndPredicate = (ArrayList) localCtx.getMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE); 2819 if (!firstPredicate || parentVar == null) { 2821 Variable newVar = (Variable) variableAndPredicate.get(0); 2822 newLEVariables.add(newVar); 2823 XQueryExpression newPredicate = (XQueryExpression) variableAndPredicate.get(1); 2825 if (newWhereExpr == null) 2827 newWhereExpr = newPredicate; 2828 else 2829 newWhereExpr = new BinOpANDExpression(newWhereExpr, newPredicate, arg.getParentModule()); 2830 localCtx.setMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE, null, true); 2832 expression4VariableBuffer = new ArrayList(); 2833 expression4VariableBuffer.add(newVar); 2834 } else { 2836 firstPredicate = false; 2838 XQueryExpression newPredicate = (XQueryExpression) variableAndPredicate.get(1); 2839 if (newWhereExpr == null) 2840 newWhereExpr = newPredicate; 2841 else 2842 newWhereExpr = new BinOpANDExpression(newWhereExpr, newPredicate, arg.getParentModule()); 2843 localCtx.setMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE, null, true); 2845 expression4VariableBuffer = new ArrayList(); 2846 expression4VariableBuffer.add(parentVar); 2847 } 2848 } 2849 } else { 2850 expression4VariableBuffer.add(recurseVisitor.getExpr()); 2852 } 2853 2854 } else { 2855 eliminateThisLE = true; 2856 } 2857 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 2859 } localCtx.removeMemo(this.depth + 1, VisitorContext._STEP_ISPARENTAXISSTEP); 2862 localCtx.removeMemo(this.depth + 1, VisitorContext._STEP_GETPREDICATE); 2863 2864 if (eliminateThisLE) { 2866 this.expr = null; 2867 return; 2868 } 2869 2871 if (newLEVariables.size() > 0 || (parentVar != null && hasPredicates)) { XQueryExpression newReturnExpr = null; 2879 if (expression4VariableBuffer.get(0) instanceof Variable) { 2880 Variable headerVariable = (Variable) expression4VariableBuffer.get(0); 2881 if (expression4VariableBuffer.size() > 1) { 2882 Step headerStep = new Step(false, Axis.NONE, headerVariable, null, null); 2884 expression4VariableBuffer.set(0, headerStep); 2885 ((Step) expression4VariableBuffer.get(1)).setHasSeparator(true); 2886 Variable lastVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new LocatedExpression(expression4VariableBuffer, arg.getParentModule()), Variable.NORM_CREATOR); 2888 newLEVariables.add(lastVar); 2889 newReturnExpr = lastVar; 2891 } else { newReturnExpr = headerVariable; 2893 } 2894 } else { 2895 Variable lastVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new LocatedExpression(expression4VariableBuffer, arg.getParentModule()), Variable.NORM_CREATOR); 2897 newLEVariables.add(lastVar); 2898 newReturnExpr = lastVar; 2900 } 2901 this.normalized = true; 2903 if (parentVar == null) { 2904 this.expr = new FLWRExpression(newLEVariables, null, newWhereExpr, newReturnExpr, arg.getParentModule()); 2905 this.expr.setParentModule(arg.getParentModule()); 2907 } else { 2908 FLWRExpression flwr = parentVar.getParentFLWRExpression(); 2909 if (!newLEVariables.isEmpty()) 2910 flwr.addVariables(flwr.getVarPosition(parentVar) + 1, newLEVariables); 2911 HashMap substituteMap = new HashMap(); 2912 substituteMap.put(parentVar, newReturnExpr); 2913 if (flwr.getWhereClause() != null) { 2914 if (flwr.getWhereClause().equals(parentVar)) 2915 flwr.setWhereClause(newReturnExpr); 2916 else 2917 flwr.getWhereClause().substitute(substituteMap, typeVisitor); 2918 } 2919 ArrayList tmpList = flwr.getOrderBy(); 2920 if (tmpList != null) 2921 for (int i = 0; i < tmpList.size(); i++) { 2922 XQueryExpression orderi = (XQueryExpression) tmpList.get(i); 2923 if (orderi.equals(parentVar)) 2924 tmpList.set(i, newReturnExpr); 2925 else 2926 orderi.substitute(substituteMap, typeVisitor); 2927 } 2928 if (flwr.getReturnClause().equals(parentVar)) 2929 flwr.setReturnClause(newReturnExpr); 2930 else 2931 flwr.getReturnClause().substitute(substituteMap, typeVisitor); 2932 flwr.addWhereClause(newWhereExpr); 2933 this.expr = parentVar.getExpression(); 2934 } 2935 } else { 2984 ler.reset(arg, typeVisitor); 3025 if (ler.reduceLocatedExpression(arg.getParentModule())) { 3026 this.expr = ler.getReducedExpression(); 3027 this.normalized = true; 3028 if (this.expr != null) { 3029 this.expr.setParenthesis(parenthesis); 3032 if (reType) 3033 this.expr.accept(typeVisitor); 3034 } 3035 } else { 3036 this.expr = arg; 3037 } 3038 if ((newVar4LE_Predicate != null) && (this.expr instanceof LocatedExpression)) { 3043 localCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE, newVar4LE_Predicate, true); 3046 ArrayList newSteps = ((LocatedExpression) this.expr).getSteps(); 3048 Step firstStep = (Step) newSteps.get(0); 3050 if (!firstStep.hasSeparator() && (firstStep.getAxis() != Axis.NONE)) { 3051 this.normalized = true; 3056 Step newFirstStep = new Step(false, Axis.NONE, newVar4LE_Predicate, null, null); 3057 firstStep.setHasSeparator(true); 3058 this.expr.setContext(false); 3060 boolean isSelfNode = false; 3062 if ((newSteps.size() >= 2) && (firstStep != null) && (firstStep.getPredicates() == null) && (firstStep.getAxis() == Axis.SELF)) { 3063 XQueryExpression test = firstStep.getExpression(); 3064 if ((test != null) && (test instanceof NodeTest) && (((NodeTest) test).getKind() == NodeKind.NODE)) { 3065 isSelfNode = true; 3066 } 3067 } 3068 if (isSelfNode) { 3069 newSteps.set(0, newFirstStep); 3070 } else { 3071 newSteps.add(0, newFirstStep); 3072 } 3073 } 3074 if (reType) 3076 this.expr.accept(typeVisitor); 3077 } 3078 3080 else { 3081 3090 int parentIndex = arg.hasParentStep(); 3091 if (parentIndex != -1 && arg.startsWithVariable()) { 3092 XQueryExpression argParent = (XQueryExpression) arg.getParentExpression().get(0); 3093 if (parentIndex != 1 && arg.getStepNum(parentIndex - 1).getAxis() != Axis.DESCENDANT_OR_SELF) 3095 throw new NormalizeException("Could not normalize located expression with parent::node : " + arg); 3096 Variable var = (Variable) arg.getExpression(); 3098 if (!(var.getExpression() instanceof LocatedExpression)) 3100 throw new NormalizeException("Could not normalize located expression with parent::node : " + arg); 3101 FLWRExpression parentflwr = var.getParentFLWRExpression(); 3103 if (!(argParent instanceof Variable) || parentflwr != ((Variable) argParent).getParentFLWRExpression()) { 3105 Variable newVar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.NORM_CREATOR); 3108 HashMap substituteMap = new HashMap(); 3109 substituteMap.put(arg, newVar); 3110 parentflwr.substitute(substituteMap, typeVisitor); 3111 parentflwr.addVariable(parentflwr.getVarPosition(var) + 1, newVar); 3112 this.normalized = true; 3113 this.expr = newVar; 3114 } else { 3115 Variable varParent = (Variable) argParent; 3117 LocatedExpression varLoc = (LocatedExpression) var.getExpression(); 3119 ArrayList varLocSteps = varLoc.getSteps(); 3121 Step lastStep = varLoc.getStepNum(varLocSteps.size() - 1); 3122 if (lastStep.getAxis() != Axis.CHILD && lastStep.getAxis() != Axis.DESCENDANT_OR_SELF) 3123 throw new NormalizeException("Could not normalize located expression with parent::node : " + arg); 3124 int varPos = parentflwr.getVarPosition(var); 3125 if (parentIndex == 1) { 3127 if (parentIndex == steps.size() - 1) { 3129 parentflwr.getVariables().remove(varPos); 3131 parentflwr.addVariable(parentflwr.getVarPosition(varParent) + 1, var); 3132 arg.getSteps().remove(0); 3134 arg.getSteps().addAll(0, varLocSteps); 3135 this.expr = arg; 3136 int retValue = LocatedExpressionReducer.simplifySteps(arg.getSteps(), false, arg.getParentModule()); 3138 if (retValue == 0) 3139 throw new NormalizeException("Could not normalize located expression with parent::node : " + arg); 3140 ArrayList newSteps = new ArrayList(2); 3142 newSteps.add(new Step(false, Axis.NONE, varParent, null, null)); 3143 newSteps.add(new Step(true, Axis.CHILD, lastStep.getExpression(), null, null)); 3144 varLoc.setSteps(newSteps); 3145 } else { List xp3 = steps.subList(parentIndex + 1, steps.size()); 3148 List xp2pn = steps.subList(1, parentIndex + 1); 3149 arg.setSteps((ArrayList) varLocSteps.clone()); 3150 arg.getSteps().addAll(xp2pn); 3151 int retValue = LocatedExpressionReducer.simplifySteps(arg.getSteps(), false, arg.getParentModule()); 3153 if (retValue == 0) 3154 throw new NormalizeException("Could not normalize located expression with parent::node : " + arg); 3155 Variable newVar = typeVisitor.getStaticContext().createVariable(var.getBindingType(), arg, Variable.NORM_CREATOR); 3156 parentflwr.addVariable(varPos, newVar); 3157 Step newVarStep = new Step(false, Axis.NONE, newVar, null, null); 3161 ArrayList newSteps = new ArrayList(2); 3162 newSteps.add(newVarStep); 3163 newSteps.add(new Step(true, Axis.CHILD, lastStep.getExpression(), null, null)); 3164 varLoc.setSteps(newSteps); 3165 newSteps = new ArrayList(); 3167 newSteps.add(newVarStep.clone()); 3168 newSteps.addAll(xp3); 3169 this.expr = new LocatedExpression(newSteps, arg.getParentModule()); 3171 } 3172 } else { 3173 3176 if (parentIndex == steps.size() - 1) { 3177 ArrayList newSteps = new ArrayList(); 3179 for (int i = 0; i < parentIndex - 1; i++) 3180 newSteps.add(((Step) steps.get(i)).clone()); 3181 newSteps.add(steps.get(parentIndex)); 3182 LocatedExpression locParent = new LocatedExpression(newSteps, false, arg.getParentModule()); 3183 newSteps = new ArrayList(); 3184 for (int i = 0; i < parentIndex - 1; i++) 3185 newSteps.add(steps.get(i)); 3186 newSteps.add(steps.get(parentIndex - 1)); 3187 LocatedExpression locDosNode = new LocatedExpression(newSteps, false, arg.getParentModule()); 3188 this.expr = new ListOpUNIONExpression(locParent, locDosNode, arg.getParentModule()); 3189 newSteps = new ArrayList(2); 3191 newSteps.add(new Step(false, Axis.NONE, varParent, null, null)); 3192 newSteps.add(new Step(true, Axis.CHILD, new NodeTest(NodeKind.NODE, null, null), null, null)); 3193 parentflwr.addWhereClause(new LocatedExpression(newSteps, false, arg.getParentModule(), false)); 3194 } else { 3195 ArrayList newSteps = new ArrayList(); 3197 for (int i = 0; i < parentIndex - 1; i++) 3198 newSteps.add(((Step) steps.get(i)).clone()); 3199 newSteps.add(steps.get(parentIndex)); 3200 LocatedExpression locParent = new LocatedExpression(newSteps, false, arg.getParentModule()); 3201 newSteps = new ArrayList(); 3202 for (int i = 0; i < parentIndex - 1; i++) 3203 newSteps.add(steps.get(i)); 3204 newSteps.add(steps.get(parentIndex - 1)); 3205 LocatedExpression locDosNode = new LocatedExpression(newSteps, false, arg.getParentModule()); 3206 XQueryExpression newVarExpr = new ListOpUNIONExpression(locParent, locDosNode, arg.getParentModule()); 3207 Variable newVar = typeVisitor.getStaticContext().createVariable(varParent.getBindingType(), newVarExpr, Variable.NORM_CREATOR); 3208 parentflwr.addVariable(parentflwr.getVarPosition(varParent), newVar); 3209 newSteps = new ArrayList(); 3211 newSteps.add(new Step(false, Axis.NONE, newVar, null, null)); 3212 newSteps.addAll(steps.subList(parentIndex + 1, steps.size())); 3213 this.expr = new LocatedExpression(newSteps, false, arg.getParentModule()); 3214 newSteps = new ArrayList(2); 3216 newSteps.add(new Step(false, Axis.NONE, newVar, null, null)); 3217 newSteps.add(new Step(true, Axis.CHILD, new NodeTest(NodeKind.NODE, null, null), null, null)); 3218 parentflwr.addWhereClause(new LocatedExpression(newSteps, false, arg.getParentModule(), false)); 3219 } 3220 3224 3225 3228 } 3229 this.normalized = true; 3230 } 3231 } 3232 } 3233 3234 if ((this.expr != null) && (this.expr instanceof LocatedExpression) && (localCtx.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION))) { 3236 this.normalized = true; 3238 boolean parenthesis2 = this.expr.getParenthesis(); 3241 this.expr.setParenthesis(false); 3244 ArrayList parameter = new ArrayList(); 3245 parameter.add(this.expr); 3246 this.expr = new FunctionEXISTS(parameter, arg.getParentModule()); 3247 this.expr.setParenthesis(parenthesis2); 3250 } 3251 } 3252 3255 localCtx.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 3256 3257 this.context.update(localCtx); 3259 } catch (CloneNotSupportedException e) { 3261 throw new NormalizeException(0, e.getMessage(), e); 3262 } catch (XQueryException e) { 3263 throw new NormalizeException(0, e.getMessage()); 3264 } 3265 } 3266 3267 3281 public void visit(NodeTest arg) throws NormalizeException { 3282 try { 3283 this.expr = arg; 3286 boolean parenthesis = this.expr.getParenthesis(); 3290 if (this.context.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE)) { 3292 Variable newVar4LE_Predicate = (Variable) this.context.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 3294 this.normalized = true; 3296 ArrayList newSteps = new ArrayList(); 3297 Step firstStep = new Step(false, Axis.NONE, newVar4LE_Predicate, null, null); 3298 newSteps.add(firstStep); 3299 this.expr.setParenthesis(false); 3302 this.expr.setContext(false); 3304 Step secondStep = new Step(true, Axis.CHILD, this.expr, null, null); 3305 newSteps.add(secondStep); 3306 LocatedExpression newLocated = new LocatedExpression(newSteps, arg.getParentModule()); 3307 this.expr = newLocated; 3308 if (this.context.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION)) { 3310 ArrayList parameter = new ArrayList(); 3312 parameter.add(this.expr); 3313 this.expr = new FunctionEXISTS(parameter, arg.getParentModule()); 3314 } 3315 this.expr.setParenthesis(parenthesis); 3318 } 3319 if (reType) 3321 this.expr.accept(typeVisitor); 3322 } catch (XQueryException e) { 3324 throw new NormalizeException(0, e); 3325 } 3326 } 3327 3328 3335 public void visit(QName arg) throws NormalizeException { 3336 try { 3337 this.expr = arg; 3340 boolean parenthesis = this.expr.getParenthesis(); 3344 if (this.context.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE)) { 3346 Variable newVar4LE_Predicate = (Variable) this.context.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 3348 this.normalized = true; 3350 ArrayList newSteps = new ArrayList(); 3351 Step firstStep = new Step(false, Axis.NONE, newVar4LE_Predicate, null, null); 3352 newSteps.add(firstStep); 3353 this.expr.setParenthesis(false); 3356 this.expr.setContext(false); 3358 Step secondStep = new Step(true, Axis.CHILD, this.expr, null, null); 3359 newSteps.add(secondStep); 3360 LocatedExpression newLocated = new LocatedExpression(newSteps, arg.getParentModule()); 3361 this.expr = newLocated; 3362 if (this.context.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION)) { 3364 ArrayList parameter = new ArrayList(); 3366 parameter.add(this.expr); 3367 this.expr = new FunctionEXISTS(parameter, arg.getParentModule()); 3368 } 3369 this.expr.setParenthesis(parenthesis); 3372 } 3373 3377 } catch (XQueryException e) { 3379 throw new NormalizeException(0, e); 3380 } 3381 } 3382 3383 3390 public void visit(SequenceType arg) throws NormalizeException { 3391 try { 3392 throw new NormalizeException(0, "SequenceTypeExpression not supported : (" + arg + ")"); 3394 3397 } catch (XQueryException e) { 3398 throw new NormalizeException(0, e); 3399 } 3400 } 3401 3402 3415 public void visit(SortedExpression arg) throws NormalizeException { 3416 try { 3417 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 3419 VisitorContext localCtx = new VisitorContext(); 3420 localCtx.merge(this.context, false); 3421 localCtx.filter(this.depth); 3423 recurseVisitor.setContext(localCtx); 3424 XQueryExpression exprSeq = arg.getExpression(); 3426 exprSeq.accept(recurseVisitor); 3427 localCtx.update(recurseVisitor.getContext()); 3428 exprSeq = recurseVisitor.getExpr(); 3429 this.normalized = recurseVisitor.wasNormalized(); 3431 if (recurseVisitor.wasNormalized()) { 3432 if (exprSeq != null) { 3433 arg.setExpression(exprSeq); 3434 } else { 3435 arg = null; 3436 } 3437 } 3438 if (arg != null) { 3439 ArrayList sortClauses = arg.getSortClauses(); 3441 if ((sortClauses != null) && (sortClauses.size() != 0)) { 3442 int sortClauseLen = sortClauses.size(); 3444 XQueryExpression aClause = null; 3445 for (int i = sortClauseLen - 1; i >= 0; i--) { 3446 int[] direction = ((XQueryExpression) sortClauses.get(i)).getOrder(); 3448 ((XQueryExpression) sortClauses.get(i)).accept(recurseVisitor); 3450 localCtx.update(recurseVisitor.getContext()); 3451 aClause = recurseVisitor.getExpr(); 3452 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 3454 if (recurseVisitor.wasNormalized()) { 3455 aClause = recurseVisitor.getExpr(); 3456 if (aClause != null) { 3457 aClause.setOrder(direction); 3458 sortClauses.set(i, aClause); 3459 } else { 3460 sortClauses.remove(i); 3461 } 3462 } 3463 } 3464 if (sortClauses.size() == 0) { 3465 this.expr = exprSeq; 3466 } else { 3467 arg.setSortClauses(sortClauses); 3468 this.expr = arg; 3469 } 3470 } else { 3471 this.expr = exprSeq; 3472 } 3473 if (reType && this.normalized && this.expr != null) { 3475 this.expr.accept(typeVisitor); 3476 } 3477 } else { 3478 this.expr = null; 3479 } 3480 this.context.update(localCtx); 3482 } catch (XQueryException e) { 3484 throw new NormalizeException(0, e); 3485 } 3486 } 3487 3488 3503 public void visit(Step arg) throws NormalizeException { 3504 try { 3505 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 3507 VisitorContext localCtx = new VisitorContext(); 3508 localCtx.merge(this.context, false); 3509 localCtx.filter(this.depth); 3511 recurseVisitor.setContext(localCtx); 3512 XQueryExpression subExpr = arg.getExpression(); 3524 subExpr.accept(recurseVisitor); 3525 localCtx.update(recurseVisitor.getContext()); 3526 subExpr = recurseVisitor.getExpr(); 3527 this.normalized = recurseVisitor.wasNormalized(); 3529 if (recurseVisitor.wasNormalized()) { 3530 if (subExpr != null) { 3531 arg.setExpression(subExpr); 3532 } else { 3533 arg = null; 3534 } 3535 } 3536 ArrayList expression4VariableBuffer = (ArrayList) localCtx.getMemo(this.depth, VisitorContext._STEP_GETPREDICATE); 3539 localCtx.setMemo(this.depth, VisitorContext._STEP_GETPREDICATE, null, true); 3540 if (arg != null) { 3541 ArrayList predicates = arg.getPredicates(); 3543 if ((predicates != null) && (predicates.size() > 0)) { 3544 Variable newVar = null; 3547 if (expression4VariableBuffer != null) { 3548 newVar = (Variable) localCtx.getMemo(this.depth, VisitorContext._STEP_GETPREDICATE_VAR); 3549 arg.setPredicates(null); 3551 expression4VariableBuffer.add(arg); 3552 if (expression4VariableBuffer.get(0) instanceof Variable) { 3553 Variable headerVariable = (Variable) expression4VariableBuffer.get(0); 3554 Step headerStep = new Step(false, Axis.NONE, headerVariable, null, null); 3555 expression4VariableBuffer.set(0, headerStep); 3556 } 3557 if (newVar == null) { 3558 if (expression4VariableBuffer.size() == 1) 3561 newVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, ((Step) expression4VariableBuffer.get(0)).getExpression(), Variable.NORM_CREATOR); 3562 else 3563 newVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new LocatedExpression(expression4VariableBuffer, arg.getParentModule()), Variable.NORM_CREATOR); 3564 } else { 3565 if (expression4VariableBuffer.size() == 1) 3566 newVar.setExpression(((Step) expression4VariableBuffer.get(0)).getExpression(), true); 3567 else 3568 newVar.setExpression(new LocatedExpression(expression4VariableBuffer, arg.getParentModule()), true); 3569 } 3570 localCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE, newVar, true); 3571 } 3572 3573 3577 int predicatesLen = predicates.size(); 3579 boolean eliminateThis = false; 3580 XQueryExpression lastPredicate = null; 3581 for (int i = predicatesLen - 1; (i >= 0) && (arg != null); i--) { 3582 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 3584 ((XQueryExpression) predicates.get(i)).accept(recurseVisitor); 3586 localCtx.update(recurseVisitor.getContext()); 3587 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 3589 if (recurseVisitor.getExpr() != null) { 3590 XQueryExpression aPredicate = recurseVisitor.getExpr(); 3591 if (aPredicate instanceof FunctionTRUE) { 3593 this.normalized = true; 3595 aPredicate = null; 3596 } else if (aPredicate instanceof FunctionFALSE) { 3597 this.normalized = true; 3599 arg = null; 3600 } else if (aPredicate instanceof XQueryExpressionSequence) { 3601 int size = ((XQueryExpressionSequence) aPredicate).getSubExpressions().size(); 3603 this.normalized = true; 3604 if (size == 0) { 3605 arg = null; } else { 3607 aPredicate = null; 3608 } 3610 } 3611 if (arg != null) { 3613 if (aPredicate != null) { 3614 if (!(aPredicate instanceof XQueryExpressionSequence)) { 3616 aPredicate.setParenthesis(true); 3617 } 3618 if ((predicatesLen >= 2) && (lastPredicate != null)) { 3619 this.normalized = true; 3620 lastPredicate = new BinOpANDExpression(aPredicate, lastPredicate, arg.getParentModule()); 3621 } else { 3622 lastPredicate = aPredicate; 3623 } 3624 } 3625 } 3626 } else { 3627 this.normalized = true; 3628 arg = null; 3629 } 3630 } localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 3633 if (arg != null) { 3634 if (lastPredicate != null) { 3635 ArrayList variableAndPredicate = new ArrayList(); 3637 variableAndPredicate.add(newVar); 3638 variableAndPredicate.add(lastPredicate); 3639 localCtx.setMemo(this.depth, VisitorContext._STEP_GETPREDICATE, variableAndPredicate, true); 3640 this.normalized = true; 3642 } 3643 arg.setPredicates(null); 3644 } 3645 } 3646 if (localCtx.existsMemo(this.depth, VisitorContext._STEP_GETPREDICATE)) { 3649 localCtx.removeMemo(VisitorContext._ANY_DEPTH, VisitorContext._LOCATEDEXPRESSION_INPREDICATE); 3650 } 3651 } 3652 this.expr = arg; 3653 if (this.expr != null) { 3655 if ((localCtx.existsMemo(this.depth, VisitorContext._STEP_ISPARENTAXISSTEP)) && (this.expr instanceof Step) && (((Step) this.expr).getAxis() == Axis.PARENT)) { 3658 localCtx.setMemo(this.depth, VisitorContext._STEP_ISPARENTAXISSTEP, Boolean.TRUE, true); 3659 } 3660 } 3661 if (reType && this.normalized && this.expr != null) { 3663 this.expr.accept(typeVisitor); 3664 } 3665 this.context.update(localCtx); 3668 } catch (XQueryException e) { 3670 throw new NormalizeException(0, e); 3671 } 3672 } 3673 3674 3688 public void visit(Variable arg) throws NormalizeException { 3689 try { 3690 if (arg.getBindingType() == Constants.DECLARATION_BINDINGTYPE) { 3692 if (arg.getExpression() != null) { 3693 this.expr = arg.getExpression(); 3694 this.normalized = true; 3695 } 3696 return; 3697 } 3698 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 3699 VisitorContext localCtx = new VisitorContext(); 3700 localCtx.merge(this.context, false); 3701 localCtx.filter(this.depth); 3704 recurseVisitor.setContext(localCtx); 3705 if (localCtx.existsMemo(this.depth, VisitorContext._VARIABLE_DECLARATION)) { 3707 (arg.getExpression()).accept(recurseVisitor); 3708 localCtx.update(recurseVisitor.getContext()); 3709 if (recurseVisitor.getExpr() != null) { 3710 arg.setExpression(recurseVisitor.getExpr(), true); 3711 } else { 3712 arg = null; 3713 } 3714 this.normalized = recurseVisitor.wasNormalized(); 3716 } 3717 this.expr = arg; 3718 if (this.expr != null) { 3720 3723 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_CHANGEEXPRESSION4FLWR)) { 3726 Variable changeExpr = (Variable) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_CHANGEEXPRESSION4FLWR); 3727 if (changeExpr.getVarName().equals(arg.getVarName())) { 3728 arg.setExpression((XQueryExpression) changeExpr.getExpression().clone(), true); 3732 this.expr = arg; 3733 this.normalized = true; 3735 } 3736 3737 } 3738 HashMap substVariables = null; 3739 if (this.expr != null) { 3742 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR)) { 3743 substVariables = (HashMap) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4FLWR); 3744 if (substVariables.containsKey(arg.getVarName())) { 3745 XQueryExpression substExpr = (XQueryExpression) substVariables.get(arg.getVarName()); 3746 if (substExpr != null) { 3748 this.expr = (XQueryExpression) substExpr.clone(); 3750 } else { this.expr = null; 3752 } 3753 this.normalized = true; 3755 } 3756 } 3757 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR)) { 3758 substVariables = (HashMap) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4LETFLWR); 3759 if (substVariables.containsKey(arg.getVarName())) { 3760 XQueryExpression substExpr = (XQueryExpression) substVariables.get(arg.getVarName()); 3761 if (substExpr != null) { 3764 this.expr = (XQueryExpression) substExpr.clone(); 3766 this.normalized = true; 3771 if (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_WASSUBSTITUTELETFLWR)) { 3773 localCtx.setMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_WASSUBSTITUTELETFLWR, Boolean.TRUE, true); 3774 } 3775 } else if (substExpr == null) { 3776 this.expr = null; 3777 this.normalized = true; 3779 } 3780 } 3781 3782 } 3783 } 3784 if ((this.expr != null) && (localCtx.existsMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED))) { 3787 substVariables = (HashMap) localCtx.getMemo(VisitorContext._ANY_DEPTH, VisitorContext._VARIABLE_SUBSTITUTION4QUANTIFIED); 3788 if (substVariables.containsKey(arg.getVarName())) { 3790 XQueryExpression substExpr = (XQueryExpression) substVariables.get(arg.getVarName()); 3791 if (substExpr != null) { 3793 this.expr = (XQueryExpression) substExpr.clone(); 3795 } else { this.expr = null; 3797 } 3798 this.normalized = true; 3800 } 3801 } 3802 } 3803 if ((this.expr != null) && (localCtx.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION))) { 3805 this.normalized = true; 3806 boolean parenthesis = this.expr.getParenthesis(); 3809 this.expr.setParenthesis(false); 3812 ArrayList parameter = new ArrayList(); 3813 parameter.add(this.expr); 3814 this.expr = new FunctionEXISTS(parameter, arg.getParentModule()); 3815 this.expr.setParenthesis(parenthesis); 3818 } 3819 if (reType && this.normalized && this.expr != null) { 3821 this.expr.accept(typeVisitor); 3822 } 3823 this.context.update(localCtx); 3825 } catch (CloneNotSupportedException e) { 3828 throw new NormalizeException(0, e); 3829 } catch (XQueryException e) { 3830 throw new NormalizeException(0, e); 3831 } 3832 } 3833 3834 3860 public void visit(XQueryExpressionSequence arg) throws NormalizeException { 3861 try { 3862 ExpressionNormalizationVisitor recurseVisitor = new ExpressionNormalizationVisitor(this.depth, typeVisitor, sourceName); 3864 VisitorContext localCtx = new VisitorContext(); 3865 localCtx.merge(this.context, false); 3867 localCtx.filter(this.depth); 3869 recurseVisitor.setContext(localCtx); 3872 ArrayList expressions = arg.getSubExpressions(); 3874 boolean isASequence = true; 3876 while ((expressions != null) && (expressions.size() == 1) && (expressions.get(0) instanceof XQueryExpressionSequence)) { 3878 arg = (XQueryExpressionSequence) expressions.get(0); 3880 expressions = arg.getSubExpressions(); 3881 this.normalized = true; 3884 } 3885 if (expressions.size() > 1) { 3888 Object [] childExpr = expressions.toArray(); 3889 ArrayList subExprTmp; 3890 expressions.clear(); 3891 for (int i = 0; i < childExpr.length; i++) { 3892 if (childExpr[i] instanceof XQueryExpressionSequence) { 3893 subExprTmp = ((XQueryExpressionSequence) childExpr[i]).getSubExpressions(); 3895 for (int j = 0; j < subExprTmp.size(); j++) { 3897 expressions.add(subExprTmp.get(j)); 3898 } 3899 this.normalized = true; 3901 } else if (!(childExpr[i] instanceof XQueryVoid)) { 3902 expressions.add(childExpr[i]); 3904 } } 3906 } 3907 ArrayList childNormalizedExpr = new ArrayList(); 3909 boolean mustBeInExistsFunction = false; 3911 if (localCtx.existsMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION)) { 3912 localCtx.removeMemo(this.depth, VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 3913 mustBeInExistsFunction = true; 3914 } 3915 for (int i = 0; i < expressions.size(); i++) { 3917 if (mustBeInExistsFunction) { 3919 localCtx.setMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION, null, true); 3920 } 3921 ((XQueryExpression) expressions.get(i)).accept(recurseVisitor); 3922 localCtx.update(recurseVisitor.getContext()); 3923 if (recurseVisitor.getExpr() != null) { 3924 childNormalizedExpr.add(recurseVisitor.getExpr()); 3925 } 3926 this.normalized = this.normalized | recurseVisitor.wasNormalized(); 3928 } 3929 localCtx.removeMemo((this.depth + 1), VisitorContext._MULTIVALUED_NEEDEXISTSFUNCTION); 3931 if ((childNormalizedExpr.size() == 1) 3933 && (childNormalizedExpr.get(0) instanceof Element)) { 3934 this.expr = (XQueryExpression) childNormalizedExpr.get(0); 3936 isASequence = false; 3937 this.normalized = true; 3939 } else if ((childNormalizedExpr.size() == 1) && (arg.getParenthesis()) && (this.depth == 1)) { 3940 this.expr = (XQueryExpression) childNormalizedExpr.get(0); 3943 isASequence = false; 3944 this.normalized = true; 3946 } else { 3947 if (this.normalized) { 3949 if (childNormalizedExpr.size() == 0) { 3950 expr = null; 3951 } else if (childNormalizedExpr.size() == 1) { 3952 expr = (XQueryExpression) childNormalizedExpr.get(0); 3953 } else { 3954 expr = new XQueryExpressionSequence(childNormalizedExpr, arg.getParentModule()); 3956 } 3957 } else 3958 this.expr = arg; 3959 } 3960 if (this.expr != null) { 3962 if ((this.expr instanceof XQueryExpressionSequence) && (localCtx.existsMemo(this.depth, VisitorContext._INCLUDEINPARENTHESIS))) { 3974 ArrayList subExpr = ((XQueryExpressionSequence) this.expr).getSubExpressions(); 3975 if (subExpr.size() == 1) { 3976 this.expr = (XQueryExpression) subExpr.get(0); 3977 } 3978 } 3979 3980 } 3981 if (this.expr != null) { 3983 if (reType && this.normalized) { 3985 this.expr.accept(typeVisitor); 3986 } 3987 if ((localCtx.existsMemo(this.depth, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS)) && (this.expr instanceof XQueryExpressionSequence)) { 3990 int sequenceSize = ((XQueryExpressionSequence) this.expr).getSubExpressions().size(); 3991 localCtx.setMemo(this.depth, VisitorContext._XQUERYEXPRESSIONSEQUENCE_EXISTS, new Integer (sequenceSize), true); 3992 } 3993 } 3994 this.context.update(localCtx); 3996 } catch (XQueryException e) { 3997 throw new NormalizeException(0, e); 3998 } 3999 } 4000 4001 4008 public void visit(XQueryVoid arg) throws NormalizeException { 4009 this.expr = null; 4010 } 4011} | Popular Tags |