| /* $Id$ |
| * |
| * 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.commons.digester3; |
| |
| import static org.apache.commons.digester3.binder.DigesterLoader.newLoader; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.StringReader; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.apache.commons.digester3.binder.AbstractRulesModule; |
| import org.apache.commons.digester3.binder.NodeCreateRuleProvider.NodeType; |
| import org.junit.Test; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentFragment; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * <p> |
| * Test case for the <code>NodeCreateRule</code>. |
| * |
| * @author Christopher Lenz |
| */ |
| public class NodeCreateRuleTestCase |
| { |
| |
| // ----------------------------------------------------- Instance Variables |
| |
| /** |
| * Simple test xml document used in the tests. |
| */ |
| protected final static String TEST_XML = "<?xml version='1.0'?><root>ROOT BODY<alpha>ALPHA BODY</alpha>" |
| + "<beta>BETA BODY</beta><gamma>GAMMA BODY</gamma></root>"; |
| |
| // ------------------------------------------------ Individual Test Methods |
| |
| /** |
| * Tests simple element construction, using the {@link #TEST_XML} XML input data. |
| */ |
| @Test |
| public void testInvalidNodeTypes() |
| throws Exception |
| { |
| |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.ATTRIBUTE_NODE ); |
| fail( "IllegalArgumentException expected for type ATTRIBUTE_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.CDATA_SECTION_NODE ); |
| fail( "IllegalArgumentException expected for type " + "CDATA_SECTION_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.COMMENT_NODE ); |
| fail( "IllegalArgumentException expected for type COMMENT_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.DOCUMENT_NODE ); |
| fail( "IllegalArgumentException expected for type DOCUMENT_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.DOCUMENT_TYPE_NODE ); |
| fail( "IllegalArgumentException expected for type " + "DOCUMENT_TYPE_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.ENTITY_NODE ); |
| fail( "IllegalArgumentException expected for type ENTITY_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.ENTITY_REFERENCE_NODE ); |
| fail( "IllegalArgumentException expected for type " + "ENTITY_REFERENCE_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.NOTATION_NODE ); |
| fail( "IllegalArgumentException expected for type NOTATION_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.PROCESSING_INSTRUCTION_NODE ); |
| fail( "IllegalArgumentException expected for type " + "PROCESSING_INSTRUCTION_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| try |
| { |
| Rule rule = new NodeCreateRule( Node.TEXT_NODE ); |
| fail( "IllegalArgumentException expected for type TEXT_NODE" ); |
| assertNotNull( rule ); // just to prevent compiler warning on unused var |
| } |
| catch ( IllegalArgumentException iae ) |
| { |
| // expected |
| } |
| |
| } |
| |
| /** |
| * Tests simple element construction, using the {@link #TEST_XML} XML input data. |
| */ |
| @Test |
| public void testElement() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "root/alpha" ).createNode(); |
| } |
| |
| }).newDigester(); |
| |
| Element element = digester.parse( new StringReader( TEST_XML ) ); |
| |
| assertNotNull( element ); |
| assertEquals( "alpha", element.getNodeName() ); |
| assertNull( element.getLocalName() ); |
| assertNull( element.getNamespaceURI() ); |
| assertEquals( 1, element.getChildNodes().getLength() ); |
| assertEquals( "ALPHA BODY", element.getFirstChild().getNodeValue() ); |
| |
| } |
| |
| /** |
| * Tests simple fragment construction, using the {@link #TEST_XML} XML input data. |
| */ |
| @Test |
| public void testDocumentFragment() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "root" ).createNode().ofType( NodeType.DOCUMENT_FRAGMENT ); |
| } |
| |
| }).newDigester(); |
| |
| DocumentFragment fragment = digester.parse( new StringReader( TEST_XML ) ); |
| |
| assertNotNull( fragment ); |
| assertEquals( 4, fragment.getChildNodes().getLength() ); |
| |
| Node rootBody = fragment.getFirstChild(); |
| assertEquals( Node.TEXT_NODE, rootBody.getNodeType() ); |
| assertEquals( "ROOT BODY", rootBody.getNodeValue() ); |
| |
| Node alpha = fragment.getChildNodes().item( 1 ); |
| assertEquals( Node.ELEMENT_NODE, alpha.getNodeType() ); |
| assertEquals( "alpha", alpha.getNodeName() ); |
| assertNull( ( (Element) alpha ).getLocalName() ); |
| assertNull( ( (Element) alpha ).getNamespaceURI() ); |
| assertEquals( 1, alpha.getChildNodes().getLength() ); |
| assertEquals( "ALPHA BODY", alpha.getFirstChild().getNodeValue() ); |
| |
| Node beta = fragment.getChildNodes().item( 2 ); |
| assertEquals( Node.ELEMENT_NODE, beta.getNodeType() ); |
| assertEquals( "beta", beta.getNodeName() ); |
| assertNull( ( (Element) beta ).getLocalName() ); |
| assertNull( ( (Element) beta ).getNamespaceURI() ); |
| assertEquals( 1, beta.getChildNodes().getLength() ); |
| assertEquals( "BETA BODY", beta.getFirstChild().getNodeValue() ); |
| |
| Node gamma = fragment.getChildNodes().item( 3 ); |
| assertEquals( Node.ELEMENT_NODE, gamma.getNodeType() ); |
| assertEquals( "gamma", gamma.getNodeName() ); |
| assertNull( ( (Element) gamma ).getLocalName() ); |
| assertNull( ( (Element) gamma ).getNamespaceURI() ); |
| assertEquals( 1, gamma.getChildNodes().getLength() ); |
| assertEquals( "GAMMA BODY", gamma.getFirstChild().getNodeValue() ); |
| |
| } |
| |
| /** |
| * Tests whether control is returned to digester after fragment construction. |
| */ |
| @Test |
| public void testNested() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "root" ).createObject().ofType( ArrayList.class ); |
| forPattern( "root/a/b" ).createNode().ofType( NodeType.DOCUMENT_FRAGMENT ) |
| .then() |
| .setRoot( "add" ); |
| forPattern( "root/b" ).createObject().ofType( String.class ) |
| .then() |
| .setRoot( "add" ); |
| } |
| |
| }).newDigester(); |
| |
| List<?> list = digester.parse( getInputStream( "Test4.xml" ) ); |
| |
| assertNotNull( list ); |
| assertEquals( 2, list.size() ); |
| |
| assertTrue( list.get( 0 ) instanceof DocumentFragment ); |
| DocumentFragment fragment = (DocumentFragment) list.get( 0 ); |
| |
| assertEquals( Node.ELEMENT_NODE, fragment.getFirstChild().getNodeType() ); |
| Element a = (Element) fragment.getFirstChild(); |
| assertEquals( "a", a.getNodeName() ); |
| assertEquals( 1, a.getAttributes().getLength() ); |
| assertEquals( "THREE", a.getAttribute( "name" ) ); |
| |
| assertTrue( list.get( 1 ) instanceof String ); |
| |
| } |
| |
| /** |
| * Tests whether attributes are correctly imported into the fragment, using the example in the Test1 XML file. |
| */ |
| @Test |
| public void testAttributes() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "employee" ).createNode().ofType( NodeType.DOCUMENT_FRAGMENT ); |
| } |
| |
| }).newDigester(); |
| |
| DocumentFragment fragment = digester.parse( getInputStream( "Test1.xml" ) ); |
| |
| assertNotNull( fragment ); |
| assertEquals( 2, fragment.getChildNodes().getLength() ); |
| |
| assertEquals( Node.ELEMENT_NODE, fragment.getFirstChild().getNodeType() ); |
| Element address1 = (Element) fragment.getFirstChild(); |
| assertEquals( "address", address1.getNodeName() ); |
| assertEquals( 5, address1.getAttributes().getLength() ); |
| assertEquals( "home", address1.getAttribute( "type" ) ); |
| assertEquals( "Home Street", address1.getAttribute( "street" ) ); |
| assertEquals( "Home City", address1.getAttribute( "city" ) ); |
| assertEquals( "HS", address1.getAttribute( "state" ) ); |
| assertEquals( "HmZip", address1.getAttribute( "zipCode" ) ); |
| |
| assertEquals( Node.ELEMENT_NODE, fragment.getLastChild().getNodeType() ); |
| Element address2 = (Element) fragment.getLastChild(); |
| assertEquals( "address", address2.getNodeName() ); |
| assertEquals( 5, address2.getAttributes().getLength() ); |
| assertEquals( "office", address2.getAttribute( "type" ) ); |
| assertEquals( "Office Street", address2.getAttribute( "street" ) ); |
| assertEquals( "Office City", address2.getAttribute( "city" ) ); |
| assertEquals( "OS", address2.getAttribute( "state" ) ); |
| assertEquals( "OfZip", address2.getAttribute( "zipCode" ) ); |
| |
| } |
| |
| /** |
| * Tests whether namespaces are handled correctly, using the example from the file Test3 XML file. |
| */ |
| @Test |
| public void testNamespaces() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "employee" ).createNode().ofType( NodeType.DOCUMENT_FRAGMENT ); |
| } |
| |
| }) |
| .setNamespaceAware( true ) |
| .newDigester(); |
| |
| DocumentFragment fragment = digester.parse( getInputStream( "Test3.xml" ) ); |
| |
| assertNotNull( fragment ); |
| assertEquals( 2, fragment.getChildNodes().getLength() ); |
| |
| assertEquals( Node.ELEMENT_NODE, fragment.getFirstChild().getNodeType() ); |
| Element address1 = (Element) fragment.getFirstChild(); |
| assertEquals( "address", address1.getNodeName() ); |
| assertEquals( "http://commons.apache.org/digester/Bar", address1.getNamespaceURI() ); |
| assertEquals( "address", address1.getLocalName() ); |
| assertEquals( 5, address1.getAttributes().getLength() ); |
| assertEquals( "home", address1.getAttribute( "type" ) ); |
| assertEquals( "Home Street", address1.getAttribute( "street" ) ); |
| assertEquals( "Home City", address1.getAttribute( "city" ) ); |
| assertEquals( "HS", address1.getAttribute( "state" ) ); |
| assertEquals( "HmZip", address1.getAttribute( "zipCode" ) ); |
| |
| assertEquals( Node.ELEMENT_NODE, fragment.getLastChild().getNodeType() ); |
| Element address2 = (Element) fragment.getLastChild(); |
| assertEquals( "address", address2.getNodeName() ); |
| assertEquals( "http://commons.apache.org/digester/Bar", address2.getNamespaceURI() ); |
| assertEquals( "address", address2.getLocalName() ); |
| assertEquals( 5, address2.getAttributes().getLength() ); |
| assertEquals( "office", address2.getAttribute( "type" ) ); |
| assertEquals( "Office Street", address2.getAttribute( "street" ) ); |
| assertEquals( "Office City", address2.getAttribute( "city" ) ); |
| assertEquals( "OS", address2.getAttribute( "state" ) ); |
| assertEquals( "OfZip", address2.getAttribute( "zipCode" ) ); |
| |
| } |
| |
| /** |
| * Tests whether namespaced attributes are handled correctly, using the example from the file Test10 XML file. |
| */ |
| @Test |
| public void testNamespacedAttribute() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "employee" ).createNode().ofType( NodeType.ELEMENT ); |
| } |
| |
| }) |
| .setNamespaceAware( true ) |
| .newDigester(); |
| |
| Element element = digester.parse( getInputStream( "Test10.xml" ) ); |
| |
| assertNotNull( element ); |
| |
| assertNotNull( element.getAttributeNodeNS( "http://commons.apache.org/digester/Bar", "test" ) ); |
| assertEquals( "MyTestAttribute", |
| element.getAttributeNodeNS( "http://commons.apache.org/digester/Bar", "test" ).getNodeValue() ); |
| assertEquals( "test", |
| element.getAttributeNodeNS( "http://commons.apache.org/digester/Bar", "test" ).getLocalName() ); |
| assertEquals( "bar", element.getAttributeNodeNS( "http://commons.apache.org/digester/Bar", "test" ).getPrefix() ); |
| assertEquals( "bar:test", |
| element.getAttributeNodeNS( "http://commons.apache.org/digester/Bar", "test" ).getName() ); |
| |
| } |
| |
| /** |
| * Tests whether non-namespaced attributes are handled correctly, using the example from the file Test11 XML file. |
| */ |
| @Test |
| public void testNonNamespacedAttribute() |
| throws SAXException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "employee" ).createNode().ofType( NodeType.ELEMENT ); |
| } |
| |
| }) |
| .setNamespaceAware( true ) |
| .newDigester(); |
| |
| Element element = digester.parse( getInputStream( "Test10.xml" ) ); |
| |
| assertNotNull( element ); |
| |
| assertNotNull( element.getAttributeNode( "firstName" ) ); |
| assertEquals( "First Name", element.getAttributeNode( "firstName" ).getNodeValue() ); |
| assertEquals( "firstName", element.getAttributeNode( "firstName" ).getLocalName() ); |
| assertEquals( null, element.getAttributeNode( "firstName" ).getPrefix() ); |
| assertEquals( "firstName", element.getAttributeNode( "firstName" ).getName() ); |
| |
| } |
| |
| /** |
| * Tests whether the created fragment can be imported into an existing document. |
| */ |
| @Test |
| public void testImport() |
| throws SAXException, ParserConfigurationException, IOException |
| { |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "root" ).createNode().ofType( NodeType.DOCUMENT_FRAGMENT ); |
| } |
| |
| }) |
| .newDigester(); |
| |
| DocumentFragment fragment = digester.parse( new StringReader( TEST_XML ) ); |
| |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.newDocument(); |
| Node importedFragment = doc.importNode( fragment, true ); |
| doc.appendChild( doc.createElement( "root" ) ); |
| doc.getFirstChild().appendChild( importedFragment ); |
| |
| } |
| |
| /** |
| * This unit test checks that text nodes are correctly created when xml entities are used. In particular, this |
| * usually causes the xml parser to make multiple invocations of the characters(..) sax callback, rather than just |
| * one. |
| */ |
| @Test |
| public void testEntityText() |
| throws Exception |
| { |
| String TEST_XML2 = "<?xml version='1.0'?><root><alpha>A A</alpha></root>"; |
| |
| Digester digester = newLoader( new AbstractRulesModule() |
| { |
| |
| @Override |
| protected void configure() |
| { |
| forPattern( "root/alpha" ).createNode(); |
| } |
| |
| }) |
| .newDigester(); |
| |
| Element element = digester.parse( new StringReader( TEST_XML2 ) ); |
| |
| assertNotNull( element ); |
| assertEquals( "alpha", element.getNodeName() ); |
| assertNull( element.getLocalName() ); |
| assertNull( element.getNamespaceURI() ); |
| assertEquals( 1, element.getChildNodes().getLength() ); |
| assertEquals( "A A", element.getFirstChild().getNodeValue() ); |
| } |
| |
| // ------------------------------------------------ Utility Support Methods |
| |
| /** |
| * Return an appropriate InputStream for the specified test file (which must be inside our current package. |
| * |
| * @param name Name of the test file we want |
| * @throws IOException if an input/output error occurs |
| */ |
| protected InputStream getInputStream( String name ) |
| throws IOException |
| { |
| |
| return ( this.getClass().getResourceAsStream( "/org/apache/commons/digester3/" + name ) ); |
| |
| } |
| |
| } |