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