/* $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.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
     * @throws 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() );

    }

}
