Package org.jboss.dna.sequencer.xml

Source Code of org.jboss.dna.sequencer.xml.XmlSequencerHandlerTest

/*
* JBoss DNA (http://www.jboss.org/dna)
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
* See the AUTHORS.txt file in the distribution for a full listing of
* individual contributors.
*
* JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
* is licensed to you under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* JBoss DNA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.dna.sequencer.xml;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.jboss.dna.common.statistic.Stopwatch;
import org.jboss.dna.common.text.Jsr283Encoder;
import org.jboss.dna.common.text.TextDecoder;
import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.JcrNtLexicon;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathFactory;
import org.jboss.dna.graph.property.Property;
import org.jboss.dna.graph.sequencer.MockSequencerContext;
import org.jboss.dna.graph.sequencer.MockSequencerOutput;
import org.jboss.dna.graph.sequencer.StreamSequencerContext;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
* @author Randall Hauch
*/
public class XmlSequencerHandlerTest {

    private XmlSequencerHandler handler;
    private StreamSequencerContext context;
    private MockSequencerOutput output;
    private TextDecoder decoder;
    private Name primaryType;
    private Name nameAttribute;
    private XmlSequencer.AttributeScoping scoping;
    private LinkedList<Path> pathsInCreationOrder;

    @Before
    public void beforeEach() {
        context = new MockSequencerContext();
        output = new MockSequencerOutput(context, true);
        context.getNamespaceRegistry().register(JcrLexicon.Namespace.PREFIX, JcrLexicon.Namespace.URI);
        context.getNamespaceRegistry().register(JcrNtLexicon.Namespace.PREFIX, JcrNtLexicon.Namespace.URI);
        context.getNamespaceRegistry().register(DnaXmlLexicon.Namespace.PREFIX, DnaXmlLexicon.Namespace.URI);
        context.getNamespaceRegistry().register(DnaDtdLexicon.Namespace.PREFIX, DnaDtdLexicon.Namespace.URI);
        decoder = null;
        nameAttribute = JcrLexicon.NAME;
        primaryType = JcrNtLexicon.UNSTRUCTURED;
        scoping = XmlSequencer.AttributeScoping.USE_DEFAULT_NAMESPACE;
        handler = new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
    }

    @Test( expected = IllegalArgumentException.class )
    public void shouldNotConstructInstanceWhenGivenNullContext() {
        context = null;
        new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
    }

    @Test( expected = IllegalArgumentException.class )
    public void shouldNotConstructInstanceWhenGivenNullOutput() {
        output = null;
        new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
    }

    @Test
    public void shouldUseDefaultDecoderIfNoneIsProvidedInConstructor() {
        decoder = null;
        handler = new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
    }

    @Test
    public void shouldUseDecoderProvidedInConstructor() {
        decoder = new Jsr283Encoder();
        new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
    }

    @Test
    public void shouldParseXmlDocumentWithoutNamespaces() throws IOException, SAXException {
        parse("docWithoutNamespaces.xml");
        // Check the generated content; note that the attribute name doesn't match, so the nodes don't get special names
        assertDocumentNode();
        assertNode("Cars");
        assertNode("Cars/Hybrid");
        assertNode("Cars/Hybrid/car[1]", "name=Toyota Prius", "maker=Toyota", "model=Prius");
        assertNode("Cars/Hybrid/car[2]", "name=Toyota Highlander", "maker=Toyota", "model=Highlander");
        assertNode("Cars/Hybrid/car[3]", "name=Nissan Altima", "maker=Nissan", "model=Altima");
        assertNode("Cars/Sports");
        assertNode("Cars/Sports/car[1]", "name=Aston Martin DB9", "maker=Aston Martin", "model=DB9");
        assertNode("Cars/Sports/car[2]", "name=Infiniti G37", "maker=Infiniti", "model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithNamespaces() throws IOException, SAXException {
        context.getNamespaceRegistry().register("c", "http://default.namespace.com");
        parse("docWithNamespaces.xml");
        // Check the generated content.
        // Note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        // Also, the "jcr:name" attribute values use the default namespace, which is "c" in the registry
        assertDocumentNode();
        assertNode("c:Cars");
        assertNode("c:Cars/c:Hybrid");
        assertNode("c:Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota", "c:model=Prius");
        assertNode("c:Cars/c:Hybrid/c:Toyota Highlander", "c:maker=Toyota", "c:model=Highlander");
        assertNode("c:Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan", "c:model=Altima");
        assertNode("c:Cars/c:Sports");
        assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston Martin", "c:model=DB9");
        assertNode("c:Cars/c:Sports/c:Infiniti G37", "c:maker=Infiniti", "c:model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithNestedNamespaceDeclarations() throws IOException, SAXException {
        context.getNamespaceRegistry().register("c", "http://default.namespace.com");
        context.getNamespaceRegistry().register("i", "http://attributes.com");
        parse("docWithNestedNamespaces.xml");
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode("Cars");
        assertNode("Cars/c:Hybrid");
        assertNode("Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota", "c:model=Prius");
        assertNode("Cars/c:Hybrid/c:Toyota Highlander", "c:maker=Toyota", "c:model=Highlander");
        assertNode("Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan", "c:model=Altima");
        assertNode("Cars/Sports");
        assertNode("Cars/Sports/Aston Martin DB9", "i:maker=Aston Martin", "model=DB9");
        assertNode("Cars/Sports/Infiniti G37", "i:maker=Infiniti", "model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithNamespacePrefixesThatDoNotMatchRegistry() throws IOException, SAXException {
        context.getNamespaceRegistry().register("c", "http://default.namespace.com");
        parse("docWithNamespaces.xml");
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode("c:Cars");
        assertNode("c:Cars/c:Hybrid");
        assertNode("c:Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota", "c:model=Prius");
        assertNode("c:Cars/c:Hybrid/c:Toyota Highlander", "c:maker=Toyota", "c:model=Highlander");
        assertNode("c:Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan", "c:model=Altima");
        assertNode("c:Cars/c:Sports");
        assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston Martin", "c:model=DB9");
        assertNode("c:Cars/c:Sports/c:Infiniti G37", "c:maker=Infiniti", "c:model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithNamespacesThatAreNotYetInRegistry() throws IOException, SAXException {
        NamespaceRegistry reg = context.getNamespaceRegistry();
        reg.unregister(JcrLexicon.Namespace.URI);
        reg.unregister(JcrNtLexicon.Namespace.URI);
        // Verify the prefixes don't exist ...
        assertThat(reg.getPrefixForNamespaceUri(JcrLexicon.Namespace.URI, false), is(nullValue()));
        assertThat(reg.getPrefixForNamespaceUri(JcrNtLexicon.Namespace.URI, false), is(nullValue()));
        assertThat(reg.getPrefixForNamespaceUri("http://default.namespace.com", false), is(nullValue()));
        // Parse the XML file ...
        parse("docWithNestedNamespaces.xml");
        // Get the prefix for the default namespace ...
        String c = reg.getPrefixForNamespaceUri("http://default.namespace.com", false);
        String i = reg.getPrefixForNamespaceUri("http://attributes.com", false);
        String d = reg.getPrefixForNamespaceUri(reg.getDefaultNamespaceUri(), false);
        assertThat("Namespace not properly registered in primary registry", c, is(notNullValue()));
        assertThat("Namespace not properly registered in primary registry", d, is(notNullValue()));
        assertThat("Namespace not properly registered in primary registry", i, is(notNullValue()));
        if (c.length() != 0) c = c + ":";
        if (d.length() != 0) d = d + ":";
        if (i.length() != 0) i = i + ":";
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode(d + "Cars");
        assertNode(d + "Cars/" + c + "Hybrid");
        assertNode(d + "Cars/" + c + "Hybrid/" + c + "Toyota Prius", c + "maker=Toyota", c + "model=Prius");
        assertNode(d + "Cars/" + c + "Hybrid/" + c + "Toyota Highlander", c + "maker=Toyota", c + "model=Highlander");
        assertNode(d + "Cars/" + c + "Hybrid/" + c + "Nissan Altima", c + "maker=Nissan", c + "model=Altima");
        assertNode(d + "Cars/" + d + "Sports");
        assertNode(d + "Cars/" + d + "Sports/Aston Martin DB9", i + "maker=Aston Martin", "model=DB9");
        assertNode(d + "Cars/" + d + "Sports/Infiniti G37", i + "maker=Infiniti", "model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentThatUsesNameAttribute() throws IOException, SAXException {
        context.getNamespaceRegistry().register("c", "http://default.namespace.com");
        parse("docWithNamespaces.xml");
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode("c:Cars");
        assertNode("c:Cars/c:Hybrid");
        assertNode("c:Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota", "c:model=Prius");
        assertNode("c:Cars/c:Hybrid/c:Toyota Highlander", "c:maker=Toyota", "c:model=Highlander");
        assertNode("c:Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan", "c:model=Altima");
        assertNode("c:Cars/c:Sports");
        assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston Martin", "c:model=DB9");
        assertNode("c:Cars/c:Sports/c:Infiniti G37", "c:maker=Infiniti", "c:model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithoutDefaultNamespaceThatUsesNameAttribute() throws IOException, SAXException {
        parse("docWithNamespacesWithoutDefault.xml");
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode("Cars");
        assertNode("Cars/Hybrid");
        assertNode("Cars/Hybrid/Toyota Prius", "maker=Toyota", "model=Prius");
        assertNode("Cars/Hybrid/Toyota Highlander", "maker=Toyota", "model=Highlander");
        assertNode("Cars/Hybrid/Nissan Altima", "maker=Nissan", "model=Altima");
        assertNode("Cars/Sports");
        assertNode("Cars/Sports/Aston Martin DB9", "maker=Aston Martin", "model=DB9");
        assertNode("Cars/Sports/Infiniti G37", "maker=Infiniti", "model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithoutDefaultNamespaceThatUsesNoNameAttribute() throws IOException, SAXException {
        nameAttribute = null;
        handler = new XmlSequencerHandler(output, context, nameAttribute, primaryType, decoder, scoping);
        parse("docWithNamespacesWithoutDefault.xml");
        // Check the generated content; note that the attribute name DOES match, so the nodes names come from "jcr:name" attribute
        assertDocumentNode();
        assertNode("Cars");
        assertNode("Cars/Hybrid");
        assertNode("Cars/Hybrid/car[1]", "maker=Toyota", "model=Prius");
        assertNode("Cars/Hybrid/car[2]", "maker=Toyota", "model=Highlander");
        assertNode("Cars/Hybrid/car[3]", "maker=Nissan", "model=Altima");
        assertNode("Cars/Sports");
        assertNode("Cars/Sports/car[1]", "maker=Aston Martin", "model=DB9");
        assertNode("Cars/Sports/car[2]", "maker=Infiniti", "model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentThatContainsNoContent() throws IOException, SAXException {
        parse("docWithOnlyRootElement.xml");
        assertNode("", "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document");
        assertNode("Cars");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithXmlComments() throws IOException, SAXException {
        context.getNamespaceRegistry().register("c", "http://default.namespace.com");
        parse("docWithComments.xml");
        assertDocumentNode();
        assertNode("c:Cars");
        assertComment("c:Cars/dnaxml:comment[1]", "This is a comment");
        assertNode("c:Cars/c:Hybrid");
        assertNode("c:Cars/c:Hybrid/c:Toyota Prius", "c:maker=Toyota", "c:model=Prius");
        assertNode("c:Cars/c:Hybrid/c:Toyota Highlander", "c:maker=Toyota", "c:model=Highlander");
        assertNode("c:Cars/c:Hybrid/c:Nissan Altima", "c:maker=Nissan", "c:model=Altima");
        assertComment("c:Cars/dnaxml:comment[2]", "This is another comment");
        assertNode("c:Cars/c:Sports");
        assertNode("c:Cars/c:Sports/c:Aston Martin DB9", "c:maker=Aston Martin", "c:model=DB9");
        assertNode("c:Cars/c:Sports/c:Infiniti G37", "c:maker=Infiniti", "c:model=G37");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithDtdEntities() throws IOException, SAXException {
        // Note the expected element content has leading and trailing whitespace removed, and any sequential
        // whitespace is replaced with a single space
        String longContent = "This is some long content that spans multiple lines and should span multiple "
                             + "calls to 'character(...)'. Repeating to make really long. This is some "
                             + "long content that spans multiple lines and should span multiple "
                             + "calls to 'character(...)'. Repeating to make really long. "
                             + "This is some long content that spans multiple lines and should span multiple "
                             + "calls to 'character(...)'. Repeating to make really long. This is some "
                             + "long content that spans multiple lines and should span multiple "
                             + "calls to 'character(...)'. Repeating to make really long.";

        parse("docWithDtdEntities.xml");
        assertDocumentNode("book", "-//OASIS//DTD DocBook XML V4.4//EN", "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd");
        assertComment("dnaxml:comment", "Document comment");
        assertEntity(1, "%RH-ENTITIES", null, "Common_Config/rh-entities.ent");
        assertEntity(2, "versionNumber", "0.1");
        assertEntity(3, "copyrightYear", "2008");
        assertEntity(4, "copyrightHolder", "Red Hat Middleware, LLC.");
        assertNode("book");
        assertNode("book/bookinfo");
        assertNode("book/bookinfo/title");
        assertNode("book/bookinfo/title/dnaxml:elementContent",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=JBoss DNA");
        assertNode("book/bookinfo/releaseinfo");
        assertNode("book/bookinfo/releaseinfo/dnaxml:elementContent",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=&versionNumber;");
        assertNode("book/bookinfo/productnumber");
        assertNode("book/bookinfo/productnumber/dnaxml:elementContent",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=some text with &versionNumber;inside");
        assertNode("book/bookinfo/abstract");
        assertNode("book/bookinfo/abstract/dnaxml:elementContent",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=" + longContent);
        assertNode("book/programlisting1");
        assertNode("book/programlisting1/dnaxml:elementContent",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=&lt;dependency&gt; &lt;/dependency&gt;");
        assertNode("book/programlisting2");
        assertNode("book/programlisting2/dnaxml:cData", "dnaxml:cDataContent=\n&lt;dependency&gt;\n&lt;/dependency&gt;\n");
        assertNode("book/programlisting3");
        assertNode("book/programlisting3/dnaxml:elementContent[1]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=mixture of text and");
        assertNode("book/programlisting3/dnaxml:cData", "dnaxml:cDataContent=\n&lt;dependency&gt;\n&lt;/dependency&gt;\n");
        assertNode("book/programlisting3/dnaxml:elementContent[2]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=and some text");
        assertComment("book/programlisting3/dnaxml:comment", "comment in content");
        assertNode("book/programlisting3/dnaxml:elementContent[3]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=after.");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithProcessingInstructions() throws IOException, SAXException {
        parse("docWithProcessingInstructions.xml");
        assertDocumentNode();
        assertPI(1, "target", "content");
        assertPI(2, "target2", "other stuff in the processing instruction");
        assertNode("Cars");
        assertComment("Cars/dnaxml:comment", "This is a comment");
        assertNode("Cars/Hybrid");
        assertNode("Cars/Hybrid/Toyota Prius");
        assertNode("Cars/Sports");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithCDATA() throws IOException, SAXException {
        String cdata = "\n" + "\n" + "              import mx.events.ValidationResultEvent;\t\t\t\n"
                       + "              private var vResult:ValidationResultEvent;\n" + "\t\t\t\n"
                       + "              // Event handler to validate and format input.\n"
                       + "              private function Format():void {\n" + "              \n"
                       + "                    vResult = numVal.validate();\n" + "\n"
                       + "                    if (vResult.type==ValidationResultEvent.VALID) {\n"
                       + "                        var temp:Number=Number(priceUS.text); \n"
                       + "                        formattedUSPrice.text= usdFormatter.format(temp);\n"
                       + "                    }\n" + "                    \n" + "                    else {\n"
                       + "                       formattedUSPrice.text=\"\";\n" + "                    }\n" + "              }\n"
                       + "        ";
        parse("docWithCDATA.xml");
        assertDocumentNode();
        assertComment("dnaxml:comment", "Simple example to demonstrate the CurrencyFormatter.");
        assertNode("mx:Application");
        assertNode("mx:Application/mx:Script");
        assertCdata("mx:Application/mx:Script/dnaxml:cData", cdata);
        // Now there's an element that contains a mixture of regular element content, CDATA content, and comments
        assertNode("mx:Application/programlisting3");
        assertNode("mx:Application/programlisting3/dnaxml:elementContent[1]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=mixture of text and");
        assertNode("mx:Application/programlisting3/dnaxml:cData",
                   "dnaxml:cDataContent=\n<dependency>entities like &gt; are not replaced in a CDATA\n</dependency>\n");
        assertNode("mx:Application/programlisting3/dnaxml:elementContent[2]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=and some text");
        assertComment("mx:Application/programlisting3/dnaxml:comment", "comment in content");
        assertNode("mx:Application/programlisting3/dnaxml:elementContent[3]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}elementContent",
                   "dnaxml:elementContent=after.");
        // Now the final element
        assertNode("mx:Application/mx:NumberValidator",
                   "id=numVal",
                   "source={priceUS}",
                   "property=text",
                   "allowNegative=true",
                   "domain=real");
        assertNoMoreNodes();
    }

    @Test
    public void shouldParseXmlDocumentWithDtd() throws IOException, SAXException {
        parse("master.xml");
        assertDocumentNode("book", "-//OASIS//DTD DocBook XML V4.4//EN", "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd");
    }

    protected void assertNoMoreNodes() {
        if (!pathsInCreationOrder.isEmpty()) {
            fail("Extra nodes were not expected:" + pathsInCreationOrder);
        }
    }

    protected void assertNode( String path,
                               String... properties ) {
        // Append an index to the path if not there ...
        if (path.length() != 0 && !path.endsWith("]")) {
            path = path + "[1]";
        }

        // Create the expected path ...
        PathFactory factory = context.getValueFactories().getPathFactory();
        Path expectedPath = null;
        if (path.length() == 0) {
            expectedPath = factory.createRelativePath();
        } else {
            expectedPath = factory.create(path);
        }

        // Pop the next node and compare ...
        Path next = this.pathsInCreationOrder.removeFirst();
        assertThat(next, is(expectedPath));

        // Create the list of properties ...
        Map<Name, Property> expectedProperties = new HashMap<Name, Property>();
        for (String propertyString : properties) {
            String[] strings = propertyString.split("=");
            if (strings.length < 2) continue;
            Name name = context.getValueFactories().getNameFactory().create(strings[0]);
            Object[] values = new Object[strings.length - 1];
            for (int i = 1; i != strings.length; ++i) {
                values[i - 1] = strings[i];
            }
            Property property = context.getPropertyFactory().create(name, values);
            expectedProperties.put(name, property);
        }
        // If properties does not contain a primaryType property, then add the default ...
        if (!expectedProperties.containsKey(JcrLexicon.PRIMARY_TYPE)) {
            Property property = context.getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE, primaryType);
            expectedProperties.put(property.getName(), property);
        }

        // Now get the Properties for this path ...
        Map<Name, Property> actualProperties = output.getProperties(expectedPath);
        assertThat("node not found", actualProperties, is(notNullValue()));
        for (Property actual : actualProperties.values()) {
            Property expected = expectedProperties.remove(actual.getName());
            assertThat("unexpected actual property: " + actual, expected, is(notNullValue()));
            assertThat(actual, is(expected));
        }
        if (!expectedProperties.isEmpty()) {
            StringBuilder msg = new StringBuilder("missing actual properties: ");
            boolean isFirst = true;
            for (Property expected : expectedProperties.values()) {
                if (!isFirst) msg.append(", ");
                else isFirst = false;
                msg.append(expected.getName());
            }
            assertThat(msg.toString(), expectedProperties.isEmpty(), is(true));
        }
    }

    protected void assertComment( String path,
                                  String comment ) {
        assertNode(path, "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}comment", "dnaxml:commentContent=" + comment.trim());
    }

    protected void assertCdata( String path,
                                String content ) {
        // Append an index to the path if not there ...
        if (path.length() != 0 && !path.endsWith("]")) {
            path = path + "[1]";
        }
        PathFactory factory = context.getValueFactories().getPathFactory();
        Path expectedPath = factory.create("/" + path);

        // Pop the next node and compare ...
        Path next = this.pathsInCreationOrder.removeFirst();
        assertThat(next, is(expectedPath));

        // There should be a single property ...
        Property actualPrimaryType = output.getProperty(expectedPath, JcrLexicon.PRIMARY_TYPE);
        assertThat(actualPrimaryType.getValues().next(), is((Object)JcrNtLexicon.UNSTRUCTURED));
        Property actual = output.getProperty(expectedPath, DnaXmlLexicon.CDATA_CONTENT);
        assertThat("expected one CDATA property", actual, is(notNullValue()));
        Property expected = context.getPropertyFactory().create(DnaXmlLexicon.CDATA_CONTENT, content);
        assertThat("CDATA content differed", actual, is(expected));
    }

    protected void assertDocumentNode() {
        assertNode("", "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document");
    }

    protected void assertDocumentNode( String name,
                                       String publicId,
                                       String systemId ) {
        assertNode("",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document",
                   "dnadtd:name=" + name,
                   "dnadtd:publicId=" + publicId,
                   "dnadtd:systemId=" + systemId);
    }

    protected void assertEntity( int index,
                                 String entityName,
                                 String value ) {
        String path = "dnadtd:entity[" + index + "]";
        assertNode(path, "jcr:primaryType={http://www.jboss.org/dna/dtd/1.0}entity", "dnadtd:name=" + entityName, "dnadtd:value="
                                                                                                                  + value);
    }

    protected void assertEntity( int index,
                                 String entityName,
                                 String publicId,
                                 String systemId ) {
        String path = "dnadtd:entity[" + index + "]";
        if (publicId != null) {
            assertNode(path,
                       "jcr:primaryType={http://www.jboss.org/dna/dtd/1.0}entity",
                       "dnadtd:name=" + entityName,
                       "dnadtd:publicId=" + publicId,
                       "dnadtd:systemId=" + systemId);
        } else {
            assertNode(path,
                       "jcr:primaryType={http://www.jboss.org/dna/dtd/1.0}entity",
                       "dnadtd:name=" + entityName,
                       "dnadtd:systemId=" + systemId);
        }
    }

    protected void assertPI( int index,
                             String target,
                             String data ) {
        assertNode("dnaxml:processingInstruction[" + index + "]",
                   "jcr:primaryType={http://www.jboss.org/dna/xml/1.0}processingInstruction",
                   "dnaxml:target=" + target,
                   "dnaxml:processingInstructionContent=" + data);
    }

    protected void parse( String relativePathToXmlFile ) throws IOException, SAXException {
        Stopwatch sw = new Stopwatch();
        sw.start();
        InputStream stream = getClass().getClassLoader().getResourceAsStream(relativePathToXmlFile);
        try {
            XMLReader reader = XMLReaderFactory.createXMLReader();
            reader.setContentHandler(handler);
            reader.setErrorHandler(handler);
            // Ensure handler acting as entity resolver 2
            reader.setProperty(XmlSequencer.DECL_HANDLER_FEATURE, handler);
            // Ensure handler acting as lexical handler
            reader.setProperty(XmlSequencer.LEXICAL_HANDLER_FEATURE, handler);
            // Ensure handler acting as entity resolver 2
            XmlSequencer.setFeature(reader, XmlSequencer.ENTITY_RESOLVER_2_FEATURE, true);
            // Prevent loading of external DTDs
            XmlSequencer.setFeature(reader, XmlSequencer.LOAD_EXTERNAL_DTDS_FEATURE, false);
            // Prevent the resolving of DTD entities into fully-qualified URIS
            XmlSequencer.setFeature(reader, XmlSequencer.RESOLVE_DTD_URIS_FEATURE, false);
            reader.parse(new InputSource(stream));
        } finally {
            if (stream != null) stream.close();
            sw.stop();
            System.out.println("Parsing: " + sw);
        }
        pathsInCreationOrder = new LinkedList<Path>(output.getOrderOfCreation());
    }
}
TOP

Related Classes of org.jboss.dna.sequencer.xml.XmlSequencerHandlerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.