/*
 * (C) Copyright IBM Corp. 1997-1998  All rights reserved.
 *
 * US Government Users Restricted Rights Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package com.ibm.xml.parser;

/**
 * An interface for receiving control when the various components of the Document Object
 * Model (DOM) and XML4J need to be created and initialized by the XML4J parser.
 * <p>This interface is primarily for use by the XML4J parser, but may be implemented
 * by applications which wish to override the <code>DefaultElementFactory</code> in its
 * entirety.
 * <p>A factory provides a generalized constructor for the XML4J parser.  In order to
 * direct the XML4J parser to call the constructor for the new subclass, the application-defined
 * factory is registered to the parser instance, prior to parsing the input stream, by using
 * the <code>setElementFactory</code> method.  The registered element factory calls the
 * appropriate constructor as required.
 * <p>If only a small number of customized DOM or XML4J components are required, the following
 * design pattern should be used in preference to reimplementing the entire ElementFactory
 * interface.  The following example illustrates the use of the ElementFactory interface in order
 * to subclass the TXElement Node in favor of a MyElement Node:
 * <pre>
 *
 * class MyElement extends TXElement {
 *   // Customized MyElement logic
 * }
 *
 * class MyElementFactory extends DefaultElementFactory {   // Extend default factory rather 
 *                                                          // than reimplement ElementFactory.
 *   public TXElement createElement(String name) {
 *       MyElement el = new MyElement(name);
 *       el.setFactory(this);
 *       return el;
 *   }
 *   ... // Additional constructors for other customized DOM or XML4J components.
 * }
 *
 * public static void main(String[] argv) {
 *   ...
 *   Parser p = new Parser(...);
 *   p.setElementFactory(new MyElementFactory());  // register customized constructor(s)
 *   TXDocument doc = p.readStream(is);
 *   // doc instance now contains MyElement instances instead of TXElement instances.
 *   ...
 * }
 *
 * </pre>
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 * @see com.ibm.xml.parser.Parser#setElementFactory
 */
public interface ElementFactory {
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXElement instance be created and initialized.  
     * Control is transferred after the parsing the Element's start tag, but prior to parsing any children.
     * @param name      The name of the Element.
     * @return          The newly initialized Element Node.
     * @see com.ibm.xml.parser.TXElement
     * @see com.ibm.xml.parser.DefaultElementFactory#createElement
     */
    public TXElement createElement(String name);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXAttributeList instance be created and initialized.  
     * Control is transferred after the initial Attribute of an Element.
     * @return          The newly initialized Attribute list.
     * @see com.ibm.xml.parser.TXAttributeList
     * @see com.ibm.xml.parser.DefaultElementFactory#createAttributeList
     */
    public TXAttributeList createAttributeList();

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXAttribute instance be created and initialized.  
     * @param name      The name of the Attribute. 
     * @param value     The value of the Attribute.
     * @return          The newly initialized Attribute Node.
     * @see com.ibm.xml.parser.TXAttribute
     * @see com.ibm.xml.parser.DefaultElementFactory#createAttribute
     */
    public TXAttribute createAttribute(String name, String value);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXText instance be created and initialized with a default ignorable
     * whitespace setting.
     * @param data      The actual content of the Text Node.
     * @return          The newly initialized Text Node.
     * @see com.ibm.xml.parser.TXText
     * @see com.ibm.xml.parser.DefaultElementFactory#createText
     */
    public TXText createText(String data);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXText instance be created and initialized with a specified ignorable
     * whitespace setting.
     * <P>This method is never called by the parser.
     *
     * @param data      The actual content of the Text Node.
     * @param isIgnorableWhitespace =true indicates whitespace is ignored; =false indicates whitespace is significant.
     * @return          The newly initialized Text Node.
     * @see com.ibm.xml.parser.TXText#setIsIgnorableWhitespace
     * @see com.ibm.xml.parser.DefaultElementFactory#createText
     */
    public TXText createText(String data, boolean isIgnorableWhitespace);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXText instance be created and initialized with a specified ignorable
     * whitespace setting.
     * @param chararray     an array of chracter including the actual content of the Text Node.
     * @param offset        a position of starting content.
     * @param length        a length of content
     * @param isIgnorableWhitespace =true indicates whitespace is ignored; =false indicates whitespace is significant.
     * @return          The newly initialized Text Node.
     * @see com.ibm.xml.parser.TXText#setIsIgnorableWhitespace
     * @see com.ibm.xml.parser.DefaultElementFactory#createText
     */
    public TXText createText(char[] chararray, int offset, int length, boolean isIgnorableWhitespace);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXCDATASection instance be created and initialized.  
     * @param data      The actual content of the CDATASection Node.
     * @return          The newly initialized CDATASection Node.
     * @see com.ibm.xml.parser.TXCDATASection
     * @see com.ibm.xml.parser.DefaultElementFactory#createCDATA
     */
    public TXCDATASection createCDATA(String data);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXComment instance be created and initialized.  
     * @param data      The actual content of the Comment Node.
     * @return          The newly initialized Comment Node.
     * @see com.ibm.xml.parser.TXComment
     * @see com.ibm.xml.parser.DefaultElementFactory#createComment
     */
    public TXComment createComment(String data);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXPI instance be created and initialized.  
     * @param name      The first token following the markup.
     * @param data      From the character immediately after <var>name</var> to the 
     *                    character immediately preceding the <code>?&gt;</code>.
     * @return          The newly initialized PI Node.
     * @see #createNamespacePI
     * @see #createStylesheetPI
     * @see com.ibm.xml.parser.TXPI
     * @see com.ibm.xml.parser.DefaultElementFactory#createPI
     */
    public TXPI createPI(String name, String data);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a NamespacePI instance be created and initialized.  
     * @param name          The first token following the markup (i.e. "xml:namespace").
     * @param data          From the character immediately after the name to the character immediately preceding the <code>?&gt;</code>.
     * @param nsURI         The value of the <code>ns=</code> attribute.
     * @param prefixName    The value of the <code>prefix=</code> attribute.
     * @param srcURI        The value of the <code>src=</code> attribute, or <var>null</var>.
     * @return              The newly initialized namespace PI Node.
     * @see #createPI
     * @see #createStylesheetPI
     * @see com.ibm.xml.parser.NamespacePI
     * @see com.ibm.xml.parser.DefaultElementFactory#createNamespacePI
     */
    public NamespacePI createNamespacePI(String name, String data, String nsURI, String prefixName, String srcURI);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a StylesheetPI instance be created and initialized.  
     * @param name          The first token following the markup (e.g. <CODE>"xml:stylesheet"</CODE>).
     * @param data          From the character immediately after <var>name</var> to the character immediately preceding the <code>?&gt;</code>.
     * @param type          The value of the <code>type=</code> attribute.
     * @param hrefURI       The value of the <code>href=</code> attribute.
     * @param title         The value of the <CODE>title=</CODE> attribute, or <var>null</var>.
     * @return              The newly initialized stylesheet PI Node.
     * @see #createPI
     * @see #createNamespacePI
     * @see com.ibm.xml.parser.StylesheetPI
     * @see com.ibm.xml.parser.DefaultElementFactory#createStylesheetPI
     */
    public StylesheetPI createStylesheetPI(String name, String data, String type, String hrefURI, String title);


    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXDocument instance be created and initialized.  
     * Control is transferred before parsing any PIs, comments, DTDs, and the root Document Element.
     * @return          The newly initialized Document Node.
     * @see com.ibm.xml.parser.TXDocument
     * @see com.ibm.xml.parser.DefaultElementFactory#createDocument
     */
    public TXDocument createDocument();

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a TXNotation instance be created and initialized.  
     * @param name          The name of the Notation.
     * @param externalID    The public or system identifier which defines the DTD's notation.
     * @return              The newly initialized Notation Node.
     * @see com.ibm.xml.parser.TXNotation
     * @see com.ibm.xml.parser.DefaultElementFactory#createNotation
     */
    public TXNotation createNotation(String name, ExternalID externalID);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a DTD instance be created and initialized.  
     * Control is transferred after parsing the DOCTYPE tag, but prior to parsing any 
     * constituent objects of the internal or external DTD subset.
     * @return              The newly initialized DTD.
     * @see com.ibm.xml.parser.DTD
     * @see com.ibm.xml.parser.DefaultElementFactory#createDTD
     */
    public DTD createDTD();

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a DTD instance be created and initialized.  
     * Control is transferred after parsing the DOCTYPE tag, but prior to parsing any 
     * constituent objects of the internal or external DTD subset.
     * @param name          The name of the DTD.  This value is also known as the <code>DOCTYPE</code>
     *                      and the root Element Name.
     * @param externalID    The external ID associated with this DTD.
     * @return              The newly initialized DTD.
     * @see com.ibm.xml.parser.DTD
     * @see com.ibm.xml.parser.DefaultElementFactory#createDTD
     */
    public DTD createDTD(String name, ExternalID externalID);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that an ElementDecl instance be created and initialized.  
     * Control is transferred after parsing the entire element declaration.
     * @param name          The element definition's name. 
     * @param contentModel  The content model to associate with this element definition.
     * @return              The newly initialized element definition.
     * @see com.ibm.xml.parser.ElementDecl
     * @see com.ibm.xml.parser.DefaultElementFactory#createElementDecl
     */
    public ElementDecl createElementDecl(String name, ContentModel contentModel);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a content model instance be created and initialized of a type other than
     * <var>MODEL_GROUP</var>.  
     * Control is transferred after parsing the entire content model.
     * @param   type    The type of the content model. 
     *                  Must be one of org.w3c.dom.ElementDefinition#ContentType.
     *                  Note that the XML4J parser will never set <code>#PCDATA</code> as the
     *                  content type; <code>MODEL_GROUP</code> will be set instead.
     * @return          The newly initialized content model.
     * @see org.w3c.dom.ElementDefinition
     * @see com.ibm.xml.parser.ElementDecl
     * @see com.ibm.xml.parser.DefaultElementFactory#createContentModel
     */
    public ContentModel createContentModel(int type);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a content model instance be created and initialized of type <var>MODEL_GROUP</var>.
     * Control is transferred after parsing the entire content model.
     * @param   modelGroupNode  The content model associated with the model group.
     * @return                  The newly initialized content model.
     * @see org.w3c.dom.ElementDefinition
     * @see com.ibm.xml.parser.ElementDecl
     * @see com.ibm.xml.parser.DefaultElementFactory#createContentModel
     */
    public ContentModel createContentModel(CMNode modelGroupNode);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that an Attlist instance be created and initialized.  
     * Control is transferred after parsing the attribute list name, but prior to parsing
     * any constituent attribute definitions.
     * @param name      The attribute list name; this value is also known as the Element type.
     * @return          The newly initialized attribute list definition.
     * @see com.ibm.xml.parser.Attlist
     * @see com.ibm.xml.parser.DefaultElementFactory#createAttlist
     */
    public Attlist createAttlist(String name);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a StylesheetPI instance be created and initialized.  
     * @param   name        The name of this attribute.
     * @return              The newly initialized attribute definition.
     * @see com.ibm.xml.parser.AttDef
     * @see com.ibm.xml.parser.DefaultElementFactory#createAttDef
     */
    public AttDef createAttDef(String name);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that an internal Entity instance be created and initialized.  
     * @param   name        Name of this Entity.
     * @param   value       The XML-encoded value that was directly assigned to the Entity.
     * @param   isParameter =true if a parameter Entity; otherwise =false.
     * @return              The newly initialized Entity.
     * @see com.ibm.xml.parser.Entity
     * @see com.ibm.xml.parser.DefaultElementFactory#createEntity
     */
    public Entity createEntity(String name, String value, boolean isParameter);
    
    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that an external Entity instance be created and initialized.  
     * @param   name        Name of the Entity.
     * @param   externalID  The reference(s) to the external entity to retrieve. 
     * @param   isParameter =true if a parameter Entity; otherwise =false.
     * @param   ndata       The notation associated with the binary Entity.
     * @return              The newly initialized Entity.
     * @see com.ibm.xml.parser.Entity
     * @see com.ibm.xml.parser.DefaultElementFactory#createEntity
     * @see com.ibm.xml.parser.ExternalID
     */
    public Entity createEntity(String name, ExternalID externalID, boolean isParameter, String ndata);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a general reference instance be created and initialized.  
     * Control is transferred after parsing the general reference, but prior to parsing
     * the entity referred to by the reference.
     * @param name      The name of the Entity.
     * @return          The newly initialized general reference.
     * @see com.ibm.xml.parser.GeneralReference
     * @see com.ibm.xml.parser.DefaultElementFactory#createGeneralReference
     */
    public GeneralReference createGeneralReference(String name);

    /**
     * Interface to be implemented for receiving control when the XML4J parser requires
     * that a MessageDigest instance be created and initialized.  
     * @return              The newly initialized message digest.
     * @exception java.security.NoSuchAlgorithmException Thrown if the message digest algorithm is not locally available
     * @see java.security.MessageDigest#getInstance
     * @see com.ibm.xml.parser.DefaultElementFactory#createMessageDigest
     * @see com.ibm.xml.parser.DefaultElementFactory#setDigestAlgorithm
     */
    public java.security.MessageDigest createMessageDigest()
        throws java.security.NoSuchAlgorithmException;

    /**
     * Interface to be implemented to return a Child Node instance in XML format using the 
     * specified character encoding.
     * Entities embedded in the returned string should be respected.
     * For example, the characters <code>&lt;,  &gt;,  &amp;,  &apos;, and &quot; </code> 
     * should be represented as <code>&amp;lt;, &amp;gt;, &amp;amp;, &amp;apos;, &amp;quot; </code>. 
     * @param child     Child node to return in XML format.
     * @param enc       Java character encoding to use.
     * @see com.ibm.xml.parser.DefaultElementFactory#toString
     */
    public String toString(Child child, String enc);

    /**
     * Interface to be implemented to print a Child Node instance in XML format, 
     * using the specified character encoding, and indented by <var>indent</var> spaces.
     * Entities embedded in the returned string should be respected.
     * For example, the characters <code>&lt;,  &gt;,  &amp;,  &apos;, and &quot; </code> 
     * should be represented as <code>&amp;lt;, &amp;gt;, &amp;amp;, &amp;apos;, &amp;quot; </code>. 
     * @param child     Child node to print in XML format.
     * @param pw        The character output stream to use.
     * @param enc       Java character encoding in use by <VAR>pw</VAR>.
     * @see com.ibm.xml.parser.DefaultElementFactory#print
     */
    public void print(Child child, java.io.PrintWriter pw, String enc);

    /**
     * Interface to be implemented to calculate the digest of a Child Node instance and
     * any children. 
     * <p>Message digests are secure one-way hash functions that take arbitrary-sized data 
     * and output a fixed-length hash value.
     * @param child     Child node for which to generate a message digest.
     * @return          The array of bytes for the resulting hash value.  
     * @see com.ibm.xml.parser.DefaultElementFactory#makeDigest
     * @see java.security.MessageDigest#digest
     */
    public byte[] makeDigest(Child child);
}
