Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/utils/XMLUtils.java


1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
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         // Initialize SAX Parser factory defaults
110         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     /**
124      * Encode a string appropriately for XML.
125      * @param orig the String to encode
126      * @return a String in which XML special chars are repalced by entities
127      */
128     public static String xmlEncodeString(String orig)
129     {
130         XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
131         return encoder.encode(orig);
132     }
133 
134     /**
135      * Get the current XMLEncoder
136      * @return XMLEncoder
137      */
138     public static XMLEncoder getXMLEncoder(MessageContext msgContext) {        
139         return getXMLEncoder(getEncoding(null, msgContext));
140     }
141     
142     /**
143      * Get the XMLEncoder for specific encoding
144      * @return XMLEncoder
145      */
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     /**
158      * Get the current encoding in effect
159      * @return string
160      */
161     public static String getEncoding(MessageContext msgContext) {
162         XMLEncoder encoder = getXMLEncoder(msgContext);
163         return encoder.getEncoding();
164     }
165 
166     /**
167      * Get the current encoding in effect
168      * @return string
169      */
170     public static String getEncoding() {
171         XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
172         return encoder.getEncoding();
173     }
174 
175     /** Initialize the SAX parser factory.
176      *
177      * @param factoryClassName The (optional) class name of the desired
178      *                         SAXParserFactory implementation. Will be
179      *                         assigned to the system property
180      *                         <b>javax.xml.parsers.SAXParserFactory</b>
181      *                         unless this property is already set.
182      *                         If <code>null</code>, leaves current setting
183      *                         alone.
184      * @param namespaceAware true if we want a namespace-aware parser
185      * @param validating true if we want a validating parser
186      *
187      */
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                 /*
197                  * Set the system property only if it is not already set to
198                  * avoid corrupting environments in which Axis is embedded.
199                  */
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         // Discard existing parsers
215         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     /**
232      * Gets a DocumentBuilder
233      * @return DocumentBuilder
234      * @throws ParserConfigurationException
235      */
236     public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
237         return (DocumentBuilder) documentBuilder.get();
238     }
239 
240     /**
241      * Releases a DocumentBuilder
242      * @param db
243      */
244     public static void releaseDocumentBuilder(DocumentBuilder db) {
245         try {
246             db.setErrorHandler(null); // setting implementation default
247         } catch (Throwable t) {
248             log.debug("Failed to set ErrorHandler to null on DocumentBuilder",
249                     t);
250         }
251         try {
252             db.setEntityResolver(null); // setting implementation default
253         } catch (Throwable t) {
254             log.debug("Failed to set EntityResolver to null on DocumentBuilder",
255                     t);
256         }
257     }
258 
259     /** Get a SAX parser instance from the JAXP factory.
260      *
261      * @return a SAXParser instance.
262      */
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             // parser.getParser().setEntityResolver(new DefaultEntityResolver());
272             // The above commented line and the following line are added
273             // for preventing XXE (bug #14105).
274             // We may need to uncomment the deprecated setting
275             // in case that it is considered necessary.
276             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     /** Return a SAX parser for reuse.
294      * @param parser A SAX parser that is available for reuse
295      */
296     public static void releaseSAXParser(SAXParser parser) {
297         if(!tryReset || !enableParserReuse) return;
298 
299         //Free up possible ref. held by past contenthandler.
300         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     /**
328      * Get an empty new Document
329      *
330      * @return Document
331      * @throws ParserConfigurationException if construction problems occur
332      */
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     /**
348      * Get a new Document read from the input source
349      * @return Document
350      * @throws ParserConfigurationException if construction problems occur
351      * @throws SAXException if the document has xml sax problems
352      * @throws IOException if i/o exceptions occur
353      */
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     /**
379      * Get a new Document read from the input stream
380      * @return Document
381      * @throws ParserConfigurationException if construction problems occur
382      * @throws SAXException if the document has xml sax problems
383      * @throws IOException if i/o exceptions occur
384      */
385     public static Document newDocument(InputStream inp)
386         throws ParserConfigurationException, SAXException, IOException
387     {
388         return XMLUtils.newDocument(new InputSource(inp));
389     }
390 
391     /**
392      * Get a new Document read from the indicated uri
393      * @return Document
394      * @throws ParserConfigurationException if construction problems occur
395      * @throws SAXException if the document has xml sax problems
396      * @throws IOException if i/o exceptions occur
397      */
398     public static Document newDocument(String uri)
399         throws ParserConfigurationException, SAXException, IOException
400     {
401         // call the authenticated version as there might be
402         // username/password info embeded in the uri.
403         return XMLUtils.newDocument(uri, null, null);
404     }
405 
406     /**
407      * Create a new document from the given URI, use the username and password
408      * if the URI requires authentication.
409      * @param uri the resource to get
410      * @param username basic auth username
411      * @param password basic auth password
412      * @throws ParserConfigurationException if construction problems occur
413      * @throws SAXException if the document has xml sax problems
414      * @throws IOException if i/o exceptions occur
415      */
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          // Close the Stream
422          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     /**
437      * turn an element into an XML fragment
438      * @param element
439      * @return stringified element
440      */
441     public static String ElementToString(Element element) {
442         return privateElementToString(element, true);
443     }
444 
445     /**
446      * turn a whole DOM document into XML
447      * @param doc DOM document
448      * @return string representation of the document, including XML declaration
449      */
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     /**
513      * Convert a simple string to an element with a text node
514      *
515      * @param namespace - element namespace
516      * @param name - element name
517      * @param string - value of the text node
518      * @return element - an XML Element, null if no element was created
519      */
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             // This should not occur
530             throw new InternalException(e);
531         }
532     }
533 
534     /**
535      * get the inner XML inside an element as a string. This is done by
536      * converting the XML to its string representation, then extracting the
537      * subset between beginning and end tags.
538      * @param element
539      * @return textual body of the element, or null for no inner body
540      */
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     /**
569      * Searches for the namespace URI of the given prefix in the given DOM range.
570      *
571      * The namespace is not searched in parent of the "stopNode". This is
572      * usefull to get all the needed namespaces when you need to ouput only a
573      * subtree of a DOM document.
574      *
575      * @param prefix the prefix to find
576      * @param e the starting node
577      * @param stopNode null to search in all the document or a parent node where the search must stop.
578      * @return null if no namespace is found, or the namespace URI.
579      */
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     /**
602      * Return a QName when passed a string like "foo:bar" by mapping
603      * the "foo" prefix to a namespace in the context of the given Node.
604      *
605      * @return a QName generated from the given string representation
606      */
607     public static QName getQNameFromString(String str, Node e) {
608         return getQNameFromString(str, e, false);
609     }
610     /**
611      * Return a QName when passed a string like "foo:bar" by mapping
612      * the "foo" prefix to a namespace in the context of the given Node.
613      * If default namespace is found it is returned as part of the QName.
614      *
615      * @return a QName generated from the given string representation
616      */
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     /**
642      * Return a string for a particular QName, mapping a new prefix
643      * if necessary.
644      */
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   /**
663    * Concat all the text and cdata node children of this elem and return
664    * the resulting text.
665    * (by Matt Duftler)
666    *
667    * @param parentEl the element whose cdata/text node values are to
668    *                 be combined.
669    * @return the concatanated string.
670    */
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         /**
695          * Returns a string describing parse exception details
696          */
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         // The following methods are standard SAX ErrorHandler methods.
709         // See SAX documentation for more info.
710 
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     /**
729      * Utility to get the bytes uri.
730      * Does NOT handle authenticated URLs,
731      * use getInputSourceFromURI(uri, username, password)
732      *
733      * @param uri the resource to get
734      * @see #getInputSourceFromURI(String uri, String username, String password)
735      */
736     public static InputSource getInputSourceFromURI(String uri) {
737         return new InputSource(uri);
738     }
739 
740     /**
741      * Utility to get the bytes uri
742      *
743      * @param source the resource to get
744      */
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     /**
772      * Utility to get the bytes at a protected uri
773      *
774      * This will retrieve the URL if a username and password are provided.
775      * The java.net.URL class does not do Basic Authentication, so we have to
776      * do it manually in this routine.
777      *
778      * If no username is provided, we create an InputSource from the uri
779      * and let the InputSource go fetch the contents.
780      *
781      * @param uri the resource to get
782      * @param username basic auth username
783      * @param password basic auth password
784      */
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             // we can't process it, it might be a 'simple' foo.wsdl
795             // let InputSource deal with it
796             return new InputSource(uri);
797         }
798 
799         // if no authentication, just let InputSource deal with it
800         if (username == null && wsdlurl.getUserInfo() == null) {
801             return new InputSource(uri);
802         }
803 
804         // if this is not an HTTP{S} url, let InputSource deal with it
805         if (!wsdlurl.getProtocol().startsWith("http")) {
806             return new InputSource(uri);
807         }
808 
809         URLConnection connection = wsdlurl.openConnection();
810         // Does this work for https???
811         if (!(connection instanceof HttpURLConnection)) {
812             // can't do http with this URL, let InputSource deal with it
813             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         // username/password info in the URL overrides passed in values
826         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     /**
853      * Find a Node with a given QName
854      *
855      * @param node parent node
856      * @param name QName of the child we need to find
857      * @return child node
858      */
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     /**
873      * Trim all new lines from text nodes.
874      *
875      * @param node
876      */
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     /**
920      * Converts a List with org.w3c.dom.Element objects to an Array
921      * with org.w3c.dom.Element objects.
922      * @param list List containing org.w3c.dom.Element objects
923      * @return Element[] Array with org.w3c.dom.Element objects
924      */
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 }