diff -r 88b85470e72c -r f50545b5e2f1 src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Tue Mar 06 16:09:35 2012 -0800 @@ -0,0 +1,340 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.util.xml; + +import com.sun.istack.internal.Nullable; +import com.sun.org.apache.xml.internal.resolver.Catalog; +import com.sun.org.apache.xml.internal.resolver.CatalogManager; +import com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver; +import com.sun.xml.internal.ws.server.ServerRtException; +import com.sun.xml.internal.ws.util.ByteArrayBuffer; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.EntityReference; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.InputSource; + +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamSource; +import javax.xml.ws.WebServiceException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +/** + * @author WS Development Team + */ +public class XmlUtil { + private final static String LEXICAL_HANDLER_PROPERTY = + "http://xml.org/sax/properties/lexical-handler"; + + public static String getPrefix(String s) { + int i = s.indexOf(':'); + if (i == -1) + return null; + return s.substring(0, i); + } + + public static String getLocalPart(String s) { + int i = s.indexOf(':'); + if (i == -1) + return s; + return s.substring(i + 1); + } + + + + public static String getAttributeOrNull(Element e, String name) { + Attr a = e.getAttributeNode(name); + if (a == null) + return null; + return a.getValue(); + } + + public static String getAttributeNSOrNull( + Element e, + String name, + String nsURI) { + Attr a = e.getAttributeNodeNS(nsURI, name); + if (a == null) + return null; + return a.getValue(); + } + + public static String getAttributeNSOrNull( + Element e, + QName name) { + Attr a = e.getAttributeNodeNS(name.getNamespaceURI(), name.getLocalPart()); + if (a == null) + return null; + return a.getValue(); + } + +/* public static boolean matchesTagNS(Element e, String tag, String nsURI) { + try { + return e.getLocalName().equals(tag) + && e.getNamespaceURI().equals(nsURI); + } catch (NullPointerException npe) { + + // localname not null since parsing would fail before here + throw new WSDLParseException( + "null.namespace.found", + e.getLocalName()); + } + } + + public static boolean matchesTagNS( + Element e, + javax.xml.namespace.QName name) { + try { + return e.getLocalName().equals(name.getLocalPart()) + && e.getNamespaceURI().equals(name.getNamespaceURI()); + } catch (NullPointerException npe) { + + // localname not null since parsing would fail before here + throw new WSDLParseException( + "null.namespace.found", + e.getLocalName()); + } + }*/ + + public static Iterator getAllChildren(Element element) { + return new NodeListIterator(element.getChildNodes()); + } + + public static Iterator getAllAttributes(Element element) { + return new NamedNodeMapIterator(element.getAttributes()); + } + + public static List parseTokenList(String tokenList) { + List result = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(tokenList, " "); + while (tokenizer.hasMoreTokens()) { + result.add(tokenizer.nextToken()); + } + return result; + } + + public static String getTextForNode(Node node) { + StringBuffer sb = new StringBuffer(); + + NodeList children = node.getChildNodes(); + if (children.getLength() == 0) + return null; + + for (int i = 0; i < children.getLength(); ++i) { + Node n = children.item(i); + + if (n instanceof Text) + sb.append(n.getNodeValue()); + else if (n instanceof EntityReference) { + String s = getTextForNode(n); + if (s == null) + return null; + else + sb.append(s); + } else + return null; + } + + return sb.toString(); + } + + public static InputStream getUTF8Stream(String s) { + try { + ByteArrayBuffer bab = new ByteArrayBuffer(); + Writer w = new OutputStreamWriter(bab, "utf-8"); + w.write(s); + w.close(); + return bab.newInputStream(); + } catch (IOException e) { + throw new RuntimeException("should not happen"); + } + } + + static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + static final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + + static { + saxParserFactory.setNamespaceAware(true); + } + + /** + * Creates a new identity transformer. + */ + public static Transformer newTransformer() { + try { + return transformerFactory.newTransformer(); + } catch (TransformerConfigurationException tex) { + throw new IllegalStateException("Unable to create a JAXP transformer"); + } + } + + /** + * Performs identity transformation. + */ + public static + T identityTransform(Source src, T result) throws TransformerException, SAXException, ParserConfigurationException, IOException { + if (src instanceof StreamSource) { + // work around a bug in JAXP in JDK6u4 and earlier where the namespace processing + // is not turned on by default + StreamSource ssrc = (StreamSource) src; + TransformerHandler th = ((SAXTransformerFactory) transformerFactory).newTransformerHandler(); + th.setResult(result); + XMLReader reader = saxParserFactory.newSAXParser().getXMLReader(); + reader.setContentHandler(th); + reader.setProperty(LEXICAL_HANDLER_PROPERTY, th); + reader.parse(toInputSource(ssrc)); + } else { + newTransformer().transform(src, result); + } + return result; + } + + private static InputSource toInputSource(StreamSource src) { + InputSource is = new InputSource(); + is.setByteStream(src.getInputStream()); + is.setCharacterStream(src.getReader()); + is.setPublicId(src.getPublicId()); + is.setSystemId(src.getSystemId()); + return is; + } + + /* + * Gets an EntityResolver using XML catalog + */ + public static EntityResolver createEntityResolver(@Nullable URL catalogUrl) { + // set up a manager + CatalogManager manager = new CatalogManager(); + manager.setIgnoreMissingProperties(true); + // Using static catalog may result in to sharing of the catalog by multiple apps running in a container + manager.setUseStaticCatalog(false); + Catalog catalog = manager.getCatalog(); + try { + if (catalogUrl != null) { + catalog.parseCatalog(catalogUrl); + } + } catch (IOException e) { + throw new ServerRtException("server.rt.err",e); + } + return workaroundCatalogResolver(catalog); + } + + /** + * Gets a default EntityResolver for catalog at META-INF/jaxws-catalog.xml + */ + public static EntityResolver createDefaultCatalogResolver() { + + // set up a manager + CatalogManager manager = new CatalogManager(); + manager.setIgnoreMissingProperties(true); + // Using static catalog may result in to sharing of the catalog by multiple apps running in a container + manager.setUseStaticCatalog(false); + // parse the catalog + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Enumeration catalogEnum; + Catalog catalog = manager.getCatalog(); + try { + if (cl == null) { + catalogEnum = ClassLoader.getSystemResources("META-INF/jax-ws-catalog.xml"); + } else { + catalogEnum = cl.getResources("META-INF/jax-ws-catalog.xml"); + } + + while(catalogEnum.hasMoreElements()) { + URL url = catalogEnum.nextElement(); + catalog.parseCatalog(url); + } + } catch (IOException e) { + throw new WebServiceException(e); + } + + return workaroundCatalogResolver(catalog); + } + + /** + * Default CatalogResolver implementation is broken as it depends on CatalogManager.getCatalog() which will always create a new one when + * useStaticCatalog is false. + * This returns a CatalogResolver that uses the catalog passed as parameter. + * @param catalog + * @return CatalogResolver + */ + private static CatalogResolver workaroundCatalogResolver(final Catalog catalog) { + // set up a manager + CatalogManager manager = new CatalogManager() { + @Override + public Catalog getCatalog() { + return catalog; + } + }; + manager.setIgnoreMissingProperties(true); + // Using static catalog may result in to sharing of the catalog by multiple apps running in a container + manager.setUseStaticCatalog(false); + + return new CatalogResolver(manager); + } + + /** + * {@link ErrorHandler} that always treat the error as fatal. + */ + public static final ErrorHandler DRACONIAN_ERROR_HANDLER = new ErrorHandler() { + public void warning(SAXParseException exception) { + } + + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + }; +}