/* $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.digester;


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

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
 * @version $Revision$ $Date$
 */

public class RuleTestCase extends TestCase {


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


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


    // ----------------------------------------------------------- Constructors


    /**
     * Construct a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public RuleTestCase(String name) {

        super(name);

    }


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


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

        digester = new Digester();

    }


    /**
     * Return the tests included in this test suite.
     */
    public static Test suite() {

        return (new TestSuite(RuleTestCase.class));

    }


    /**
     * Tear down instance variables required by this test case.
     */
    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.
     */
    public void testObjectCreate1() throws SAXException, IOException {

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

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

        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());


    }


    /**
     * 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.
     */
    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.digester.Address");
        digester.addSetProperties("employee/address");

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

        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());


    }


    /**
     * 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.
     */
    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.digester.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.
     */
    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.
        Object root = null;
        root = digester.parse(getInputStream("Test1.xml"));

        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());

    }


    /**
     * 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).
     */
    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.
        Object root = null;
        root = digester.parse(getInputStream("Test5.xml"));

        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());

    }


    /**
     * It should be possible to parse the same input twice, and get trees
     * of objects that are isomorphic but not be identical object instances.
     */
    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.digester.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.
     */
    public void testRuleSet1() throws SAXException, IOException {

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

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

        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());
        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.
     */
    public void testRuleSet2() throws SAXException, IOException {

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

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

        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());
        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.
     */
    public void testRuleSet3() throws SAXException, IOException {

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

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

        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());
        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>.
     */
    public void testSetTopRule1() throws SAXException, IOException {

        // Configure the digester as required
        digester.addObjectCreate("employee",
                "org.apache.commons.digester.Employee");
        digester.addSetProperties("employee");
        digester.addObjectCreate("employee/address",
                "org.apache.commons.digester.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.
     */
    public void testSetTopRule2() throws SAXException, IOException {

        // Configure the digester as required
        digester.addObjectCreate("employee",
                "org.apache.commons.digester.Employee");
        digester.addSetProperties("employee");
        digester.addObjectCreate("employee/address",
                "org.apache.commons.digester.Address");
        digester.addSetProperties("employee/address");
        digester.addSetTop("employee/address", "setEmployee",
                "org.apache.commons.digester.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.
     */
    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());

    }
    

    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 = 
            (ArrayList) 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");               
        
    }
    
    
    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 = 
            (ArrayList) 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());

    }


    /**
     */
    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 = 
            (ArrayList) 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/digester/" + name));

    }


    /**
     * Validate the assertions for ObjectCreateRule3.
     *
     * @param object 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());

    }
    

}
