mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1610 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1610 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Java
		
	
	
	
/* 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., 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.
 | 
						|
 | 
						|
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 Æ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 <dbrownell@users.sourceforge.net>
 | 
						|
 * @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 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(),
 | 
						|
                                  entityResolver != base));
 | 
						|
        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;
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
}
 |