//*****************************************************************************
/*
** FILE:   xe_ParserFactory.java
**
** (c) 1997, 1998 Steve Withall.
**
** HISTORY:
**    06Oct97  stevew  Created.
**    04Jul98  stevew  Split basics into new base class xm_NodeFactory.
*/
package xe;

import xm.xm_NodeFactory;
import xm.xm_NodeTypeDefn;
import xm.xm_NodeTypeRegistry;
import xm.xm_ParseException;

import xg.xg_Node;

import eh.eh_Debug;

import java.lang.Class;

//*****************************************************************************
/** Factory for generating parsers for parts of an XML source. It can also
 *  create nodes in a similar way.
 *
 *  Given the name of an XML entity, it returns a parser object suitable
 *  for parsing it. It is able to handle all the normal features of XML, but
 *  may be enhanced to support specialised parsers for particular types of
 *  entities.
 */
public class xe_ParserFactory extends xm_NodeFactory
{
    //*****************************************************************************
    /** <p>Create a parser of the type suitable for parsing an entity whose type is
     *  'InputNodeName'. If no parser is registered for InputNodeName, then a
     *  parser suitable for InputNodeType is created. This dual-level scheme allows
     *  special parsers to be added, while still creating parsers of the correct
     *  standard type the rest of the time.</p>
     *
     *  <p>Non-standard parsers can be added by registering them with
     *  xm_NodeTypeRegistry.</p>
     *
     *  @param      InputNodeName  The name of the node for which we need a parser
     *  @param      InputNodeType  The type of node for which we need a parser
     *  @return                    The newly-created parser for the named entity
     *  @exception  xm_ParseException  Either no parser class is registered
     *                                  or it cannot be instantiated
     */
    static public xe_Parser createParser(String InputNodeName,
                                         int    InputNodeType)
                                                   throws xm_ParseException
    {
        String     NewParserClassName = null;
        xe_Parser  NewParser          = null;

        xm_NodeTypeDefn  CurrentNodeTypeDefn = xm_NodeTypeRegistry.getDefn(InputNodeName,
                                                                           InputNodeType);

        // Get the name of the class used to parse nodes of this type.
        NewParserClassName = CurrentNodeTypeDefn.getParserClassName();
        if (NewParserClassName == null)
        {
            throw new xm_ParseException("No parser class registered for "
                                           + InputNodeName + " or node type "
                                           + InputNodeType);
        }

        eh_Debug.add(7, "xe_ParserFactory: Create parser of type " + NewParserClassName
                           + " for node '" + InputNodeName + "'");
        try
        {
            // Create a parser.
            Class  ParserClass = Class.forName(NewParserClassName);
            NewParser = (xe_Parser)ParserClass.newInstance();
        }
        catch (Exception  InputException)
        {
            throw new xm_ParseException("Error creating parser of type "
                                           + NewParserClassName
                                           + " (" + InputException + ")");
        }

        // Tell the NewParser something about the node it's parsing.
        NewParser.setEntityType(CurrentNodeTypeDefn.getType() );
        NewParser.setEntityName(InputNodeName);
        NewParser.setEntityClassName(CurrentNodeTypeDefn.getNodeClassName() );
        return NewParser;
    }
}

//*****************************************************************************
