//*****************************************************************************
/*
** FILE:   xm_NodeTypeElement.java
**
** (c) 1998 Steve Withall.
**
** HISTORY:
**    04Aug98  stevew  Created.
*/
package xm;

import xg.xg_Element;
import xg.xg_VerificationException;

import java.sql.Driver;
import java.sql.DriverManager;

import eh.eh_Debug;

//*****************************************************************************
/** An XML element which defines an entry in the node type registry. When
 *  verify() is called during parsing, this entry is immediately registered,
 *  which allows the classes named in the entry to be used when parsing an
 *  entity of this type directly afterwards (even if it is the next entity in
 *  the XML source).
 */
public class xm_NodeTypeElement extends xg_Element
{
    /** The name of the node to register. */
    String  RegistryNodeName = null;

    /** The element type name normally used in XML for this sort of element. */
    public final static String RegisteredName         = "NodeType";

    /** The name of the attribute which holds the name of the node to which this
     *  registry entry relates. */
    public final static String NameAttName            = "Name";

    /** The name of the attribute which holds the description of this entry. */
    public final static String DescriptionAttName     = "Description";

    /** The name of the attribute which holds the name of the node class. */
    public final static String NodeClassAttName       = "NodeClass";

    /** The name of the attribute which holds the name of the parser class. */
    public final static String ParserClassAttName     = "ParserClass";

    /** The name of the attribute which holds the name of the customizer class. */
    public final static String CustomizerClassAttName = "CustomizerClass";

    /** The name of the attribute which holds the name of the view class. */
    public final static String ViewClassAttName       = "ViewClass";

    //*****************************************************************************
    /** Construct a node type registry entry element with no name.
     */
    public xm_NodeTypeElement()
    {
    }

    //*****************************************************************************
    /** Construct a node type registry entry element with a name.
     *
     *  @param  InputNodeName  The name of the element
     */
    public xm_NodeTypeElement(String InputNodeName)
    {
        super(InputNodeName);
    }

    //*****************************************************************************
    /** <p>Verify that this node is correct (ie. internally correct and/or consistent
     *  with other nodes - such as its parent). The node is OK if it possesses a
     *  'Name' attribute which names a valid node type registry entry class.</p>
     *
     *  @exception  xg_VerificationException  Description of verification problem
     */
    public void verify() throws xg_VerificationException
    {
        eh_Debug.add(8, "xm_NodeTypeElement.verify: Verify '" + NodeName + "'");

        // Obtain the node's name (mandatory) and description (optional).
        RegistryNodeName        = getAttributeValueVerified(NameAttName);
        String  NodeDescription = getAttributeValue(DescriptionAttName);

        // Obtain the names of the classes to register. All of them are optional,
        // but if present, the class must exist.
        String  NodeClassName = checkClassExistence(NodeClassAttName, "node");

        String  ParserClassName = checkClassExistence(ParserClassAttName,
                                                      "parser");
        if (ParserClassName == null)
            ParserClassName = xm_NodeTypeRegistry.getDefaultParserClassName();

        String  CustomizerClassName = checkClassExistence(CustomizerClassAttName,
                                                          "customizer");
        if (CustomizerClassName == null)
            CustomizerClassName = xm_NodeTypeRegistry.getDefaultCustomizerClassName();

        String  ViewClassName = checkClassExistence(ViewClassAttName, "view");
        if (ViewClassName == null)
            ViewClassName = xm_NodeTypeRegistry.getDefaultViewClassName();

        // Register this entry.
        xm_NodeTypeRegistry.register(RegistryNodeName,
                                     xm_NodeTypeRegistry.UNKNOWN,
                                     NodeDescription,
                                     NodeClassName,
                                     ParserClassName,
                                     CustomizerClassName,
                                     ViewClassName);
    }

    //*****************************************************************************
    /** Check that the class exists.
     *
     *  @param      InputClassName             The name of the class to be checked
     *  @param      InputClassTypeDescription  A snippet of text to place in any
     *                                          exception to explain the type of
     *                                          class which could not be found
     *  @return     The name of the class from the attribute named InputAttName
     *  @exception  xg_VerificationException  The named class does not exist
     */
    public String checkClassExistence(String  InputAttName,
                                      String  InputClassTypeDescription)
                                                throws xg_VerificationException
    {
        // Obtain name of the class from the attribute named in InputAttName.
        String  ClassName = getAttributeValue(InputAttName);

        if (ClassName != null)
        {
            try
            {
                Class.forName(ClassName);  // Load the named class
            }
            catch (Exception InputException)
            {
                throw new xg_VerificationException("Error loading "
                                                      + InputClassTypeDescription
                                                      + " class '"
                                                      + ClassName + "': "
                                                      + InputException);
            }
        }

        return ClassName;
    }

    //*****************************************************************************
    /** Get a summary descriptive string suitable for display in the tree view or
     *  elsewhere.
     *
     *  @return  A description suitable for display in the tree view
     */
    public String toString()
    {
        return("Node type registry entry '" + RegistryNodeName + "'");
    }
}

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