/*
 * (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;

import java.io.*;
import java.util.*;

/**
 * GeneralReference implements general references as defined by the Document Object Model (DOM).
 * <p>There are two flavors of general references:
 * <ol>
 * <li>Parsed entities: Parsed entities are declared in the internal or external DTD subsets,
 * and are referenced one or more places in the document.
 * <li>Unparsed entities: Unparsed entities are used for embedding data that is not in XML format
 * into the document.  An example of an unparsed entitiy is an image.
 * </ol>
 * <p>General References do NOT include character references(e.g. &quot;&lt;&quot; is 
 * referenced as &quot;&amp;#60;&quot;).
 * <p>The object tree produced by the XML4J parser does NOT include General Reference Nodes
 * because general references are expanded.  If an application is sensitive to the existence
 * of parsed entities, it should implement the ReferenceHandler interface.
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 * @see com.ibm.xml.parser.Parent
 * @see com.ibm.xml.parser.Child
 * @see com.ibm.xml.parser.ReferenceHandler
 */
public class GeneralReference extends Parent {

    private String  name    =   null;

    /**
     * Constructor.
     * @param name  This General Reference's name.  This is also the name of the entity
     *              being referred to by the General Reference.
     */
    public GeneralReference(String name) {
        this.name = name;
    }

    /**
     * Clone this General Reference Node and its children using the appropriate factories.
     * <p>This method is defined by Child.
     * @return          Cloned General Reference Node.
     * @see com.ibm.xml.parser.Child#clone
     */
    public synchronized Object clone() {
        checkFactory();
        GeneralReference gr = factory.createGeneralReference(getName());
        gr.children.ensureCapacity(children.getLength());
        for (int i = 0;  i < children.getLength();  i ++)
            gr.addElement((Child)((Child)children.item(i)).clone());
        return gr;
    }

    /**
     * Returns that this object is a General Reference Node.
     * <p>This method is defined by DOM.
     * @return          General Reference Node indicator.
     */
    public int getNodeType() {
        return Child.GENERALREFERENCE;
    }

    /**
     * Returns this General Reference's name.
     * @return          The string that is this General Reference's name (should never
     *                  be <var>null</var>).
     */
    public String getName() {
        return this.name;
    }

    /**
     * Return all text associated with this Node and its children without considering entities.
     * <p>This method is defined by Child.
     * @return          Text associated with all children, or <var>""</var> if no children.
     * @see com.ibm.xml.parser.Child#toString
     */
    public String getText() {
        StringBuffer sb = new StringBuffer(1024);
        synchronized (children) {
            int len = children.getLength();
            for (int i = 0;  i < len;  i ++)
                sb.append(((Child)children.item(i)).getText());
        }
        return sb.toString();
    }

    /**
     * Returns the XML language ID (the value of the <code>xml:lang</code> Attribute) in
     * use for this General Reference Node.  If this General Reference Node has no explicitly
     * defined language Attribute, Parent Nodes will be recursively checked.
     * @return          The XML language ID, or <var>null</var> if all Parents have no language ID.
     */
    public String getLanguage() {
        if (null == parent)  return null;
        if (parent instanceof TXElement)
            return ((TXElement)parent).getLanguage();
        if (parent instanceof GeneralReference)
            return ((GeneralReference)parent).getLanguage();
        return null;
    }
}
