/*
 * Copyright 2004-2005 The Apache Software Foundation.
 * 
 * Licensed 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.tiles.xmlDefinition;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

/**
 * Parse an XML definitions file.
 *
 * @author Cedric Dumoulin
 * @author David Geary
 */
public class XmlParser {
    /** Associated digester. */
  protected Digester digester;
    /**
     * Should we use a validating XML parser to read the configuration file.
     * Default is <code>false</code>.
     */
    protected boolean validating = false;
    /**
     * The set of public identifiers, and corresponding resource names for
     * the versions of the configuration file DTDs we know about.  There
     * <strong>MUST</strong> be an even number of Strings in this list!
     */
    protected String registrations[] = {
          // pre 1.1
        "-//Apache Software Foundation//DTD Tiles Configuration//EN",
        "/org/apache/struts/resources/tiles-config_1_1.dtd",
        "-//Apache Software Foundation//DTD Components Configuration//EN",
        "/org/apache/struts/resources/tiles-config.dtd",
         // version 1.1
        "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
        "/org/apache/struts/resources/tiles-config_1_1.dtd",
        // version 1.2
        "-//Apache Software Foundation//DTD Tiles Configuration 1.2//EN",
        "/org/apache/tiles/resources/tiles-config_1_2.dtd"
    };

     /**
      * Constructor.
      * Creates a digester parser and initializes syntax rules.
      */
  public XmlParser()
  {
	digester = new Digester();
	digester.setValidating(validating);
	digester.setNamespaceAware(true);
	digester.setUseContextClassLoader(true);
	// Register our local copy of the DTDs that we can find
  for (int i = 0; i < registrations.length; i += 2) {
      URL url = this.getClass().getResource(registrations[i+1]);
      if (url != null)
          {
          digester.register(registrations[i], url.toString());
          }
  }
    // Init syntax rules
  initDigester( digester );
  }

    /**
     * Set digester validating flag.
     */
  public void setValidating( boolean validating )
    {
    digester.setValidating( validating);
    }


   /**
    * Init digester for components syntax.
    * This is an old set of rules, left for backward compatibility.
    * @param digester Digester instance to use.
    */
  private void initDigesterForComponentsDefinitionsSyntax( Digester digester )
  {
	 // Common constants
  String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
  String DEFINITION_TAG = "component-definitions/definition";
  String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";

  String PUT_TAG  = DEFINITION_TAG + "/put";
  String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";

  String LIST_TAG = DEFINITION_TAG + "/putList";
  String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";

  String ADD_LIST_ELE_TAG = LIST_TAG + "/add";

    // syntax rules
	digester.addObjectCreate(  DEFINITION_TAG, definitionHandlerClass );
	digester.addSetProperties( DEFINITION_TAG);
	digester.addSetNext(       DEFINITION_TAG, "putDefinition", definitionHandlerClass);
    // put / putAttribute rules
	digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
	digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
	digester.addSetProperties( PUT_TAG);
	digester.addCallMethod(    PUT_TAG, "setBody", 0);
    // list rules
	digester.addObjectCreate(  LIST_TAG, listHandlerClass);
	digester.addSetProperties( LIST_TAG);
	digester.addSetNext(       LIST_TAG, "addAttribute", putAttributeHandlerClass);
    // list elements rules
    // We use Attribute class to avoid rewriting a new class.
    // Name part can't be used in listElement attribute.
	digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
	digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
	digester.addSetProperties( ADD_LIST_ELE_TAG);
	digester.addCallMethod(    ADD_LIST_ELE_TAG, "setBody", 0);
  }

   /**
    * Init digester for Tiles syntax.
    * Same as components, but with first element = tiles-definitions
    * @param digester Digester instance to use.
    */
  private void initDigesterForTilesDefinitionsSyntax( Digester digester )
  {
	 // Common constants
  String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
  String DEFINITION_TAG = "tiles-definitions/definition";
  String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";

  String PUT_TAG  = DEFINITION_TAG + "/put";
  String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";

  //String LIST_TAG = DEFINITION_TAG + "/putList";
    // List tag value
  String LIST_TAG = "putList";
  String DEF_LIST_TAG = DEFINITION_TAG + "/" + LIST_TAG;
  String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";
    // Tag value for adding an element in a list
  String ADD_LIST_ELE_TAG = "*/" + LIST_TAG + "/add";

    // syntax rules
	digester.addObjectCreate(  DEFINITION_TAG, definitionHandlerClass );
	digester.addSetProperties( DEFINITION_TAG);
	digester.addSetNext(       DEFINITION_TAG, "putDefinition", definitionHandlerClass);
    // put / putAttribute rules
    // Rules for a same pattern are called in order, but rule.end() are called
    // in reverse order.
    // SetNext and CallMethod use rule.end() method. So, placing SetNext in
    // first position ensure it will be called last (sic).
	digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
	digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
	digester.addSetProperties( PUT_TAG);
	digester.addCallMethod(    PUT_TAG, "setBody", 0);
    // Definition level list rules
    // This is rules for lists nested in a definition
	digester.addObjectCreate(  DEF_LIST_TAG, listHandlerClass);
	digester.addSetProperties( DEF_LIST_TAG);
	digester.addSetNext(       DEF_LIST_TAG, "addAttribute", putAttributeHandlerClass);
    // list elements rules
    // We use Attribute class to avoid rewriting a new class.
    // Name part can't be used in listElement attribute.
	digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
	digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
	digester.addSetProperties( ADD_LIST_ELE_TAG);
	digester.addCallMethod(    ADD_LIST_ELE_TAG, "setBody", 0);

    // nested list elements rules
    // Create a list handler, and add it to parent list
  String NESTED_LIST = "*/" + LIST_TAG + "/" + LIST_TAG;
	digester.addObjectCreate(  NESTED_LIST, listHandlerClass);
	digester.addSetProperties( NESTED_LIST);
	digester.addSetNext(       NESTED_LIST, "add", putAttributeHandlerClass);

    // item elements rules
    // We use Attribute class to avoid rewriting a new class.
    // Name part can't be used in listElement attribute.
  //String ADD_WILDCARD = LIST_TAG + "/addItem";
  // non String ADD_WILDCARD = LIST_TAG + "/addx*";
  String ADD_WILDCARD = "*/item";
  String menuItemDefaultClass = "org.apache.tiles.beans.SimpleMenuItem";
	digester.addObjectCreate(  ADD_WILDCARD, menuItemDefaultClass, "classtype");
	digester.addSetNext(       ADD_WILDCARD, "add", "java.lang.Object");
	digester.addSetProperties( ADD_WILDCARD);

    // bean elements rules
  String BEAN_TAG = "*/bean";
  String beanDefaultClass = "org.apache.tiles.beans.SimpleMenuItem";
	digester.addObjectCreate(  BEAN_TAG, beanDefaultClass, "classtype");
	digester.addSetNext(       BEAN_TAG, "add", "java.lang.Object");
	digester.addSetProperties( BEAN_TAG);

    // Set properties to surrounding element
  digester.addSetProperty(BEAN_TAG+ "/set-property", "property", "value");
  }

   /**
    * Init digester in order to parse instances definition file syntax.
    * Instances is an old name for "definition". This method is left for
    * backwards compatibility.
    * @param digester Digester instance to use.
    */
  private void initDigesterForInstancesSyntax( Digester digester )
  {
    	// Build a digester to process our configuration resource
  String PACKAGE_NAME = "org.apache.tiles.xmlDefinition";
  String INSTANCE_TAG = "component-instances/instance";
  String instanceHandlerClass = PACKAGE_NAME + ".XmlDefinition";

  String PUT_TAG = INSTANCE_TAG + "/put";
  String PUTATTRIBUTE_TAG = INSTANCE_TAG + "/putAttribute";
  String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";

  String LIST_TAG     = INSTANCE_TAG + "/putList";
  String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";

  String ADD_LIST_ELE_TAG = LIST_TAG + "/add";

    // component instance rules
	digester.addObjectCreate(  INSTANCE_TAG, instanceHandlerClass );
	digester.addSetProperties( INSTANCE_TAG);
	digester.addSetNext(       INSTANCE_TAG, "putDefinition", instanceHandlerClass);
    // put / putAttribute rules
	digester.addObjectCreate(  PUTATTRIBUTE_TAG, putAttributeHandlerClass);
	digester.addSetProperties( PUTATTRIBUTE_TAG);
	digester.addSetNext(       PUTATTRIBUTE_TAG, "addAttribute", putAttributeHandlerClass);
    // put / putAttribute rules
	digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
	digester.addSetProperties( PUT_TAG);
	digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
    // list rules
	digester.addObjectCreate(  LIST_TAG, listHandlerClass);
	digester.addSetProperties( LIST_TAG);
	digester.addSetNext(       LIST_TAG, "addAttribute", putAttributeHandlerClass);
    // list elements rules
    // We use Attribute class to avoid rewriting a new class.
    // Name part can't be used in listElement attribute.
	digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
	digester.addSetProperties( ADD_LIST_ELE_TAG);
	digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
  }

   /**
    * Init digester.
    * @param digester Digester instance to use.
    */
  protected void initDigester( Digester digester )
  {
  initDigesterForTilesDefinitionsSyntax( digester );
  initDigesterForComponentsDefinitionsSyntax( digester );
  initDigesterForInstancesSyntax( digester );
  }

  /**
   * Parse input reader and add encountered definitions to definitions set.
   * @param in Input stream.
   * @param definitions Xml Definitions set to which encountered definition are added.
   * @throws IOException On errors during file parsing.
   * @throws SAXException On errors parsing XML.
   */
  public void parse( InputStream in, XmlDefinitionsSet definitions ) throws IOException, SAXException
  {
	try
    {
      // set first object in stack
    //digester.clear();
    digester.push(definitions);
      // parse
	  digester.parse(in);
	  in.close();
	  }
  catch (SAXException e)
    {
	  //throw new ServletException( "Error while parsing " + mappingConfig, e);
    throw e;
	  }

  }

    /**
     * Main method to check file syntax.
     */
  public static void main(String[] args)
  {
  //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
  String filename = "E:/programs/jakarta-tomcat-4.0.3/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
  //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tilesDefinitions.xml";
  //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-channel/WEB-INF/componentDefinitions.xml";
  //String filename2 = "E:/programs/jakarta-tomcat/webapps/wtiles-tutorial/WEB-INF/componentDefinitions.xml";


    if( args.length > 1 )
      {
      filename = args[1];
      } // end if

  System.out.println( "Read file '" + filename  +"'" );

  InputStream input = null;
  // InputStream input2 = null;
    // Open file
    try
      {
	    input = new BufferedInputStream(
                             new FileInputStream( filename) );
	//    input2 = new BufferedInputStream(
          //                   new FileInputStream( filename2) );
      }
     catch( IOException ex )
      {
      System.out.println( "can't open file '" + filename + "' : " + ex.getMessage() );
      }
    // Check file syntax
    try
      {
	    XmlParser parser = new XmlParser();
      parser.setValidating(true);
      XmlDefinitionsSet definitions = new XmlDefinitionsSet();
        System.out.println( "  Parse file" );
      parser.parse( input, definitions);
      //  System.out.println( "  Check file 2" );
      //parser.parse( input2, definitions);
        System.out.println( "  done." );
      System.out.println( "  Result : " + definitions.toString() );
      }
     catch( Exception ex )
      {
      System.out.println( "Error during parsing '" + filename + "' : " + ex.getMessage() );
      ex.printStackTrace();
      }
  }

}
