/* XmlReader.java --
   Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.aelfred2;

import java.io.IOException;
import java.util.Locale;

import org.xml.sax.*;
import org.xml.sax.ext.*;

import gnu.xml.pipeline.EventFilter;
import gnu.xml.pipeline.ValidationConsumer;


/**
 * This SAX2 parser optionally layers a validator over the &AElig;lfred2
 * SAX2 parser.  While this will not evaluate every XML validity constraint,
 * it does support all the validity constraints that are of any real utility
 * outside the strict SGML-compatible world.  See the documentation for the
 * SAXDriver class for information about the SAX2 features and properties
 * that are supported, and documentation for the ValidationConsumer for
 * information about what validity constraints may not be supported.
 * (&AElig;lfred2 tests some of those, even in non-validating mode, to
 * achieve better conformance.)
 *
 * <p> Note that due to its internal construction, you can't change most
 * handlers until parse() returns.  This diverges slightly from SAX, which
 * expects later binding to be supported.  Early binding involves less
 * runtime overhead, which is an issue for event pipelines as used inside
 * this parser.  Rather than relying on the parser to handle late binding
 * to your own handlers, do it yourself.
 *
 * @see SAXDriver
 * @see gnu.xml.pipeline.ValidationConsumer
 *
 * @author David Brownell
 */
public final class XmlReader
  implements XMLReader
{

  static class FatalErrorHandler
    extends DefaultHandler2
  {

    public void error(SAXParseException e)
      throws SAXException
    {
      throw e;
    }

  }

  private SAXDriver aelfred2 = new SAXDriver();
  private EventFilter filter = new EventFilter();
  private boolean isValidating;
  private boolean active;

  /**
   * Constructs a SAX Parser.
   */
  public XmlReader()
  {
  }

  /**
   * Constructs a SAX Parser, optionally treating validity errors
   * as if they were fatal errors.
   */
  public XmlReader(boolean invalidIsFatal)
  {
    if (invalidIsFatal)
      {
        setErrorHandler(new FatalErrorHandler());
      }
  }

  /**
   * <b>SAX2</b>: Returns the object used to report the logical
   * content of an XML document.
   */
  public ContentHandler getContentHandler()
  {
    return filter.getContentHandler();
  }

  /**
   * <b>SAX2</b>: Assigns the object used to report the logical
   * content of an XML document.
   * @exception IllegalStateException if called mid-parse
   */
  public void setContentHandler(ContentHandler handler)
  {
    if (active)
      {
        throw new IllegalStateException("already parsing");
      }
    filter.setContentHandler(handler);
  }

  /**
   * <b>SAX2</b>: Returns the object used to process declarations related
   * to notations and unparsed entities.
   */
  public DTDHandler getDTDHandler()
  {
    return filter.getDTDHandler();
  }

  /**
   * <b>SAX1</b> Assigns DTD handler
   * @exception IllegalStateException if called mid-parse
   */
  public void setDTDHandler(DTDHandler handler)
  {
    if (active)
      {
        throw new IllegalStateException("already parsing");
      }
    filter.setDTDHandler(handler);
  }

  /**
   * <b>SAX2</b>: Returns the object used when resolving external
   * entities during parsing (both general and parameter entities).
   */
  public EntityResolver getEntityResolver()
  {
    return aelfred2.getEntityResolver();
  }

  /**
   * <b>SAX1</b> Assigns parser's entity resolver
   */
  public void setEntityResolver(EntityResolver handler)
  {
    aelfred2.setEntityResolver(handler);
  }

  /**
   * <b>SAX2</b>: Returns the object used to receive callbacks for XML
   * errors of all levels (fatal, nonfatal, warning); this is never null;
   */
  public ErrorHandler getErrorHandler()
  {
    return aelfred2.getErrorHandler();
  }

  /**
   * <b>SAX1</b> Assigns error handler
   * @exception IllegalStateException if called mid-parse
   */
  public void setErrorHandler(ErrorHandler handler)
  {
    if (active)
      {
        throw new IllegalStateException("already parsing");
      }
    aelfred2.setErrorHandler(handler);
  }

  /**
   * <b>SAX2</b>:  Assigns the specified property.
   * @exception IllegalStateException if called mid-parse
   */
  public void setProperty(String propertyId, Object value)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    if (active)
      {
        throw new IllegalStateException("already parsing");
      }
    if (getProperty(propertyId) != value)
      {
        filter.setProperty(propertyId, value);
      }
  }

  /**
   * <b>SAX2</b>:  Returns the specified property.
   */
  public Object getProperty(String propertyId)
    throws SAXNotRecognizedException
  {
    if ((SAXDriver.PROPERTY + "declaration-handler").equals(propertyId)
        || (SAXDriver.PROPERTY + "lexical-handler").equals(propertyId))
      {
        return filter.getProperty(propertyId);
      }
    throw new SAXNotRecognizedException(propertyId);
  }

  private void forceValidating()
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
                        true);
    aelfred2.setFeature(SAXDriver.FEATURE + "external-general-entities",
                        true);
    aelfred2.setFeature(SAXDriver.FEATURE + "external-parameter-entities",
                        true);
  }

  /**
   * <b>SAX2</b>:  Sets the state of features supported in this parser.
   * Note that this parser requires reporting of namespace prefixes when
   * validating.
   */
  public void setFeature(String featureId, boolean state)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    boolean value = getFeature(featureId);

    if (state == value)
      {
        return;
      }

    if ((SAXDriver.FEATURE + "validation").equals(featureId))
      {
        if (active)
          {
            throw new SAXNotSupportedException("already parsing");
          }
        if (state)
          {
            forceValidating();
          }
        isValidating = state;
      }
    else
      {
        aelfred2.setFeature(featureId, state);
      }
  }

  /**
   * <b>SAX2</b>: Tells whether this parser supports the specified feature.
   * At this time, this directly parallels the underlying SAXDriver,
   * except that validation is optionally supported.
   *
   * @see SAXDriver
   */
  public boolean getFeature(String featureId)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    if ((SAXDriver.FEATURE + "validation").equals(featureId))
      {
        return isValidating;
      }

    return aelfred2.getFeature(featureId);
  }

  /**
   * <b>SAX1</b>: Sets the locale used for diagnostics; currently,
   * only locales using the English language are supported.
   * @param locale The locale for which diagnostics will be generated
   */
  public void setLocale(Locale locale)
    throws SAXException
  {
    aelfred2.setLocale(locale);
  }

  /**
   * <b>SAX1</b>: Preferred API to parse an XML document, using a
   * system identifier (URI).
     */
  public void parse(String systemId)
    throws SAXException, IOException
  {
    parse(new InputSource(systemId));
  }

  /**
   * <b>SAX1</b>: Underlying API to parse an XML document, used
   * directly when no URI is available.  When this is invoked,
   * and the parser is set to validate, some features will be
   * automatically reset to appropriate values:  for reporting
   * namespace prefixes, and incorporating external entities.
   *
   * @param source The XML input source.
   *
   * @exception IllegalStateException if called mid-parse
   * @exception SAXException The handlers may throw any SAXException,
   *  and the parser normally throws SAXParseException objects.
   * @exception IOException IOExceptions are normally through through
   *  the parser if there are problems reading the source document.
   */
  public void parse(InputSource source)
    throws SAXException, IOException
  {
    EventFilter next;
    boolean nsdecls;

    synchronized (aelfred2)
      {
        if (active)
          {
            throw new IllegalStateException("already parsing");
          }
        active = true;
      }

    // set up the output pipeline
    if (isValidating)
      {
        forceValidating();
        next = new ValidationConsumer(filter);
      }
    else
      {
        next = filter;
      }

    // connect pipeline and error handler
    // don't let _this_ call to bind() affect xmlns* attributes
    nsdecls = aelfred2.getFeature(SAXDriver.FEATURE + "namespace-prefixes");
    EventFilter.bind(aelfred2, next);
    if (!nsdecls)
      {
        aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
                            false);
      }

    // parse, clean up
    try
      {
        aelfred2.parse(source);
      }
    finally
      {
        active = false;
      }
  }

}
