1 23 24 package org.xquark.mediator.DOMUtils; 25 26 import java.math.BigDecimal ; 27 import java.sql.Date ; 28 import java.util.ArrayList ; 29 30 import org.w3c.dom.NamedNodeMap ; 31 import org.w3c.dom.Node ; 32 import org.w3c.dom.NodeList ; 33 import org.xquark.mediator.plan.DynamicContext; 34 import org.xquark.mediator.runtime.MediatorException; 35 import org.xquark.schema.SchemaManager; 36 import org.xquark.xpath.Axis; 37 import org.xquark.xpath.NodeKind; 38 import org.xquark.xpath.datamodel.*; 39 import org.xquark.xquery.parser.*; 40 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.FunctionDATETIME; 41 import org.xquark.xquery.parser.util.Constants; 42 import org.xquark.xquery.typing.*; 43 44 public class DOMUtils { 45 private static final String RCSRevision = "$Revision: 1.14 $"; 49 private static final String RCSName = "$Name: $"; 50 51 protected static TypedDocumentImpl docimpl = null; 52 static { 53 docimpl = new TypedDocumentImpl(); 54 } 55 56 protected static EvaluationVisitor evalVisitor = null; 57 static { 58 evalVisitor = new EvaluationVisitor(null); 59 } 60 61 public static boolean evalCondition(DynamicContext context, XQueryExpression expr, Tuple tuple) throws MediatorException { 62 try { 63 evalVisitor.setSchemaManager(context.getSchemaManager()); 64 if (tuple != null) 65 context.addCurrentTuple(tuple); 66 evalVisitor.reset(context.getCurrentTuples()); 67 evalVisitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE); 68 expr.accept(evalVisitor); 69 if (tuple != null) 70 context.deleteCurrentTuple(tuple); 71 return evalVisitor.getVerdict(); 72 } catch (XQueryException e) { 73 throw new MediatorException(e.getMessage()); 74 } 75 } 76 77 public static ArrayList evalNodes(DynamicContext context, XQueryExpression expr, Tuple tuple) throws MediatorException { 78 try { 79 evalVisitor.setSchemaManager(context.getSchemaManager()); 80 if (tuple != null) 81 context.addCurrentTuple(tuple); 82 evalVisitor.reset(context.getCurrentTuples()); 83 evalVisitor.setReturnType(EvaluationVisitor.NODE_TYPE); 84 expr.accept(evalVisitor); 85 if (tuple != null) 86 context.deleteCurrentTuple(tuple); 87 return evalVisitor.getResNodes(); 88 } catch (XQueryException e) { 89 throw new MediatorException(e.getMessage()); 90 } 91 } 92 93 public static boolean compareTree(ArrayList trees1, ArrayList trees2) { 97 if ((trees1 == null) && (trees2 == null)) 98 return true; 99 if ((trees1 != null) && (trees2 == null)) 100 return false; 101 if ((trees1 == null) && (trees2 != null)) 102 return false; 103 if (trees1.size() != trees2.size()) 104 return false; 105 for (int i = 0; i < trees1.size(); i++) 106 if (compareTree((TypedNode) trees1.get(i), (TypedNode) trees2.get(i)) == false) 107 return false; 108 return true; 109 } 110 111 120 public static boolean compareTree(TypedNode node1, TypedNode node2) { 121 if (!node1.getNodeName().equals(node2.getNodeName())) 122 return false; 123 Comparable value1 = (Comparable ) node1.getTypedValue(); 124 Comparable value2 = (Comparable ) node2.getTypedValue(); 125 if ((value1 == null) && (value2 != null)) 126 return false; 127 if ((value1 != null) && (value2 == null)) 128 return false; 129 if ((value1 != null) && (value2 != null)) 130 if (!value1.equals(value2)) 131 return false; 132 org.w3c.dom.NodeList nl1 = node1.getChildNodes(); 133 org.w3c.dom.NodeList nl2 = node2.getChildNodes(); 134 135 if (nl1.getLength() != nl2.getLength()) 136 return false; 137 138 for (int i = 0; i < nl1.getLength(); i++) { 139 TypedNode n1 = (TypedNode) nl1.item(i); 140 String label = n1.getNodeName(); 141 ArrayList v = getAllNodeByName(node2, label); 142 if (v.size() < 1) 143 return false; 144 boolean b = false; 145 for (int j = 0; j < v.size(); j++) { 146 TypedNode n2 = (TypedNode) v.get(j); 147 b = compareTree(n1, n2); 148 if (b == true) 149 break; 150 } 151 if (b == false) 152 return false; 153 } 154 org.w3c.dom.NamedNodeMap nnm1 = node1.getAttributes(); 155 org.w3c.dom.NamedNodeMap nnm2 = node2.getAttributes(); 156 if ((nnm1 == null) && (nnm1 == null)) 157 return true; 158 if (nnm1 == null) 159 return false; 160 if (nnm2 == null) 161 return false; 162 if (nnm1.getLength() != nnm2.getLength()) 163 return false; 164 for (int i = 0; i < nnm1.getLength(); i++) { 165 TypedNode n1 = (TypedNode) nnm1.item(i); 166 TypedNode n2 = (TypedNode) nnm2.getNamedItem(n1.getNodeName()); 167 if (n2 == null) 168 return false; 169 if (n1.getTypedValue() == null && n2.getTypedValue() == null) 170 continue; 171 if (n1.getTypedValue() == null || n2.getTypedValue() == null) 172 return false; 173 if (n1.getTypedValue() instanceof Comparable && n2.getTypedValue() instanceof Comparable ) { 174 if (DOMUtils.compareObjects((Comparable ) n1.getTypedValue(), (Comparable ) n2.getTypedValue()) != 0) 175 return false; 176 } else { 177 if (!n1.getTypedValue().equals(n2.getTypedValue())) 178 return false; 179 } 180 } 181 return true; 182 } 183 184 189 public static int simpleCompareNodeValue(ArrayList nodes1, ArrayList nodes2) { 190 if (nodes1 == null || nodes1.isEmpty()) return -1; 191 if (nodes2 == null || nodes2.isEmpty()) return 1; 192 TypedNode node1 = (TypedNode)nodes1.get(0); 193 TypedNode node2 = (TypedNode)nodes2.get(0); 194 Comparable value1 = (Comparable ) node1.getTypedValue(); 195 Comparable value2 = (Comparable ) node2.getTypedValue(); 196 if (value1 == null) 197 value1 = (Comparable ) ((TypedNode) node1.getChildNodes().item(0)).getTypedValue(); 198 if (value2 == null) 199 value2 = (Comparable ) ((TypedNode) node2.getChildNodes().item(0)).getTypedValue(); 200 return compareObjects(value1, value2); 201 } 202 203 public static int compareObjects(Comparable value1, Comparable value2) { 204 if (value1.getClass() == value2.getClass()) 207 return value1.compareTo(value2); 208 209 if (value1 instanceof Double ) { 210 value2 = new Double (value2.toString()); 211 } else if (value2 instanceof Double ) { 212 value1 = new Double (value1.toString()); 213 } else if (value1 instanceof Float ) { 214 value2 = new Float (value2.toString()); 215 } else if (value2 instanceof Float ) { 216 value1 = new Float (value1.toString()); 217 } else if (value1 instanceof BigDecimal ) { 218 value2 = new BigDecimal (value2.toString()); 219 } else if (value2 instanceof BigDecimal ) { 220 value1 = new BigDecimal (value1.toString()); 221 } else if (value1 instanceof Integer ) { 222 value2 = new Integer (value2.toString()); 223 } else if (value2 instanceof Integer ) { 224 value1 = new Integer (value1.toString()); 225 } 226 return value1.compareTo(value2); 227 } 228 229 236 public static ArrayList getAllNodeByName(TypedNode root, String label) { 237 org.w3c.dom.NodeList nl = root.getChildNodes(); 238 ArrayList vect = new ArrayList (); 239 240 for (int i = 0; i < nl.getLength(); i++) { 241 if (nl.item(i).getNodeName().equalsIgnoreCase(label)) { 242 vect.add(nl.item(i)); 243 } 244 } 245 return vect; 246 } 247 248 278 public static Object getTextLeaf(TypedNode node) { 279 if (node == null) 280 return null; 281 if (node instanceof TypedValue) { 282 return ((TypedValue) node).getData(); 283 } 284 if (node instanceof TypedAttributeImpl) { 285 return ((TypedAttributeImpl) node).getNodeValue(); 286 } 287 org.w3c.dom.NodeList nl = node.getChildNodes(); 288 if (nl.getLength() != 1) 289 return null; 290 TypedNode n = (TypedNode) nl.item(0); 291 return n.getTypedValue(); 292 } 293 294 public static Object getTextLeaf(TypedNode node, LocatedExpression paths) { 296 ArrayList path = new ArrayList (); 297 ArrayList steps = paths.getSteps(); 298 for (int i = 0; i < steps.size(); i++) { 299 Step step = (Step) steps.get(i); 300 XQueryExpression exp = step.getExpression(); 301 if (exp instanceof QName) 303 path.add(((QName) exp).getLocalName()); 304 } 305 TypedNode leafnode = getNodeByPath(path, node); 306 return getTextLeaf(leafnode); 307 } 308 309 public static void getStringValue(Node node, StringBuffer sb) { 310 if (node == null) 311 return; 312 if (node.getNodeType() == Node.TEXT_NODE) { 313 sb.append(node.getNodeValue()); 314 } 315 org.w3c.dom.NodeList nl = node.getChildNodes(); 316 for (int i = 0; i < nl.getLength(); i++) { 317 getStringValue(nl.item(i), sb); 318 } 319 } 320 321 328 private static TypedNode getNodeByPath(ArrayList path, TypedNode root) { 329 330 if (root == null) 331 return null; 332 if (path == null || path.isEmpty()) 333 return root; 334 335 org.w3c.dom.NodeList nl = root.getChildNodes(); 336 boolean found = false; 337 TypedNode n = null; 338 for (int i = 0; i < nl.getLength(); i++) { 339 n = (TypedNode) nl.item(i); 340 if (n.getNodeName().equals((String ) path.get(0))) { 341 path.remove(0); 342 found = true; 343 break; 344 } 345 } 346 if (found == false) 347 return null; 348 if (path.size() <= 0) 349 return n; 350 return (getNodeByPath(path, n)); 351 } 352 353 360 private static ArrayList getNodeListByPath(ArrayList path, TypedNode root) { 361 if ((path == null) || (path.size() <= 0)) 362 return null; 363 364 String str = (String ) path.get(path.size() - 1); 365 path.remove(path.size() - 1); 366 TypedNode n = getNodeByPath(path, root); 367 368 if (n == null) 369 return null; 370 371 org.w3c.dom.NodeList nl = n.getChildNodes(); 372 373 ArrayList v = new ArrayList (); 374 for (int i = 0; i < nl.getLength(); i++) { 375 n = (TypedNode) nl.item(i); 376 if (n.getNodeName().equals(str)) 377 v.add(n); 378 } 379 return v; 380 } 381 382 private static boolean compareQNames(String nameSpace1, String localName1, String nameSpace2, String localName2) { 383 if ((((nameSpace1 == null || nameSpace1.equals("")) && (nameSpace2 == null || nameSpace2.equals(""))) || (nameSpace1 != null && nameSpace1.equals("*")) || (nameSpace2 != null) && (nameSpace2.equals("*") || nameSpace2.equals(nameSpace2))) && localName1 != null && localName2 != null && localName1.equals(localName2)) 384 return true; 385 return false; 386 } 387 388 private static ArrayList getStep(TypedNode node, Step step) throws MediatorException { 389 return getStep(node, step, null); 390 } 391 392 private static ArrayList getStep(TypedNode node, Step step, ArrayList reslist) throws MediatorException { 393 if (step == null) 394 return null; 395 XQueryExpression stepExpr = step.getExpression(); 398 int nodeType = node.getNodeType(); 399 switch (step.getAxis()) { 400 case Axis.NONE : 402 if (stepExpr instanceof ListOpUNIONExpression) { 403 ArrayList nodelist = new ArrayList (1); 404 nodelist.add(node); 405 ArrayList steps = ((LocatedExpression) ((ListOpUNIONExpression) stepExpr).getExpression1()).getSteps(); 406 for (int i = 0; i < steps.size(); i++) { 407 nodelist = getStep(nodelist, (Step) steps.get(i)); 408 if (nodelist == null) 409 break; 410 } 411 if (nodelist != null && !nodelist.isEmpty()) { 412 if (reslist == null) 413 reslist = new ArrayList (); 414 reslist.addAll(nodelist); 415 } 416 nodelist = new ArrayList (1); 417 nodelist.add(node); 418 steps = ((LocatedExpression) ((ListOpUNIONExpression) stepExpr).getExpression2()).getSteps(); 419 for (int i = 0; i < steps.size(); i++) { 420 nodelist = getStep(nodelist, (Step) steps.get(i)); 421 if (nodelist == null) 422 break; 423 } 424 if (nodelist != null && !nodelist.isEmpty()) { 425 if (reslist == null) 426 reslist = new ArrayList (); 427 reslist.addAll(nodelist); 428 } 429 return reslist; 430 } else 431 return null; 432 case Axis.CHILD : 433 if (nodeType == Node.ATTRIBUTE_NODE) 437 return null; 438 if (stepExpr instanceof QName) { 439 NodeList nl = node.getChildNodes(); 440 for (int i = 0; i < nl.getLength(); i++) { 441 Node tmpnode = nl.item(i); 442 if (tmpnode.getNodeType() == Node.ELEMENT_NODE) { 443 if (compareQNames(((QName) stepExpr).getNameSpace(), ((QName) stepExpr).getLocalName(), tmpnode.getNamespaceURI(), tmpnode.getLocalName())) { 444 if (reslist == null) 445 reslist = new ArrayList (); 446 reslist.add(tmpnode); 447 } 448 } 449 } 450 return reslist; 451 } else if (stepExpr instanceof NodeTest) { 452 NodeList nl = node.getChildNodes(); 453 switch (((NodeTest) stepExpr).getKind()) { 454 case NodeKind.TEXT : 455 for (int i = 0; i < nl.getLength(); i++) { 456 Node tmpnode = nl.item(i); 457 if (tmpnode.getNodeType() == Node.TEXT_NODE) { 458 if (reslist == null) 459 reslist = new ArrayList (); 460 reslist.add(tmpnode); 461 } 462 } 463 return reslist; 464 case NodeKind.NODE : 465 for (int i = 0; i < nl.getLength(); i++) { 466 Node tmpnode = nl.item(i); 467 if (tmpnode.getNodeType() == Node.TEXT_NODE || tmpnode.getNodeType() == Node.ELEMENT_NODE) { 468 if (reslist == null) 469 reslist = new ArrayList (); 470 reslist.add(tmpnode); 471 } 472 } 473 return reslist; 474 } 475 } 476 break; 477 case Axis.DESCENDANT_OR_SELF : 478 if (stepExpr instanceof NodeTest) { 481 if (reslist == null) { 482 reslist = new ArrayList (); 483 reslist.add(node); 484 } 485 if (nodeType == Node.ATTRIBUTE_NODE) 486 return reslist; 487 NodeList nl = node.getChildNodes(); 488 switch (((NodeTest) step.getExpression()).getKind()) { 489 case NodeKind.NODE : 490 for (int i = 0; i < nl.getLength(); i++) { 491 Node tmpnode = nl.item(i); 492 if (tmpnode.getNodeType() == Node.TEXT_NODE || tmpnode.getNodeType() == Node.ELEMENT_NODE) { 493 reslist.add(tmpnode); 494 getStep((TypedNode) tmpnode, step, reslist); 495 } 496 } 497 return reslist; 498 } 499 } 500 break; 501 case Axis.ATTRIBUTE : 502 if (stepExpr instanceof QName) { 504 NamedNodeMap nnm = node.getAttributes(); 505 if (nnm != null) { 506 Node tmpnode = nnm.getNamedItem(step.getExpression().getStringValue()); 507 if (tmpnode != null) { 508 if (reslist == null) 509 reslist = new ArrayList (1); 510 reslist.add(tmpnode); 511 return reslist; 512 } 513 } 514 return reslist; 515 } 516 break; 517 case Axis.SELF : 518 if (stepExpr instanceof QName) { 522 if (nodeType != Node.ELEMENT_NODE && nodeType != Node.ATTRIBUTE_NODE) 523 return null; 524 if (compareQNames(((QName) stepExpr).getNameSpace(), ((QName) stepExpr).getLocalName(), node.getNamespaceURI(), node.getLocalName())) { 525 if (reslist == null) 526 reslist = new ArrayList (1); 527 reslist.add(node); 528 } 529 return reslist; 530 } else if (stepExpr instanceof NodeTest) { 531 switch (((NodeTest) stepExpr).getKind()) { 532 case NodeKind.TEXT : 533 if (nodeType != Node.TEXT_NODE) 534 return null; 535 String text = node.getNodeValue(); 536 if (text == null || text.length() == 0) 537 return null; 538 if (reslist == null) 539 reslist = new ArrayList (1); 540 reslist.add(node); 541 return reslist; 548 case NodeKind.NODE : 549 if (reslist == null) 550 reslist = new ArrayList (1); 551 reslist.add(node); 552 return reslist; 553 } 554 break; 555 } 556 } 557 throw new MediatorException("getStep : could not handle step : " + step); 558 } 559 560 public static ArrayList getStep(ArrayList nodelist, Step step) throws MediatorException { 561 if (nodelist == null || nodelist.isEmpty()) 562 return null; 563 ArrayList reslist = new ArrayList (); 564 for (int i = 0; i < nodelist.size(); i++) { 565 TypedNode nodei = (TypedNode) nodelist.get(i); 566 ArrayList tmplist = DOMUtils.getStep(nodei, step); 567 if (tmplist != null) 568 reslist.addAll(tmplist); 569 } 570 if (reslist.isEmpty()) 571 reslist = null; 572 return reslist; 573 } 574 575 public static ArrayList getSteps(TypedNode node, XQueryExpression expr) throws MediatorException { 576 if (node == null) 577 return null; 578 if (expr instanceof Variable) { 579 ArrayList reslist = new ArrayList (1); 580 reslist.add(node); 581 return reslist; 582 } 583 if (!(expr instanceof LocatedExpression)) 584 return null; 585 ArrayList reslist = new ArrayList (1); 586 reslist.add(node); 587 ArrayList steps = ((LocatedExpression) expr).getSteps(); 588 for (int i = 1; i < steps.size(); i++) { 589 reslist = getStep(reslist, (Step) steps.get(i)); 590 if (reslist == null) 591 break; 592 } 593 if (reslist != null && reslist.isEmpty()) 594 reslist = null; 595 return reslist; 596 } 597 public static ArrayList getSteps(ArrayList nodelist, XQueryExpression expr) throws MediatorException { 598 if (nodelist == null || nodelist.isEmpty()) 599 return null; 600 if (expr instanceof Variable) 601 return nodelist; 602 if (!(expr instanceof LocatedExpression)) 603 return null; 604 ArrayList reslist = (ArrayList ) nodelist.clone(); 605 ArrayList steps = ((LocatedExpression) expr).getSteps(); 606 for (int i = 1; i < steps.size(); i++) { 607 reslist = getStep(reslist, (Step) steps.get(i)); 608 if (reslist == null) 609 break; 610 } 611 if (reslist != null && reslist.isEmpty()) 612 reslist = null; 613 return reslist; 614 } 615 616 public static boolean orderTuple(Tuple tuple1, Tuple tuple2, ArrayList orderbys) throws MediatorException { 618 for (int i = 0; i < orderbys.size(); i++) { 619 String stri = ((XQueryExpression) orderbys.get(i)).getStringValue(); int order = ((XQueryExpression) orderbys.get(i)).getOrder(0); 621 if (order == -1) 622 order = Constants.ASCENDING_ORDER; 623 ArrayList list1 = tuple1.getPath(stri); 624 ArrayList list2 = tuple2.getPath(stri); 625 if (list1 == null || list1.isEmpty()) { 626 if (list2 == null || list2.isEmpty()) 627 continue; 628 else { 629 if (list2.size() > 1) 630 throw new MediatorException("Could not compare more than one element!"); 631 if (order == Constants.DESCENDING_ORDER) 632 return false; 633 } 634 } else { 635 if (list1.size() > 1) 636 throw new MediatorException("Could not compare more than one element!"); 637 if (list2 == null || list2.isEmpty()) { 638 if (order == Constants.ASCENDING_ORDER) 639 return false; 640 } else { 641 if (list2.size() > 1) 642 throw new MediatorException("Could not compare more than one element!"); 643 int comp = fullCompareTree((TypedNode) list1.get(0), (TypedNode) list2.get(0), order); 644 if (comp == 0) 645 continue; 646 else if (comp > 0) { 647 if (order == Constants.ASCENDING_ORDER) 648 return false; 649 else 650 return true; 651 } else if (comp < 0) { 652 if (order == Constants.DESCENDING_ORDER) 653 return false; 654 else 655 return true; 656 } 657 } 658 } 659 } 660 return true; 661 } 662 663 private static int fullCompareTree(TypedNode node1, TypedNode node2, int order) throws MediatorException { 664 if (!node1.getNodeName().equals(node2.getNodeName())) 665 throw new MediatorException("Could not compare elements with different names!"); 666 Comparable value1 = (Comparable ) node1.getTypedValue(); 667 Comparable value2 = (Comparable ) node2.getTypedValue(); 668 if (value1 != null && value2 != null) 669 return compareObjects(value1, value2); 670 if (order != Constants.PLACE_ORDER) { 671 TypedNode tmpnode1 = node1; 672 TypedNode tmpnode2 = node2; 673 if (value1 == null) { 674 org.w3c.dom.NodeList nl = node1.getChildNodes(); 675 if (nl.getLength() != 1) 676 throw new MediatorException("Could not compare elements, at least one incorrect value"); 677 node1 = (TypedNode) nl.item(0); 678 } 679 if (value2 == null) { 680 org.w3c.dom.NodeList nl = node2.getChildNodes(); 681 if (nl.getLength() != 1) 682 throw new MediatorException("Could not compare elements, at least one incorrect value"); 683 node2 = (TypedNode) nl.item(0); 684 } 685 return fullCompareTree(node1, node2, order); 686 } else { if (compareTree(node1, node2)) 688 return 0; 689 else 690 return 1; 691 } 692 } 693 694 public static TypedNode makeTextNode(Value value, SchemaManager schemamanager) { 696 TypedNode text = (TypedNode) docimpl.createTextNode(value.getValue()); 697 if (value instanceof ValueInteger) { 698 text.setType(schemamanager.getIntegerType()); 699 text.setTypedValue(((ValueInteger) value).getIntValue()); 700 } else if (value instanceof ValueDecimal) { 701 text.setType(schemamanager.getDecimalType()); 702 text.setTypedValue(((ValueDecimal) value).getDecimalValue()); 703 } else if (value instanceof ValueFloat) { 704 text.setType(schemamanager.getFloatType()); 705 text.setTypedValue(((ValueFloat) value).getFloatValue()); 706 } else if (value instanceof ValueDouble) { 707 text.setType(schemamanager.getDoubleType()); 708 text.setTypedValue(((ValueDouble) value).getDoubleValue()); 709 } else if (value instanceof ValueString) { 710 text.setType(schemamanager.getStringType()); 711 text.setTypedValue(value.getValue()); 712 } 713 return text; 714 } 715 716 public static XQueryExpression getXQueryExpression(Object obj) throws TypeException, XQueryException { 717 718 if (obj instanceof Integer ) 719 return new ValueInteger(obj.toString(), null); 720 else if (obj instanceof Double ) 721 return new ValueDouble(obj.toString(), null); 722 else if (obj instanceof Float ) 723 return new ValueFloat(obj.toString(), null); 724 else if (obj instanceof BigDecimal ) 725 return new ValueDecimal(obj.toString(), null); 726 else if (obj instanceof String ) 727 return new ValueString(obj.toString(), null); 728 else if (obj instanceof Date ) { 729 ArrayList list = new ArrayList (1); 730 list.add(new ValueString(obj.toString(), null)); 731 return new FunctionDATETIME(list, null); 732 } 733 throw new XQueryException("Impossible to convert object : " + obj); 734 } 735 736 } 737 | Popular Tags |