From 6bb92d330a2fe58f8cc6bbd98005b072aa67dca0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 27 Nov 2003 12:00:57 +0000 Subject: [PATCH] Add a helper class for tasks that want literal XML as input git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275702 13f79535-47bb-0310-9956-ffa450edef68 --- src/etc/testcases/types/xmlfragment.xml | 14 ++ .../org/apache/tools/ant/util/JAXPUtils.java | 42 +++++ .../apache/tools/ant/util/XMLFragment.java | 170 ++++++++++++++++++ .../tools/ant/util/XMLFragmentTest.java | 118 ++++++++++++ 4 files changed, 344 insertions(+) create mode 100644 src/etc/testcases/types/xmlfragment.xml create mode 100644 src/main/org/apache/tools/ant/util/XMLFragment.java create mode 100644 src/testcases/org/apache/tools/ant/util/XMLFragmentTest.java diff --git a/src/etc/testcases/types/xmlfragment.xml b/src/etc/testcases/types/xmlfragment.xml new file mode 100644 index 000000000..cf1e3559c --- /dev/null +++ b/src/etc/testcases/types/xmlfragment.xml @@ -0,0 +1,14 @@ + + + + foo + + + foo + + + + + + diff --git a/src/main/org/apache/tools/ant/util/JAXPUtils.java b/src/main/org/apache/tools/ant/util/JAXPUtils.java index 033ade3bf..e4f6f8c87 100644 --- a/src/main/org/apache/tools/ant/util/JAXPUtils.java +++ b/src/main/org/apache/tools/ant/util/JAXPUtils.java @@ -54,6 +54,8 @@ package org.apache.tools.ant.util; import java.io.File; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; @@ -97,6 +99,12 @@ public class JAXPUtils { */ private static SAXParserFactory nsParserFactory = null; + /** + * Parser factory to use to create document builders. + * + * @since Ant 1.7 + */ + private static DocumentBuilderFactory builderFactory = null; /** * Returns the parser factory to use. Only one parser factory is @@ -209,6 +217,20 @@ public class JAXPUtils { return fu.toURI(file.getAbsolutePath()); } + /** + * Returns a newly created DocumentBuilder. + * + * @return a DocumentVuilder + * @since Ant 1.7 + */ + public static DocumentBuilder getDocumentBuilder() throws BuildException { + try { + return getDocumentBuilderFactory().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new BuildException(e); + } + } + /** * @return a new SAXParser instance as helper for getParser and * getXMLReader. @@ -241,4 +263,24 @@ public class JAXPUtils { } } + /** + * Obtains the default builder factory if not already. + * + * @since Ant 1.7 + */ + private static synchronized + DocumentBuilderFactory getDocumentBuilderFactory() + throws BuildException { + if (builderFactory == null) { + try { + builderFactory = DocumentBuilderFactory.newInstance(); + } catch (FactoryConfigurationError e) { + throw new BuildException("Document builder factory has not " + + "been configured correctly: " + + e.getMessage(), e); + } + } + return builderFactory; + } + } diff --git a/src/main/org/apache/tools/ant/util/XMLFragment.java b/src/main/org/apache/tools/ant/util/XMLFragment.java new file mode 100644 index 000000000..e738e937a --- /dev/null +++ b/src/main/org/apache/tools/ant/util/XMLFragment.java @@ -0,0 +1,170 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Ant" and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.util; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.Text; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DynamicConfigurator; +import org.apache.tools.ant.ProjectHelper; + +/** + * Use this class as a nested element if you want to get a literal DOM + * fragment of something nested into your task/type. + * + *

This is useful for tasks that want to deal with the "real" XML + * from the build file instead of objects.

+ * + *

Code heavily influenced by code written by Dominique Devienne.

+ * + * @since Ant 1.7 + */ +public class XMLFragment implements DynamicConfigurator { + + private Document doc; + private DocumentFragment fragment; + + public XMLFragment() { + doc = JAXPUtils.getDocumentBuilder().newDocument(); + fragment = doc.createDocumentFragment(); + } + + /** + * Return the DocumentFragment that corresponds to the nested + * structure. + */ + public DocumentFragment getFragment() { + return fragment; + } + + /** + * Add nested text. + */ + public void addText(String s) { + addText(fragment, s); + } + + /** + * No attributes for the wrapping element. + */ + public void setDynamicAttribute(String name, String value) + throws BuildException { + throw new BuildException("Attribute " + name + " is not supported."); + } + + /** + * Creates a nested element. + */ + public Object createDynamicElement(String name) { + /* I don't get the namespace prefix here + Element e = doc + .createElementNS(ProjectHelper.extractUriFromComponentName(name), + ProjectHelper.extractNameFromComponentName(name)); + */ + Element e = doc.createElement(name); + fragment.appendChild(e); + return new Child(e); + } + + private void addText(Node n, String s) { + if (s != null && !s.trim().equals("")) { + Text t = doc.createTextNode(s); + n.appendChild(t); + } + } + + public class Child implements DynamicConfigurator { + private Element e; + + Child(Element e) { + this.e = e; + } + + /** + * Add nested text. + */ + public void addText(String s) { + XMLFragment.this.addText(e, s); + } + + /** + * Sets the attribute + */ + public void setDynamicAttribute(String name, String value) { + e.setAttribute(name, value); + } + + /** + * Creates a nested element. + */ + public Object createDynamicElement(String name) { + /* + Element e2 = doc + .createElementNS(ProjectHelper + .extractUriFromComponentName(name), + ProjectHelper + .extractNameFromComponentName(name)); + */ + Element e2 = doc.createElement(name); + e.appendChild(e2); + return new Child(e2); + } + } + +} diff --git a/src/testcases/org/apache/tools/ant/util/XMLFragmentTest.java b/src/testcases/org/apache/tools/ant/util/XMLFragmentTest.java new file mode 100644 index 000000000..67e952294 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/util/XMLFragmentTest.java @@ -0,0 +1,118 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Ant" and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.util; + +import org.apache.tools.ant.BuildFileTest; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class XMLFragmentTest extends BuildFileTest { + + public XMLFragmentTest(String name) { + super(name); + } + + public void setUp() { + configureProject("src/etc/testcases/types/xmlfragment.xml"); + } + + public void testNestedText() { + XMLFragment x = (XMLFragment) getProject().getReference("nested-text"); + assertNotNull(x); + Node n = x.getFragment(); + assertTrue("No attributes", !n.hasAttributes()); + NodeList nl = n.getChildNodes(); + assertEquals(1, nl.getLength()); + assertEquals(Node.TEXT_NODE, nl.item(0).getNodeType()); + assertEquals("foo", nl.item(0).getNodeValue()); + } + + public void testNestedChildren() { + XMLFragment x = + (XMLFragment) getProject().getReference("with-children"); + assertNotNull(x); + Node n = x.getFragment(); + assertTrue("No attributes", !n.hasAttributes()); + NodeList nl = n.getChildNodes(); + assertEquals(3, nl.getLength()); + + assertEquals(Node.ELEMENT_NODE, nl.item(0).getNodeType()); + Element child1 = (Element) nl.item(0); + assertEquals("child1", child1.getTagName()); + assertTrue(!child1.hasAttributes()); + NodeList nl2 = child1.getChildNodes(); + assertEquals(1, nl2.getLength()); + assertEquals(Node.TEXT_NODE, nl2.item(0).getNodeType()); + assertEquals("foo", nl2.item(0).getNodeValue()); + + assertEquals(Node.ELEMENT_NODE, nl.item(1).getNodeType()); + Element child2 = (Element) nl.item(1); + assertEquals("child2", child2.getTagName()); + assertTrue(child2.hasAttributes()); + nl2 = child2.getChildNodes(); + assertEquals(0, nl2.getLength()); + assertEquals("bar", child2.getAttribute("foo")); + + assertEquals(Node.ELEMENT_NODE, nl.item(2).getNodeType()); + Element child3 = (Element) nl.item(2); + assertEquals("child3", child3.getTagName()); + assertTrue(!child3.hasAttributes()); + nl2 = child3.getChildNodes(); + assertEquals(1, nl2.getLength()); + assertEquals(Node.ELEMENT_NODE, nl2.item(0).getNodeType()); + assertEquals("child4", ((Element) nl2.item(0)).getTagName()); + } +}