From e5b7380c874745c989d1816b8f552504f038e1bc Mon Sep 17 00:00:00 2001 From: lresende Date: Thu, 26 Sep 2013 20:33:20 +0000 Subject: 2.0 branch for possible maintenance release git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1526672 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany/sca/common/xml/dom/DOMHelper.java | 302 +++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 sca-java-2.x/branches/2.0/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java (limited to 'sca-java-2.x/branches/2.0/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java') diff --git a/sca-java-2.x/branches/2.0/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java b/sca-java-2.x/branches/2.0/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java new file mode 100644 index 0000000000..c5e7015364 --- /dev/null +++ b/sca-java-2.x/branches/2.0/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java @@ -0,0 +1,302 @@ +/* + * 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.tuscany.sca.common.xml.dom; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +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.sax.SAXResult; +import javax.xml.transform.stream.StreamResult; + +import org.apache.tuscany.sca.common.xml.dom.impl.SAX2DOMAdapter; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.LifeCycleListener; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.ext.LexicalHandler; + +/** + * Helper for DOM + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public class DOMHelper implements LifeCycleListener { + protected static final int INITIAL_POOL_SIZE = 8; + protected static final int MAX_POOL_SIZE = 64; + private DocumentBuilderFactory documentBuilderFactory; + private TransformerFactory transformerFactory; + protected ParserPool builderPool; + protected ParserPool transformerPool; + + public static DOMHelper getInstance(ExtensionPointRegistry registry) { + UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); + return utilities.getUtility(DOMHelper.class); + } + + public DOMHelper(ExtensionPointRegistry registry) { + FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class); + documentBuilderFactory = factories.getFactory(DocumentBuilderFactory.class); + documentBuilderFactory.setNamespaceAware(true); + transformerFactory = factories.getFactory(TransformerFactory.class); + } + + /** + * @param documentBuilderFactory + * @param transformerFactory + */ + public DOMHelper(DocumentBuilderFactory documentBuilderFactory, TransformerFactory transformerFactory) { + super(); + this.documentBuilderFactory = documentBuilderFactory; + this.transformerFactory = transformerFactory; + } + + public Document newDocument() { + DocumentBuilder builder = newDocumentBuilder(); + try { + return builder.newDocument(); + } finally { + returnDocumentBuilder(builder); + } + + } + + public DocumentBuilder newDocumentBuilder() { + return builderPool.borrowFromPool(); + } + + public void returnDocumentBuilder(DocumentBuilder builder) { + builderPool.returnToPool(builder); + } + + private DocumentBuilder createDocumentBuilder() { + try { + return documentBuilderFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public Document load(String xmlString) throws IOException, SAXException { + DocumentBuilder builder = newDocumentBuilder(); + try { + InputSource is = new InputSource(new StringReader(xmlString)); + return builder.parse(is); + } finally { + returnDocumentBuilder(builder); + } + } + + public Document load(Source source) { + Transformer transformer = newTransformer(); + DOMResult result = new DOMResult(newDocument()); + try { + transformer.transform(source, result); + } catch (TransformerException e) { + throw new IllegalArgumentException(e); + } finally { + transformerPool.returnToPool(transformer); + } + return (Document)result.getNode(); + } + + public NodeContentHandler createContentHandler(Node root) { + if (root == null) { + root = newDocument(); + } + return new SAX2DOMAdapter(root); + } + + public String saveAsString(Node node) { + Transformer transformer = newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult result = new StreamResult(sw); + try { + transformer.transform(new DOMSource(node), result); + } catch (TransformerException e) { + throw new IllegalArgumentException(e); + } finally { + returnTransformer(transformer); + } + return result.getWriter().toString(); + } + + public Transformer newTransformer() { + return transformerPool.borrowFromPool(); + } + + public void returnTransformer(Transformer transformer) { + transformerPool.returnToPool(transformer); + } + + private Transformer createTransformer() { + Transformer transformer = null; + try { + transformer = transformerFactory.newTransformer(); + } catch (TransformerConfigurationException e) { + throw new IllegalArgumentException(e); + } + return transformer; + } + + public void saveAsSAX(Node node, ContentHandler contentHandler) { + Transformer transformer = transformerPool.borrowFromPool(); + SAXResult result = new SAXResult(contentHandler); + try { + transformer.transform(new DOMSource(node), result); + } catch (TransformerException e) { + throw new IllegalArgumentException(e); + } finally { + returnTransformer(transformer); + } + } + + public static QName getQName(Node node) { + String ns = node.getNamespaceURI(); + String prefix = node.getPrefix(); + String localName = node.getLocalName(); + if (localName == null) { + localName = node.getNodeName(); + } + if (ns == null) { + ns = ""; + } + if (prefix == null) { + prefix = ""; + } + return new QName(ns, localName, prefix); + } + + public static Element createElement(Document document, QName name) { + String prefix = name.getPrefix(); + String qname = + (prefix != null && prefix.length() > 0) ? prefix + ":" + name.getLocalPart() : name.getLocalPart(); + return document.createElementNS(name.getNamespaceURI(), qname); + } + + /** + * Wrap an element as a DOM document + * @param node + * @return + */ + public static Document promote(Node node) { + if (node instanceof Document) { + return (Document)node; + } + Element element = (Element)node; + Document doc = element.getOwnerDocument(); + if (doc.getDocumentElement() == element) { + return doc; + } + doc = (Document)element.getOwnerDocument().cloneNode(false); + Element schema = (Element)doc.importNode(element, true); + doc.appendChild(schema); + Node parent = element.getParentNode(); + while (parent instanceof Element) { + Element root = (Element)parent; + NamedNodeMap nodeMap = root.getAttributes(); + for (int i = 0; i < nodeMap.getLength(); i++) { + Attr attr = (Attr)nodeMap.item(i); + String name = attr.getName(); + if ("xmlns".equals(name) || name.startsWith("xmlns:")) { + if (schema.getAttributeNode(name) == null) { + schema.setAttributeNodeNS((Attr)doc.importNode(attr, true)); + } + } + } + parent = parent.getParentNode(); + } + return doc; + } + + public static String getPrefix(Element element, String namespace) { + if (element.isDefaultNamespace(namespace)) { + return XMLConstants.DEFAULT_NS_PREFIX; + } + return element.lookupPrefix(namespace); + } + + public static String getNamespaceURI(Element element, String prefix) { + if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + prefix = null; + } + return element.lookupNamespaceURI(prefix); + } + + public static interface NodeContentHandler extends ContentHandler, LexicalHandler { + Node getNode(); + } + + @Override + public void start() { + builderPool = new ParserPool(MAX_POOL_SIZE, INITIAL_POOL_SIZE) { + + @Override + protected DocumentBuilder newInstance() { + return createDocumentBuilder(); + } + + @Override + protected void resetInstance(DocumentBuilder obj) { + obj.reset(); + } + }; + + transformerPool = new ParserPool(64, 8) { + + @Override + protected Transformer newInstance() { + return createTransformer(); + } + + @Override + protected void resetInstance(Transformer obj) { + obj.reset(); + } + }; + } + + @Override + public void stop() { + builderPool.clear(); + transformerPool.clear(); + } + +} -- cgit v1.2.3