Package org.apache.commons.digester3

Source Code of org.apache.commons.digester3.RuleTestCase

/* $Id: RuleTestCase.java 1212599 2011-12-09 19:46:42Z simonetripodi $
*
* 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.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.util.ArrayList;

import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.ExtendedBaseRules;
import org.apache.commons.digester3.RuleSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;

/**
* <p>
* Test Case for the Digester class. These tests perform parsing of XML documents to exercise the built-in rules.
* </p>
*
* @author Craig R. McClanahan
* @author Janek Bogucki
*/
public class RuleTestCase
{

    // ----------------------------------------------------- Instance Variables

    /**
     * The digester instance we will be processing.
     */
    protected Digester digester = null;

    // --------------------------------------------------- Overall Test Methods

    /**
     * Set up instance variables required by this test case.
     */
    @Before
    public void setUp()
    {

        digester = new Digester();

    }

    /**
     * Tear down instance variables required by this test case.
     */
    @After
    public void tearDown()
    {

        digester = null;

    }

    // ------------------------------------------------ Individual Test Methods

    /**
     * Test object creation (and associated property setting) with nothing on the stack, which should cause an
     * appropriate Employee object to be returned.
     */
    @Test
    public void testObjectCreate1()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", "org.apache.commons.digester3.Employee" );
        digester.addSetProperties( "employee" );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test1.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );

    }

    /**
     * Test object creation (and associated property setting) with nothing on the stack, which should cause an
     * appropriate Employee object to be returned. The processing rules will process the nested Address elements as
     * well, but will not attempt to add them to the Employee.
     */
    @Test
    public void testObjectCreate2()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", Employee.class );
        digester.addSetProperties( "employee" );
        digester.addObjectCreate( "employee/address", "org.apache.commons.digester3.Address" );
        digester.addSetProperties( "employee/address" );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test1.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );

    }

    /**
     * Test object creation (and associated property setting) with nothing on the stack, which should cause an
     * appropriate Employee object to be returned. The processing rules will process the nested Address elements as
     * well, and will add them to the owning Employee.
     */
    @Test
    public void testObjectCreate3()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", Employee.class );
        digester.addSetProperties( "employee" );
        digester.addObjectCreate( "employee/address", "org.apache.commons.digester3.Address" );
        digester.addSetProperties( "employee/address" );
        digester.addSetNext( "employee/address", "addAddress" );

        // Parse our test input once
        Object root = null;
        root = digester.parse( getInputStream( "Test1.xml" ) );

        validateObjectCreate3( root );

        // Parse the same input again
        try
        {
            root = digester.parse( getInputStream( "Test1.xml" ) );
        }
        catch ( Throwable t )
        {
            fail( "Digester threw IOException: " + t );
        }
        validateObjectCreate3( root );

    }

    /**
     * Same as testObjectCreate1(), except use individual call method rules to set the properties of the Employee.
     */
    @Test
    public void testObjectCreate4()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", Employee.class );
        digester.addCallMethod( "employee", "setFirstName", 1 );
        digester.addCallParam( "employee", 0, "firstName" );
        digester.addCallMethod( "employee", "setLastName", 1 );
        digester.addCallParam( "employee", 0, "lastName" );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test1.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );

    }

    /**
     * Same as testObjectCreate1(), except use individual call method rules to set the properties of the Employee. Bean
     * data are defined using elements instead of attributes. The purpose is to test CallMethod with a paramCount=0 (ie
     * the body of the element is the argument of the method).
     */
    @Test
    public void testObjectCreate5()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", Employee.class );
        digester.addCallMethod( "employee/firstName", "setFirstName", 0 );
        digester.addCallMethod( "employee/lastName", "setLastName", 0 );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test5.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );

    }

    /**
     * It should be possible to parse the same input twice, and get trees of objects that are isomorphic but not be
     * identical object instances.
     */
    @Test
    public void testRepeatedParse()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", Employee.class );
        digester.addSetProperties( "employee" );
        digester.addObjectCreate( "employee/address", "org.apache.commons.digester3.Address" );
        digester.addSetProperties( "employee/address" );
        digester.addSetNext( "employee/address", "addAddress" );

        // Parse our test input the first time
        Object root1 = null;
        root1 = digester.parse( getInputStream( "Test1.xml" ) );

        validateObjectCreate3( root1 );

        // Parse our test input the second time
        Object root2 = null;
        root2 = digester.parse( getInputStream( "Test1.xml" ) );

        validateObjectCreate3( root2 );

        // Make sure that it was a different root
        assertTrue( "Different tree instances were returned", root1 != root2 );

    }

    /**
     * Test object creation (and associated property setting) with nothing on the stack, which should cause an
     * appropriate Employee object to be returned. The processing rules will process the nested Address elements as
     * well, but will not attempt to add them to the Employee.
     */
    @Test
    public void testRuleSet1()
        throws SAXException, IOException
    {

        // Configure the digester as required
        RuleSet rs = new TestRuleSet();
        digester.addRuleSet( rs );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test1.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );
        assertNotNull( "Can retrieve home address", employee.getAddress( "home" ) );
        assertNotNull( "Can retrieve office address", employee.getAddress( "office" ) );

    }

    /**
     * Same as <code>testRuleSet1</code> except using a single namespace.
     */
    @Test
    public void testRuleSet2()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.setNamespaceAware( true );
        RuleSet rs = new TestRuleSet( null, "http://commons.apache.org/digester/Foo" );
        digester.addRuleSet( rs );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test2.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );
        assertNotNull( "Can retrieve home address", employee.getAddress( "home" ) );
        assertNotNull( "Can retrieve office address", employee.getAddress( "office" ) );

    }

    /**
     * Same as <code>testRuleSet2</code> except using a namespace for employee that we should recognize, and a namespace
     * for address that we should skip.
     */
    @Test
    public void testRuleSet3()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.setNamespaceAware( true );
        RuleSet rs = new TestRuleSet( null, "http://commons.apache.org/digester/Foo" );
        digester.addRuleSet( rs );

        // Parse our test input.
        Employee employee = digester.parse( getInputStream( "Test3.xml" ) );

        assertNotNull( "Digester returned an object", employee );
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );
        assertNull( "Can not retrieve home address", employee.getAddress( "home" ) );
        assertNull( "Can not retrieve office address", employee.getAddress( "office" ) );

    }

    /**
     * Test the two argument version of the SetTopRule rule. This test is based on testObjectCreate3 and should result
     * in the same tree of objects. Instead of using the SetNextRule rule which results in a method invocation on the
     * (top-1) (parent) object with the top object (child) as an argument, this test uses the SetTopRule rule which
     * results in a method invocation on the top object (child) with the top-1 (parent) object as an argument. The three
     * argument form is tested in <code>testSetTopRule2</code>.
     */
    @Test
    public void testSetTopRule1()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", "org.apache.commons.digester3.Employee" );
        digester.addSetProperties( "employee" );
        digester.addObjectCreate( "employee/address", "org.apache.commons.digester3.Address" );
        digester.addSetProperties( "employee/address" );
        digester.addSetTop( "employee/address", "setEmployee" );

        // Parse our test input.
        Object root = null;
        root = digester.parse( getInputStream( "Test1.xml" ) );
        validateObjectCreate3( root );

    }

    /**
     * Same as <code>testSetTopRule1</code> except using the three argument form of the SetTopRule rule.
     */
    @Test
    public void testSetTopRule2()
        throws SAXException, IOException
    {

        // Configure the digester as required
        digester.addObjectCreate( "employee", "org.apache.commons.digester3.Employee" );
        digester.addSetProperties( "employee" );
        digester.addObjectCreate( "employee/address", "org.apache.commons.digester3.Address" );
        digester.addSetProperties( "employee/address" );
        digester.addSetTop( "employee/address", "setEmployee", "org.apache.commons.digester3.Employee" );

        // Parse our test input.
        Object root = null;
        root = digester.parse( getInputStream( "Test1.xml" ) );

        validateObjectCreate3( root );

    }

    /**
     * Test rule addition - this boils down to making sure that digester is set properly on rule addition.
     */
    @Test
    public void testAddRule()
    {
        Digester digester = new Digester();
        TestRule rule = new TestRule( "Test" );
        digester.addRule( "/root", rule );

        assertEquals( "Digester is not properly on rule addition.", digester, rule.getDigester() );

    }

    @Test
    public void testSetNext()
        throws SAXException, IOException
    {
        Digester digester = new Digester();
        digester.setRules( new ExtendedBaseRules() );
        digester.setValidating( false );

        digester.addObjectCreate( "!*/b", BetaBean.class );
        digester.addObjectCreate( "!*/a", AlphaBean.class );
        digester.addObjectCreate( "root", ArrayList.class );
        digester.addSetProperties( "!*" );
        digester.addSetNext( "!*/b/?", "setChild" );
        digester.addSetNext( "!*/a/?", "setChild" );
        digester.addSetNext( "!root/?", "add" );
        ArrayList<?> root = digester.parse( getInputStream( "Test4.xml" ) );

        assertEquals( "Wrong array size", 2, root.size() );
        AlphaBean one = (AlphaBean) root.get( 0 );
        assertTrue( one.getChild() instanceof BetaBean );
        BetaBean two = (BetaBean) one.getChild();
        assertEquals( "Wrong name (1)", two.getName(), "TWO" );
        assertTrue( two.getChild() instanceof AlphaBean );
        AlphaBean three = (AlphaBean) two.getChild();
        assertEquals( "Wrong name (2)", three.getName(), "THREE" );
        BetaBean four = (BetaBean) root.get( 1 );
        assertEquals( "Wrong name (3)", four.getName(), "FOUR" );
        assertTrue( four.getChild() instanceof BetaBean );
        BetaBean five = (BetaBean) four.getChild();
        assertEquals( "Wrong name (4)", five.getName(), "FIVE" );

    }

    @Test
    public void testSetTop()
        throws SAXException, IOException
    {
        Digester digester = new Digester();
        digester.setRules( new ExtendedBaseRules() );
        digester.setValidating( false );

        digester.addObjectCreate( "!*/b", BetaBean.class );
        digester.addObjectCreate( "!*/a", AlphaBean.class );
        digester.addObjectCreate( "root", ArrayList.class );
        digester.addSetProperties( "!*" );
        digester.addSetTop( "!*/b/?", "setParent" );
        digester.addSetTop( "!*/a/?", "setParent" );
        digester.addSetRoot( "!*/a", "add" );
        digester.addSetRoot( "!*/b", "add" );
        ArrayList<?> root = digester.parse( getInputStream( "Test4.xml" ) );

        assertEquals( "Wrong array size", 5, root.size() );

        // note that the array is in popped order (rather than pushed)

        Object obj = root.get( 1 );
        assertTrue( "TWO should be a BetaBean", obj instanceof BetaBean );
        BetaBean two = (BetaBean) obj;
        assertNotNull( "Two's parent should not be null", two.getParent() );
        assertEquals( "Wrong name (1)", "TWO", two.getName() );
        assertEquals( "Wrong name (2)", "ONE", two.getParent().getName() );

        obj = root.get( 0 );
        assertTrue( "THREE should be an AlphaBean", obj instanceof AlphaBean );
        AlphaBean three = (AlphaBean) obj;
        assertNotNull( "Three's parent should not be null", three.getParent() );
        assertEquals( "Wrong name (3)", "THREE", three.getName() );
        assertEquals( "Wrong name (4)", "TWO", three.getParent().getName() );

        obj = root.get( 3 );
        assertTrue( "FIVE should be a BetaBean", obj instanceof BetaBean );
        BetaBean five = (BetaBean) obj;
        assertNotNull( "Five's parent should not be null", five.getParent() );
        assertEquals( "Wrong name (5)", "FIVE", five.getName() );
        assertEquals( "Wrong name (6)", "FOUR", five.getParent().getName() );

    }

    /**
     */
    @Test
    public void testSetCustomProperties()
        throws SAXException, IOException
    {

        Digester digester = new Digester();

        digester.setValidating( false );

        digester.addObjectCreate( "toplevel", ArrayList.class );
        digester.addObjectCreate( "toplevel/one", Address.class );
        digester.addSetNext( "toplevel/one", "add" );
        digester.addObjectCreate( "toplevel/two", Address.class );
        digester.addSetNext( "toplevel/two", "add" );
        digester.addObjectCreate( "toplevel/three", Address.class );
        digester.addSetNext( "toplevel/three", "add" );
        digester.addObjectCreate( "toplevel/four", Address.class );
        digester.addSetNext( "toplevel/four", "add" );
        digester.addSetProperties( "toplevel/one" );
        digester.addSetProperties( "toplevel/two", new String[] { "alt-street", "alt-city", "alt-state" },
                                   new String[] { "street", "city", "state" } );
        digester.addSetProperties( "toplevel/three", new String[] { "aCity", "state" }, new String[] { "city" } );
        digester.addSetProperties( "toplevel/four", "alt-city", "city" );

        ArrayList<?> root = digester.parse( getInputStream( "Test7.xml" ) );

        assertEquals( "Wrong array size", 4, root.size() );

        // note that the array is in popped order (rather than pushed)

        Object obj = root.get( 0 );
        assertTrue( "(1) Should be an Address ", obj instanceof Address );
        Address addressOne = (Address) obj;
        assertEquals( "(1) Street attribute", "New Street", addressOne.getStreet() );
        assertEquals( "(1) City attribute", "Las Vegas", addressOne.getCity() );
        assertEquals( "(1) State attribute", "Nevada", addressOne.getState() );

        obj = root.get( 1 );
        assertTrue( "(2) Should be an Address ", obj instanceof Address );
        Address addressTwo = (Address) obj;
        assertEquals( "(2) Street attribute", "Old Street", addressTwo.getStreet() );
        assertEquals( "(2) City attribute", "Portland", addressTwo.getCity() );
        assertEquals( "(2) State attribute", "Oregon", addressTwo.getState() );

        obj = root.get( 2 );
        assertTrue( "(3) Should be an Address ", obj instanceof Address );
        Address addressThree = (Address) obj;
        assertEquals( "(3) Street attribute", "4th Street", addressThree.getStreet() );
        assertEquals( "(3) City attribute", "Dayton", addressThree.getCity() );
        assertEquals( "(3) State attribute", "US", addressThree.getState() );

        obj = root.get( 3 );
        assertTrue( "(4) Should be an Address ", obj instanceof Address );
        Address addressFour = (Address) obj;
        assertEquals( "(4) Street attribute", "6th Street", addressFour.getStreet() );
        assertEquals( "(4) City attribute", "Cleveland", addressFour.getCity() );
        assertEquals( "(4) State attribute", "Ohio", addressFour.getState() );

    }

    // ------------------------------------------------ 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
     * @exception IOException if an input/output error occurs
     */
    protected InputStream getInputStream( String name )
        throws IOException
    {

        return ( this.getClass().getResourceAsStream( "/org/apache/commons/digester3/" + name ) );

    }

    /**
     * Validate the assertions for ObjectCreateRule3.
     *
     * @param root Root object returned by <code>digester.parse()</code>
     */
    protected void validateObjectCreate3( Object root )
    {

        // Validate the retrieved Employee
        assertNotNull( "Digester returned an object", root );
        assertTrue( "Digester returned an Employee", root instanceof Employee );
        Employee employee = (Employee) root;
        assertEquals( "First name is correct", "First Name", employee.getFirstName() );
        assertEquals( "Last name is correct", "Last Name", employee.getLastName() );

        // Validate the corresponding "home" Address
        Address home = employee.getAddress( "home" );
        assertNotNull( "Retrieved home address", home );
        assertEquals( "Home street", "Home Street", home.getStreet() );
        assertEquals( "Home city", "Home City", home.getCity() );
        assertEquals( "Home state", "HS", home.getState() );
        assertEquals( "Home zip", "HmZip", home.getZipCode() );

        // Validate the corresponding "office" Address
        Address office = employee.getAddress( "office" );
        assertNotNull( "Retrieved office address", office );
        assertEquals( "Office street", "Office Street", office.getStreet() );
        assertEquals( "Office city", "Office City", office.getCity() );
        assertEquals( "Office state", "OS", office.getState() );
        assertEquals( "Office zip", "OfZip", office.getZipCode() );

    }

}
TOP

Related Classes of org.apache.commons.digester3.RuleTestCase

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.