1 16 17 package org.apache.axis.utils ; 18 19 import org.apache.axis.AxisEngine; 20 import org.apache.axis.Constants; 21 import org.apache.axis.InternalException; 22 import org.apache.axis.Message; 23 import org.apache.axis.MessageContext; 24 import org.apache.axis.AxisProperties; 25 import org.apache.axis.components.encoding.XMLEncoder; 26 import org.apache.axis.components.encoding.XMLEncoderFactory; 27 import org.apache.axis.components.logger.LogFactory; 28 import org.apache.commons.logging.Log; 29 import org.w3c.dom.Attr ; 30 import org.w3c.dom.CharacterData ; 31 import org.w3c.dom.Document ; 32 import org.w3c.dom.Element ; 33 import org.w3c.dom.NamedNodeMap ; 34 import org.w3c.dom.Node ; 35 import org.w3c.dom.NodeList ; 36 import org.w3c.dom.Text ; 37 import org.xml.sax.ErrorHandler ; 38 import org.xml.sax.InputSource ; 39 import org.xml.sax.SAXException ; 40 import org.xml.sax.SAXParseException ; 41 import org.xml.sax.XMLReader ; 42 import org.xml.sax.helpers.DefaultHandler ; 43 44 import javax.xml.namespace.QName ; 45 import javax.xml.parsers.DocumentBuilder ; 46 import javax.xml.parsers.DocumentBuilderFactory ; 47 import javax.xml.parsers.ParserConfigurationException ; 48 import javax.xml.parsers.SAXParser ; 49 import javax.xml.parsers.SAXParserFactory ; 50 import javax.xml.soap.SOAPException ; 51 import javax.xml.soap.SOAPMessage ; 52 import javax.xml.transform.Source ; 53 import javax.xml.transform.dom.DOMSource ; 54 import javax.xml.transform.sax.SAXSource ; 55 import javax.xml.transform.stream.StreamSource ; 56 import java.io.ByteArrayInputStream ; 57 import java.io.ByteArrayOutputStream ; 58 import java.io.IOException ; 59 import java.io.InputStream ; 60 import java.io.OutputStream ; 61 import java.io.OutputStreamWriter ; 62 import java.io.StringWriter ; 63 import java.io.UnsupportedEncodingException ; 64 import java.io.Writer ; 65 import java.net.HttpURLConnection ; 66 import java.net.MalformedURLException ; 67 import java.net.ProtocolException ; 68 import java.net.URL ; 69 import java.net.URLConnection ; 70 import java.util.Iterator ; 71 import java.util.List ; 72 import java.util.Stack ; 73 74 75 public class XMLUtils { 76 protected static Log log = 77 LogFactory.getLog(XMLUtils.class.getName()); 78 79 public static final String httpAuthCharEncoding = "ISO-8859-1"; 80 private static final String saxParserFactoryProperty = 81 "javax.xml.parsers.SAXParserFactory"; 82 83 private static DocumentBuilderFactory dbf = getDOMFactory(); 84 private static SAXParserFactory saxFactory; 85 private static Stack saxParsers = new Stack (); 86 private static DefaultHandler doNothingContentHandler = new DefaultHandler (); 87 88 private static String EMPTY = ""; 89 private static ByteArrayInputStream bais = new ByteArrayInputStream (EMPTY.getBytes()); 90 91 private static boolean tryReset= true; 92 93 protected static boolean enableParserReuse = false; 94 95 private static class ThreadLocalDocumentBuilder extends ThreadLocal { 96 protected Object initialValue() { 97 try { 98 return getDOMFactory().newDocumentBuilder(); 99 } catch (ParserConfigurationException e) { 100 log.error(Messages.getMessage("parserConfigurationException00"), 101 e); 102 } 103 return null; 104 } 105 } 106 private static ThreadLocalDocumentBuilder documentBuilder = new ThreadLocalDocumentBuilder(); 107 108 static { 109 initSAXFactory(null, true, false); 111 112 String value = AxisProperties.getProperty(AxisEngine.PROP_XML_REUSE_SAX_PARSERS, 113 "" + false); 114 if (value.equalsIgnoreCase("true") || 115 value.equals("1") || 116 value.equalsIgnoreCase("yes")) { 117 enableParserReuse = true; 118 } else { 119 enableParserReuse = false; 120 } 121 } 122 123 128 public static String xmlEncodeString(String orig) 129 { 130 XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext()); 131 return encoder.encode(orig); 132 } 133 134 138 public static XMLEncoder getXMLEncoder(MessageContext msgContext) { 139 return getXMLEncoder(getEncoding(null, msgContext)); 140 } 141 142 146 public static XMLEncoder getXMLEncoder(String encoding) { 147 XMLEncoder encoder = null; 148 try { 149 encoder = XMLEncoderFactory.getEncoder(encoding); 150 } catch (Exception e) { 151 log.error(Messages.getMessage("exception00"), e); 152 encoder = XMLEncoderFactory.getDefaultEncoder(); 153 } 154 return encoder; 155 } 156 157 161 public static String getEncoding(MessageContext msgContext) { 162 XMLEncoder encoder = getXMLEncoder(msgContext); 163 return encoder.getEncoding(); 164 } 165 166 170 public static String getEncoding() { 171 XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext()); 172 return encoder.getEncoding(); 173 } 174 175 188 public static void initSAXFactory(String factoryClassName, 189 boolean namespaceAware, 190 boolean validating) 191 { 192 if (factoryClassName != null) { 193 try { 194 saxFactory = (SAXParserFactory )Class.forName(factoryClassName). 195 newInstance(); 196 200 if (System.getProperty(saxParserFactoryProperty) == null) { 201 System.setProperty(saxParserFactoryProperty, 202 factoryClassName); 203 } 204 } catch (Exception e) { 205 log.error(Messages.getMessage("exception00"), e); 206 saxFactory = null; 207 } 208 } else { 209 saxFactory = SAXParserFactory.newInstance(); 210 } 211 saxFactory.setNamespaceAware(namespaceAware); 212 saxFactory.setValidating(validating); 213 214 saxParsers.clear(); 216 } 217 218 private static DocumentBuilderFactory getDOMFactory() { 219 DocumentBuilderFactory dbf; 220 try { 221 dbf = DocumentBuilderFactory.newInstance(); 222 dbf.setNamespaceAware(true); 223 } 224 catch( Exception e ) { 225 log.error(Messages.getMessage("exception00"), e ); 226 dbf = null; 227 } 228 return( dbf ); 229 } 230 231 236 public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException { 237 return (DocumentBuilder ) documentBuilder.get(); 238 } 239 240 244 public static void releaseDocumentBuilder(DocumentBuilder db) { 245 try { 246 db.setErrorHandler(null); } catch (Throwable t) { 248 log.debug("Failed to set ErrorHandler to null on DocumentBuilder", 249 t); 250 } 251 try { 252 db.setEntityResolver(null); } catch (Throwable t) { 254 log.debug("Failed to set EntityResolver to null on DocumentBuilder", 255 t); 256 } 257 } 258 259 263 public static synchronized SAXParser getSAXParser() { 264 if(enableParserReuse && !saxParsers.empty()) { 265 return (SAXParser )saxParsers.pop(); 266 } 267 268 try { 269 SAXParser parser = saxFactory.newSAXParser(); 270 XMLReader reader = parser.getXMLReader(); 271 try { 277 reader.setEntityResolver(new DefaultEntityResolver()); 278 } catch (Throwable t) { 279 log.debug("Failed to set EntityResolver on DocumentBuilder", t); 280 } 281 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 282 return parser; 283 } catch (ParserConfigurationException e) { 284 log.error(Messages.getMessage("parserConfigurationException00"), e); 285 return null; 286 } catch (SAXException se) { 287 log.error(Messages.getMessage("SAXException00"), se); 288 return null; 289 } 290 } 291 292 293 296 public static void releaseSAXParser(SAXParser parser) { 297 if(!tryReset || !enableParserReuse) return; 298 299 try{ 301 XMLReader xmlReader= parser.getXMLReader(); 302 if(null != xmlReader){ 303 xmlReader.setContentHandler(doNothingContentHandler); 304 xmlReader.setDTDHandler(doNothingContentHandler); 305 try { 306 xmlReader.setEntityResolver(doNothingContentHandler); 307 } catch (Throwable t) { 308 log.debug("Failed to set EntityResolver on DocumentBuilder", t); 309 } 310 try { 311 xmlReader.setErrorHandler(doNothingContentHandler); 312 } catch (Throwable t) { 313 log.debug("Failed to set ErrorHandler on DocumentBuilder", t); 314 } 315 316 synchronized (XMLUtils.class ) { 317 saxParsers.push(parser); 318 } 319 } 320 else { 321 tryReset= false; 322 } 323 } catch (org.xml.sax.SAXException e) { 324 tryReset= false; 325 } 326 } 327 333 public static Document newDocument() 334 throws ParserConfigurationException { 335 DocumentBuilder db = null; 336 try { 337 db = getDocumentBuilder(); 338 Document doc = db.newDocument(); 339 return doc; 340 } finally { 341 if (db != null) { 342 releaseDocumentBuilder(db); 343 } 344 } 345 } 346 347 354 public static Document newDocument(InputSource inp) 355 throws ParserConfigurationException , SAXException , IOException { 356 DocumentBuilder db = null; 357 try { 358 db = getDocumentBuilder(); 359 try { 360 db.setEntityResolver(new DefaultEntityResolver()); 361 } catch (Throwable t) { 362 log.debug("Failed to set EntityResolver on DocumentBuilder", t); 363 } 364 try { 365 db.setErrorHandler(new XMLUtils.ParserErrorHandler()); 366 } catch (Throwable t) { 367 log.debug("Failed to set ErrorHandler on DocumentBuilder", t); 368 } 369 Document doc = db.parse(inp); 370 return doc; 371 } finally { 372 if (db != null) { 373 releaseDocumentBuilder(db); 374 } 375 } 376 } 377 378 385 public static Document newDocument(InputStream inp) 386 throws ParserConfigurationException , SAXException , IOException 387 { 388 return XMLUtils.newDocument(new InputSource (inp)); 389 } 390 391 398 public static Document newDocument(String uri) 399 throws ParserConfigurationException , SAXException , IOException 400 { 401 return XMLUtils.newDocument(uri, null, null); 404 } 405 406 416 public static Document newDocument(String uri, String username, String password) 417 throws ParserConfigurationException , SAXException , IOException 418 { 419 InputSource ins = XMLUtils.getInputSourceFromURI(uri, username, password); 420 Document doc = XMLUtils.newDocument(ins); 421 if (ins.getByteStream() != null) { 423 ins.getByteStream().close(); 424 } else if (ins.getCharacterStream() != null) { 425 ins.getCharacterStream().close(); 426 } 427 return doc; 428 } 429 430 private static String privateElementToString(Element element, 431 boolean omitXMLDecl) 432 { 433 return DOM2Writer.nodeToString(element, omitXMLDecl); 434 } 435 436 441 public static String ElementToString(Element element) { 442 return privateElementToString(element, true); 443 } 444 445 450 public static String DocumentToString(Document doc) { 451 return privateElementToString(doc.getDocumentElement(), false); 452 } 453 454 public static String PrettyDocumentToString(Document doc) { 455 StringWriter sw = new StringWriter (); 456 PrettyElementToWriter(doc.getDocumentElement(), sw); 457 return sw.toString(); 458 } 459 460 public static void privateElementToWriter(Element element, Writer writer, 461 boolean omitXMLDecl, 462 boolean pretty) { 463 DOM2Writer.serializeAsXML(element, writer, omitXMLDecl, pretty); 464 } 465 466 public static void ElementToStream(Element element, OutputStream out) { 467 Writer writer = getWriter(out); 468 privateElementToWriter(element, writer, true, false); 469 } 470 471 public static void PrettyElementToStream(Element element, OutputStream out) { 472 Writer writer = getWriter(out); 473 privateElementToWriter(element, writer, true, true); 474 } 475 476 public static void ElementToWriter(Element element, Writer writer) { 477 privateElementToWriter(element, writer, true, false); 478 } 479 480 public static void PrettyElementToWriter(Element element, Writer writer) { 481 privateElementToWriter(element, writer, true, true); 482 } 483 484 public static void DocumentToStream(Document doc, OutputStream out) { 485 Writer writer = getWriter(out); 486 privateElementToWriter(doc.getDocumentElement(), writer, false, false); 487 } 488 489 public static void PrettyDocumentToStream(Document doc, OutputStream out) { 490 Writer writer = getWriter(out); 491 privateElementToWriter(doc.getDocumentElement(), writer, false, true); 492 } 493 494 private static Writer getWriter(OutputStream os) { 495 Writer writer = null; 496 try { 497 writer = new OutputStreamWriter (os, "UTF-8"); 498 } catch (UnsupportedEncodingException uee) { 499 log.error(Messages.getMessage("exception00"), uee); 500 writer = new OutputStreamWriter (os); 501 } 502 return writer; 503 } 504 505 public static void DocumentToWriter(Document doc, Writer writer) { 506 privateElementToWriter(doc.getDocumentElement(), writer, false, false); 507 } 508 509 public static void PrettyDocumentToWriter(Document doc, Writer writer) { 510 privateElementToWriter(doc.getDocumentElement(), writer, false, true); 511 } 512 520 public static Element StringToElement(String namespace, String name, String string) { 521 try { 522 Document doc = XMLUtils.newDocument(); 523 Element element = doc.createElementNS(namespace, name); 524 Text text = doc.createTextNode(string); 525 element.appendChild(text); 526 return element; 527 } 528 catch (ParserConfigurationException e) { 529 throw new InternalException(e); 531 } 532 } 533 534 541 public static String getInnerXMLString(Element element) { 542 String elementString = ElementToString(element); 543 int start, end; 544 start = elementString.indexOf(">") + 1; 545 end = elementString.lastIndexOf("</"); 546 if (end > 0) 547 return elementString.substring(start,end); 548 else 549 return null; 550 } 551 552 public static String getPrefix(String uri, Node e) { 553 while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) { 554 NamedNodeMap attrs = e.getAttributes(); 555 for (int n = 0; n < attrs.getLength(); n++) { 556 Attr a = (Attr )attrs.item(n); 557 String name; 558 if ((name = a.getName()).startsWith("xmlns:") && 559 a.getNodeValue().equals(uri)) { 560 return name.substring(6); 561 } 562 } 563 e = e.getParentNode(); 564 } 565 return null; 566 } 567 568 580 public static String getNamespace(String prefix, Node e, Node stopNode) { 581 while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) { 582 Attr attr = null; 583 if (prefix == null) { 584 attr = ((Element ) e).getAttributeNode("xmlns"); 585 } else { 586 attr = ((Element ) e).getAttributeNodeNS(Constants.NS_URI_XMLNS, 587 prefix); 588 } 589 if (attr != null) return attr.getValue(); 590 if (e == stopNode) 591 return null; 592 e = e.getParentNode(); 593 } 594 return null; 595 } 596 597 public static String getNamespace(String prefix, Node e) { 598 return getNamespace(prefix, e, null); 599 } 600 601 607 public static QName getQNameFromString(String str, Node e) { 608 return getQNameFromString(str, e, false); 609 } 610 617 public static QName getFullQNameFromString(String str, Node e) { 618 return getQNameFromString(str, e, true); 619 } 620 private static QName getQNameFromString(String str, Node e, boolean defaultNS) { 621 if (str == null || e == null) 622 return null; 623 624 int idx = str.indexOf(':'); 625 if (idx > -1) { 626 String prefix = str.substring(0, idx); 627 String ns = getNamespace(prefix, e); 628 if (ns == null) 629 return null; 630 return new QName (ns, str.substring(idx + 1)); 631 } else { 632 if (defaultNS) { 633 String ns = getNamespace(null, e); 634 if (ns != null) 635 return new QName (ns, str); 636 } 637 return new QName ("", str); 638 } 639 } 640 641 645 public static String getStringForQName(QName qname, Element e) 646 { 647 String uri = qname.getNamespaceURI(); 648 String prefix = getPrefix(uri, e); 649 if (prefix == null) { 650 int i = 1; 651 prefix = "ns" + i; 652 while (getNamespace(prefix, e) != null) { 653 i++; 654 prefix = "ns" + i; 655 } 656 e.setAttributeNS(Constants.NS_URI_XMLNS, 657 "xmlns:" + prefix, uri); 658 } 659 return prefix + ":" + qname.getLocalPart(); 660 } 661 662 671 public static String getChildCharacterData (Element parentEl) { 672 if (parentEl == null) { 673 return null; 674 } 675 Node tempNode = parentEl.getFirstChild(); 676 StringBuffer strBuf = new StringBuffer (); 677 CharacterData charData; 678 679 while (tempNode != null) { 680 switch (tempNode.getNodeType()) { 681 case Node.TEXT_NODE : 682 case Node.CDATA_SECTION_NODE : charData = (CharacterData )tempNode; 683 strBuf.append(charData.getData()); 684 break; 685 } 686 tempNode = tempNode.getNextSibling(); 687 } 688 return strBuf.toString(); 689 } 690 691 public static class ParserErrorHandler implements ErrorHandler { 692 protected static Log log = 693 LogFactory.getLog(ParserErrorHandler.class.getName()); 694 697 private String getParseExceptionInfo(SAXParseException spe) { 698 String systemId = spe.getSystemId(); 699 if (systemId == null) { 700 systemId = "null"; 701 } 702 String info = "URI=" + systemId + 703 " Line=" + spe.getLineNumber() + 704 ": " + spe.getMessage(); 705 return info; 706 } 707 708 711 public void warning(SAXParseException spe) throws SAXException { 712 if (log.isDebugEnabled()) 713 log.debug( Messages.getMessage("warning00", getParseExceptionInfo(spe))); 714 } 715 716 public void error(SAXParseException spe) throws SAXException { 717 String message = "Error: " + getParseExceptionInfo(spe); 718 throw new SAXException (message); 719 } 720 721 public void fatalError(SAXParseException spe) throws SAXException { 722 String message = "Fatal Error: " + getParseExceptionInfo(spe); 723 throw new SAXException (message); 724 } 725 } 726 727 728 736 public static InputSource getInputSourceFromURI(String uri) { 737 return new InputSource (uri); 738 } 739 740 745 public static InputSource sourceToInputSource(Source source) { 746 if (source instanceof SAXSource ) { 747 return ((SAXSource ) source).getInputSource(); 748 } else if (source instanceof DOMSource ) { 749 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 750 Node node = ((DOMSource )source).getNode(); 751 if (node instanceof Document ) { 752 node = ((Document )node).getDocumentElement(); 753 } 754 Element domElement = (Element )node; 755 ElementToStream(domElement, baos); 756 InputSource isource = new InputSource (source.getSystemId()); 757 isource.setByteStream(new ByteArrayInputStream (baos.toByteArray())); 758 return isource; 759 } else if (source instanceof StreamSource ) { 760 StreamSource ss = (StreamSource ) source; 761 InputSource isource = new InputSource (ss.getSystemId()); 762 isource.setByteStream(ss.getInputStream()); 763 isource.setCharacterStream(ss.getReader()); 764 isource.setPublicId(ss.getPublicId()); 765 return isource; 766 } else { 767 return getInputSourceFromURI(source.getSystemId()); 768 } 769 } 770 771 785 private static InputSource getInputSourceFromURI(String uri, 786 String username, 787 String password) 788 throws IOException , ProtocolException , UnsupportedEncodingException 789 { 790 URL wsdlurl = null; 791 try { 792 wsdlurl = new URL (uri); 793 } catch (MalformedURLException e) { 794 return new InputSource (uri); 797 } 798 799 if (username == null && wsdlurl.getUserInfo() == null) { 801 return new InputSource (uri); 802 } 803 804 if (!wsdlurl.getProtocol().startsWith("http")) { 806 return new InputSource (uri); 807 } 808 809 URLConnection connection = wsdlurl.openConnection(); 810 if (!(connection instanceof HttpURLConnection )) { 812 return new InputSource (uri); 814 } 815 HttpURLConnection uconn = (HttpURLConnection ) connection; 816 String userinfo = wsdlurl.getUserInfo(); 817 uconn.setRequestMethod("GET"); 818 uconn.setAllowUserInteraction(false); 819 uconn.setDefaultUseCaches(false); 820 uconn.setDoInput(true); 821 uconn.setDoOutput(false); 822 uconn.setInstanceFollowRedirects(true); 823 uconn.setUseCaches(false); 824 825 String auth = null; 827 if (userinfo != null) { 828 auth = userinfo; 829 } else if (username != null) { 830 auth = (password == null) ? username : username + ":" + password; 831 } 832 833 if (auth != null) { 834 uconn.setRequestProperty("Authorization", 835 "Basic " + 836 base64encode(auth.getBytes(httpAuthCharEncoding))); 837 } 838 839 uconn.connect(); 840 841 return new InputSource (uconn.getInputStream()); 842 } 843 844 public static final String base64encode(byte[] bytes) { 845 return new String (Base64.encode(bytes)); 846 } 847 848 public static InputSource getEmptyInputSource() { 849 return new InputSource (bais); 850 } 851 852 859 public static Node findNode(Node node, QName name){ 860 if(name.getNamespaceURI().equals(node.getNamespaceURI()) && 861 name.getLocalPart().equals(node.getLocalName())) 862 return node; 863 NodeList children = node.getChildNodes(); 864 for(int i=0;i<children.getLength();i++){ 865 Node ret = findNode(children.item(i), name); 866 if(ret != null) 867 return ret; 868 } 869 return null; 870 } 871 872 877 public static void normalize(Node node) { 878 if (node.getNodeType() == Node.TEXT_NODE) { 879 String data = ((Text ) node).getData(); 880 if (data.length() > 0) { 881 char ch = data.charAt(data.length()-1); 882 if(ch == '\n' || ch == '\r' || ch == ' ') { 883 String data2 = trim(data); 884 ((Text ) node).setData(data2); 885 } 886 } 887 } 888 for (Node currentChild = node.getFirstChild(); currentChild != null; currentChild = currentChild.getNextSibling()) { 889 normalize(currentChild); 890 } 891 } 892 893 public static String trim(String str) { 894 if (str.length() == 0) { 895 return str; 896 } 897 898 if (str.length() == 1) { 899 if ("\r".equals(str) || "\n".equals(str)) { 900 return ""; 901 } else { 902 return str; 903 } 904 } 905 906 int lastIdx = str.length() - 1; 907 char last = str.charAt(lastIdx); 908 while(lastIdx > 0) { 909 if(last != '\n' && last != '\r' && last != ' ') 910 break; 911 lastIdx--; 912 last = str.charAt(lastIdx); 913 } 914 if(lastIdx == 0) 915 return ""; 916 return str.substring(0, lastIdx); 917 } 918 919 925 public static Element [] asElementArray(List list) { 926 927 Element [] elements = new Element [list.size()]; 928 929 int i = 0; 930 Iterator detailIter = list.iterator(); 931 while (detailIter.hasNext()) { 932 elements[i++] = (Element ) detailIter.next(); 933 } 934 935 return elements; 936 } 937 938 public static String getEncoding(Message message, 939 MessageContext msgContext) { 940 return getEncoding(message, msgContext, 941 XMLEncoderFactory.getDefaultEncoder()); 942 } 943 944 public static String getEncoding(Message message, 945 MessageContext msgContext, 946 XMLEncoder defaultEncoder) { 947 String encoding = null; 948 try { 949 if(message != null) { 950 encoding = (String ) message.getProperty(SOAPMessage.CHARACTER_SET_ENCODING); 951 } 952 } catch (SOAPException e) { 953 } 954 if(msgContext == null) { 955 msgContext = MessageContext.getCurrentContext(); 956 } 957 if(msgContext != null && encoding == null){ 958 encoding = (String ) msgContext.getProperty(SOAPMessage.CHARACTER_SET_ENCODING); 959 } 960 if (msgContext != null && encoding == null && msgContext.getAxisEngine() != null) { 961 encoding = (String ) msgContext.getAxisEngine().getOption(AxisEngine.PROP_XML_ENCODING); 962 } 963 if (encoding == null && defaultEncoder != null) { 964 encoding = defaultEncoder.getEncoding(); 965 } 966 return encoding; 967 } 968 } 969 | Popular Tags |