Could you please open a bug report with a "diff -u" against latest
XMLUtils.java?

thanks,
dims


On Mon, 06 Dec 2004 16:40:34 +0100, [EMAIL PROTECTED]
<[EMAIL PROTECTED]> wrote:
> Hi,
> 
> While doing performance tests on deserialization, I noticed that Axis
> scales very poorly when increasing the number of threads.
> 
> Here are the figures:
> 5 threads, 1000 messages: 15 seconds
> 10 threads, 1000 messages: 56 seconds
> 15 threads, 1000 messages: 93 seconds
> 
> The root of the problem is in XMLUtils. Each time a node is created via
> the static fuction newDocument(...), there are two functions,
> getDocumentBuilder() and realeaseDocumentBuilder(), called which both
> peform synchronisation over a pool of document builders
> (documentBuilders ). Since XML documents contain many nodes and there
> are at least two synchronization points in the code per node created, I
> let you imagine the overhead suffered when more threads come into play.
> 
> I was able to achieve a significant performance boost by replacing the
> pool of DocumentBuilders (documentBuilders) by a single document builder
> stored in a ThreadLocal variable. This was already suggested a while ago
> in this mailing list (see "Performance Issues with AXIS & Axis Response
> time appears linear with load").
> 
> The results of my benchmark with the changes brought to the code are
> shown below.
> 
> 5 threads, 1000 messages:  13seconds
> 10 threads, 1000 messages:  25,5 seconds
> 15 threads, 1000 messages: 37 seconds
> 
> As you can see, deserialization time scales now linearly with the number
> of threads which is a lot better. I placed the code in attachment. Could
> you include sth equivalent in the next release of the Axis.
> 
> Thanks,
> Sebastien
> 
> 
> /*
>  * Copyright 2001-2004 The Apache Software Foundation.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> package org.apache.axis.utils ;
> 
> import org.apache.axis.AxisEngine;
> import org.apache.axis.Constants;
> import org.apache.axis.InternalException;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.AxisProperties;
> import org.apache.axis.components.encoding.XMLEncoder;
> import org.apache.axis.components.encoding.XMLEncoderFactory;
> import org.apache.axis.components.logger.LogFactory;
> import org.apache.commons.logging.Log;
> import org.w3c.dom.Attr;
> import org.w3c.dom.CharacterData;
> import org.w3c.dom.Document;
> import org.w3c.dom.Element;
> import org.w3c.dom.NamedNodeMap;
> import org.w3c.dom.Node;
> import org.w3c.dom.NodeList;
> import org.w3c.dom.Text;
> import org.xml.sax.ErrorHandler;
> import org.xml.sax.InputSource;
> import org.xml.sax.SAXException;
> import org.xml.sax.SAXParseException;
> import org.xml.sax.XMLReader;
> import org.xml.sax.helpers.DefaultHandler;
> 
> import javax.xml.namespace.QName;
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import javax.xml.parsers.ParserConfigurationException;
> import javax.xml.parsers.SAXParser;
> import javax.xml.parsers.SAXParserFactory;
> import javax.xml.soap.SOAPException;
> import javax.xml.soap.SOAPMessage;
> import javax.xml.transform.Source;
> import javax.xml.transform.dom.DOMSource;
> import javax.xml.transform.sax.SAXSource;
> import javax.xml.transform.stream.StreamSource;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.OutputStream;
> import java.io.OutputStreamWriter;
> import java.io.StringWriter;
> import java.io.UnsupportedEncodingException;
> import java.io.Writer;
> import java.net.HttpURLConnection;
> import java.net.MalformedURLException;
> import java.net.ProtocolException;
> import java.net.URL;
> import java.net.URLConnection;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Stack;
> 
> public class XMLUtils {
>     protected static Log log =
>         LogFactory.getLog(XMLUtils.class.getName());
> 
>     public static final String httpAuthCharEncoding = "ISO-8859-1";
>     private static final String saxParserFactoryProperty =
>         "javax.xml.parsers.SAXParserFactory";
> 
>     // @Alcatel DocumentBuilderFactory is not thread-safe. Place 
> DocumentBuilder
>     // in thread local variable to remove synchronization overhead.
> 
>     // private static DocumentBuilderFactory dbf = getDOMFactory();
>     // private static Stack                  documentBuilders = new Stack();
>     private static class ThreadLocalDocumentBuilder extends ThreadLocal {
>         protected Object initialValue() {
>                 try {
>                                 return getDOMFactory().newDocumentBuilder();
>                         } catch (ParserConfigurationException e) {
>                     
> log.error(Messages.getMessage("parserConfigurationException00"), e);
>                         }
>                         return null;
>         }
>     }
>     private static ThreadLocalDocumentBuilder documentBuilder = new 
> ThreadLocalDocumentBuilder();
> 
>     private static SAXParserFactory       saxFactory;
>     private static Stack                  saxParsers = new Stack();
>     private static DefaultHandler doNothingContentHandler = new 
> DefaultHandler();
> 
>     private static String EMPTY = "";
>     private static ByteArrayInputStream bais = new 
> ByteArrayInputStream(EMPTY.getBytes());
> 
>     protected static boolean enableParserReuse = false;
> 
>     static {
>         // Initialize SAX Parser factory defaults
>         initSAXFactory(null, true, false);
> 
>         String value = 
> AxisProperties.getProperty(AxisEngine.PROP_XML_REUSE_SAX_PARSERS,
>                 "" + false);
>         if (value.equalsIgnoreCase("true") ||
>                 value.equals("1") ||
>                 value.equalsIgnoreCase("yes")) {
>             enableParserReuse = true;
>         } else {
>             enableParserReuse = false;
>         }
>     }
> 
>     /**
>      * Encode a string appropriately for XML.
>      * @param orig the String to encode
>      * @return a String in which XML special chars are repalced by entities
>      */
>     public static String xmlEncodeString(String orig)
>     {
>         XMLEncoder encoder = 
> getXMLEncoder(MessageContext.getCurrentContext());
>         return encoder.encode(orig);
>     }
> 
>     /**
>      * Get the current XMLEncoder
>      * @return XMLEncoder
>      */
>     public static XMLEncoder getXMLEncoder(MessageContext msgContext) {
>         XMLEncoder encoder = null;
>         String encoding = getEncoding(null, msgContext);
>         try {
>             encoder = XMLEncoderFactory.getEncoder(encoding);
>         } catch (Exception e) {
>             log.error(Messages.getMessage("exception00"), e);
>             encoder = XMLEncoderFactory.getDefaultEncoder();
>         }
>         return encoder;
>     }
> 
>     /**
>      * Get the current encoding in effect
>      * @return string
>      */
>     public static String getEncoding(MessageContext msgContext) {
>         XMLEncoder encoder = getXMLEncoder(msgContext);
>         return encoder.getEncoding();
>     }
> 
>     /**
>      * Get the current encoding in effect
>      * @return string
>      */
>     public static String getEncoding() {
>         XMLEncoder encoder = 
> getXMLEncoder(MessageContext.getCurrentContext());
>         return encoder.getEncoding();
>     }
> 
>     /** Initialize the SAX parser factory.
>      *
>      * @param factoryClassName The (optional) class name of the desired
>      *                         SAXParserFactory implementation. Will be
>      *                         assigned to the system property
>      *                         <b>javax.xml.parsers.SAXParserFactory</b>
>      *                         unless this property is already set.
>      *                         If <code>null</code>, leaves current setting
>      *                         alone.
>      * @param namespaceAware true if we want a namespace-aware parser
>      * @param validating true if we want a validating parser
>      *
>      */
>     public static void initSAXFactory(String factoryClassName,
>                                       boolean namespaceAware,
>                                       boolean validating)
>     {
>         if (factoryClassName != null) {
>             try {
>                 saxFactory = 
> (SAXParserFactory)Class.forName(factoryClassName).
>                     newInstance();
>                 /*
>                  * Set the system property only if it is not already set to
>                  * avoid corrupting environments in which Axis is embedded.
>                  */
>                 if (System.getProperty(saxParserFactoryProperty) == null) {
>                     System.setProperty(saxParserFactoryProperty,
>                                        factoryClassName);
>                 }
>             } catch (Exception e) {
>                 log.error(Messages.getMessage("exception00"), e);
>                 saxFactory = null;
>             }
>        } else {
>             saxFactory = SAXParserFactory.newInstance();
>         }
>         saxFactory.setNamespaceAware(namespaceAware);
>         saxFactory.setValidating(validating);
> 
>         // Discard existing parsers
>         saxParsers.clear();
>     }
> 
>     private static DocumentBuilderFactory getDOMFactory() {
>         DocumentBuilderFactory dbf;
>         try {
>             dbf = DocumentBuilderFactory.newInstance();
>             dbf.setNamespaceAware(true);
>         }
>         catch( Exception e ) {
>             log.error(Messages.getMessage("exception00"), e );
>             dbf = null;
>         }
>         return( dbf );
>     }
> 
>     private static boolean tryReset= true;
> 
>     /** Get a SAX parser instance from the JAXP factory.
>      *
>      * @return a SAXParser instance.
>      */
>     public static synchronized SAXParser getSAXParser() {
>         if(enableParserReuse && !saxParsers.empty()) {
>             return (SAXParser )saxParsers.pop();
>         }
> 
>         try {
>             SAXParser parser = saxFactory.newSAXParser();
>             XMLReader reader = parser.getXMLReader();
>             // parser.getParser().setEntityResolver(new 
> DefaultEntityResolver());
>             // The above commented line and the following line are added
>             // for preventing XXE (bug #14105).
>             // We may need to uncomment the deprecated setting
>             // in case that it is considered necessary.
>             reader.setEntityResolver(new DefaultEntityResolver());
>             
> reader.setFeature("http://xml.org/sax/features/namespace-prefixes";, false);
>             return parser;
>         } catch (ParserConfigurationException e) {
>             log.error(Messages.getMessage("parserConfigurationException00"), 
> e);
>             return null;
>         } catch (SAXException se) {
>             log.error(Messages.getMessage("SAXException00"), se);
>             return null;
>         }
>     }
> 
>     /** Return a SAX parser for reuse.
>      * @param parser A SAX parser that is available for reuse
>      */
>     public static void releaseSAXParser(SAXParser parser) {
>         if(!tryReset || !enableParserReuse) return;
> 
>         //Free up possible ref. held by past contenthandler.
>         try{
>             XMLReader xmlReader= parser.getXMLReader();
>             if(null != xmlReader){
>                 xmlReader.setContentHandler(doNothingContentHandler);
>                 xmlReader.setDTDHandler(doNothingContentHandler);
>                 xmlReader.setEntityResolver(doNothingContentHandler);
>                 xmlReader.setErrorHandler(doNothingContentHandler);
>                 synchronized (XMLUtils.class ) {
>                     saxParsers.push(parser);
>                 }
>             }
>             else {
>                 tryReset= false;
>             }
>         } catch (org.xml.sax.SAXException e) {
>             tryReset= false;
>         }
>     }
>     /**
>      * Get an empty new Document
>      *
>      * @return Document
>      * @throws ParserConfigurationException if construction problems occur
>      */
>     public static Document newDocument()
>             throws ParserConfigurationException {
>         DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
>         Document doc = db.newDocument();
>         return doc;
>     }
> 
>     /**
>      * Get a new Document read from the input source
>      * @return Document
>      * @throws ParserConfigurationException if construction problems occur
>      * @throws SAXException if the document has xml sax problems
>      * @throws IOException if i/o exceptions occur
>      */
>     public static Document newDocument(InputSource inp)
>         throws ParserConfigurationException, SAXException, IOException
>     {
>         DocumentBuilder db = (DocumentBuilder) documentBuilder.get();
>         db.setEntityResolver(new DefaultEntityResolver());
>         db.setErrorHandler(new ParserErrorHandler());
>         Document doc = db.parse(inp);
>         return doc;
>     }
> 
>     /**
>      * Get a new Document read from the input stream
>      * @return Document
>      * @throws ParserConfigurationException if construction problems occur
>      * @throws SAXException if the document has xml sax problems
>      * @throws IOException if i/o exceptions occur
>      */
>     public static Document newDocument(InputStream inp)
>         throws ParserConfigurationException, SAXException, IOException
>     {
>         return XMLUtils.newDocument(new InputSource(inp));
>     }
> 
>     /**
>      * Get a new Document read from the indicated uri
>      * @return Document
>      * @throws ParserConfigurationException if construction problems occur
>      * @throws SAXException if the document has xml sax problems
>      * @throws IOException if i/o exceptions occur
>      */
>     public static Document newDocument(String uri)
>         throws ParserConfigurationException, SAXException, IOException
>     {
>         // call the authenticated version as there might be
>         // username/password info embeded in the uri.
>         return XMLUtils.newDocument(uri, null, null);
>     }
> 
>     /**
>      * Create a new document from the given URI, use the username and password
>      * if the URI requires authentication.
>      * @param uri the resource to get
>      * @param username basic auth username
>      * @param password basic auth password
>      * @throws ParserConfigurationException if construction problems occur
>      * @throws SAXException if the document has xml sax problems
>      * @throws IOException if i/o exceptions occur
>      */
>     public static Document newDocument(String uri, String username, String 
> password)
>         throws ParserConfigurationException, SAXException, IOException
>      {
>          InputSource ins = XMLUtils.getInputSourceFromURI(uri, username, 
> password);
>          Document doc = XMLUtils.newDocument(ins);
>          // Close the Stream
>          if (ins.getByteStream() != null) {
>              ins.getByteStream().close();
>          } else if (ins.getCharacterStream() != null) {
>              ins.getCharacterStream().close();
>          }
>          return doc;
>      }
> 
>     private static String privateElementToString(Element element,
>                                                  boolean omitXMLDecl)
>     {
>         return DOM2Writer.nodeToString(element, omitXMLDecl);
>     }
> 
>     /**
>      * turn an element into an XML fragment
>      * @param element
>      * @return stringified element
>      */
>     public static String ElementToString(Element element) {
>         return privateElementToString(element, true);
>     }
> 
>     /**
>      * turn a whole DOM document into XML
>      * @param doc DOM document
>      * @return string representation of the document, including XML 
> declaration
>      */
>     public static String DocumentToString(Document doc) {
>         return privateElementToString(doc.getDocumentElement(), false);
>     }
> 
>     public static String PrettyDocumentToString(Document doc) {
>         StringWriter sw = new StringWriter();
>         PrettyElementToWriter(doc.getDocumentElement(), sw);
>         return sw.toString();
>     }
> 
>     public static void privateElementToWriter(Element element, Writer writer,
>                                               boolean omitXMLDecl,
>                                               boolean pretty) {
>         DOM2Writer.serializeAsXML(element, writer, omitXMLDecl, pretty);
>     }
> 
>     public static void ElementToStream(Element element, OutputStream out) {
>         Writer writer = getWriter(out);
>         privateElementToWriter(element, writer, true, false);
>     }
> 
>     public static void PrettyElementToStream(Element element, OutputStream 
> out) {
>         Writer writer = getWriter(out);
>         privateElementToWriter(element, writer, true, true);
>     }
> 
>     public static void ElementToWriter(Element element, Writer writer) {
>         privateElementToWriter(element, writer, true, false);
>     }
> 
>     public static void PrettyElementToWriter(Element element, Writer writer) {
>         privateElementToWriter(element, writer, true, true);
>     }
> 
>     public static void DocumentToStream(Document doc, OutputStream out) {
>         Writer writer = getWriter(out);
>         privateElementToWriter(doc.getDocumentElement(), writer, false, 
> false);
>     }
> 
>     public static void PrettyDocumentToStream(Document doc, OutputStream out) 
> {
>         Writer writer = getWriter(out);
>         privateElementToWriter(doc.getDocumentElement(), writer, false, true);
>     }
> 
>     private static Writer getWriter(OutputStream os) {
>         Writer writer = null;
>         try {
>             writer = new OutputStreamWriter(os, "UTF-8");
>         } catch (UnsupportedEncodingException uee) {
>             log.error(Messages.getMessage("exception00"), uee);
>             writer = new OutputStreamWriter(os);
>         }
>         return writer;
>     }
> 
>     public static void DocumentToWriter(Document doc, Writer writer) {
>         privateElementToWriter(doc.getDocumentElement(), writer, false, 
> false);
>     }
> 
>     public static void PrettyDocumentToWriter(Document doc, Writer writer) {
>         privateElementToWriter(doc.getDocumentElement(), writer, false, true);
>     }
>     /**
>      * Convert a simple string to an element with a text node
>      *
>      * @param namespace - element namespace
>      * @param name - element name
>      * @param string - value of the text node
>      * @return element - an XML Element, null if no element was created
>      */
>     public static Element StringToElement(String namespace, String name, 
> String string) {
>         try {
>             Document doc = XMLUtils.newDocument();
>             Element element = doc.createElementNS(namespace, name);
>             Text text = doc.createTextNode(string);
>             element.appendChild(text);
>             return element;
>         }
>         catch (ParserConfigurationException e) {
>             // This should not occur
>             throw new InternalException(e);
>         }
>     }
> 
>     /**
>      * get the inner XML inside an element as a string. This is done by
>      * converting the XML to its string representation, then extracting the
>      * subset between beginning and end tags.
>      * @param element
>      * @return textual body of the element, or null for no inner body
>      */
>     public static String getInnerXMLString(Element element) {
>         String elementString = ElementToString(element);
>         int start, end;
>         start = elementString.indexOf(">") + 1;
>         end = elementString.lastIndexOf("</");
>         if (end > 0)
>             return elementString.substring(start,end);
>         else
>             return null;
>     }
> 
>     public static String getPrefix(String uri, Node e) {
>         while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) {
>             NamedNodeMap attrs = e.getAttributes();
>             for (int n = 0; n < attrs.getLength(); n++) {
>                 Attr a = (Attr)attrs.item(n);
>                 String name;
>                 if ((name = a.getName()).startsWith("xmlns:") &&
>                     a.getNodeValue().equals(uri)) {
>                     return name.substring(6);
>                 }
>             }
>             e = e.getParentNode();
>         }
>         return null;
>     }
> 
>     /**
>      * Searches for the namespace URI of the given prefix in the given DOM 
> range.
>      *
>      * The namespace is not searched in parent of the "stopNode". This is
>      * usefull to get all the needed namespaces when you need to ouput only a
>      * subtree of a DOM document.
>      *
>      * @param prefix the prefix to find
>      * @param e the starting node
>      * @param stopNode null to search in all the document or a parent node 
> where the search must stop.
>      * @return null if no namespace is found, or the namespace URI.
>      */
>     public static String getNamespace(String prefix, Node e, Node stopNode) {
>         while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) {
>             Attr attr = null;
>             if (prefix == null) {
>                 attr = ((Element) e).getAttributeNode("xmlns");
>             } else {
>                 attr = ((Element) 
> e).getAttributeNodeNS(Constants.NS_URI_XMLNS,
>                         prefix);
>             }
>             if (attr != null) return attr.getValue();
>             if (e == stopNode)
>                 return null;
>             e = e.getParentNode();
>         }
>         return null;
>     }
> 
>     public static String getNamespace(String prefix, Node e) {
>         return getNamespace(prefix, e, null);
>     }
> 
>     /**
>      * Return a QName when passed a string like "foo:bar" by mapping
>      * the "foo" prefix to a namespace in the context of the given Node.
>      *
>      * @return a QName generated from the given string representation
>      */
>     public static QName getQNameFromString(String str, Node e) {
>         return getQNameFromString(str, e, false);
>     }
>     /**
>      * Return a QName when passed a string like "foo:bar" by mapping
>      * the "foo" prefix to a namespace in the context of the given Node.
>      * If default namespace is found it is returned as part of the QName.
>      *
>      * @return a QName generated from the given string representation
>      */
>     public static QName getFullQNameFromString(String str, Node e) {
>         return getQNameFromString(str, e, true);
>     }
>     private static QName getQNameFromString(String str, Node e, boolean 
> defaultNS) {
>         if (str == null || e == null)
>             return null;
> 
>         int idx = str.indexOf(':');
>         if (idx > -1) {
>             String prefix = str.substring(0, idx);
>             String ns = getNamespace(prefix, e);
>             if (ns == null)
>                 return null;
>             return new QName(ns, str.substring(idx + 1));
>         } else {
>             if (defaultNS) {
>                 String ns = getNamespace(null, e);
>                 if (ns != null)
>                     return new QName(ns, str);
>             }
>             return new QName("", str);
>         }
>     }
> 
>     /**
>      * Return a string for a particular QName, mapping a new prefix
>      * if necessary.
>      */
>     public static String getStringForQName(QName qname, Element e)
>     {
>         String uri = qname.getNamespaceURI();
>         String prefix = getPrefix(uri, e);
>         if (prefix == null) {
>             int i = 1;
>             prefix = "ns" + i;
>             while (getNamespace(prefix, e) != null) {
>                 i++;
>                 prefix = "ns" + i;
>             }
>             e.setAttributeNS(Constants.NS_URI_XMLNS,
>                         "xmlns:" + prefix, uri);
>         }
>         return prefix + ":" + qname.getLocalPart();
>     }
> 
>   /**
>    * Concat all the text and cdata node children of this elem and return
>    * the resulting text.
>    * (by Matt Duftler)
>    *
>    * @param parentEl the element whose cdata/text node values are to
>    *                 be combined.
>    * @return the concatanated string.
>    */
>   public static String getChildCharacterData (Element parentEl) {
>     if (parentEl == null) {
>       return null;
>     }
>     Node          tempNode = parentEl.getFirstChild();
>     StringBuffer  strBuf   = new StringBuffer();
>     CharacterData charData;
> 
>     while (tempNode != null) {
>       switch (tempNode.getNodeType()) {
>         case Node.TEXT_NODE :
>         case Node.CDATA_SECTION_NODE : charData = (CharacterData)tempNode;
>                                        strBuf.append(charData.getData());
>                                        break;
>       }
>       tempNode = tempNode.getNextSibling();
>     }
>     return strBuf.toString();
>   }
> 
>     public static class ParserErrorHandler implements ErrorHandler
>     {
>         protected static Log log =
>             LogFactory.getLog(ParserErrorHandler.class.getName());
>         /**
>          * Returns a string describing parse exception details
>          */
>         private String getParseExceptionInfo(SAXParseException spe) {
>             String systemId = spe.getSystemId();
>             if (systemId == null) {
>                 systemId = "null";
>             }
>             String info = "URI=" + systemId +
>                 " Line=" + spe.getLineNumber() +
>                 ": " + spe.getMessage();
>             return info;
>         }
> 
>         // The following methods are standard SAX ErrorHandler methods.
>         // See SAX documentation for more info.
> 
>         public void warning(SAXParseException spe) throws SAXException {
>             if (log.isDebugEnabled())
>                 log.debug( Messages.getMessage("warning00", 
> getParseExceptionInfo(spe)));
>         }
> 
>         public void error(SAXParseException spe) throws SAXException {
>             String message = "Error: " + getParseExceptionInfo(spe);
>             throw new SAXException(message);
>         }
> 
>         public void fatalError(SAXParseException spe) throws SAXException {
>             String message = "Fatal Error: " + getParseExceptionInfo(spe);
>             throw new SAXException(message);
>         }
>     }
> 
>     /**
>      * Utility to get the bytes uri.
>      * Does NOT handle authenticated URLs,
>      * use getInputSourceFromURI(uri, username, password)
>      *
>      * @param uri the resource to get
>      * @see #getInputSourceFromURI(String uri, String username, String 
> password)
>      */
>     public static InputSource getInputSourceFromURI(String uri) {
>         return new InputSource(uri);
>     }
> 
>     /**
>      * Utility to get the bytes uri
>      *
>      * @param source the resource to get
>      */
>     public static InputSource sourceToInputSource(Source source) {
>         if (source instanceof SAXSource) {
>             return ((SAXSource) source).getInputSource();
>         } else if (source instanceof DOMSource) {
>             ByteArrayOutputStream baos = new ByteArrayOutputStream();
>             Node node = ((DOMSource)source).getNode();
>             if (node instanceof Document) {
>                 node = ((Document)node).getDocumentElement();
>             }
>             Element domElement = (Element)node;
>             ElementToStream(domElement, baos);
>             InputSource  isource = new InputSource(source.getSystemId());
>             isource.setByteStream(new 
> ByteArrayInputStream(baos.toByteArray()));
>             return isource;
>         } else if (source instanceof StreamSource) {
>             StreamSource ss      = (StreamSource) source;
>             InputSource  isource = new InputSource(ss.getSystemId());
>             isource.setByteStream(ss.getInputStream());
>             isource.setCharacterStream(ss.getReader());
>             isource.setPublicId(ss.getPublicId());
>             return isource;
>         } else {
>             return getInputSourceFromURI(source.getSystemId());
>         }
>     }
> 
>     /**
>      * Utility to get the bytes at a protected uri
>      *
>      * This will retrieve the URL if a username and password are provided.
>      * The java.net.URL class does not do Basic Authentication, so we have to
>      * do it manually in this routine.
>      *
>      * If no username is provided, we create an InputSource from the uri
>      * and let the InputSource go fetch the contents.
>      *
>      * @param uri the resource to get
>      * @param username basic auth username
>      * @param password basic auth password
>      */
>     private static InputSource getInputSourceFromURI(String uri,
>                                                      String username,
>                                                      String password)
>         throws IOException, ProtocolException, UnsupportedEncodingException
>     {
>         URL wsdlurl = null;
>         try {
>             wsdlurl = new URL(uri);
>         } catch (MalformedURLException e) {
>             // we can't process it, it might be a 'simple' foo.wsdl
>             // let InputSource deal with it
>             return new InputSource(uri);
>         }
> 
>         // if no authentication, just let InputSource deal with it
>         if (username == null && wsdlurl.getUserInfo() == null) {
>             return new InputSource(uri);
>         }
> 
>         // if this is not an HTTP{S} url, let InputSource deal with it
>         if (!wsdlurl.getProtocol().startsWith("http")) {
>             return new InputSource(uri);
>         }
> 
>         URLConnection connection = wsdlurl.openConnection();
>         // Does this work for https???
>         if (!(connection instanceof HttpURLConnection)) {
>             // can't do http with this URL, let InputSource deal with it
>             return new InputSource(uri);
>         }
>         HttpURLConnection uconn = (HttpURLConnection) connection;
>         String userinfo = wsdlurl.getUserInfo();
>         uconn.setRequestMethod("GET");
>         uconn.setAllowUserInteraction(false);
>         uconn.setDefaultUseCaches(false);
>         uconn.setDoInput(true);
>         uconn.setDoOutput(false);
>         uconn.setInstanceFollowRedirects(true);
>         uconn.setUseCaches(false);
> 
>         // username/password info in the URL overrides passed in values
>         String auth = null;
>         if (userinfo != null) {
>             auth = userinfo;
>         } else if (username != null) {
>             auth = (password == null) ? username : username + ":" + password;
>         }
> 
>         if (auth != null) {
>             uconn.setRequestProperty("Authorization",
>                                      "Basic " +
>                                      
> base64encode(auth.getBytes(httpAuthCharEncoding)));
>         }
> 
>         uconn.connect();
> 
>         return new InputSource(uconn.getInputStream());
>     }
> 
>     public static final String base64encode(byte[] bytes) {
>         return new String(Base64.encode(bytes));
>     }
> 
>     public static InputSource getEmptyInputSource() {
>         return new InputSource(bais);
>     }
> 
>     /**
>      * Find a Node with a given QName
>      *
>      * @param node parent node
>      * @param name QName of the child we need to find
>      * @return child node
>      */
>     public static Node findNode(Node node, QName name){
>         if(name.getNamespaceURI().equals(node.getNamespaceURI()) &&
>            name.getLocalPart().equals(node.getLocalName()))
>             return node;
>         NodeList children = node.getChildNodes();
>         for(int i=0;i<children.getLength();i++){
>             Node ret = findNode(children.item(i), name);
>             if(ret != null)
>                 return ret;
>         }
>         return null;
>     }
> 
>     /**
>      * Trim all new lines from text nodes.
>      *
>      * @param node
>      */
>     public static void normalize(Node node) {
>         if (node.getNodeType() == Node.TEXT_NODE) {
>             String data = ((Text) node).getData();
>             if (data.length() > 0) {
>                 char ch = data.charAt(data.length()-1);
>                  if(ch == '\n' || ch == '\r' || ch == ' ') {
>                     String data2 = trim(data);
>                     ((Text) node).setData(data2);
>                  }
>             }
>         }
>         for (Node currentChild = node.getFirstChild(); currentChild != null; 
> currentChild = currentChild.getNextSibling()) {
>             normalize(currentChild);
>         }
>     }
> 
>     public static String trim(String str) {
>         if (str.length() == 0) {
>             return str;
>         }
> 
>         if (str.length() == 1) {
>             if ("\r".equals(str) || "\n".equals(str)) {
>                 return "";
>             } else {
>                 return str;
>             }
>         }
> 
>         int lastIdx = str.length() - 1;
>         char last = str.charAt(lastIdx);
>         while(lastIdx > 0) {
>             if(last != '\n' && last != '\r' && last != ' ')
>                 break;
>             lastIdx--;
>             last = str.charAt(lastIdx);
>         }
>         if(lastIdx == 0)
>             return "";
>         return str.substring(0, lastIdx);
>     }
> 
>     /**
>      * Converts a List with org.w3c.dom.Element objects to an Array
>      * with org.w3c.dom.Element objects.
>      * @param list List containing org.w3c.dom.Element objects
>      * @return Element[] Array with org.w3c.dom.Element objects
>      */
>     public static Element[] asElementArray(List list) {
> 
>         Element[] elements = new Element[list.size()];
> 
>         int i = 0;
>         Iterator detailIter = list.iterator();
>         while (detailIter.hasNext()) {
>             elements[i++] = (Element) detailIter.next();
>         }
> 
>         return elements;
>     }
> 
>     public static String getEncoding(Message message,
>                                      MessageContext msgContext) {
>         return getEncoding(message, msgContext,
>                 XMLEncoderFactory.getDefaultEncoder());
>     }
> 
>     public static String getEncoding(Message message,
>                                      MessageContext msgContext,
>                                      XMLEncoder defaultEncoder) {
>         String encoding = null;
>         try {
>             if(message != null) {
>                 encoding = (String) 
> message.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
>             }
>         } catch (SOAPException e) {
>         }
>         if(msgContext == null) {
>             msgContext = MessageContext.getCurrentContext();
>         }
>         if(msgContext != null && encoding == null){
>             encoding = (String) 
> msgContext.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
>         }
>         if (msgContext != null && encoding == null) {
>             encoding = (String) 
> msgContext.getAxisEngine().getOption(AxisEngine.PROP_XML_ENCODING);
>         }
>         if (encoding == null && defaultEncoder != null) {
>             encoding = defaultEncoder.getEncoding();
>         }
>         return encoding;
>     }
> }
> 
> 
> 


-- 
Davanum Srinivas - http://webservices.apache.org/~dims/

Reply via email to