//*****************************************************************************
/*
** FILE:   xm_NodeFactory.java
**
** (c) 1997 Steve Withall.
**
** HISTORY:
**    06Oct97  stevew  Created.
**    03Jul98  stevew  Moved from xe to xm, and renamed from xe_ParserFactory
**                      to xm_NodeFactory.
**    05Jul98  stevew  Split xm_Factory into base class.
*/
package xm;

import xg.xg_Node;

import eh.eh_Debug;

import java.lang.Class;

//*****************************************************************************
/** Factory for generating XML nodes given a name and/or type.
 */
public class xm_NodeFactory extends xm_Factory
{
    //*****************************************************************************
    /** <p>Create a node of the type suitable for the entity whose name is
     *  InputNodeName. If this name is not registered, a node of type InputNodeType
     *  is created, where InputNodeType identifies one of the fixed XML entity
     *  types.</p>
     *
     *  <p>Non-standard nodes are added by registering with xm_NodeTypeRegistry
     *  the names to which they relate.</p>
     *
     *  @param  InputNodeName        The name of the node we need to create
     *  @param  InputNodeType        The type of node we need to create
     *  @param  InputUsualClassName  The name of the class which is usually used to
     *                                represent entities of this type. The class
     *                                actually used must be this or derived from it.
     *  @return                      The newly-created node
     */
    static public xg_Node createNode(String  InputNodeName,
                                     int     InputNodeType,
                                     String  InputUsualClassName)
                                                throws xm_ParseException
    {
        xm_NodeTypeDefn  CurrentNodeTypeDefn = xm_NodeTypeRegistry.getDefn(InputNodeName,
                                                                           InputNodeType);
        String           NewNodeClassName    = CurrentNodeTypeDefn.getNodeClassName();

        eh_Debug.add(7, "xm_NodeFactory: Create object of type " + NewNodeClassName
                           + " for node '" + InputNodeName + "'");
        Class  EntityClass = null;
        try
        {
            EntityClass = Class.forName(NewNodeClassName);
        }
        catch (Exception  InputException)
        {
            throw new xm_ParseException("Node " + InputNodeName
                                           + " is of unknown class "
                                           + NewNodeClassName
                                           + " (" + InputException + ")");
        }

        // Make sure this class extends the usual class.
        if (NewNodeClassName.compareTo(InputUsualClassName) != 0)
            checkClassType(EntityClass, InputNodeName, InputUsualClassName);

        // Create a node.
        xg_Node  NewNode = null;
        try
        {
            NewNode = (xg_Node)EntityClass.newInstance();
        }
        catch (Exception  InputException)
        {
            throw new xm_ParseException("Error instantiating " + NewNodeClassName
                                           + " (" + InputException + ")");
        }

        // Tell the NewNode something about the node it represents.
        NewNode.setName(InputNodeName);
        return NewNode;
    }

    //*****************************************************************************
    /** <p>Create an entity of the type suitable for the entity whose name is
     *  InputNodeName. This is synonymous with createNode(), and is retained only
     *  to stop existing callers breaking.</p>
     *
     *  <p>Non-standard entities are added by registering with xm_NodeTypeRegistry
     *  the names to which they relate.</p>
     *
     *  @param  InputNodeName        The name of the node we need to create
     *  @param  InputNodeType        The type of node we need to create
     *  @param  InputUsualClassName  The name of the class which is usually used to
     *                                represent entities of this type. The class
     *                                actually used must be this or derived from it.
     *  @return                      The newly-created node
     *  @deprecated
     */
    static public xg_Node createEntity(String  InputNodeName,
                                       int     InputNodeType,
                                       String  InputUsualClassName)
                                                  throws xm_ParseException
    {
        return (createNode(InputNodeName, InputNodeType, InputUsualClassName) );
    }
}

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