286N/A/*
286N/A * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
286N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
286N/A *
286N/A * This code is free software; you can redistribute it and/or modify it
286N/A * under the terms of the GNU General Public License version 2 only, as
286N/A * published by the Free Software Foundation. Oracle designates this
286N/A * particular file as subject to the "Classpath" exception as provided
286N/A * by Oracle in the LICENSE file that accompanied this code.
286N/A *
286N/A * This code is distributed in the hope that it will be useful, but WITHOUT
286N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
286N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
286N/A * version 2 for more details (a copy is included in the LICENSE file that
286N/A * accompanied this code).
286N/A *
286N/A * You should have received a copy of the GNU General Public License version
286N/A * 2 along with this work; if not, write to the Free Software Foundation,
286N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
286N/A *
286N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
286N/A * or visit www.oracle.com if you need additional information or have any
286N/A * questions.
286N/A */
286N/A
286N/A// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
286N/A// http://www.saxproject.org
286N/A// Written by David Megginson
286N/A// NO WARRANTY! This class is in the public domain.
286N/A// $Id: ParserAdapter.java,v 1.3 2004/11/03 22:53:09 jsuttor Exp $
286N/A
286N/Apackage org.xml.sax.helpers;
286N/A
286N/Aimport java.io.IOException;
286N/Aimport java.util.Enumeration;
286N/Aimport java.util.Vector;
286N/A
286N/Aimport org.xml.sax.Parser; // deprecated
286N/Aimport org.xml.sax.InputSource;
286N/Aimport org.xml.sax.Locator;
286N/Aimport org.xml.sax.AttributeList; // deprecated
286N/Aimport org.xml.sax.EntityResolver;
286N/Aimport org.xml.sax.DTDHandler;
286N/Aimport org.xml.sax.DocumentHandler; // deprecated
286N/Aimport org.xml.sax.ErrorHandler;
286N/Aimport org.xml.sax.SAXException;
286N/Aimport org.xml.sax.SAXParseException;
286N/A
286N/Aimport org.xml.sax.XMLReader;
286N/Aimport org.xml.sax.Attributes;
286N/Aimport org.xml.sax.ContentHandler;
286N/Aimport org.xml.sax.SAXNotRecognizedException;
286N/Aimport org.xml.sax.SAXNotSupportedException;
286N/A
286N/A
286N/A/**
286N/A * Adapt a SAX1 Parser as a SAX2 XMLReader.
286N/A *
286N/A * <blockquote>
286N/A * <em>This module, both source code and documentation, is in the
286N/A * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
286N/A * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
286N/A * for further information.
286N/A * </blockquote>
286N/A *
286N/A * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
286N/A * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
286N/A * with feature, property, and Namespace support. Note
286N/A * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
286N/A * skippedEntity} events, since SAX1 does not make that information available.</p>
286N/A *
286N/A * <p>This adapter does not test for duplicate Namespace-qualified
286N/A * attribute names.</p>
286N/A *
286N/A * @since SAX 2.0
286N/A * @author David Megginson
524N/A * @version 2.0.1 (sax2r2)
286N/A * @see org.xml.sax.helpers.XMLReaderAdapter
286N/A * @see org.xml.sax.XMLReader
286N/A * @see org.xml.sax.Parser
286N/A */
286N/Apublic class ParserAdapter implements XMLReader, DocumentHandler
286N/A{
524N/A private static SecuritySupport ss = new SecuritySupport();
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Constructors.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A
286N/A /**
286N/A * Construct a new parser adapter.
286N/A *
286N/A * <p>Use the "org.xml.sax.parser" property to locate the
286N/A * embedded SAX1 driver.</p>
286N/A *
286N/A * @exception SAXException If the embedded driver
286N/A * cannot be instantiated or if the
286N/A * org.xml.sax.parser property is not specified.
286N/A */
286N/A public ParserAdapter ()
286N/A throws SAXException
286N/A {
286N/A super();
286N/A
524N/A String driver = ss.getSystemProperty("org.xml.sax.parser");
286N/A
286N/A try {
286N/A setup(ParserFactory.makeParser());
286N/A } catch (ClassNotFoundException e1) {
286N/A throw new
286N/A SAXException("Cannot find SAX1 driver class " +
286N/A driver, e1);
286N/A } catch (IllegalAccessException e2) {
286N/A throw new
286N/A SAXException("SAX1 driver class " +
286N/A driver +
286N/A " found but cannot be loaded", e2);
286N/A } catch (InstantiationException e3) {
286N/A throw new
286N/A SAXException("SAX1 driver class " +
286N/A driver +
286N/A " loaded but cannot be instantiated", e3);
286N/A } catch (ClassCastException e4) {
286N/A throw new
286N/A SAXException("SAX1 driver class " +
286N/A driver +
286N/A " does not implement org.xml.sax.Parser");
286N/A } catch (NullPointerException e5) {
286N/A throw new
286N/A SAXException("System property org.xml.sax.parser not specified");
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Construct a new parser adapter.
286N/A *
286N/A * <p>Note that the embedded parser cannot be changed once the
286N/A * adapter is created; to embed a different parser, allocate
286N/A * a new ParserAdapter.</p>
286N/A *
286N/A * @param parser The SAX1 parser to embed.
286N/A * @exception java.lang.NullPointerException If the parser parameter
286N/A * is null.
286N/A */
286N/A public ParserAdapter (Parser parser)
286N/A {
286N/A super();
286N/A setup(parser);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Internal setup method.
286N/A *
286N/A * @param parser The embedded parser.
286N/A * @exception java.lang.NullPointerException If the parser parameter
286N/A * is null.
286N/A */
286N/A private void setup (Parser parser)
286N/A {
286N/A if (parser == null) {
286N/A throw new
286N/A NullPointerException("Parser argument must not be null");
286N/A }
286N/A this.parser = parser;
286N/A atts = new AttributesImpl();
286N/A nsSupport = new NamespaceSupport();
286N/A attAdapter = new AttributeListAdapter();
286N/A }
286N/A
286N/A
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Implementation of org.xml.sax.XMLReader.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A
286N/A //
286N/A // Internal constants for the sake of convenience.
286N/A //
286N/A private final static String FEATURES = "http://xml.org/sax/features/";
286N/A private final static String NAMESPACES = FEATURES + "namespaces";
286N/A private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
286N/A private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
286N/A
286N/A
286N/A /**
286N/A * Set a feature flag for the parser.
286N/A *
286N/A * <p>The only features recognized are namespaces and
286N/A * namespace-prefixes.</p>
286N/A *
286N/A * @param name The feature name, as a complete URI.
286N/A * @param value The requested feature value.
286N/A * @exception SAXNotRecognizedException If the feature
286N/A * can't be assigned or retrieved.
286N/A * @exception SAXNotSupportedException If the feature
286N/A * can't be assigned that value.
286N/A * @see org.xml.sax.XMLReader#setFeature
286N/A */
286N/A public void setFeature (String name, boolean value)
286N/A throws SAXNotRecognizedException, SAXNotSupportedException
286N/A {
286N/A if (name.equals(NAMESPACES)) {
286N/A checkNotParsing("feature", name);
286N/A namespaces = value;
286N/A if (!namespaces && !prefixes) {
286N/A prefixes = true;
286N/A }
286N/A } else if (name.equals(NAMESPACE_PREFIXES)) {
286N/A checkNotParsing("feature", name);
286N/A prefixes = value;
286N/A if (!prefixes && !namespaces) {
286N/A namespaces = true;
286N/A }
286N/A } else if (name.equals(XMLNS_URIs)) {
286N/A checkNotParsing("feature", name);
286N/A uris = value;
286N/A } else {
286N/A throw new SAXNotRecognizedException("Feature: " + name);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Check a parser feature flag.
286N/A *
286N/A * <p>The only features recognized are namespaces and
286N/A * namespace-prefixes.</p>
286N/A *
286N/A * @param name The feature name, as a complete URI.
286N/A * @return The current feature value.
286N/A * @exception SAXNotRecognizedException If the feature
286N/A * value can't be assigned or retrieved.
286N/A * @exception SAXNotSupportedException If the
286N/A * feature is not currently readable.
286N/A * @see org.xml.sax.XMLReader#setFeature
286N/A */
286N/A public boolean getFeature (String name)
286N/A throws SAXNotRecognizedException, SAXNotSupportedException
286N/A {
286N/A if (name.equals(NAMESPACES)) {
286N/A return namespaces;
286N/A } else if (name.equals(NAMESPACE_PREFIXES)) {
286N/A return prefixes;
286N/A } else if (name.equals(XMLNS_URIs)) {
286N/A return uris;
286N/A } else {
286N/A throw new SAXNotRecognizedException("Feature: " + name);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set a parser property.
286N/A *
286N/A * <p>No properties are currently recognized.</p>
286N/A *
286N/A * @param name The property name.
286N/A * @param value The property value.
286N/A * @exception SAXNotRecognizedException If the property
286N/A * value can't be assigned or retrieved.
286N/A * @exception SAXNotSupportedException If the property
286N/A * can't be assigned that value.
286N/A * @see org.xml.sax.XMLReader#setProperty
286N/A */
286N/A public void setProperty (String name, Object value)
286N/A throws SAXNotRecognizedException, SAXNotSupportedException
286N/A {
286N/A throw new SAXNotRecognizedException("Property: " + name);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Get a parser property.
286N/A *
286N/A * <p>No properties are currently recognized.</p>
286N/A *
286N/A * @param name The property name.
286N/A * @return The property value.
286N/A * @exception SAXNotRecognizedException If the property
286N/A * value can't be assigned or retrieved.
286N/A * @exception SAXNotSupportedException If the property
286N/A * value is not currently readable.
286N/A * @see org.xml.sax.XMLReader#getProperty
286N/A */
286N/A public Object getProperty (String name)
286N/A throws SAXNotRecognizedException, SAXNotSupportedException
286N/A {
286N/A throw new SAXNotRecognizedException("Property: " + name);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set the entity resolver.
286N/A *
286N/A * @param resolver The new entity resolver.
286N/A * @see org.xml.sax.XMLReader#setEntityResolver
286N/A */
286N/A public void setEntityResolver (EntityResolver resolver)
286N/A {
286N/A entityResolver = resolver;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the current entity resolver.
286N/A *
286N/A * @return The current entity resolver, or null if none was supplied.
286N/A * @see org.xml.sax.XMLReader#getEntityResolver
286N/A */
286N/A public EntityResolver getEntityResolver ()
286N/A {
286N/A return entityResolver;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set the DTD handler.
286N/A *
286N/A * @param handler the new DTD handler
286N/A * @see org.xml.sax.XMLReader#setEntityResolver
286N/A */
286N/A public void setDTDHandler (DTDHandler handler)
286N/A {
286N/A dtdHandler = handler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the current DTD handler.
286N/A *
286N/A * @return the current DTD handler, or null if none was supplied
286N/A * @see org.xml.sax.XMLReader#getEntityResolver
286N/A */
286N/A public DTDHandler getDTDHandler ()
286N/A {
286N/A return dtdHandler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set the content handler.
286N/A *
286N/A * @param handler the new content handler
286N/A * @see org.xml.sax.XMLReader#setEntityResolver
286N/A */
286N/A public void setContentHandler (ContentHandler handler)
286N/A {
286N/A contentHandler = handler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the current content handler.
286N/A *
286N/A * @return The current content handler, or null if none was supplied.
286N/A * @see org.xml.sax.XMLReader#getEntityResolver
286N/A */
286N/A public ContentHandler getContentHandler ()
286N/A {
286N/A return contentHandler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set the error handler.
286N/A *
286N/A * @param handler The new error handler.
286N/A * @see org.xml.sax.XMLReader#setEntityResolver
286N/A */
286N/A public void setErrorHandler (ErrorHandler handler)
286N/A {
286N/A errorHandler = handler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the current error handler.
286N/A *
286N/A * @return The current error handler, or null if none was supplied.
286N/A * @see org.xml.sax.XMLReader#getEntityResolver
286N/A */
286N/A public ErrorHandler getErrorHandler ()
286N/A {
286N/A return errorHandler;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Parse an XML document.
286N/A *
286N/A * @param systemId The absolute URL of the document.
286N/A * @exception java.io.IOException If there is a problem reading
286N/A * the raw content of the document.
286N/A * @exception SAXException If there is a problem
286N/A * processing the document.
286N/A * @see #parse(org.xml.sax.InputSource)
286N/A * @see org.xml.sax.Parser#parse(java.lang.String)
286N/A */
286N/A public void parse (String systemId)
286N/A throws IOException, SAXException
286N/A {
286N/A parse(new InputSource(systemId));
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Parse an XML document.
286N/A *
286N/A * @param input An input source for the document.
286N/A * @exception java.io.IOException If there is a problem reading
286N/A * the raw content of the document.
286N/A * @exception SAXException If there is a problem
286N/A * processing the document.
286N/A * @see #parse(java.lang.String)
286N/A * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
286N/A */
286N/A public void parse (InputSource input)
286N/A throws IOException, SAXException
286N/A {
286N/A if (parsing) {
286N/A throw new SAXException("Parser is already in use");
286N/A }
286N/A setupParser();
286N/A parsing = true;
286N/A try {
286N/A parser.parse(input);
286N/A } finally {
286N/A parsing = false;
286N/A }
286N/A parsing = false;
286N/A }
286N/A
286N/A
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Implementation of org.xml.sax.DocumentHandler.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 document locator event.
286N/A *
286N/A * @param locator A document locator.
286N/A * @see org.xml.sax.ContentHandler#setDocumentLocator
286N/A */
286N/A public void setDocumentLocator (Locator locator)
286N/A {
286N/A this.locator = locator;
286N/A if (contentHandler != null) {
286N/A contentHandler.setDocumentLocator(locator);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 start document event.
286N/A *
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#startDocument
286N/A */
286N/A public void startDocument ()
286N/A throws SAXException
286N/A {
286N/A if (contentHandler != null) {
286N/A contentHandler.startDocument();
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 end document event.
286N/A *
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#endDocument
286N/A */
286N/A public void endDocument ()
286N/A throws SAXException
286N/A {
286N/A if (contentHandler != null) {
286N/A contentHandler.endDocument();
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 startElement event.
286N/A *
286N/A * <p>If necessary, perform Namespace processing.</p>
286N/A *
286N/A * @param qName The qualified (prefixed) name.
286N/A * @param qAtts The XML attribute list (with qnames).
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A */
286N/A public void startElement (String qName, AttributeList qAtts)
286N/A throws SAXException
286N/A {
286N/A // These are exceptions from the
286N/A // first pass; they should be
286N/A // ignored if there's a second pass,
286N/A // but reported otherwise.
286N/A Vector exceptions = null;
286N/A
286N/A // If we're not doing Namespace
286N/A // processing, dispatch this quickly.
286N/A if (!namespaces) {
286N/A if (contentHandler != null) {
286N/A attAdapter.setAttributeList(qAtts);
286N/A contentHandler.startElement("", "", qName.intern(),
286N/A attAdapter);
286N/A }
286N/A return;
286N/A }
286N/A
286N/A
286N/A // OK, we're doing Namespace processing.
286N/A nsSupport.pushContext();
286N/A int length = qAtts.getLength();
286N/A
286N/A // First pass: handle NS decls
286N/A for (int i = 0; i < length; i++) {
286N/A String attQName = qAtts.getName(i);
286N/A
286N/A if (!attQName.startsWith("xmlns"))
286N/A continue;
286N/A // Could be a declaration...
286N/A String prefix;
286N/A int n = attQName.indexOf(':');
286N/A
286N/A // xmlns=...
286N/A if (n == -1 && attQName.length () == 5) {
286N/A prefix = "";
286N/A } else if (n != 5) {
286N/A // XML namespaces spec doesn't discuss "xmlnsf:oo"
286N/A // (and similarly named) attributes ... at most, warn
286N/A continue;
286N/A } else // xmlns:foo=...
286N/A prefix = attQName.substring(n+1);
286N/A
286N/A String value = qAtts.getValue(i);
286N/A if (!nsSupport.declarePrefix(prefix, value)) {
286N/A reportError("Illegal Namespace prefix: " + prefix);
286N/A continue;
286N/A }
286N/A if (contentHandler != null)
286N/A contentHandler.startPrefixMapping(prefix, value);
286N/A }
286N/A
286N/A // Second pass: copy all relevant
286N/A // attributes into the SAX2 AttributeList
286N/A // using updated prefix bindings
286N/A atts.clear();
286N/A for (int i = 0; i < length; i++) {
286N/A String attQName = qAtts.getName(i);
286N/A String type = qAtts.getType(i);
286N/A String value = qAtts.getValue(i);
286N/A
286N/A // Declaration?
286N/A if (attQName.startsWith("xmlns")) {
286N/A String prefix;
286N/A int n = attQName.indexOf(':');
286N/A
286N/A if (n == -1 && attQName.length () == 5) {
286N/A prefix = "";
286N/A } else if (n != 5) {
286N/A // XML namespaces spec doesn't discuss "xmlnsf:oo"
286N/A // (and similarly named) attributes ... ignore
286N/A prefix = null;
286N/A } else {
286N/A prefix = attQName.substring(6);
286N/A }
286N/A // Yes, decl: report or prune
286N/A if (prefix != null) {
286N/A if (prefixes) {
286N/A if (uris)
286N/A // note funky case: localname can be null
286N/A // when declaring the default prefix, and
286N/A // yet the uri isn't null.
286N/A atts.addAttribute (nsSupport.XMLNS, prefix,
286N/A attQName.intern(), type, value);
286N/A else
286N/A atts.addAttribute ("", "",
286N/A attQName.intern(), type, value);
286N/A }
286N/A continue;
286N/A }
286N/A }
286N/A
286N/A // Not a declaration -- report
286N/A try {
286N/A String attName[] = processName(attQName, true, true);
286N/A atts.addAttribute(attName[0], attName[1], attName[2],
286N/A type, value);
286N/A } catch (SAXException e) {
286N/A if (exceptions == null)
286N/A exceptions = new Vector();
286N/A exceptions.addElement(e);
286N/A atts.addAttribute("", attQName, attQName, type, value);
286N/A }
286N/A }
286N/A
286N/A // now handle the deferred exception reports
286N/A if (exceptions != null && errorHandler != null) {
286N/A for (int i = 0; i < exceptions.size(); i++)
286N/A errorHandler.error((SAXParseException)
286N/A (exceptions.elementAt(i)));
286N/A }
286N/A
286N/A // OK, finally report the event.
286N/A if (contentHandler != null) {
286N/A String name[] = processName(qName, false, false);
286N/A contentHandler.startElement(name[0], name[1], name[2], atts);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 end element event.
286N/A *
286N/A * @param qName The qualified (prefixed) name.
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#endElement
286N/A */
286N/A public void endElement (String qName)
286N/A throws SAXException
286N/A {
286N/A // If we're not doing Namespace
286N/A // processing, dispatch this quickly.
286N/A if (!namespaces) {
286N/A if (contentHandler != null) {
286N/A contentHandler.endElement("", "", qName.intern());
286N/A }
286N/A return;
286N/A }
286N/A
286N/A // Split the name.
286N/A String names[] = processName(qName, false, false);
286N/A if (contentHandler != null) {
286N/A contentHandler.endElement(names[0], names[1], names[2]);
286N/A Enumeration prefixes = nsSupport.getDeclaredPrefixes();
286N/A while (prefixes.hasMoreElements()) {
286N/A String prefix = (String)prefixes.nextElement();
286N/A contentHandler.endPrefixMapping(prefix);
286N/A }
286N/A }
286N/A nsSupport.popContext();
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 characters event.
286N/A *
286N/A * @param ch An array of characters.
286N/A * @param start The starting position in the array.
286N/A * @param length The number of characters to use.
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#characters
286N/A */
286N/A public void characters (char ch[], int start, int length)
286N/A throws SAXException
286N/A {
286N/A if (contentHandler != null) {
286N/A contentHandler.characters(ch, start, length);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 ignorable whitespace event.
286N/A *
286N/A * @param ch An array of characters.
286N/A * @param start The starting position in the array.
286N/A * @param length The number of characters to use.
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#ignorableWhitespace
286N/A */
286N/A public void ignorableWhitespace (char ch[], int start, int length)
286N/A throws SAXException
286N/A {
286N/A if (contentHandler != null) {
286N/A contentHandler.ignorableWhitespace(ch, start, length);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Adapter implementation method; do not call.
286N/A * Adapt a SAX1 processing instruction event.
286N/A *
286N/A * @param target The processing instruction target.
286N/A * @param data The remainder of the processing instruction
286N/A * @exception SAXException The client may raise a
286N/A * processing exception.
286N/A * @see org.xml.sax.DocumentHandler#processingInstruction
286N/A */
286N/A public void processingInstruction (String target, String data)
286N/A throws SAXException
286N/A {
286N/A if (contentHandler != null) {
286N/A contentHandler.processingInstruction(target, data);
286N/A }
286N/A }
286N/A
286N/A
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Internal utility methods.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A
286N/A /**
286N/A * Initialize the parser before each run.
286N/A */
286N/A private void setupParser ()
286N/A {
286N/A // catch an illegal "nonsense" state.
286N/A if (!prefixes && !namespaces)
286N/A throw new IllegalStateException ();
286N/A
286N/A nsSupport.reset();
286N/A if (uris)
286N/A nsSupport.setNamespaceDeclUris (true);
286N/A
286N/A if (entityResolver != null) {
286N/A parser.setEntityResolver(entityResolver);
286N/A }
286N/A if (dtdHandler != null) {
286N/A parser.setDTDHandler(dtdHandler);
286N/A }
286N/A if (errorHandler != null) {
286N/A parser.setErrorHandler(errorHandler);
286N/A }
286N/A parser.setDocumentHandler(this);
286N/A locator = null;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Process a qualified (prefixed) name.
286N/A *
286N/A * <p>If the name has an undeclared prefix, use only the qname
286N/A * and make an ErrorHandler.error callback in case the app is
286N/A * interested.</p>
286N/A *
286N/A * @param qName The qualified (prefixed) name.
286N/A * @param isAttribute true if this is an attribute name.
286N/A * @return The name split into three parts.
286N/A * @exception SAXException The client may throw
286N/A * an exception if there is an error callback.
286N/A */
286N/A private String [] processName (String qName, boolean isAttribute,
286N/A boolean useException)
286N/A throws SAXException
286N/A {
286N/A String parts[] = nsSupport.processName(qName, nameParts,
286N/A isAttribute);
286N/A if (parts == null) {
286N/A if (useException)
286N/A throw makeException("Undeclared prefix: " + qName);
286N/A reportError("Undeclared prefix: " + qName);
286N/A parts = new String[3];
286N/A parts[0] = parts[1] = "";
286N/A parts[2] = qName.intern();
286N/A }
286N/A return parts;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Report a non-fatal error.
286N/A *
286N/A * @param message The error message.
286N/A * @exception SAXException The client may throw
286N/A * an exception.
286N/A */
286N/A void reportError (String message)
286N/A throws SAXException
286N/A {
286N/A if (errorHandler != null)
286N/A errorHandler.error(makeException(message));
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Construct an exception for the current context.
286N/A *
286N/A * @param message The error message.
286N/A */
286N/A private SAXParseException makeException (String message)
286N/A {
286N/A if (locator != null) {
286N/A return new SAXParseException(message, locator);
286N/A } else {
286N/A return new SAXParseException(message, null, null, -1, -1);
286N/A }
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Throw an exception if we are parsing.
286N/A *
286N/A * <p>Use this method to detect illegal feature or
286N/A * property changes.</p>
286N/A *
286N/A * @param type The type of thing (feature or property).
286N/A * @param name The feature or property name.
286N/A * @exception SAXNotSupportedException If a
286N/A * document is currently being parsed.
286N/A */
286N/A private void checkNotParsing (String type, String name)
286N/A throws SAXNotSupportedException
286N/A {
286N/A if (parsing) {
286N/A throw new SAXNotSupportedException("Cannot change " +
286N/A type + ' ' +
286N/A name + " while parsing");
286N/A
286N/A }
286N/A }
286N/A
286N/A
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Internal state.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A private NamespaceSupport nsSupport;
286N/A private AttributeListAdapter attAdapter;
286N/A
286N/A private boolean parsing = false;
286N/A private String nameParts[] = new String[3];
286N/A
286N/A private Parser parser = null;
286N/A
286N/A private AttributesImpl atts = null;
286N/A
286N/A // Features
286N/A private boolean namespaces = true;
286N/A private boolean prefixes = false;
286N/A private boolean uris = false;
286N/A
286N/A // Properties
286N/A
286N/A // Handlers
286N/A Locator locator;
286N/A
286N/A EntityResolver entityResolver = null;
286N/A DTDHandler dtdHandler = null;
286N/A ContentHandler contentHandler = null;
286N/A ErrorHandler errorHandler = null;
286N/A
286N/A
286N/A
286N/A ////////////////////////////////////////////////////////////////////
286N/A // Inner class to wrap an AttributeList when not doing NS proc.
286N/A ////////////////////////////////////////////////////////////////////
286N/A
286N/A
286N/A /**
286N/A * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
286N/A *
286N/A * <p>This class is in the Public Domain, and comes with NO
286N/A * WARRANTY of any kind.</p>
286N/A *
286N/A * <p>This wrapper class is used only when Namespace support
286N/A * is disabled -- it provides pretty much a direct mapping
286N/A * from SAX1 to SAX2, except that names and types are
286N/A * interned whenever requested.</p>
286N/A */
286N/A final class AttributeListAdapter implements Attributes
286N/A {
286N/A
286N/A /**
286N/A * Construct a new adapter.
286N/A */
286N/A AttributeListAdapter ()
286N/A {
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Set the embedded AttributeList.
286N/A *
286N/A * <p>This method must be invoked before any of the others
286N/A * can be used.</p>
286N/A *
286N/A * @param The SAX1 attribute list (with qnames).
286N/A */
286N/A void setAttributeList (AttributeList qAtts)
286N/A {
286N/A this.qAtts = qAtts;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the length of the attribute list.
286N/A *
286N/A * @return The number of attributes in the list.
286N/A * @see org.xml.sax.Attributes#getLength
286N/A */
286N/A public int getLength ()
286N/A {
286N/A return qAtts.getLength();
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the Namespace URI of the specified attribute.
286N/A *
286N/A * @param The attribute's index.
286N/A * @return Always the empty string.
286N/A * @see org.xml.sax.Attributes#getURI
286N/A */
286N/A public String getURI (int i)
286N/A {
286N/A return "";
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the local name of the specified attribute.
286N/A *
286N/A * @param The attribute's index.
286N/A * @return Always the empty string.
286N/A * @see org.xml.sax.Attributes#getLocalName
286N/A */
286N/A public String getLocalName (int i)
286N/A {
286N/A return "";
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the qualified (prefixed) name of the specified attribute.
286N/A *
286N/A * @param The attribute's index.
286N/A * @return The attribute's qualified name, internalized.
286N/A */
286N/A public String getQName (int i)
286N/A {
286N/A return qAtts.getName(i).intern();
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the type of the specified attribute.
286N/A *
286N/A * @param The attribute's index.
286N/A * @return The attribute's type as an internalized string.
286N/A */
286N/A public String getType (int i)
286N/A {
286N/A return qAtts.getType(i).intern();
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Return the value of the specified attribute.
286N/A *
286N/A * @param The attribute's index.
286N/A * @return The attribute's value.
286N/A */
286N/A public String getValue (int i)
286N/A {
286N/A return qAtts.getValue(i);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up an attribute index by Namespace name.
286N/A *
286N/A * @param uri The Namespace URI or the empty string.
286N/A * @param localName The local name.
286N/A * @return The attributes index, or -1 if none was found.
286N/A * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
286N/A */
286N/A public int getIndex (String uri, String localName)
286N/A {
286N/A return -1;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up an attribute index by qualified (prefixed) name.
286N/A *
286N/A * @param qName The qualified name.
286N/A * @return The attributes index, or -1 if none was found.
286N/A * @see org.xml.sax.Attributes#getIndex(java.lang.String)
286N/A */
286N/A public int getIndex (String qName)
286N/A {
286N/A int max = atts.getLength();
286N/A for (int i = 0; i < max; i++) {
286N/A if (qAtts.getName(i).equals(qName)) {
286N/A return i;
286N/A }
286N/A }
286N/A return -1;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up the type of an attribute by Namespace name.
286N/A *
286N/A * @param uri The Namespace URI
286N/A * @param localName The local name.
286N/A * @return The attribute's type as an internalized string.
286N/A */
286N/A public String getType (String uri, String localName)
286N/A {
286N/A return null;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up the type of an attribute by qualified (prefixed) name.
286N/A *
286N/A * @param qName The qualified name.
286N/A * @return The attribute's type as an internalized string.
286N/A */
286N/A public String getType (String qName)
286N/A {
286N/A return qAtts.getType(qName).intern();
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up the value of an attribute by Namespace name.
286N/A *
286N/A * @param uri The Namespace URI
286N/A * @param localName The local name.
286N/A * @return The attribute's value.
286N/A */
286N/A public String getValue (String uri, String localName)
286N/A {
286N/A return null;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Look up the value of an attribute by qualified (prefixed) name.
286N/A *
286N/A * @param qName The qualified name.
286N/A * @return The attribute's value.
286N/A */
286N/A public String getValue (String qName)
286N/A {
286N/A return qAtts.getValue(qName);
286N/A }
286N/A
286N/A private AttributeList qAtts;
286N/A }
286N/A}
286N/A
286N/A// end of ParserAdapter.java