1 16 package org.apache.cocoon.xml.dom; 17 18 import java.io.IOException ; 19 import java.io.Reader ; 20 import java.io.StringReader ; 21 import java.io.StringWriter ; 22 import java.io.Writer ; 23 import java.util.Collection ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import java.util.Properties ; 27 28 import javax.xml.parsers.DocumentBuilder ; 29 import javax.xml.parsers.DocumentBuilderFactory ; 30 import javax.xml.parsers.ParserConfigurationException ; 31 import javax.xml.transform.OutputKeys ; 32 import javax.xml.transform.TransformerException ; 33 34 import org.apache.cocoon.ProcessingException; 35 import org.apache.cocoon.xml.IncludeXMLConsumer; 36 import org.apache.cocoon.xml.XMLUtils; 37 import org.apache.commons.lang.BooleanUtils; 38 import org.apache.commons.lang.StringUtils; 39 import org.apache.excalibur.source.SourceParameters; 40 import org.apache.excalibur.xml.sax.SAXParser; 41 import org.apache.excalibur.xml.sax.XMLizable; 42 import org.apache.excalibur.xml.xpath.NodeListImpl; 43 import org.apache.excalibur.xml.xpath.XPathProcessor; 44 import org.apache.excalibur.xml.xpath.XPathUtil; 45 import org.apache.xpath.XPathAPI; 46 import org.w3c.dom.DOMException ; 47 import org.w3c.dom.Document ; 48 import org.w3c.dom.DocumentFragment ; 49 import org.w3c.dom.Element ; 50 import org.w3c.dom.NamedNodeMap ; 51 import org.w3c.dom.Node ; 52 import org.w3c.dom.NodeList ; 53 import org.xml.sax.InputSource ; 54 import org.xml.sax.SAXException ; 55 import org.xml.sax.helpers.AttributesImpl ; 56 57 64 public final class DOMUtil { 65 66 73 public static Document getOwnerDocument(Node node) { 74 if (node.getNodeType() == Node.DOCUMENT_NODE) { 75 return (Document ) node; 76 } else { 77 return node.getOwnerDocument(); 78 } 79 } 80 81 90 public static String getValueOfNode(XPathProcessor processor, Node root, String path) 91 throws ProcessingException { 92 if (path == null) { 93 throw new ProcessingException("Not a valid XPath: " + path); 94 } 95 if (root != null) { 96 path = StringUtils.strip(path, "/"); 97 Node node = XPathUtil.searchSingleNode(processor, root, path); 98 if (node != null) { 99 return getValueOfNode(node); 100 } 101 } 102 return null; 103 } 104 105 115 public static String getValueOfNode( 116 XPathProcessor processor, 117 Node root, 118 String path, 119 String defaultValue) 120 throws ProcessingException { 121 String value = getValueOfNode(processor, root, path); 122 if (value == null) 123 value = defaultValue; 124 125 return value; 126 } 127 128 139 public static boolean getValueOfNodeAsBoolean(XPathProcessor processor, Node root, String path) 140 throws ProcessingException { 141 String value = getValueOfNode(processor, root, path); 142 if (value == null) { 143 throw new ProcessingException("No such node: " + path); 144 } 145 return Boolean.valueOf(value).booleanValue(); 146 } 147 148 160 public static boolean getValueOfNodeAsBoolean(XPathProcessor processor, 161 Node root, 162 String path, 163 boolean defaultValue) 164 throws ProcessingException { 165 String value = getValueOfNode(processor, root, path); 166 if (value != null) { 167 return BooleanUtils.toBoolean(value); 168 } 169 return defaultValue; 170 } 171 172 177 public static String getValueOfNode(Node node) { 178 if (node != null) { 179 if (node.getNodeType() == Node.ATTRIBUTE_NODE) { 180 return node.getNodeValue(); 181 } else { 182 node.normalize(); 183 NodeList childs = node.getChildNodes(); 184 int i = 0; 185 int length = childs.getLength(); 186 while (i < length) { 187 if (childs.item(i).getNodeType() == Node.TEXT_NODE) { 188 return childs.item(i).getNodeValue().trim(); 189 } else { 190 i++; 191 } 192 } 193 } 194 } 195 return null; 196 } 197 198 204 public static String getValueOfNode(Node node, String defaultValue) { 205 return StringUtils.defaultString(getValueOfNode(node), defaultValue); 206 } 207 208 213 public static void setValueOfNode(Node node, String value) { 214 if (node.getNodeType() == Node.ATTRIBUTE_NODE) { 215 node.setNodeValue(value); 216 } else { 217 while (node.hasChildNodes() == true) { 218 node.removeChild(node.getFirstChild()); 219 } 220 node.appendChild(node.getOwnerDocument().createTextNode(value)); 221 } 222 } 223 224 225 private static final String XML_DEFINITION = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"; 226 private static final String XML_ROOT_DEFINITION = XML_DEFINITION + "<root>"; 227 228 234 public static DocumentFragment getDocumentFragment(SAXParser parser, Reader stream) 235 throws ProcessingException { 236 DocumentFragment frag = null; 237 238 Writer writer; 239 Reader reader; 240 boolean removeRoot = true; 241 242 try { 243 writer = new StringWriter (); 247 248 writer.write(XML_ROOT_DEFINITION); 249 char[] cbuf = new char[16384]; 250 int len; 251 do { 252 len = stream.read(cbuf, 0, 16384); 253 if (len != -1) { 254 writer.write(cbuf, 0, len); 255 } 256 } while (len != -1); 257 writer.write("</root>"); 258 259 String xml = writer.toString(); 261 String searchString = XML_ROOT_DEFINITION + "<?xml "; 262 if (xml.startsWith(searchString) == true) { 263 xml = xml.substring(XML_ROOT_DEFINITION.length(), xml.length() - 7); 265 removeRoot = false; 266 } 267 268 reader = new StringReader (xml); 269 270 InputSource input = new InputSource (reader); 271 272 DOMBuilder builder = new DOMBuilder(); 273 builder.startDocument(); 274 builder.startElement("", "root", "root", new AttributesImpl ()); 275 276 IncludeXMLConsumer filter = new IncludeXMLConsumer(builder, builder); 277 parser.parse(input, filter); 278 279 builder.endElement("", "root", "root"); 280 builder.endDocument(); 281 282 final Document doc = builder.getDocument(); 284 frag = doc.createDocumentFragment(); 285 final Node root = doc.getDocumentElement().getFirstChild(); 286 root.normalize(); 287 if (removeRoot == false) { 288 root.getParentNode().removeChild(root); 289 frag.appendChild(root); 290 } else { 291 Node child; 292 while (root.hasChildNodes() == true) { 293 child = root.getFirstChild(); 294 root.removeChild(child); 295 frag.appendChild(child); 296 } 297 } 298 } catch (SAXException sax) { 299 throw new ProcessingException("SAXException: " + sax, sax); 300 } catch (IOException ioe) { 301 throw new ProcessingException("IOException: " + ioe, ioe); 302 } 303 return frag; 304 } 305 306 315 public static SourceParameters createParameters(Node fragment, SourceParameters source) { 316 SourceParameters par = (source == null ? new SourceParameters() : source); 317 if (fragment != null) { 318 NodeList childs = fragment.getChildNodes(); 319 if (childs != null) { 320 Node current; 321 for (int i = 0; i < childs.getLength(); i++) { 322 current = childs.item(i); 323 324 if (current.getNodeType() == Node.ELEMENT_NODE) { 326 current.normalize(); 327 NodeList valueChilds = current.getChildNodes(); 328 String key; 329 StringBuffer valueBuffer; 330 String value; 331 332 key = current.getNodeName(); 333 valueBuffer = new StringBuffer (); 334 for (int m = 0; m < valueChilds.getLength(); m++) { 335 current = valueChilds.item(m); if (current.getNodeType() == Node.TEXT_NODE) { if (valueBuffer.length() > 0) 338 valueBuffer.append(' '); 339 valueBuffer.append(current.getNodeValue()); 340 } 341 } 342 value = valueBuffer.toString().trim(); 343 if (key != null && value != null && value.length() > 0) { 344 par.setParameter(key, value); 345 } 346 } 347 } 348 } 349 } 350 return par; 351 } 352 353 357 public static String createText(DocumentFragment fragment) { 358 StringBuffer value = new StringBuffer (); 359 if (fragment != null) { 360 NodeList childs = fragment.getChildNodes(); 361 if (childs != null) { 362 Node current; 363 364 for (int i = 0; i < childs.getLength(); i++) { 365 current = childs.item(i); 366 367 if (current.getNodeType() == Node.TEXT_NODE) { 369 if (value.length() > 0) 370 value.append(' '); 371 value.append(current.getNodeValue()); 372 } 373 } 374 } 375 } 376 return value.toString().trim(); 377 } 378 379 385 public static boolean compareAttributes(Element first, Element second) { 386 NamedNodeMap attr1 = first.getAttributes(); 387 NamedNodeMap attr2 = second.getAttributes(); 388 String value; 389 390 if (attr1 == null && attr2 == null) 391 return true; 392 int attr1Len = (attr1 == null ? 0 : attr1.getLength()); 393 int attr2Len = (attr2 == null ? 0 : attr2.getLength()); 394 if (attr1Len > 0) { 395 int l = attr1.getLength(); 396 for (int i = 0; i < l; i++) { 397 if (attr1.item(i).getNodeName().startsWith("xmlns:") == true) 398 attr1Len--; 399 } 400 } 401 if (attr2Len > 0) { 402 int l = attr2.getLength(); 403 for (int i = 0; i < l; i++) { 404 if (attr2.item(i).getNodeName().startsWith("xmlns:") == true) 405 attr2Len--; 406 } 407 } 408 if (attr1Len != attr2Len) 409 return false; 410 int i, l; 411 int m, l2; 412 i = 0; 413 l = attr1.getLength(); 414 l2 = attr2.getLength(); 415 boolean ok = true; 416 while (i < l && ok == true) { 418 value = attr1.item(i).getNodeName(); 419 if (value.startsWith("xmlns:") == false) { 420 ok = false; 421 m = 0; 422 while (m < l2 && ok == false) { 423 if (attr2.item(m).getNodeName().equals(value) == true) { 424 ok = attr1.item(i).getNodeValue().equals(attr2.item(m).getNodeValue()); 426 } 427 m++; 428 } 429 } 430 431 i++; 432 } 433 return ok; 434 } 435 436 443 public static void valueOf(Node parent, String text) throws ProcessingException { 444 if (text != null) { 445 parent.appendChild(parent.getOwnerDocument().createTextNode(text)); 446 } 447 } 448 449 456 public static void valueOf(Node parent, XMLizable v) throws ProcessingException { 457 if (v != null) { 458 DOMBuilder builder = new DOMBuilder(parent); 459 try { 460 v.toSAX(builder); 461 } catch (SAXException e) { 462 throw new ProcessingException(e); 463 } 464 } 465 } 466 467 474 public static void valueOf(Node parent, Node v) throws ProcessingException { 475 if (v != null) { 476 parent.appendChild(parent.getOwnerDocument().importNode(v, true)); 477 } 478 } 479 480 488 public static void valueOf(Node parent, Collection v) throws ProcessingException { 489 if (v != null) { 490 Iterator iterator = v.iterator(); 491 while (iterator.hasNext()) { 492 valueOf(parent, iterator.next()); 493 } 494 } 495 } 496 497 506 public static void valueOf(Node parent, Map v) throws ProcessingException { 507 if (v != null) { 508 Node mapNode = parent.getOwnerDocument().createElementNS(null, "java.util.map"); 509 parent.appendChild(mapNode); 510 for (Iterator iter = v.entrySet().iterator(); iter.hasNext(); ) { 511 Map.Entry me = (Map.Entry )iter.next(); 512 513 Node entryNode = mapNode.getOwnerDocument().createElementNS(null, "entry"); 514 mapNode.appendChild(entryNode); 515 516 Node keyNode = entryNode.getOwnerDocument().createElementNS(null, "key"); 517 entryNode.appendChild(keyNode); 518 valueOf(keyNode, me.getKey()); 519 520 Node valueNode = entryNode.getOwnerDocument().createElementNS(null, "value"); 521 entryNode.appendChild(valueNode); 522 valueOf(valueNode, me.getValue()); 523 } 524 } 525 } 526 527 538 public static void valueOf(Node parent, Object v) throws ProcessingException { 539 if (v == null) { 540 return; 541 } 542 543 if (v.getClass().isArray()) { 545 Object [] elements = (Object []) v; 546 547 for (int i = 0; i < elements.length; i++) { 548 valueOf(parent, elements[i]); 549 } 550 return; 551 } 552 553 555 if (v instanceof XMLizable) { 557 valueOf(parent, (XMLizable) v); 558 return; 559 } 560 561 if (v instanceof Node ) { 563 valueOf(parent, (Node ) v); 564 return; 565 } 566 567 if (v instanceof Collection ) { 569 valueOf(parent, (Collection ) v); 570 return; 571 } 572 573 if (v instanceof Map ) { 575 valueOf(parent, (Map ) v); 576 return; 577 } 578 579 valueOf(parent, String.valueOf(v)); 581 } 582 583 595 public static Node getSingleNode(Node contextNode, String str, 596 XPathProcessor processor) 597 throws TransformerException { 598 String [] pathComponents = buildPathArray(str); 599 if (pathComponents == null) { 600 return processor.selectSingleNode(contextNode, str); 601 } else { 602 return getFirstNodeFromPath(contextNode, pathComponents, false); 603 } 604 } 605 606 618 public static Node getSingleNode(Node contextNode, String str) throws TransformerException { 619 String [] pathComponents = buildPathArray(str); 620 if (pathComponents == null) { 621 return XPathAPI.selectSingleNode(contextNode, str); 622 } else { 623 return getFirstNodeFromPath(contextNode, pathComponents, false); 624 } 625 } 626 627 651 public static Node selectSingleNode(Node rootNode, String path) throws ProcessingException { 652 if (path == null) { 655 throw new ProcessingException("XPath is required."); 656 } 657 if (rootNode == null) 658 return rootNode; 659 660 if (path.length() == 0 || path.equals("/") == true) 661 return rootNode; 662 663 try { 666 Node testNode = getSingleNode(rootNode, path); 667 if (testNode != null) 668 return testNode; 669 } catch (javax.xml.transform.TransformerException local) { 670 throw new ProcessingException( 671 "Transforming exception during selectSingleNode with path: '" 672 + path 673 + "'. Exception: " 674 + local, 675 local); 676 } 677 path = StringUtils.strip(path, "/"); 679 680 Node parent = rootNode; 682 int pos; 683 int posSelector; 684 do { 685 pos = path.indexOf("/"); posSelector = path.indexOf("["); 687 if (posSelector != -1 && posSelector < pos) { 688 posSelector = path.indexOf("]"); 689 pos = path.indexOf("/", posSelector); 690 } 691 692 String nodeName; 693 boolean isAttribute = false; 694 if (pos != -1) { nodeName = path.substring(0, pos); path = path.substring(pos + 1); } else { 698 nodeName = path; 699 } 700 701 if (nodeName.startsWith("@") == true) { 703 isAttribute = true; 704 } 705 706 Node singleNode; 707 try { 708 singleNode = getSingleNode(parent, nodeName); 709 } catch (javax.xml.transform.TransformerException localException) { 710 throw new ProcessingException( 711 "XPathUtil.selectSingleNode: " + localException.getMessage(), 712 localException); 713 } 714 715 if (singleNode == null) { 717 Node newNode; 718 int posSelect = nodeName.indexOf("["); 720 String XPathExp = null; 721 if (posSelect != -1) { 722 XPathExp = nodeName.substring(posSelect + 1, nodeName.length() - 1); 723 nodeName = nodeName.substring(0, posSelect); 724 } 725 if (isAttribute == true) { 726 try { 727 newNode = 728 getOwnerDocument(rootNode).createAttributeNS( 729 null, 730 nodeName.substring(1)); 731 ((Element ) parent).setAttributeNodeNS((org.w3c.dom.Attr ) newNode); 732 parent = newNode; 733 } catch (DOMException local) { 734 throw new ProcessingException( 735 "Unable to create new DOM node: '" + nodeName + "'.", 736 local); 737 } 738 } else { 739 try { 740 newNode = getOwnerDocument(rootNode).createElementNS(null, nodeName); 741 } catch (DOMException local) { 742 throw new ProcessingException( 743 "Unable to create new DOM node: '" + nodeName + "'.", 744 local); 745 } 746 if (XPathExp != null) { 747 java.util.List attrValuePairs = new java.util.ArrayList (4); 748 boolean noError = true; 749 750 String attr; 751 String value; 752 java.util.StringTokenizer tokenizer = 754 new java.util.StringTokenizer (XPathExp, "= "); 755 while (tokenizer.hasMoreTokens() == true) { 756 attr = tokenizer.nextToken(); 757 if (attr.startsWith("@") == true) { 758 if (tokenizer.hasMoreTokens() == true) { 759 value = tokenizer.nextToken(); 760 if (value.startsWith("'") && value.endsWith("'")) 761 value = value.substring(1, value.length() - 1); 762 if (value.startsWith("\"") && value.endsWith("\"")) 763 value = value.substring(1, value.length() - 1); 764 attrValuePairs.add(attr.substring(1)); 765 attrValuePairs.add(value); 766 } else { 767 noError = false; 768 } 769 } else if (attr.trim().equals("and") == false) { 770 noError = false; 771 } 772 } 773 if (noError == true) { 774 for (int l = 0; l < attrValuePairs.size(); l = l + 2) { 775 ((Element ) newNode).setAttributeNS( 776 null, 777 (String ) attrValuePairs.get(l), 778 (String ) attrValuePairs.get(l + 1)); 779 } 780 } 781 } 782 parent.appendChild(newNode); 783 parent = newNode; 784 } 785 } else { 786 parent = singleNode; 787 } 788 } 789 while (pos != -1); 790 return parent; 791 } 792 793 817 public static Node selectSingleNode(Node rootNode, String path, XPathProcessor processor) 818 throws ProcessingException { 819 if (path == null) { 822 throw new ProcessingException("XPath is required."); 823 } 824 if (rootNode == null) 825 return rootNode; 826 827 if (path.length() == 0 || path.equals("/") == true) 828 return rootNode; 829 830 try { 833 Node testNode = getSingleNode(rootNode, path, processor); 834 if (testNode != null) 835 return testNode; 836 } catch (javax.xml.transform.TransformerException local) { 837 throw new ProcessingException( 838 "Transforming exception during selectSingleNode with path: '" 839 + path 840 + "'. Exception: " 841 + local, 842 local); 843 } 844 845 path = StringUtils.strip(path, "/"); 847 848 Node parent = rootNode; 850 int pos; 851 int posSelector; 852 do { 853 pos = path.indexOf("/"); posSelector = path.indexOf("["); 855 if (posSelector != -1 && posSelector < pos) { 856 posSelector = path.indexOf("]"); 857 pos = path.indexOf("/", posSelector); 858 } 859 860 String nodeName; 861 boolean isAttribute = false; 862 if (pos != -1) { nodeName = path.substring(0, pos); path = path.substring(pos + 1); } else { 866 nodeName = path; 867 } 868 869 if (nodeName.startsWith("@") == true) { 871 isAttribute = true; 872 } 873 874 Node singleNode; 875 try { 876 singleNode = getSingleNode(parent, nodeName, processor); 877 } catch (javax.xml.transform.TransformerException localException) { 878 throw new ProcessingException( 879 "XPathUtil.selectSingleNode: " + localException.getMessage(), 880 localException); 881 } 882 883 if (singleNode == null) { 885 Node newNode; 886 int posSelect = nodeName.indexOf("["); 888 String XPathExp = null; 889 if (posSelect != -1) { 890 XPathExp = nodeName.substring(posSelect + 1, nodeName.length() - 1); 891 nodeName = nodeName.substring(0, posSelect); 892 } 893 if (isAttribute == true) { 894 try { 895 newNode = 896 getOwnerDocument(rootNode).createAttributeNS( 897 null, 898 nodeName.substring(1)); 899 ((Element ) parent).setAttributeNodeNS((org.w3c.dom.Attr ) newNode); 900 parent = newNode; 901 } catch (DOMException local) { 902 throw new ProcessingException( 903 "Unable to create new DOM node: '" + nodeName + "'.", 904 local); 905 } 906 } else { 907 try { 908 newNode = getOwnerDocument(rootNode).createElementNS(null, nodeName); 909 } catch (DOMException local) { 910 throw new ProcessingException( 911 "Unable to create new DOM node: '" + nodeName + "'.", 912 local); 913 } 914 if (XPathExp != null) { 915 java.util.List attrValuePairs = new java.util.ArrayList (4); 916 boolean noError = true; 917 918 String attr; 919 String value; 920 java.util.StringTokenizer tokenizer = 922 new java.util.StringTokenizer (XPathExp, "= "); 923 while (tokenizer.hasMoreTokens() == true) { 924 attr = tokenizer.nextToken(); 925 if (attr.startsWith("@") == true) { 926 if (tokenizer.hasMoreTokens() == true) { 927 value = tokenizer.nextToken(); 928 if (value.startsWith("'") && value.endsWith("'")) 929 value = value.substring(1, value.length() - 1); 930 if (value.startsWith("\"") && value.endsWith("\"")) 931 value = value.substring(1, value.length() - 1); 932 attrValuePairs.add(attr.substring(1)); 933 attrValuePairs.add(value); 934 } else { 935 noError = false; 936 } 937 } else if (attr.trim().equals("and") == false) { 938 noError = false; 939 } 940 } 941 if (noError == true) { 942 for (int l = 0; l < attrValuePairs.size(); l = l + 2) { 943 ((Element ) newNode).setAttributeNS( 944 null, 945 (String ) attrValuePairs.get(l), 946 (String ) attrValuePairs.get(l + 1)); 947 } 948 } 949 } 950 parent.appendChild(newNode); 951 parent = newNode; 952 } 953 } else { 954 parent = singleNode; 955 } 956 } 957 while (pos != -1); 958 return parent; 959 } 960 961 971 public static String getValueOf(Node root, String path) throws ProcessingException { 972 if (path == null) { 973 throw new ProcessingException("Not a valid XPath: " + path); 974 } 975 if (root == null) 976 return null; 977 path = StringUtils.strip(path, "/"); 978 979 try { 980 Node node = getSingleNode(root, path); 981 if (node != null) { 982 return getValueOfNode(node); 983 } 984 } catch (javax.xml.transform.TransformerException localException) { 985 throw new ProcessingException( 986 "XPathUtil.selectSingleNode: " + localException.getMessage(), 987 localException); 988 } 989 return null; 990 } 991 992 1002 public static String getValueOf(Node root, String path, 1003 XPathProcessor processor) throws ProcessingException { 1004 if (path == null) { 1005 throw new ProcessingException("Not a valid XPath: " + path); 1006 } 1007 if (root == null) 1008 return null; 1009 path = StringUtils.strip(path, "/"); 1010 1011 try { 1012 Node node = getSingleNode(root, path, processor); 1013 if (node != null) { 1014 return getValueOfNode(node); 1015 } 1016 } catch (javax.xml.transform.TransformerException localException) { 1017 throw new ProcessingException( 1018 "XPathUtil.selectSingleNode: " + localException.getMessage(), 1019 localException); 1020 } 1021 return null; 1022 } 1023 1024 1035 public static String getValueOf(Node root, String path, String defaultValue) 1036 throws ProcessingException { 1037 String value = getValueOf(root, path); 1038 if (value == null) { 1039 value = defaultValue; 1040 } 1041 return value; 1042 } 1043 1044 1055 public static String getValueOf(Node root, String path, String defaultValue, 1056 XPathProcessor processor) 1057 throws ProcessingException { 1058 String value = getValueOf(root, path, processor); 1059 if (value == null) { 1060 value = defaultValue; 1061 } 1062 return value; 1063 } 1064 1065 1077 public static boolean getValueAsBooleanOf(Node root, String path) throws ProcessingException { 1078 String value = getValueOf(root, path); 1079 if (value != null) { 1080 return Boolean.valueOf(value).booleanValue(); 1081 } else { 1082 throw new ProcessingException("No such node: " + path); 1083 } 1084 } 1085 1086 1098 public static boolean getValueAsBooleanOf(Node root, String path, 1099 XPathProcessor processor) 1100 throws ProcessingException { 1101 String value = getValueOf(root, path, processor); 1102 if (value == null) { 1103 throw new ProcessingException("No such node: " + path); 1104 } 1105 return Boolean.valueOf(value).booleanValue(); 1106 } 1107 1108 1121 public static boolean getValueAsBooleanOf(Node root, String path, boolean defaultValue) 1122 throws ProcessingException { 1123 String value = getValueOf(root, path); 1124 if (value != null) { 1125 return Boolean.valueOf(value).booleanValue(); 1126 } 1127 return defaultValue; 1128 } 1129 1130 1143 public static boolean getValueAsBooleanOf(Node root, String path, boolean defaultValue, 1144 XPathProcessor processor) 1145 throws ProcessingException { 1146 String value = getValueOf(root, path, processor); 1147 if (value != null) { 1148 return Boolean.valueOf(value).booleanValue(); 1149 } 1150 return defaultValue; 1151 } 1152 1153 1156 public static Document createDocument() throws ProcessingException { 1157 try { 1158 DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); 1159 documentFactory.setNamespaceAware(true); 1160 documentFactory.setValidating(false); 1161 DocumentBuilder docBuilder = documentFactory.newDocumentBuilder(); 1162 return docBuilder.newDocument(); 1163 } catch (ParserConfigurationException pce) { 1164 throw new ProcessingException("Creating document failed.", pce); 1165 } 1166 } 1167 1168 1179 public static NodeList selectNodeList(Node contextNode, String str) 1180 throws TransformerException { 1181 String [] pathComponents = buildPathArray(str); 1182 if (pathComponents != null) { 1183 return getNodeListFromPath(contextNode, pathComponents); 1184 } 1185 return XPathAPI.selectNodeList(contextNode, str); 1186 } 1187 1188 1199 public static NodeList selectNodeList(Node contextNode, String str, XPathProcessor processor) 1200 throws TransformerException { 1201 String [] pathComponents = buildPathArray(str); 1202 if (pathComponents != null) { 1203 return getNodeListFromPath(contextNode, pathComponents); 1204 } 1205 return processor.selectNodeList(contextNode, str); 1206 } 1207 1208 1213 public static String [] buildPathArray(String xpath) { 1214 String [] result = null; 1215 if (xpath != null && xpath.charAt(0) != '/') { 1216 int components = 1; 1218 int i, l; 1219 l = xpath.length(); 1220 boolean found = false; 1221 i = 0; 1222 while (i < l && found == false) { 1223 switch (xpath.charAt(i)) { 1224 case '[' : 1225 found = true; 1226 break; 1227 case '(' : 1228 found = true; 1229 break; 1230 case '*' : 1231 found = true; 1232 break; 1233 case '@' : 1234 found = true; 1235 break; 1236 case ':' : 1237 found = true; 1238 break; 1239 case '/' : 1240 components++; 1241 default : 1242 i++; 1243 } 1244 } 1245 if (found == false) { 1246 result = new String [components]; 1247 if (components == 1) { 1248 result[components - 1] = xpath; 1249 } else { 1250 i = 0; 1251 int start = 0; 1252 components = 0; 1253 while (i < l) { 1254 if (xpath.charAt(i) == '/') { 1255 result[components] = xpath.substring(start, i); 1256 start = i + 1; 1257 components++; 1258 } 1259 i++; 1260 } 1261 result[components] = xpath.substring(start); 1262 } 1263 } 1264 } 1265 return result; 1266 } 1267 1268 1278 public static Node getFirstNodeFromPath( 1279 Node contextNode, 1280 final String [] path, 1281 final boolean create) { 1282 if (contextNode == null || path == null || path.length == 0) 1283 return contextNode; 1284 Node item = getFirstNodeFromPath(contextNode, path, 0); 1286 if (item == null && create == true) { 1287 int i = 0; 1288 NodeList childs; 1289 boolean found; 1290 int m, l; 1291 while (contextNode != null && i < path.length) { 1292 childs = contextNode.getChildNodes(); 1293 found = false; 1294 if (childs != null) { 1295 m = 0; 1296 l = childs.getLength(); 1297 while (found == false && m < l) { 1298 item = childs.item(m); 1299 if (item.getNodeType() == Node.ELEMENT_NODE 1300 && item.getLocalName().equals(path[i]) == true) { 1301 found = true; 1302 contextNode = item; 1303 } 1304 m++; 1305 } 1306 } 1307 if (found == false) { 1308 Element e = contextNode.getOwnerDocument().createElementNS(null, path[i]); 1309 contextNode.appendChild(e); 1310 contextNode = e; 1311 } 1312 i++; 1313 } 1314 item = contextNode; 1315 } 1316 return item; 1317 } 1318 1319 1322 private static Node getFirstNodeFromPath( 1323 final Node contextNode, 1324 final String [] path, 1325 final int startIndex) { 1326 int i = 0; 1327 NodeList childs; 1328 boolean found; 1329 int l; 1330 Node item = null; 1331 1332 childs = contextNode.getChildNodes(); 1333 found = false; 1334 if (childs != null) { 1335 i = 0; 1336 l = childs.getLength(); 1337 while (found == false && i < l) { 1338 item = childs.item(i); 1339 if (item.getNodeType() == Node.ELEMENT_NODE 1340 && path[startIndex].equals( 1341 item.getLocalName() != null ? item.getLocalName() : item.getNodeName()) 1342 == true) { 1343 if (startIndex == path.length - 1) { 1344 found = true; 1345 } else { 1346 item = getFirstNodeFromPath(item, path, startIndex + 1); 1347 if (item != null) 1348 found = true; 1349 } 1350 } 1351 if (found == false) { 1352 i++; 1353 } 1354 } 1355 if (found == false) { 1356 item = null; 1357 } 1358 } 1359 return item; 1360 } 1361 1362 1370 public static NodeList getNodeListFromPath(Node contextNode, String [] path) { 1371 if (contextNode == null) 1372 return new NodeListImpl(); 1373 if (path == null || path.length == 0) { 1374 return new NodeListImpl(new Node [] { contextNode }); 1375 } 1376 NodeListImpl result = new NodeListImpl(); 1377 try { 1378 getNodesFromPath(result, contextNode, path, 0); 1379 } catch (NullPointerException npe) { 1380 throw new NullPointerException ( 1383 "XMLUtil.getNodeListFromPath() did catch a NullPointerException." 1384 + "This might be due to a missconfigured XML parser which does not use DOM Level 2." 1385 + "Make sure that you use the XML parser shipped with Cocoon."); 1386 } 1387 return result; 1388 } 1389 1390 1393 private static void getNodesFromPath( 1394 final NodeListImpl result, 1395 final Node contextNode, 1396 final String [] path, 1397 final int startIndex) { 1398 final NodeList childs = contextNode.getChildNodes(); 1399 int m, l; 1400 Node item; 1401 if (startIndex == (path.length - 1)) { 1402 if (childs != null) { 1403 m = 0; 1404 l = childs.getLength(); 1405 while (m < l) { 1406 item = childs.item(m); 1407 if (item.getNodeType() == Node.ELEMENT_NODE) { 1408 if (path[startIndex] 1410 .equals( 1411 item.getLocalName() != null 1412 ? item.getLocalName() 1413 : item.getNodeName()) 1414 == true) { 1415 result.addNode(item); 1416 } 1417 } 1418 m++; 1419 } 1420 } 1421 } else { 1422 if (childs != null) { 1423 m = 0; 1424 l = childs.getLength(); 1425 while (m < l) { 1426 item = childs.item(m); 1427 if (item.getNodeType() == Node.ELEMENT_NODE) { 1428 if (path[startIndex] 1430 .equals( 1431 item.getLocalName() != null 1432 ? item.getLocalName() 1433 : item.getNodeName()) 1434 == true) { 1435 getNodesFromPath(result, item, path, startIndex + 1); 1436 } 1437 } 1438 m++; 1439 } 1440 } 1441 } 1442 } 1443 1444 1452 public static String node2String(Node node) { 1453 try { 1454 return XMLUtils.serializeNodeToXML(node); 1455 } catch (ProcessingException e) { 1456 } 1458 return ""; 1459 } 1460 1461 1469 public static String node2String(Node node, boolean pretty) { 1470 try { 1471 if (pretty) { 1472 Properties props = new Properties (); 1473 props.setProperty(OutputKeys.INDENT, "yes"); 1474 return XMLUtils.serializeNode(node, props); 1475 } else { 1476 return XMLUtils.serializeNodeToXML(node); 1477 } 1478 } catch (ProcessingException e) { 1479 } 1480 return ""; 1481 } 1482 1483 1490 public static StringBuffer node2StringBuffer(Node node) { 1491 return new StringBuffer (node2String(node)); 1492 } 1493 1494 1504 public static StringBuffer node2StringBuffer(Node node, boolean pretty, String indent) { 1505 return new StringBuffer (node2String(node, pretty)); 1506 } 1507} 1508 | Popular Tags |