[izpack-devel] Adding XInclude support
Matthew Fudge
matfud at yahoo.com
Thu Dec 13 17:03:33 CET 2007
Index: src/tests/net/n3/nanoxml/xinclude/XIncludeXMLBuilderTestCase.java
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/XIncludeXMLBuilderTestCase.java (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/XIncludeXMLBuilderTestCase.java (revision 0)
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2007 Volantis Systems Ltd., All Rights Reserved.
+ *
+ * Licensed 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 net.n3.nanoxml.xinclude;
+
+import junit.framework.TestCase;
+import net.n3.nanoxml.IXMLReader;
+import net.n3.nanoxml.NonValidator;
+import net.n3.nanoxml.StdXMLParser;
+import net.n3.nanoxml.StdXMLReader;
+import net.n3.nanoxml.XMLBuilderFactory;
+import net.n3.nanoxml.XMLElement;
+
+import java.util.Enumeration;
+
+/**
+ * Test the XInclude style functionality added to the XMLBuilder
+ */
+public class XIncludeXMLBuilderTestCase extends TestCase {
+
+
+ /**
+ * This method takes the fileBase name and attempts to find two files
+ * called <fileBase>-input.xml and <fileBase>-expected.xml
+ *
+ * @param fileBase the base of the test file names
+ * @throws Exception
+ */
+ public void doTest(String fileBase) throws Exception {
+
+ String baseURL = getClass().getResource(fileBase + "-input.xml").toExternalForm();
+ // set up a new parser to parse the input xml (with includes)
+ StdXMLParser inputParser = new StdXMLParser();
+ inputParser.setBuilder(XMLBuilderFactory.createXMLBuilder());
+ IXMLReader inputReader = new StdXMLReader(
+ getClass().getResourceAsStream(fileBase + "-input.xml"));
+ inputReader.setSystemID(baseURL);
+ inputParser.setReader(inputReader);
+ inputParser.setValidator(new NonValidator());
+
+ // set up a new parser to parse the expected xml (without includes)
+ StdXMLParser expectedParser = new StdXMLParser();
+ expectedParser.setBuilder(XMLBuilderFactory.createXMLBuilder());
+ IXMLReader expectedReader = new StdXMLReader(
+ getClass().getResourceAsStream(fileBase + "-expect.xml"));
+ expectedReader.setSystemID(baseURL);
+ expectedParser.setReader(expectedReader);
+ expectedParser.setValidator(new NonValidator());
+
+ XMLElement inputElement = (XMLElement) inputParser.parse();
+ XMLElement expectedElement = (XMLElement) expectedParser.parse();
+
+ deepEqual(expectedElement, inputElement);
+
+ }
+
+ /**
+ * This method is used to ensure that the contents of the specified file
+ * (when having "-input.xml" appended) cause the parser to fail
+ *
+ * @param fileBase the base name of the input file.
+ * @throws Exception
+ */
+ public void ensureFailure(String fileBase) throws Exception {
+ try {
+ String baseURL = getClass().getResource(fileBase + "-input.xml").toExternalForm();
+ // set up a new parser to parse the input xml (with includes)
+ StdXMLParser inputParser = new StdXMLParser();
+ inputParser.setBuilder(XMLBuilderFactory.createXMLBuilder());
+ IXMLReader inputReader = new StdXMLReader(
+ getClass().getResourceAsStream(fileBase + "-input.xml"));
+ inputReader.setSystemID(baseURL);
+ inputParser.setReader(inputReader);
+ inputParser.setValidator(new NonValidator());
+
+ inputParser.parse();
+ fail("an exception should have been thrown");
+ } catch (Throwable t) {
+ // success
+ }
+ }
+
+ /**
+ * Perform a deep equality check on the two nodes.
+ *
+ */
+ public void deepEqual(XMLElement a, XMLElement b) {
+
+ assertEquals("element names", a.getName(), b.getName());
+ assertEquals("element attributes for "+ a.getName(),
+ a.getAttributes(), b.getAttributes());
+ assertEquals("content for " + a.getName(),
+ a.getContent(), b.getContent());
+ assertEquals("equal number of children" + a.getName(),
+ a.getChildrenCount(), b.getChildrenCount());
+
+ Enumeration aChildren = a.enumerateChildren();
+ Enumeration bChildren = b.enumerateChildren();
+ while (aChildren.hasMoreElements()) {
+ XMLElement aChild = (XMLElement) aChildren.nextElement();
+ XMLElement bChild = (XMLElement) bChildren.nextElement();
+ deepEqual(aChild, bChild);
+ }
+ }
+
+ /**
+ * Test Empty document with include
+ * @throws Exception
+ */
+ public void testIncludeOnly() throws Exception {
+ doTest("include-only");
+ }
+
+ /**
+ * Test that a fragment included as the root node does not have the
+ * "fragment" element removed
+ * @throws Exception
+ */
+ public void testIncludeFragmentOnly() throws Exception {
+ doTest("include-fragment-only");
+ }
+
+ /**
+ * Test to ensure that content is correctly included when the include
+ * element is not the root element
+ * @throws Exception
+ */
+ public void testIncludeInElement() throws Exception {
+ doTest("include-in-element");
+ }
+
+ /**
+ * Test to ensure that content is correctly included when the include
+ * element is not the root element
+ * @throws Exception
+ */
+ public void testIncludeFragmentInElement() throws Exception {
+ doTest("include-fragment-in-element");
+ }
+
+ /**
+ * Test text inclusion
+ * @throws Exception
+ */
+ public void testIncludeTextInElement() throws Exception {
+ doTest("include-fragment-in-element");
+ }
+
+ /**
+ * Ensure that the parse attribute accepts "text" and treats it like text
+ * @throws Exception
+ */
+ public void testParseAttributeText() throws Exception {
+ doTest("include-xml-as-text");
+ }
+
+ /**
+ * Ensure that the parse attribute accepts "xml" and treats like xml
+ * (most other tests do not explicitly set the parse parameter and let it
+ * default to "xml"
+ * @throws Exception
+ */
+ public void testParseAttributeXML() throws Exception {
+ doTest("include-xml-as-xml");
+ }
+
+ /**
+ * Make sure that a failure occurs for a parse valid that is not "xml"
+ * or "text"
+ *
+ * @throws Exception
+ */
+ public void testParseInvalidAttribute() throws Exception {
+ ensureFailure("invalid-parse-attrib");
+ }
+
+ /**
+ * Ensure fallbacks work correctly
+ *
+ * @throws Exception
+ */
+ public void testFallback() throws Exception {
+ doTest("fallback");
+ }
+
+ /**
+ * Test that an empty fallback just removes the include and fallback
+ * elements
+ *
+ * @throws Exception
+ */
+ public void testEmptyFallback() throws Exception {
+ doTest("empty-fallback");
+ }
+
+ /**
+ * Ensure that two includes in the same element both get included
+ * @throws Exception
+ */
+ public void testMultipleIncludes() throws Exception {
+ doTest("multiple-include");
+ }
+
+
+}
Index: src/tests/net/n3/nanoxml/xinclude/empty-fallback-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/empty-fallback-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/empty-fallback-expect.xml (revision 0)
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/fallback-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/fallback-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/fallback-expect.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ [<bbb/>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-only-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-only-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-only-expect.xml (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<eeee>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</eeee>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/empty-fallback-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/empty-fallback-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/empty-fallback-input.xml (revision 0)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <xinclude href="does-not-exist.xml">
+ <xfallback/>
+ </xinclude>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-fragment-only-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-fragment-only-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-fragment-only-expect.xml (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<xfragment>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</xfragment>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-expect.xml (revision 0)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+<![CDATA[<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<eeee>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</eeee>]]>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-text-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-text-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-text-expect.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<a>
+This is some sample text that should be included
+</a>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/fallback-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/fallback-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/fallback-input.xml (revision 0)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <xinclude href="does-not-exist.xml">
+ <xfallback>
+ <![CDATA[<bbb/>]]>
+ </xfallback>
+ </xinclude>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-only-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-only-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-only-input.xml (revision 0)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<xinclude href="content.xml"/>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-fragment-only-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-fragment-only-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-fragment-only-input.xml (revision 0)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<xinclude href="content-fragment.xml"/>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-xml-as-text-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <xinclude href="content.xml" parse="text"/>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-text-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-text-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-text-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<a>
+ <xinclude href="text.txt" parse="text"/>
+</a>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/multiple-include-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/multiple-include-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/multiple-include-expect.xml (revision 0)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaaa>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</aaaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/text.txt
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/text.txt (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/text.txt (revision 0)
@@ -0,0 +1 @@
+This is some sample text that should be included
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-in-element-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-in-element-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-in-element-expect.xml (revision 0)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<bob>
+ <eeee>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+ </eeee>
+</bob>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-expect.xml (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<bob>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</bob>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-expect.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-expect.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-expect.xml (revision 0)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <eeee>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+ </eeee>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/multiple-include-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/multiple-include-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/multiple-include-input.xml (revision 0)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaaa>
+ <xinclude href="content-fragment.xml"/>
+ <xinclude href="content-fragment.xml"/>
+</aaaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/content.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/content.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/content.xml (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<eeee>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</eeee>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/content-fragment.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/content-fragment.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/content-fragment.xml (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<xfragment>
+ <ffff>
+ <gggg>hello</gggg>
+ </ffff>
+
+ <hhhh>
+ <iiii>there</iiii>
+ </hhhh>
+</xfragment>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-in-element-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-in-element-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-in-element-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<bob>
+ <xinclude href="content.xml"/>
+</bob>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-fragment-in-element-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<bob>
+ <xinclude href="content-fragment.xml"/>
+</bob>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/include-xml-as-xml-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <xinclude href="content.xml" parse="xml"/>
+</aaa>
\ No newline at end of file
Index: src/tests/net/n3/nanoxml/xinclude/invalid-parse-attrib-input.xml
===================================================================
--- src/tests/net/n3/nanoxml/xinclude/invalid-parse-attrib-input.xml (revision 0)
+++ src/tests/net/n3/nanoxml/xinclude/invalid-parse-attrib-input.xml (revision 0)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<aaa>
+ <xinclude href="content.xml" parse="invalid"/>
+</aaa>
\ No newline at end of file
Index: src/lib/net/n3/nanoxml/XMLBuilderFactory.java
===================================================================
--- src/lib/net/n3/nanoxml/XMLBuilderFactory.java (revision 0)
+++ src/lib/net/n3/nanoxml/XMLBuilderFactory.java (revision 0)
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2007 Volantis Systems Ltd., All Rights Reserved.
+ *
+ * Licensed 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 net.n3.nanoxml;
+
+/**
+ * Simple factory for creating builders
+ */
+public class XMLBuilderFactory {
+
+ /**
+ * Return an IXMLBuilder instance
+ *
+ * @return an IXMLBuilder instance
+ */
+ public static IXMLBuilder createXMLBuilder() {
+ return new XIncludeXMLBuilder();
+ }
+}
Index: src/lib/net/n3/nanoxml/XIncludeXMLBuilder.java
===================================================================
--- src/lib/net/n3/nanoxml/XIncludeXMLBuilder.java (revision 0)
+++ src/lib/net/n3/nanoxml/XIncludeXMLBuilder.java (revision 0)
@@ -0,0 +1,368 @@
+/*
+ * Copyright 2007 Volantis Systems Ltd., All Rights Reserved.
+ *
+ * Licensed 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 net.n3.nanoxml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+
+/**
+ * Extend the XMLBuilder to add XInclude functionality
+ */
+public class XIncludeXMLBuilder extends StdXMLBuilder {
+ /**
+ * Namespace to for XInclude (NOTE that this is not used
+ * at the moment). The specification can be found
+ * here'>http://www.w3.org/TR/xinclude/">here.
+ */
+ public static final String INCLUDE_NS = "http://www.w3.org/2001/XInclude";
+ /**
+ * The name of the include element (this should be "include" using the
+ * {@link #INCLUDE_NS} but namespaces are not supported
+ */
+ public static final String INCLUDE_ELEMENT = "xinclude";
+ /**
+ * The location of the included data
+ */
+ public static final String HREF_ATTRIB = "href";
+
+ /**
+ * The xpointer attribute. This must not be used when "parse='text'"
+ */
+ public static final String XPOINTER_ATTRIB = "xpointer";
+
+ /**
+ * The attribute to decribe the encoding of the text include (no effect when
+ * parse='xml')
+ */
+ public static final String ENCODING_ATTRIB = "encoding";
+
+ /**
+ * The attribute describing the accept header that will be used with
+ * http based includes.
+ */
+ public static final String ACCEPT_ENCODING = "accept";
+
+ /**
+ * The element for handling fallbacks. This should be called "fallback" and
+ * be in the {@link #INCLUDE_NS} but namespaces are not supported
+ */
+ public static final String FALLBACK_ELEMENT = "xfallback";
+
+ /**
+ * Parse attribute. If missing this implies "xml" its other valid value
+ * is "text"
+ */
+ public static final String PARSE_ATTRIB = "parse";
+
+ /**
+ * Namespace for the "fragment" element used to include xml documents with
+ * no explicit root node.
+ */
+ public static final String FRAGMENT_NS = "https://izpack.github.io/izpack/fragment";
+
+ /**
+ * The name of the fragment element is a root node element that can be
+ * used to wrap xml fragments for inclusion. It is removed during the
+ * include operation. This should be called "fragment" and be in the
+ * {@link #FRAGMENT_NS} but namespaces are not supported.
+ */
+ public static final String FRAGMENT = "xfragment";
+
+ // Javadoc inherited
+ public void endElement(String name, String nsPrefix, String nsSystemID) {
+ // get the current element before it gets popped from the stack
+ XMLElement element = getCurrentElement();
+ // let normal processing occur
+ super.endElement(name, nsPrefix, nsSystemID);
+ // now process the "include" element
+ processXInclude(element);
+ }
+
+ /**
+ * This method handles XInclude elements in the code
+ *
+ * @param element the node currently being procesed. In this case it should
+ * be the {@link #INCLUDE_ELEMENT}
+ */
+ private void processXInclude(final XMLElement element) {
+ if (INCLUDE_ELEMENT.equals(element.getName())) {
+
+ Vector fallbackChildren = element.getChildrenNamed(FALLBACK_ELEMENT);
+ if (element.getChildrenCount() != fallbackChildren.size() ||
+ fallbackChildren.size() > 1) {
+ throw new RuntimeException(new XMLParseException(
+ element.getSystemID(),
+ element.getLineNr(),
+ INCLUDE_ELEMENT + " can optionally have a single " +
+ FRAGMENT + " as a child"));
+ }
+ boolean usingFallback = false;
+
+ String href = element.getAttribute(HREF_ATTRIB, "");
+ if (!href.equals("")) { // including an external file.
+
+ IXMLReader reader = null;
+ try {
+ reader = getReader(element);
+ } catch (Exception e) { // yes really catch all exceptions
+ // ok failed to read from the location for some reason.
+ // see if we have a fallback
+ reader = handleFallback(element);
+ usingFallback = true;
+ }
+ String parse = element.getAttribute(PARSE_ATTRIB, "xml");
+ // process as text if we are not using our fallback and the parse
+ // type is "text"
+ if ("text".equals(parse) && !usingFallback) {
+ includeText(element, reader);
+ } else if ("xml".equals(parse)) {
+ includeXML(element, reader);
+ } else {
+ throw new RuntimeException(
+ new XMLParseException(
+ element.getSystemID(),
+ element.getLineNr(),
+ PARSE_ATTRIB + " attribute of " + INCLUDE_ELEMENT +
+ " must be \"xml\" or \"text\" but was " +
+ parse));
+ }
+ } else { // including part of this file rather then an external one
+ if (!element.hasAttribute(XPOINTER_ATTRIB)) {
+ throw new RuntimeException(
+ new XMLParseException(
+ element.getSystemID(),
+ element.getLineNr(),
+ XPOINTER_ATTRIB + "must be specified if href is " +
+ "empty or missing"));
+ }
+ }
+ }
+ }
+
+ /**
+ * Handle the fallback if one exists. If one does not exist then throw
+ * a runtime exception as this is a fatal error
+ *
+ * @param include the include element
+ * @return a reader for the fallback
+ */
+ private IXMLReader handleFallback(XMLElement include) {
+ Vector fallbackChildren = include.getChildrenNamed(FALLBACK_ELEMENT);
+ if (fallbackChildren.size() == 1) {
+ // process fallback
+
+ XMLElement fallback = (XMLElement) fallbackChildren.get(0);
+ // fallback element can only contain a CDATA so it will not have
+ // its content in un-named children
+ String content = fallback.getContent();
+ if (content != null) {
+ content = content.trim();
+ }
+
+ if ("".equals(content) || content == null) {
+ // an empty fragment requires us to just remove the "include"
+ // element. A nasty hack follows:
+ // a "fragment" with no children will just be removed along with
+ // the "include" element.
+ content = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\" ?><"+ FRAGMENT + "/>";
+ }
+ return StdXMLReader.stringReader(content);
+ } else {
+ throw new RuntimeException(new XMLParseException(
+ include.getSystemID(),
+ include.getLineNr(),
+ "could not load content"));
+ }
+ }
+
+ /**
+ * Include the xml contained in the specified reader. This content will be
+ * parsed and attached to the parent of the <param>element</param> node
+ *
+ * @param element the include element
+ * @param reader the reader containing the xml to parse and include.
+ */
+ private void includeXML(final XMLElement element, IXMLReader reader) {
+
+ try {
+ Stack stack = getStack();
+ // set up a new parser to parse the include file.
+ StdXMLParser parser = new StdXMLParser();
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
+ parser.setReader(reader);
+ parser.setValidator(new NonValidator());
+
+ XMLElement childroot = (XMLElement) parser.parse();
+ // if the include element was the root element in the original
+ // document then keep the element as-is (i.e.
+ // don't remove the "fragment" element from the included content
+ if (stack.isEmpty()) {
+ setRootElement(childroot);
+ } else {
+ XMLElement parent = (XMLElement) stack.peek();
+ // remove the include element from its parent
+ parent.removeChild(element);
+
+ // if there was a "fragment" included remove the fragment
+ // element and attach its children in place of this include
+ // element.
+ if (FRAGMENT.equals(childroot.getName())) {
+ Vector grandchildren = childroot.getChildren();
+ Iterator it = grandchildren.iterator();
+ while (it.hasNext()) {
+ XMLElement grandchild = (XMLElement) it.next();
+ parent.addChild(grandchild);
+ }
+ } else {
+ // if it was a complete document included then
+ // just add it in place of the include element
+ parent.addChild(childroot);
+ }
+ }
+ } catch (XMLException e) {
+ throw new RuntimeException(new XMLParseException(
+ element.getSystemID(), element.getLineNr(), e.getMessage()));
+ }
+ }
+
+
+ /**
+ * Include plain text. The reader contains the content in the appropriate
+ * encoding as determined by the {@link #ENCODING_ATTRIB} if one was
+ * present.
+ *
+ * @param element the include element
+ * @param reader the reader containing the include text
+ */
+ private void includeText(XMLElement element, IXMLReader reader) {
+
+ if (element.getAttribute("xpointer") != null) {
+ throw new RuntimeException(new XMLParseException(
+ "xpointer cannot be used with parse='text'"));
+ }
+
+ Stack stack = getStack();
+ if (stack.isEmpty()) {
+ throw new RuntimeException(new XMLParseException(
+ element.getSystemID(),
+ element.getLineNr(),
+ "cannot include text as the root node"));
+ }
+
+ // remove the include element from the parent
+ XMLElement parent = (XMLElement)stack.peek();
+ parent.removeChild(element);
+ StringBuffer buffer = new StringBuffer();
+ try {
+ while (!reader.atEOF()) {
+ buffer.append(reader.read());
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(new XMLParseException(
+ element.getSystemID(), element.getLineNr(), e.getMessage()));
+ }
+
+ if (parent.getChildrenCount() == 0) {
+ // no children so just set the content as there cannot have been
+ // any content there already
+ parent.setContent(buffer.toString());
+ } else {
+ // nanoxml also claims to store #PCDATA in unnamed children
+ // if there was a combination of #PCDATA and child elements.
+ // This should put it in the correct place as we haven't finihshed
+ // parsing the children of includes parent yet.
+ XMLElement content = new XMLElement();
+ content.setContent(buffer.toString());
+ parent.addChild(content);
+ }
+ }
+
+ /**
+ * Return a reader for the specified {@link #INCLUDE_ELEMENT}. The caller
+ * is responsible for closing the reader produced.
+ *
+ * @param element the include element to obtain a reader for
+ * @return a reader for the include element
+ * @throws XMLParseException if a problem occurs parsing the
+ * {@link #INCLUDE_ELEMENT}
+ * @throws IOException if the href cannot be read
+ */
+ private IXMLReader getReader(XMLElement element) throws XMLParseException, IOException {
+ String href = element.getAttribute(HREF_ATTRIB);
+ // This is a bit nasty but is a simple way of handling files that are
+ // not fully qualified urls
+ URL url = null;
+ try {
+ // standard URL
+ url = new URL(href);
+ } catch (MalformedURLException e) {
+ try {
+ // absolute file without a protocol
+ if (href.charAt(0) == '/') {
+ url = new URL("file://" + href);
+ } else {
+ // relative file
+ url = new URL(new URL(element.getSystemID()), href);
+ }
+ } catch (MalformedURLException e1) {
+ new XMLParseException(element.getSystemID(),
+ element.getLineNr(), "malformed url '" + href + "'");
+ }
+ }
+
+ URLConnection connection = url.openConnection();
+ // special handling for http and https
+ if (connection instanceof HttpURLConnection &&
+ element.hasAttribute(ENCODING_ATTRIB)) {
+ connection.setRequestProperty(
+ "accept", element.getAttribute(ENCODING_ATTRIB));
+ }
+
+ InputStream is = connection.getInputStream();
+
+ InputStreamReader reader = null;
+ // Only pay attention to the {@link #ENCODING_ATTRIB} if parse='text'
+ if (element.getAttribute(PARSE_ATTRIB, "xml").equals("text") &&
+ element.hasAttribute(ENCODING_ATTRIB)) {
+ reader = new InputStreamReader(
+ is, element.getAttribute(ENCODING_ATTRIB, ""));
+ } else {
+ reader = new InputStreamReader(is);
+ }
+
+ IXMLReader ireader = new StdXMLReader(reader);
+ ireader.setSystemID(url.toExternalForm());
+ return ireader;
+ }
+
+ /**
+ * used to record the system id for this document.
+ *
+ * @param systemID the system id of the document being built
+ * @param lineNr the line number
+ */
+ public void startBuilding(String systemID, int lineNr) {
+ super.startBuilding(systemID, lineNr);
+ }
+}
Index: src/lib/net/n3/nanoxml/XMLParserFactory.java
===================================================================
--- src/lib/net/n3/nanoxml/XMLParserFactory.java (revision 1951)
+++ src/lib/net/n3/nanoxml/XMLParserFactory.java (working copy)
@@ -65,7 +65,7 @@
{
String className = System.getProperty(XMLParserFactory.CLASS_KEY,
XMLParserFactory.DEFAULT_CLASS);
- return XMLParserFactory.createXMLParser(className, new StdXMLBuilder());
+ return XMLParserFactory.createXMLParser(className, XMLBuilderFactory.createXMLBuilder());
}
/**
Index: src/lib/net/n3/nanoxml/StdXMLBuilder.java
===================================================================
--- src/lib/net/n3/nanoxml/StdXMLBuilder.java (revision 1951)
+++ src/lib/net/n3/nanoxml/StdXMLBuilder.java (working copy)
@@ -63,6 +63,36 @@
}
/**
+ * Return the element that is currently being processed
+ *
+ * @return the element that is currently being processed
+ */
+ protected XMLElement getCurrentElement() {
+ return (XMLElement) stack.peek();
+ }
+
+ /**
+ * Return the stack used for processing the elements.
+ *
+ * @return the stack used for processing the elements.
+ */
+ protected Stack getStack() {
+ return stack;
+ }
+
+ /**
+ * Set the root element to a new element. This causes the internal stack
+ * to be flushed and the supplied element to be pushed onto it
+ *
+ * @param element the new root element.
+ */
+ protected void setRootElement(XMLElement element) {
+ stack.clear();
+ stack.push(element);
+ this.root = element;
+ }
+
+ /**
* Cleans up the object when it's destroyed.
*/
protected void finalize() throws Throwable
Index: src/lib/net/n3/nanoxml/StdXMLReader.java
===================================================================
--- src/lib/net/n3/nanoxml/StdXMLReader.java (revision 1951)
+++ src/lib/net/n3/nanoxml/StdXMLReader.java (working copy)
@@ -138,7 +138,7 @@
}
catch (MalformedURLException e)
{
- systemID = "file:" + systemID;
+ systemID = "file://" + systemID;
try
{
Index: src/lib/com/izforge/izpack/panels/UserInputPanel.java
===================================================================
--- src/lib/com/izforge/izpack/panels/UserInputPanel.java (revision 1951)
+++ src/lib/com/izforge/izpack/panels/UserInputPanel.java (working copy)
@@ -54,10 +54,10 @@
import javax.swing.text.Document;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.LocaleDatabase;
import com.izforge.izpack.Pack;
@@ -1145,7 +1145,7 @@
// initialize the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
parser.setReader(new StdXMLReader(input));
Index: src/lib/com/izforge/izpack/panels/ShortcutPanel.java
===================================================================
--- src/lib/com/izforge/izpack/panels/ShortcutPanel.java (revision 1951)
+++ src/lib/com/izforge/izpack/panels/ShortcutPanel.java (working copy)
@@ -49,10 +49,10 @@
import javax.swing.event.ListSelectionListener;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.ExecutableFile;
import com.izforge.izpack.Pack;
@@ -830,7 +830,7 @@
* System.out.println( "==================================================================" ); }
*/
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
parser.setReader(StdXMLReader.stringReader(substitutedSpec));
Index: src/lib/com/izforge/izpack/installer/AutomatedInstaller.java
===================================================================
--- src/lib/com/izforge/izpack/installer/AutomatedInstaller.java (revision 1951)
+++ src/lib/com/izforge/izpack/installer/AutomatedInstaller.java (working copy)
@@ -40,10 +40,10 @@
import java.util.zip.ZipOutputStream;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.CustomData;
import com.izforge.izpack.ExecutableFile;
@@ -454,7 +454,7 @@
// Initialises the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setReader(new StdXMLReader(in));
parser.setValidator(new NonValidator());
Index: src/lib/com/izforge/izpack/installer/InstallerFrame.java
===================================================================
--- src/lib/com/izforge/izpack/installer/InstallerFrame.java (revision 1951)
+++ src/lib/com/izforge/izpack/installer/InstallerFrame.java (working copy)
@@ -84,11 +84,11 @@
import javax.swing.text.JTextComponent;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
import net.n3.nanoxml.XMLWriter;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.CustomData;
import com.izforge.izpack.ExecutableFile;
@@ -351,7 +351,7 @@
}
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
parser.setReader(new StdXMLReader(input));
@@ -443,7 +443,7 @@
// Initialises the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setReader(new StdXMLReader(inXML));
parser.setValidator(new NonValidator());
@@ -495,7 +495,7 @@
// Initialises the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setReader(new StdXMLReader(inXML));
parser.setValidator(new NonValidator());
Index: src/lib/com/izforge/izpack/installer/CompileWorker.java
===================================================================
--- src/lib/com/izforge/izpack/installer/CompileWorker.java (revision 1951)
+++ src/lib/com/izforge/izpack/installer/CompileWorker.java (working copy)
@@ -40,10 +40,10 @@
import java.util.Vector;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.LocaleDatabase;
import com.izforge.izpack.util.Debug;
@@ -240,7 +240,7 @@
}
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
try
Index: src/lib/com/izforge/izpack/installer/ProcessPanelWorker.java
===================================================================
--- src/lib/com/izforge/izpack/installer/ProcessPanelWorker.java (revision 1951)
+++ src/lib/com/izforge/izpack/installer/ProcessPanelWorker.java (working copy)
@@ -38,10 +38,10 @@
import java.util.Vector;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.Pack;
import com.izforge.izpack.rules.Condition;
@@ -117,7 +117,7 @@
}
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
XMLElement spec;
Index: src/lib/com/izforge/izpack/LocaleDatabase.java
===================================================================
--- src/lib/com/izforge/izpack/LocaleDatabase.java (revision 1951)
+++ src/lib/com/izforge/izpack/LocaleDatabase.java (working copy)
@@ -25,10 +25,10 @@
import java.util.Vector;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
/**
* Represents a database of a locale.
@@ -64,7 +64,7 @@
{
// Initialises the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setReader(new StdXMLReader(in));
parser.setValidator(new NonValidator());
Index: src/lib/com/izforge/izpack/compiler/CompilerConfig.java
===================================================================
--- src/lib/com/izforge/izpack/compiler/CompilerConfig.java (revision 1951)
+++ src/lib/com/izforge/izpack/compiler/CompilerConfig.java (working copy)
@@ -75,11 +75,11 @@
import net.n3.nanoxml.IXMLReader;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
import net.n3.nanoxml.XMLException;
+import net.n3.nanoxml.XMLBuilderFactory;
/**
* A parser for the installer xml configuration. This parses a document
@@ -1001,7 +1001,7 @@
}
StdXMLParser refXMLParser = new StdXMLParser();
- refXMLParser.setBuilder(new StdXMLBuilder());
+ refXMLParser.setBuilder(XMLBuilderFactory.createXMLBuilder());
refXMLParser.setReader(refXMLReader);
refXMLParser.setValidator(new NonValidator());
@@ -1688,7 +1688,7 @@
}
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setReader(reader);
parser.setValidator(new NonValidator());
Index: src/lib/com/izforge/izpack/util/SpecHelper.java
===================================================================
--- src/lib/com/izforge/izpack/util/SpecHelper.java (revision 1951)
+++ src/lib/com/izforge/izpack/util/SpecHelper.java (working copy)
@@ -29,10 +29,10 @@
import java.util.Vector;
import net.n3.nanoxml.NonValidator;
-import net.n3.nanoxml.StdXMLBuilder;
import net.n3.nanoxml.StdXMLParser;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
+import net.n3.nanoxml.XMLBuilderFactory;
import com.izforge.izpack.installer.InstallerException;
import com.izforge.izpack.installer.ResourceManager;
@@ -142,7 +142,7 @@
// initialize the parser
StdXMLParser parser = new StdXMLParser();
- parser.setBuilder(new StdXMLBuilder());
+ parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
parser.setValidator(new NonValidator());
parser.setReader(new StdXMLReader(input));
__________________________________________________________
Sent from Yahoo! Mail - a smarter inbox http://uk.mail.yahoo.com
More information about the izpack-devel
mailing list