Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Package com.thermidor.xml.output

The com.thermidor.xml package is a generic package providing classes and utilities to support the prograommatic manipulation of XML documents.

See:
          Description

Class Summary
AppendHandler  
FileHandler  
HandlerRegister  
NulHandler  
Output  
OutputHandler The OutputHandler class is the base class for output handlers used by the Output class to manage stack based output.
OutputStack  
OutputType This enumeration details the types of output mechansim that can be used by the Output class in stack based output.
PrintWriterHandler  
StringHandler The purpose of the StringHandler is to manage/collect output into a buffer.
 

Exception Summary
 

Package com.thermidor.xml.output Description

The com.thermidor.xml package is a generic package providing classes and utilities to support the prograommatic manipulation of XML documents. The classes provided here are based on the SAX 2.0 API. Each class provided here builds upon the SAX to provide a fine grained and more powerful framework and solution environment than would be provided by SAX alone.

Use of the SAXParserBase

The SAXParserBase class is a base is provided as a framework for the creation of XML content handlers. The framework captures some of the simplicities of using DOM while maintaing much of the power and efficently of the SAX API. The primary arena for the use of the SAXParserBase as a framework for XML processing is where XML documents have to be converted to in memory models. To put this an other way the XML is really an externalization of an 'object model'

Core to the conception of the SAXParserBase s the SAXEement class. This class in many ways is superficailly similar to the DOM node. On of the recurring issues with SAX programming is the maintence of context while parsing the document. The SAXParserBase does this by maintaining a stack of SAXElements, where each SAXElement instance corresponds to an encountered tag. When a tag is encountered it is pushed on to the stack and passed to the handleStartElement operation. As this context information is maintained on the stack the end elent can be retrieved from the top of the stack when the SAX event is recieved. At this time the element is poped from the stack and passed to the handleEndElement operation. Any PCDATA tat is found that is within the immediate context of the tag is added to the that element. There are a number of rules constraints that apply of the lifecycle of SAXElements as therey are dispatched to the handler operations. In the handleStartElement operation non of the PCDATA for a tag is availbel as the SAXEvent that corresponds to it has not yet been recieved by the SAXParserBase. . Whn the end tag is encounterd all attributes and PCDATA for the tag are availble. This is very different from the basic SAX API and is of considerable utility.

Virtually all content handlers that use the SAXParserBase as their base class follow a similar pattern. The following example illustrates this. It is common that the implementation of a SAXParserBase based content handler consists of two classes, and abstract parser, and its contrete implementation. The abstract parser extends the SAXParserBase to provide a token table and the implementation of the handleStartElement and handleEndElement operations. These two operations are dispathc functions that associate a lookup in the token table with an operation to handle eith the start of end of that element. In many ways each abstract parser is a specialization of the SAX parser paradigm that provides fine grain events for the start and end of tags for specific schemas or DTDs. In an abstract parser it is usual to define start and end events for all of the lements in the DTD or schema although it is not always necessary to provide real implemntations for all events.

Below are example implemetations of the abstract parser for a document and the implementation that is responsible for constructing the actual java objects

Example Abstract Base Parser

The example below is of an example abstract parser for the configuration files for the XMLRouter.


package com.XXX.xmlrouter;
//Generated by XMLRouterParserGenerator-0.0.1
import java.util.Hashtable;
import com.thermidor.xml.SAXParserBase;
import org.xml.sax.SAXException;
/**
   The ConfigParserBase is the abstract parser the XMLRouters configuration
   files.
   @author Edward Turnock
 */
public abstract class ConfigParserBase extends SAXParserBase {
    /**
     * The ATTR_publicId attribute is a symbolic constant for the 
     * publicId attribute
    */
    public static final String ATTR_publicId = "publicId";
    /**
     * The ATTR_systemId attribute is a symbolic constant for the 
     *  systemId attribute
    */
    public static final String ATTR_systemId = "systemId";
    /**
     * The ATTR_ejb_class attribute is a symbolic constant for the 
     *  ejb-class attribute
    */
    public static final String ATTR_ejb_class = "ejb-class";
    /**
     * The ATTR_ejbhome_class attribute is a symbolic constant for 
     *  the ejbhome-class attribute
    */
    public static final String ATTR_ejbhome_class = "ejbhome-class";
    /**
     * The ATTR_ejbhome_jndi attribute is a symbolic constant 
     *  for the ejbhome-jndi attribute
    */
    public static final String ATTR_ejbhome_jndi = "ejbhome-jndi";
    /**
     * The ATTR_method attribute is a symbolic constant for the 
     *  method attribute
    */
    public static final String ATTR_method = "method";
    /**
     * The ATTR_name attribute is a symbolic constant for the name 
     *  attribute
    */
    public static final String ATTR_name = "name";
    /**
     * The ATTR_value attribute is a symbolic constant for the 
     *  value attribute
    */
    public static final String ATTR_value = "value";
    /**
     * The ATTR_path_info attribute is a symbolic constant for the 
     *  path-info attribute
    */
    public static final String ATTR_path_info = "path-info";
    /**
     * The ATTR_validate_request attribute is a symbolic constant 
     *  for the validate-request attribute
    */
    public static final String ATTR_validate_request = "validate-request";
    /**
     * The ATTR_validate_response attribute is a symbolic constant  
     * for the validate-response attribute
    */
    public static final String ATTR_validate_response = "validate-response";
    /**
     * The ATTR_class attribute is a symbolic constant for the 
     *  class attribute
    */
    public static final String ATTR_class = "class";
    /**
     * The STR_dtd attribute is a symbolic constant for the 
     *  <dtd> DTD element
    */
    public static final String STR_dtd = "dtd";
    /**
     * The STR_properties attribute is a symbolic constant for the 
     *  <properties> DTD element
    */
    public static final String STR_properties = "properties";
    /**
     * The STR_property attribute is a symbolic constant for the 
     *  <property> DTD element
    */
    public static final String STR_property = "property";
    /**
     * The STR_xml_router attribute is a symbolic constant for 
     *  the <xml-router> DTD element
    */
    public static final String STR_xml_router = "xml-router";
    /**
     * The STR_map attribute is a symbolic constant for the <map> 
     *  DTD element
    */
    public static final String STR_map = "map";
    /**
     * The STR_bean_mapping attribute is a symbolic constant for the 
     *  <bean-mapping> DTD element
    */
    public static final String STR_bean_mapping = "bean-mapping";
    /**
     * The STR_service_invocation attribute is a symbolic constant for 
     *  the <service-invocation> DTD element
    */
    public static final String STR_service_invocation = "service-invocation";
    /**
        The STR_request attribute is a symbolic constant for 
     *  the <request> DTD element
    */
    public static final String STR_request = "request";
    /**
        The STR_formal_arglist attribute is a symbolic constant for 
     *  the <formal-arglist> DTD element
    */
    public static final String STR_formal_arglist = "formal-arglist";
    /**
     * The STR_formal_arg attribute is a symbolic constant fo 
     * r the <formal-arg> DTD element
    */
    public static final String STR_formal_arg = "formal-arg";
    /**
     * The STR_content_handler attribute is a symbolic constant for 
     *  the <content-handler> DTD element
    */
    public static final String STR_content_handler = "content-handler";
    /**
     * The STR_response attribute is a symbolic constant for 
     *  the <response> DTD element
    */
    public static final String STR_response = "response";
    /**
     * The STR_serializer attribute is a symbolic constant for the 
     *  <serializer> DTD element
    */
    public static final String STR_serializer = "serializer";
    /**
     * The STR_exceptions attribute is a symbolic constant for the 
     *  <exceptions> DTD element
    */
    public static final String STR_exceptions = "exceptions";
    /**
     * The STR_exception attribute is a symbolic constant for 
     *  the <exception> DTD element
    */
    public static final String STR_exception = "exception";
    /**
     * The TOKEN_dtd attribtue is a unique integer identifier  
     * corresponding to the <dtd> DTD element.
    */
    public static final int TOKEN_dtd = 0;
    /**
     * The TOKEN_properties attribtue is a unique integer identifier 
     *  corresponding to the <properties> DTD element.
    */
    public static final int TOKEN_properties = 1;
    /**
     * The TOKEN_property attribtue is a unique integer identifier 
     *  corresponding to the <property> DTD element.
    */
    public static final int TOKEN_property = 2;
    /**
     * The TOKEN_xml_router attribtue is a unique integer identifier 
     *  corresponding to the <xml_router> DTD element.
    */
    public static final int TOKEN_xml_router = 3;
    /**
     * The TOKEN_map attribtue is a unique integer identifier 
     *  corresponding to the <map> DTD element.
    */
    public static final int TOKEN_map = 4;
    /**
     * The TOKEN_bean_mapping attribtue is a unique integer identifier 
     *  corresponding to the <bean_mapping> DTD element.
    */
    public static final int TOKEN_bean_mapping = 5;
    /**
     * The TOKEN_service_invocation attribtue is a unique integer 
     *  identifier corresponding to the <service_invocation> DTD element.
    */
    public static final int TOKEN_service_invocation = 6;
    /**
     * The TOKEN_request attribtue is a unique integer identifier 
     *  corresponding to the <request> DTD element.
    */
    public static final int TOKEN_request = 7;
    /**
     * The TOKEN_formal_arglist attribtue is a unique integer identifier 
     *  corresponding to the <formal_arglist> DTD element.
    */
    public static final int TOKEN_formal_arglist = 8;
    /**
     * The TOKEN_formal_arg attribtue is a unique integer identifier 
     *  corresponding to the <formal_arg> DTD element.
    */
    public static final int TOKEN_formal_arg = 9;
    /**
     * The TOKEN_content_handler attribtue is a unique integer identifier 
     *  corresponding to the <content_handler> DTD element.
    */
    public static final int TOKEN_content_handler = 10;
    /**
     * The TOKEN_response attribtue is a unique integer identifier 
     *  corresponding to the <response> DTD element.
    */
    public static final int TOKEN_response = 11;
    /**
     * The TOKEN_serializer attribtue is a unique integer identifier 
     *  corresponding to the <serializer> DTD element.
    */
    public static final int TOKEN_serializer = 12;
    /**
     * The TOKEN_exceptions attribtue is a unique integer identifier 
     *  corresponding to the <exceptions> DTD element.
    */
    public static final int TOKEN_exceptions = 13;
    /**
     * The TOKEN_exception attribtue is a unique integer identifier 
     *  corresponding to the <exception> DTD element.
    */
    public static final int TOKEN_exception = 14;
    /**
     * The token table is used by the parser to map element names to there 
     * defined token constants. It is this relationship that is used to select
     * the appropriate handler functions for the element.
    */
    private static final Hashtable TOKEN_TABLE = new Hashtable();
    static
    {
        TOKEN_TABLE.put(STR_dtd, 
                        new Integer(TOKEN_dtd));
        TOKEN_TABLE.put(STR_properties, 
                        new Integer(TOKEN_properties));
        TOKEN_TABLE.put(STR_property, 
                        new Integer(TOKEN_property));
        TOKEN_TABLE.put(STR_xml_router, 
                        new Integer(TOKEN_xml_router));
        TOKEN_TABLE.put(STR_map, 
                        new Integer(TOKEN_map));
        TOKEN_TABLE.put(STR_bean_mapping, 
                        new Integer(TOKEN_bean_mapping));
        TOKEN_TABLE.put(STR_service_invocation,
                        new Integer(TOKEN_service_invocation));
        TOKEN_TABLE.put(STR_request, 
                        new Integer(TOKEN_request));
        TOKEN_TABLE.put(STR_formal_arglist, 
                        new Integer(TOKEN_formal_arglist));
        TOKEN_TABLE.put(STR_formal_arg, 
                        new Integer(TOKEN_formal_arg));
        TOKEN_TABLE.put(STR_content_handler, 
                        new Integer(TOKEN_content_handler));
        TOKEN_TABLE.put(STR_response, 
                        new Integer(TOKEN_response));
        TOKEN_TABLE.put(STR_serializer, 
                        new Integer(TOKEN_serializer));
        TOKEN_TABLE.put(STR_exceptions, 
                        new Integer(TOKEN_exceptions));
        TOKEN_TABLE.put(STR_exception, 
                        new Integer(TOKEN_exception));
    }
    /**
     * Handle the start of the <dtd> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <dtd&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void dtdStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <properties> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <properties&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void propertiesStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <property> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <property&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void propertyStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <xml_router> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <xml_router&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void xml_routerStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <map> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <map&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void mapStart(SAXElement element) throws SAXException {}

    /**
       Handle the start of the <bean_mapping> DTD element.
       This operation should be overridden in the
       implementation sub class if it want to handle the start tag for
       the <bean_mapping&gt element 
       @param element the SAXelement that encapsulates the current state of 
       the element. Any pcdata for this element will not be available until
       the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void bean_mappingStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <service_invocation> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <service_invocation&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void service_invocationStart(SAXElement element)
        throws SAXException {}

    /**
     * Handle the start of the <request> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <request&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void requestStart(SAXElement element) throws SAXException {}

    /**
     *  Handle the start of the <formal_arglist> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <formal_arglist&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
      * @throws SAXException is raised if there is a processing error.
   */
    protected void formal_arglistStart(SAXElement element) 
        throws SAXException {}

    /**
     * Handle the start of the <formal_arg> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <formal_arg&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void formal_argStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <content_handler> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <content_handler&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void content_handlerStart(SAXElement element)
        throws SAXException {}

    /**
     * Handle the start of the <response> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <response&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void responseStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <serializer> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <serializer&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void serializerStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <exceptions> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <exceptions&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void exceptionsStart(SAXElement element) throws SAXException {}

    /**
     * Handle the start of the <exception> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the start tag for
     * the <exception&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. Any pcdata for this element will not be available until
     * the end tag is reached. 
     * @throws SAXException is raised if there is a processing error.
    */
    protected void exceptionStart(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <dtd> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <dtd&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void dtdEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <properties> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <properties&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void propertiesEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <property> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <property&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void propertyEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <xml_router> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <xml_router&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void xml_routerEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <map> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <map&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void mapEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <bean_mapping> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <bean_mapping&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     *  the element. When this handler function is called any pcdata for this
     *  element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void bean_mappingEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <service_invocation> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     *  the <service_invocation&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void service_invocationEnd(SAXElement element)
        throws SAXException {}

    /**
     * Handle the end of the <request> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <request&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void requestEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <formal_arglist> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <formal_arglist&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void formal_arglistEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <formal_arg> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <formal_arg&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void formal_argEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <content_handler> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <content_handler&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     *  element will be available through the element parameter.
      * @throws SAXException is raised if there is a processing error.
   */
    protected void content_handlerEnd(SAXElement element) 
        throws SAXException {}

    /**
     *  Handle the end of the <response> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <response&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void responseEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <serializer> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <serializer&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void serializerEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <exceptions> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <exceptions&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void exceptionsEnd(SAXElement element) throws SAXException {}

    /**
     * Handle the end of the <exception> DTD element.
     * This operation should be overridden in the
     * implementation sub class if it want to handle the end tag for
     * the <exception&gt element 
     * @param element the SAXelement that encapsulates the current state of 
     * the element. When this handler function is called any pcdata for this
     * element will be available through the element parameter.
     * @throws SAXException is raised if there is a processing error.
    */
    protected void exceptionEnd(SAXElement element) throws SAXException {}

    /**
     * Retrive the token that corresponds to the spcified element name. 
     * @param lname the name of the element to return the unique token for.
     * @return the integer token that corresponds to the element name or -1
     * if the element is not defined in the token table
    */
    private static int select(String lname) {
        Integer result = null;
        result = (Integer)TOKEN_TABLE.get(lname);

        if (result != null) {
            return result.intValue();
        }

        return -1;
    }

    /**
     * Handle the SAXElement provided as the start tag has been encountered.
     * This operation retrieves the token
     * That corresponds to the name of the XML element and then uses this token
     *  to identify the handler function that should be called for the element.
     * @param element the SAXElement that has been created by the SAXParserBase
     * that contain maintains the current paring state of the XML tag. 
     * @throws SAXException is raised if there is a processing error.
    */
    public final void handleStartElement(SAXElement element) 
        throws SAXException {
        int token = select(element.getLname());

        switch (token) {

        case TOKEN_dtd: {
                dtdStart(element);
                break;
            }

        case TOKEN_properties: {
                propertiesStart(element);
                break;
            }

        case TOKEN_property: {
                propertyStart(element);
                break;
            }

        case TOKEN_xml_router: {
                xml_routerStart(element);
                break;
            }

        case TOKEN_map: {
                mapStart(element);
                break;
            }

        case TOKEN_bean_mapping: {
                bean_mappingStart(element);
                break;
            }

        case TOKEN_service_invocation: {
                service_invocationStart(element);
                break;
            }

        case TOKEN_request: {
                requestStart(element);
                break;
            }

        case TOKEN_formal_arglist: {
                formal_arglistStart(element);
                break;
            }

        case TOKEN_formal_arg: {
                formal_argStart(element);
                break;
            }

        case TOKEN_content_handler: {
                content_handlerStart(element);
                break;
            }

        case TOKEN_response: {
                responseStart(element);
                break;
            }

        case TOKEN_serializer: {
                serializerStart(element);
                break;
            }

        case TOKEN_exceptions: {
                exceptionsStart(element);
                break;
            }

        case TOKEN_exception: {
                exceptionStart(element);
                break;
            }

        default: {
                unknownElementStart(element);
            }
        }
    }

    /**
     * Handle the SAXElement provided as the end tag has been encounterd
     * This operation retrieves the token
     * that corresponds to the name of the XML element and then uses this token
     * to identify the handler function that should be called for the element.
     * @param element the SAXElement that has been created by the SAXParserBase
     * that contain maintains the current paring state of the XML tag. 
     * @throws SAXException is raised if there is a processing error.
    */
    public final void handleEndElement(SAXElement element)
        throws SAXException {
        int token = select(element.getLname());

        switch (token) {

        case TOKEN_dtd: {
                dtdEnd(element);
                break;
            }

        case TOKEN_properties: {
                propertiesEnd(element);
                break;
            }

        case TOKEN_property: {
                propertyEnd(element);
                break;
            }

        case TOKEN_xml_router: {
                xml_routerEnd(element);
                break;
            }

        case TOKEN_map: {
                mapEnd(element);
                break;
            }

        case TOKEN_bean_mapping: {
                bean_mappingEnd(element);
                break;
            }

        case TOKEN_service_invocation: {
                service_invocationEnd(element);
                break;
            }

        case TOKEN_request: {
                requestEnd(element);
                break;
            }

        case TOKEN_formal_arglist: {
                formal_arglistEnd(element);
                break;
            }

        case TOKEN_formal_arg: {
                formal_argEnd(element);
                break;
            }

        case TOKEN_content_handler: {
                content_handlerEnd(element);
                break;
            }

        case TOKEN_response: {
                responseEnd(element);
                break;
            }

        case TOKEN_serializer: {
                serializerEnd(element);
                break;
            }

        case TOKEN_exceptions: {
                exceptionsEnd(element);
                break;
            }

        case TOKEN_exception: {
                exceptionEnd(element);
                break;
            }

        default: {
                unknownElementEnd(element);
            }
        }
    }

    /**
     * Message constant ConfigParserBase encountered 
     * an unknown start tag [
     */
    private static final String MSG_UNKNOWN_START;
    /**
     * Message constant ConfigParserBase encountered 
     * an unknown end tag [
     */
    private static final String MSG_UNKNOWN_END;
    static{
        MSG_UNKNOWN_START = "ConfigParserBase encountered" +
                            " an unknown start tag [";
        MSG_UNKNOWN_END = "ConfigParserBase encountered" +
                          " an unknown end tag [";
    }
    /**
     * Handle the start of an unknown element. The default implementation 
     * of this operation will throw a SAXException when an unknown element 
     * is encountered. If different behaviour is required then the
     * operation should be overridden in the implementation
     * @param element the SAXElement that encapsulates the unknown element
     * @throws SAXException is raised if an unknown start tag is encountered
    */
    protected void unknownElementStart(SAXElement element)
    throws SAXException {
        throw new SAXException(MSG_UNKNOWN_START + element.getLname() + "]");
    }

    /**
     * Handle the end of an unknown element. The default implementation of
     * this operation will throw a SAXException when an unknown element
     * is encountered. If different behaviour is required then the
     * operation should be overridden in the implementation
     * @param element the SAXElement that encapsulates the unknown element
     * @throws SAXException is raised if an unknown end tag is encountered
     */
    protected void unknownElementEnd(SAXElement element) throws SAXException {
        throw new SAXException(MSG_UNKNOWN_END + element.getLname() + "]");
    }
}

Example Parser Implementation

The following example demonstrates how a parser implementation would be prodiced if you where hand coding it.


package com.thermidor.xmlrouter;
/*@LEGAL@*/
import java.util.Properties;
import org.xml.sax.SAXException;
import java.util.ArrayList;
import java.io.InputStream;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.thermidor.util.ClassUtil;
import com.thermidor.xml.DTD;
import com.thermidor.xml.SAXParserBase;;
/**
   The ConfigParserImpl class is the implemetation of the DefaultHandler for the
   management of the xmlrouting configuration file.
 */
public class ConfigParserImpl extends ConfigParserBase
{
    /**
       The mapTable attribute represents the cumalitive state of the parsing
       process. It is returned to the XMLRouter when the configuration has
       been successfully parsed it is returned to the XMLRouter and it becomes
       the entry point for the routers brokering functionality.
     */
    private MapTable         mapTable;
    /**
       Retrieve the MapTable instance that has been constructed from the xml
       configuration data.
       @return the service map table.
     */
    public MapTable getMapTable(){
    return mapTable;
    }
    /**
       An instance of a mapping object that is currently being parsed from the
       XML source.
     */
    private Mapping          currentMapping;
    /**
       An instance of a java properties list that is currently being parsed from
       the XML source. This property list may belong to the XMLRouter, a 
       parameter handler or a return handler instance
     */
    private Properties       currentProperties;
    /**
       A list of formal method parameters that is currently being constructed by
       the parser from the XML configuration data source. This list is used by 
       the parameter handler instance that is currently being constructed.
     */
    private ArrayList        formalArgs;
    /**
       A list of exception class that is currently being coinstructed by the
       parser from the XML confiuguration data source. This list is used by the 
       return handler that is currently being constructed by the parser.
     */
    private ArrayList        exceptions;
    /**
       An instrance of DTD data that is constructed while the configuration file
       is being parsed. This instance may be associated with either a parameter
       handler, for an incomming invocation, or with a return handler to 
       validate that the XML that it is creating is valid.
     */
    private DTD              currentDtd;
    /**
       Handle the start element of the <code>&lt;properties&gt;</code> tag. The 
       operation creates a a new instance of the currentProperties object to 
       which properties are added in the propertyStart() operation.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void propertiesStart(SAXElement element) throws SAXException{
    currentProperties=new Properties();
    }
    /**
       Handle the start element of the <code>&lt;property&gt;</code> tag. The 
       property tag represents a single java property. Each property that is 
       encountered is added to the currentProperties attribute which will 
       eventually be assogned to the appropriate parameterHandler or return 
       handler instance in the mapping. Properties can also be specified for
       the xml router.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void propertyStart(SAXElement element) throws SAXException{
    currentProperties.setProperty(element.getValue(ATTR_name),
                      element.getValue(ATTR_value));
    }
    /**
       Handle the start element of the <code>&lt;xml-router&gt;</code> tag. The
       <code>&lt;xml-router&gt;</code> tag is the root tag of the 
       configuration file.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void xml_routerStart(SAXElement element) throws SAXException{
    String validateRequest=null;
    String validateResponse=null;
    mapTable=new MapTable();
    validateRequest=element.getValue(ATTR_validate_request);
    validateResponse=element.getValue(ATTR_validate_response); 
    mapTable.setValidateRequest(Boolean.valueOf(validateRequest).booleanValue());
    mapTable.setValidateResponse(Boolean.valueOf(validateResponse).booleanValue());
    }
    /**
       Handle the start element of the <code>&lt;map&gt;</code> tag. Within this
       operation the properties for the xml router are assigned to the maptable
       and the currentProperties reset.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void mapStart(SAXElement element) throws SAXException{
    if(currentProperties!=null){
        mapTable.setProperties(currentProperties);
        currentProperties=null;
    }
    }
    /**
       Handle the start element of the <code>&lt;mapping&gt;</code> tag. During
       the parsing process the Mapping class instance are the focus for data 
       collection. All information from sub tags of <code>&lt;mapping&gt;</code>
       are assigned to the currentMapping instance.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void bean_mappingStart(SAXElement element) throws SAXException{
    String name=null;
    String pathinfo=null;
    currentMapping=new Mapping();
    
    name=SAXParserBase.noEmptyValue(ATTR_name,
                    element.getValue(ATTR_name));
    pathinfo=SAXParserBase.noEmptyValue(ATTR_path_info,
                        element.getValue(ATTR_path_info));
    currentMapping.setName(name);
    currentMapping.setPathinfo(pathinfo);
    currentMapping.setValidateRequests(mapTable.getValidateRequests());
    currentMapping.setValidateResponses(mapTable.getValidateResponses());
    mapTable.addMapping(currentMapping);
    }
    /**
       Handle the start element of the <code>&lt;service-invocation&gt;</code> 
       tag. Within this operation the EJB meta data is collected.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void service_invocationStart(SAXElement element)
    throws SAXException
    {
    /*...*/
    String ejbHomeClassName=null;
    String ejbHomeJNDIName=null;
    String ejbClassName=null;
    String method;
    ejbHomeClassName=SAXParserBase.noEmptyValue(ATTR_ejbhome_class,
                            element.getValue(ATTR_ejbhome_class));
    ejbHomeJNDIName=SAXParserBase.noEmptyValue(ATTR_ejbhome_jndi,
                           element.getValue(ATTR_ejbhome_jndi));
    ejbClassName=SAXParserBase.noEmptyValue(ATTR_ejb_class,
                        element.getValue(ATTR_ejb_class));
    method=SAXParserBase.noEmptyValue(ATTR_method,
                      element.getValue(ATTR_method));
    
    currentMapping.setEjbHomeClass(ejbHomeClassName);
    currentMapping.setEjbHomeJNDIName(ejbHomeJNDIName);
    currentMapping.setEjbClass(ejbClassName);
        currentMapping.setMethodName(method);
    /*...*/
    }
    /**
       Handle the start element of the <code>&lt;request&gt;</code> tag. There 
       is not data that needs to be handled on the start of the request tag.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void requestStart(SAXElement element) throws SAXException{}
    /**
       Handle the start element of the <code>&lt;formal-arglist&gt;</code> tag.
       Construct a new collection to manage the list of formal arguments
       associated with this argument list.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void formal_arglistStart(SAXElement element) throws SAXException{
    formalArgs=new ArrayList();
    }
    /**
       Handle the start element of the <code>&lt;formal-arg&gt;</code> tag. This
       handler operation retrieves the class of a formal argument of and EJB 
       methods parameter list.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void formal_argStart(SAXElement element) throws SAXException{
    String formalArgClassName=null;
    formalArgClassName=SAXParserBase.noEmptyValue(ATTR_class,
                              element.getValue(ATTR_class));
    formalArgs.add(loadFormalArg(formalArgClassName));
    }
    /**
       Handle the start element of the <code>&lt;content-handler&gt;</code> tag.
       The content handler tag contains information for the parameter handler.
       This operation retrieves the class of the parameter handler that is to be
       used with the current mapping.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void content_handlerStart(SAXElement element) throws SAXException{
    String handlerClassName=null;
    handlerClassName=SAXParserBase.noEmptyValue(ATTR_class,element.getValue(ATTR_class));
        try{
            currentMapping.setParameterHandlerClass(ClassUtil.lookup(handlerClassName));
        }
        catch(ClassNotFoundException cnfe){
            throw new ConfigurationException("Could not load parameter handler class",cnfe);
        }
    }
    /**
       Handle the start element of the <code>&lt;response&gt;</code> tag. This
       operation handles the <code>class</code> attribute of the response 
       element to retrieve the class of the EJB operations return type.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void responseStart(SAXElement element) throws SAXException{
    String returnTypeClassName=null;
    returnTypeClassName=SAXParserBase.noEmptyValue(ATTR_class,
                               element.getValue(ATTR_class));
    try {
        currentMapping.setReturnType(ClassUtil.lookup(returnTypeClassName));
    }
    catch(ClassNotFoundException cnfe){
        throw new ConfigurationException("Could not load the class of the return type",cnfe);
    }
    }
    /**
       Handle the start element of the <code>&lt;serializer&gt;</code> tag. This
       handler operation retrieve the class of the return handler that will be 
       used by the current mapping.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void serializerStart(SAXElement element) throws SAXException{
    /*...*/
    String serializerClassName=null;
    serializerClassName=SAXParserBase.noEmptyValue(ATTR_class,
                               element.getValue(ATTR_class));
        try{
            currentMapping.setReturnHandlerClass(ClassUtil.lookup(serializerClassName));
        }
        catch(ClassNotFoundException cnfe){
            throw new ConfigurationException("Could not load the return handler class",
                                             cnfe);
        }
    }
    /**
       Handle the start element of the <code>&lt;exceptions&gt;</code> tag. This
       method creates the a collection for the management of the list of 
       exceptions that the mapping should handle.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void exceptionsStart(SAXElement element) throws SAXException{
    exceptions=new ArrayList();
    }
    /**
       Handle the start element of the <code>&lt;exception&gt;</code> tag. Each
       exception tag represents a java exception type that the mapping should
       catch and handle by converting them to an XML reply through the return 
       handler.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void exceptionStart(SAXElement element) throws SAXException{
    String exceptionClassName=null;
    exceptionClassName=SAXParserBase.noEmptyValue(ATTR_class,element.getValue(ATTR_class));
    exceptions.add(loadException(exceptionClassName));
    }
    /**
       Handle the start element of the <code>&lt;dtd&gt;</code> tag. The dtd tag
       is used to coolect infomation about the DTDs that are used to define the
       XML for the XMLRouters request and reply. The purpose of the dtd tag is
       to map the public id of a the DTD to the a java resource. This resource
       is the path to the DTD within the class path of the distribution. This 
       is done to reduce the overhead of loading and managing the DTD within 
       the distribution. Each DTD is cached within the Mapping to ensure that 
       it does not have to be reloaded with every request or response 
       validation.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream,
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void dtdStart(SAXElement element) 
    throws SAXException
    {
    String publicId=null;
    String systemId=null;
    publicId=SAXParserBase.noEmptyValue(ATTR_publicId,element.getValue(ATTR_publicId));
    systemId=SAXParserBase.noEmptyValue(ATTR_systemId,element.getValue(ATTR_systemId));
        System.out.println("ConfigParserImpl dtdStart publicId:="+publicId+" systemId:="+systemId);
    currentDtd=new DTD(publicId,systemId);
    }

    /**
       Handle the end element of the <code>&lt;properties&gt;</code> tag. As 
       properties are associated with several tags within the configfile the 
       association of the current properties list with the coresponding
       elements is handled in other specific locations that provide the correct
       context for the association.  Therefore there is not behaviour assocated
       with this operation.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void propertiesEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;property&gt;</code> tag. As the 
       property tag is an empty tag there the end tag does not need to be 
       handled.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA define 
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void propertyEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;xml-router&gt;</code> tag. No
       handling is required for the end of the <code>&lt;xml-router&gt;</code> 
       tag.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void xml_routerEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;map&gt;</code> tag. No handling
       is required for the end of the <code>&lt;map&gt;</code> tag.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void mapEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;bean-mapping&gt;</code> tag. Once
       the <code>&lt;/bean-mapping&gt;</code> tag is encountered all the
       necessary data for the mapping has been collected. At this point the
       ready() operation is called on the currentMapping to initialize the 
       mapping and to run its validation functions.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void bean_mappingEnd(SAXElement element) throws SAXException{
        try{
            currentMapping.ready();
        }
        catch(Throwable t){
            t.printStackTrace();
            if(t instanceof Error)
                throw (Error)t;
            if(t instanceof SAXException)
                throw (SAXException)t;
            if(t instanceof RuntimeException)
                throw (RuntimeException)t;
        }
    }
    /**
       Handle the end element of the <code>&lt;/service-invocation&gt;</code>
       tag. No handling is required for the
       <code>&lt;/service-invocation&gt;</code> tag.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined 
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void service_invocationEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;request&gt;</code> tag. This 
       handler operation for the <code>&lt;/request&gt;</code> tag sets the DTD
       information for the request.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void requestEnd(SAXElement element)
    throws SAXException
    {
    currentMapping.setIncomingDtd(currentDtd);
    currentDtd=null;
    }
    /**
       Handle the end element of the <code>&lt;formal-arglist&gt;</code> tag. 
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void formal_arglistEnd(SAXElement element) throws SAXException{
    Class[] formal=new Class[formalArgs.size()];
    formal=(Class[])formalArgs.toArray(formal);
    currentMapping.setFormalArgs(formal);
    }
    /**
       Handle the end element of the <code>&lt;formal-arg&gt;</code> tag. As the
       tag that we are handling here is an empty element then we no dot need to 
       handle the end tag.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA define 
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void formal_argEnd(SAXElement element) throws SAXException{;}
    /**
       Handle the end element of the <code>&lt;content-handler&gt;</code> tag.
       This handler operation assocates the parmeter handlers properties with
       the current mapping.
       @param element the SAXParserBase.SAXElement instanc that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void content_handlerEnd(SAXElement element) throws SAXException{
    currentMapping.setParameterHandlerProperties(currentProperties);
    currentProperties=null;
    }
    /**
       Handle the end element of the <code>&lt;response&gt;</code> tag. This 
       handler operation for the <code>&lt;/response&gt;</code> tag sets the DTD
       information for the response.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA define 
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void responseEnd(SAXElement element) 
    throws SAXException
    {
    currentMapping.setOutgoingDtd(currentDtd);
    currentDtd=null;
    }
    /**
       Handle the end element of the <code>&lt;serializer&gt;</code> tag. 
       Handling this end tag associated any defined properties with the current
       return handler.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void serializerEnd(SAXElement element) throws SAXException{
    //handle tthe end of the serializers propertis;
    currentMapping.setReturnHandlerProperties(currentProperties);
    currentProperties=null;
    }
    /**
       Handle the end element of the <code>&lt;exceptions&gt;</code> tag. When
       the <code>&lt;/exceptions&gt;</code> tag is encountered the exceptions
       list for the return handler has been completed. At this point the list
       of exceptions is converted in to a Class array and provided to the
       current Mapping instance
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void exceptionsEnd(SAXElement element) throws SAXException{
    Class[] exps=new Class[exceptions.size()];
    exps=(Class[])exceptions.toArray(exps);
    currentMapping.setExceptions(exps);
    }
    /**
       Handle the end element of the <code>&lt;exception&gt;</code> tag. As the
       <code>&lt;exception&gt;</code> tag is an empty element no handling is 
       required when the end tag is encountered.
       @param element the SAXParserBase.SAXElement instance that represents the 
       current position of the SAX parsers within the token stream, as an end 
       element it will contain the function now has access to any PCDATA defined
       for the tag.
       @throws SAXException is raised if an error occured while the element was 
       being parsed.
     */
    protected void exceptionEnd(SAXElement element) throws SAXException{;}


    /**
       This utility operation is used to retrieve the Class of a formal 
       parameter.
       @param className the class name of the formal parameter to load.
       @return the class that corresponds to the name.
       @throws ConfigurationException is raised if the class could not be found.
     */
    private Class loadFormalArg(String className)
    throws ConfigurationException
    {
    try
    {
        return ClassUtil.lookup(className);
    }
    catch(ClassNotFoundException cnfe){
        String message="Formal argument class not found ["+className+"]";
        throw new ConfigurationException(message,cnfe);
    }
    }
    /**
       This utility operation is used to load the the class of and exception
       that a return handler should deal with.
       @param className the fully qualified class name of the the exception 
       class.
       @return the laoded class.
       @throws ConfigurationException is raised if the exception class could 
       not be loaded.
     */
    private Class loadException(String className)
    throws ConfigurationException
    {
    try
    {
        return Class.forName(className);
    }
    catch(ClassNotFoundException cnfe){
        String message="Exception class not found ["+className+"]";
        throw new ConfigurationException(message,cnfe);
    }
    }
    /**
       The public id of the DTD that constrains and defines the configuration 
       file format.
     */
    public static final String PUBLIC_ID="-//thermidor, Limited//XML Router 1.0 Config";
    /**
       The java resource identifier that is used to load the DTD from the classpath.
     */
    public static final String DTD_RESOURCE="/com/thermidor/xmlrouter/xmlrouter.dtd";

    /**
       The ConfigParserImpl class overrides the default resolveEntity operation
       of the SAXParserBase to return the input source that wrapps the DTD
       loaded from the classpath. If the public id matches that that has been
       defined for the configuration file dtd then the system id is ignored and
       the DTD is loaded from the classpath. Otherwise the operation is
       delegate to the superclass to perform.
       @param publicId the publicID of the external entity to resolve.
       @param systemId the system id of the external entity to resolve.
     */
    public InputSource resolveEntity(String publicId,String systemId) throws SAXException{
    InputSource retval=null;

    System.out.println("PUBLIC "+publicId+" SYSTEM "+systemId);

    if(PUBLIC_ID.equals(publicId)){
        try{
        retval=loadConfigDTD();
        System.out.println("resolveEntity():="+retval);
        } 
        catch(IOException ioe){
        throw new SAXException(ioe);
        }

    }
    return retval;
    }
    /**
       Load the Config DTD from the classpath.
       @return the InputSource that encapsulates the loaded DTD.
       @throws IOException is raised if the DTD could not be loaded
     */
    public static InputSource loadConfigDTD() throws IOException{
    return createInputSource(loadBuffer(getResource(DTD_RESOURCE)));
    }
    /**
       Create an Inputource from a buffer.
       @param data the buffer to encapsulate in an InputSource.
       @return the InputSource instance
     */
    private static InputSource createInputSource(byte[] data){
    InputSource retval=null;
    ByteArrayInputStream bais=new ByteArrayInputStream(data);
    retval=new InputSource(bais);
    System.out.println("createInputSource(data):="+retval);
    return retval;
    }
    /**
       Constant indicating the temporary buffer size to use while loading the 
       buffer from the stream.
     */
    private static int BUFFER_SIZE=512;
    /**
       Create a buffer from the contents of the specified stream.
       @param is the input stream to laod the buffer from.
       @return the buffer that contains the full contents of the stream.
     */
    private static byte[] loadBuffer(InputStream is)
    throws IOException
    {
    ByteArrayOutputStream baos=new ByteArrayOutputStream();
    byte[] buffer=new byte[BUFFER_SIZE];
    int bytesRead=0;
    bytesRead=is.read(buffer);
    while(bytesRead!=-1){
        baos.write(buffer,0,bytesRead);
        baos.flush();
        bytesRead=is.read(buffer);
    }
    baos.close();
    System.out.println("loadBuffer(is:"+is+"):="+baos.toString());
    return baos.toByteArray();
    }
    /**
       Retrieve an input stream to the the specified class loader resource.
       @param resourceId the id of the resource to load.
       @return the input stream to that resource or null if the resource id
       could not be resolved.
     */
    private static InputStream getResource(String resourceId){
    InputStream is=null;
    is=ConfigParserImpl.class.getResourceAsStream(resourceId);
    System.out.println("getResource(resourceId="+resourceId+"):="+is);
    return is;
    }



}