1 23 24 package org.xquark.mediator.DOMUtils; 25 26 import java.math.BigDecimal ; 27 import java.sql.Timestamp ; 28 import java.util.*; 29 30 import org.w3c.dom.Attr ; 31 import org.w3c.dom.Node ; 32 import org.xquark.schema.*; 33 import org.xquark.xpath.datamodel.*; 34 import org.xquark.xquery.parser.*; 35 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*; 36 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.*; 37 import org.xquark.xquery.parser.util.Constants; 38 39 44 public class EvaluationVisitor extends DefaultParserVisitor { 45 private static final String RCSRevision = "$Revision: 1.23 $"; 49 private static final String RCSName = "$Name: $"; 50 private BufferTuple buffertuple = null; 54 private ArrayList tuplelist = null; 55 private Tuple tuple = null; 56 58 private boolean verdict = false; 59 60 private Tuple resulttuple = null; 62 private ArrayList resnodes = null; 63 private Comparable resvalue = null; 64 65 protected static TypedDocumentImpl docimpl = null; 66 static { 67 docimpl = new TypedDocumentImpl(); 68 } 69 private SchemaManager schemamanager = null; 70 71 public static Integer UNKNOWN_TYPE = new Integer (-1); 72 public static Integer BOOLEAN_TYPE = new Integer (0); 73 public static Integer VALUE_TYPE = new Integer (1); 74 public static Integer NODE_TYPE = new Integer (2); 75 public static Integer TUPLE_TYPE = new Integer (3); 76 public static Integer BUFFER_TYPE = new Integer (4); 77 private Stack returnType = new Stack(); 78 79 82 public EvaluationVisitor(SchemaManager schemamanager) { 83 this.schemamanager = schemamanager; 84 } 85 86 89 public EvaluationVisitor(SchemaManager schemamanager, Tuple tuple) { 90 this.schemamanager = schemamanager; 91 this.tuple = tuple; 92 } 93 94 97 public EvaluationVisitor(SchemaManager schemamanager, ArrayList tuplelist) { 98 this.schemamanager = schemamanager; 99 this.tuplelist = tuplelist; 100 } 101 102 105 111 public void setReturnType(Integer setType) { 112 if (!returnType.isEmpty()) 113 this.returnType.pop(); 114 returnType.push(setType); 115 } 116 117 private void clear() { 118 resulttuple = null; 120 resnodes = null; 121 resvalue = null; 122 verdict = false; 123 } 124 private void setResultTuple(Tuple tuple) { 125 resulttuple = tuple; 127 resnodes = null; 128 resvalue = null; 129 verdict = false; 130 } 131 private void setResultBufferTuple(BufferTuple buffertuple) { 132 resulttuple = null; 134 resnodes = null; 135 resvalue = null; 136 verdict = false; 137 } 138 private void setResnodes(ArrayList nodes) { 139 resulttuple = null; 141 resnodes = nodes; 142 resvalue = null; 143 verdict = false; 144 } 145 private void setValue(Comparable comp) { 146 resulttuple = null; 148 resnodes = null; 149 resvalue = comp; 150 verdict = false; 151 } 152 private void setVerdict(boolean bool) { 153 resulttuple = null; 155 resnodes = null; 156 resvalue = null; 157 verdict = bool; 158 } 159 public void setSchemaManager(SchemaManager schemamanager) { 160 this.schemamanager = schemamanager; 161 } 162 public void reset() { 163 clear(); 164 this.tuple = null; 165 this.buffertuple = null; 166 this.tuplelist = null; 167 returnType.clear(); 168 } 169 public void reset(Tuple tuple) { 170 clear(); 171 this.tuple = tuple; 172 this.buffertuple = null; 173 this.tuplelist = null; 174 returnType.clear(); 175 } 176 public void reset(BufferTuple buffertuple) { 177 clear(); 178 this.tuple = null; 179 this.buffertuple = buffertuple; 180 this.tuplelist = null; 181 returnType.clear(); 182 } 183 public void reset(ArrayList tuplelist) { 184 clear(); 185 if (tuplelist.size() > 1) { 186 this.tuple = null; 187 this.buffertuple = null; 188 this.tuplelist = tuplelist; 189 } else if (tuplelist.size() == 1) { 190 this.tuple = (Tuple) tuplelist.get(0); 191 this.buffertuple = null; 192 this.tuplelist = null; 193 } else { 194 this.tuple = null; 195 this.buffertuple = null; 196 this.tuplelist = null; 197 } 198 returnType.clear(); 199 } 200 public boolean getVerdict() { 201 return verdict; 202 } 203 public Tuple getResultTuple() { 207 return resulttuple; 208 } 209 public ArrayList getResNodes() { 210 return resnodes; 211 } 212 public Comparable getResValue() { 213 if (resvalue != null) 214 return resvalue; 215 if (resnodes != null && resnodes.size() == 1) { 216 resvalue = (Comparable )((TypedNode)resnodes.get(0)).getTypedValue(); 217 } 218 return resvalue; 219 } 220 221 public void visit(AttributeValuePair arg) throws XQueryException { 222 if (arg.isXmlns()) { 223 setResnodes(null); 224 return; 225 } 226 if (!(arg.getExpression1() instanceof QName)) { 227 throw new XQueryException("EvaluationVisitor : name of AttributeValuePair is not a QName : " + arg.getExpression1()); 228 } 229 QName attName = (QName) arg.getExpression1(); 230 Object attValue = null; 231 if (!(arg.getExpression2() instanceof Value)) { 232 returnType.push(VALUE_TYPE); 233 arg.getExpression2().accept(this); 234 returnType.pop(); 235 if (resvalue == null) { 236 throw new XQueryException("EvaluationVisitor : value of AttributeValuePair is null : " + arg.getExpression2()); 237 } 238 attValue = resvalue; 239 } else 240 attValue = ((Value) arg.getExpression2()).getObjectValue(); 241 if (attValue != null) { 242 TypedAttributeImpl att = new TypedAttributeImpl(docimpl, ((QName) attName).getNameSpace(), ((QName) attName).getLocalName()); 243 att.setNodeValue(attValue.toString()); 244 att.setTypedValue(attValue); 245 ArrayList tmplist = new ArrayList(1); 246 tmplist.add(att); 247 setResnodes(tmplist); 248 return; 249 } 250 setResnodes(null); 251 } 252 253 public void visit(BinOpANDExpression arg) throws XQueryException { 254 if (tuple != null) { 256 XQueryExpression exp1 = arg.getExpression1(); 257 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, tuple); 258 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 259 exp1.accept(visitor); 260 verdict = visitor.getVerdict(); 261 if (verdict == false) { 262 setVerdict(false); 263 return; 264 } 265 XQueryExpression exp2 = arg.getExpression2(); 266 visitor.reset(tuple); 268 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 269 exp2.accept(visitor); 270 verdict &= visitor.getVerdict(); 271 } else if (buffertuple != null) { 272 verdict = false; 273 } else if (tuplelist != null) { 274 XQueryExpression exp1 = arg.getExpression1(); 275 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, tuplelist); 276 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 277 exp1.accept(visitor); 278 verdict = visitor.getVerdict(); 279 if (verdict == false) { 280 setVerdict(false); 281 return; 282 } 283 XQueryExpression exp2 = arg.getExpression2(); 284 visitor.reset(tuplelist); 286 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 287 exp2.accept(visitor); 288 verdict &= visitor.getVerdict(); 289 } else { 290 XQueryExpression exp1 = arg.getExpression1(); 291 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager); 292 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 293 exp1.accept(visitor); 294 verdict = visitor.getVerdict(); 295 if (verdict == false) { 296 setVerdict(false); 297 return; 298 } 299 XQueryExpression exp2 = arg.getExpression2(); 300 visitor.reset(); 302 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 303 exp2.accept(visitor); 304 verdict &= visitor.getVerdict(); 305 } 306 setVerdict(verdict); 307 } 308 309 public void visit(BinOpORExpression arg) throws XQueryException { 310 if (tuple != null) { 312 XQueryExpression exp1 = arg.getExpression1(); 313 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, tuple); 314 exp1.accept(visitor); 315 verdict = visitor.getVerdict(); 316 XQueryExpression exp2 = arg.getExpression2(); 317 visitor.reset(tuple); 319 exp2.accept(visitor); 320 verdict = verdict || visitor.getVerdict(); 321 } else if (buffertuple != null) { 322 verdict = false; 323 } else if (tuplelist != null) { 324 XQueryExpression exp1 = arg.getExpression1(); 325 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, tuplelist); 326 exp1.accept(visitor); 327 verdict = visitor.getVerdict(); 328 XQueryExpression exp2 = arg.getExpression2(); 329 visitor.reset(tuplelist); 331 exp2.accept(visitor); 332 verdict = verdict || visitor.getVerdict(); 333 } else { 334 XQueryExpression exp1 = arg.getExpression1(); 335 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager); 336 exp1.accept(visitor); 337 verdict = visitor.getVerdict(); 338 XQueryExpression exp2 = arg.getExpression2(); 339 visitor.reset(); 341 exp2.accept(visitor); 342 verdict = verdict || visitor.getVerdict(); 343 } 344 setVerdict(verdict); 345 } 346 347 351 public void visit(Element arg) throws XQueryException { 352 XQueryExpression startTag = arg.getStartTag(); 353 if (!(startTag instanceof QName)) 354 throw new XQueryException("Tag of Element expression is not a QName : " + startTag); 355 QName startTagQName = (QName) startTag; 356 TypedElement element = new TypedElementImpl(docimpl, startTagQName.getNameSpace(), startTagQName.getLocalName()); 357 ArrayList tmplist = arg.getAttributes(); 358 if (tmplist != null && !tmplist.isEmpty()) { 359 for (int i = 0; i < tmplist.size(); i++) { 360 AttributeValuePair attValPair = (AttributeValuePair) tmplist.get(i); 361 returnType.push(NODE_TYPE); 362 attValPair.accept(this); 363 returnType.pop(); 364 if (resnodes != null) { 365 TypedAttribute att = (TypedAttribute) resnodes.get(0); 366 element.setAttributeNodeNS((Attr ) att); 367 } 368 } 369 } 370 tmplist = arg.getSubExpressions(); 371 if (tmplist != null && !tmplist.isEmpty()) { 372 for (int i = 0; i < tmplist.size(); i++) { 373 XQueryExpression subExpr = (XQueryExpression) tmplist.get(i); 374 returnType.push(NODE_TYPE); 375 subExpr.accept(this); 376 returnType.pop(); 377 if (resnodes != null) { 378 for (int j = 0; j < resnodes.size(); j++) { 379 TypedNode resnode = (TypedNode) resnodes.get(j); 380 if (docimpl != resnode.getOwnerDocument()) 381 resnode = (TypedNode) element.getOwnerDocument().importNode(resnode, true); 382 if (resnode instanceof TypedAttributeImpl) { 383 element.setAttributeNodeNS((Attr ) resnode); 384 } else if (resnode instanceof TypedElementImpl) { 385 element.appendChild((Node ) resnode); 386 } else if (resnode instanceof TypedValueImpl) { 387 element.appendChild((Node ) resnode); 388 } else { 389 throw new XQueryException("Could not add child : " + resnode + " to parent."); 390 } 392 } 393 } 394 } 395 } 396 tmplist = new ArrayList(1); 397 tmplist.add(element); 398 setResnodes(tmplist); 399 } 400 401 public void visit (ExternalVariable arg) throws XQueryException { 402 Variable var = (Variable)arg.getObjectValue(); 403 if (var.getExpression() != null) 404 var.getExpression().accept(this); 405 else 406 var.accept(this); 407 } 408 409 418 public void visit(ListOpArithExpression arg) throws XQueryException { 419 XQueryExpression exp1 = arg.getExpression1(); 420 XQueryExpression exp2 = arg.getExpression2(); 421 int operator = arg.getOperator(); 422 423 returnType.push(UNKNOWN_TYPE); 424 exp1.accept(this); 425 ArrayList trees1 = resnodes; 426 Number value1 = (resvalue instanceof Number ) ? (Number ) resvalue : null; 427 exp2.accept(this); 428 ArrayList trees2 = resnodes; 429 Number value2 = (resvalue instanceof Number ) ? (Number ) resvalue : null; 430 returnType.pop(); 431 432 if ((trees1 == null || trees1.isEmpty()) && (trees2 == null || trees2.isEmpty())) { 435 Number res = processOperation(exp1, exp2, null, null, value1, value2, operator); 436 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 438 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 439 text.setTypedValue(res); 440 text.setType(st); 441 ArrayList tmplist = new ArrayList(1); 442 tmplist.add(text); 443 setResnodes(tmplist); 444 return; 451 } 452 453 if ((trees1 == null || trees1.isEmpty()) && (trees2 != null) && (!trees2.isEmpty())) { 454 ArrayList tmplist = new ArrayList(trees2.size()); 455 for (int j = 0; j < trees2.size(); j++) { 456 TypedNode tree2 = (TypedNode) trees2.get(j); 457 Number res = processOperation(exp1, exp2, null, tree2, value1, value2, operator); 458 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 459 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 460 text.setTypedValue(res); 461 text.setType(st); 462 tmplist.add(text); 463 } 464 setResnodes(tmplist); 466 return; 470 } 471 472 if ((trees1 != null) && (!trees1.isEmpty()) && (trees2 == null) || (trees2.isEmpty())) { 473 ArrayList tmplist = new ArrayList(trees1.size()); 474 for (int i = 0; i < trees1.size(); i++) { 475 TypedNode tree1 = (TypedNode) trees1.get(i); 476 Number res = processOperation(exp1, exp2, tree1, null, value1, value2, operator); 477 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 478 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 479 text.setTypedValue(res); 480 text.setType(st); 481 tmplist.add(text); 482 } 483 setResnodes(tmplist); 485 return; 489 } 490 491 ArrayList tmplist = new ArrayList(trees1.size() * trees2.size()); 492 for (int i = 0; i < trees1.size(); i++) { 493 TypedNode tree1 = (TypedNode) trees1.get(i); 494 for (int j = 0; j < trees2.size(); j++) { 495 TypedNode tree2 = (TypedNode) trees2.get(j); 496 Number res = processOperation(exp1, exp2, tree1, tree2, value1, value2, operator); 497 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 498 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 499 text.setTypedValue(res); 500 text.setType(st); 501 tmplist.add(text); 502 } 503 } 504 setResnodes(tmplist); 506 } 510 511 public void visit(ListOpCompExpression arg) throws XQueryException { 513 XQueryExpression exp1 = arg.getExpression1(); 514 XQueryExpression exp2 = arg.getExpression2(); 515 int operator = arg.getOperator(); 516 517 returnType.push(EvaluationVisitor.NODE_TYPE); 518 resnodes = null; 519 resvalue = null; 520 exp1.accept(this); 521 ArrayList trees1 = resnodes; 523 if (trees1 != null && trees1.isEmpty()) 524 trees1 = null; 525 Comparable value1 = resvalue; 526 resnodes = null; 528 resvalue = null; 529 exp2.accept(this); 530 returnType.pop(); 531 ArrayList trees2 = resnodes; 532 if (trees2 != null && trees2.isEmpty()) 533 trees2 = null; 534 Comparable value2 = resvalue; 535 536 if (value1 != null && value2 != null) { 537 processComparison(null, null, null, null, value1, value2, operator); 538 setVerdict(verdict); 539 return; 540 } 541 542 if (trees1 == null && trees2 == null) { 543 processComparison(exp1, exp2, null, null, value1, value2, operator); 544 return; 545 } 546 547 if (trees1 == null && trees2 != null) { 548 for (int j = 0; j < trees2.size(); j++) { 549 TypedNode tree2 = (TypedNode) trees2.get(j); 550 processComparison(exp1, exp2, null, tree2, value1, value2, operator); 551 if (verdict == true) { 552 setVerdict(true); 553 return; 554 } 555 } 556 setVerdict(false); 557 return; 558 } 559 560 if (trees1 != null && trees2 == null) { 561 for (int i = 0; i < trees1.size(); i++) { 562 TypedNode tree1 = (TypedNode) trees1.get(i); 563 processComparison(exp1, exp2, tree1, null, value1, value2, operator); 564 if (verdict == true) { 565 setVerdict(true); 566 return; 567 } 568 } 569 setVerdict(false); 570 return; 571 } 572 573 for (int i = 0; i < trees1.size(); i++) { 574 TypedNode tree1 = (TypedNode) trees1.get(i); 575 for (int j = 0; j < trees2.size(); j++) { 576 TypedNode tree2 = (TypedNode) trees2.get(j); 577 processComparison(exp1, exp2, tree1, tree2, value1, value2, operator); 578 if (verdict == true) { 579 setVerdict(true); 580 return; 581 } 582 } 583 setVerdict(false); 584 } 585 } 586 587 590 public void visit(ListOpUNIONExpression arg) throws XQueryException { 591 XQueryExpression exp1 = arg.getExpression1(); 592 XQueryExpression exp2 = arg.getExpression2(); 593 594 returnType.push(NODE_TYPE); 595 resnodes = null; 596 exp1.accept(this); 597 ArrayList trees = resnodes; 598 resnodes = null; 599 exp2.accept(this); 600 returnType.pop(); 601 if (resnodes != null) { 602 if (trees == null) 603 trees = resnodes; 604 else 605 trees.addAll(resnodes); 606 } 607 setResnodes(trees); 608 } 609 610 public void visit(LocatedExpression arg) throws XQueryException { 611 clear(); 612 if (!(arg.getStepNum(0).getExpression() instanceof Variable)) { 613 returnType.push(NODE_TYPE); 614 arg.getStepNum(0).getExpression().accept(this); 615 returnType.pop(); 616 ArrayList tmplist = resnodes; 617 for (int j = 1; j < arg.getSteps().size(); j++) { 618 tmplist = DOMUtils.getStep(tmplist, arg.getStepNum(j)); 619 if (tmplist == null || tmplist.isEmpty()) 620 break; 621 } 622 if (tmplist != null) 623 setResnodes(tmplist); 624 return; 625 } 626 if (this.tuple == null && this.tuplelist == null) { 627 return; 628 } 629 if (tuple != null) { 630 if ((resnodes = tuple.getPath(arg.getStringValue())) != null) { 631 setResnodes(resnodes); 632 return; 633 } 634 } else { 635 for (int i = 0; i < tuplelist.size(); i++) { 636 if ((resnodes = ((Tuple) tuplelist.get(i)).getPath(arg.getStringValue())) != null) { 637 setResnodes(resnodes); 638 return; 639 } 640 } 641 } 642 resnodes = null; 643 ArrayList steps = arg.getSteps(); 644 ArrayList tmplist = null; 645 if (tuple != null) { 646 StringBuffer buf = new StringBuffer (arg.toString(false,false,true)); 647 int i; 648 for (i = steps.size() - 1; i > 0; i--) { 649 buf.delete(buf.length() - ((Step) steps.get(i)).getStringValue().length(), buf.length()); 650 tmplist = tuple.getPath(buf.toString()); 651 if (tmplist != null) 652 break; 653 } 654 if (tmplist == null) 655 return; 656 for (int j = i; j < steps.size(); j++) { 657 tmplist = DOMUtils.getStep(tmplist, arg.getStepNum(j)); 658 if (tmplist == null || tmplist.isEmpty()) 659 break; 660 } 661 } else { for (int k = 0; k < tuplelist.size(); k++) { 663 StringBuffer buf = new StringBuffer (arg.getStringValue()); 664 Tuple tuplek = (Tuple) tuplelist.get(k); 665 int i; 666 for (i = steps.size() - 1; i > 0; i--) { 667 buf.delete(buf.length() - ((Step) steps.get(i)).getStringValue().length(), buf.length()); 668 tmplist = tuplek.getPath(buf.toString()); 669 if (tmplist != null) 670 break; 671 } 672 if (tmplist == null) 673 continue; 674 for (int j = i; j < steps.size(); j++) { 675 tmplist = DOMUtils.getStep(tmplist, arg.getStepNum(j)); 676 if (tmplist == null || tmplist.isEmpty()) 677 break; 678 } 679 break; 680 } 681 } 682 if (tmplist != null) 683 setResnodes(tmplist); 684 } 685 696 private Comparable getMinus(Comparable obj) throws XQueryException { 697 Comparable retObj = null; 698 if (obj instanceof Number ) { 699 if (obj instanceof Double ) { 701 retObj = new Double (- ((Double ) obj).doubleValue()); 702 } else if (obj instanceof Float ) { 703 retObj = new Float (- ((Float ) obj).floatValue()); 704 } else if (obj instanceof BigDecimal ) { 705 retObj = new BigDecimal (((BigDecimal ) obj).unscaledValue().negate(), ((BigDecimal ) obj).scale()); 706 } else if (obj instanceof Integer ) { 707 retObj = new Integer (- ((Integer ) obj).intValue()); 708 } else if (obj instanceof Long ) { 709 retObj = new Long (- ((Long ) obj).longValue()); 710 } 711 } else if (obj instanceof String ) { 712 try { 713 retObj = new Double (-Double.parseDouble((String ) obj)); 714 } catch (NumberFormatException e) { 715 } 717 } 718 return retObj; 719 } 720 721 public void visit(UnOpMinusExpression arg) throws XQueryException { 722 returnType.push(UNKNOWN_TYPE); 723 arg.getExpression().accept(this); 724 returnType.pop(); 725 Integer rettype = (Integer ) returnType.peek(); 726 if (resvalue != null) { 727 if (!arg.getMinus()) { 728 if (rettype == NODE_TYPE) { 729 ArrayList nodes = new ArrayList(1); 730 TypedValue text = null; 731 if (resvalue instanceof Long ) 732 text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 733 else if (resvalue instanceof BigDecimal ) 734 text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType()); 735 else if (resvalue instanceof Double ) 736 text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 737 else 738 throw new XQueryException("UnOpMinusExpression could not cast resvalue"); 739 nodes.add(text); 740 setResnodes(nodes); 741 return; 742 } else { setValue(resvalue); 744 return; 745 } 746 } 747 Comparable comp = getMinus(resvalue); 748 if (comp != null) { 749 if (rettype == NODE_TYPE) { 750 ArrayList nodes = new ArrayList(1); 751 TypedValue text = null; 752 if (comp instanceof Long ) 753 text = docimpl.createTypedValue(comp, this.schemamanager.getIntegerType()); 754 else if (resvalue instanceof BigDecimal ) 755 text = docimpl.createTypedValue(comp, this.schemamanager.getDecimalType()); 756 else if (comp instanceof Double ) 757 text = docimpl.createTypedValue(comp, this.schemamanager.getDoubleType()); 758 else 759 throw new XQueryException("UnOpMinusExpression could not cast comp"); 760 nodes.add(text); 761 setResnodes(nodes); 762 return; 763 } else { setValue(comp); 765 return; 766 } 767 } else 768 throw new XQueryException("UnOpMinusExpression could not cast operator to Number"); 769 } else if (resnodes != null) { 770 if (rettype == VALUE_TYPE && resnodes.size() != 1) { 771 throw new XQueryException("UnOpMinusExpression could not get value from node list"); 772 } 773 if (!arg.getMinus()) { 774 if (rettype == NODE_TYPE) { 775 ArrayList tmplist = new ArrayList(resnodes.size()); 776 for (int i = 0; i < resnodes.size(); i++) { 777 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 778 if (tmpnode == null) 779 tmpnode = (TypedNode) resnodes.get(0); 780 tmplist.add(docimpl.createTypedValue((Comparable ) tmpnode.getTypedValue(), (SimpleType) tmpnode.getType())); 781 } 782 setResnodes(tmplist); 783 return; 784 } else { TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 786 if (tmpnode == null) 787 tmpnode = (TypedNode) resnodes.get(0); 788 setValue((Comparable ) tmpnode.getTypedValue()); 789 return; 790 } 791 } 792 ArrayList tmplist = new ArrayList(resnodes.size()); 793 for (int i = 0; i < resnodes.size(); i++) { 794 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 795 if (tmpnode == null) 796 tmpnode = (TypedNode) resnodes.get(0); 797 Comparable comp = getMinus((Comparable ) tmpnode.getTypedValue()); 798 if (comp != null) { 799 TypedValue text = docimpl.createTypedValue(comp, (SimpleType) tmpnode.getType()); 800 tmplist.add(text); 801 } 802 } 803 if (rettype == NODE_TYPE) { 804 setResnodes(tmplist); 805 return; 806 } else { if (tmplist.size() == 1) { 808 setValue((Comparable ) ((TypedValue) tmplist.get(0)).getTypedValue()); 809 return; 810 } 811 } 812 } 813 clear(); 814 } 815 816 public void visit(Value arg) throws XQueryException { 817 clear(); 818 } 819 public void visit(ValueDecimal arg) throws XQueryException { 821 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 822 if (rettype == NODE_TYPE) { 823 ArrayList nodes = new ArrayList(1); 824 TypedValue text = docimpl.createTypedValue(arg.getDecimalValue(), this.schemamanager.getDecimalType()); 825 nodes.add(text); 826 setResnodes(nodes); 827 return; 828 } else { setValue(arg.getDecimalValue()); 830 return; 831 } 832 } 833 public void visit(ValueDouble arg) throws XQueryException { 834 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 835 if (rettype == NODE_TYPE) { 836 ArrayList nodes = new ArrayList(1); 837 TypedValue text = docimpl.createTypedValue(arg.getDoubleValue(), this.schemamanager.getDoubleType()); 838 nodes.add(text); 839 setResnodes(nodes); 840 return; 841 } else { setValue(arg.getDoubleValue()); 843 return; 844 } 845 } 846 public void visit(ValueFloat arg) throws XQueryException { 847 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 848 if (rettype == NODE_TYPE) { 849 ArrayList nodes = new ArrayList(1); 850 TypedValue text = docimpl.createTypedValue(arg.getFloatValue(), this.schemamanager.getFloatType()); 851 nodes.add(text); 852 setResnodes(nodes); 853 return; 854 } else { setValue(arg.getFloatValue()); 856 return; 857 } 858 } 859 public void visit(ValueInteger arg) throws XQueryException { 860 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 861 if (rettype == NODE_TYPE) { 862 ArrayList nodes = new ArrayList(1); 863 TypedValue text = docimpl.createTypedValue(new Long (arg.getIntValue().longValue()), this.schemamanager.getIntegerType()); 864 nodes.add(text); 865 setResnodes(nodes); 866 return; 867 } else { setValue(new Long (arg.getIntValue().longValue())); 869 return; 870 } 871 } 872 public void visit(ValueString arg) throws XQueryException { 873 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 874 if (rettype == NODE_TYPE) { 875 ArrayList nodes = new ArrayList(1); 876 TypedValue text = docimpl.createTypedValue(arg.getStringValue(), this.schemamanager.getStringType()); 877 nodes.add(text); 878 setResnodes(nodes); 879 return; 880 } else { setValue(arg.getStringValue()); 882 return; 883 } 884 } 885 public void visit(ValueText arg) throws XQueryException { 886 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 887 if (rettype == NODE_TYPE) { 888 ArrayList nodes = new ArrayList(1); 889 TypedValue text = docimpl.createTypedValue(arg.getTextValue(), this.schemamanager.getStringType()); 890 nodes.add(text); 891 setResnodes(nodes); 892 return; 893 } else { setValue(arg.getTextValue()); 895 return; 896 } 897 } 898 public void visit(Variable arg) throws XQueryException { 899 if (this.tuple != null) { 900 setResnodes(tuple.getPath(arg.getStringValue())); 901 return; 902 } else if (tuplelist != null) { 903 for (int i = 0; i < tuplelist.size(); i++) { 904 if ((resnodes = ((Tuple) tuplelist.get(i)).getPath(arg.getStringValue())) != null) { 905 this.setResnodes(resnodes); 906 return; 907 } 908 } 909 } 910 this.clear(); 911 } 912 public void visit(XQueryExpression arg) throws XQueryException { 915 throw new XQueryException("Class " + arg.getClass().getName() + " not supported in EvaluationVisitor"); 916 } 917 public void visit(XQueryExpressionSequence arg) throws XQueryException { 918 if (arg.getSubExpressions().size() == 1) 919 ((XQueryExpression) arg.getSubExpressions().get(0)).accept(this); 920 else { 921 ArrayList expressions = arg.getSubExpressions(); 922 ArrayList tmpnodes = new ArrayList(); 923 returnType.push(NODE_TYPE); 924 for (int i = 0; i < expressions.size(); i++) { 925 XQueryExpression expri = (XQueryExpression) expressions.get(i); 926 expri.accept(this); 927 if (resnodes != null) 928 tmpnodes.addAll(resnodes); 929 } 930 setResnodes(tmpnodes); 931 returnType.pop(); 932 } 934 } 935 939 public void visit(FunctionFALSE arg) throws XQueryException { 943 setVerdict(false); 944 } 945 946 public void visit(FunctionTRUE arg) throws XQueryException { 947 setVerdict(true); 948 } 949 950 954 public void visit(FunctionAVG arg) throws XQueryException { 955 boolean isLongSum = false; 956 double doubleSum = 0; 957 long longSum = 0; 958 int count = 0; 959 if (buffertuple != null) { 961 int index = buffertuple.getPathIndex(arg.getArgument(0).getStringValue()); 962 if (index == -1) 963 index = 0; 964 for (int i = 0; i < buffertuple.size(); i++) { 965 Tuple tuplei = (Tuple) buffertuple.get(i); 966 Number valuei = null; 969 TypedNode treei = (TypedNode) tuplei.getNodesAtIndex(index).get(0); 970 try { 971 if (treei.getTypedValue() != null) 972 valuei = (Number ) treei.getTypedValue(); 973 else 974 valuei = (Number ) DOMUtils.getTextLeaf(treei); 975 } catch (ClassCastException cce) { 976 } 978 if (valuei == null) 979 return; 980 if (isLongSum && (valuei instanceof Integer || valuei instanceof Long )) { 981 longSum += valuei.longValue(); 982 } else { 983 if (isLongSum) { 984 doubleSum = longSum; 985 isLongSum = false; 986 } 987 doubleSum += valuei.doubleValue(); 988 } 989 } 990 count = buffertuple.size(); 991 } else { 992 returnType.push(NODE_TYPE); 993 arg.getArgument(0).accept(this); 994 returnType.pop(); 995 if (resnodes == null || resnodes.isEmpty()) 996 return; 997 998 for (int i = 0; i < resnodes.size(); i++) { 999 Number valuei = null; 1000 TypedNode treei = (TypedNode) resnodes.get(i); 1001 try { 1002 if (treei.getTypedValue() != null) 1003 valuei = (Number ) treei.getTypedValue(); 1004 else 1005 valuei = (Number ) DOMUtils.getTextLeaf(treei); 1006 } catch (ClassCastException cce) { 1007 } 1009 if (valuei == null) 1010 return; 1011 if (isLongSum && (valuei instanceof Integer || valuei instanceof Long )) { 1012 longSum += valuei.longValue(); 1013 } else { 1014 if (isLongSum) { 1015 doubleSum = longSum; 1016 isLongSum = false; 1017 } 1018 doubleSum += valuei.doubleValue(); 1019 } 1020 } 1021 count = resnodes.size(); 1022 } 1023 Integer retType = (Integer ) this.returnType.peek(); 1024 if (retType == TUPLE_TYPE) { 1025 Tuple tuple = new Tuple(1); 1026 TypedValue text = null; 1027 if (isLongSum) 1028 text = docimpl.createTypedValue(new BigDecimal (longSum / count), this.schemamanager.getDecimalType()); 1029 else 1030 text = docimpl.createTypedValue(new Double (doubleSum / count), this.schemamanager.getDoubleType()); 1031 tuple.addNodeAtIndex(0, text); 1032 this.setResultTuple(tuple); 1033 return; 1034 } else if (retType == NODE_TYPE) { 1035 ArrayList nodes = new ArrayList(1); 1036 TypedValue text = null; 1037 if (isLongSum) 1038 text = docimpl.createTypedValue(new BigDecimal (longSum / count), this.schemamanager.getDecimalType()); 1039 else 1040 text = docimpl.createTypedValue(new Double (doubleSum / count), this.schemamanager.getDoubleType()); 1041 nodes.add(text); 1042 setResnodes(nodes); 1043 return; 1044 } else { 1045 if (isLongSum) 1046 setValue(new BigDecimal (longSum / count)); 1047 else 1048 setValue(new Double (doubleSum / count)); 1049 return; 1050 } 1051 1053 } 1054 1055 public void visit(FunctionSUM arg) throws XQueryException { 1056 boolean isLongSum = false; 1057 double doubleSum = 0; 1058 long longSum = 0; 1059 if (buffertuple != null) { 1061 int index = buffertuple.getPathIndex(arg.getArgument(0).getStringValue()); 1062 if (index == -1) 1063 index = 0; 1064 for (int i = 0; i < buffertuple.size(); i++) { 1065 Tuple tuplei = (Tuple) buffertuple.get(i); 1066 Number valuei = null; 1069 TypedNode treei = (TypedNode) tuplei.getNodesAtIndex(index).get(0); 1070 try { 1071 if (treei.getTypedValue() != null) 1072 valuei = (Number ) treei.getTypedValue(); 1073 else 1074 valuei = (Number ) DOMUtils.getTextLeaf(treei); 1075 } catch (ClassCastException cce) { 1076 } 1078 if (valuei == null) 1079 return; 1080 if (isLongSum && (valuei instanceof Integer || valuei instanceof Long )) { 1081 longSum += valuei.longValue(); 1082 } else { 1083 if (isLongSum) { 1084 doubleSum = longSum; 1085 isLongSum = false; 1086 } 1087 doubleSum += valuei.doubleValue(); 1088 } 1089 } 1090 } else { 1091 returnType.push(NODE_TYPE); 1092 arg.getArgument(0).accept(this); 1093 returnType.pop(); 1094 if (resnodes == null || resnodes.isEmpty()) 1095 return; 1096 1097 for (int i = 0; i < resnodes.size(); i++) { 1098 Number valuei = null; 1099 TypedNode treei = (TypedNode) resnodes.get(i); 1100 try { 1101 if (treei.getTypedValue() != null) 1102 valuei = (Number ) treei.getTypedValue(); 1103 else 1104 valuei = (Number ) DOMUtils.getTextLeaf(treei); 1105 } catch (ClassCastException cce) { 1106 } 1108 if (valuei == null) 1109 return; 1110 if (isLongSum && (valuei instanceof Integer || valuei instanceof Long )) { 1111 longSum += valuei.longValue(); 1112 } else { 1113 if (isLongSum) { 1114 doubleSum = longSum; 1115 isLongSum = false; 1116 } 1117 doubleSum += valuei.doubleValue(); 1118 } 1119 } 1120 } 1121 Integer retType = (Integer ) this.returnType.peek(); 1122 if (retType == TUPLE_TYPE) { 1123 Tuple tuple = new Tuple(1); 1124 TypedValue text = null; 1125 if (isLongSum) 1126 text = docimpl.createTypedValue(new Long (longSum), this.schemamanager.getIntegerType()); 1127 else 1128 text = docimpl.createTypedValue(new Double (doubleSum), this.schemamanager.getDoubleType()); 1129 tuple.addNodeAtIndex(0, text); 1130 setResultTuple(tuple); 1131 return; 1132 } else if (retType == NODE_TYPE) { 1133 ArrayList nodes = new ArrayList(1); 1134 TypedValue text = null; 1135 if (isLongSum) 1136 text = docimpl.createTypedValue(new Long (longSum), this.schemamanager.getIntegerType()); 1137 else 1138 text = docimpl.createTypedValue(new Double (doubleSum), this.schemamanager.getDoubleType()); 1139 nodes.add(text); 1140 setResnodes(nodes); 1141 return; 1142 } else { 1143 if (isLongSum) 1144 setValue(new Long (longSum)); 1145 else 1146 setValue(new Double (doubleSum)); 1147 return; 1148 } 1149 1151 } 1152 1153 public void visit(FunctionMAX arg) throws XQueryException { 1154 Comparable max = null; 1155 TypedNode result = null; 1156 if (buffertuple != null) { 1158 int index = buffertuple.getPathIndex(arg.getArgument(0).getStringValue()); 1159 if (index == -1) 1160 index = 0; 1161 for (int i = 0; i < buffertuple.size(); i++) { 1162 Tuple tuplei = (Tuple) buffertuple.get(i); 1163 Comparable valuei = null; 1166 TypedNode treei = (TypedNode) tuplei.getNodesAtIndex(index).get(0); 1167 try { 1168 if (treei.getTypedValue() != null) 1169 valuei = (Comparable ) treei.getTypedValue(); 1170 else 1171 valuei = (Comparable ) DOMUtils.getTextLeaf(treei); 1172 } catch (ClassCastException cce) { 1173 } 1175 if (valuei == null) 1176 return; 1177 if (max == null) { 1178 max = valuei; 1179 result = treei; 1180 } else if (DOMUtils.compareObjects(valuei,max) > 0) { 1181 max = valuei; 1182 result = treei; 1183 } 1184 } 1185 } else { 1186 returnType.push(NODE_TYPE); 1187 arg.getArgument(0).accept(this); 1188 returnType.pop(); 1189 if (resnodes == null || resnodes.isEmpty()) 1190 return; 1191 1192 for (int i = 0; i < resnodes.size(); i++) { 1193 Comparable valuei = null; 1194 TypedNode treei = (TypedNode) resnodes.get(i); 1195 try { 1196 if (treei.getTypedValue() != null) 1197 valuei = (Comparable ) treei.getTypedValue(); 1198 else 1199 valuei = (Comparable ) DOMUtils.getTextLeaf(treei); 1200 } catch (ClassCastException cce) { 1201 } 1203 if (valuei == null) 1204 return; 1205 if (max == null) { 1206 max = valuei; 1207 result = treei; 1208 } else if (DOMUtils.compareObjects(valuei,max) > 0) { 1209 max = valuei; 1210 result = treei; 1211 } 1212 } 1213 } 1214 1215 Integer retType = (Integer ) this.returnType.peek(); 1216 if (retType == TUPLE_TYPE) { 1217 Tuple tuple = new Tuple(1); 1218 TypedValue text = docimpl.createTypedValue(max, (SimpleType) result.getType()); 1219 tuple.addNodeAtIndex(0, text); 1220 setResultTuple(tuple); 1221 return; 1222 } else if (retType == NODE_TYPE) { 1223 ArrayList nodes = new ArrayList(1); 1224 TypedValue text = docimpl.createTypedValue(max, (SimpleType) result.getType()); 1225 nodes.add(text); 1226 setResnodes(nodes); 1227 return; 1228 } else { 1229 setValue(max); 1230 return; 1231 } 1232 1234 } 1235 1236 public void visit(FunctionMIN arg) throws XQueryException { 1237 Comparable min = null; 1238 TypedNode result = null; 1239 if (buffertuple != null) { 1241 int index = buffertuple.getPathIndex(arg.getArgument(0).getStringValue()); 1242 if (index == -1) 1243 index = 0; 1244 for (int i = 0; i < buffertuple.size(); i++) { 1245 Tuple tuplei = (Tuple) buffertuple.get(i); 1246 Comparable valuei = null; 1249 TypedNode treei = (TypedNode) tuplei.getNodesAtIndex(index).get(0); 1250 try { 1251 if (treei.getTypedValue() != null) 1252 valuei = (Comparable ) treei.getTypedValue(); 1253 else 1254 valuei = (Comparable ) DOMUtils.getTextLeaf(treei); 1255 } catch (ClassCastException cce) { 1256 } 1258 if (valuei == null) 1259 return; 1260 if (min == null) { 1261 min = valuei; 1262 result = treei; 1263 } else if (DOMUtils.compareObjects(valuei,min) < 0) { 1264 min = valuei; 1265 result = treei; 1266 } 1267 } 1268 } else { 1269 returnType.push(NODE_TYPE); 1270 arg.getArgument(0).accept(this); 1271 returnType.pop(); 1272 if (resnodes == null || resnodes.isEmpty()) 1273 return; 1274 1275 for (int i = 0; i < resnodes.size(); i++) { 1276 Comparable valuei = null; 1277 TypedNode treei = (TypedNode) resnodes.get(i); 1278 try { 1279 if (treei.getTypedValue() != null) 1280 valuei = (Comparable ) treei.getTypedValue(); 1281 else 1282 valuei = (Comparable ) DOMUtils.getTextLeaf(treei); 1283 } catch (ClassCastException cce) { 1284 } 1286 if (valuei == null) 1287 return; 1288 if (min == null) { 1289 min = valuei; 1290 result = treei; 1291 } else if (DOMUtils.compareObjects(valuei,min) < 0) { 1292 min = valuei; 1293 result = treei; 1294 } 1295 } 1296 } 1297 1298 Integer retType = (Integer ) this.returnType.peek(); 1299 if (retType == TUPLE_TYPE) { 1300 Tuple tuple = new Tuple(1); 1301 TypedValue text = docimpl.createTypedValue(min, (SimpleType) result.getType()); 1302 tuple.addNodeAtIndex(0, text); 1303 setResultTuple(tuple); 1304 return; 1305 } else if (retType == NODE_TYPE) { 1306 ArrayList nodes = new ArrayList(1); 1307 TypedValue text = docimpl.createTypedValue(min, (SimpleType) result.getType()); 1308 nodes.add(text); 1309 setResnodes(nodes); 1310 return; 1311 } else { 1312 setValue(min); 1313 return; 1314 } 1315 1317 } 1318 1319 public void visit(FunctionCOUNT arg) throws XQueryException { 1320 long strvalue = 0; 1321 if (buffertuple != null) { 1323 strvalue = buffertuple.size(); 1324 } else { 1325 returnType.push(NODE_TYPE); 1326 arg.getArgument(0).accept(this); 1327 returnType.pop(); 1328 if (resnodes != null) 1329 strvalue = resnodes.size(); 1330 } 1331 1332 Integer retType = (Integer ) this.returnType.peek(); 1333 if (retType == TUPLE_TYPE) { 1334 Tuple tuple = new Tuple(1); 1335 TypedValue text = docimpl.createTypedValue(new Long (strvalue), this.schemamanager.getIntegerType()); 1336 tuple.addNodeAtIndex(0, text); 1337 setResultTuple(tuple); 1338 return; 1339 } else if (retType == NODE_TYPE) { 1340 ArrayList nodes = new ArrayList(1); 1341 TypedValue text = docimpl.createTypedValue(new Long (strvalue), this.schemamanager.getIntegerType()); 1342 nodes.add(text); 1343 setResnodes(nodes); 1344 return; 1345 } else { 1346 setValue(new Long (strvalue)); 1347 return; 1348 } 1349 } 1351 1352 Calendar cal = Calendar.getInstance(); 1365 1366 public void visit(FunctionCURRENT_DATETIME arg) throws XQueryException { 1367 resvalue = Calendar.getInstance().getTime(); 1368 Integer rettype = (Integer ) returnType.peek(); 1369 if (rettype == NODE_TYPE) { 1370 ArrayList nodes = new ArrayList(1); 1371 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType())); 1372 setResnodes(nodes); 1373 return; 1374 } else { setValue(resvalue); 1376 return; 1377 } 1378 } 1380 1381 public void visit(FunctionDATE arg) throws XQueryException { 1382 returnType.push(VALUE_TYPE); 1383 arg.getArgument(0).accept(this); 1384 returnType.pop(); 1385 if (resvalue instanceof Date) { cal.setTime((Date) resvalue); 1387 cal.set(Calendar.HOUR, 0); 1388 cal.set(Calendar.MINUTE, 0); 1389 cal.set(Calendar.SECOND, 0); 1390 resvalue = cal.getTime(); 1391 } else if (resvalue instanceof String ) { 1392 try { 1393 resvalue = (Comparable ) this.schemamanager.getDateType().convert((String ) resvalue, true, null); 1394 } catch (SchemaException se) { 1395 throw new XQueryException("Argument of function date is not a valid date"); 1396 } 1397 } else 1398 throw new XQueryException("Argument of function date cannot be converted"); 1399 Integer rettype = (Integer ) returnType.peek(); 1400 if (rettype == NODE_TYPE) { 1401 ArrayList nodes = new ArrayList(1); 1402 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateType())); 1403 setResnodes(nodes); 1404 return; 1405 } else { setValue(resvalue); 1407 return; 1408 } 1409 } 1411 1412 public void visit(FunctionDATETIME arg) throws XQueryException { 1413 returnType.push(VALUE_TYPE); 1414 arg.getArgument(0).accept(this); 1415 returnType.pop(); 1416 if (resvalue instanceof Date) { } else if (resvalue instanceof String ) { 1418 try { 1419 resvalue = (Comparable ) this.schemamanager.getDateTimeType().convert((String ) resvalue, true, null); 1420 } catch (SchemaException se) { 1421 throw new XQueryException("Argument of function datetime is not a valid date"); 1422 } 1423 } else 1424 throw new XQueryException("Argument of function datetime cannot be converted"); 1425 Integer rettype = (Integer ) returnType.peek(); 1426 if (rettype == NODE_TYPE) { 1427 ArrayList nodes = new ArrayList(1); 1428 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType())); 1429 setResnodes(nodes); 1430 return; 1431 } else { setValue(resvalue); 1433 return; 1434 } 1435 } 1437 1438 public void visit(FunctionTIME arg) throws XQueryException { 1439 returnType.push(VALUE_TYPE); 1440 arg.getArgument(0).accept(this); 1441 returnType.pop(); 1442 if (resvalue instanceof Date) { } else if (resvalue instanceof String ) { 1444 try { 1445 resvalue = (Comparable ) this.schemamanager.getTimeType().convert((String ) resvalue, true, null); 1446 } catch (SchemaException se) { 1447 throw new XQueryException("Argument of function time is not a valid date"); 1448 } 1449 } else 1450 throw new XQueryException("Argument of function time cannot be converted"); 1451 1459 cal.setTime((Date) resvalue); 1460 cal.set(Calendar.YEAR, 0); 1461 cal.set(Calendar.MONTH, 0); 1462 cal.set(Calendar.DAY_OF_MONTH, 0); 1463 resvalue = cal.getTime(); 1464 Integer rettype = (Integer ) returnType.peek(); 1465 if (rettype == NODE_TYPE) { 1466 ArrayList nodes = new ArrayList(1); 1467 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getTimeType())); 1468 setResnodes(nodes); 1469 return; 1470 } else { setValue(resvalue); 1472 return; 1473 } 1474 } 1476 1477 public void visit(FunctionGET_YEAR_FROM_DATE arg) throws XQueryException { 1478 returnType.push(VALUE_TYPE); 1479 arg.getArgument(0).accept(this); 1480 returnType.pop(); 1481 if (resvalue == null) { 1482 clear(); 1483 return; 1484 } 1485 if (resvalue instanceof Date) 1486 throw new XQueryException("Argument of function get-year-from-date is not a date"); 1487 cal.setTime((Date) resvalue); 1488 resvalue = new Long (cal.get(Calendar.YEAR)); 1489 Integer rettype = (Integer ) returnType.peek(); 1490 if (rettype == NODE_TYPE) { 1491 ArrayList nodes = new ArrayList(1); 1492 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType()))); 1493 setResnodes(nodes); 1494 return; 1495 } else { setValue(resvalue); 1497 return; 1498 } 1499 } 1501 1502 public void visit(FunctionGET_MONTH_FROM_DATE arg) throws XQueryException { 1503 returnType.push(VALUE_TYPE); 1504 arg.getArgument(0).accept(this); 1505 returnType.pop(); 1506 if (resvalue == null) { 1507 clear(); 1508 return; 1509 } 1510 if (resvalue instanceof Date) 1511 throw new XQueryException("Argument of function get-month-from-date is not a date"); 1512 cal.setTime((Date) resvalue); 1513 resvalue = new Long (cal.get(Calendar.MONTH)); 1514 Integer rettype = (Integer ) returnType.peek(); 1515 if (rettype == NODE_TYPE) { 1516 ArrayList nodes = new ArrayList(1); 1517 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType()))); 1518 setResnodes(nodes); 1519 return; 1520 } else { setValue(resvalue); 1522 return; 1523 } 1524 } 1526 1527 1531 private Comparable c0 = null; 1532 private Comparable c1 = null; 1533 1534 private void getComparables(XQueryExpression arg0, XQueryExpression arg1) throws XQueryException { 1535 resulttuple = null; 1536 resnodes = null; 1537 c0 = null; 1538 c1 = null; 1539 if (arg0 instanceof Value) 1540 c0 = (((Value) arg0).getValue()); 1541 if (arg1 instanceof Value) 1542 c1 = (((Value) arg1).getValue()); 1543 if (c0 == null) { 1544 returnType.push(VALUE_TYPE); 1545 arg0.accept(this); 1546 returnType.pop(); 1547 c0 = this.resvalue; 1548 if (c0 == null && resnodes != null && resnodes.size() == 1) { 1549 TypedNode node = (TypedNode) resnodes.get(0); 1550 if (node instanceof TypedValueImpl) { 1551 c0 = (Comparable ) node.getTypedValue(); 1552 } else if (node instanceof TypedElementImpl) { 1553 StringBuffer sb = new StringBuffer (); 1554 DOMUtils.getStringValue(node, sb); 1555 c0 = sb.toString(); 1556 } 1557 } 1558 } 1559 if (c1 == null) { 1560 returnType.push(VALUE_TYPE); 1561 arg1.accept(this); 1562 returnType.pop(); 1563 c1 = this.resvalue; 1564 if (c1 == null && resnodes != null && resnodes.size() == 1) { 1565 TypedNode node = (TypedNode) resnodes.get(0); 1566 if (node instanceof TypedValueImpl) { 1567 c1 = (Comparable ) node.getTypedValue(); 1568 } else if (node instanceof TypedElementImpl) { 1569 StringBuffer sb = new StringBuffer (); 1570 DOMUtils.getStringValue(node, sb); 1571 c1 = sb.toString(); 1572 } 1573 } 1574 } 1575 1576 } 1577 1578 public void visit(FunctionLOWER_CASE arg) throws XQueryException { 1579 returnType.push(UNKNOWN_TYPE); 1580 arg.getArgument(0).accept(this); 1581 returnType.pop(); 1582 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1584 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1585 if (tmpnode == null) 1586 tmpnode = (TypedNode) resnodes.get(0); 1587 resvalue = (Comparable ) tmpnode.getTypedValue(); 1588 } 1589 if (resvalue instanceof String ) { 1590 resvalue = ((String ) resvalue).toLowerCase(); 1591 } else { 1592 throw new XQueryException("Argument of function lower-case is not a string"); 1593 } 1594 Integer rettype = (Integer ) returnType.peek(); 1595 if (rettype == VALUE_TYPE) { 1596 setValue(resvalue); 1597 return; 1598 } else if (rettype == NODE_TYPE) { 1599 ArrayList nodes = new ArrayList(1); 1600 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType()))); 1601 setResnodes(nodes); 1602 return; 1603 } 1604 } 1605 1606 public void visit(FunctionUPPER_CASE arg) throws XQueryException { 1607 returnType.push(UNKNOWN_TYPE); 1608 arg.getArgument(0).accept(this); 1609 returnType.pop(); 1610 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1612 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1613 if (tmpnode == null) 1614 tmpnode = (TypedNode) resnodes.get(0); 1615 resvalue = (Comparable ) tmpnode.getTypedValue(); 1616 } 1617 if (resvalue instanceof String ) { 1618 resvalue = ((String ) resvalue).toUpperCase(); 1619 } else { 1620 throw new XQueryException("Argument of function upper-case is not a string"); 1621 } 1622 Integer rettype = (Integer ) returnType.peek(); 1623 if (rettype == VALUE_TYPE) { 1624 setValue(resvalue); 1625 return; 1626 } else if (rettype == NODE_TYPE) { 1627 ArrayList nodes = new ArrayList(1); 1628 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType()))); 1629 setResnodes(nodes); 1630 return; 1631 } 1632 } 1633 1634 public void visit(FunctionCONCAT arg) throws XQueryException { 1635 StringBuffer buf = new StringBuffer (); 1636 for (int i = 0; i < arg.getArguments().size(); i++) { 1637 returnType.push(UNKNOWN_TYPE); 1638 arg.getArgument(i).accept(this); 1639 returnType.pop(); 1640 if (resvalue != null) { if (resvalue instanceof String ) 1642 buf.append(resvalue); 1643 else 1644 buf.append(resvalue.toString()); 1645 } else if (resnodes == null || resnodes.isEmpty()) { } else if (resnodes != null && resnodes.size() == 1) { 1647 StringBuffer sb = new StringBuffer (); 1648 DOMUtils.getStringValue((TypedNode) resnodes.get(0), sb); 1649 buf.append(sb.toString()); 1650 } else if (resnodes != null && resnodes.size() > 1) { 1651 throw new XQueryException("Evaluation : incorrect argument for function concat"); 1652 } 1653 } 1654 Integer rettype = (Integer ) returnType.peek(); 1655 if (rettype == NODE_TYPE) { 1656 ArrayList nodes = new ArrayList(1); 1657 nodes.add(docimpl.createTypedValue(buf.toString(), this.schemamanager.getStringType())); 1658 setResnodes(nodes); 1659 return; 1660 } else { setValue(buf.toString()); 1662 return; 1663 } 1664 } 1666 1667 public void visit(FunctionCONTAINS arg) throws XQueryException { 1668 getComparables(arg.getArgument(0), arg.getArgument(1)); 1669 if (c0 != null && c1 != null) { 1670 setVerdict(((String ) c0).indexOf((String ) c1) != -1); 1671 return; 1672 } 1673 clear(); 1674 } 1675 1676 public void visit(FunctionENDS_WITH arg) throws XQueryException { 1677 getComparables(arg.getArgument(0), arg.getArgument(1)); 1678 if (c0 != null && c1 != null) { 1679 setVerdict(((String ) c0).endsWith((String ) c1)); 1680 return; 1681 } 1682 clear(); 1683 } 1684 1685 public void visit(FunctionSTARTS_WITH arg) throws XQueryException { 1686 getComparables(arg.getArgument(0), arg.getArgument(1)); 1687 if (c0 != null && c1 != null) { 1688 setVerdict(((String ) c0).startsWith((String ) c1)); 1689 return; 1690 } 1691 clear(); 1692 } 1693 1694 public void visit(FunctionLOCAL_NAME arg) throws XQueryException { 1695 returnType.push(NODE_TYPE); 1696 arg.getArgument(0).accept(this); 1697 returnType.pop(); 1698 Integer rettype = (Integer ) returnType.peek(); 1699 if (this.resnodes != null && resnodes.size() == 1) { 1701 this.setValue(((TypedNode) resnodes.get(0)).getLocalName()); 1702 return; 1703 } 1704 clear(); 1706 } 1707 1708 public void visit(FunctionNAMESPACE_URI arg) throws XQueryException { 1709 returnType.push(NODE_TYPE); 1710 arg.getArgument(0).accept(this); 1711 returnType.pop(); 1712 Integer rettype = (Integer ) returnType.peek(); 1713 if (this.resnodes != null && resnodes.size() == 1) { 1715 this.setValue(((TypedNode) resnodes.get(0)).getNamespaceURI()); 1716 return; 1717 } 1718 clear(); 1720 } 1721 1722 1754 public void visit(FunctionSTRING arg) throws XQueryException { 1755 returnType.push(UNKNOWN_TYPE); 1756 arg.getArgument(0).accept(this); 1757 returnType.pop(); 1758 if (resvalue != null) { if (!(resvalue instanceof String )) 1760 resvalue = resvalue.toString(); 1761 } else if (resnodes == null || resnodes.isEmpty()) { 1762 resvalue = new String (""); 1763 } else if (resnodes != null && resnodes.size() == 1) { 1764 StringBuffer sb = new StringBuffer (); 1765 DOMUtils.getStringValue((TypedNode) resnodes.get(0), sb); 1766 resvalue = sb.toString(); 1767 } else if (resnodes != null && resnodes.size() > 1) { 1768 throw new XQueryException("Evaluation : incorrect argument for function string"); 1769 } 1770 Integer rettype = (Integer ) returnType.peek(); 1771 if (rettype == NODE_TYPE) { 1772 ArrayList nodes = new ArrayList(1); 1773 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType()); 1774 nodes.add(text); 1775 setResnodes(nodes); 1776 return; 1777 } else { setValue(resvalue); 1779 return; 1780 } 1781 } 1783 1784 1797 public void visit(FunctionSTRING_LENGTH arg) throws XQueryException { 1798 returnType.push(UNKNOWN_TYPE); 1799 arg.getArgument(0).accept(this); 1800 returnType.pop(); 1801 if (resvalue != null) { if (resvalue instanceof String ) 1803 resvalue = new Long (((String ) resvalue).length()); 1804 else 1805 resvalue = new Long (resvalue.toString().length()); 1806 } else if (resnodes == null || resnodes.isEmpty()) { 1807 resvalue = new Long (0); 1808 } else if (resnodes != null && resnodes.size() == 1) { 1809 StringBuffer sb = new StringBuffer (); 1810 DOMUtils.getStringValue((TypedNode) resnodes.get(0), sb); 1811 resvalue = new Long (sb.length()); 1812 } else if (resnodes != null && resnodes.size() > 1) { 1813 throw new XQueryException("Evaluation : incorrect argument for function string-length"); 1814 } 1815 Integer rettype = (Integer ) returnType.peek(); 1816 if (rettype == NODE_TYPE) { 1817 ArrayList nodes = new ArrayList(1); 1818 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 1819 nodes.add(text); 1820 setResnodes(nodes); 1821 return; 1822 } else { setValue(resvalue); 1824 return; 1825 } 1826 } 1828 1829 1861 public void visit(FunctionSUBSTRING arg) throws XQueryException { 1862 boolean hasLength = (arg.getArguments().size() == 3) ? true : false; 1863 String sourceString = null; 1864 returnType.push(UNKNOWN_TYPE); 1865 arg.getArgument(0).accept(this); 1866 if (resvalue != null) { 1867 if (resvalue instanceof String ) 1868 sourceString = (String ) resvalue; 1869 else 1870 sourceString = resvalue.toString(); 1871 } else if (resnodes != null && resnodes.size() == 1) { 1872 StringBuffer sb = new StringBuffer (); 1873 DOMUtils.getStringValue((TypedNode) resnodes.get(0), sb); 1874 sourceString = sb.toString(); 1875 } else if (resnodes != null && resnodes.size() > 1) { 1876 throw new XQueryException("Evaluation : incorrect first argument for function substring"); 1877 } 1878 if (sourceString == null) { 1879 clear(); 1880 return; 1881 } 1882 double startingLoc = 0; 1883 arg.getArgument(1).accept(this); 1884 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1886 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1887 if (tmpnode == null) 1888 tmpnode = (TypedNode) resnodes.get(0); 1889 resvalue = (Comparable ) tmpnode.getTypedValue(); 1890 } else 1891 throw new XQueryException("Evaluation : incorrect second argument for function substring"); 1892 if (resvalue instanceof Number ) { 1893 startingLoc = ((Number ) resvalue).doubleValue(); 1894 } else if (resvalue instanceof String ) { 1895 try { 1896 startingLoc = Double.parseDouble((String ) resvalue); 1897 } catch (NumberFormatException e) { 1898 } 1900 } else 1901 throw new XQueryException("Evaluation : incorrect second argument for function substring"); 1902 if (startingLoc < 1) 1903 startingLoc = 1; 1904 double length = sourceString.length(); 1905 if (hasLength) { 1906 arg.getArgument(2).accept(this); 1907 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1909 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1910 if (tmpnode == null) 1911 tmpnode = (TypedNode) resnodes.get(0); 1912 resvalue = (Comparable ) tmpnode.getTypedValue(); 1913 } else 1914 throw new XQueryException("Evaluation : incorrect third argument for function substring"); 1915 if (resvalue instanceof Number ) { 1916 length = ((Number ) resvalue).doubleValue(); 1917 } else if (resvalue instanceof String ) { 1918 try { 1919 length = Double.parseDouble((String ) resvalue); 1920 } catch (NumberFormatException e) { 1921 } 1923 } else 1924 throw new XQueryException("Evaluation : incorrect third argument for function substring"); 1925 if (startingLoc + length > sourceString.length()) 1926 hasLength = false; 1927 } 1928 returnType.pop(); 1929 if (hasLength) 1930 resvalue = sourceString.substring((int) Math.round(startingLoc) - 1, (int) (Math.round(startingLoc) + Math.round(length)) - 1); 1931 else 1932 resvalue = sourceString.substring((int) Math.round(startingLoc) - 1); 1933 Integer rettype = (Integer ) returnType.peek(); 1934 if (rettype == NODE_TYPE) { 1935 ArrayList nodes = new ArrayList(1); 1936 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType()); 1937 nodes.add(text); 1938 setResnodes(nodes); 1939 return; 1940 } else { setValue(resvalue); 1942 return; 1943 } 1944 } 1946 1947 public void visit(FunctionABS arg) throws XQueryException { 1951 returnType.push(UNKNOWN_TYPE); 1952 arg.getArgument(0).accept(this); 1953 returnType.pop(); 1954 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1956 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1957 if (tmpnode == null) 1958 tmpnode = (TypedNode) resnodes.get(0); 1959 resvalue = (Comparable ) tmpnode.getTypedValue(); 1960 if (!(resvalue instanceof Number )) 1961 throw new XQueryException("Could not apply function abs"); 1962 } else 1963 throw new XQueryException("Could not apply function abs"); 1964 1965 if (resvalue instanceof Long ) 1966 resvalue = new Long (Math.abs(((Long ) resvalue).longValue())); 1967 else if (resvalue instanceof BigDecimal ) 1968 resvalue = ((BigDecimal ) resvalue).abs(); 1969 else if (resvalue instanceof Float ) 1970 resvalue = new Float (Math.abs(((Float ) resvalue).floatValue())); 1971 else if (resvalue instanceof Double ) 1972 resvalue = new Double (Math.abs(((Double ) resvalue).doubleValue())); 1973 1974 Integer rettype = (Integer ) returnType.peek(); 1975 if (rettype == VALUE_TYPE) { 1976 setValue(resvalue); 1977 return; 1978 } else { ArrayList nodes = new ArrayList(1); 1980 TypedValue text = docimpl.createTypedValue(resvalue, getSimpleType(resvalue, schemamanager.getDoubleType())); 1981 nodes.add(text); 1982 setResnodes(nodes); 1983 return; 1984 } 1985 } 1987 public void visit(FunctionCEILING arg) throws XQueryException { 1988 returnType.push(UNKNOWN_TYPE); 1989 arg.getArgument(0).accept(this); 1990 returnType.pop(); 1991 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1993 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1994 if (tmpnode == null) 1995 tmpnode = (TypedNode) resnodes.get(0); 1996 resvalue = (Comparable ) tmpnode.getTypedValue(); 1997 if (!(resvalue instanceof Number )) 1998 throw new XQueryException("Could not apply function ceiling"); 1999 } else 2000 throw new XQueryException("Could not apply function ceiling"); 2001 2002 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 2004 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_CEILING); 2005 else if (resvalue instanceof Float ) 2006 resvalue = new Float (Math.ceil(((Float ) resvalue).floatValue())); 2007 else if (resvalue instanceof Double ) 2008 resvalue = new Double (Math.ceil(((Double ) resvalue).doubleValue())); 2009 2010 Integer rettype = (Integer ) returnType.peek(); 2011 if (rettype == VALUE_TYPE) { 2012 setValue(resvalue); 2013 return; 2014 } else { ArrayList nodes = new ArrayList(1); 2016 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 2017 nodes.add(text); 2018 setResnodes(nodes); 2019 return; 2020 } 2021 } 2023 public void visit(FunctionFLOOR arg) throws XQueryException { 2024 returnType.push(UNKNOWN_TYPE); 2025 arg.getArgument(0).accept(this); 2026 returnType.pop(); 2027 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2029 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2030 if (tmpnode == null) 2031 tmpnode = (TypedNode) resnodes.get(0); 2032 resvalue = (Comparable ) tmpnode.getTypedValue(); 2033 if (!(resvalue instanceof Number )) 2034 throw new XQueryException("Could not apply function floor"); 2035 } else 2036 throw new XQueryException("Could not apply function floor"); 2037 2038 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 2040 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_FLOOR); 2041 else if (resvalue instanceof Float ) 2042 resvalue = new Float (Math.floor(((Float ) resvalue).floatValue())); 2043 else if (resvalue instanceof Double ) 2044 resvalue = new Double (Math.floor(((Double ) resvalue).doubleValue())); 2045 2046 Integer rettype = (Integer ) returnType.peek(); 2047 if (rettype == VALUE_TYPE) { 2048 setValue(resvalue); 2049 return; 2050 } else { ArrayList nodes = new ArrayList(1); 2052 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 2053 nodes.add(text); 2054 setResnodes(nodes); 2055 return; 2056 } 2057 } 2059 public void visit(FunctionROUND arg) throws XQueryException { 2060 returnType.push(UNKNOWN_TYPE); 2061 arg.getArgument(0).accept(this); 2062 returnType.pop(); 2063 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2065 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2066 if (tmpnode == null) 2067 tmpnode = (TypedNode) resnodes.get(0); 2068 resvalue = (Comparable ) tmpnode.getTypedValue(); 2069 if (!(resvalue instanceof Number )) 2070 throw new XQueryException("Could not apply function round"); 2071 } else 2072 throw new XQueryException("Could not apply function round"); 2073 2074 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 2076 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_UP); 2077 else if (resvalue instanceof Float ) 2078 resvalue = new BigDecimal (Math.round(((Float ) resvalue).floatValue())); 2079 else if (resvalue instanceof Double ) 2080 resvalue = new BigDecimal (Math.round(((Double ) resvalue).doubleValue())); 2081 2082 Integer rettype = (Integer ) returnType.peek(); 2083 if (rettype == VALUE_TYPE) { 2084 setValue(resvalue); 2085 return; 2086 } else { ArrayList nodes = new ArrayList(1); 2088 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 2089 nodes.add(text); 2090 setResnodes(nodes); 2091 return; 2092 } 2093 } 2095 2096 2112 public void visit(FunctionNUMBER arg) throws XQueryException { 2113 returnType.push(UNKNOWN_TYPE); 2114 arg.getArgument(0).accept(this); 2115 returnType.pop(); 2116 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2118 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2119 if (tmpnode == null) 2120 tmpnode = (TypedNode) resnodes.get(0); 2121 resvalue = (Comparable ) tmpnode.getTypedValue(); 2122 if (resvalue instanceof Number ) { 2123 resvalue = new Double (((Number ) resvalue).doubleValue()); 2124 } else if (resvalue instanceof String ) { 2125 try { 2126 resvalue = new Double (Double.parseDouble((String ) resvalue)); 2127 } catch (NumberFormatException e) { 2128 } 2130 } 2131 } else if (resnodes != null && resnodes.size() > 1) { 2132 throw new XQueryException("Evaluation : incorrect argument for function number"); 2133 } 2134 if (resvalue == null) { 2135 resvalue = new Double (Double.NaN); 2136 } 2137 Integer rettype = (Integer ) returnType.peek(); 2138 if (rettype == NODE_TYPE) { 2139 ArrayList nodes = new ArrayList(1); 2140 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 2141 nodes.add(text); 2142 setResnodes(nodes); 2143 return; 2144 } else { setValue(resvalue); 2146 return; 2147 } 2148 } 2150 2151 public void visit(FunctionDOUBLE arg) throws XQueryException { 2155 returnType.push(UNKNOWN_TYPE); 2156 arg.getArgument(0).accept(this); 2157 returnType.pop(); 2158 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2160 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2161 if (tmpnode == null) 2162 tmpnode = (TypedNode) resnodes.get(0); 2163 resvalue = (Comparable ) tmpnode.getTypedValue(); 2164 } else 2165 throw new XQueryException("Could not create double"); 2166 2167 if (resvalue instanceof Double ) { } else if (resvalue instanceof Number ) { 2169 resvalue = new Double (((Number ) resvalue).doubleValue()); 2170 } else if (resvalue instanceof String ) { 2171 try { 2172 resvalue = new Double (Double.parseDouble((String ) resvalue)); 2173 } catch (NumberFormatException e) { 2174 } 2176 } else 2177 throw new XQueryException("Could not create double"); 2178 Integer rettype = (Integer ) returnType.peek(); 2179 if (rettype == VALUE_TYPE) { 2180 setValue(resvalue); 2181 return; 2182 } else { ArrayList nodes = new ArrayList(1); 2184 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 2185 nodes.add(text); 2186 setResnodes(nodes); 2187 return; 2188 } 2189 } 2191 2192 public void visit(FunctionINTEGER arg) throws XQueryException { 2193 returnType.push(UNKNOWN_TYPE); 2194 arg.getArgument(0).accept(this); 2195 returnType.pop(); 2196 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2198 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2199 if (tmpnode == null) 2200 tmpnode = (TypedNode) resnodes.get(0); 2201 resvalue = (Comparable ) tmpnode.getTypedValue(); 2202 } else 2203 throw new XQueryException("Could not create integer"); 2204 2205 if (resvalue instanceof Long ) { } else if (resvalue instanceof Number ) { 2207 resvalue = new Long (((Number ) resvalue).longValue()); 2208 } else if (resvalue instanceof String ) { 2209 try { 2210 resvalue = new Long ((String ) resvalue); 2211 } catch (NumberFormatException e) { 2212 } 2214 } else 2215 throw new XQueryException("Could not create integer"); 2216 Integer rettype = (Integer ) returnType.peek(); 2217 if (rettype == VALUE_TYPE) { 2218 setValue(resvalue); 2219 return; 2220 } else { ArrayList nodes = new ArrayList(1); 2222 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 2223 nodes.add(text); 2224 setResnodes(nodes); 2225 return; 2226 } 2227 } 2229 2230 public void visit(FunctionDECIMAL arg) throws XQueryException { 2231 returnType.push(UNKNOWN_TYPE); 2232 arg.getArgument(0).accept(this); 2233 returnType.pop(); 2234 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 2236 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 2237 if (tmpnode == null) 2238 tmpnode = (TypedNode) resnodes.get(0); 2239 resvalue = (Comparable ) tmpnode.getTypedValue(); 2240 } else 2241 throw new XQueryException("Could not create decimal"); 2242 2243 if (resvalue instanceof BigDecimal ) { } else if (resvalue instanceof Number ) { 2245 resvalue = new BigDecimal (((Number ) resvalue).doubleValue()); 2246 } else if (resvalue instanceof String ) { 2247 try { 2248 resvalue = new BigDecimal ((String ) resvalue); 2249 } catch (NumberFormatException e) { 2250 } 2252 } else 2253 throw new XQueryException("Could not create decimal"); 2254 Integer rettype = (Integer ) returnType.peek(); 2255 if (rettype == VALUE_TYPE) { 2256 setValue(resvalue); 2257 return; 2258 } else { ArrayList nodes = new ArrayList(1); 2260 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType()); 2261 nodes.add(text); 2262 setResnodes(nodes); 2263 return; 2264 } 2265 } 2267 2268 2272 public void visit(FunctionDATA arg) throws XQueryException { 2273 returnType.push(UNKNOWN_TYPE); 2274 arg.getArgument(0).accept(this); 2275 returnType.pop(); 2276 Integer rettype = (Integer ) returnType.peek(); 2277 if (resvalue != null) { 2278 if (rettype == VALUE_TYPE) { 2279 setValue(resvalue); 2280 return; 2281 } else { ArrayList nodes = new ArrayList(1); 2283 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getAnySimpleType())); 2284 nodes.add(text); 2285 setResnodes(nodes); 2286 return; 2287 } 2288 } else if (resnodes != null) { 2289 ArrayList tmplist = new ArrayList(resnodes.size()); 2290 for (int i = 0; i < resnodes.size(); i++) { 2291 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(i)).getFirstChild(); 2292 if (tmpnode == null || tmpnode.getTypedValue() == null) 2294 tmpnode = (TypedNode) resnodes.get(i); 2295 Comparable comp = (Comparable ) tmpnode.getTypedValue(); 2296 if (comp != null) 2297 tmplist.add(docimpl.createTypedValue(comp, this.getSimpleType(comp, schemamanager.getAnySimpleType()))); 2298 } 2301 if (rettype == VALUE_TYPE) { 2302 if (tmplist.size() == 1) { 2303 TypedNode tmpnode = (TypedNode) ((TypedNode) tmplist.get(0)).getFirstChild(); 2304 if (tmpnode == null) 2305 tmpnode = (TypedNode) tmplist.get(0); 2306 setValue((Comparable ) tmpnode.getTypedValue()); 2307 return; 2308 } 2309 } else { setResnodes(tmplist); 2311 return; 2312 } 2313 } 2314 } 2318 2319 public void visit(FunctionEXISTS arg) throws XQueryException { 2320 returnType.push(NODE_TYPE); 2321 arg.getArgument(0).accept(this); 2322 returnType.pop(); 2323 setVerdict(resnodes != null && !resnodes.isEmpty()); 2324 } 2325 2326 public void visit(FunctionEMPTY arg) throws XQueryException { 2327 if (buffertuple != null && !buffertuple.isEmpty()) { 2328 setVerdict(false); 2329 return; 2330 } 2331 returnType.push(NODE_TYPE); 2332 arg.getArgument(0).accept(this); 2333 returnType.pop(); 2334 setVerdict(resnodes == null || resnodes.isEmpty()); 2335 } 2336 2337 public void visit(FunctionNOT arg) throws XQueryException { 2338 arg.getArgument(0).accept(this); 2339 setVerdict(!verdict); 2340 } 2341 2342 public void visit(FunctionDISTINCT_VALUES arg) throws XQueryException { 2343 returnType.push(NODE_TYPE); 2344 arg.getArgument(0).accept(this); 2345 returnType.pop(); 2346 if (resnodes != null) { 2347 resnodes = (ArrayList) resnodes.clone(); 2349 for (int i = 0; i < resnodes.size(); i++) { 2350 TypedNode nodei = (TypedNode) resnodes.get(i); 2351 for (int j = 0; j < i; j++) { 2352 TypedNode nodej = (TypedNode) resnodes.get(j); 2353 if (DOMUtils.compareTree(nodei, nodej)) { 2354 resnodes.remove(i); 2355 i--; 2356 break; 2357 } 2358 } 2359 } 2360 } 2361 setResnodes(resnodes); 2362 } 2363 2364 public void visit(FunctionDEEP_EQUALS arg) throws XQueryException { 2365 resulttuple = null; 2366 resnodes = null; 2367 XQueryExpression arg0 = arg.getArgument(0); 2368 XQueryExpression arg1 = arg.getArgument(1); 2369 if (arg0 instanceof Value && arg1 instanceof Value) 2370 processComparison(arg0, arg1, null, null, null, null, Constants.EQ_COMPOP); 2371 else { 2372 if (arg0 instanceof Value) { 2373 if (tuple != null) { 2374 ArrayList nodes1 = tuple.getNodesAtIndex(tuple.getParent().getPathIndex(arg1.getStringValue())); 2375 if (nodes1 != null && nodes1.size() == 1) { 2376 processComparison(arg0, arg1, (TypedNode) null, (TypedNode) nodes1.get(0), null, null, Constants.EQ_COMPOP); 2377 } 2378 } else if (tuplelist != null) { 2379 for (int i = 0; i < tuplelist.size(); i++) { 2380 Tuple tuplei = (Tuple) tuplelist.get(i); 2381 ArrayList nodes1 = tuplei.getNodesAtIndex(tuplei.getParent().getPathIndex(arg1.getStringValue())); 2382 if (nodes1 != null && nodes1.size() == 1) { 2383 processComparison(arg0, arg1, (TypedNode) null, (TypedNode) nodes1.get(0), null, null, Constants.EQ_COMPOP); 2384 break; 2385 } 2386 } 2387 } 2388 } else if (arg1 instanceof Value) { 2389 if (tuple != null) { 2390 ArrayList nodes0 = tuple.getNodesAtIndex(tuple.getParent().getPathIndex(arg0.getStringValue())); 2391 if (nodes0 != null && nodes0.size() == 1) { 2392 processComparison(arg0, arg1, (TypedNode) nodes0.get(0), (TypedNode) null, null, null, Constants.EQ_COMPOP); 2393 } 2394 } else if (tuplelist != null) { 2395 for (int i = 0; i < tuplelist.size(); i++) { 2396 Tuple tuplei = (Tuple) tuplelist.get(i); 2397 ArrayList nodes0 = tuplei.getNodesAtIndex(tuplei.getParent().getPathIndex(arg0.getStringValue())); 2398 if (nodes0 != null && nodes0.size() == 1) { 2399 processComparison(arg0, arg1, (TypedNode) nodes0.get(0), (TypedNode) null, null, null, Constants.EQ_COMPOP); 2400 break; 2401 } 2402 } 2403 } 2404 } else { 2405 if (this.tuple != null) { 2406 ArrayList nodes0 = tuple.getNodesAtIndex(tuple.getParent().getPathIndex(arg0.getStringValue())); 2407 ArrayList nodes1 = tuple.getNodesAtIndex(tuple.getParent().getPathIndex(arg1.getStringValue())); 2408 verdict = DOMUtils.compareTree(nodes0, nodes1); 2409 } else if (tuplelist != null) { 2410 ArrayList nodes0 = null; 2411 ArrayList nodes1 = null; 2412 for (int i = 0; i < tuplelist.size(); i++) { 2413 Tuple tmptuple = (Tuple) tuplelist.get(i); 2414 if (nodes0 == null) 2415 nodes0 = tmptuple.getNodesAtIndex(tmptuple.getParent().getPathIndex(arg0.getStringValue())); 2416 if (nodes1 == null) 2417 nodes1 = tmptuple.getNodesAtIndex(tmptuple.getParent().getPathIndex(arg1.getStringValue())); 2418 if (nodes0 != null && nodes1 != null) 2419 break; 2420 } 2421 verdict = DOMUtils.compareTree(nodes0, nodes1); 2422 } else if (buffertuple != null) { 2423 throw new XQueryException("FunctionVALUE_EQUALS on BufferTuple not yet implemented"); 2424 } 2425 } 2426 } 2427 } 2428 2429 2433 private SimpleType getSimpleType(Comparable obj, SimpleType defaultType) { 2434 if (obj instanceof Long ) 2435 return this.schemamanager.getIntegerType(); 2436 else if (obj instanceof BigDecimal ) 2437 return this.schemamanager.getDecimalType(); 2438 else if (obj instanceof Float ) 2439 return this.schemamanager.getFloatType(); 2440 else if (obj instanceof Double ) 2441 return this.schemamanager.getDoubleType(); 2442 else if (obj instanceof String ) 2443 return this.schemamanager.getStringType(); 2444 else if (obj instanceof Date) 2445 return this.schemamanager.getDateTimeType(); 2446 return defaultType; 2447 } 2448 2449 private void processComparison(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Comparable value1, Comparable value2, int operator) { 2450 boolean doublecompare = false; 2452 double value1double = 0; 2453 if (value1 == null) { 2454 if (exp1 instanceof ValueInteger) { 2455 value1 = new Long (((ValueInteger) exp1).getIntValue().longValue()); 2456 } else if (exp1 instanceof ValueDecimal) { 2458 value1 = ((ValueDecimal) exp1).getDecimalValue(); 2459 } else if (exp1 instanceof ValueFloat) { 2461 value1 = ((ValueFloat) exp1).getFloatValue(); 2462 } else if (exp1 instanceof ValueDouble) { 2464 value1 = ((ValueDouble) exp1).getDoubleValue(); 2465 } else if (exp1 instanceof ValueString) { 2467 value1 = ((ValueString) exp1).getValue(); 2468 } else if (tree1 != null) { 2469 if (tree1.getTypedValue() != null) 2470 value1 = (Comparable ) tree1.getTypedValue(); 2471 else 2472 value1 = (Comparable ) DOMUtils.getTextLeaf(tree1); 2473 } 2478 } 2479 if (value1 != null && !(value1 instanceof String ) && !(value1 instanceof Timestamp ) && !(value1 instanceof Date)) { 2480 value1double = ((Number ) value1).doubleValue(); 2481 doublecompare = true; 2482 } 2483 double value2double = 0; 2485 if (value2 == null) { 2486 if (exp2 instanceof ValueInteger) { 2487 value2 = new Long (((ValueInteger) exp2).getIntValue().longValue()); 2488 } else if (exp2 instanceof ValueDecimal) { 2490 value2 = ((ValueDecimal) exp2).getDecimalValue(); 2491 } else if (exp2 instanceof ValueFloat) { 2493 value2 = ((ValueFloat) exp2).getFloatValue(); 2494 } else if (exp2 instanceof ValueDouble) { 2496 value2 = ((ValueDouble) exp2).getDoubleValue(); 2497 } else if (exp2 instanceof ValueString) 2499 value2 = ((ValueString) exp2).getValue(); 2500 else if (tree2 != null) { 2501 if (tree2.getTypedValue() != null) 2502 value2 = (Comparable ) tree2.getTypedValue(); 2503 else 2504 value2 = (Comparable ) DOMUtils.getTextLeaf(tree2); 2505 } 2511 } 2512 if (value2 != null && !(value2 instanceof String ) && !(value2 instanceof Timestamp ) && !(value2 instanceof Date)) { 2513 value2double = ((Number ) value2).doubleValue(); 2514 } else 2515 doublecompare = false; 2516 2527 boolean stringcomp = false; 2528 if (value1 == null) { 2529 if (value2 != null) { 2530 setVerdict(false); 2531 return; 2532 } 2533 } else { 2534 if (value2 == null) { 2535 setVerdict(false); 2536 return; 2537 } else { 2538 if (value1 instanceof String ) { 2539 if (!(value2 instanceof String )) { 2540 value2 = value2.toString(); 2541 if (value2 == null) { 2542 setVerdict(false); 2543 return; 2544 } 2545 stringcomp = true; 2546 } 2547 } else if (value2 instanceof String ) { 2548 value1 = value1.toString(); 2549 if (value1 == null) { 2550 setVerdict(false); 2551 return; 2552 } 2553 stringcomp = true; 2554 } 2555 } 2556 } 2557 switch (operator) { 2560 case Constants.LT_VALUECOMP : 2561 case Constants.LT_COMPOP : 2562 if ((value1 == null) && (value2 == null)) 2563 setVerdict(false); 2564 else if (stringcomp || !doublecompare) 2565 setVerdict((DOMUtils.compareObjects(value1,value2) < 0)); 2566 else 2567 setVerdict((value1double < value2double)); 2568 return; 2569 case Constants.GT_VALUECOMP : 2570 case Constants.GT_COMPOP : 2571 if ((value1 == null) && (value2 == null)) 2572 setVerdict(false); 2573 else if (stringcomp || !doublecompare) 2574 setVerdict((DOMUtils.compareObjects(value1,value2) > 0)); 2575 else 2576 setVerdict((value1double > value2double)); 2577 return; 2578 case Constants.GE_VALUECOMP : 2579 case Constants.GEQ_COMPOP : 2580 if ((value1 == null) && (value2 == null)) 2581 setVerdict(true); 2582 else if (stringcomp || !doublecompare) 2583 setVerdict((DOMUtils.compareObjects(value1,value2) >= 0)); 2584 else 2585 setVerdict((value1double >= value2double)); 2586 return; 2587 case Constants.LE_VALUECOMP : 2588 case Constants.LEQ_COMPOP : 2589 if ((value1 == null) && (value2 == null)) 2590 setVerdict(true); 2591 else if (stringcomp || !doublecompare) 2592 setVerdict((DOMUtils.compareObjects(value1,value2) <= 0)); 2593 else 2594 setVerdict((value1double <= value2double)); 2595 return; 2596 case Constants.EQ_VALUECOMP : 2597 case Constants.EQ_COMPOP : 2598 if ((value1 == null) && (value2 == null)) 2599 setVerdict(true); 2600 else if (stringcomp || !doublecompare) 2601 setVerdict((DOMUtils.compareObjects(value1,value2) == 0)); 2602 else 2603 setVerdict((value1double == value2double)); 2604 return; 2605 case Constants.NE_VALUECOMP : 2606 case Constants.NEQ_COMPOP : 2607 if ((value1 == null) && (value2 == null)) 2608 setVerdict(false); 2609 else if (stringcomp || !doublecompare) 2610 setVerdict((DOMUtils.compareObjects(value1,value2) != 0)); 2611 else 2612 setVerdict((value1double != value2double)); 2613 return; 2614 2619 } 2620 clear(); 2621 } 2622 2623 private Number processOperation(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Number value1, Number value2, int operator) throws XQueryException { 2624 if (value1 == null) { 2625 if (exp1 instanceof ValueInteger) 2626 value1 = new Long (((ValueInteger) exp1).getIntValue().longValue()); 2627 else if (exp1 instanceof ValueDecimal) 2628 value1 = ((ValueDecimal) exp1).getDecimalValue(); 2629 else if (exp1 instanceof ValueFloat) 2630 value1 = ((ValueFloat) exp1).getFloatValue(); 2631 else if (exp1 instanceof ValueDouble) 2632 value1 = ((ValueDouble) exp1).getDoubleValue(); 2633 else if (tree1 != null) 2634 if (tree1.getTypedValue() != null) 2635 value1 = (Number ) tree1.getTypedValue(); 2636 else 2637 value1 = (Number ) DOMUtils.getTextLeaf(tree1); 2638 } 2639 if (value2 == null) { 2640 if (exp2 instanceof ValueInteger) 2641 value2 = new Long (((ValueInteger) exp2).getIntValue().longValue()); 2642 else if (exp2 instanceof ValueDecimal) 2643 value2 = ((ValueDecimal) exp2).getDecimalValue(); 2644 else if (exp2 instanceof ValueFloat) 2645 value2 = ((ValueFloat) exp2).getFloatValue(); 2646 else if (exp2 instanceof ValueDouble) 2647 value2 = ((ValueDouble) exp2).getDoubleValue(); 2648 else if (tree2 != null) 2649 if (tree2.getTypedValue() != null) 2650 value2 = (Number ) tree2.getTypedValue(); 2651 else 2652 value2 = (Number ) DOMUtils.getTextLeaf(tree2); 2653 } 2654 2655 boolean integerOp = false; 2656 boolean decimalOp = false; 2657 boolean floatOp = false; 2658 if (value1 instanceof Long ) { 2659 if (value2 instanceof Long ) 2660 integerOp = true; 2661 else if (value2 instanceof BigDecimal ) { 2662 value1 = new BigDecimal (value1.longValue()); 2663 decimalOp = true; 2664 } 2665 } else if (value1 instanceof BigDecimal ) { 2666 if (value2 instanceof BigDecimal ) 2667 decimalOp = true; 2668 else if (value2 instanceof Long ) { 2669 value2 = new BigDecimal (value2.longValue()); 2670 decimalOp = true; 2671 } 2672 } else if (value1 instanceof Float ) { 2673 if (value2 instanceof Float ) 2674 floatOp = true; 2675 if (!(value2 instanceof Double )) { 2676 value2 = new Float (value2.doubleValue()); 2677 floatOp = true; 2678 } 2679 } 2680 2681 switch (operator) { 2682 case Constants.DIVIDE_ARITHMETICS : 2683 if (decimalOp) { 2691 try { 2692 return ((BigDecimal ) value1).divide((BigDecimal ) value2, 38, BigDecimal.ROUND_UP); 2693 } catch (ArithmeticException ae) { 2694 throw new XQueryException("Division by zero"); 2695 } 2696 } else if (floatOp) 2697 return new Float (value1.floatValue() / value2.floatValue()); 2698 return new Double (value1.doubleValue() / value2.doubleValue()); 2699 case Constants.MINUS_ARITHMETICS : 2700 if (integerOp) 2701 return new Long (value1.longValue() - value2.longValue()); 2702 else if (decimalOp) 2703 return ((BigDecimal ) value1).subtract((BigDecimal ) value2); 2704 else if (floatOp) 2705 return new Float (value1.floatValue() - value2.floatValue()); 2706 return new Double (value1.doubleValue() - value2.doubleValue()); 2707 case Constants.MODULO_ARITHMETICS : 2708 if (integerOp) 2709 return new Long (value1.longValue() % value2.longValue()); 2710 else if (floatOp) 2711 return new Float (value1.floatValue() % value2.floatValue()); 2712 return new Double (value1.doubleValue() % value2.doubleValue()); 2713 case Constants.MULTIPLY_ARITHMETICS : 2714 if (integerOp) 2715 return new Long (value1.longValue() * value2.longValue()); 2716 else if (decimalOp) 2717 return ((BigDecimal ) value1).multiply((BigDecimal ) value2); 2718 else if (floatOp) 2719 return new Float (value1.floatValue() * value2.floatValue()); 2720 return new Double (value1.doubleValue() * value2.doubleValue()); 2721 case Constants.PLUS_ARITHMETICS : 2722 if (integerOp) 2723 return new Long (value1.longValue() + value2.longValue()); 2724 else if (decimalOp) 2725 return ((BigDecimal ) value1).add((BigDecimal ) value2); 2726 else if (floatOp) 2727 return new Float (value1.floatValue() + value2.floatValue()); 2728 return new Double (value1.doubleValue() + value2.doubleValue()); 2729 } 2730 throw new XQueryException("Could not process operation"); 2731 } 2732 2733} 2734 | Popular Tags |