/*
 * (C) Copyright IBM Corp. 1999  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.parsers;

import java.io.IOException;
import java.util.Stack;

import org.w3c.dom.*;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * NonValidatingDOMParser exists to provide backwards compatibility with XML4J V2.0
 *
 * @deprecated The W3C's DOM L3 working group will specify a standardized API for
 *             parser instantiation.  XML4J and Xerces will switch to this API
 *             when it becomes available
 * @version %M% %I% %W% %Q%
 */
public class NonValidatingDOMParser {

    //
    // Constants
    //

    /** Represents full DOM Node expansion of Node objects and data. */
    public static final int FULL = 0;

    /** Represents deferred DOM Node expansion of Node objects and data. */
    public static final int DEFERRED = 1;

    //
    // Data
    //

    protected org.apache.xerces.parsers.DOMParser fParser = null;

    //
    // Constructors
    //

    /** Default constructor. */
    public NonValidatingDOMParser() {
        fParser = new org.apache.xerces.parsers.DOMParser();
    }

    //
    // Public methods
    //

    /**
     *
     */
    public void reset() {
        try {
            fParser.reset();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *
     */
    protected void resetOrCopy() {
    }

    //
    // Setters and Getters for DOM Parser behaviour modification.
    //

    /**
     * Sets whether <tt>EntityReference</tt> Nodes are expanded (replaced)
     * by this parser. Expanded means that the children of the
     * <tt>EntityReference</tt> Node replace it.
     * <p>
     * The default value is false, <tt>EntityReference</tt> Nodes are kept.
     *
     * @param keep  <code>=true</code> means expanding entity references;
     *              <code>=false</code> means maintain entity references.
     *
     * @see org.w3c.dom.EntityReference
     * @see com.ibm.xml.parser.GeneralReference
     */
    public void setExpandEntityReferences(boolean expand) {
        setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes",!expand);
    }

    /**
     * Return a boolean which says whether <tt>EntityReference</tt>
     * Nodes are expanded (replaced) by this parser. Expanded means
     * that the children of the <tt>EntityReference</tt> Node replace it.
     * <p>
     * The default value is false, <tt>EntityReference</tt> Nodes are kept.
     *
     * @param keep  <code>=true</code> means expanding entity references;
     *              <code>=false</code> means maintain entity references.
     *
     * @see org.w3c.dom.EntityReference
     * @see com.ibm.xml.parser.GeneralReference
     */
    public boolean getExpandEntityReferences() {
        return !getFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes");
    }

    /**
     * Sets whether Nodes are created and the data is kept within the Nodes.
     * <p>
     * @param nodeExpansion <br>
     * NonValidatingDOMParser.FULL - full expansion
     * NonValidatingDOMParser.DEFERRED - deferred expansion
     *
     */
    public void setNodeExpansion(int nodeExpansion) {
        boolean flag = true;
        if (nodeExpansion == FULL)
            flag = false;
        setFeature("http://apache.org/xml/features/dom/defer-node-expansion",flag);
    }

    /**
     * Return the Node expansion level integer mapping to the constants
     * in DOMParser.
     * Signifies whether DOM Nodes are created and the data is kept
     * within the Nodes.
     * <p>
     * @param nodeExpansion <br>
     * DOMParser.FULL - full expansion
     * DOMParser.DEFERRED - deferred expansion
     */
    public int getNodeExpansion() {
        if (getFeature("http://apache.org/xml/features/dom/defer-node-expansion")) 
            return DEFERRED;
        else
            return FULL;
    }

    /** Return the current DOM Node.
     *  <p> This function will only return meaningful Node values when
     *  setNodeExpansion(FULL). When setNodeExpansion(DEFERRED) is set,
     *  Node creation is deferred and getCurrentNode() will likely return null.
     *  <p>This function is useful for querying the parser when getting an
     *  error or warning callback.
     * @see #setNodeExpansion
     */
    public Node getCurrentNode() {
        Node n = null;
        try {
            n = (Node) fParser.getProperty("http://apache.org/xml/properties/dom/current-element-node");
        } catch (SAXException se) {
            se.printStackTrace();
        }
        return n;
    }

    //
    // XMLDocumentHandler interface
    //

    /**
     * This allows the programmer to decide which document factory
     * to use when constructing the DOM tree. However, doing so
     * will lose the parsing performance gain of the default factory.
     * <p>
     * <b>Note:</b> Setting the document class name to any other
     * document class besides the default class will switch the
     * node expansion to FULL.
     *
     * @param documentClass The fully qualified class name of the
     *                      document factory to use when constructing
     *                      the DOM tree.
     *
     * @see #DEFERRED_DOCUMENT_CLASS
     * @see #setNodeExpansion
     * @see #FULL
     */
    public void setDocumentClass(String documentClass) {
        try {
            fParser.setProperty("http://apache.org/xml/properties/dom/document-class-name", documentClass);
        } catch (SAXException se) {
            se.printStackTrace();
        }
    }

	/** Returns the document. */
    public Document getDocument() {
        return fParser.getDocument();
    }

    //
    // XMLParser methods
    //

    public void setErrorHandler(org.xml.sax.ErrorHandler handler) {
        fParser.setErrorHandler(handler);
    }

    public  void setLocale(java.util.Locale locale) throws org.xml.sax.SAXException {
        fParser.setLocale(locale);
    }

    /**
     * Parses the specified input source.
     *
     * @param source The input source.
     *
     * @exception org.xml.sax.SAXException Throws exception on SAX error.
     * @exception java.io.IOException Throws exception on i/o error.
     */
    public void parse(InputSource source) throws SAXException, IOException {
        fParser.parse(source);
    }

    public void parse(String systemId) throws org.xml.sax.SAXException, IOException
    {
        fParser.parse(systemId);
    }
    private void setFeature(String name, boolean value) {
        try {
            fParser.setFeature(name, value);
        } catch (SAXException se) {
            se.printStackTrace();
        }
    }

    private boolean getFeature(String name) {
        boolean flag = false;
        try {
            return fParser.getFeature(name);
        } catch (SAXException se) {
            se.printStackTrace();
        }
        return flag;
    }
}
