// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
// http://www.saxproject.org
// Written by David Megginson
// NO WARRANTY!  This class is in the public domain.
// $Id: ParserAdapter.java,v 1.1 2004/12/23 22:38:42 mark Exp $

package org.xml.sax.helpers;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;

import org.xml.sax.Parser;	// deprecated
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.AttributeList; // deprecated
import org.xml.sax.EntityResolver;
import org.xml.sax.DTDHandler;
import org.xml.sax.DocumentHandler; // deprecated
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import org.xml.sax.XMLReader;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;


/**
 * Adapt a SAX1 Parser as a SAX2 XMLReader.
 *
 * <blockquote>
 * <em>This module, both source code and documentation, is in the
 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
 * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
 * for further information.
 * </blockquote>
 *
 * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
 * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
 * with feature, property, and Namespace support.  Note
 * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
 * skippedEntity} events, since SAX1 does not make that information available.</p>
 *
 * <p>This adapter does not test for duplicate Namespace-qualified
 * attribute names.</p>
 *
 * @since SAX 2.0
 * @author David Megginson
 * @version 2.0.1 (sax2r2)
 * @see org.xml.sax.helpers.XMLReaderAdapter
 * @see org.xml.sax.XMLReader
 * @see org.xml.sax.Parser
 */
public class ParserAdapter implements XMLReader, DocumentHandler
{


    ////////////////////////////////////////////////////////////////////
    // Constructors.
    ////////////////////////////////////////////////////////////////////


    /**
     * Construct a new parser adapter.
     *
     * <p>Use the "org.xml.sax.parser" property to locate the
     * embedded SAX1 driver.</p>
     *
     * @exception SAXException If the embedded driver
     *            cannot be instantiated or if the
     *            org.xml.sax.parser property is not specified.
     */
    public ParserAdapter ()
      throws SAXException
    {
	super();

	String driver = System.getProperty("org.xml.sax.parser");

	try {
	    setup(ParserFactory.makeParser());
	} catch (ClassNotFoundException e1) {
	    throw new
		SAXException("Cannot find SAX1 driver class " +
			     driver, e1);
	} catch (IllegalAccessException e2) {
	    throw new
		SAXException("SAX1 driver class " +
			     driver +
			     " found but cannot be loaded", e2);
	} catch (InstantiationException e3) {
	    throw new
		SAXException("SAX1 driver class " +
			     driver +
			     " loaded but cannot be instantiated", e3);
	} catch (ClassCastException e4) {
	    throw new
		SAXException("SAX1 driver class " +
			     driver +
			     " does not implement org.xml.sax.Parser");
	} catch (NullPointerException e5) {
	    throw new 
		SAXException("System property org.xml.sax.parser not specified");
	}
    }


    /**
     * Construct a new parser adapter.
     *
     * <p>Note that the embedded parser cannot be changed once the
     * adapter is created; to embed a different parser, allocate
     * a new ParserAdapter.</p>
     *
     * @param parser The SAX1 parser to embed.
     * @exception java.lang.NullPointerException If the parser parameter
     *            is null.
     */
    public ParserAdapter (Parser parser)
    {
	super();
	setup(parser);
    }


    /**
     * Internal setup method.
     *
     * @param parser The embedded parser.
     * @exception java.lang.NullPointerException If the parser parameter
     *            is null.
     */
    private void setup (Parser parser)
    {
	if (parser == null) {
	    throw new
		NullPointerException("Parser argument must not be null");
	}
	this.parser = parser;
	atts = new AttributesImpl();
	nsSupport = new NamespaceSupport();
	attAdapter = new AttributeListAdapter();
    }



    ////////////////////////////////////////////////////////////////////
    // Implementation of org.xml.sax.XMLReader.
    ////////////////////////////////////////////////////////////////////


    //
    // Internal constants for the sake of convenience.
    //
    private final static String FEATURES = "http://xml.org/sax/features/";
    private final static String NAMESPACES = FEATURES + "namespaces";
    private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
    private final static String XMLNS_URIs = FEATURES + "xmlns-uris";


    /**
     * Set a feature flag for the parser.
     *
     * <p>The only features recognized are namespaces and 
     * namespace-prefixes.</p>
     *
     * @param name The feature name, as a complete URI.
     * @param value The requested feature value.
     * @exception SAXNotRecognizedException If the feature
     *            can't be assigned or retrieved.
     * @exception SAXNotSupportedException If the feature
     *            can't be assigned that value.
     * @see org.xml.sax.XMLReader#setFeature
     */
    public void setFeature (String name, boolean value)
	throws SAXNotRecognizedException, SAXNotSupportedException
    {
	if (name.equals(NAMESPACES)) {
	    checkNotParsing("feature", name);
	    namespaces = value;
	    if (!namespaces && !prefixes) {
		prefixes = true;
	    }
	} else if (name.equals(NAMESPACE_PREFIXES)) {
	    checkNotParsing("feature", name);
	    prefixes = value;
	    if (!prefixes && !namespaces) {
		namespaces = true;
	    }
	} else if (name.equals(XMLNS_URIs)) {
	    checkNotParsing("feature", name);
	    uris = value;
	} else {
	    throw new SAXNotRecognizedException("Feature: " + name);
	}
    }


    /**
     * Check a parser feature flag.
     *
     * <p>The only features recognized are namespaces and 
     * namespace-prefixes.</p>
     *
     * @param name The feature name, as a complete URI.
     * @return The current feature value.
     * @exception SAXNotRecognizedException If the feature
     *            value can't be assigned or retrieved.
     * @exception SAXNotSupportedException If the
     *            feature is not currently readable.
     * @see org.xml.sax.XMLReader#setFeature
     */
    public boolean getFeature (String name)
	throws SAXNotRecognizedException, SAXNotSupportedException
    {
	if (name.equals(NAMESPACES)) {
	    return namespaces;
	} else if (name.equals(NAMESPACE_PREFIXES)) {
	    return prefixes;
	} else if (name.equals(XMLNS_URIs)) {
	    return uris;
	} else {
	    throw new SAXNotRecognizedException("Feature: " + name);
	}
    }


    /**
     * Set a parser property.
     *
     * <p>No properties are currently recognized.</p>
     *
     * @param name The property name.
     * @param value The property value.
     * @exception SAXNotRecognizedException If the property
     *            value can't be assigned or retrieved.
     * @exception SAXNotSupportedException If the property
     *            can't be assigned that value.
     * @see org.xml.sax.XMLReader#setProperty
     */
    public void setProperty (String name, Object value)
	throws SAXNotRecognizedException, SAXNotSupportedException
    {
	throw new SAXNotRecognizedException("Property: " + name);
    }


    /**
     * Get a parser property.
     *
     * <p>No properties are currently recognized.</p>
     *
     * @param name The property name.
     * @return The property value.
     * @exception SAXNotRecognizedException If the property
     *            value can't be assigned or retrieved.
     * @exception SAXNotSupportedException If the property
     *            value is not currently readable.
     * @see org.xml.sax.XMLReader#getProperty
     */
    public Object getProperty (String name)
	throws SAXNotRecognizedException, SAXNotSupportedException
    {
	throw new SAXNotRecognizedException("Property: " + name);
    }


    /**
     * Set the entity resolver.
     *
     * @param resolver The new entity resolver.
     * @see org.xml.sax.XMLReader#setEntityResolver
     */
    public void setEntityResolver (EntityResolver resolver)
    {
	entityResolver = resolver;
    }


    /**
     * Return the current entity resolver.
     *
     * @return The current entity resolver, or null if none was supplied.
     * @see org.xml.sax.XMLReader#getEntityResolver
     */
    public EntityResolver getEntityResolver ()
    {
	return entityResolver;
    }


    /**
     * Set the DTD handler.
     *
     * @param handler the new DTD handler
     * @see org.xml.sax.XMLReader#setEntityResolver
     */
    public void setDTDHandler (DTDHandler handler)
    {
	dtdHandler = handler;
    }


    /**
     * Return the current DTD handler.
     *
     * @return the current DTD handler, or null if none was supplied
     * @see org.xml.sax.XMLReader#getEntityResolver
     */
    public DTDHandler getDTDHandler ()
    {
	return dtdHandler;
    }


    /**
     * Set the content handler.
     *
     * @param handler the new content handler
     * @see org.xml.sax.XMLReader#setEntityResolver
     */
    public void setContentHandler (ContentHandler handler)
    {
	contentHandler = handler;
    }


    /**
     * Return the current content handler.
     *
     * @return The current content handler, or null if none was supplied.
     * @see org.xml.sax.XMLReader#getEntityResolver
     */
    public ContentHandler getContentHandler ()
    {
	return contentHandler;
    }


    /**
     * Set the error handler.
     *
     * @param handler The new error handler.
     * @see org.xml.sax.XMLReader#setEntityResolver
     */
    public void setErrorHandler (ErrorHandler handler)
    {
	errorHandler = handler;
    }


    /**
     * Return the current error handler.
     *
     * @return The current error handler, or null if none was supplied.
     * @see org.xml.sax.XMLReader#getEntityResolver
     */
    public ErrorHandler getErrorHandler ()
    {
	return errorHandler;
    }


    /**
     * Parse an XML document.
     *
     * @param systemId The absolute URL of the document.
     * @exception java.io.IOException If there is a problem reading
     *            the raw content of the document.
     * @exception SAXException If there is a problem
     *            processing the document.
     * @see #parse(org.xml.sax.InputSource)
     * @see org.xml.sax.Parser#parse(java.lang.String)
     */
    public void parse (String systemId)
	throws IOException, SAXException
    {
	parse(new InputSource(systemId));
    }


    /**
     * Parse an XML document.
     *
     * @param input An input source for the document.
     * @exception java.io.IOException If there is a problem reading
     *            the raw content of the document.
     * @exception SAXException If there is a problem
     *            processing the document.
     * @see #parse(java.lang.String)
     * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
     */
    public void parse (InputSource input)
	throws IOException, SAXException
    {
	if (parsing) {
	    throw new SAXException("Parser is already in use");
	}
	setupParser();
	parsing = true;
	try {
	    parser.parse(input);
	} finally {
	    parsing = false;
	}
	parsing = false;
    }



    ////////////////////////////////////////////////////////////////////
    // Implementation of org.xml.sax.DocumentHandler.
    ////////////////////////////////////////////////////////////////////


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 document locator event.
     *
     * @param locator A document locator.
     * @see org.xml.sax.ContentHandler#setDocumentLocator
     */
    public void setDocumentLocator (Locator locator)
    {
	this.locator = locator;
	if (contentHandler != null) {
	    contentHandler.setDocumentLocator(locator);
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 start document event.
     *
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#startDocument
     */
    public void startDocument ()
	throws SAXException
    {
	if (contentHandler != null) {
	    contentHandler.startDocument();
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 end document event.
     *
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#endDocument
     */
    public void endDocument ()
	throws SAXException
    {
	if (contentHandler != null) {
	    contentHandler.endDocument();
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 startElement event.
     *
     * <p>If necessary, perform Namespace processing.</p>
     *
     * @param qName The qualified (prefixed) name.
     * @param qAtts The XML attribute list (with qnames).
     * @exception SAXException The client may raise a
     *            processing exception.
     */
    public void startElement (String qName, AttributeList qAtts)
	throws SAXException
    {
				// These are exceptions from the
				// first pass; they should be
				// ignored if there's a second pass,
				// but reported otherwise.
	Vector exceptions = null;

				// If we're not doing Namespace
				// processing, dispatch this quickly.
	if (!namespaces) {
	    if (contentHandler != null) {
		attAdapter.setAttributeList(qAtts);
		contentHandler.startElement("", "", qName.intern(),
					    attAdapter);
	    }
	    return;
	}


				// OK, we're doing Namespace processing.
	nsSupport.pushContext();
	int length = qAtts.getLength();
	
				// First pass:  handle NS decls
	for (int i = 0; i < length; i++) {
	    String attQName = qAtts.getName(i);

	    if (!attQName.startsWith("xmlns"))
		continue;
				// Could be a declaration...
	    String prefix;
	    int n = attQName.indexOf(':');

	    			// xmlns=...
	    if (n == -1 && attQName.length () == 5) {
		prefix = "";
	    } else if (n != 5) {
		// XML namespaces spec doesn't discuss "xmlnsf:oo"
		// (and similarly named) attributes ... at most, warn
		continue;
	    } else 		// xmlns:foo=...
		prefix = attQName.substring(n+1);

	    String value = qAtts.getValue(i);
	    if (!nsSupport.declarePrefix(prefix, value)) {
		reportError("Illegal Namespace prefix: " + prefix);
		continue;
	    }
	    if (contentHandler != null)
		contentHandler.startPrefixMapping(prefix, value);
	}
	
				// Second pass: copy all relevant
				// attributes into the SAX2 AttributeList
				// using updated prefix bindings
	atts.clear();
	for (int i = 0; i < length; i++) {
	    String attQName = qAtts.getName(i);
	    String type = qAtts.getType(i);
	    String value = qAtts.getValue(i);

				// Declaration?
	    if (attQName.startsWith("xmlns")) {
		String prefix;
		int n = attQName.indexOf(':');

		if (n == -1 && attQName.length () == 5) {
		    prefix = "";
		} else if (n != 5) {
		    // XML namespaces spec doesn't discuss "xmlnsf:oo"
		    // (and similarly named) attributes ... ignore
		    prefix = null;
		} else {
		    prefix = attQName.substring(6);
		}
				// Yes, decl:  report or prune
		if (prefix != null) {
		    if (prefixes) {
			if (uris)
			    // note funky case:  localname can be null
			    // when declaring the default prefix, and
			    // yet the uri isn't null.
			    atts.addAttribute (nsSupport.XMLNS, prefix,
				    attQName.intern(), type, value);
			else
			    atts.addAttribute ("", "",
				    attQName.intern(), type, value);
		    }
		    continue;
		}
	    } 

				// Not a declaration -- report
	    try {
		String attName[] = processName(attQName, true, true);
		atts.addAttribute(attName[0], attName[1], attName[2],
				  type, value);
	    } catch (SAXException e) {
		if (exceptions == null)
		    exceptions = new Vector();
		exceptions.addElement(e);
		atts.addAttribute("", attQName, attQName, type, value);
	    }
	}
	
	// now handle the deferred exception reports
	if (exceptions != null && errorHandler != null) {
	    for (int i = 0; i < exceptions.size(); i++)
		errorHandler.error((SAXParseException)
				(exceptions.elementAt(i)));
	}

				// OK, finally report the event.
	if (contentHandler != null) {
	    String name[] = processName(qName, false, false);
	    contentHandler.startElement(name[0], name[1], name[2], atts);
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 end element event.
     *
     * @param qName The qualified (prefixed) name.
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#endElement
     */
    public void endElement (String qName)
	throws SAXException
    {
				// If we're not doing Namespace
				// processing, dispatch this quickly.
	if (!namespaces) {
	    if (contentHandler != null) {
		contentHandler.endElement("", "", qName.intern());
	    }
	    return;
	}

				// Split the name.
	String names[] = processName(qName, false, false);
	if (contentHandler != null) {
	    contentHandler.endElement(names[0], names[1], names[2]);
	    Enumeration prefixes = nsSupport.getDeclaredPrefixes();
	    while (prefixes.hasMoreElements()) {
		String prefix = (String)prefixes.nextElement();
		contentHandler.endPrefixMapping(prefix);
	    }
	}
	nsSupport.popContext();
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 characters event.
     *
     * @param ch An array of characters.
     * @param start The starting position in the array.
     * @param length The number of characters to use.
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#characters
     */
    public void characters (char ch[], int start, int length)
	throws SAXException
    {
	if (contentHandler != null) {
	    contentHandler.characters(ch, start, length);
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 ignorable whitespace event.
     *
     * @param ch An array of characters.
     * @param start The starting position in the array.
     * @param length The number of characters to use.
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#ignorableWhitespace
     */
    public void ignorableWhitespace (char ch[], int start, int length)
	throws SAXException
    {
	if (contentHandler != null) {
	    contentHandler.ignorableWhitespace(ch, start, length);
	}
    }


    /**
     * Adapter implementation method; do not call.
     * Adapt a SAX1 processing instruction event.
     *
     * @param target The processing instruction target.
     * @param data The remainder of the processing instruction
     * @exception SAXException The client may raise a
     *            processing exception.
     * @see org.xml.sax.DocumentHandler#processingInstruction
     */
    public void processingInstruction (String target, String data)
	throws SAXException
    {
	if (contentHandler != null) {
	    contentHandler.processingInstruction(target, data);
	}
    }



    ////////////////////////////////////////////////////////////////////
    // Internal utility methods.
    ////////////////////////////////////////////////////////////////////


    /**
     * Initialize the parser before each run.
     */
    private void setupParser ()
    {
	// catch an illegal "nonsense" state.
	if (!prefixes && !namespaces)
	    throw new IllegalStateException ();

	nsSupport.reset();
	if (uris)
	    nsSupport.setNamespaceDeclUris (true);

	if (entityResolver != null) {
	    parser.setEntityResolver(entityResolver);
	}
	if (dtdHandler != null) {
	    parser.setDTDHandler(dtdHandler);
	}
	if (errorHandler != null) {
	    parser.setErrorHandler(errorHandler);
	}
	parser.setDocumentHandler(this);
	locator = null;
    }


    /**
     * Process a qualified (prefixed) name.
     *
     * <p>If the name has an undeclared prefix, use only the qname
     * and make an ErrorHandler.error callback in case the app is
     * interested.</p>
     *
     * @param qName The qualified (prefixed) name.
     * @param isAttribute true if this is an attribute name.
     * @return The name split into three parts.
     * @exception SAXException The client may throw
     *            an exception if there is an error callback.
     */
    private String [] processName (String qName, boolean isAttribute,
				   boolean useException)
	throws SAXException
    {
	String parts[] = nsSupport.processName(qName, nameParts,
					       isAttribute);
	if (parts == null) {
	    if (useException)
		throw makeException("Undeclared prefix: " + qName);
	    reportError("Undeclared prefix: " + qName);
	    parts = new String[3];
	    parts[0] = parts[1] = "";
	    parts[2] = qName.intern();
	}
	return parts;
    }


    /**
     * Report a non-fatal error.
     *
     * @param message The error message.
     * @exception SAXException The client may throw
     *            an exception.
     */
    void reportError (String message)
	throws SAXException
    {
	if (errorHandler != null)
	    errorHandler.error(makeException(message));
    }

    
    /**
     * Construct an exception for the current context.
     *
     * @param message The error message.
     */
    private SAXParseException makeException (String message)
    {
	if (locator != null) {
	    return new SAXParseException(message, locator);
	} else {
	    return new SAXParseException(message, null, null, -1, -1);
	}
    }


    /**
     * Throw an exception if we are parsing.
     *
     * <p>Use this method to detect illegal feature or
     * property changes.</p>
     *
     * @param type The type of thing (feature or property).
     * @param name The feature or property name.
     * @exception SAXNotSupportedException If a
     *            document is currently being parsed.
     */
    private void checkNotParsing (String type, String name)
	throws SAXNotSupportedException
    {
	if (parsing) {
	    throw new SAXNotSupportedException("Cannot change " +
					       type + ' ' +
					       name + " while parsing");
					       
	}
    }



    ////////////////////////////////////////////////////////////////////
    // Internal state.
    ////////////////////////////////////////////////////////////////////

    private NamespaceSupport nsSupport;
    private AttributeListAdapter attAdapter;

    private boolean parsing = false;
    private String nameParts[] = new String[3];

    private Parser parser = null;

    private AttributesImpl atts = null;

				// Features
    private boolean namespaces = true;
    private boolean prefixes = false;
    private boolean uris = false;

				// Properties

				// Handlers
    Locator locator;

    EntityResolver entityResolver = null;
    DTDHandler dtdHandler = null;
    ContentHandler contentHandler = null;
    ErrorHandler errorHandler = null;



    ////////////////////////////////////////////////////////////////////
    // Inner class to wrap an AttributeList when not doing NS proc.
    ////////////////////////////////////////////////////////////////////


    /**
     * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
     *
     * <p>This class is in the Public Domain, and comes with NO
     * WARRANTY of any kind.</p>
     *
     * <p>This wrapper class is used only when Namespace support
     * is disabled -- it provides pretty much a direct mapping
     * from SAX1 to SAX2, except that names and types are 
     * interned whenever requested.</p>
     */
    final class AttributeListAdapter implements Attributes
    {

	/**
	 * Construct a new adapter.
	 */
	AttributeListAdapter ()
	{
	}


	/**
	 * Set the embedded AttributeList.
	 *
	 * <p>This method must be invoked before any of the others
	 * can be used.</p>
	 *
	 * @param The SAX1 attribute list (with qnames).
	 */
	void setAttributeList (AttributeList qAtts)
	{
	    this.qAtts = qAtts;
	}


	/**
	 * Return the length of the attribute list.
	 *
	 * @return The number of attributes in the list.
	 * @see org.xml.sax.Attributes#getLength
	 */
	public int getLength ()
	{
	    return qAtts.getLength();
	}


	/**
	 * Return the Namespace URI of the specified attribute.
	 *
	 * @param The attribute's index.
	 * @return Always the empty string.
	 * @see org.xml.sax.Attributes#getURI
	 */
	public String getURI (int i)
	{
	    return "";
	}


	/**
	 * Return the local name of the specified attribute.
	 *
	 * @param The attribute's index.
	 * @return Always the empty string.
	 * @see org.xml.sax.Attributes#getLocalName
	 */
	public String getLocalName (int i)
	{
	    return "";
	}


	/**
	 * Return the qualified (prefixed) name of the specified attribute.
	 *
	 * @param The attribute's index.
	 * @return The attribute's qualified name, internalized.
	 */
	public String getQName (int i)
	{
	    return qAtts.getName(i).intern();
	}


	/**
	 * Return the type of the specified attribute.
	 *
	 * @param The attribute's index.
	 * @return The attribute's type as an internalized string.
	 */
	public String getType (int i)
	{
	    return qAtts.getType(i).intern();
	}


	/**
	 * Return the value of the specified attribute.
	 *
	 * @param The attribute's index.
	 * @return The attribute's value.
	 */
	public String getValue (int i)
	{
	    return qAtts.getValue(i);
	}


	/**
	 * Look up an attribute index by Namespace name.
	 *
	 * @param uri The Namespace URI or the empty string.
	 * @param localName The local name.
	 * @return The attributes index, or -1 if none was found.
	 * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
	 */
	public int getIndex (String uri, String localName)
	{
	    return -1;
	}


	/**
	 * Look up an attribute index by qualified (prefixed) name.
	 *
	 * @param qName The qualified name.
	 * @return The attributes index, or -1 if none was found.
	 * @see org.xml.sax.Attributes#getIndex(java.lang.String)
	 */
	public int getIndex (String qName)
	{
	    int max = atts.getLength();
	    for (int i = 0; i < max; i++) {
		if (qAtts.getName(i).equals(qName)) {
		    return i;
		}
	    }
	    return -1;
	}


	/**
	 * Look up the type of an attribute by Namespace name.
	 *
	 * @param uri The Namespace URI
	 * @param localName The local name.
	 * @return The attribute's type as an internalized string.
	 */
	public String getType (String uri, String localName)
	{
	    return null;
	}


	/**
	 * Look up the type of an attribute by qualified (prefixed) name.
	 *
	 * @param qName The qualified name.
	 * @return The attribute's type as an internalized string.
	 */
	public String getType (String qName)
	{
	    return qAtts.getType(qName).intern();
	}


	/**
	 * Look up the value of an attribute by Namespace name.
	 *
	 * @param uri The Namespace URI
	 * @param localName The local name.
	 * @return The attribute's value.
	 */
	public String getValue (String uri, String localName)
	{
	    return null;
	}


	/**
	 * Look up the value of an attribute by qualified (prefixed) name.
	 *
	 * @param qName The qualified name.
	 * @return The attribute's value.
	 */
	public String getValue (String qName)
	{
	    return qAtts.getValue(qName);
	}

	private AttributeList qAtts;
    }
}

// end of ParserAdapter.java
