package org.apache.commons.digester3.examples.api.addressbook;

/*
 * 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.
 */

import org.apache.commons.digester3.Digester;

/**
 * A simple program to demonstrate the basic functionality of the
 * Commons Digester module.
 * <p>
 * This code will parse the provided "example.xml" file to build a tree
 * of java objects, then cause those objects to print out their values
 * to demonstrate that the input file has been processed correctly.
 * <p>
 * As with all code, there are many ways of achieving the same goal;
 * the solution here is only one possible solution to the problem.
* <p>
 * Very verbose comments are included here, as this class is intended
 * as a tutorial; if you look closely at method "addRules", you will
 * see that the amount of code required to use the Digester is actually
 * quite low.
 * <p>
 * Usage: java Main example.xml
 */
public class Main
{

    /**
     * Main method : entry point for running this example program.
     * <p>
     * Usage: java Example example.xml
     */
    public static void main( final String[] args )
    {
        if ( args.length != 1 )
        {
            usage();
            System.exit( -1 );
        }

        final String filename = args[0];

        // Create a Digester instance
        final Digester d = new Digester();

        // Prime the digester stack with an object for rules to
        // operate on. Note that it is quite common for "this"
        // to be the object pushed.
        final AddressBook book = new AddressBook();
        d.push( book );

        // Add rules to the digester that will be triggered while
        // parsing occurs.
        addRules( d );

        // Process the input file.
        try
        {
            final java.io.File srcfile = new java.io.File( filename );
            d.parse( srcfile );
        }
        catch ( final java.io.IOException ioe )
        {
            System.out.println( "Error reading input file:" + ioe.getMessage() );
            System.exit( -1 );
        }
        catch ( final org.xml.sax.SAXException se )
        {
            System.out.println( "Error parsing input file:" + se.getMessage() );
            System.exit( -1 );
        }

        // Print out all the contents of the address book, as loaded from
        // the input file.
        book.print();
    }

    private static void addRules( final Digester d )
    {

        // --------------------------------------------------
        // when we encounter a "person" tag, do the following:

        // create a new instance of class Person, and push that
        // object onto the digester stack of objects
        d.addObjectCreate( "address-book/person", Person.class );

        // map *any* attributes on the tag to appropriate
        // setter-methods on the top object on the stack (the Person
        // instance created by the preceeding rule).
        //
        // For example:
        // if attribute "id" exists on the xml tag, and method setId
        // with one parameter exists on the object that is on top of
        // the digester object stack, then a call will be made to that
        // method. The value will be type-converted from string to
        // whatever type the target method declares (where possible),
        // using the commons ConvertUtils functionality.
        //
        // Attributes on the xml tag for which no setter methods exist
        // on the top object on the stack are just ignored.
        d.addSetProperties( "address-book/person" );

        // call the addPerson method on the second-to-top object on
        // the stack (the AddressBook object), passing the top object
        // on the stack (the recently created Person object).
        d.addSetNext( "address-book/person", "addPerson" );

        // --------------------------------------------------
        // when we encounter a "name" tag, call setName on the top
        // object on the stack, passing the text contained within the
        // body of that name element [specifying a zero parameter count
        // implies one actual parameter, being the body text].
        // The top object on the stack will be a person object, because
        // the pattern address-book/person always triggers the
        // ObjectCreateRule we added previously.
        d.addCallMethod( "address-book/person/name", "setName", 0 );

        // --------------------------------------------------
        // when we encounter an "email" tag, call addEmail on the top
        // object on the stack, passing two parameters: the "type"
        // attribute, and the text within the tag body.
        d.addCallMethod( "address-book/person/email", "addEmail", 2 );
        d.addCallParam( "address-book/person/email", 0, "type" );
        d.addCallParam( "address-book/person/email", 1 );

        // --------------------------------------------------
        // When we encounter an "address" tag, create an instance of class
        // Address and push it on the digester stack of objects. After
        // doing that, call addAddress on the second-to-top object on the
        // digester stack (a "Person" object), passing the top object on
        // the digester stack (the "Address" object). And also set things
        // up so that for each child xml element encountered between the start
        // of the address tag and the end of the address tag, the text
        // contained in that element is passed to a setXXX method on the
        // Address object where XXX is the name of the xml element found.
        d.addObjectCreate( "address-book/person/address", Address.class );
        d.addSetNext( "address-book/person/address", "addAddress" );
        d.addSetNestedProperties( "address-book/person/address" );
    }

    private static void usage()
    {
        System.out.println( "Usage: java Main example.xml" );
    }

}
