1 23 24 package org.xquark.xquery.normalize; 25 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Stack ; 29 30 import org.xquark.xpath.Axis; 31 import org.xquark.xpath.NodeKind; 32 import org.xquark.xquery.parser.*; 33 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*; 34 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.FunctionQNAME; 35 import org.xquark.xquery.parser.util.Constants; 36 import org.xquark.xquery.typing.QType; 37 import org.xquark.xquery.typing.TypeException; 38 import org.xquark.xquery.typing.TypeVisitor; 39 40 44 public class RestructureVisitor extends DefaultParserVisitor { 45 46 private static final String RCSRevision = "$Revision: 1.10 $"; 47 private static final String RCSName = "$Name: $"; 48 49 private XQueryExpression resultExpr = null; 50 private TypeVisitor typeVisitor = null; 51 52 private final Integer NO_CONTEXT = new Integer (0); 53 private final Integer IN_RETURN = new Integer (1); 54 private final Integer IN_WHERE = new Integer (2); 55 private final Integer IN_FUNCTION = new Integer (3); 56 private final Integer IN_FLWR = new Integer (4); 57 58 private Stack contextStack = new Stack (); 59 private Stack inWhereExpressionStack = new Stack (); 60 private Stack parentFLWRExpressionStack = new Stack (); 61 private Stack varDefinitionStack = new Stack (); 62 private int inReturn = 0; 63 64 private int ruleNumber = 0; 65 private boolean isMediator = false; 66 private boolean isRoot = true; 67 68 private final int[] initOrder = { -1, -1 }; 69 70 public RestructureVisitor(TypeVisitor typeVisitor) { 71 this.typeVisitor = typeVisitor; 72 } 73 74 public RestructureVisitor(TypeVisitor typeVisitor, boolean isMediator) { 75 this.typeVisitor = typeVisitor; 76 this.isMediator = isMediator; 77 } 78 79 public XQueryExpression getResult() { 80 return resultExpr; 81 } 82 public int getRuleNumber() { 83 return ruleNumber; 84 } 85 86 public void visit(ComputedText arg) throws XQueryException { 87 if (isRoot) { 88 makeDummyOneFlwr(arg); 89 return; 90 } 91 XQueryExpression tmpExpr = arg.getExpression(); 92 tmpExpr.accept(this); 93 if (resultExpr != null) { 94 arg.setExpression(resultExpr); 96 } 97 resultExpr = null; 98 } 99 100 public void visit(Document arg) throws XQueryException { 101 if (isRoot) { 102 makeDummyOneFlwr(arg); 103 return; 104 } 105 XQueryExpression tmpExpr = arg.getExpression(); 106 tmpExpr.accept(this); 107 if (resultExpr != null) { 108 arg.setExpression(resultExpr); 110 } 111 resultExpr = null; 112 } 113 114 120 public void visit(Element arg) throws XQueryException { 121 if (isRoot) { 123 makeDummyOneFlwr(arg); 124 return; 125 } 126 ArrayList subExpressions = arg.getSubExpressions(); 129 if (subExpressions != null) { 130 byte nbAtt = 0; 131 byte nbNS = 0; 132 for (int i = 0; i < subExpressions.size(); i++) { 133 XQueryExpression expri = (XQueryExpression) subExpressions.get(i); 134 if (expri instanceof ComputedNamespace) { 135 if (i > nbNS) { 136 subExpressions.remove(i); 137 subExpressions.add(nbNS, expri); 138 } 139 nbNS++; 140 } else if (expri instanceof AttributeValuePair) { 141 subExpressions.remove(i); 142 arg.addAttributes((AttributeValuePair) expri); 143 } else if (expri.getQType().getSubClass() == QType.ATTRIBUTE) { 144 if (i > nbNS + nbAtt) { 145 subExpressions.remove(i); 146 subExpressions.add(nbNS + nbAtt, expri); 147 } 148 nbAtt++; 149 } 150 } 151 arg.setComputedAttNum(nbAtt); 152 arg.setComputedNSNum(nbNS); 153 } 154 arg.getStartTag().accept(this); 156 if (resultExpr != null) 157 arg.setStartTag(resultExpr); 158 if (arg.getAttributes() != null) { 159 ArrayList newAttributes = new ArrayList (arg.getAttributes().size()); 160 for (int i = 0; i < arg.getAttributes().size(); i++) { 161 AttributeValuePair expri = (AttributeValuePair) arg.getAttributes().get(i); 162 expri.accept(this); 163 if (resultExpr != null) 164 newAttributes.add(resultExpr); 165 else 166 newAttributes.add(expri); 167 } 168 arg.setAttributes(newAttributes); 169 } 170 if (subExpressions != null) { 171 ArrayList newSubExpressions = new ArrayList (subExpressions.size()); 172 for (int i = 0; i < subExpressions.size(); i++) { 173 XQueryExpression expri = (XQueryExpression) subExpressions.get(i); 174 expri.accept(this); 175 if (resultExpr != null) 176 newSubExpressions.add(resultExpr); 177 else 178 newSubExpressions.add(expri); 179 } 180 arg.setSubExpressions(newSubExpressions); 181 } 182 resultExpr = null; 200 } 201 202 213 public void visit(FLWRExpression arg) throws XQueryException { 214 if (isRoot) { 215 isRoot = false; 216 } 217 220 XQueryExpression returnClause = arg.getReturnClause(); 221 XQueryExpression whereClause = arg.getWhereClause(); 222 while (returnClause instanceof FLWRExpression) { 235 ArrayList orderBys = ((FLWRExpression) returnClause).getOrderBy(); 236 if (orderBys == null || orderBys.isEmpty()) { 237 ArrayList vars = ((FLWRExpression) returnClause).getVariables(); 238 for (int i = 0; i < vars.size(); i++) 239 arg.addVariable((Variable) vars.get(i)); 240 if (whereClause == null) 241 arg.setWhereClause(((FLWRExpression) returnClause).getWhereClause()); 242 else 243 arg.addWhereClause(((FLWRExpression) returnClause).getWhereClause()); 244 arg.setReturnClause(((FLWRExpression) returnClause).getReturnClause()); 245 returnClause = arg.getReturnClause(); 246 } else 247 break; 248 } 249 if (!(returnClause instanceof XQueryExpressionSequence) && !(returnClause instanceof LocatedExpression) && !(returnClause instanceof Variable) && !(returnClause instanceof Element) && !(returnClause instanceof ITEExpression) && !(returnClause instanceof SortedExpression) && !(returnClause instanceof XMLComment) && !(returnClause instanceof Document) && !(returnClause instanceof XMLProcessingInstruction) && !(returnClause instanceof FLWRExpression) && !(returnClause instanceof ComputedText) && !(returnClause instanceof AttributeValuePair)) { 251 Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, returnClause, Variable.RES_CREATOR); 252 arg.addVariable(var); 253 arg.setReturnClause(var); 254 returnClause = arg.getReturnClause(); 255 } 256 ArrayList variables = arg.getVariables(); 259 for (int j = 0; j < variables.size(); j++) { 260 Variable tmpVar = (Variable) variables.get(j); 261 if (tmpVar.getCreator() != Variable.RES_CREATOR && tmpVar.getBindingType() == Constants.FOR_BINDINGTYPE && !tmpVar.isInput() && tmpVar.getExpression().getQType().getOccurence() == QType.OCC_1_1 && (variables.size() != 1 || arg.getParentExpression() != null)) { 267 tmpVar.setBindingType(Constants.LET_BINDINGTYPE); 268 ruleNumber++; 269 } 270 contextStack.push(IN_FLWR); 271 parentFLWRExpressionStack.push(arg); 272 tmpVar.accept(this); 273 contextStack.pop(); 274 parentFLWRExpressionStack.pop(); 275 } 276 277 XQueryExpression tmpSubExpr = null; 278 variables = arg.getVariables(); 279 whereClause = arg.getWhereClause(); 280 returnClause = arg.getReturnClause(); 281 ArrayList orderBys = arg.getOrderBy(); 282 if (whereClause != null) { 284 parentFLWRExpressionStack.push(arg); 285 inWhereExpressionStack.push(arg); 286 contextStack.push(IN_WHERE); 287 whereClause.accept(this); 288 parentFLWRExpressionStack.pop(); 289 inWhereExpressionStack.pop(); 290 contextStack.pop(); 291 XQueryExpression tmpExpr = resultExpr; 292 if (tmpExpr != null) 293 arg.setWhereClause(tmpExpr); 294 } 295 boolean noloop = true; 297 for (int j = 0; j < variables.size(); j++) { 298 Variable tmpVar = (Variable) variables.get(j); 299 XQueryExpression tmpVarExpr = tmpVar.getExpression(); 300 int bindingtype = tmpVar.getBindingType(); 301 if (tmpVar.getCreator() != Variable.RES_CREATOR && (tmpVarExpr instanceof Value || (bindingtype == Constants.LET_BINDINGTYPE && !tmpVarExpr.getQType().isMultiple() && !(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()))) { 309 HashMap map = new HashMap (1); 312 map.put(tmpVar, tmpVarExpr); 313 for (int i = j + 1; i < variables.size(); i++) 315 ((Variable) variables.get(i)).getExpression().substitute(map, typeVisitor); 316 if (whereClause != null) { 318 if ((tmpSubExpr = (XQueryExpression) map.get(whereClause)) != null) 319 arg.setWhereClause(tmpSubExpr); 320 else 321 whereClause.substitute(map, typeVisitor); 322 } 323 if (orderBys != null) { 325 for (int i = 0; i < orderBys.size(); i++) { 326 XQueryExpression orderby = (XQueryExpression) orderBys.get(i); 327 if ((tmpSubExpr = (XQueryExpression) map.get(orderby)) != null) 328 orderBys.set(i, tmpSubExpr); 329 else 330 orderby.substitute(map, typeVisitor); 331 } 332 } 333 if ((tmpSubExpr = (XQueryExpression) map.get(returnClause)) != null) 335 arg.setReturnClause(tmpSubExpr); 336 else 337 returnClause.substitute(map, typeVisitor); 338 variables.remove(j); 339 j--; 340 } else if (bindingtype == Constants.FOR_BINDINGTYPE) 343 noloop = false; 344 } 345 if (variables.isEmpty()) { 347 Integer tmpInt = this.NO_CONTEXT; 348 if (!contextStack.isEmpty()) 349 tmpInt = (Integer ) contextStack.peek(); 350 if (whereClause != null) { 351 if (tmpInt == this.IN_FLWR) { 352 ((FLWRExpression) this.parentFLWRExpressionStack.peek()).addWhereClause(whereClause); 353 resultExpr = arg.getReturnClause(); 354 ruleNumber++; 355 } else { 356 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR); 358 var.isDummy(true); 359 ArrayList vars = new ArrayList (1); 360 vars.add(var); 361 resultExpr = new FLWRExpression(vars, null, whereClause, arg.getReturnClause(), arg.getParentModule()); 363 resultExpr.setParentModule(arg.getParentModule()); 364 isRoot = true; 365 ruleNumber++; 366 } 367 } else { 368 resultExpr = arg.getReturnClause(); 369 isRoot = true; 370 } 371 if (resultExpr != null) { 374 resultExpr.setParentExpressions(arg.getParentExpression()); 375 XQueryExpression tmpExpr = resultExpr; 376 resultExpr.accept(this); 377 if (resultExpr == null) 378 resultExpr = tmpExpr; 379 } 380 return; 381 } 382 if (noloop) { 384 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR); 385 var.isDummy(true); 386 arg.insertVariable(var); 387 } 388 389 ArrayList orderby = arg.getOrderBy(); 391 if (orderby != null) { 392 for (int i = 0; i < orderby.size(); i++) { 393 XQueryExpression orderi = (XQueryExpression) orderby.get(i); 394 if (orderi instanceof Variable || (orderi instanceof LocatedExpression && ((LocatedExpression) orderi).getExpression() instanceof Variable)) 399 continue; 400 Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, orderi, Variable.RES_CREATOR); 402 arg.addVariable(var); 403 orderby.set(i, var); 404 } 405 } 406 returnClause = arg.getReturnClause(); 409 inReturn++; 410 contextStack.push(IN_RETURN); 411 this.parentFLWRExpressionStack.push(arg); 413 returnClause.accept(this); 414 this.parentFLWRExpressionStack.pop(); 416 inReturn--; 417 contextStack.pop(); 418 XQueryExpression tmpExpr = resultExpr; 419 if (tmpExpr != null) 420 arg.setReturnClause(tmpExpr); 421 422 Integer tmpInt = this.NO_CONTEXT; 425 if (!contextStack.isEmpty()) 426 tmpInt = (Integer ) contextStack.peek(); 427 if (tmpInt == this.IN_FUNCTION) { 428 FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek(); 430 Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR); 431 if (varDefinitionStack.isEmpty()) { 432 lastflwr.addVariable(addvar); 433 } else { 434 Variable lastvar = (Variable) varDefinitionStack.peek(); 435 int prevpos = lastflwr.getVarPosition(lastvar); 436 if (prevpos != -1) 437 lastflwr.addVariable(prevpos, addvar); 438 else 439 lastflwr.addVariable(addvar); 440 } 441 resultExpr = addvar; 442 return; 443 } 444 445 if (isMediator) { 448 while (((Variable) arg.getVariables().get(0)).isDummy()) { 449 if (arg.getVariables().size() > 1) 450 arg.getVariables().remove(0); 451 else 452 break; 453 } 454 } 455 456 resultExpr = null; 458 } 459 460 public void visit(ListOpArithExpression arg) throws XQueryException { 461 if (isRoot) { 462 makeDummyOneFlwr(arg); 463 return; 464 } 465 if (!contextStack.isEmpty()) { 468 Integer tmpInt = (Integer ) contextStack.peek(); 469 if (tmpInt.equals(IN_RETURN)) { 470 XQueryExpression parent0Expr = (XQueryExpression) arg.getParentExpression().get(0); 471 if (!(parent0Expr instanceof Variable)) { 472 FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek(); 473 Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR); 474 if (varDefinitionStack.isEmpty()) { 475 lastflwr.addVariable(addvar); 476 } else { 477 Variable lastvar = (Variable) varDefinitionStack.peek(); 478 int prevpos = lastflwr.getVarPosition(lastvar); 479 if (prevpos != -1) 480 lastflwr.addVariable(prevpos, addvar); 481 else 482 lastflwr.addVariable(addvar); 483 } 484 resultExpr = addvar; 485 return; 486 } 487 } 488 } 489 contextStack.push(IN_FUNCTION); 490 XQueryExpression tmpExpr = arg.getExpression1(); 491 tmpExpr.accept(this); 492 if (resultExpr != null) { 493 arg.setExpression1(resultExpr); 494 } 495 tmpExpr = arg.getExpression2(); 496 tmpExpr.accept(this); 497 if (resultExpr != null) { 498 arg.setExpression2(resultExpr); 499 } 500 resultExpr = null; 501 contextStack.pop(); 502 } 503 504 public void visit(ITEExpression arg) throws XQueryException { 505 if (isRoot) { 506 throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree"); 507 } 508 if (contextStack.peek() != IN_RETURN) 509 throw new XQueryException(arg.getClass().getName() + " can only appear in a return clause"); 510 XQueryExpression ifExpr = arg.getIfExpression(); 513 while (ifExpr instanceof FunctionNOT) { 514 arg.setIfExpression(((FunctionNOT) ifExpr).getArgument(0)); 515 XQueryExpression expr = arg.getElseExpression(); 516 arg.setElseExpression(arg.getThenExpression()); 517 arg.setThenExpression(expr); 518 } 519 ifExpr = arg.getIfExpression(); 520 if (ifExpr instanceof FunctionEMPTY && ((FunctionEMPTY) ifExpr).getArgument(0).getQType().isMultiple()) { 521 ArrayList args = new ArrayList (1); 522 args.add(((FunctionEMPTY) ifExpr).getArgument(0)); 523 arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.EQ_COMPOP, arg.getParentModule())); 524 } else if (ifExpr instanceof FunctionEXISTS && ((FunctionEXISTS) ifExpr).getArgument(0).getQType().isMultiple()) { 525 ArrayList args = new ArrayList (1); 526 args.add(((FunctionEXISTS) ifExpr).getArgument(0)); 527 arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.NEQ_COMPOP, arg.getParentModule())); 528 } else { 529 QType qtype = ifExpr.getQType(); 530 if (qtype != null && qtype.isMultiple()) { 531 ArrayList args = new ArrayList (1); 532 args.add(ifExpr); 533 arg.setIfExpression(new ListOpCompExpression(new FunctionCOUNT(args, arg.getParentModule()), new ValueInteger("0", arg.getParentModule()), Constants.NEQ_COMPOP, arg.getParentModule())); 534 } 535 } 536 contextStack.push(IN_FUNCTION); 537 arg.getIfExpression().accept(this); 538 if (resultExpr != null) { 539 arg.setIfExpression(resultExpr); 540 } 541 contextStack.pop(); 550 resultExpr = arg; 551 } 552 553 559 public void visit(LocatedExpression arg) throws XQueryException { 560 if (isRoot) { 561 makeDummyFlwr(arg); 562 return; 563 } 564 resultExpr = null; 565 ArrayList parents = arg.getParentExpression(); 567 boolean noParents = false; 568 if (parents == null || parents.isEmpty()) 569 noParents = true; 570 if (noParents || (XQueryExpression) parents.get(0) instanceof SortedExpression) { 572 if (arg.getQType() != null && arg.getQType().isMultiple() && !(arg.getExpression() instanceof Variable)) { 573 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR); 574 ArrayList varlist = new ArrayList (1); 575 varlist.add(var); 576 FLWRExpression tmpFLWR = new FLWRExpression(varlist, null, null, var, arg.getParentModule()); 577 tmpFLWR.setParentModule(arg.getParentModule()); 578 resultExpr = tmpFLWR; 579 ruleNumber++; 580 } 581 } 582 else if (!noParents && !parentFLWRExpressionStack.isEmpty() && !((XQueryExpression) parents.get(0) instanceof FunctionCall) && !((XQueryExpression) parents.get(0) instanceof Variable) && arg.getExpression() instanceof InputFunctionCall) { 585 Variable var = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR); 586 FLWRExpression parentflwr = (FLWRExpression) parentFLWRExpressionStack.peek(); 587 parentflwr.addVariable(var); 588 resultExpr = var; 589 } 590 else if (!contextStack.isEmpty()) { 593 Integer tmpInt = (Integer ) contextStack.peek(); 594 if (tmpInt.equals(IN_RETURN)) { 595 QType qtype = arg.getQType(); 597 if (qtype != null && qtype.isMultiple() && (!(arg.getExpression() instanceof Variable) || arg.getExpression().getQType().isMultiple()) && (noParents || !(parents.get(0) instanceof Variable))) { 598 Variable tmpVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR); 599 ArrayList vars = new ArrayList (1); 600 vars.add(tmpVar); 601 FLWRExpression tmpFLWR = new FLWRExpression(vars, null, tmpVar, arg.getParentModule()); 602 tmpFLWR.setParentModule(arg.getParentModule()); 603 resultExpr = tmpFLWR; 604 ruleNumber++; 605 } 606 } 607 } 608 609 } 610 611 615 public void visit(PrimitiveFunctionCall arg) throws XQueryException { 616 if (isRoot) { 617 makeDummyFlwr(arg); 618 return; 619 } 620 resultExpr = null; 621 Integer context = null; 622 if (!this.contextStack.isEmpty()) 623 context = (Integer ) this.contextStack.peek(); 624 if (context != IN_FLWR && !(arg.getQType() != null && arg.getQType().isBoolean()) && ((context == this.IN_RETURN && !(arg instanceof FunctionQNAME) && !(arg instanceof FunctionEXPANDED_QNAME)) || arg instanceof AggregateFunctionCall || arg instanceof InputFunctionCall)) 627 { 633 FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek(); 634 Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR); 635 if (varDefinitionStack.isEmpty()) { 636 lastflwr.addVariable(addvar); 637 } else { 638 Variable lastvar = (Variable) varDefinitionStack.peek(); 639 int prevpos = lastflwr.getVarPosition(lastvar); 640 if (prevpos != -1) 641 lastflwr.addVariable(prevpos, addvar); 642 else 643 lastflwr.addVariable(addvar); 644 } 645 resultExpr = addvar; 646 return; 647 } 648 contextStack.push(IN_FUNCTION); 651 ArrayList arguments = arg.getArguments(); 652 if (arguments != null) { 654 boolean change = false; 655 ArrayList newArguments = new ArrayList (arguments.size()); 656 for (int i = 0; i < arguments.size(); i++) { 657 XQueryExpression argi = (XQueryExpression) arguments.get(i); 658 argi.accept(this); 659 if (resultExpr != null) { 660 change = true; 661 newArguments.add(resultExpr); 662 } else 663 newArguments.add(argi); 664 } 665 if (change) { 666 arg.setArguments(newArguments); 668 ruleNumber++; 670 } 671 resultExpr = null; 673 } 674 contextStack.pop(); 675 } 676 677 682 public void visit(QuantifiedExpression arg) throws XQueryException { 683 if (isRoot) { 684 throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree"); 685 } 686 resultExpr = null; 687 if (isMediator) { 689 FLWRExpression parentFLWR = (FLWRExpression) this.inWhereExpressionStack.peek(); 690 ArrayList variables = arg.getVariables(); 691 for (int i = 0; i < variables.size(); i++) { 692 ((Variable) variables.get(i)).setBindingType(Constants.FOR_BINDINGTYPE); 693 ((Variable) variables.get(i)).addSubPath(((Variable) variables.get(i))); 694 } 695 int kind = arg.getKind(); 696 ArrayList countArgs = new ArrayList (1); 697 XQueryExpression tmpExpr = null; 698 Variable tmpvar = null; 699 if (kind == Constants.SOME_QUANTIFIER) { 700 if (variables.size() > 1) 701 tmpExpr = new FLWRExpression(variables, arg.getExpression(), new XQueryExpressionSequence((ArrayList ) variables.clone(), arg.getParentModule()), arg.getParentModule()); 702 else 703 tmpExpr = new FLWRExpression(variables, arg.getExpression(), (XQueryExpression) variables.get(0), arg.getParentModule()); 704 tmpExpr.accept(this); 705 if (resultExpr != null) 706 tmpExpr = resultExpr; 707 if (tmpExpr instanceof Variable) 708 tmpvar = (Variable)tmpExpr; 709 else { 710 tmpvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, tmpExpr, Variable.RES_CREATOR); 711 parentFLWR.addVariable(tmpvar); 712 } 713 countArgs.add(tmpvar); 714 tmpExpr = new FunctionCOUNT(countArgs, arg.getParentModule()); 715 tmpExpr = new ListOpCompExpression(tmpExpr, new ValueInteger("0", arg.getParentModule()), Constants.GT_COMPOP, arg.getParentModule()); 716 } else { ArrayList args = new ArrayList (1); 718 args.add(arg.getExpression()); 719 if (variables.size() > 1) 720 tmpExpr = new FLWRExpression(variables, new FunctionNOT(args, arg.getParentModule()), new XQueryExpressionSequence((ArrayList ) variables.clone(), arg.getParentModule()), arg.getParentModule()); 721 else 722 tmpExpr = new FLWRExpression(variables, new FunctionNOT(args, arg.getParentModule()), (XQueryExpression) variables.get(0), arg.getParentModule()); 723 tmpExpr.accept(this); 724 if (resultExpr != null) 725 tmpExpr = resultExpr; 726 if (tmpExpr instanceof Variable) 727 tmpvar = (Variable)tmpExpr; 728 else { 729 tmpvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, tmpExpr, Variable.RES_CREATOR); 730 parentFLWR.addVariable(tmpvar); 731 } 732 countArgs.add(tmpvar); 733 tmpExpr = new FunctionCOUNT(countArgs, arg.getParentModule()); 734 tmpExpr = new ListOpCompExpression(tmpExpr, new ValueInteger("0", arg.getParentModule()), Constants.EQ_COMPOP, arg.getParentModule()); 735 } 736 tmpExpr.accept(this); 737 if (resultExpr == null) 738 resultExpr = tmpExpr; 739 } else { 740 for (int i = 0; i < arg.getVariables().size(); i++) { 741 Variable var = (Variable) arg.getVariables().get(i); 742 XQueryExpression varExpr = var.getExpression(); 743 varExpr.accept(this); 744 } 745 XQueryExpression tmpExpr = arg.getExpression(); 746 tmpExpr.accept(this); 747 if (resultExpr != null) { 748 arg.setExpression(resultExpr); 749 } 750 } 751 } 752 753 762 public void visit(SortedExpression arg) throws XQueryException { 763 if (isRoot) { 764 isRoot = false; 765 } 766 XQueryExpression expr = arg.getExpression(); 767 if (!(expr instanceof FLWRExpression) && !(expr instanceof LocatedExpression)) 771 throw new RestructureException("SORTBY can only be used with sequence of single FLWR expression or with a LocatedExpression!!!"); 772 if (!expr.getQType().isMultiple()) { 774 expr.accept(this); 775 if (resultExpr == null) 776 resultExpr = expr; 777 return; 778 } 779 FLWRExpression tmpFLWR = null; 781 if (expr instanceof LocatedExpression) { 782 expr.accept(this); 783 if (resultExpr == null || !(resultExpr instanceof FLWRExpression)) 784 throw new RestructureException("SORTBY used with incorrect path expression"); 785 tmpFLWR = (FLWRExpression) resultExpr; 786 } else 787 tmpFLWR = (FLWRExpression) expr; 788 tmpFLWR.accept(this); 791 if (resultExpr != null) 792 tmpFLWR = (FLWRExpression) resultExpr; 793 ArrayList sortClauses = arg.getSortClauses(); 795 XQueryExpression returnClause = tmpFLWR.getReturnClause(); 796 ArrayList newSortClauses = new ArrayList (sortClauses.size()); 797 SubExpressionVisitor subvisitor = new SubExpressionVisitor(typeVisitor); 798 for (int i = 0; i < sortClauses.size(); i++) { 800 XQueryExpression sortiexpr = (XQueryExpression) sortClauses.get(i); 801 int[] order = sortiexpr.getOrder(); 803 sortiexpr.setOrder(initOrder); 804 ArrayList resultExprs = null; 805 XQueryExpression tmpExpr = null; 806 807 if (sortiexpr instanceof QName) { 809 ruleNumber++; 810 subvisitor.setSubExpression((QName) sortiexpr, true); 811 returnClause.accept(subvisitor); 812 resultExprs = subvisitor.getResultExprs(); 813 if (resultExprs.isEmpty() || resultExprs.size() > 1) 814 throw new TypeException("Invalid sort clause : " + sortiexpr); 815 tmpExpr = (XQueryExpression) resultExprs.get(0); 816 } else if (sortiexpr instanceof LocatedExpression) { 817 LocatedExpression tmpLoc = (LocatedExpression) sortiexpr; 818 ArrayList steps = tmpLoc.getSteps(); 819 Step tmpStep0 = (Step) steps.get(0); 820 if (tmpStep0.hasSeparator()) 821 throw new TypeException("Invalid sort clause : " + sortiexpr); 822 XQueryExpression tmpStep0Expr = tmpStep0.getExpression(); 823 if (steps.size() == 1) { 824 ruleNumber++; 825 if (tmpStep0Expr instanceof NodeTest) { 827 NodeTest tmpNode = (NodeTest) tmpStep0.getExpression(); 828 if (tmpNode.getKind() != NodeKind.NODE) 829 throw new TypeException("Invalid sort clause : " + sortiexpr); 830 if (tmpStep0.getAxis() != Axis.SELF) 831 throw new TypeException("Invalid sort clause : " + sortiexpr); 832 subvisitor.setSubExpression(null, tmpStep0.getAxis(), 0, true); 833 returnClause.accept(subvisitor); 834 resultExprs = subvisitor.getResultExprs(); 835 if (resultExprs.isEmpty() || resultExprs.size() > 1) 836 throw new TypeException("Invalid sort clause : " + sortiexpr); 837 tmpExpr = (XQueryExpression) resultExprs.get(0); 838 } 839 else if (tmpStep0Expr instanceof QName) { 841 QName tmpQName = (QName) tmpStep0.getExpression(); 842 if (tmpStep0.getAxis() != Axis.CHILD && tmpStep0.getAxis() != Axis.ATTRIBUTE) 843 throw new TypeException("Invalid sort clause : " + sortiexpr); 844 subvisitor.setSubExpression(tmpQName, tmpStep0.getAxis(), 845 1, true); 846 returnClause.accept(subvisitor); 847 resultExprs = subvisitor.getResultExprs(); 848 if (resultExprs.isEmpty() || resultExprs.size() > 1) 849 throw new TypeException("Invalid sort clause : " + sortiexpr); 850 tmpExpr = (XQueryExpression) resultExprs.get(0); 851 } else 852 throw new TypeException("Invalid sort clause : " + sortiexpr); 853 } else { 854 ArrayList tmpExprList = new ArrayList (1); 856 tmpExprList.add(returnClause); 857 int depth = 1; 858 for (int j = 0; j < steps.size(); j++) { 859 ruleNumber++; 860 Step stepj = (Step) steps.get(j); 862 if (j == 0 && stepj.hasSeparator()) 864 throw new TypeException("Invalid sort clause : " + sortiexpr); 865 XQueryExpression stepjExpr = stepj.getExpression(); 866 if (stepjExpr instanceof QName) { 867 if (j != 0 && stepj.getAxis() != Axis.CHILD && stepj.getAxis() != Axis.ATTRIBUTE) 868 throw new TypeException("Invalid sort clause : " + sortiexpr); 869 if (stepj.getAxis() == Axis.ATTRIBUTE && j != steps.size() - 1) 870 throw new TypeException("Invalid sort clause : " + sortiexpr); 871 if (depth == -1) { 872 depth = 0; 873 subvisitor.setSubExpression((QName) stepjExpr, stepj.getAxis(), depth, j == steps.size() - 1 ? true : false); 874 for (int k = 0; k < tmpExprList.size(); k++) { 875 XQueryExpression tmpExprListk = (XQueryExpression) tmpExprList.get(k); 876 tmpExprListk.accept(subvisitor); 877 if (resultExprs == null) 878 resultExprs = (ArrayList ) subvisitor.getResultExprs().clone(); 879 else 880 resultExprs.addAll(subvisitor.getResultExprs()); 881 } 882 depth = -1; 883 } 884 if (depth != -1) 885 if (j == 0) 886 depth = 1; 887 else 888 depth = 0; 889 subvisitor.setSubExpression((QName) stepjExpr, stepj.getAxis(), depth, j == steps.size() - 1 ? true : false); 890 for (int k = 0; k < tmpExprList.size(); k++) { 891 XQueryExpression tmpExprListk = (XQueryExpression) tmpExprList.get(k); 892 tmpExprListk.accept(subvisitor); 893 if (resultExprs == null) 894 resultExprs = (ArrayList ) subvisitor.getResultExprs().clone(); 895 else 896 resultExprs.addAll(subvisitor.getResultExprs()); 897 } 898 if (depth == -1) 899 if (j != steps.size() - 1) 900 depth = 1; 901 else 902 depth = 0; 903 if (resultExprs.isEmpty() || (j == steps.size() - 1 && resultExprs.size() > 1)) 905 throw new TypeException("Invalid sort clause : " + sortiexpr); 906 tmpExprList = (ArrayList ) resultExprs.clone(); 907 resultExprs = null; 908 } else if (stepjExpr instanceof NodeTest) { 909 NodeTest tmpNode = (NodeTest) stepj.getExpression(); 910 if (tmpNode.getKind() != NodeKind.NODE) 911 throw new TypeException("Invalid sort clause : " + sortiexpr); 912 if (stepj.getAxis() != Axis.DESCENDANT_OR_SELF) 913 throw new TypeException("Invalid sort clause : " + sortiexpr); 914 if (tmpNode.getKind() == NodeKind.NODE) 915 depth = -1; 916 } else 917 throw new TypeException("Invalid sort clause : " + sortiexpr); 918 } 919 tmpExpr = (XQueryExpression) tmpExprList.get(0); 920 } 921 } 922 if (tmpExpr != null) { 923 tmpExpr.setOrder(order); 925 newSortClauses.add(tmpExpr); 926 } 927 928 } 929 930 if (!newSortClauses.isEmpty()) { 935 GetBoundVariablesVisitor gbvv = new GetBoundVariablesVisitor(true, false); 936 for (int i = 0; i < newSortClauses.size(); i++) { 937 gbvv.reset(); 938 XQueryExpression sortiexpr = (XQueryExpression) newSortClauses.get(i); 939 940 sortiexpr.accept(gbvv); 941 ArrayList tmplist = gbvv.getVariables(); 942 if (tmplist == null || tmplist.isEmpty()) { 943 newSortClauses.remove(i); 944 i--; 945 continue; 946 } 947 boolean cont = false; 948 for (int j = 0; j < tmplist.size(); j++) { 949 if (tmpFLWR.getVariables().contains(tmplist.get(j))) { 950 cont = true; 951 break; 952 } 953 } 954 if (cont == false) { 955 newSortClauses.remove(i); 956 i--; 957 continue; 958 } 959 QType qtypei = sortiexpr.getQType(); 961 if (qtypei == null || !qtypei.isAtomic() || qtypei.isMultiple()) 962 throw new TypeException("Invalid sort clause : " + sortiexpr); 963 } 964 } 965 if (!newSortClauses.isEmpty()) 966 tmpFLWR.setOrderBy(newSortClauses); 967 resultExpr = tmpFLWR; 968 } 969 970 public void visit(UnOpMinusExpression arg) throws XQueryException { 971 if (isRoot) { 972 makeDummyOneFlwr(arg); 973 return; 974 } 975 XQueryExpression parent0Expr = (XQueryExpression) arg.getParentExpression().get(0); 977 if (!(parent0Expr instanceof Variable)) { 978 FLWRExpression lastflwr = (FLWRExpression) parentFLWRExpressionStack.peek(); 979 Variable addvar = typeVisitor.getStaticContext().createVariable(Constants.LET_BINDINGTYPE, arg, Variable.RES_CREATOR); 980 if (varDefinitionStack.isEmpty()) { 981 lastflwr.addVariable(addvar); 982 } else { 983 Variable lastvar = (Variable) varDefinitionStack.peek(); 984 int prevpos = lastflwr.getVarPosition(lastvar); 985 if (prevpos != -1) 986 lastflwr.addVariable(prevpos, addvar); 987 else 988 lastflwr.addVariable(addvar); 989 } 990 resultExpr = addvar; 991 return; 992 } 993 contextStack.push(IN_FUNCTION); 994 XQueryExpression tmpExpr = arg.getExpression(); 995 tmpExpr.accept(this); 996 if (resultExpr != null) { 997 arg.setExpression(resultExpr); 998 } 999 resultExpr = null; 1000 contextStack.pop(); 1001 } 1002 1003 public void visit(ValidateExpression arg) throws XQueryException { 1004 XQueryExpression tmpExpr = arg.getExpression(); 1005 tmpExpr.accept(this); 1006 if (resultExpr != null) { 1007 arg.setExpression(resultExpr); 1008 } 1009 resultExpr = null; 1010 } 1011 1012 public void visit(Value arg) throws XQueryException { 1013 if (isRoot) { 1014 makeDummyFlwr(arg); 1015 return; 1016 } 1017 resultExpr = null; 1018 } 1019 1020 1025 public void visit(Variable arg) throws XQueryException { 1026 if (isRoot) { 1027 throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree"); 1028 } 1029 resultExpr = null; 1030 Integer context = null; 1031 if (!this.contextStack.isEmpty()) 1032 context = (Integer ) this.contextStack.peek(); 1033 if (context != null && context.equals(this.IN_FLWR)) { 1035 varDefinitionStack.add(arg); 1036 arg.getExpression().accept(this); 1037 varDefinitionStack.pop(); 1038 if (resultExpr != null) 1039 arg.setExpression(resultExpr,true); 1040 resultExpr = arg; 1041 ruleNumber++; 1042 } else if (context != null && (context.equals(this.IN_WHERE))) { 1043 } else { 1052 if (arg.getExpression() == null) 1054 return; 1055 QType qtype = arg.getQType(); 1056 if (context != null && context.equals(this.IN_RETURN) && qtype.isMultiple()) { 1060 Variable tmpVar = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR); 1062 ArrayList vars = new ArrayList (1); 1063 vars.add(tmpVar); 1064 FLWRExpression tmpFLWR = new FLWRExpression(vars, null, tmpVar, arg.getParentModule()); 1065 tmpFLWR.setParentModule(arg.getParentModule()); 1066 resultExpr = tmpFLWR; 1067 ruleNumber++; 1068 } 1069 } 1070 } 1071 1072 1076 public void visit(XQueryBinaryOperatorExpression arg) throws XQueryException { 1077 if (isRoot) { 1078 throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree"); 1079 } 1080 XQueryExpression tmpExpr = arg.getExpression1(); 1081 tmpExpr.accept(this); 1082 if (resultExpr != null) { 1083 arg.setExpression1(resultExpr); 1084 } 1085 tmpExpr = arg.getExpression2(); 1086 tmpExpr.accept(this); 1087 if (resultExpr != null) { 1088 arg.setExpression2(resultExpr); 1089 } 1090 resultExpr = null; 1091 } 1092 1093 1095 public void visit(XQueryExpression arg) throws XQueryException { 1096 resultExpr = null; 1101 } 1102 1103 1107 public void visit(XQueryExpressionSequence arg) throws XQueryException { 1108 if (isRoot) { 1109 makeDummyFlwr(arg); 1110 return; 1111 } 1112 resultExpr = null; 1113 ArrayList subExpressions = arg.getSubExpressions(); 1114 if (subExpressions != null) { 1115 ArrayList newSubExpressions = new ArrayList (subExpressions.size()); 1116 for (int i = 0; i < subExpressions.size(); i++) { 1117 XQueryExpression expri = (XQueryExpression) subExpressions.get(i); 1118 expri.accept(this); 1119 if (resultExpr != null) 1120 newSubExpressions.add(resultExpr); 1121 else 1122 newSubExpressions.add(expri); 1123 } 1124 arg.setSubExpressions(newSubExpressions); 1125 resultExpr = arg; 1126 } 1127 } 1128 1129 public void visit(XQueryModule arg) throws XQueryException { 1130 ArrayList expressions = arg.getExpressions(); 1131 if (expressions != null) 1132 for (int i = 0; i < expressions.size(); i++) { 1133 ((XQueryExpression) expressions.get(i)).accept(this); 1134 if (resultExpr != null) { 1135 expressions.set(i, resultExpr); 1136 } 1137 } 1138 resultExpr = null; 1139 } 1140 1141 1145 public void visit(XQueryUnaryOperatorExpression arg) throws XQueryException { 1146 if (isRoot) { 1147 throw new XQueryException(arg.getClass().getName() + " cannot be root expression of parse tree"); 1148 } 1149 XQueryExpression tmpExpr = arg.getExpression(); 1150 tmpExpr.accept(this); 1151 if (resultExpr != null) { 1152 arg.setExpression(resultExpr); 1153 } 1154 resultExpr = null; 1155 } 1156 1157 public void visit(XMLComment arg) throws XQueryException { 1158 if (isRoot) { 1159 makeDummyOneFlwr(arg); 1160 return; 1161 } 1162 XQueryExpression tmpExpr = arg.getExpression(); 1163 tmpExpr.accept(this); 1164 if (resultExpr != null) { 1165 arg.setExpression(resultExpr); 1166 } 1167 resultExpr = null; 1168 } 1169 1170 1172 private void makeDummyFlwr(XQueryExpression arg) throws XQueryException { 1173 isRoot = false; 1174 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, arg, Variable.RES_CREATOR); 1175 ArrayList vars = new ArrayList (1); 1176 vars.add(var); 1177 arg.setRoot(true); 1178 FLWRExpression tmpFLWR = new FLWRExpression(vars, null, null, var, arg.getParentModule()); 1179 tmpFLWR.setParentModule(arg.getParentModule()); 1180 parentFLWRExpressionStack.push(tmpFLWR); 1181 tmpFLWR.accept(this); 1182 parentFLWRExpressionStack.pop(); 1183 if (resultExpr == null) 1184 resultExpr = tmpFLWR; 1185 } 1186 1187 private void makeDummyOneFlwr(XQueryExpression arg) throws XQueryException { 1188 isRoot = false; 1189 Variable var = typeVisitor.getStaticContext().createVariable(Constants.FOR_BINDINGTYPE, new ValueInteger("1", arg.getParentModule()), Variable.RES_CREATOR); 1190 var.isDummy(true); 1191 ArrayList vars = new ArrayList (1); 1192 vars.add(var); 1193 arg.setRoot(true); 1194 FLWRExpression tmpFLWR = new FLWRExpression(vars, null, null, arg, arg.getParentModule()); 1195 tmpFLWR.setParentModule(arg.getParentModule()); 1196 parentFLWRExpressionStack.push(tmpFLWR); 1197 tmpFLWR.accept(this); 1198 parentFLWRExpressionStack.pop(); 1199 if (resultExpr == null) 1200 resultExpr = tmpFLWR; 1201 } 1202 1203} 1204 | Popular Tags |