| 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 &n
|