1 16 19 package org.apache.xml.utils; 20 21 import java.util.Hashtable ; 22 import java.util.Vector ; 23 24 import javax.xml.parsers.DocumentBuilder ; 25 import javax.xml.parsers.DocumentBuilderFactory ; 26 import javax.xml.parsers.ParserConfigurationException ; 27 28 import org.apache.xml.dtm.ref.DTMNodeProxy; 29 import org.apache.xml.res.XMLErrorResources; 30 import org.apache.xml.res.XMLMessages; 31 32 import org.w3c.dom.Attr ; 33 import org.w3c.dom.DOMImplementation ; 34 import org.w3c.dom.Document ; 35 import org.w3c.dom.DocumentType ; 36 import org.w3c.dom.Element ; 37 import org.w3c.dom.Entity ; 38 import org.w3c.dom.NamedNodeMap ; 39 import org.w3c.dom.Node ; 40 import org.w3c.dom.Text ; 41 42 49 public class DOMHelper 50 { 51 52 73 public static Document createDocument() 74 { 75 76 try 77 { 78 79 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 82 83 dfactory.setNamespaceAware(true); 84 dfactory.setValidating(true); 85 86 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 87 Document outNode = docBuilder.newDocument(); 88 89 return outNode; 90 } 91 catch (ParserConfigurationException pce) 92 { 93 throw new RuntimeException ( 94 XMLMessages.createXMLMessage( 95 XMLErrorResources.ER_CREATEDOCUMENT_NOT_SUPPORTED, null)); 97 } 99 } 100 101 113 public boolean shouldStripSourceNode(Node textNode) 114 throws javax.xml.transform.TransformerException 115 { 116 117 return false; 119 } 120 121 146 public String getUniqueID(Node node) 147 { 148 return "N" + Integer.toHexString(node.hashCode()).toUpperCase(); 149 } 150 151 169 public static boolean isNodeAfter(Node node1, Node node2) 170 { 171 if (node1 == node2 || isNodeTheSame(node1, node2)) 172 return true; 173 174 boolean isNodeAfter = true; 176 177 Node parent1 = getParentOfNode(node1); 178 Node parent2 = getParentOfNode(node2); 179 180 if (parent1 == parent2 || isNodeTheSame(parent1, parent2)) { 183 if (null != parent1) 184 isNodeAfter = isNodeAfterSibling(parent1, node1, node2); 185 else 186 { 187 192 } 196 } 197 else 198 { 199 200 209 int nParents1 = 2, nParents2 = 2; 212 while (parent1 != null) 213 { 214 nParents1++; 215 216 parent1 = getParentOfNode(parent1); 217 } 218 219 while (parent2 != null) 220 { 221 nParents2++; 222 223 parent2 = getParentOfNode(parent2); 224 } 225 226 Node startNode1 = node1, startNode2 = node2; 229 230 if (nParents1 < nParents2) 233 { 234 int adjust = nParents2 - nParents1; 236 237 for (int i = 0; i < adjust; i++) 238 { 239 startNode2 = getParentOfNode(startNode2); 240 } 241 } 242 else if (nParents1 > nParents2) 243 { 244 int adjust = nParents1 - nParents2; 246 247 for (int i = 0; i < adjust; i++) 248 { 249 startNode1 = getParentOfNode(startNode1); 250 } 251 } 252 253 Node prevChild1 = null, prevChild2 = null; 255 while (null != startNode1) 257 { 258 if (startNode1 == startNode2 || isNodeTheSame(startNode1, startNode2)) { 260 if (null == prevChild1) { 262 263 isNodeAfter = (nParents1 < nParents2) ? true : false; 265 266 break; } 268 else 269 { 270 isNodeAfter = isNodeAfterSibling(startNode1, prevChild1, 272 prevChild2); 273 274 break; } 276 } 278 prevChild1 = startNode1; 280 startNode1 = getParentOfNode(startNode1); 281 prevChild2 = startNode2; 282 startNode2 = getParentOfNode(startNode2); 283 } } 286 289 294 return isNodeAfter; 295 } 297 304 public static boolean isNodeTheSame(Node node1, Node node2) 305 { 306 if (node1 instanceof DTMNodeProxy && node2 instanceof DTMNodeProxy) 307 return ((DTMNodeProxy)node1).equals((DTMNodeProxy)node2); 308 else 309 return (node1 == node2); 310 } 311 312 326 private static boolean isNodeAfterSibling(Node parent, Node child1, 327 Node child2) 328 { 329 330 boolean isNodeAfterSibling = false; 331 short child1type = child1.getNodeType(); 332 short child2type = child2.getNodeType(); 333 334 if ((Node.ATTRIBUTE_NODE != child1type) 335 && (Node.ATTRIBUTE_NODE == child2type)) 336 { 337 338 isNodeAfterSibling = false; 340 } 341 else if ((Node.ATTRIBUTE_NODE == child1type) 342 && (Node.ATTRIBUTE_NODE != child2type)) 343 { 344 345 isNodeAfterSibling = true; 347 } 348 else if (Node.ATTRIBUTE_NODE == child1type) 349 { 350 NamedNodeMap children = parent.getAttributes(); 351 int nNodes = children.getLength(); 352 boolean found1 = false, found2 = false; 353 354 for (int i = 0; i < nNodes; i++) 356 { 357 Node child = children.item(i); 358 359 if (child1 == child || isNodeTheSame(child1, child)) 360 { 361 if (found2) 362 { 363 isNodeAfterSibling = false; 364 365 break; 366 } 367 368 found1 = true; 369 } 370 else if (child2 == child || isNodeTheSame(child2, child)) 371 { 372 if (found1) 373 { 374 isNodeAfterSibling = true; 375 376 break; 377 } 378 379 found2 = true; 380 } 381 } 382 } 383 else 384 { 385 Node child = parent.getFirstChild(); 397 boolean found1 = false, found2 = false; 398 399 while (null != child) 400 { 401 402 if (child1 == child || isNodeTheSame(child1, child)) 404 { 405 if (found2) 406 { 407 isNodeAfterSibling = false; 408 409 break; 410 } 411 412 found1 = true; 413 } 414 else if (child2 == child || isNodeTheSame(child2, child)) 415 { 416 if (found1) 417 { 418 isNodeAfterSibling = true; 419 420 break; 421 } 422 423 found2 = true; 424 } 425 426 child = child.getNextSibling(); 427 } 428 } 429 430 return isNodeAfterSibling; 431 } 433 437 445 public short getLevel(Node n) 446 { 447 448 short level = 1; 449 450 while (null != (n = getParentOfNode(n))) 451 { 452 level++; 453 } 454 455 return level; 456 } 457 458 477 public String getNamespaceForPrefix(String prefix, Element namespaceContext) 478 { 479 480 int type; 481 Node parent = namespaceContext; 482 String namespace = null; 483 484 if (prefix.equals("xml")) 485 { 486 namespace = QName.S_XMLNAMESPACEURI; } 488 else if(prefix.equals("xmlns")) 489 { 490 namespace = "http://www.w3.org/2000/xmlns/"; 496 } 497 else 498 { 499 String declname=(prefix=="") 501 ? "xmlns" 502 : "xmlns:"+prefix; 503 504 while ((null != parent) && (null == namespace) 506 && (((type = parent.getNodeType()) == Node.ELEMENT_NODE) 507 || (type == Node.ENTITY_REFERENCE_NODE))) 508 { 509 if (type == Node.ELEMENT_NODE) 510 { 511 512 519 Attr attr=((Element )parent).getAttributeNode(declname); 521 if(attr!=null) 522 { 523 namespace = attr.getNodeValue(); 524 break; 525 } 526 } 527 528 parent = getParentOfNode(parent); 529 } 530 } 531 532 return namespace; 533 } 534 535 538 Hashtable m_NSInfos = new Hashtable (); 539 540 542 protected static final NSInfo m_NSInfoUnProcWithXMLNS = new NSInfo(false, 543 true); 544 545 547 protected static final NSInfo m_NSInfoUnProcWithoutXMLNS = new NSInfo(false, 548 false); 549 550 552 protected static final NSInfo m_NSInfoUnProcNoAncestorXMLNS = 553 new NSInfo(false, false, NSInfo.ANCESTORNOXMLNS); 554 555 557 protected static final NSInfo m_NSInfoNullWithXMLNS = new NSInfo(true, 558 true); 559 560 562 protected static final NSInfo m_NSInfoNullWithoutXMLNS = new NSInfo(true, 563 false); 564 565 567 protected static final NSInfo m_NSInfoNullNoAncestorXMLNS = 568 new NSInfo(true, false, NSInfo.ANCESTORNOXMLNS); 569 570 572 protected Vector m_candidateNoAncestorXMLNS = new Vector (); 573 574 586 public String getNamespaceOfNode(Node n) 587 { 588 589 String namespaceOfPrefix; 590 boolean hasProcessedNS; 591 NSInfo nsInfo; 592 short ntype = n.getNodeType(); 593 594 if (Node.ATTRIBUTE_NODE != ntype) 595 { 596 Object nsObj = m_NSInfos.get(n); 598 nsInfo = (nsObj == null) ? null : (NSInfo) nsObj; 599 hasProcessedNS = (nsInfo == null) ? false : nsInfo.m_hasProcessedNS; 600 } 601 else 602 { 603 hasProcessedNS = false; 604 nsInfo = null; 605 } 606 607 if (hasProcessedNS) 608 { 609 namespaceOfPrefix = nsInfo.m_namespace; 610 } 611 else 612 { 613 namespaceOfPrefix = null; 614 615 String nodeName = n.getNodeName(); 616 int indexOfNSSep = nodeName.indexOf(':'); 617 String prefix; 618 619 if (Node.ATTRIBUTE_NODE == ntype) 620 { 621 if (indexOfNSSep > 0) 622 { 623 prefix = nodeName.substring(0, indexOfNSSep); 624 } 625 else 626 { 627 628 return namespaceOfPrefix; 631 } 632 } 633 else 634 { 635 prefix = (indexOfNSSep >= 0) 636 ? nodeName.substring(0, indexOfNSSep) : ""; 637 } 638 639 boolean ancestorsHaveXMLNS = false; 640 boolean nHasXMLNS = false; 641 642 if (prefix.equals("xml")) 643 { 644 namespaceOfPrefix = QName.S_XMLNAMESPACEURI; 645 } 646 else 647 { 648 int parentType; 649 Node parent = n; 650 651 while ((null != parent) && (null == namespaceOfPrefix)) 652 { 653 if ((null != nsInfo) 654 && (nsInfo.m_ancestorHasXMLNSAttrs 655 == NSInfo.ANCESTORNOXMLNS)) 656 { 657 break; 658 } 659 660 parentType = parent.getNodeType(); 661 662 if ((null == nsInfo) || nsInfo.m_hasXMLNSAttrs) 663 { 664 boolean elementHasXMLNS = false; 665 666 if (parentType == Node.ELEMENT_NODE) 667 { 668 NamedNodeMap nnm = parent.getAttributes(); 669 670 for (int i = 0; i < nnm.getLength(); i++) 671 { 672 Node attr = nnm.item(i); 673 String aname = attr.getNodeName(); 674 675 if (aname.charAt(0) == 'x') 676 { 677 boolean isPrefix = aname.startsWith("xmlns:"); 678 679 if (aname.equals("xmlns") || isPrefix) 680 { 681 if (n == parent) 682 nHasXMLNS = true; 683 684 elementHasXMLNS = true; 685 ancestorsHaveXMLNS = true; 686 687 String p = isPrefix ? aname.substring(6) : ""; 688 689 if (p.equals(prefix)) 690 { 691 namespaceOfPrefix = attr.getNodeValue(); 692 693 break; 694 } 695 } 696 } 697 } 698 } 699 700 if ((Node.ATTRIBUTE_NODE != parentType) && (null == nsInfo) 701 && (n != parent)) 702 { 703 nsInfo = elementHasXMLNS 704 ? m_NSInfoUnProcWithXMLNS : m_NSInfoUnProcWithoutXMLNS; 705 706 m_NSInfos.put(parent, nsInfo); 707 } 708 } 709 710 if (Node.ATTRIBUTE_NODE == parentType) 711 { 712 parent = getParentOfNode(parent); 713 } 714 else 715 { 716 m_candidateNoAncestorXMLNS.addElement(parent); 717 m_candidateNoAncestorXMLNS.addElement(nsInfo); 718 719 parent = parent.getParentNode(); 720 } 721 722 if (null != parent) 723 { 724 Object nsObj = m_NSInfos.get(parent); 726 nsInfo = (nsObj == null) ? null : (NSInfo) nsObj; 727 } 728 } 729 730 int nCandidates = m_candidateNoAncestorXMLNS.size(); 731 732 if (nCandidates > 0) 733 { 734 if ((false == ancestorsHaveXMLNS) && (null == parent)) 735 { 736 for (int i = 0; i < nCandidates; i += 2) 737 { 738 Object candidateInfo = m_candidateNoAncestorXMLNS.elementAt(i 739 + 1); 740 741 if (candidateInfo == m_NSInfoUnProcWithoutXMLNS) 742 { 743 m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i), 744 m_NSInfoUnProcNoAncestorXMLNS); 745 } 746 else if (candidateInfo == m_NSInfoNullWithoutXMLNS) 747 { 748 m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i), 749 m_NSInfoNullNoAncestorXMLNS); 750 } 751 } 752 } 753 754 m_candidateNoAncestorXMLNS.removeAllElements(); 755 } 756 } 757 758 if (Node.ATTRIBUTE_NODE != ntype) 759 { 760 if (null == namespaceOfPrefix) 761 { 762 if (ancestorsHaveXMLNS) 763 { 764 if (nHasXMLNS) 765 m_NSInfos.put(n, m_NSInfoNullWithXMLNS); 766 else 767 m_NSInfos.put(n, m_NSInfoNullWithoutXMLNS); 768 } 769 else 770 { 771 m_NSInfos.put(n, m_NSInfoNullNoAncestorXMLNS); 772 } 773 } 774 else 775 { 776 m_NSInfos.put(n, new NSInfo(namespaceOfPrefix, nHasXMLNS)); 777 } 778 } 779 } 780 781 return namespaceOfPrefix; 782 } 783 784 793 public String getLocalNameOfNode(Node n) 794 { 795 796 String qname = n.getNodeName(); 797 int index = qname.indexOf(':'); 798 799 return (index < 0) ? qname : qname.substring(index + 1); 800 } 801 802 814 public String getExpandedElementName(Element elem) 815 { 816 817 String namespace = getNamespaceOfNode(elem); 818 819 return (null != namespace) 820 ? namespace + ":" + getLocalNameOfNode(elem) 821 : getLocalNameOfNode(elem); 822 } 823 824 836 public String getExpandedAttributeName(Attr attr) 837 { 838 839 String namespace = getNamespaceOfNode(attr); 840 841 return (null != namespace) 842 ? namespace + ":" + getLocalNameOfNode(attr) 843 : getLocalNameOfNode(attr); 844 } 845 846 850 865 public boolean isIgnorableWhitespace(Text node) 866 { 867 868 boolean isIgnorable = false; 870 return isIgnorable; 877 } 878 879 887 public Node getRoot(Node node) 888 { 889 890 Node root = null; 891 892 while (node != null) 893 { 894 root = node; 895 node = getParentOfNode(node); 896 } 897 898 return root; 899 } 900 901 919 public Node getRootNode(Node n) 920 { 921 int nt = n.getNodeType(); 922 return ( (Node.DOCUMENT_NODE == nt) || (Node.DOCUMENT_FRAGMENT_NODE == nt) ) 923 ? n : n.getOwnerDocument(); 924 } 925 926 936 public boolean isNamespaceNode(Node n) 937 { 938 939 if (Node.ATTRIBUTE_NODE == n.getNodeType()) 940 { 941 String attrName = n.getNodeName(); 942 943 return (attrName.startsWith("xmlns:") || attrName.equals("xmlns")); 944 } 945 946 return false; 947 } 948 949 975 public static Node getParentOfNode(Node node) throws RuntimeException 976 { 977 Node parent; 978 short nodeType = node.getNodeType(); 979 980 if (Node.ATTRIBUTE_NODE == nodeType) 981 { 982 Document doc = node.getOwnerDocument(); 983 990 991 DOMImplementation impl=doc.getImplementation(); 1001 if(impl!=null && impl.hasFeature("Core","2.0")) 1002 { 1003 parent=((Attr )node).getOwnerElement(); 1004 return parent; 1005 } 1006 1007 1009 Element rootElem = doc.getDocumentElement(); 1010 1011 if (null == rootElem) 1012 { 1013 throw new RuntimeException ( 1014 XMLMessages.createXMLMessage( 1015 XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT, 1016 null)); } 1018 1019 parent = locateAttrParent(rootElem, node); 1020 1021 } 1022 else 1023 { 1024 parent = node.getParentNode(); 1025 1026 } 1031 1032 return parent; 1033 } 1034 1035 1053 public Element getElementByID(String id, Document doc) 1054 { 1055 return null; 1056 } 1057 1058 1093 public String getUnparsedEntityURI(String name, Document doc) 1094 { 1095 1096 String url = ""; 1097 DocumentType doctype = doc.getDoctype(); 1098 1099 if (null != doctype) 1100 { 1101 NamedNodeMap entities = doctype.getEntities(); 1102 if(null == entities) 1103 return url; 1104 Entity entity = (Entity ) entities.getNamedItem(name); 1105 if(null == entity) 1106 return url; 1107 1108 String notationName = entity.getNotationName(); 1109 1110 if (null != notationName) { 1112 url = entity.getSystemId(); 1122 1123 if (null == url) 1124 { 1125 url = entity.getPublicId(); 1126 } 1127 else 1128 { 1129 } 1132 } 1133 } 1134 1135 return url; 1136 } 1137 1138 1159 private static Node locateAttrParent(Element elem, Node attr) 1160 { 1161 1162 Node parent = null; 1163 1164 Attr check=elem.getAttributeNode(attr.getNodeName()); 1170 if(check==attr) 1171 parent = elem; 1172 1173 if (null == parent) 1174 { 1175 for (Node node = elem.getFirstChild(); null != node; 1176 node = node.getNextSibling()) 1177 { 1178 if (Node.ELEMENT_NODE == node.getNodeType()) 1179 { 1180 parent = locateAttrParent((Element ) node, attr); 1181 1182 if (null != parent) 1183 break; 1184 } 1185 } 1186 } 1187 1188 return parent; 1189 } 1190 1191 1195 protected Document m_DOMFactory = null; 1196 1197 1205 public void setDOMFactory(Document domFactory) 1206 { 1207 this.m_DOMFactory = domFactory; 1208 } 1209 1210 1216 public Document getDOMFactory() 1217 { 1218 1219 if (null == this.m_DOMFactory) 1220 { 1221 this.m_DOMFactory = createDocument(); 1222 } 1223 1224 return this.m_DOMFactory; 1225 } 1226 1227 1238 public static String getNodeData(Node node) 1239 { 1240 1241 FastStringBuffer buf = StringBufferPool.get(); 1242 String s; 1243 1244 try 1245 { 1246 getNodeData(node, buf); 1247 1248 s = (buf.length() > 0) ? buf.toString() : ""; 1249 } 1250 finally 1251 { 1252 StringBufferPool.free(buf); 1253 } 1254 1255 return s; 1256 } 1257 1258 1275 public static void getNodeData(Node node, FastStringBuffer buf) 1276 { 1277 1278 switch (node.getNodeType()) 1279 { 1280 case Node.DOCUMENT_FRAGMENT_NODE : 1281 case Node.DOCUMENT_NODE : 1282 case Node.ELEMENT_NODE : 1283 { 1284 for (Node child = node.getFirstChild(); null != child; 1285 child = child.getNextSibling()) 1286 { 1287 getNodeData(child, buf); 1288 } 1289 } 1290 break; 1291 case Node.TEXT_NODE : 1292 case Node.CDATA_SECTION_NODE : 1293 buf.append(node.getNodeValue()); 1294 break; 1295 case Node.ATTRIBUTE_NODE : 1296 buf.append(node.getNodeValue()); 1297 break; 1298 case Node.PROCESSING_INSTRUCTION_NODE : 1299 break; 1301 default : 1302 break; 1304 } 1305 } 1306} 1307 | Popular Tags |