/* SAXDriver.java -- 
   Copyright (C) 1999,2000,2001,2004 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.

Portions derived from code which carried the following notice:

  Copyright (c) 1997, 1998 by Microstar Software Ltd.

  AElfred is free for both commercial and non-commercial use and
  redistribution, provided that Microstar's copyright and disclaimer are
  retained intact.  You are free to modify AElfred for your own use and
  to redistribute AElfred with your modifications, provided that the
  modifications are clearly documented.

  This program 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.  Please use it AT
  YOUR OWN RISK.
*/

package gnu.xml.aelfred2;

import java.io.*;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
import java.util.Stack;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

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


/**
 * An enhanced SAX2 version of Microstar's &AElig;lfred XML parser.
 * The enhancements primarily relate to significant improvements in
 * conformance to the XML specification, and SAX2 support.  Performance
 * has been improved.  See the package level documentation for more
 * information.
 *
 * <table border="1" width='100%' cellpadding='3' cellspacing='0'>
 * <tr bgcolor='#ccccff'>
 *	<th><font size='+1'>Name</font></th>
 *	<th><font size='+1'>Notes</font></th></tr>
 *
 * <tr><td colspan=2><center><em>Features ... URL prefix is
 * <b>http://xml.org/sax/features/</b></em></center></td></tr>
 *
 * <tr><td>(URL)/external-general-entities</td>
 *	<td>Value defaults to <em>true</em></td></tr>
 * <tr><td>(URL)/external-parameter-entities</td>
 *	<td>Value defaults to <em>true</em></td></tr>
 * <tr><td>(URL)/is-standalone</td>
 *	<td>(PRELIMINARY) Returns true iff the document's parsing
 *	has started (some non-error event after <em>startDocument()</em>
 *	was reported) and the document's standalone flag is set.</td></tr>
 * <tr><td>(URL)/namespace-prefixes</td>
 *	<td>Value defaults to <em>false</em> (but XML 1.0 names are
 *		always reported)</td></tr>
 * <tr><td>(URL)/lexical-handler/parameter-entities</td>
 *	<td>Value is fixed at <em>true</em></td></tr>
 * <tr><td>(URL)/namespaces</td>
 *	<td>Value defaults to <em>true</em></td></tr>
 * <tr><td>(URL)/resolve-dtd-uris</td>
 *	<td>(PRELIMINARY) Value defaults to <em>true</em></td></tr>
 * <tr><td>(URL)/string-interning</td>
 *	<td>Value is fixed at <em>true</em></td></tr>
 * <tr><td>(URL)/use-attributes2</td>
 *	<td>(PRELIMINARY) Value is fixed at <em>true</em></td></tr>
 * <tr><td>(URL)/use-entity-resolver2</td>
 *	<td>(PRELIMINARY) Value defaults to <em>true</em></td></tr>
 * <tr><td>(URL)/validation</td>
 *	<td>Value is fixed at <em>false</em></td></tr>
 *
 * <tr><td colspan=2><center><em>Handler Properties ... URL prefix is
 * <b>http://xml.org/sax/properties/</b></em></center></td></tr>
 *
 * <tr><td>(URL)/declaration-handler</td>
 *	<td>A declaration handler may be provided.  </td></tr>
 * <tr><td>(URL)/lexical-handler</td>
 *	<td>A lexical handler may be provided.  </td></tr>
 * </table>
 *
 * <p>This parser currently implements the SAX1 Parser API, but
 * it may not continue to do so in the future.
 *
 * @author Written by David Megginson (version 1.2a from Microstar)
 * @author Updated by David Brownell &lt;dbrownell@users.sourceforge.net&gt;
 * @see org.xml.sax.Parser
 */
final public class SAXDriver
  implements Locator, Attributes2, XMLReader, Parser, AttributeList
{
  
  private final DefaultHandler2 base = new DefaultHandler2();
  private XmlParser parser;
  
  private EntityResolver entityResolver = base;
  private EntityResolver2 resolver2 = null;
  private ContentHandler contentHandler = base;
  private DTDHandler dtdHandler = base;
  private ErrorHandler errorHandler = base;
  private DeclHandler declHandler = base;
  private LexicalHandler lexicalHandler = base;
  
  private String elementName;
  private Stack entityStack;
  
  // one vector (of object/struct): faster, smaller
  private List attributesList;
  
  private boolean namespaces = true;
  private boolean xmlNames = false;
  private boolean extGE = true;
  private boolean extPE = true;
  private boolean resolveAll = true;
  private boolean useResolver2 = true;
  
  // package private to allow (read-only) access in XmlParser
  boolean stringInterning = true;
  
  private int attributeCount;
  private boolean attributes;
  private String[] nsTemp;
  private NamespaceSupport prefixStack;
  
  //
  // Constructor.
  //

  /**
   * Constructs a SAX Parser.
   */
  public SAXDriver()
  {
    reset();
  }

  private void reset()
  {
    elementName = null;
    entityStack = new Stack();
    attributesList = Collections.synchronizedList(new ArrayList());
    attributeCount = 0;
    attributes = false;
    nsTemp = new String[3];
    prefixStack = null;
  }


  //
  // Implementation of org.xml.sax.Parser.
  //

  /**
   * <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
  {
    if ("en".equals(locale.getLanguage()))
      {
        return;
      }
    throw new SAXException ("AElfred2 only supports English locales.");
  }

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

  /**
   * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.
   * @param handler The object to receive entity events.
   */
  public void setEntityResolver(EntityResolver resolver)
  {
    if (resolver instanceof EntityResolver2)
      {
        resolver2 = (EntityResolver2) resolver;
      }
    else
      {
        resolver2 = null;
      }
    if (resolver == null)
      {
        resolver = base;
      }
    entityResolver = resolver;
  }

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

  /**
   * <b>SAX1, SAX2</b>: Set the DTD handler for this parser.
   * @param handler The object to receive DTD events.
   */
  public void setDTDHandler(DTDHandler handler)
  {
    if (handler == null)
      {
        handler = base;
      }
    this.dtdHandler = handler;
  }


  /**
   * <b>SAX1</b>: Set the document handler for this parser.  If a
   * content handler was set, this document handler will supplant it.
   * The parser is set to report all XML 1.0 names rather than to
   * filter out "xmlns" attributes (the "namespace-prefixes" feature
   * is set to true).
   *
   * @deprecated SAX2 programs should use the XMLReader interface
   *  and a ContentHandler.
   *
   * @param handler The object to receive document events.
   */
  public void setDocumentHandler(DocumentHandler handler)
  {
    contentHandler = new Adapter(handler);
    xmlNames = true;
  }

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

  /**
   * <b>SAX2</b>: Assigns the object used to report the logical
   * content of an XML document.  If a document handler was set,
   * this content handler will supplant it (but XML 1.0 style name
   * reporting may remain enabled).
   */
  public void setContentHandler(ContentHandler handler)
  {
    if (handler == null)
      {
        handler = base;
      }
    contentHandler = handler;
  }

  /**
   * <b>SAX1, SAX2</b>: Set the error handler for this parser.
   * @param handler The object to receive error events.
   */
  public void setErrorHandler(ErrorHandler handler)
  {
    if (handler == null)
      {
        handler = base;
      }
    this.errorHandler = 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 (errorHandler == base) ? null : errorHandler;
  }

  /**
   * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
   * when no URI is available.
   * If you want anything useful to happen, you should set
   * at least one type of handler.
   * @param source The XML input source.  Don't set 'encoding' unless
   *  you know for a fact that it's correct.
   * @see #setEntityResolver
   * @see #setDTDHandler
   * @see #setContentHandler
   * @see #setErrorHandler
   * @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
  {
    synchronized (base)
      {
        parser = new XmlParser();
        if (namespaces)
          {
            prefixStack = new NamespaceSupport();
          }
        else if (!xmlNames)
          {
            throw new IllegalStateException();
          }
        parser.setHandler(this);
        
        try
          {
            Reader r = source.getCharacterStream();
            InputStream in = source.getByteStream();
                        
            parser.doParse(source.getSystemId(),
                           source.getPublicId(),
                           r,
                           in,
                           source.getEncoding());
          }
        catch (SAXException e)
          {
            throw e;
          }
        catch (IOException e)
          {
            throw e;
          }
        catch (RuntimeException e)
          {
            throw e;
          }
        catch (Exception e)
          {
            throw new SAXParseException(e.getMessage(), this, e);
          }
        finally
          {
            contentHandler.endDocument();
            reset();
          }
      }
  }

  /**
   * <b>SAX1, SAX2</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));
  }

  //
  // Implementation of SAX2 "XMLReader" interface
  //
  static final String FEATURE = "http://xml.org/sax/features/";
  static final String PROPERTY = "http://xml.org/sax/properties/";

  /**
   * <b>SAX2</b>: Tells the value of the specified feature flag.
   *
   * @exception SAXNotRecognizedException thrown if the feature flag
   *  is neither built in, nor yet assigned.
   */
  public boolean getFeature(String featureId)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    if ((FEATURE + "validation").equals(featureId))
      {
        return false;
      }

    // external entities (both types) are optionally included
    if ((FEATURE + "external-general-entities").equals(featureId))
      {
        return extGE;
      }
    if ((FEATURE + "external-parameter-entities").equals(featureId))
      {
        return extPE;
      }
    
    // element/attribute names are as written in document; no mangling
    if ((FEATURE + "namespace-prefixes").equals(featureId))
      {
        return xmlNames;
      }

    // report element/attribute namespaces?
    if ((FEATURE + "namespaces").equals(featureId))
      {
        return namespaces;
      }

    // all PEs and GEs are reported
    if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId))
      {
        return true;
      }

    // default is true
    if ((FEATURE + "string-interning").equals(featureId))
      {
        return stringInterning;
      }
  
    // EXTENSIONS 1.1
    
    // always returns isSpecified info
    if ((FEATURE + "use-attributes2").equals(featureId))
      {
        return true;
      }
  
    // meaningful between startDocument/endDocument
    if ((FEATURE + "is-standalone").equals(featureId))
      {
        if (parser == null)
          {
            throw new SAXNotSupportedException(featureId);
          }
        return parser.isStandalone();
      }

    // optionally don't absolutize URIs in declarations
    if ((FEATURE + "resolve-dtd-uris").equals(featureId))
      {
        return resolveAll;
      }

    // optionally use resolver2 interface methods, if possible
    if ((FEATURE + "use-entity-resolver2").equals(featureId))
      {
        return useResolver2;
      }
  
    throw new SAXNotRecognizedException(featureId);
  }

  // package private
  DeclHandler getDeclHandler()
  {
    return declHandler;
  }

  // package private
  boolean resolveURIs()
  {
    return resolveAll;
  }

  /**
   * <b>SAX2</b>:  Returns the specified property.
   *
   * @exception SAXNotRecognizedException thrown if the property value
   *  is neither built in, nor yet stored.
   */
  public Object getProperty(String propertyId)
    throws SAXNotRecognizedException
  {
    if ((PROPERTY + "declaration-handler").equals(propertyId))
      {
        return (declHandler == base) ? null : declHandler;
      }

    if ((PROPERTY + "lexical-handler").equals(propertyId))
      {
        return (lexicalHandler == base) ? null : lexicalHandler;
      }
    
    // unknown properties
    throw new SAXNotRecognizedException(propertyId);
  }

  /**
   * <b>SAX2</b>:  Sets the state of feature flags in this parser.  Some
   * built-in feature flags are mutable.
   */
  public void setFeature(String featureId, boolean value)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    boolean state;
  
    // Features with a defined value, we just change it if we can.
    state = getFeature (featureId);
    
    if (state == value)
      {
        return;
      }
    if (parser != null)
      {
        throw new SAXNotSupportedException("not while parsing");
      }

    if ((FEATURE + "namespace-prefixes").equals(featureId))
      {
        // in this implementation, this only affects xmlns reporting
        xmlNames = value;
        // forcibly prevent illegal parser state
        if (!xmlNames)
          {
            namespaces = true;
          }
        return;
      }

    if ((FEATURE + "namespaces").equals(featureId))
      {
        namespaces = value;
        // forcibly prevent illegal parser state
        if (!namespaces)
          {
            xmlNames = true;
          }
        return;
      }

    if ((FEATURE + "external-general-entities").equals(featureId))
      {
        extGE = value;
        return;
      }
    if ((FEATURE + "external-parameter-entities").equals(featureId))
      {
        extPE = value;
        return;
      }
    if ((FEATURE + "resolve-dtd-uris").equals(featureId))
      {
        resolveAll = value;
        return;
      }

    if ((FEATURE + "use-entity-resolver2").equals(featureId))
      {
        useResolver2 = value;
        return;
      }

    throw new SAXNotRecognizedException(featureId);
  }

  /**
   * <b>SAX2</b>:  Assigns the specified property.  Like SAX1 handlers,
   * these may be changed at any time.
   */
  public void setProperty(String propertyId, Object value)
    throws SAXNotRecognizedException, SAXNotSupportedException
  {
    // see if the property is recognized
    getProperty(propertyId);
    
    // Properties with a defined value, we just change it if we can.
    
    if ((PROPERTY + "declaration-handler").equals(propertyId))
      {
        if (value == null)
          {
            declHandler = base;
          }
        else if (!(value instanceof DeclHandler))
          {
            throw new SAXNotSupportedException(propertyId);
          }
        else
          {
            declHandler = (DeclHandler) value;
          }
        return ;
      }
    
    if ((PROPERTY + "lexical-handler").equals(propertyId))
      {
        if (value == null)
          {
            lexicalHandler = base;
          }
        else if (!(value instanceof LexicalHandler))
          {
            throw new SAXNotSupportedException(propertyId);
          }
        else
          {
            lexicalHandler = (LexicalHandler) value;
          }
        return;
      }
    
    throw new SAXNotSupportedException(propertyId);
  }

  //
  // This is where the driver receives XmlParser callbacks and translates
  // them into SAX callbacks.  Some more callbacks have been added for
  // SAX2 support.
  //

  void startDocument()
    throws SAXException
  {
    contentHandler.setDocumentLocator(this);
    contentHandler.startDocument();
    attributesList.clear();
  }

  void xmlDecl(String version,
               String encoding,
               boolean standalone,
               String inputEncoding)
    throws SAXException
  {
    if (contentHandler instanceof ContentHandler2)
      {
        ((ContentHandler2) contentHandler).xmlDecl(version,
                                                   encoding,
                                                   standalone,
                                                   inputEncoding);
      }
  }

  void skippedEntity(String name)
    throws SAXException
  {
    contentHandler.skippedEntity(name);
  }

  InputSource getExternalSubset(String name, String baseURI)
    throws SAXException, IOException
  {
    if (resolver2 == null || !useResolver2 || !extPE)
      {
        return null;
      }
    return resolver2.getExternalSubset(name, baseURI);
  }

  InputSource resolveEntity(boolean isPE, String name,
                            InputSource in, String baseURI)
    throws SAXException, IOException
  {
    InputSource  source;
    
    // external entities might be skipped
    if (isPE && !extPE)
      {
        return null;
      }
    if (!isPE && !extGE)
      {
        return null;
      }

    // ... or not
    lexicalHandler.startEntity(name);
    if (resolver2 != null && useResolver2)
      {
        source = resolver2.resolveEntity(name, in.getPublicId(),
                                         baseURI, in.getSystemId());
        if (source == null)
          {
            in.setSystemId(absolutize(baseURI,
                                      in.getSystemId(), false));
            source = in;
          }
      }
    else
      {
        in.setSystemId(absolutize(baseURI, in.getSystemId(), false));
        source = entityResolver.resolveEntity(in.getPublicId(),
                                              in.getSystemId());
        if (source == null)
          {
            source = in;
          }
      }
    startExternalEntity(name, source.getSystemId(), true);
    return source;
  }

  // absolutize a system ID relative to the specified base URI
  // (temporarily) package-visible for external entity decls
  String absolutize(String baseURI, String systemId, boolean nice)
    throws MalformedURLException, SAXException
  {
    // FIXME normalize system IDs -- when?
    // - Convert to UTF-8
    // - Map reserved and non-ASCII characters to %HH
    
    try
      {
        if (baseURI == null)
          {
            if (XmlParser.uriWarnings)
              {
                warn ("No base URI; hope this SYSTEM id is absolute: "
                      + systemId);
              }
            return new URL(systemId).toString();
          }
        else
          {
            return new URL(new URL(baseURI), systemId).toString();
          }
      }
    catch (MalformedURLException e)
      {
        // Let unknown URI schemes pass through unless we need
        // the JVM to map them to i/o streams for us...
        if (!nice)
          {
            throw e;
          }
        
        // sometimes sysids for notations or unparsed entities
        // aren't really URIs...
        warn("Can't absolutize SYSTEM id: " + e.getMessage());
        return systemId;
      }
  }

  void startExternalEntity(String name, String systemId, boolean stackOnly)
    throws SAXException
  {
    // The following warning was deleted because the application has the
    // option of not setting systemId. Sun's JAXP or Xerces seems to
    // ignore this case.
    /*
       if (systemId == null)
       warn ("URI was not reported to parser for entity " + name);
     */
    if (!stackOnly)  // spliced [dtd] needs startEntity
      {
        lexicalHandler.startEntity(name);
      }
    entityStack.push(systemId);
  }

  void endExternalEntity(String name)
    throws SAXException
  {
    if (!"[document]".equals(name))
      {
        lexicalHandler.endEntity(name);
      }
    entityStack.pop();
  }

  void startInternalEntity(String name)
    throws SAXException
  {
    lexicalHandler.startEntity(name);
  }

  void endInternalEntity(String name)
    throws SAXException
  {
    lexicalHandler.endEntity(name);
  }

  void doctypeDecl(String name, String publicId, String systemId)
    throws SAXException
  {
    lexicalHandler.startDTD(name, publicId, systemId);
  
    // ... the "name" is a declaration and should be given
    // to the DeclHandler (but sax2 doesn't).
    
    // the IDs for the external subset are lexical details,
    // as are the contents of the internal subset; but sax2
    // doesn't provide the internal subset "pre-parse"
  }
  
  void notationDecl(String name, String publicId, String systemId,
                    String baseUri)
    throws SAXException
  {
    try
      {
        dtdHandler.notationDecl(name, publicId,
                                (resolveAll && systemId != null)
                                ? absolutize(baseUri, systemId, true)
                                : systemId);
      }
    catch (IOException e)
      {
        // "can't happen"
        throw new SAXParseException(e.getMessage(), this, e);
      }
  }

  void unparsedEntityDecl(String name, String publicId, String systemId,
                          String baseUri, String notation)
    throws SAXException
  {
    try
      {
        dtdHandler.unparsedEntityDecl(name, publicId,
                                      resolveAll
                                      ? absolutize(baseUri, systemId, true)
                                      : systemId,
                                      notation);
      }
    catch (IOException e)
      {
        // "can't happen"
        throw new SAXParseException(e.getMessage(), this, e);
      }
  }

  void endDoctype()
    throws SAXException
  {
    lexicalHandler.endDTD();
  }

  private void declarePrefix(String prefix, String uri)
    throws SAXException
  {
    int index = uri.indexOf(':');

    // many versions of nwalsh docbook stylesheets 
    // have bogus URLs; so this can't be an error...
    if (index < 1 && uri.length() != 0)
      {
        warn("relative URI for namespace: " + uri);
      }

    // FIXME:  char [0] must be ascii alpha; chars [1..index]
    // must be ascii alphanumeric or in "+-." [RFC 2396]
    
    //Namespace Constraints
    //name for xml prefix must be http://www.w3.org/XML/1998/namespace
    boolean prefixEquality = prefix.equals("xml");
    boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");
    if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
      {
        fatal("xml is by definition bound to the namespace name " +
              "http://www.w3.org/XML/1998/namespace");
      }
  
    //xmlns prefix declaration is illegal but xml prefix declaration is llegal...
    if (prefixEquality && uriEquality)
      {
        return;
      }
  
    //name for xmlns prefix must be http://www.w3.org/2000/xmlns/
    prefixEquality = prefix.equals("xmlns");
    uriEquality = uri.equals("http://www.w3.org/2000/xmlns/");
    if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
      {
        fatal("http://www.w3.org/2000/xmlns/ is by definition bound" +
              " to prefix xmlns");
      }
  
    //even if the uri is http://www.w3.org/2000/xmlns/
    // it is illegal to declare it
    if (prefixEquality && uriEquality)
      {
        fatal ("declaring the xmlns prefix is illegal");
      }
  
    uri = uri.intern();
    prefixStack.declarePrefix(prefix, uri);
    contentHandler.startPrefixMapping(prefix, uri);
  }

  void attribute(String qname, String value, boolean isSpecified)
    throws SAXException
  {
    if (!attributes)
      {
        attributes = true;
        if (namespaces)
          {
            prefixStack.pushContext();
          }
      }
    
    // process namespace decls immediately;
    // then maybe forget this as an attribute
    if (namespaces)
      {
        int index;
        
        // default NS declaration?
        if (stringInterning)
          {
            if ("xmlns" == qname)
              {
                declarePrefix("", value);
                if (!xmlNames)
                  {
                    return;
                  }
              }
            // NS prefix declaration?
            else if ((index = qname.indexOf(':')) == 5
                     && qname.startsWith("xmlns"))
              {
                String prefix = qname.substring(6);
              
                if (prefix.equals(""))
                  {
                    fatal("missing prefix " +
                          "in namespace declaration attribute");  
                  }
                if (value.length() == 0)
                  {
                    verror("missing URI in namespace declaration attribute: "
                           + qname);
                  }
                else
                  {
                    declarePrefix(prefix, value);
                  }
                if (!xmlNames)
                  {
                    return;
                  }
              }
          }
        else
          {
            if ("xmlns".equals(qname))
              {
                declarePrefix("", value);
                if (!xmlNames)
                  {
                    return;
                  }
              }
            // NS prefix declaration?
            else if ((index = qname.indexOf(':')) == 5
                     && qname.startsWith("xmlns"))
              {
                String prefix = qname.substring(6);
                
                if (value.length() == 0)
                  {
                    verror("missing URI in namespace decl attribute: "
                           + qname);
                  }
                else
                  {
                    declarePrefix(prefix, value);
                  }
                if (!xmlNames)
                  {
                    return;
                  }
              }
          }
      }
    // remember this attribute ...
    attributeCount++;
    
    // attribute type comes from querying parser's DTD records
    attributesList.add(new Attribute(qname, value, isSpecified));
    
  }
  
  void startElement(String elname)
    throws SAXException
  {
    ContentHandler handler = contentHandler;

    //
    // NOTE:  this implementation of namespace support adds something
    // like six percent to parsing CPU time, in a large (~50 MB)
    // document that doesn't use namespaces at all.  (Measured by PC
    // sampling, with a bug where endElement processing was omitted.)
    // [Measurement referred to older implementation, older JVM ...]
    //
    // It ought to become notably faster in such cases.  Most
    // costs are the prefix stack calling Hashtable.get() (2%),
    // String.hashCode() (1.5%) and about 1.3% each for pushing
    // the context, and two chunks of name processing.
    //
    
    if (!attributes)
      {
        if (namespaces)
          {
            prefixStack.pushContext();
          }
      }
    else if (namespaces)
      {
      
        // now we can patch up namespace refs; we saw all the
        // declarations, so now we'll do the Right Thing
        Iterator itt = attributesList.iterator();
        while (itt.hasNext())
          {
            Attribute attribute = (Attribute) itt.next();
            String qname = attribute.name;
            int index;
            
            // default NS declaration?
            if (stringInterning)
              {
                if ("xmlns" == qname)
                  {
                    continue;
                  }
              }
            else
              {
                if ("xmlns".equals(qname))
                  {
                    continue;
                  }
              }
            //Illegal in the new Namespaces Draft
            //should it be only in 1.1 docs??
            if (qname.equals (":"))
              {
                fatal("namespace names consisting of a single colon " +
                      "character are invalid");
              }
            index = qname.indexOf(':');
            
            // NS prefix declaration?
            if (index == 5 && qname.startsWith("xmlns"))
              {
                continue;
              }
            
            // it's not a NS decl; patch namespace info items
            if (prefixStack.processName(qname, nsTemp, true) == null)
              {
                fatal("undeclared attribute prefix in: " + qname);
              }
            else
              {
                attribute.nameSpace = nsTemp[0];
                attribute.localName = nsTemp[1];
              }
          }
      }
    
    // save element name so attribute callbacks work
    elementName = elname;
    if (namespaces)
      {
        if (prefixStack.processName(elname, nsTemp, false) == null)
          {
            fatal("undeclared element prefix in: " + elname);
            nsTemp[0] = nsTemp[1] = "";
          }
        handler.startElement(nsTemp[0], nsTemp[1], elname, this);
      }
    else
      {
        handler.startElement("", "", elname, this);
      }
    // elementName = null;
    
    // elements with no attributes are pretty common!
    if (attributes)
      {
        attributesList.clear();
        attributeCount = 0;
        attributes = false;
      }
  }
  
  void endElement(String elname)
    throws SAXException
  {
    ContentHandler handler = contentHandler;

    if (!namespaces)
      {
        handler.endElement("", "", elname);
        return;
      }
    prefixStack.processName(elname, nsTemp, false);
    handler.endElement(nsTemp[0], nsTemp[1], elname);
    
    Enumeration prefixes = prefixStack.getDeclaredPrefixes();
    
    while (prefixes.hasMoreElements())
      {
        handler.endPrefixMapping((String) prefixes.nextElement());
      }
    prefixStack.popContext();
  }

  void startCDATA()
    throws SAXException
  {
    lexicalHandler.startCDATA();
  }

  void charData(char[] ch, int start, int length)
    throws SAXException
  {
    contentHandler.characters(ch, start, length);
  }

  void endCDATA()
    throws SAXException
  {
    lexicalHandler.endCDATA();
  }

  void ignorableWhitespace(char[] ch, int start, int length)
    throws SAXException
  {
    contentHandler.ignorableWhitespace(ch, start, length);
  }

  void processingInstruction(String target, String data)
    throws SAXException
  {
    contentHandler.processingInstruction(target, data);
  }

  void comment(char[] ch, int start, int length)
    throws SAXException
  {
    if (lexicalHandler != base)
      {
        lexicalHandler.comment(ch, start, length);
      }
  }

  void fatal(String message)
    throws SAXException
  {
    SAXParseException fatal;
  
    fatal = new SAXParseException(message, this);
    errorHandler.fatalError(fatal);

    // Even if the application can continue ... we can't!
    throw fatal;
  }

  // We can safely report a few validity errors that
  // make layered SAX2 DTD validation more conformant
  void verror(String message)
    throws SAXException
  {
    SAXParseException err;
    
    err = new SAXParseException(message, this);
    errorHandler.error(err);
  }
  
  void warn(String message)
    throws SAXException
  {
    SAXParseException err;
  
    err = new SAXParseException(message, this);
    errorHandler.warning(err);
  }

  //
  // Implementation of org.xml.sax.Attributes.
  //

  /**
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
   * (don't invoke on parser);
   */
  public int getLength()
  {
    return attributesList.size();
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public String getURI(int index)
  {
    if (index < 0 || index >= attributesList.size())
      {
        return null;
      }
    return ((Attribute) attributesList.get(index)).nameSpace;
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public String getLocalName(int index)
  {
    if (index < 0 || index >= attributesList.size())
      {
        return null;
      }
    Attribute attr = (Attribute) attributesList.get(index);
    // FIXME attr.localName is sometimes null, why?
    if (namespaces && attr.localName == null)
      {
        // XXX fix this here for now
        int ci = attr.name.indexOf(':');
        attr.localName = (ci == -1) ? attr.name :
          attr.name.substring(ci + 1);
      }
    return (attr.localName == null) ? "" : attr.localName;
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public String getQName(int index)
  {
    if (index < 0 || index >= attributesList.size())
      {
      return null;
      }
    Attribute attr = (Attribute) attributesList.get(index);
    return (attr.name == null) ? "" : attr.name;
  }

  /**
   * <b>SAX1 AttributeList</b> method (don't invoke on parser);
   */
  public String getName(int index)
  {
    return getQName(index);
  }

  /**
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
   * (don't invoke on parser);
   */
  public String getType(int index)
  {
    if (index < 0 || index >= attributesList.size())
      {
        return null;
      }
    String type = parser.getAttributeType(elementName, getQName(index));
    if (type == null)
      {
        return "CDATA";
      }
    // ... use DeclHandler.attributeDecl to see enumerations
    if (type == "ENUMERATION")
      {
        return "NMTOKEN";
      }
    return type;
  }

  /**
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
   * (don't invoke on parser);
   */
  public String getValue(int index)
  {
    if (index < 0 || index >= attributesList.size())
      {
        return null;
      }
    return ((Attribute) attributesList.get(index)).value;
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public int getIndex(String uri, String local)
    {
      int length = getLength();
      
      for (int i = 0; i < length; i++)
        {
          if (!getURI(i).equals(uri))
            {
              continue;
            }
          if (getLocalName(i).equals(local))
            {
              return i;
            }
        }
      return -1;
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public int getIndex(String xmlName)
  {
    int length = getLength();
    
    for (int i = 0; i < length; i++)
      {
        if (getQName(i).equals(xmlName))
          {
            return i;
          }
      }
    return -1;
  }

  /**
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
   */
  public String getType(String uri, String local)
  {
    int index = getIndex(uri, local);
    
    if (index < 0)
      {
        return null;
      }
    return getType(index);
  }

  /**
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
   * (don't invoke on parser);
   */
  public String getType(String xmlName)
  {
    int index = getIndex(xmlName);
    
    if (index < 0)
      {
        return null;
      }
    return getType(index);
  }

  /**
   * <b>SAX Attributes</b> method (don't invoke on parser);
   */
  public String getValue(String uri, String local)
  {
    int index = getIndex(uri, local);
    
    if (index < 0)
      {
        return null;
      }
    return getValue(index);
  }

  /**
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
   * (don't invoke on parser);
   */
  public String getValue(String xmlName)
  {
    int index = getIndex(xmlName);
    
    if (index < 0)
      {
        return null;
      }
    return getValue(index);
  }

  //
  // Implementation of org.xml.sax.ext.Attributes2
  //

  /** @return false unless the attribute was declared in the DTD.
   * @throws java.lang.ArrayIndexOutOfBoundsException
   *   When the supplied index does not identify an attribute.
   */  
  public boolean isDeclared(int index)
  {
    if (index < 0 || index >= attributeCount)
      {
        throw new ArrayIndexOutOfBoundsException();
      }
    String type = parser.getAttributeType(elementName, getQName(index));
    return (type != null);
  }

  /** @return false unless the attribute was declared in the DTD.
   * @throws java.lang.IllegalArgumentException
   *   When the supplied names do not identify an attribute.
   */
  public boolean isDeclared(String qName)
  {
    int index = getIndex(qName);
    if (index < 0)
      {
        throw new IllegalArgumentException();
      }
    String type = parser.getAttributeType(elementName, qName);
    return (type != null);
  }

  /** @return false unless the attribute was declared in the DTD.
   * @throws java.lang.IllegalArgumentException
   *   When the supplied names do not identify an attribute.
   */
  public boolean isDeclared(String uri, String localName)
  {
    int index = getIndex(uri, localName);
    return isDeclared(index);
  }

  /**
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
   */
  public boolean isSpecified(int index)
  {
    return ((Attribute) attributesList.get(index)).specified;
  }

  /**
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
   */
  public boolean isSpecified(String uri, String local)
  {
    int index = getIndex (uri, local);
    return isSpecified(index);
  }

  /**
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
   */
  public boolean isSpecified(String xmlName)
  {
    int index = getIndex (xmlName);
    return isSpecified(index);
  }

  //
  // Implementation of org.xml.sax.Locator.
  //

  /**
   * <b>SAX Locator</b> method (don't invoke on parser);
   */
  public String getPublicId()
  {
    return null;   // FIXME track public IDs too
  }

  /**
   * <b>SAX Locator</b> method (don't invoke on parser);
   */
  public String getSystemId()
  {
    if (entityStack.empty())
      {
        return null;
      }
    else
      {
        return (String) entityStack.peek();
      }
  }

  /**
   * <b>SAX Locator</b> method (don't invoke on parser);
   */
  public int getLineNumber()
  {
    return parser.getLineNumber();
  }

  /**
   * <b>SAX Locator</b> method (don't invoke on parser);
   */
  public int getColumnNumber()
  {
    return parser.getColumnNumber();
  }

  // adapter between SAX2 content handler and SAX1 document handler callbacks
  private static class Adapter
    implements ContentHandler
  {
    
    private DocumentHandler docHandler;

    Adapter(DocumentHandler dh)
    {
      docHandler = dh;
    }

    public void setDocumentLocator(Locator l)
    {
      docHandler.setDocumentLocator(l);
    }
  
    public void startDocument()
      throws SAXException
    {
      docHandler.startDocument();
    }
  
    public void processingInstruction(String target, String data)
      throws SAXException
    {
      docHandler.processingInstruction(target, data);
    }
  
    public void startPrefixMapping(String prefix, String uri)
    {
      /* ignored */
    }

    public void startElement(String namespace,
                             String local,
                             String name,
                             Attributes attrs)
      throws SAXException
    {
      docHandler.startElement(name, (AttributeList) attrs);
    }

    public void characters(char[] buf, int offset, int len)
      throws SAXException
    {
      docHandler.characters(buf, offset, len);
    }

    public void ignorableWhitespace(char[] buf, int offset, int len)
      throws SAXException
    {
      docHandler.ignorableWhitespace(buf, offset, len);
    }

    public void skippedEntity(String name)
    {
      /* ignored */
    }

    public void endElement(String u, String l, String name)
      throws SAXException
    {
      docHandler.endElement(name);
    }

    public void endPrefixMapping(String prefix)
    {
      /* ignored */
    }

    public void endDocument()
      throws SAXException
    {
      docHandler.endDocument();
    }
  }

  private static class Attribute
  {
    
    String name;
    String value;
    String nameSpace;
    String localName;
    boolean specified;
    
    Attribute(String name, String value, boolean specified)
    {
      this.name = name;
      this.value = value;
      this.nameSpace = "";
      this.specified = specified;
    }
    
  }

}
