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

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import org.apache.commons.digester3.binder.AbstractRulesModule;
import org.junit.Test;
import org.xml.sax.SAXException;

/**
 * <p>
 * Test case for <code>SetNestedPropertiesRule</code>. This contains tests for the main applications of the rule and two
 * more general tests of digester functionality used by this rule.
 */
public class SetNestedPropertiesRuleTestCase
{

    // ----------------------------------------------------- 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>" + "<delta>DELTA BODY</delta>" + "</root>";

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

    /**
     * Test that you can successfully automatically set properties.
     */
    @Test
    public void testAutomaticallySetProperties()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties();
            }

        }).newDigester();

        SimpleTestBean bean = digester.parse( xmlTestReader() );

        // check properties are set correctly
        assertEquals( "Property alpha not set correctly", "ALPHA BODY", bean.getAlpha() );

        assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );

        assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );

        assertEquals( "Property delta not set correctly", "DELTA BODY", bean.getDeltaValue() );
    }

    /**
     * Test that it is an error when a child element exists but no corresponding java property exists.
     */
    @Test
    public void testMandatoryProperties()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties();
            }

        }).newDigester();

        String TEST_XML = "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<badprop>ALPHA BODY</badprop>" + "</root>";

        try
        {
            SimpleTestBean bean = digester.parse( new StringReader( TEST_XML ) );

            // we should never get here...
            fail( "No exception thrown by parse when unknown child element found." );
            assertNotNull( bean ); // just to prevent compiler warning on unused var
        }
        catch ( org.xml.sax.SAXParseException e )
        {
            String msg = e.getMessage();
            if ( msg.indexOf( "badprop" ) >= 0 )
            {
                // ok, this is expected; there is no "setBadprop" method on the
                // SimpleTestBean class...
            }
            else
            {
                fail( "Unexpected parse exception:" + e.getMessage() );
            }
        }
    }

    /**
     * Test that you can customise the property mappings using the constructor which takes arrays-of-strings.
     */
    @Test
    public void testCustomisedProperties1()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties()
                        .addAlias( "alpha" ).forProperty( null )
                        .addAlias( "gamma-alt" ).forProperty( "gamma" )
                        .addAlias( "delta" ).forProperty(  null );
            }

        }).newDigester();

        String TEST_XML =
            "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<alpha>ALPHA BODY</alpha>" + "<beta>BETA BODY</beta>"
                + "<gamma-alt>GAMMA BODY</gamma-alt>" + "<delta>DELTA BODY</delta>" + "</root>";

        SimpleTestBean bean = digester.parse( new StringReader( TEST_XML ) );

        // check properties are set correctly
        assertEquals( "Property alpha was not ignored (it should be)", null, bean.getAlpha() );

        assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );

        assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );

        assertEquals( "Property delta was not ignored (it should be)", null, bean.getDeltaValue() );

        // check no bad rules object is left
        assertEquals( "Digester rules object not reset.", RulesBase.class, digester.getRules().getClass() );
    }

    /**
     * Test that you can ignore a single input xml element using the constructor which takes a single remapping.
     */
    @Test
    public void testCustomisedProperties2a()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties()
                        .addAlias( "alpha" ).forProperty( null );
            }

        }).newDigester();

        String TEST_XML =
            "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<alpha>ALPHA BODY</alpha>" + "<beta>BETA BODY</beta>"
                + "<gamma>GAMMA BODY</gamma>" + "<delta>DELTA BODY</delta>" + "</root>";

        SimpleTestBean bean = digester.parse( new StringReader( TEST_XML ) );

        // check properties are set correctly
        assertEquals( "Property alpha was not ignored (it should be)", null, bean.getAlpha() );

        assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );

        assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );

        assertEquals( "Property delta not set correctly", "DELTA BODY", bean.getDeltaValue() );

        // check no bad rules object is left
        assertEquals( "Digester rules object not reset.", RulesBase.class, digester.getRules().getClass() );
    }

    /**
     * Test that you can customise the property mappings using the constructor which takes a single remapping.
     */
    @Test
    public void testCustomisedProperties2b()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties()
                        .addAlias( "alpha-alt" ).forProperty( "alpha" );
            }

        }).newDigester();

        String TEST_XML =
            "<?xml version='1.0'?>" + "<root>ROOT BODY" + "<alpha-alt>ALPHA BODY</alpha-alt>"
                + "<beta>BETA BODY</beta>" + "<gamma>GAMMA BODY</gamma>" + "<delta>DELTA BODY</delta>" + "</root>";

        SimpleTestBean bean = digester.parse( new StringReader( TEST_XML ) );

        // check properties are set correctly
        assertEquals( "Property alpha not set correctly", "ALPHA BODY", bean.getAlpha() );

        assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );

        assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );

        assertEquals( "Property delta not set correctly", "DELTA BODY", bean.getDeltaValue() );

        // check no bad rules object is left
        assertEquals( "Digester rules object not reset.", RulesBase.class, digester.getRules().getClass() );
    }

    /**
     * Test that:
     * <ul>
     * <li>you can have rules matching the same pattern as the SetNestedPropertiesRule,</li>
     * <li>you can have rules matching child elements of the rule,</li>
     * <li>the Rules object is reset nicely.</li>
     * </ul>
     */
    @Test
    public void testMultiRuleMatch()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root/testbean" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setProperties()
                    .then()
                    .setNestedProperties();
                forPattern( "root/testbean/gamma/prop" ).setProperty( "name" ).extractingValueFromAttribute( "value" );
            }

        }).newDigester();

        String testXml =
            "<?xml version='1.0'?>" + "<root>" + "<testbean alpha='alpha-attr'>ROOT BODY" + "<beta>BETA BODY</beta>"
                + "<gamma>GAMMA " + "<prop name='delta' value='delta-prop'/>" + "BODY" + "</gamma>" + "</testbean>"
                + "</root>";

        Reader reader = new StringReader( testXml );

        SimpleTestBean bean = digester.parse( reader );

        assertNotNull( "No object created", bean );

        // check properties are set correctly
        assertEquals( "Property alpha not set correctly", "alpha-attr", bean.getAlpha() );

        assertEquals( "Property beta not set correctly", "BETA BODY", bean.getBeta() );

        assertEquals( "Property gamma not set correctly", "GAMMA BODY", bean.getGamma() );

        assertEquals( "Property delta not set correctly", "delta-prop", bean.getDeltaValue() );

        // check no bad rules object is left
        assertEquals( "Digester rules object not reset.", RulesBase.class, digester.getRules().getClass() );
    }

    /**
     * Test that unknown child elements trigger an exception.
     */
    @Test
    public void testUnknownChildrenCausesException()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties();
            }

        }).newDigester();

        String testXml =
            "<?xml version='1.0'?>" + "<root>" + "<testbean>" + "<beta>BETA BODY</beta>" + "<foo>GAMMA</foo>"
                + "</testbean>" + "</root>";

        Reader reader = new StringReader( testXml );

        try
        {
            SimpleTestBean bean = digester.parse( reader );
            fail( "Expected to generate an exception." );
            assertNotNull( bean ); // just to prevent compiler warning on unused var
        }
        catch ( SAXException e )
        {
            Exception nested = e.getException();
            if ( ( nested == null ) || !( nested instanceof NoSuchMethodException ) )
            {
                // nope, not the sort of exception we expected
                throw e;
            }
        }
    }

    /**
     * Test that unknown child elements are allowed if the appropriate flag is set.
     */
    @Test
    public void testUnknownChildrenExceptionOverride()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "root" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties().allowUnknownChildElements( true );
            }

        }).newDigester();

        String testXml =
            "<?xml version='1.0'?>" + "<root>" + "<testbean>" + "<beta>BETA BODY</beta>" + "<foo>GAMMA</foo>"
                + "</testbean>" + "</root>";

        Reader reader = new StringReader( testXml );

        SimpleTestBean bean = digester.parse( reader );
        assertNotNull( bean );
    }

    /**
     * Test that the rule works in a sane manner when the associated pattern is a wildcard such that the rule matches
     * one of its own child elements.
     * <p>
     * See bugzilla entry 31393.
     */
    @Test
    public void testRecursiveNestedProperties()
        throws SAXException, IOException
    {
        Digester digester = newLoader( new AbstractRulesModule()
        {

            @Override
            protected void configure()
            {
                forPattern( "*/testbean" ).createObject().ofType( "org.apache.commons.digester3.SimpleTestBean" )
                    .then()
                    .setNestedProperties().allowUnknownChildElements( true );
            }

        }).newDigester();

        String testXml =
            "<?xml version='1.0'?>" + "<testbean>" + "<beta>BETA BODY</beta>" + "<testbean>" + "<beta>BETA BODY</beta>"
                + "</testbean>" + "</testbean>";

        Reader reader = new StringReader( testXml );

        SimpleTestBean bean = digester.parse( reader );
        assertNotNull( bean );
    }

    /**
     * Get input stream from {@link #TEST_XML}.
     */
    private Reader xmlTestReader()
    {
        return new StringReader( TEST_XML );
    }

}
