org.apache.tiles.xmlDefinition.XmlParser.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.tiles.xmlDefinition.XmlParser.java

Source

/*
 * 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();
        }
    }

}