FileDocCategorySizeDatePackage
XMLUtils.javaAPI DocApache Axis 1.434551Sat Apr 22 18:57:26 BST 2006org.apache.axis.utils

XMLUtils

public class XMLUtils extends Object

Fields Summary
protected static Log
log
public static final String
httpAuthCharEncoding
private static final String
saxParserFactoryProperty
private static DocumentBuilderFactory
dbf
private static SAXParserFactory
saxFactory
private static Stack
saxParsers
private static DefaultHandler
doNothingContentHandler
private static String
EMPTY
private static ByteArrayInputStream
bais
private static boolean
tryReset
protected static boolean
enableParserReuse
private static ThreadLocalDocumentBuilder
documentBuilder
Constructors Summary
Methods Summary
public static voidDocumentToStream(org.w3c.dom.Document doc, java.io.OutputStream out)

        Writer writer = getWriter(out);
        privateElementToWriter(doc.getDocumentElement(), writer, false, false);
    
public static java.lang.StringDocumentToString(org.w3c.dom.Document doc)
turn a whole DOM document into XML

param
doc DOM document
return
string representation of the document, including XML declaration

        return privateElementToString(doc.getDocumentElement(), false);
    
public static voidDocumentToWriter(org.w3c.dom.Document doc, java.io.Writer writer)

        privateElementToWriter(doc.getDocumentElement(), writer, false, false);
    
public static voidElementToStream(org.w3c.dom.Element element, java.io.OutputStream out)

        Writer writer = getWriter(out);
        privateElementToWriter(element, writer, true, false);
    
public static java.lang.StringElementToString(org.w3c.dom.Element element)
turn an element into an XML fragment

param
element
return
stringified element

        return privateElementToString(element, true);
    
public static voidElementToWriter(org.w3c.dom.Element element, java.io.Writer writer)

        privateElementToWriter(element, writer, true, false);
    
public static voidPrettyDocumentToStream(org.w3c.dom.Document doc, java.io.OutputStream out)

        Writer writer = getWriter(out);
        privateElementToWriter(doc.getDocumentElement(), writer, false, true);
    
public static java.lang.StringPrettyDocumentToString(org.w3c.dom.Document doc)

        StringWriter sw = new StringWriter();
        PrettyElementToWriter(doc.getDocumentElement(), sw);
        return sw.toString();
    
public static voidPrettyDocumentToWriter(org.w3c.dom.Document doc, java.io.Writer writer)

        privateElementToWriter(doc.getDocumentElement(), writer, false, true);
    
public static voidPrettyElementToStream(org.w3c.dom.Element element, java.io.OutputStream out)

        Writer writer = getWriter(out);
        privateElementToWriter(element, writer, true, true);
    
public static voidPrettyElementToWriter(org.w3c.dom.Element element, java.io.Writer writer)

        privateElementToWriter(element, writer, true, true);
    
public static org.w3c.dom.ElementStringToElement(java.lang.String namespace, java.lang.String name, java.lang.String string)
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

        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);
        }
    
public static org.w3c.dom.Element[]asElementArray(java.util.List list)
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


        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 final java.lang.Stringbase64encode(byte[] bytes)

        return new String(Base64.encode(bytes));
    
public static org.w3c.dom.NodefindNode(org.w3c.dom.Node node, javax.xml.namespace.QName name)
Find a Node with a given QName

param
node parent node
param
name QName of the child we need to find
return
child node

        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;
    
public static java.lang.StringgetChildCharacterData(org.w3c.dom.Element parentEl)
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.

    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();
  
private static javax.xml.parsers.DocumentBuilderFactorygetDOMFactory()

        DocumentBuilderFactory dbf;
        try {
            dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
        }
        catch( Exception e ) {
            log.error(Messages.getMessage("exception00"), e );
            dbf = null;
        }
        return( dbf );
    
public static javax.xml.parsers.DocumentBuildergetDocumentBuilder()
Gets a DocumentBuilder

return
DocumentBuilder
throws
ParserConfigurationException

        return (DocumentBuilder) documentBuilder.get();
    
public static org.xml.sax.InputSourcegetEmptyInputSource()

        return new InputSource(bais);
    
public static java.lang.StringgetEncoding(org.apache.axis.MessageContext msgContext)
Get the current encoding in effect

return
string

        XMLEncoder encoder = getXMLEncoder(msgContext);
        return encoder.getEncoding();
    
public static java.lang.StringgetEncoding()
Get the current encoding in effect

return
string

        XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
        return encoder.getEncoding();
    
public static java.lang.StringgetEncoding(org.apache.axis.Message message, org.apache.axis.MessageContext msgContext)

        return getEncoding(message, msgContext,
                XMLEncoderFactory.getDefaultEncoder());
    
public static java.lang.StringgetEncoding(org.apache.axis.Message message, org.apache.axis.MessageContext msgContext, org.apache.axis.components.encoding.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 && msgContext.getAxisEngine() != null) {
            encoding = (String) msgContext.getAxisEngine().getOption(AxisEngine.PROP_XML_ENCODING);
        }
        if (encoding == null && defaultEncoder != null) {
            encoding = defaultEncoder.getEncoding();
        }
        return encoding;
    
public static javax.xml.namespace.QNamegetFullQNameFromString(java.lang.String str, org.w3c.dom.Node e)
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

        return getQNameFromString(str, e, true);
    
public static java.lang.StringgetInnerXMLString(org.w3c.dom.Element element)
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

        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 org.xml.sax.InputSourcegetInputSourceFromURI(java.lang.String uri)
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)

        return new InputSource(uri);
    
private static org.xml.sax.InputSourcegetInputSourceFromURI(java.lang.String uri, java.lang.String username, java.lang.String password)
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

        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 java.lang.StringgetNamespace(java.lang.String prefix, org.w3c.dom.Node e, org.w3c.dom.Node stopNode)
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.

        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 java.lang.StringgetNamespace(java.lang.String prefix, org.w3c.dom.Node e)

        return getNamespace(prefix, e, null);
    
public static java.lang.StringgetPrefix(java.lang.String uri, org.w3c.dom.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;
    
public static javax.xml.namespace.QNamegetQNameFromString(java.lang.String str, org.w3c.dom.Node e)
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

        return getQNameFromString(str, e, false);
    
private static javax.xml.namespace.QNamegetQNameFromString(java.lang.String str, org.w3c.dom.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);
        }
    
public static synchronized javax.xml.parsers.SAXParsergetSAXParser()
Get a SAX parser instance from the JAXP factory.

return
a SAXParser instance.

        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.
            try {
                reader.setEntityResolver(new DefaultEntityResolver());
            } catch (Throwable t) {
                log.debug("Failed to set EntityResolver on DocumentBuilder", t);
            }
            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;
        }
    
public static java.lang.StringgetStringForQName(javax.xml.namespace.QName qname, org.w3c.dom.Element e)
Return a string for a particular QName, mapping a new prefix if necessary.

        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();
    
private static java.io.WritergetWriter(java.io.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 org.apache.axis.components.encoding.XMLEncodergetXMLEncoder(org.apache.axis.MessageContext msgContext)
Get the current XMLEncoder

return
XMLEncoder

        
        return getXMLEncoder(getEncoding(null, msgContext));
    
public static org.apache.axis.components.encoding.XMLEncodergetXMLEncoder(java.lang.String encoding)
Get the XMLEncoder for specific encoding

return
XMLEncoder

        XMLEncoder encoder = null;
        try {
            encoder = XMLEncoderFactory.getEncoder(encoding);
        } catch (Exception e) {
            log.error(Messages.getMessage("exception00"), e);
            encoder = XMLEncoderFactory.getDefaultEncoder();
        }
        return encoder;
    
public static voidinitSAXFactory(java.lang.String factoryClassName, boolean namespaceAware, boolean validating)
Initialize the SAX parser factory.

param
factoryClassName The (optional) class name of the desired SAXParserFactory implementation. Will be assigned to the system property javax.xml.parsers.SAXParserFactory unless this property is already set. If null, leaves current setting alone.
param
namespaceAware true if we want a namespace-aware parser
param
validating true if we want a validating parser

        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();
    
public static org.w3c.dom.DocumentnewDocument()
Get an empty new Document

return
Document
throws
ParserConfigurationException if construction problems occur

        DocumentBuilder db = null;
        try {
            db = getDocumentBuilder();
            Document doc = db.newDocument();
            return doc;
        } finally {
            if (db != null) {
                releaseDocumentBuilder(db);
            }
        }
    
public static org.w3c.dom.DocumentnewDocument(org.xml.sax.InputSource inp)
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

        DocumentBuilder db = null;
        try {
            db = getDocumentBuilder();
            try {
                db.setEntityResolver(new DefaultEntityResolver());
            } catch (Throwable t) {
                log.debug("Failed to set EntityResolver on DocumentBuilder", t);
            }
            try {
                db.setErrorHandler(new XMLUtils.ParserErrorHandler());
            } catch (Throwable t) {
                log.debug("Failed to set ErrorHandler on DocumentBuilder", t);
            }
            Document doc = db.parse(inp);
            return doc;
        } finally {
            if (db != null) {
                releaseDocumentBuilder(db);
            }
        }
    
public static org.w3c.dom.DocumentnewDocument(java.io.InputStream inp)
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

        return XMLUtils.newDocument(new InputSource(inp));
    
public static org.w3c.dom.DocumentnewDocument(java.lang.String uri)
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

        // call the authenticated version as there might be
        // username/password info embeded in the uri.
        return XMLUtils.newDocument(uri, null, null);
    
public static org.w3c.dom.DocumentnewDocument(java.lang.String uri, java.lang.String username, java.lang.String password)
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

         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;
     
public static voidnormalize(org.w3c.dom.Node node)
Trim all new lines from text nodes.

param
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);
        }
    
private static java.lang.StringprivateElementToString(org.w3c.dom.Element element, boolean omitXMLDecl)

        return DOM2Writer.nodeToString(element, omitXMLDecl);
    
public static voidprivateElementToWriter(org.w3c.dom.Element element, java.io.Writer writer, boolean omitXMLDecl, boolean pretty)

        DOM2Writer.serializeAsXML(element, writer, omitXMLDecl, pretty);
    
public static voidreleaseDocumentBuilder(javax.xml.parsers.DocumentBuilder db)
Releases a DocumentBuilder

param
db

        try {
            db.setErrorHandler(null); // setting implementation default
        } catch (Throwable t) {
            log.debug("Failed to set ErrorHandler to null on DocumentBuilder",
                    t);
        }
        try {
            db.setEntityResolver(null); // setting implementation default
        } catch (Throwable t) {
            log.debug("Failed to set EntityResolver to null on DocumentBuilder",
                    t);
        }
    
public static voidreleaseSAXParser(javax.xml.parsers.SAXParser parser)
Return a SAX parser for reuse.

param
parser A SAX parser that is available for reuse

        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);
                try {
                    xmlReader.setEntityResolver(doNothingContentHandler);
                } catch (Throwable t) {
                    log.debug("Failed to set EntityResolver on DocumentBuilder", t);
                }
                try {
                    xmlReader.setErrorHandler(doNothingContentHandler);
                } catch (Throwable t) {
                    log.debug("Failed to set ErrorHandler on DocumentBuilder", t);
                }

                synchronized (XMLUtils.class ) {
                    saxParsers.push(parser);
                }
            }
            else {
                tryReset= false;
            }
        } catch (org.xml.sax.SAXException e) {
            tryReset= false;
        }
    
public static org.xml.sax.InputSourcesourceToInputSource(javax.xml.transform.Source source)
Utility to get the bytes uri

param
source the resource to get

        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());
        }
    
public static java.lang.Stringtrim(java.lang.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);
    
public static java.lang.StringxmlEncodeString(java.lang.String orig)
Encode a string appropriately for XML.

param
orig the String to encode
return
a String in which XML special chars are repalced by entities

 
    
     
        // Initialize SAX Parser factory defaults
        initSAXFactory(null, true, false);

        String value = AxisProperties.getProperty(AxisEngine.PROP_XML_REUSE_SAX_PARSERS,
                "" + true);
        if (value.equalsIgnoreCase("true") ||
                value.equals("1") ||
                value.equalsIgnoreCase("yes")) {
            enableParserReuse = true;
        } else {
            enableParserReuse = false;
        }
    
        XMLEncoder encoder = getXMLEncoder(MessageContext.getCurrentContext());
        return encoder.encode(orig);