org.apache.cxf.helpers.XMLUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-minimal Show documentation
Show all versions of cxf-bundle-minimal Show documentation
Apache CXF Minimal Bundle Jar
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cxf.helpers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
public final class XMLUtils {
private static final Logger LOG = LogUtils.getL7dLogger(XMLUtils.class);
private static final Map DOCUMENT_BUILDER_FACTORIES
= Collections.synchronizedMap(new WeakHashMap());
private static final Map TRANSFORMER_FACTORIES
= Collections.synchronizedMap(new WeakHashMap());
private static final Pattern XML_ESCAPE_CHARS = Pattern.compile("[\"'&<>]");
private static final Map XML_ENCODING_TABLE;
static {
XML_ENCODING_TABLE = new HashMap();
XML_ENCODING_TABLE.put("\"", """);
XML_ENCODING_TABLE.put("'", "'");
XML_ENCODING_TABLE.put("<", "<");
XML_ENCODING_TABLE.put(">", ">");
XML_ENCODING_TABLE.put("&", "&");
}
private XMLUtils() {
}
private static TransformerFactory getTransformerFactory() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = XMLUtils.class.getClassLoader();
}
if (loader == null) {
return TransformerFactory.newInstance();
}
TransformerFactory factory = TRANSFORMER_FACTORIES.get(loader);
if (factory == null) {
factory = TransformerFactory.newInstance();
TRANSFORMER_FACTORIES.put(loader, factory);
}
return factory;
}
private static DocumentBuilderFactory getDocumentBuilderFactory() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = XMLUtils.class.getClassLoader();
}
if (loader == null) {
return DocumentBuilderFactory.newInstance();
}
DocumentBuilderFactory factory = DOCUMENT_BUILDER_FACTORIES.get(loader);
if (factory == null) {
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DOCUMENT_BUILDER_FACTORIES.put(loader, factory);
}
return factory;
}
public static Transformer newTransformer() throws TransformerConfigurationException {
return getTransformerFactory().newTransformer();
}
public static Transformer newTransformer(int indent) throws TransformerConfigurationException {
if (indent > 0) {
TransformerFactory f = TransformerFactory.newInstance();
try {
//sun way of setting indent
f.setAttribute("indent-number", Integer.toString(indent));
} catch (Throwable t) {
//ignore
}
return f.newTransformer();
}
return getTransformerFactory().newTransformer();
}
public static DocumentBuilder getParser() throws ParserConfigurationException {
return getDocumentBuilderFactory().newDocumentBuilder();
}
public static Document parse(InputSource is) throws ParserConfigurationException, SAXException,
IOException {
return getParser().parse(is);
}
public static Document parse(File is) throws ParserConfigurationException, SAXException,
IOException {
return getParser().parse(is);
}
public static Document parse(InputStream in) throws ParserConfigurationException, SAXException,
IOException {
if (in == null && LOG.isLoggable(Level.FINE)) {
LOG.fine("XMLUtils trying to parse a null inputstream");
}
return getParser().parse(in);
}
public static Document parse(String in) throws ParserConfigurationException, SAXException, IOException {
return parse(in.getBytes());
}
public static Document parse(byte[] in) throws ParserConfigurationException, SAXException, IOException {
if (in == null) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("XMLUtils trying to parse a null bytes");
}
return null;
}
return getParser().parse(new ByteArrayInputStream(in));
}
public static Document newDocument() throws ParserConfigurationException {
return getParser().newDocument();
}
public static void writeTo(Node node, OutputStream os) {
writeTo(new DOMSource(node), os);
}
public static void writeTo(Node node, OutputStream os, int indent) {
writeTo(new DOMSource(node), os, indent);
}
public static void writeTo(Source src, OutputStream os) {
writeTo(src, os, -1);
}
public static void writeTo(Node node, Writer os) {
writeTo(new DOMSource(node), os);
}
public static void writeTo(Node node, Writer os, int indent) {
writeTo(new DOMSource(node), os, indent);
}
public static void writeTo(Source src, Writer os) {
writeTo(src, os, -1);
}
public static void writeTo(Source src, OutputStream os, int indent) {
String enc = null;
if (src instanceof DOMSource
&& ((DOMSource)src).getNode() instanceof Document) {
try {
enc = ((Document)((DOMSource)src).getNode()).getXmlEncoding();
} catch (Exception ex) {
//ignore - not DOM level 3
}
}
writeTo(src, os, indent, enc, "no");
}
public static void writeTo(Source src, Writer os, int indent) {
String enc = null;
if (src instanceof DOMSource
&& ((DOMSource)src).getNode() instanceof Document) {
try {
enc = ((Document)((DOMSource)src).getNode()).getXmlEncoding();
} catch (Exception ex) {
//ignore - not DOM level 3
}
}
writeTo(src, os, indent, enc, "no");
}
public static void writeTo(Source src,
OutputStream os,
int indent,
String charset,
String omitXmlDecl) {
Transformer it;
try {
if (StringUtils.isEmpty(charset)) {
charset = "utf-8";
}
it = newTransformer(indent);
it.setOutputProperty(OutputKeys.METHOD, "xml");
if (indent > -1) {
it.setOutputProperty(OutputKeys.INDENT, "yes");
it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
Integer.toString(indent));
}
it.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omitXmlDecl);
it.setOutputProperty(OutputKeys.ENCODING, charset);
it.transform(src, new StreamResult(os));
} catch (TransformerException e) {
throw new RuntimeException("Failed to configure TRaX", e);
}
}
public static void writeTo(Source src,
Writer os,
int indent,
String charset,
String omitXmlDecl) {
Transformer it;
try {
if (StringUtils.isEmpty(charset)) {
charset = "utf-8";
}
it = newTransformer(indent);
it.setOutputProperty(OutputKeys.METHOD, "xml");
if (indent > -1) {
it.setOutputProperty(OutputKeys.INDENT, "yes");
it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
Integer.toString(indent));
}
it.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omitXmlDecl);
it.setOutputProperty(OutputKeys.ENCODING, charset);
it.transform(src, new StreamResult(os));
} catch (TransformerException e) {
throw new RuntimeException("Failed to configure TRaX", e);
}
}
public static String toString(Source source) throws TransformerException, IOException {
return toString(source, null);
}
public static String toString(Source source, Properties props) throws TransformerException, IOException {
StringWriter bos = new StringWriter();
StreamResult sr = new StreamResult(bos);
Transformer trans = newTransformer();
if (props == null) {
props = new Properties();
props.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
}
trans.setOutputProperties(props);
trans.transform(source, sr);
bos.close();
return bos.toString();
}
public static String toString(Node node, int indent) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeTo(node, out, indent);
return out.toString();
}
public static String toString(Node node) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeTo(node, out);
return out.toString();
}
public static void printDOM(Node node) {
printDOM("", node);
}
public static void printDOM(String words, Node node) {
System.out.println(words);
System.out.println(toString(node));
}
public static Attr getAttribute(Element el, String attrName) {
return el.getAttributeNode(attrName);
}
public static void replaceAttribute(Element element, String attr, String value) {
if (element.hasAttribute(attr)) {
element.removeAttribute(attr);
}
element.setAttribute(attr, value);
}
public static boolean hasAttribute(Element element, String value) {
NamedNodeMap attributes = element.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
if (value.equals(node.getNodeValue())) {
return true;
}
}
return false;
}
public static void printAttributes(Element element) {
NamedNodeMap attributes = element.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
System.err.println("## prefix=" + node.getPrefix() + " localname:" + node.getLocalName()
+ " value=" + node.getNodeValue());
}
}
public static QName getNamespace(Map namespaces, String str, String defaultNamespace) {
String prefix = null;
String localName = null;
StringTokenizer tokenizer = new StringTokenizer(str, ":");
if (tokenizer.countTokens() == 2) {
prefix = tokenizer.nextToken();
localName = tokenizer.nextToken();
} else if (tokenizer.countTokens() == 1) {
localName = tokenizer.nextToken();
}
String namespceURI = defaultNamespace;
if (prefix != null) {
namespceURI = namespaces.get(prefix);
}
return new QName(namespceURI, localName);
}
public static void generateXMLFile(Element element, Writer writer) {
try {
Transformer it = newTransformer();
it.setOutputProperty(OutputKeys.METHOD, "xml");
it.setOutputProperty(OutputKeys.INDENT, "yes");
it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
it.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
it.transform(new DOMSource(element), new StreamResult(writer));
} catch (Exception e) {
e.printStackTrace();
}
}
public static Element createElementNS(Node node, QName name) {
return createElementNS(node.getOwnerDocument(), name.getNamespaceURI(), name.getLocalPart());
}
public static Element createElementNS(Document root, QName name) {
return createElementNS(root, name.getNamespaceURI(), name.getLocalPart());
}
public static Element createElementNS(Document root, String namespaceURI, String qualifiedName) {
return root.createElementNS(namespaceURI, qualifiedName);
}
public static Text createTextNode(Document root, String data) {
return root.createTextNode(data);
}
public static Text createTextNode(Node node, String data) {
return createTextNode(node.getOwnerDocument(), data);
}
public static void removeContents(Node parent) {
Node node = parent.getFirstChild();
while (node != null) {
parent.removeChild(node);
node = node.getNextSibling();
}
}
public static InputStream getInputStream(Document doc) throws Exception {
DOMImplementationLS impl = null;
DOMImplementation docImpl = doc.getImplementation();
// Try to get the DOMImplementation from doc first before
// defaulting to the sun implementation.
if (docImpl != null && docImpl.hasFeature("LS", "3.0")) {
impl = (DOMImplementationLS)docImpl.getFeature("LS", "3.0");
} else {
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
impl = (DOMImplementationLS)registry.getDOMImplementation("LS");
if (impl == null) {
System.setProperty(DOMImplementationRegistry.PROPERTY,
"com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");
registry = DOMImplementationRegistry.newInstance();
impl = (DOMImplementationLS)registry.getDOMImplementation("LS");
}
}
LSOutput output = impl.createLSOutput();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
output.setByteStream(byteArrayOutputStream);
LSSerializer writer = impl.createLSSerializer();
writer.write(doc, output);
byte[] buf = byteArrayOutputStream.toByteArray();
return new ByteArrayInputStream(buf);
}
public static Element fetchElementByNameAttribute(Element parent, String targetName, String nameValue) {
List elemList = DOMUtils.findAllElementsByTagName(parent, targetName);
for (Element elem : elemList) {
if (elem.getAttribute("name").equals(nameValue)) {
return elem;
}
}
return null;
}
public static QName getQName(String value, Node node) {
if (value == null) {
return null;
}
int index = value.indexOf(":");
if (index == -1) {
return new QName(value);
}
String prefix = value.substring(0, index);
String localName = value.substring(index + 1);
String ns = node.lookupNamespaceURI(prefix);
if (ns == null || localName == null) {
throw new RuntimeException("Invalid QName in mapping: " + value);
}
return new QName(ns, localName, prefix);
}
public static Node fromSource(Source src) throws Exception {
Transformer trans = TransformerFactory.newInstance().newTransformer();
DOMResult res = new DOMResult();
trans.transform(src, res);
return res.getNode();
}
public static QName convertStringToQName(String expandedQName) {
return convertStringToQName(expandedQName, "");
}
public static QName convertStringToQName(String expandedQName, String prefix) {
int ind1 = expandedQName.indexOf('{');
if (ind1 != 0) {
return new QName(expandedQName);
}
int ind2 = expandedQName.indexOf('}');
if (ind2 <= ind1 + 1 || ind2 >= expandedQName.length() - 1) {
return null;
}
String ns = expandedQName.substring(ind1 + 1, ind2);
String localName = expandedQName.substring(ind2 + 1);
return new QName(ns, localName, prefix);
}
public static Set convertStringsToQNames(List expandedQNames) {
Set dropElements = Collections.emptySet();
if (expandedQNames != null) {
dropElements = new LinkedHashSet(expandedQNames.size());
for (String val : expandedQNames) {
dropElements.add(XMLUtils.convertStringToQName(val));
}
}
return dropElements;
}
public static String xmlEncode(String value) {
Matcher m = XML_ESCAPE_CHARS.matcher(value);
boolean match = m.find();
if (match) {
int i = 0;
StringBuilder sb = new StringBuilder();
do {
String replacement = XML_ENCODING_TABLE.get(m.group());
sb.append(value.substring(i, m.start()));
sb.append(replacement);
i = m.end();
} while (m.find());
sb.append(value.substring(i, value.length()));
return sb.toString();
} else {
return value;
}
}
}