1 23 24 package org.xquark.xquery.reconstruction; 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.w3c.dom.Text ; 33 import org.xquark.schema.SchemaException; 34 import org.xquark.schema.SchemaManager; 35 import org.xquark.schema.SimpleType; 36 import org.xquark.schema.validation.ValidationContextProvider; 37 import org.xquark.xml.xdbc.XMLDBCException; 38 import org.xquark.xpath.datamodel.*; 39 import org.xquark.xquery.metadata.DynamicContext; 40 import org.xquark.xquery.parser.*; 41 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*; 42 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.*; 43 import org.xquark.xquery.parser.util.Constants; 44 import org.xquark.xquery.xdbc.XDBCResultSetInterface; 45 46 51 public class EvaluationVisitor extends DefaultParserVisitor { 52 private static final String RCSRevision = "$Revision: 1.7 $"; 56 private static final String RCSName = "$Name: $"; 57 private XDBCResultSetInterface resultSet = null; 61 62 private boolean verdict = false; 63 64 private ArrayList resnodes = null; 65 private Comparable resvalue = null; 66 67 protected static TypedDocumentImpl docimpl = null; 68 static { 69 docimpl = new TypedDocumentImpl(); 70 } 71 private SchemaManager schemamanager = null; 72 private DynamicContext dc = null; 73 private ValidationContextProvider context = null; 74 75 public static Integer UNKNOWN_TYPE = new Integer (-1); 76 public static Integer BOOLEAN_TYPE = new Integer (0); 77 public static Integer VALUE_TYPE = new Integer (1); 78 public static Integer NODE_TYPE = new Integer (2); 79 public static Integer TUPLE_TYPE = new Integer (3); 80 public static Integer BUFFER_TYPE = new Integer (4); 81 private Stack returnType = new Stack(); 82 83 86 public EvaluationVisitor(XDBCResultSetInterface resultSet, ValidationContextProvider context) { 87 this.schemamanager = new SchemaManager(); 88 this.resultSet = resultSet; 89 this.context = context; 90 } 91 92 95 public EvaluationVisitor(SchemaManager schemamanager, XDBCResultSetInterface resultSet) { 96 this.schemamanager = schemamanager; 97 this.resultSet = resultSet; 98 } 99 100 public void setReturnType(Integer setType) { 101 if (!returnType.isEmpty()) 102 this.returnType.pop(); 103 returnType.push(setType); 104 } 105 106 private void clear() { 107 resnodes = null; 108 resvalue = null; 109 verdict = false; 110 } 111 private void setResnodes(ArrayList nodes) { 112 resnodes = nodes; 113 resvalue = null; 114 verdict = false; 115 } 116 private void setValue(Comparable comp) { 117 resnodes = null; 118 resvalue = comp; 119 verdict = false; 120 } 121 private void setVerdict(boolean bool) { 122 resnodes = null; 123 resvalue = null; 124 verdict = bool; 125 } 126 public void setSchemaManager(SchemaManager schemamanager) { 127 this.schemamanager = schemamanager; 128 } 129 public void setDynamicContext(DynamicContext dc) { 130 this.dc = dc; 131 } 132 public void reset() { 133 clear(); 134 this.resultSet = null; 135 returnType.clear(); 136 } 137 public void reset(XDBCResultSetInterface resultSet) { 138 clear(); 139 this.resultSet = resultSet; 140 returnType.clear(); 141 } 142 public boolean getVerdict() { 143 return verdict; 144 } 145 public Comparable getResValue() { 146 return resvalue; 147 } 148 public ArrayList getResNodes() { 149 return resnodes; 150 } 151 152 public void visit(AttributeValuePair arg) throws XQueryException { 153 if (arg.isXmlns()) { 154 setResnodes(null); 155 return; 156 } 157 if (!(arg.getExpression1() instanceof QName)) { 158 throw new XQueryException("EvaluationVisitor : name of AttributeValuePair is not a QName : " + arg.getExpression1()); 159 } 160 QName attName = (QName) arg.getExpression1(); 161 Object attValue = null; 162 if (!(arg.getExpression2() instanceof Value)) { 163 returnType.push(VALUE_TYPE); 164 arg.getExpression2().accept(this); 165 returnType.pop(); 166 if (resvalue == null) { 167 throw new XQueryException("EvaluationVisitor : value of AttributeValuePair is null : " + arg.getExpression2()); 168 } 169 attValue = resvalue; 170 } else 171 attValue = ((Value) arg.getExpression2()).getObjectValue(); 172 if (attValue != null) { 173 TypedAttributeImpl att = new TypedAttributeImpl(docimpl, ((QName) attName).getNameSpace(), ((QName) attName).getLocalName()); 174 att.setNodeValue(attValue.toString()); 175 att.setTypedValue(attValue); 176 ArrayList tmplist = new ArrayList(1); 177 tmplist.add(att); 178 setResnodes(tmplist); 179 return; 180 } 181 setResnodes(null); 182 } 183 184 public void visit(BinOpANDExpression arg) throws XQueryException { 185 XQueryExpression exp1 = arg.getExpression1(); 186 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, resultSet); 187 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 188 exp1.accept(visitor); 189 verdict = visitor.getVerdict(); 190 if (!verdict) { 191 setVerdict(false); 192 return; 193 } 194 XQueryExpression exp2 = arg.getExpression2(); 195 visitor.reset(resultSet); 196 visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 197 exp2.accept(visitor); 198 verdict &= visitor.getVerdict(); 199 setVerdict(verdict); 200 } 201 202 public void visit(BinOpORExpression arg) throws XQueryException { 203 XQueryExpression exp1 = arg.getExpression1(); 204 EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, resultSet); 205 exp1.accept(visitor); 206 verdict = visitor.getVerdict(); 207 if (verdict) { 208 setVerdict(true); 209 return; 210 } 211 XQueryExpression exp2 = arg.getExpression2(); 212 visitor.reset(resultSet); 213 exp2.accept(visitor); 214 verdict = verdict || visitor.getVerdict(); 215 setVerdict(verdict); 216 } 217 218 222 public void visit(Element arg) throws XQueryException { 223 XQueryExpression startTag = arg.getStartTag(); 224 if (!(startTag instanceof QName)) 225 throw new XQueryException("Tag of Element expression is not a QName : " + startTag); 226 Integer rettype = (Integer ) returnType.peek(); 227 QName startTagQName = null; 228 TypedElement element = null; 229 ArrayList tmplist = null; 230 StringBuffer buf = null; 231 if (rettype == NODE_TYPE) { 232 startTagQName = (QName) startTag; 233 element = new TypedElementImpl(docimpl, startTagQName.getNameSpace(), startTagQName.getLocalName()); 234 tmplist = arg.getAttributes(); 235 if (tmplist != null && !tmplist.isEmpty()) { 236 for (int i = 0; i < tmplist.size(); i++) { 237 AttributeValuePair attValPair = (AttributeValuePair) tmplist.get(i); 238 attValPair.accept(this); 239 if (resnodes != null) { 240 TypedAttribute att = (TypedAttribute) resnodes.get(0); 241 element.setAttributeNodeNS((Attr ) att); 242 } 243 } 244 } 245 } else 246 buf = new StringBuffer (); 247 tmplist = arg.getSubExpressions(); 248 if (tmplist != null && !tmplist.isEmpty()) { 249 for (int i = 0; i < tmplist.size(); i++) { 250 XQueryExpression subExpr = (XQueryExpression) tmplist.get(i); 251 subExpr.accept(this); 252 if (rettype == NODE_TYPE && resnodes != null) { 253 for (int j = 0; j < resnodes.size(); j++) { 254 TypedNode resnode = (TypedNode) resnodes.get(j); 255 if (docimpl != resnode.getOwnerDocument()) 256 resnode = (TypedNode) element.getOwnerDocument().importNode(resnode, true); 257 if (resnode instanceof TypedAttributeImpl) { 258 element.setAttributeNodeNS((Attr ) resnode); 259 } else if (resnode instanceof TypedElementImpl) { 260 element.appendChild((Node ) resnode); 261 } else if (resnode instanceof TypedValueImpl) { 262 element.appendChild((Node ) resnode); 263 } else { 264 throw new XQueryException("Could not add child : " + resnode + " to parent."); 265 } 267 } 268 } 269 else if (rettype == VALUE_TYPE && resvalue != null) { 270 buf.append(resvalue.toString()); 271 } 272 } 273 } 274 clear(); 275 if (rettype == VALUE_TYPE) { 276 setValue(buf.toString()); 277 } else { tmplist = new ArrayList(1); 279 tmplist.add(element); 280 setResnodes(tmplist); 281 } 282 } 283 284 public void visit(ITEExpression arg) throws XQueryException { 290 returnType.push(BOOLEAN_TYPE); 291 arg.getIfExpression().accept(this); 292 returnType.pop(); 293 if (verdict) 294 arg.getThenExpression().accept(this); 295 else 296 arg.getElseExpression().accept(this); 297 } 298 299 public void visit(LibraryFunctionCall arg) throws XQueryException { 300 FunctionDeclaration funDecl = arg.getFunctionDefinition(); 301 if (funDecl.getExpressions() != null) { 302 } else { 304 Object [] params = new Object [arg.getArguments().size()]; 305 for (int i=0;i<arg.getArguments().size();i++) { 306 returnType.push(VALUE_TYPE); 307 arg.getArgument(i).accept(this); 308 params[i] = resvalue; 309 returnType.pop(); 310 } 311 Object obj = dc.invoke(arg,params); 312 setValue((Comparable )obj); 313 } 314 } 315 316 318 public void visit(ListOpArithExpression arg) throws XQueryException { 319 XQueryExpression exp1 = arg.getExpression1(); 320 XQueryExpression exp2 = arg.getExpression2(); 321 int operator = arg.getOperator(); 322 323 returnType.push(UNKNOWN_TYPE); 324 exp1.accept(this); 325 ArrayList trees1 = resnodes; 326 Number value1 = (resvalue instanceof Number ) ? (Number ) resvalue : null; 327 exp2.accept(this); 328 ArrayList trees2 = resnodes; 329 Number value2 = (resvalue instanceof Number ) ? (Number ) resvalue : null; 330 returnType.pop(); 331 332 if ((trees1 == null || trees1.isEmpty()) && (trees2 == null || trees2.isEmpty())) { 335 Number res = processOperation(exp1, exp2, null, null, value1, value2, operator); 336 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 338 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 339 text.setTypedValue(res); 340 text.setType(st); 341 ArrayList tmplist = new ArrayList(1); 342 tmplist.add(text); 343 setResnodes(tmplist); 344 return; 351 } 352 353 if ((trees1 == null || trees1.isEmpty()) && (trees2 != null) && (!trees2.isEmpty())) { 354 ArrayList tmplist = new ArrayList(trees2.size()); 355 for (int j = 0; j < trees2.size(); j++) { 356 TypedNode tree2 = (TypedNode) trees2.get(j); 357 Number res = processOperation(exp1, exp2, null, tree2, value1, value2, operator); 358 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 359 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 360 text.setTypedValue(res); 361 text.setType(st); 362 tmplist.add(text); 363 } 364 setResnodes(tmplist); 366 return; 370 } 371 372 if ((trees1 != null) && (!trees1.isEmpty()) && (trees2 == null) || (trees2.isEmpty())) { 373 ArrayList tmplist = new ArrayList(trees1.size()); 374 for (int i = 0; i < trees1.size(); i++) { 375 TypedNode tree1 = (TypedNode) trees1.get(i); 376 Number res = processOperation(exp1, exp2, tree1, null, value1, value2, operator); 377 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 378 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 379 text.setTypedValue(res); 380 text.setType(st); 381 tmplist.add(text); 382 } 383 setResnodes(tmplist); 385 return; 389 } 390 391 ArrayList tmplist = new ArrayList(trees1.size() * trees2.size()); 392 for (int i = 0; i < trees1.size(); i++) { 393 TypedNode tree1 = (TypedNode) trees1.get(i); 394 for (int j = 0; j < trees2.size(); j++) { 395 TypedNode tree2 = (TypedNode) trees2.get(j); 396 Number res = processOperation(exp1, exp2, tree1, tree2, value1, value2, operator); 397 SimpleType st = getSimpleType((Comparable ) res, schemamanager.getDoubleType()); 398 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st); 399 text.setTypedValue(res); 400 text.setType(st); 401 tmplist.add(text); 402 } 403 } 404 setResnodes(tmplist); 406 } 410 411 public void visit(ListOpCompExpression arg) throws XQueryException { 413 XQueryExpression exp1 = arg.getExpression1(); 414 XQueryExpression exp2 = arg.getExpression2(); 415 int operator = arg.getOperator(); 416 417 returnType.push(EvaluationVisitor.NODE_TYPE); 418 resnodes = null; 419 resvalue = null; 420 exp1.accept(this); 421 ArrayList trees1 = resnodes; 423 if (trees1 != null && trees1.isEmpty()) 424 trees1 = null; 425 Comparable value1 = resvalue; 426 resnodes = null; 428 resvalue = null; 429 exp2.accept(this); 430 returnType.pop(); 431 ArrayList trees2 = resnodes; 432 if (trees2 != null && trees2.isEmpty()) 433 trees2 = null; 434 Comparable value2 = resvalue; 435 436 if (value1 != null && value2 != null) { 437 processComparison(null, null, null, null, value1, value2, operator); 438 setVerdict(verdict); 439 return; 440 } 441 442 if (trees1 == null && trees2 == null) { 443 processComparison(exp1, exp2, null, null, value1, value2, operator); 444 return; 445 } 446 447 if (trees1 == null && trees2 != null) { 448 for (int j = 0; j < trees2.size(); j++) { 449 TypedNode tree2 = (TypedNode) trees2.get(j); 450 processComparison(exp1, exp2, null, tree2, value1, value2, operator); 451 if (verdict == true) { 452 setVerdict(true); 453 return; 454 } 455 } 456 setVerdict(false); 457 return; 458 } 459 460 if (trees1 != null && trees2 == null) { 461 for (int i = 0; i < trees1.size(); i++) { 462 TypedNode tree1 = (TypedNode) trees1.get(i); 463 processComparison(exp1, exp2, tree1, null, value1, value2, operator); 464 if (verdict == true) { 465 setVerdict(true); 466 return; 467 } 468 } 469 setVerdict(false); 470 return; 471 } 472 473 for (int i = 0; i < trees1.size(); i++) { 474 TypedNode tree1 = (TypedNode) trees1.get(i); 475 for (int j = 0; j < trees2.size(); j++) { 476 TypedNode tree2 = (TypedNode) trees2.get(j); 477 processComparison(exp1, exp2, tree1, tree2, value1, value2, operator); 478 if (verdict == true) { 479 setVerdict(true); 480 return; 481 } 482 } 483 setVerdict(false); 484 } 485 } 486 487 490 public void visit(ListOpUNIONExpression arg) throws XQueryException { 491 XQueryExpression exp1 = arg.getExpression1(); 492 XQueryExpression exp2 = arg.getExpression2(); 493 494 returnType.push(NODE_TYPE); 495 resnodes = null; 496 exp1.accept(this); 497 ArrayList trees = resnodes; 498 resnodes = null; 499 exp2.accept(this); 500 returnType.pop(); 501 if (resnodes != null) { 502 if (trees == null) 503 trees = resnodes; 504 else 505 trees.addAll(resnodes); 506 } 507 setResnodes(trees); 508 } 509 510 public void visit(LocatedExpression arg) throws XQueryException { 511 ArrayList steps = arg.getSteps(); 512 int nodeAccessor = arg.getNodeAccessor(); 513 boolean hasSpecialStep = false; 514 if (nodeAccessor == Step.NONE) { 515 int lastPosition = steps.size() - 1; 516 Step lastStep = (Step) steps.get(lastPosition); 517 if (lastStep.getStepKind()%16 != 0) { 518 arg.setNodeAccessor(lastStep.getStepKind()); 519 nodeAccessor = arg.getNodeAccessor(); 520 steps.remove(lastPosition); 521 } 522 } 523 clear(); 556 String str = null; 557 try { 558 str = resultSet.fetch(arg.getStringValue(), nodeAccessor); 559 } catch (XMLDBCException xe) { 560 throw new XQueryException(xe.getMessage(), xe); 561 } 562 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 566 if (rettype == NODE_TYPE) { 567 ArrayList nodes = null; 568 if (str != null) { 569 nodes = new ArrayList(1); 570 Text text = docimpl.createTextNode(str); 571 nodes.add(text); 572 } 573 setResnodes(nodes); 574 return; 575 } else { setValue(str); 577 return; 578 } 579 } 580 public void visit(QName arg) throws XQueryException { 584 String str = arg.getStringValue(); 585 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 586 if (rettype == NODE_TYPE) { 587 ArrayList nodes = null; 588 if (str != null) { 589 nodes = new ArrayList(1); 590 Text text = docimpl.createTextNode(str); 591 nodes.add(text); 592 } 593 setResnodes(nodes); 594 return; 595 } else { setValue(str); 597 return; 598 } 599 } 600 607 private Comparable getMinus(Comparable obj) { 608 Comparable retObj = null; 609 if (obj instanceof Number ) { 610 if (obj instanceof Double ) { 612 retObj = new Double (- ((Double ) obj).doubleValue()); 613 } else if (obj instanceof Float ) { 614 retObj = new Float (- ((Float ) obj).floatValue()); 615 } else if (obj instanceof BigDecimal ) { 616 retObj = new BigDecimal (((BigDecimal ) obj).unscaledValue().negate(), ((BigDecimal ) obj).scale()); 617 } else if (obj instanceof Integer ) { 618 retObj = new Integer (- ((Integer ) obj).intValue()); 619 } else if (obj instanceof Long ) { 620 retObj = new Long (- ((Long ) obj).longValue()); 621 } 622 } else if (obj instanceof String ) { 623 try { 624 retObj = new Double (-Double.parseDouble((String ) obj)); 625 } catch (NumberFormatException e) { 626 } 628 } 629 return retObj; 630 } 631 632 public void visit(UnOpMinusExpression arg) throws XQueryException { 633 returnType.push(UNKNOWN_TYPE); 634 arg.getExpression().accept(this); 635 returnType.pop(); 636 Integer rettype = (Integer ) returnType.peek(); 637 if (resvalue != null) { 638 if (!arg.getMinus()) { 639 if (rettype == NODE_TYPE) { 640 ArrayList nodes = new ArrayList(1); 641 TypedValue text = null; 642 if (resvalue instanceof Long ) 643 text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 644 else if (resvalue instanceof BigDecimal ) 645 text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType()); 646 else if (resvalue instanceof Double ) 647 text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 648 else 649 throw new XQueryException("UnOpMinusExpression could not cast resvalue"); 650 nodes.add(text); 651 setResnodes(nodes); 652 return; 653 } else { setValue(resvalue); 655 return; 656 } 657 } 658 Comparable comp = getMinus(resvalue); 659 if (comp != null) { 660 if (rettype == NODE_TYPE) { 661 ArrayList nodes = new ArrayList(1); 662 TypedValue text = null; 663 if (comp instanceof Long ) 664 text = docimpl.createTypedValue(comp, this.schemamanager.getIntegerType()); 665 else if (resvalue instanceof BigDecimal ) 666 text = docimpl.createTypedValue(comp, this.schemamanager.getDecimalType()); 667 else if (comp instanceof Double ) 668 text = docimpl.createTypedValue(comp, this.schemamanager.getDoubleType()); 669 else 670 throw new XQueryException("UnOpMinusExpression could not cast comp"); 671 nodes.add(text); 672 setResnodes(nodes); 673 return; 674 } else { setValue(comp); 676 return; 677 } 678 } else 679 throw new XQueryException("UnOpMinusExpression could not cast operator to Number"); 680 } else if (resnodes != null) { 681 if (rettype == VALUE_TYPE && resnodes.size() != 1) { 682 throw new XQueryException("UnOpMinusExpression could not get value from node list"); 683 } 684 if (!arg.getMinus()) { 685 if (rettype == NODE_TYPE) { 686 ArrayList tmplist = new ArrayList(resnodes.size()); 687 for (int i = 0; i < resnodes.size(); i++) { 688 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 689 if (tmpnode == null) 690 tmpnode = (TypedNode) resnodes.get(0); 691 tmplist.add(docimpl.createTypedValue((Comparable ) tmpnode.getTypedValue(), (SimpleType) tmpnode.getType())); 692 } 693 setResnodes(tmplist); 694 return; 695 } else { TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 697 if (tmpnode == null) 698 tmpnode = (TypedNode) resnodes.get(0); 699 setValue((Comparable ) tmpnode.getTypedValue()); 700 return; 701 } 702 } 703 ArrayList tmplist = new ArrayList(resnodes.size()); 704 for (int i = 0; i < resnodes.size(); i++) { 705 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 706 if (tmpnode == null) 707 tmpnode = (TypedNode) resnodes.get(0); 708 Comparable comp = getMinus((Comparable ) tmpnode.getTypedValue()); 709 if (comp != null) { 710 TypedValue text = docimpl.createTypedValue(comp, (SimpleType) tmpnode.getType()); 711 tmplist.add(text); 712 } 713 } 714 if (rettype == NODE_TYPE) { 715 setResnodes(tmplist); 716 return; 717 } else { if (tmplist.size() == 1) { 719 setValue((Comparable ) ((TypedValue) tmplist.get(0)).getTypedValue()); 720 return; 721 } 722 } 723 } 724 clear(); 725 } 726 727 public void visit(Value arg) throws XQueryException { 728 clear(); 729 String str = null; 730 try { 731 str = resultSet.fetch(arg.getStringValue(), 0); 732 733 } catch (XMLDBCException xe) { 734 throw new XQueryException(xe.getMessage(), xe); 735 } 736 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 737 ArrayList nodes = null; 738 if (rettype == NODE_TYPE) { 739 if (str != null) { 740 nodes = new ArrayList(1); 741 Text text = docimpl.createTextNode(str); 742 nodes.add(text); 743 } 744 setResnodes(nodes); 745 return; 746 } else { setValue(str); 748 return; 749 } 750 } 751 public void visit(ValueDecimal arg) throws XQueryException { 753 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 754 if (rettype == NODE_TYPE) { 755 ArrayList nodes = new ArrayList(1); 756 TypedValue text = docimpl.createTypedValue(arg.getDecimalValue(), this.schemamanager.getDecimalType()); 757 nodes.add(text); 758 setResnodes(nodes); 759 return; 760 } else { setValue(arg.getDecimalValue()); 762 return; 763 } 764 } 765 public void visit(ValueDouble arg) throws XQueryException { 766 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 767 if (rettype == NODE_TYPE) { 768 ArrayList nodes = new ArrayList(1); 769 TypedValue text = docimpl.createTypedValue(arg.getDoubleValue(), this.schemamanager.getDoubleType()); 770 nodes.add(text); 771 setResnodes(nodes); 772 return; 773 } else { setValue(arg.getDoubleValue()); 775 return; 776 } 777 } 778 public void visit(ValueFloat arg) throws XQueryException { 779 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 780 if (rettype == NODE_TYPE) { 781 ArrayList nodes = new ArrayList(1); 782 TypedValue text = docimpl.createTypedValue(arg.getFloatValue(), this.schemamanager.getFloatType()); 783 nodes.add(text); 784 setResnodes(nodes); 785 return; 786 } else { setValue(arg.getFloatValue()); 788 return; 789 } 790 } 791 public void visit(ValueInteger arg) throws XQueryException { 792 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 793 if (rettype == NODE_TYPE) { 794 ArrayList nodes = new ArrayList(1); 795 TypedValue text = docimpl.createTypedValue(new Long (arg.getIntValue().longValue()), this.schemamanager.getIntegerType()); 796 nodes.add(text); 797 setResnodes(nodes); 798 return; 799 } else { setValue(new Long (arg.getIntValue().longValue())); 801 return; 802 } 803 } 804 public void visit(ValueString arg) throws XQueryException { 805 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 806 if (rettype == NODE_TYPE) { 807 ArrayList nodes = new ArrayList(1); 808 TypedValue text = docimpl.createTypedValue(arg.getStringValue(), this.schemamanager.getStringType()); 809 nodes.add(text); 810 setResnodes(nodes); 811 return; 812 } else { setValue(arg.getStringValue()); 814 return; 815 } 816 } 817 public void visit(ValueText arg) throws XQueryException { 818 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 819 if (rettype == NODE_TYPE) { 820 ArrayList nodes = new ArrayList(1); 821 TypedValue text = docimpl.createTypedValue(arg.getTextValue(), this.schemamanager.getStringType()); 822 nodes.add(text); 823 setResnodes(nodes); 824 return; 825 } else { setValue(arg.getTextValue()); 827 return; 828 } 829 } 830 public void visit(Variable arg) throws XQueryException { 831 clear(); 832 String str = null; 833 try { 834 str = resultSet.fetch(arg.getStringValue(), 0); 835 836 } catch (XMLDBCException xe) { 837 throw new XQueryException(xe.getMessage(), xe); 838 } 839 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 840 if (rettype == NODE_TYPE) { 841 ArrayList nodes = null; 842 if (str != null) { 843 nodes = new ArrayList(1); 844 Text text = docimpl.createTextNode(str); 845 nodes.add(text); 846 } 847 setResnodes(nodes); 848 return; 849 } else { setValue(str); 851 return; 852 } 853 } 854 public void visit(XQueryExpression arg) throws XQueryException { 857 throw new XQueryException("Class " + arg.getClass().getName() + " not supported in EvaluationVisitor"); 858 } 859 public void visit(XQueryExpressionSequence arg) throws XQueryException { 860 if (arg.getSubExpressions().size() == 1) 861 ((XQueryExpression) arg.getSubExpressions().get(0)).accept(this); 862 else { 863 ArrayList expressions = arg.getSubExpressions(); 864 Integer rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer ) returnType.peek(); 865 if (rettype == VALUE_TYPE) { 866 StringBuffer buf = new StringBuffer (); 867 returnType.push(VALUE_TYPE); 868 for (int i = 0; i < expressions.size(); i++) { 869 XQueryExpression expri = (XQueryExpression) expressions.get(i); 870 expri.accept(this); 871 if (resvalue != null) { 872 if (buf.length() != 0) 873 buf.append(' '); 874 buf.append(resvalue.toString()); 875 } 876 } 877 setValue(buf.toString()); 878 returnType.pop(); 879 } else { 880 ArrayList tmpnodes = new ArrayList(); 881 returnType.push(NODE_TYPE); 882 for (int i = 0; i < expressions.size(); i++) { 883 XQueryExpression expri = (XQueryExpression) expressions.get(i); 884 expri.accept(this); 885 if (resnodes != null) 886 tmpnodes.addAll(resnodes); 887 } 888 setResnodes(tmpnodes); 889 returnType.pop(); 890 } 891 } 893 } 894 898 public void visit(FunctionFALSE arg) throws XQueryException { 902 setVerdict(false); 903 } 904 905 public void visit(FunctionTRUE arg) throws XQueryException { 906 setVerdict(true); 907 } 908 909 913 919 Calendar cal = Calendar.getInstance(); 932 933 public void visit(FunctionCURRENT_DATETIME arg) throws XQueryException { 934 resvalue = Calendar.getInstance().getTime(); 935 Integer rettype = (Integer ) returnType.peek(); 936 if (rettype == NODE_TYPE) { 937 ArrayList nodes = new ArrayList(1); 938 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType())); 939 setResnodes(nodes); 940 return; 941 } else { setValue(resvalue); 943 return; 944 } 945 } 947 948 public void visit(FunctionDATE arg) throws XQueryException { 949 returnType.push(VALUE_TYPE); 950 arg.getArgument(0).accept(this); 951 returnType.pop(); 952 if (resvalue instanceof Date) { cal.setTime((Date) resvalue); 954 cal.set(Calendar.HOUR, 0); 955 cal.set(Calendar.MINUTE, 0); 956 cal.set(Calendar.SECOND, 0); 957 resvalue = cal.getTime(); 958 } else if (resvalue instanceof String ) { 959 try { 960 resvalue = (Comparable ) this.schemamanager.getDateType().convert((String ) resvalue, true, null); 961 } catch (SchemaException se) { 962 throw new XQueryException("Argument of function date is not a valid date"); 963 } 964 } else 965 throw new XQueryException("Argument of function date cannot be converted"); 966 Integer rettype = (Integer ) returnType.peek(); 967 if (rettype == NODE_TYPE) { 968 ArrayList nodes = new ArrayList(1); 969 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateType())); 970 setResnodes(nodes); 971 return; 972 } else { setValue(resvalue); 974 return; 975 } 976 } 978 979 public void visit(FunctionDATETIME arg) throws XQueryException { 980 returnType.push(VALUE_TYPE); 981 arg.getArgument(0).accept(this); 982 returnType.pop(); 983 if (resvalue instanceof Date) { } else if (resvalue instanceof String ) { 985 try { 986 resvalue = (Comparable ) this.schemamanager.getDateTimeType().convert((String ) resvalue, true, null); 987 } catch (SchemaException se) { 988 throw new XQueryException("Argument of function datetime is not a valid date"); 989 } 990 } else 991 throw new XQueryException("Argument of function datetime cannot be converted"); 992 Integer rettype = (Integer ) returnType.peek(); 993 if (rettype == NODE_TYPE) { 994 ArrayList nodes = new ArrayList(1); 995 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType())); 996 setResnodes(nodes); 997 return; 998 } else { setValue(resvalue); 1000 return; 1001 } 1002 } 1004 1005 public void visit(FunctionTIME arg) throws XQueryException { 1006 returnType.push(VALUE_TYPE); 1007 arg.getArgument(0).accept(this); 1008 returnType.pop(); 1009 if (resvalue instanceof Date) { } else if (resvalue instanceof String ) { 1011 try { 1012 resvalue = (Comparable ) this.schemamanager.getTimeType().convert((String ) resvalue, true, null); 1013 } catch (SchemaException se) { 1014 throw new XQueryException("Argument of function time is not a valid date"); 1015 } 1016 } else 1017 throw new XQueryException("Argument of function time cannot be converted"); 1018 1026 cal.setTime((Date) resvalue); 1027 cal.set(Calendar.YEAR, 0); 1028 cal.set(Calendar.MONTH, 0); 1029 cal.set(Calendar.DAY_OF_MONTH, 0); 1030 resvalue = cal.getTime(); 1031 Integer rettype = (Integer ) returnType.peek(); 1032 if (rettype == NODE_TYPE) { 1033 ArrayList nodes = new ArrayList(1); 1034 nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getTimeType())); 1035 setResnodes(nodes); 1036 return; 1037 } else { setValue(resvalue); 1039 return; 1040 } 1041 } 1043 1044 public void visit(FunctionGET_YEAR_FROM_DATE arg) throws XQueryException { 1045 returnType.push(VALUE_TYPE); 1046 arg.getArgument(0).accept(this); 1047 returnType.pop(); 1048 if (resvalue == null) { 1049 clear(); 1050 return; 1051 } 1052 if (resvalue instanceof Date) 1053 throw new XQueryException("Argument of function get-year-from-date is not a date"); 1054 cal.setTime((Date) resvalue); 1055 resvalue = new Long (cal.get(Calendar.YEAR)); 1056 Integer rettype = (Integer ) returnType.peek(); 1057 if (rettype == NODE_TYPE) { 1058 ArrayList nodes = new ArrayList(1); 1059 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType()))); 1060 setResnodes(nodes); 1061 return; 1062 } else { setValue(resvalue); 1064 return; 1065 } 1066 } 1068 1069 public void visit(FunctionGET_MONTH_FROM_DATE arg) throws XQueryException { 1070 returnType.push(VALUE_TYPE); 1071 arg.getArgument(0).accept(this); 1072 returnType.pop(); 1073 if (resvalue == null) { 1074 clear(); 1075 return; 1076 } 1077 if (resvalue instanceof Date) 1078 throw new XQueryException("Argument of function get-month-from-date is not a date"); 1079 cal.setTime((Date) resvalue); 1080 resvalue = new Long (cal.get(Calendar.MONTH)); 1081 Integer rettype = (Integer ) returnType.peek(); 1082 if (rettype == NODE_TYPE) { 1083 ArrayList nodes = new ArrayList(1); 1084 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType()))); 1085 setResnodes(nodes); 1086 return; 1087 } else { setValue(resvalue); 1089 return; 1090 } 1091 } 1093 1094 1098 private Comparable c0 = null; 1099 private Comparable c1 = null; 1100 1101 private void getComparables(XQueryExpression arg0, XQueryExpression arg1) throws XQueryException { 1102 resnodes = null; 1103 c0 = null; 1104 c1 = null; 1105 if (arg0 instanceof Value) 1106 c0 = (((Value) arg0).getValue()); 1107 if (arg1 instanceof Value) 1108 c1 = (((Value) arg1).getValue()); 1109 if (c0 == null) { 1110 returnType.push(VALUE_TYPE); 1111 arg0.accept(this); 1112 returnType.pop(); 1113 c0 = this.resvalue; 1114 if (c0 == null && resnodes != null && resnodes.size() == 1) { 1115 TypedNode node = (TypedNode) resnodes.get(0); 1116 if (node instanceof TypedValueImpl) { 1117 c0 = (Comparable ) node.getTypedValue(); 1118 } else if (node instanceof TypedElementImpl) { 1119 StringBuffer sb = new StringBuffer (); 1120 getStringValue(node, sb); 1121 c0 = sb.toString(); 1122 } 1123 } 1124 } 1125 if (c1 == null) { 1126 returnType.push(VALUE_TYPE); 1127 arg1.accept(this); 1128 returnType.pop(); 1129 c1 = this.resvalue; 1130 if (c1 == null && resnodes != null && resnodes.size() == 1) { 1131 TypedNode node = (TypedNode) resnodes.get(0); 1132 if (node instanceof TypedValueImpl) { 1133 c1 = (Comparable ) node.getTypedValue(); 1134 } else if (node instanceof TypedElementImpl) { 1135 StringBuffer sb = new StringBuffer (); 1136 getStringValue(node, sb); 1137 c1 = sb.toString(); 1138 } 1139 } 1140 } 1141 1142 } 1143 1144 public void visit(FunctionLOWER_CASE arg) throws XQueryException { 1145 returnType.push(UNKNOWN_TYPE); 1146 arg.getArgument(0).accept(this); 1147 returnType.pop(); 1148 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1150 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1151 if (tmpnode == null) 1152 tmpnode = (TypedNode) resnodes.get(0); 1153 resvalue = (Comparable ) tmpnode.getTypedValue(); 1154 } 1155 if (resvalue instanceof String ) { 1156 resvalue = ((String ) resvalue).toLowerCase(); 1157 } else { 1158 throw new XQueryException("Argument of function lower-case is not a string"); 1159 } 1160 Integer rettype = (Integer ) returnType.peek(); 1161 if (rettype == VALUE_TYPE) { 1162 setValue(resvalue); 1163 return; 1164 } else if (rettype == NODE_TYPE) { 1165 ArrayList nodes = new ArrayList(1); 1166 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType()))); 1167 setResnodes(nodes); 1168 return; 1169 } 1170 } 1171 1172 public void visit(FunctionUPPER_CASE arg) throws XQueryException { 1173 returnType.push(UNKNOWN_TYPE); 1174 arg.getArgument(0).accept(this); 1175 returnType.pop(); 1176 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1178 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1179 if (tmpnode == null) 1180 tmpnode = (TypedNode) resnodes.get(0); 1181 resvalue = (Comparable ) tmpnode.getTypedValue(); 1182 } 1183 if (resvalue instanceof String ) { 1184 resvalue = ((String ) resvalue).toUpperCase(); 1185 } else { 1186 throw new XQueryException("Argument of function upper-case is not a string"); 1187 } 1188 Integer rettype = (Integer ) returnType.peek(); 1189 if (rettype == VALUE_TYPE) { 1190 setValue(resvalue); 1191 return; 1192 } else if (rettype == NODE_TYPE) { 1193 ArrayList nodes = new ArrayList(1); 1194 nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType()))); 1195 setResnodes(nodes); 1196 return; 1197 } 1198 } 1199 1200 public void visit(FunctionCONCAT arg) throws XQueryException { 1201 StringBuffer buf = new StringBuffer (); 1202 for (int i = 0; i < arg.getArguments().size(); i++) { 1203 returnType.push(UNKNOWN_TYPE); 1204 arg.getArgument(i).accept(this); 1205 returnType.pop(); 1206 if (resvalue != null) { if (resvalue instanceof String ) 1208 buf.append(resvalue); 1209 else 1210 buf.append(resvalue.toString()); 1211 } else if (resnodes == null || resnodes.isEmpty()) { } else if (resnodes != null && resnodes.size() == 1) { 1213 StringBuffer sb = new StringBuffer (); 1214 getStringValue((TypedNode) resnodes.get(0), sb); 1215 buf.append(sb.toString()); 1216 } else if (resnodes != null && resnodes.size() > 1) { 1217 throw new XQueryException("Evaluation : incorrect argument for function concat"); 1218 } 1219 } 1220 Integer rettype = (Integer ) returnType.peek(); 1221 if (rettype == NODE_TYPE) { 1222 ArrayList nodes = new ArrayList(1); 1223 nodes.add(docimpl.createTypedValue(buf.toString(), this.schemamanager.getStringType())); 1224 setResnodes(nodes); 1225 return; 1226 } else { setValue(buf.toString()); 1228 return; 1229 } 1230 } 1232 1233 public void visit(FunctionCONTAINS arg) throws XQueryException { 1234 getComparables(arg.getArgument(0), arg.getArgument(1)); 1235 if (c0 != null && c1 != null) { 1236 setVerdict(((String ) c0).indexOf((String ) c1) != -1); 1237 return; 1238 } 1239 clear(); 1240 } 1241 1242 public void visit(FunctionENDS_WITH arg) throws XQueryException { 1243 getComparables(arg.getArgument(0), arg.getArgument(1)); 1244 if (c0 != null && c1 != null) { 1245 setVerdict(((String ) c0).endsWith((String ) c1)); 1246 return; 1247 } 1248 clear(); 1249 } 1250 1251 public void visit(FunctionSTARTS_WITH arg) throws XQueryException { 1252 getComparables(arg.getArgument(0), arg.getArgument(1)); 1253 if (c0 != null && c1 != null) { 1254 setVerdict(((String ) c0).startsWith((String ) c1)); 1255 return; 1256 } 1257 clear(); 1258 } 1259 1260 public void visit(FunctionLOCAL_NAME arg) throws XQueryException { 1261 returnType.push(NODE_TYPE); 1262 arg.getArgument(0).accept(this); 1263 returnType.pop(); 1264 Integer rettype = (Integer ) returnType.peek(); 1265 if (this.resnodes != null && resnodes.size() == 1) { 1267 this.setValue(((TypedNode) resnodes.get(0)).getLocalName()); 1268 return; 1269 } 1270 clear(); 1272 } 1273 1274 public void visit(FunctionNAMESPACE_URI arg) throws XQueryException { 1275 returnType.push(NODE_TYPE); 1276 arg.getArgument(0).accept(this); 1277 returnType.pop(); 1278 Integer rettype = (Integer ) returnType.peek(); 1279 if (this.resnodes != null && resnodes.size() == 1) { 1281 this.setValue(((TypedNode) resnodes.get(0)).getNamespaceURI()); 1282 return; 1283 } 1284 clear(); 1286 } 1287 1288 1320 public void visit(FunctionSTRING arg) throws XQueryException { 1321 returnType.push(UNKNOWN_TYPE); 1322 arg.getArgument(0).accept(this); 1323 returnType.pop(); 1324 if (resvalue != null) { if (!(resvalue instanceof String )) 1326 resvalue = resvalue.toString(); 1327 } else if (resnodes == null || resnodes.isEmpty()) { 1328 resvalue = new String (""); 1329 } else if (resnodes != null && resnodes.size() == 1) { 1330 StringBuffer sb = new StringBuffer (); 1331 getStringValue((TypedNode) resnodes.get(0), sb); 1332 resvalue = sb.toString(); 1333 } else if (resnodes != null && resnodes.size() > 1) { 1334 throw new XQueryException("Evaluation : incorrect argument for function string"); 1335 } 1336 Integer rettype = (Integer ) returnType.peek(); 1337 if (rettype == NODE_TYPE) { 1338 ArrayList nodes = new ArrayList(1); 1339 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType()); 1340 nodes.add(text); 1341 setResnodes(nodes); 1342 return; 1343 } else { setValue(resvalue); 1345 return; 1346 } 1347 } 1349 1350 1363 public void visit(FunctionSTRING_LENGTH arg) throws XQueryException { 1364 returnType.push(UNKNOWN_TYPE); 1365 arg.getArgument(0).accept(this); 1366 returnType.pop(); 1367 if (resvalue != null) { if (resvalue instanceof String ) 1369 resvalue = new Long (((String ) resvalue).length()); 1370 else 1371 resvalue = new Long (resvalue.toString().length()); 1372 } else if (resnodes == null || resnodes.isEmpty()) { 1373 resvalue = new Long (0); 1374 } else if (resnodes != null && resnodes.size() == 1) { 1375 StringBuffer sb = new StringBuffer (); 1376 getStringValue((TypedNode) resnodes.get(0), sb); 1377 resvalue = new Long (sb.length()); 1378 } else if (resnodes != null && resnodes.size() > 1) { 1379 throw new XQueryException("Evaluation : incorrect argument for function string-length"); 1380 } 1381 Integer rettype = (Integer ) returnType.peek(); 1382 if (rettype == NODE_TYPE) { 1383 ArrayList nodes = new ArrayList(1); 1384 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 1385 nodes.add(text); 1386 setResnodes(nodes); 1387 return; 1388 } else { setValue(resvalue); 1390 return; 1391 } 1392 } 1394 1395 1427 public void visit(FunctionSUBSTRING arg) throws XQueryException { 1428 boolean hasLength = (arg.getArguments().size() == 3) ? true : false; 1429 String sourceString = null; 1430 returnType.push(UNKNOWN_TYPE); 1431 arg.getArgument(0).accept(this); 1432 if (resvalue != null) { 1433 if (resvalue instanceof String ) 1434 sourceString = (String ) resvalue; 1435 else 1436 sourceString = resvalue.toString(); 1437 } else if (resnodes != null && resnodes.size() == 1) { 1438 StringBuffer sb = new StringBuffer (); 1439 getStringValue((TypedNode) resnodes.get(0), sb); 1440 sourceString = sb.toString(); 1441 } else if (resnodes != null && resnodes.size() > 1) { 1442 throw new XQueryException("Evaluation : incorrect first argument for function substring"); 1443 } 1444 if (sourceString == null) { 1445 clear(); 1446 return; 1447 } 1448 double startingLoc = 0; 1449 arg.getArgument(1).accept(this); 1450 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1452 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1453 if (tmpnode == null) 1454 tmpnode = (TypedNode) resnodes.get(0); 1455 resvalue = (Comparable ) tmpnode.getTypedValue(); 1456 } else 1457 throw new XQueryException("Evaluation : incorrect second argument for function substring"); 1458 if (resvalue instanceof Number ) { 1459 startingLoc = ((Number ) resvalue).doubleValue(); 1460 } else if (resvalue instanceof String ) { 1461 try { 1462 startingLoc = Double.parseDouble((String ) resvalue); 1463 } catch (NumberFormatException e) { 1464 } 1466 } else 1467 throw new XQueryException("Evaluation : incorrect second argument for function substring"); 1468 if (startingLoc < 1) 1469 startingLoc = 1; 1470 double length = sourceString.length(); 1471 if (hasLength) { 1472 arg.getArgument(2).accept(this); 1473 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1475 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1476 if (tmpnode == null) 1477 tmpnode = (TypedNode) resnodes.get(0); 1478 resvalue = (Comparable ) tmpnode.getTypedValue(); 1479 } else 1480 throw new XQueryException("Evaluation : incorrect third argument for function substring"); 1481 if (resvalue instanceof Number ) { 1482 length = ((Number ) resvalue).doubleValue(); 1483 } else if (resvalue instanceof String ) { 1484 try { 1485 length = Double.parseDouble((String ) resvalue); 1486 } catch (NumberFormatException e) { 1487 } 1489 } else 1490 throw new XQueryException("Evaluation : incorrect third argument for function substring"); 1491 if (startingLoc + length > sourceString.length()) 1492 hasLength = false; 1493 } 1494 returnType.pop(); 1495 if (hasLength) 1496 resvalue = sourceString.substring((int) Math.round(startingLoc) - 1, (int) (Math.round(startingLoc) + Math.round(length)) - 1); 1497 else 1498 resvalue = sourceString.substring((int) Math.round(startingLoc) - 1); 1499 Integer rettype = (Integer ) returnType.peek(); 1500 if (rettype == NODE_TYPE) { 1501 ArrayList nodes = new ArrayList(1); 1502 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType()); 1503 nodes.add(text); 1504 setResnodes(nodes); 1505 return; 1506 } else { setValue(resvalue); 1508 return; 1509 } 1510 } 1512 1513 public void visit(FunctionABS arg) throws XQueryException { 1517 returnType.push(UNKNOWN_TYPE); 1518 arg.getArgument(0).accept(this); 1519 returnType.pop(); 1520 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1522 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1523 if (tmpnode == null) 1524 tmpnode = (TypedNode) resnodes.get(0); 1525 resvalue = (Comparable ) tmpnode.getTypedValue(); 1526 if (!(resvalue instanceof Number )) 1527 throw new XQueryException("Could not apply function abs"); 1528 } else 1529 throw new XQueryException("Could not apply function abs"); 1530 1531 if (resvalue instanceof Long ) 1532 resvalue = new Long (Math.abs(((Long ) resvalue).longValue())); 1533 else if (resvalue instanceof BigDecimal ) 1534 resvalue = ((BigDecimal ) resvalue).abs(); 1535 else if (resvalue instanceof Float ) 1536 resvalue = new Float (Math.abs(((Float ) resvalue).floatValue())); 1537 else if (resvalue instanceof Double ) 1538 resvalue = new Double (Math.abs(((Double ) resvalue).doubleValue())); 1539 1540 Integer rettype = (Integer ) returnType.peek(); 1541 if (rettype == VALUE_TYPE) { 1542 setValue(resvalue); 1543 return; 1544 } else { ArrayList nodes = new ArrayList(1); 1546 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 1547 nodes.add(text); 1548 setResnodes(nodes); 1549 return; 1550 } 1551 } 1553 public void visit(FunctionCEILING arg) throws XQueryException { 1554 returnType.push(UNKNOWN_TYPE); 1555 arg.getArgument(0).accept(this); 1556 returnType.pop(); 1557 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1559 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1560 if (tmpnode == null) 1561 tmpnode = (TypedNode) resnodes.get(0); 1562 resvalue = (Comparable ) tmpnode.getTypedValue(); 1563 if (!(resvalue instanceof Number )) 1564 throw new XQueryException("Could not apply function ceiling"); 1565 } else 1566 throw new XQueryException("Could not apply function ceiling"); 1567 1568 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 1570 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_CEILING); 1571 else if (resvalue instanceof Float ) 1572 resvalue = new Float (Math.ceil(((Float ) resvalue).floatValue())); 1573 else if (resvalue instanceof Double ) 1574 resvalue = new Double (Math.ceil(((Double ) resvalue).doubleValue())); 1575 1576 Integer rettype = (Integer ) returnType.peek(); 1577 if (rettype == VALUE_TYPE) { 1578 setValue(resvalue); 1579 return; 1580 } else { ArrayList nodes = new ArrayList(1); 1582 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 1583 nodes.add(text); 1584 setResnodes(nodes); 1585 return; 1586 } 1587 } 1589 public void visit(FunctionFLOOR arg) throws XQueryException { 1590 returnType.push(UNKNOWN_TYPE); 1591 arg.getArgument(0).accept(this); 1592 returnType.pop(); 1593 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1595 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1596 if (tmpnode == null) 1597 tmpnode = (TypedNode) resnodes.get(0); 1598 resvalue = (Comparable ) tmpnode.getTypedValue(); 1599 if (!(resvalue instanceof Number )) 1600 throw new XQueryException("Could not apply function floor"); 1601 } else 1602 throw new XQueryException("Could not apply function floor"); 1603 1604 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 1606 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_FLOOR); 1607 else if (resvalue instanceof Float ) 1608 resvalue = new Float (Math.floor(((Float ) resvalue).floatValue())); 1609 else if (resvalue instanceof Double ) 1610 resvalue = new Double (Math.floor(((Double ) resvalue).doubleValue())); 1611 1612 Integer rettype = (Integer ) returnType.peek(); 1613 if (rettype == VALUE_TYPE) { 1614 setValue(resvalue); 1615 return; 1616 } else { ArrayList nodes = new ArrayList(1); 1618 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 1619 nodes.add(text); 1620 setResnodes(nodes); 1621 return; 1622 } 1623 } 1625 public void visit(FunctionROUND arg) throws XQueryException { 1626 returnType.push(UNKNOWN_TYPE); 1627 arg.getArgument(0).accept(this); 1628 returnType.pop(); 1629 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1631 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1632 if (tmpnode == null) 1633 tmpnode = (TypedNode) resnodes.get(0); 1634 resvalue = (Comparable ) tmpnode.getTypedValue(); 1635 if (!(resvalue instanceof Number )) 1636 throw new XQueryException("Could not apply function round"); 1637 } else 1638 throw new XQueryException("Could not apply function round"); 1639 1640 if (resvalue instanceof Long ) { } else if (resvalue instanceof BigDecimal ) 1642 resvalue = ((BigDecimal ) resvalue).setScale(0, BigDecimal.ROUND_UP); 1643 else if (resvalue instanceof Float ) 1644 resvalue = new BigDecimal (Math.round(((Float ) resvalue).floatValue())); 1645 else if (resvalue instanceof Double ) 1646 resvalue = new BigDecimal (Math.round(((Double ) resvalue).doubleValue())); 1647 1648 Integer rettype = (Integer ) returnType.peek(); 1649 if (rettype == VALUE_TYPE) { 1650 setValue(resvalue); 1651 return; 1652 } else { ArrayList nodes = new ArrayList(1); 1654 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType())); 1655 nodes.add(text); 1656 setResnodes(nodes); 1657 return; 1658 } 1659 } 1661 1662 1678 public void visit(FunctionNUMBER arg) throws XQueryException { 1679 returnType.push(UNKNOWN_TYPE); 1680 arg.getArgument(0).accept(this); 1681 returnType.pop(); 1682 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1684 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1685 if (tmpnode == null) 1686 tmpnode = (TypedNode) resnodes.get(0); 1687 resvalue = (Comparable ) tmpnode.getTypedValue(); 1688 if (resvalue instanceof Number ) { 1689 resvalue = new Double (((Number ) resvalue).doubleValue()); 1690 } else if (resvalue instanceof String ) { 1691 try { 1692 resvalue = new Double (Double.parseDouble((String ) resvalue)); 1693 } catch (NumberFormatException e) { 1694 } 1696 } 1697 } else if (resnodes != null && resnodes.size() > 1) { 1698 throw new XQueryException("Evaluation : incorrect argument for function number"); 1699 } 1700 if (resvalue == null) { 1701 resvalue = new Double (Double.NaN); 1702 } 1703 Integer rettype = (Integer ) returnType.peek(); 1704 if (rettype == NODE_TYPE) { 1705 ArrayList nodes = new ArrayList(1); 1706 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 1707 nodes.add(text); 1708 setResnodes(nodes); 1709 return; 1710 } else { setValue(resvalue); 1712 return; 1713 } 1714 } 1716 1717 public void visit(FunctionDOUBLE arg) throws XQueryException { 1721 returnType.push(UNKNOWN_TYPE); 1722 arg.getArgument(0).accept(this); 1723 returnType.pop(); 1724 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1726 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1727 if (tmpnode == null) 1728 tmpnode = (TypedNode) resnodes.get(0); 1729 resvalue = (Comparable ) tmpnode.getTypedValue(); 1730 } else 1731 throw new XQueryException("Could not create double"); 1732 1733 if (resvalue instanceof Double ) { } else if (resvalue instanceof Number ) { 1735 resvalue = new Double (((Number ) resvalue).doubleValue()); 1736 } else if (resvalue instanceof String ) { 1737 try { 1738 resvalue = new Double (Double.parseDouble((String ) resvalue)); 1739 } catch (NumberFormatException e) { 1740 } 1742 } else 1743 throw new XQueryException("Could not create double"); 1744 Integer rettype = (Integer ) returnType.peek(); 1745 if (rettype == VALUE_TYPE) { 1746 setValue(resvalue); 1747 return; 1748 } else { ArrayList nodes = new ArrayList(1); 1750 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType()); 1751 nodes.add(text); 1752 setResnodes(nodes); 1753 return; 1754 } 1755 } 1757 1758 public void visit(FunctionINTEGER arg) throws XQueryException { 1759 returnType.push(UNKNOWN_TYPE); 1760 arg.getArgument(0).accept(this); 1761 returnType.pop(); 1762 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1764 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1765 if (tmpnode == null) 1766 tmpnode = (TypedNode) resnodes.get(0); 1767 resvalue = (Comparable ) tmpnode.getTypedValue(); 1768 } else 1769 throw new XQueryException("Could not create integer"); 1770 1771 if (resvalue instanceof Long ) { } else if (resvalue instanceof Number ) { 1773 resvalue = new Long (((Number ) resvalue).longValue()); 1774 } else if (resvalue instanceof String ) { 1775 try { 1776 resvalue = new Long ((String ) resvalue); 1777 } catch (NumberFormatException e) { 1778 } 1780 } else 1781 throw new XQueryException("Could not create integer"); 1782 Integer rettype = (Integer ) returnType.peek(); 1783 if (rettype == VALUE_TYPE) { 1784 setValue(resvalue); 1785 return; 1786 } else { ArrayList nodes = new ArrayList(1); 1788 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType()); 1789 nodes.add(text); 1790 setResnodes(nodes); 1791 return; 1792 } 1793 } 1795 1796 public void visit(FunctionDECIMAL arg) throws XQueryException { 1797 returnType.push(UNKNOWN_TYPE); 1798 arg.getArgument(0).accept(this); 1799 returnType.pop(); 1800 if (resvalue != null) { } else if (resnodes != null && resnodes.size() == 1) { 1802 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild(); 1803 if (tmpnode == null) 1804 tmpnode = (TypedNode) resnodes.get(0); 1805 resvalue = (Comparable ) tmpnode.getTypedValue(); 1806 } else 1807 throw new XQueryException("Could not create decimal"); 1808 1809 if (resvalue instanceof BigDecimal ) { } else if (resvalue instanceof Number ) { 1811 resvalue = new BigDecimal (((Number ) resvalue).doubleValue()); 1812 } else if (resvalue instanceof String ) { 1813 try { 1814 resvalue = new BigDecimal ((String ) resvalue); 1815 } catch (NumberFormatException e) { 1816 } 1818 } else 1819 throw new XQueryException("Could not create decimal"); 1820 Integer rettype = (Integer ) returnType.peek(); 1821 if (rettype == VALUE_TYPE) { 1822 setValue(resvalue); 1823 return; 1824 } else { ArrayList nodes = new ArrayList(1); 1826 TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType()); 1827 nodes.add(text); 1828 setResnodes(nodes); 1829 return; 1830 } 1831 } 1833 1834 1838 public void visit(FunctionDATA arg) throws XQueryException { 1839 returnType.push(UNKNOWN_TYPE); 1840 arg.getArgument(0).accept(this); 1841 returnType.pop(); 1842 Integer rettype = (Integer ) returnType.peek(); 1843 if (resvalue != null) { 1844 if (rettype == VALUE_TYPE) { 1845 setValue(resvalue); 1846 return; 1847 } else if (rettype == BOOLEAN_TYPE) { 1848 setVerdict(true); 1849 return; 1850 } else { ArrayList nodes = new ArrayList(1); 1852 TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getAnySimpleType())); 1853 nodes.add(text); 1854 setResnodes(nodes); 1855 return; 1856 } 1857 } else if (resnodes != null) { 1858 ArrayList tmplist = new ArrayList(resnodes.size()); 1859 for (int i = 0; i < resnodes.size(); i++) { 1860 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(i)).getFirstChild(); 1861 if (tmpnode == null || tmpnode.getTypedValue() == null) 1863 tmpnode = (TypedNode) resnodes.get(i); 1864 Comparable comp = (Comparable ) tmpnode.getTypedValue(); 1865 if (comp != null) 1866 tmplist.add(docimpl.createTypedValue(comp, this.getSimpleType(comp, schemamanager.getAnySimpleType()))); 1867 } 1870 if (rettype == VALUE_TYPE) { 1871 if (tmplist.size() == 1) { 1872 TypedNode tmpnode = (TypedNode) ((TypedNode) tmplist.get(0)).getFirstChild(); 1873 if (tmpnode == null) 1874 tmpnode = (TypedNode) tmplist.get(0); 1875 setValue((Comparable ) tmpnode.getTypedValue()); 1876 return; 1877 } 1878 } else if (rettype == BOOLEAN_TYPE) { 1879 if (tmplist.size() > 0) 1880 setVerdict(true); 1881 else 1882 setVerdict(false); 1883 return; 1884 } else { setResnodes(tmplist); 1886 return; 1887 } 1888 } 1889 } 1893 1894 public void visit(FunctionEXISTS arg) throws XQueryException { 1895 returnType.push(NODE_TYPE); 1896 arg.getArgument(0).accept(this); 1897 returnType.pop(); 1898 setVerdict(resnodes != null && !resnodes.isEmpty()); 1899 } 1900 1901 public void visit(FunctionEMPTY arg) throws XQueryException { 1902 returnType.push(NODE_TYPE); 1907 arg.getArgument(0).accept(this); 1908 returnType.pop(); 1909 setVerdict(resnodes == null || resnodes.isEmpty()); 1910 } 1911 1912 public void visit(FunctionNOT arg) throws XQueryException { 1913 arg.getArgument(0).accept(this); 1914 setVerdict(!verdict); 1915 } 1916 1917 1919 public void visit(FunctionDEEP_EQUALS arg) throws XQueryException { 1920 resnodes = null; 1921 XQueryExpression arg0 = arg.getArgument(0); 1922 XQueryExpression arg1 = arg.getArgument(1); 1923 if (arg0 instanceof Value && arg1 instanceof Value) 1924 processComparison(arg0, arg1, null, null, null, null, Constants.EQ_COMPOP); 1925 else { 1926 if (arg0 instanceof Value) { 1927 } else if (arg1 instanceof Value) { 1928 } else { 1929 } 1930 } 1931 } 1932 1933 1934 1938 public void visit(FunctionEXPANDED_QNAME arg) throws XQueryException { 1939 returnType.push(VALUE_TYPE); 1940 arg.getArgument(0).accept(this); 1941 if (resvalue == null) 1942 throw new XQueryException("Could not evaluate " + arg.getArgument(0)); 1943 String prefix = resvalue.toString(); 1944 String namespace = context.getNamespaceURI(prefix); 1945 if (namespace == null) 1946 throw new XQueryException("Could not find prefix : " + prefix); 1947 resvalue = null; 1948 arg.getArgument(1).accept(this); 1949 returnType.pop(); 1950 if (resvalue == null) 1951 throw new XQueryException("Could not evaluate " + arg.getArgument(1)); 1952 String localname = resvalue.toString(); 1953 setValue((namespace.length() == 0)?localname:namespace+":"+localname); 1954 } 1955 1956 public void visit(FunctionQNAME arg) throws XQueryException { 1957 returnType.push(VALUE_TYPE); 1958 arg.getArgument(0).accept(this); 1959 if (resvalue == null) 1960 throw new XQueryException("Could not evaluate " + arg.getArgument(0)); 1961 String qname = resvalue.toString(); 1962 int index = qname.indexOf(":"); 1963 String prefix = null; 1964 String namespace = null; 1965 if (index != -1) { 1966 prefix = qname.substring(0,index); 1967 namespace = context.getNamespaceURI(prefix); 1968 if (namespace == null) 1969 throw new XQueryException("Could not find prefix : " + prefix); 1970 } 1971 String localname = qname.substring(index+1); 1972 setValue((namespace == null || namespace.length() == 0)?localname:namespace+":"+localname); 1973 } 1974 1975 1979 private SimpleType getSimpleType(Comparable obj, SimpleType defaultType) { 1980 if (obj instanceof Long ) 1981 return this.schemamanager.getIntegerType(); 1982 else if (obj instanceof BigDecimal ) 1983 return this.schemamanager.getDecimalType(); 1984 else if (obj instanceof Float ) 1985 return this.schemamanager.getFloatType(); 1986 else if (obj instanceof Double ) 1987 return this.schemamanager.getDoubleType(); 1988 else if (obj instanceof String ) 1989 return this.schemamanager.getStringType(); 1990 else if (obj instanceof Date) 1991 return this.schemamanager.getDateTimeType(); 1992 return defaultType; 1993 } 1994 1995 private void processComparison(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Comparable value1, Comparable value2, int operator) { 1996 boolean doublecompare = false; 1998 double value1double = 0; 1999 if (value1 == null) { 2000 if (exp1 instanceof ValueInteger) { 2001 value1 = new Long (((ValueInteger) exp1).getIntValue().longValue()); 2002 } else if (exp1 instanceof ValueDecimal) { 2003 value1 = ((ValueDecimal) exp1).getDecimalValue(); 2004 } else if (exp1 instanceof ValueFloat) { 2005 value1 = ((ValueFloat) exp1).getFloatValue(); 2006 } else if (exp1 instanceof ValueDouble) { 2007 value1 = ((ValueDouble) exp1).getDoubleValue(); 2008 } else if (exp1 instanceof ValueString) { 2009 value1 = ((ValueString) exp1).getValue(); 2010 } else if (tree1 != null) { 2011 if (tree1.getTypedValue() != null) 2012 value1 = (Comparable ) tree1.getTypedValue(); 2013 else 2014 value1 = (Comparable ) getTextLeaf(tree1); 2015 } 2016 } 2017 if (value1 != null && !(value1 instanceof String ) && !(value1 instanceof Timestamp ) && !(value1 instanceof Date)) { 2018 value1double = ((Number ) value1).doubleValue(); 2019 doublecompare = true; 2020 } 2021 double value2double = 0; 2023 if (value2 == null) { 2024 if (exp2 instanceof ValueInteger) { 2025 value2 = new Long (((ValueInteger) exp2).getIntValue().longValue()); 2026 } else if (exp2 instanceof ValueDecimal) { 2027 value2 = ((ValueDecimal) exp2).getDecimalValue(); 2028 } else if (exp2 instanceof ValueFloat) { 2029 value2 = ((ValueFloat) exp2).getFloatValue(); 2030 } else if (exp2 instanceof ValueDouble) { 2031 value2 = ((ValueDouble) exp2).getDoubleValue(); 2032 } else if (exp2 instanceof ValueString) 2033 value2 = ((ValueString) exp2).getValue(); 2034 else if (tree2 != null) { 2035 if (tree2.getTypedValue() != null) 2036 value2 = (Comparable ) tree2.getTypedValue(); 2037 else 2038 value2 = (Comparable ) getTextLeaf(tree2); 2039 } 2040 } 2041 if (value2 != null && !(value2 instanceof String ) && !(value2 instanceof Timestamp ) && !(value2 instanceof Date)) { 2042 value2double = ((Number ) value2).doubleValue(); 2043 } else 2044 doublecompare = false; 2045 boolean stringcomp = false; 2046 if (value1 == null) { 2047 if (value2 != null) { 2048 setVerdict(false); 2049 return; 2050 } 2051 } else { 2052 if (value2 == null) { 2053 setVerdict(false); 2054 return; 2055 } else { 2056 if (value1 instanceof String ) { 2057 if (!(value2 instanceof String )) { 2058 value2 = value2.toString(); 2059 if (value2 == null) { 2060 setVerdict(false); 2061 return; 2062 } 2063 stringcomp = true; 2064 } 2065 } else if (value2 instanceof String ) { 2066 value1 = value1.toString(); 2067 if (value1 == null) { 2068 setVerdict(false); 2069 return; 2070 } 2071 stringcomp = true; 2072 } 2073 } 2074 } 2075 switch (operator) { 2076 case Constants.LT_VALUECOMP : 2077 case Constants.LT_COMPOP : 2078 if ((value1 == null) && (value2 == null)) 2079 setVerdict(false); 2080 else if (stringcomp || !doublecompare) 2081 setVerdict((value1.compareTo(value2) < 0)); 2082 else 2083 setVerdict((value1double < value2double)); 2084 return; 2085 case Constants.GT_VALUECOMP : 2086 case Constants.GT_COMPOP : 2087 if ((value1 == null) && (value2 == null)) 2088 setVerdict(false); 2089 else if (stringcomp || !doublecompare) 2090 setVerdict((value1.compareTo(value2) > 0)); 2091 else 2092 setVerdict((value1double > value2double)); 2093 return; 2094 case Constants.GE_VALUECOMP : 2095 case Constants.GEQ_COMPOP : 2096 if ((value1 == null) && (value2 == null)) 2097 setVerdict(true); 2098 else if (stringcomp || !doublecompare) 2099 setVerdict((value1.compareTo(value2) >= 0)); 2100 else 2101 setVerdict((value1double >= value2double)); 2102 return; 2103 case Constants.LE_VALUECOMP : 2104 case Constants.LEQ_COMPOP : 2105 if ((value1 == null) && (value2 == null)) 2106 setVerdict(true); 2107 else if (stringcomp || !doublecompare) 2108 setVerdict((value1.compareTo(value2) <= 0)); 2109 else 2110 setVerdict((value1double <= value2double)); 2111 return; 2112 case Constants.EQ_VALUECOMP : 2113 case Constants.EQ_COMPOP : 2114 if ((value1 == null) && (value2 == null)) 2115 setVerdict(true); 2116 else if (stringcomp || !doublecompare) 2117 setVerdict((value1.compareTo(value2) == 0)); 2118 else 2119 setVerdict((value1double == value2double)); 2120 return; 2121 case Constants.NE_VALUECOMP : 2122 case Constants.NEQ_COMPOP : 2123 if ((value1 == null) && (value2 == null)) 2124 setVerdict(false); 2125 else if (stringcomp || !doublecompare) 2126 setVerdict((value1.compareTo(value2) != 0)); 2127 else 2128 setVerdict((value1double != value2double)); 2129 return; 2130 2135 } 2136 clear(); 2137 } 2138 2139 private Number processOperation(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Number value1, Number value2, int operator) throws XQueryException { 2140 if (value1 == null) { 2141 if (exp1 instanceof ValueInteger) 2142 value1 = new Long (((ValueInteger) exp1).getIntValue().longValue()); 2143 else if (exp1 instanceof ValueDecimal) 2144 value1 = ((ValueDecimal) exp1).getDecimalValue(); 2145 else if (exp1 instanceof ValueFloat) 2146 value1 = ((ValueFloat) exp1).getFloatValue(); 2147 else if (exp1 instanceof ValueDouble) 2148 value1 = ((ValueDouble) exp1).getDoubleValue(); 2149 else if (tree1 != null) 2150 if (tree1.getTypedValue() != null) 2151 value1 = (Number ) tree1.getTypedValue(); 2152 else 2153 value1 = (Number ) getTextLeaf(tree1); 2154 } 2155 if (value2 == null) { 2156 if (exp2 instanceof ValueInteger) 2157 value2 = new Long (((ValueInteger) exp2).getIntValue().longValue()); 2158 else if (exp2 instanceof ValueDecimal) 2159 value2 = ((ValueDecimal) exp2).getDecimalValue(); 2160 else if (exp2 instanceof ValueFloat) 2161 value2 = ((ValueFloat) exp2).getFloatValue(); 2162 else if (exp2 instanceof ValueDouble) 2163 value2 = ((ValueDouble) exp2).getDoubleValue(); 2164 else if (tree2 != null) 2165 if (tree2.getTypedValue() != null) 2166 value2 = (Number ) tree2.getTypedValue(); 2167 else 2168 value2 = (Number ) getTextLeaf(tree2); 2169 } 2170 2171 boolean integerOp = false; 2172 boolean decimalOp = false; 2173 boolean floatOp = false; 2174 if (value1 instanceof Long ) { 2175 if (value2 instanceof Long ) 2176 integerOp = true; 2177 else if (value2 instanceof BigDecimal ) { 2178 value1 = new BigDecimal (value1.longValue()); 2179 decimalOp = true; 2180 } 2181 } else if (value1 instanceof BigDecimal ) { 2182 if (value2 instanceof BigDecimal ) 2183 decimalOp = true; 2184 else if (value2 instanceof Long ) { 2185 value2 = new BigDecimal (value2.longValue()); 2186 decimalOp = true; 2187 } 2188 } else if (value1 instanceof Float ) { 2189 if (value2 instanceof Float ) 2190 floatOp = true; 2191 if (!(value2 instanceof Double )) { 2192 value2 = new Float (value2.doubleValue()); 2193 floatOp = true; 2194 } 2195 } 2196 2197 switch (operator) { 2198 case Constants.DIVIDE_ARITHMETICS : 2199 if (decimalOp) { 2207 try { 2208 return ((BigDecimal ) value1).divide((BigDecimal ) value2, 38, BigDecimal.ROUND_UP); 2209 } catch (ArithmeticException ae) { 2210 throw new XQueryException("Division by zero"); 2211 } 2212 } else if (floatOp) 2213 return new Float (value1.floatValue() / value2.floatValue()); 2214 return new Double (value1.doubleValue() / value2.doubleValue()); 2215 case Constants.MINUS_ARITHMETICS : 2216 if (integerOp) 2217 return new Long (value1.longValue() - value2.longValue()); 2218 else if (decimalOp) 2219 return ((BigDecimal ) value1).subtract((BigDecimal ) value2); 2220 else if (floatOp) 2221 return new Float (value1.floatValue() - value2.floatValue()); 2222 return new Double (value1.doubleValue() - value2.doubleValue()); 2223 case Constants.MODULO_ARITHMETICS : 2224 if (integerOp) 2225 return new Long (value1.longValue() % value2.longValue()); 2226 else if (floatOp) 2227 return new Float (value1.floatValue() % value2.floatValue()); 2228 return new Double (value1.doubleValue() % value2.doubleValue()); 2229 case Constants.MULTIPLY_ARITHMETICS : 2230 if (integerOp) 2231 return new Long (value1.longValue() * value2.longValue()); 2232 else if (decimalOp) 2233 return ((BigDecimal ) value1).multiply((BigDecimal ) value2); 2234 else if (floatOp) 2235 return new Float (value1.floatValue() * value2.floatValue()); 2236 return new Double (value1.doubleValue() * value2.doubleValue()); 2237 case Constants.PLUS_ARITHMETICS : 2238 if (integerOp) 2239 return new Long (value1.longValue() + value2.longValue()); 2240 else if (decimalOp) 2241 return ((BigDecimal ) value1).add((BigDecimal ) value2); 2242 else if (floatOp) 2243 return new Float (value1.floatValue() + value2.floatValue()); 2244 return new Double (value1.doubleValue() + value2.doubleValue()); 2245 } 2246 throw new XQueryException("Could not process operation"); 2247 } 2248 2249 private void getStringValue(Node node, StringBuffer sb) { 2250 if (node == null) 2251 return; 2252 if (node.getNodeType() == Node.TEXT_NODE) { 2253 sb.append(node.getNodeValue()); 2254 } 2255 org.w3c.dom.NodeList nl = node.getChildNodes(); 2256 for (int i = 0; i < nl.getLength(); i++) { 2257 getStringValue(nl.item(i), sb); 2258 } 2259 } 2260 2261 private Object getTextLeaf(TypedNode node) { 2262 if (node == null) 2263 return null; 2264 if (node instanceof TypedValue) { 2265 return ((TypedValue) node).getData(); 2266 } 2267 if (node instanceof TypedAttributeImpl) { 2268 return ((TypedAttributeImpl) node).getNodeValue(); 2269 } 2270 org.w3c.dom.NodeList nl = node.getChildNodes(); 2271 if (nl.getLength() != 1) 2272 return null; 2273 TypedNode n = (TypedNode) nl.item(0); 2274 return n.getTypedValue(); 2275 } 2276 2277} 2278 | Popular Tags |