This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
I'm checking this in on the trunk and the 4.0 branch.
This pulls over some GNU JAXP fixes from Classpath. I cherry-picked
the ones that are bug fixes for things we're specifically interested
in at the moment, mostly Eclipse.
Tom
Index: ChangeLog
from Chris Burdess <dog@gnu.org>
* gnu/xml/dom/DomNode.java (notifyNode): grow listener array as
required.
2005-03-13 Michael Koch <konqueror@gmx.de>
* gnu/xml/aelfred2/XmlParser.java: Fixed typo.
2005-03-11 Chris Burdess <dog@gnu.org>
* gnu/xml/aelfred2/SAXDriver.java: Corrected bug handling URI
warnings.
2005-02-27 Chris Burdess <dog@gnu.org>
* gnu/xml/aelfred2/JAXPFactory.java,
gnu/xml/aelfred2/SAXDriver.java,
gnu/xml/aelfred2/XmlParser.java,
gnu/xml/aelfred2/XmlReader.java: Applied GNU Classpath source code
formatting conventions. Replaced arrays of Object with struct-like
classes for easier maintainability. Made SAXDriver.stringInterning
package private to allow access from XmlParser inside the loop without
a method call overhead.
2005-03-11 Chris Burdess <dog@gnu.org>
* gnu/xml/aelfred2/SAXDriver.java: Corrected bug handling URI
warnings.
Index: gnu/xml/aelfred2/JAXPFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/xml/aelfred2/JAXPFactory.java,v
retrieving revision 1.1
diff -u -r1.1 JAXPFactory.java
--- gnu/xml/aelfred2/JAXPFactory.java 2 Feb 2005 00:42:07 -0000 1.1
+++ gnu/xml/aelfred2/JAXPFactory.java 29 Mar 2005 19:50:35 -0000
@@ -60,137 +60,172 @@
*
* @author David Brownell
*/
-public final class JAXPFactory extends SAXParserFactory
+public final class JAXPFactory
+ extends SAXParserFactory
{
- private Hashtable flags = new Hashtable ();
+
+ private Hashtable flags = new Hashtable();
- /**
- * Constructs a factory which normally returns a non-validating
- * parser.
- */
- public JAXPFactory () { }
+ /**
+ * Constructs a factory which normally returns a non-validating
+ * parser.
+ */
+ public JAXPFactory()
+ {
+ }
- public SAXParser newSAXParser ()
+ public SAXParser newSAXParser()
throws ParserConfigurationException, SAXException
+ {
+ JaxpParser jaxp = new JaxpParser();
+ Enumeration e = flags.keys();
+ XMLReader parser = jaxp.getXMLReader();
+
+ parser.setFeature(SAXDriver.FEATURE + "namespaces",
+ isNamespaceAware());
+ parser.setFeature(SAXDriver.FEATURE + "validation",
+ isValidating());
+ // that makes SAX2 feature flags trump JAXP
+
+ while (e.hasMoreElements())
+ {
+ String uri = (String) e.nextElement();
+ Boolean value = (Boolean) flags.get(uri);
+ parser.setFeature(uri, value.booleanValue());
+ }
+
+ return jaxp;
+ }
+
+ // yes, this "feature transfer" mechanism doesn't play well
+
+ public void setFeature(String name, boolean value)
+ throws ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException
+ {
+ try
+ {
+ // force "early" detection of errors where possible
+ // (flags can't necessarily be set before parsing)
+ new JaxpParser().getXMLReader().setFeature(name, value);
+
+ flags.put(name, new Boolean(value));
+ }
+ catch (SAXNotRecognizedException e)
+ {
+ throw new SAXNotRecognizedException(name);
+ }
+ catch (SAXNotSupportedException e)
+ {
+ throw new SAXNotSupportedException(name);
+ }
+ catch (Exception e)
+ {
+ throw new ParserConfigurationException(e.getClass().getName()
+ + ": "
+ + e.getMessage());
+ }
+ }
+
+ public boolean getFeature(String name)
+ throws ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException
+ {
+ Boolean value = (Boolean) flags.get(name);
+
+ if (value != null)
+ {
+ return value.booleanValue();
+ }
+ else
+ {
+ try
+ {
+ return new JaxpParser().getXMLReader().getFeature(name);
+ }
+ catch (SAXNotRecognizedException e)
+ {
+ throw new SAXNotRecognizedException(name);
+ }
+ catch (SAXNotSupportedException e)
+ {
+ throw new SAXNotSupportedException(name);
+ }
+ catch (SAXException e)
+ {
+ throw new ParserConfigurationException(e.getClass().getName()
+ + ": "
+ + e.getMessage());
+ }
+ }
+ }
+
+ private static class JaxpParser
+ extends SAXParser
+ {
+
+ private XmlReader ae2 = new XmlReader();
+ private XMLReaderAdapter parser = null;
+
+ JaxpParser()
{
- JaxpParser jaxp = new JaxpParser ();
- Enumeration e = flags.keys ();
- XMLReader parser = jaxp.getXMLReader ();
-
- parser.setFeature (
- SAXDriver.FEATURE + "namespaces",
- isNamespaceAware ());
- parser.setFeature (
- SAXDriver.FEATURE + "validation",
- isValidating ());
- // that makes SAX2 feature flags trump JAXP
-
- while (e.hasMoreElements ()) {
- String uri = (String) e.nextElement ();
- Boolean value = (Boolean) flags.get (uri);
- parser.setFeature (uri, value.booleanValue ());
- }
-
- return jaxp;
- }
-
- // yes, this "feature transfer" mechanism doesn't play well
-
- public void setFeature (String name, boolean value)
- throws
- ParserConfigurationException,
- SAXNotRecognizedException,
- SAXNotSupportedException
- {
- try {
- // force "early" detection of errors where possible
- // (flags can't necessarily be set before parsing)
- new JaxpParser ().getXMLReader ().setFeature (name, value);
-
- flags.put (name, new Boolean (value));
- } catch (SAXNotRecognizedException e) {
- throw new SAXNotRecognizedException (name);
- } catch (SAXNotSupportedException e) {
- throw new SAXNotSupportedException (name);
- } catch (Exception e) {
- throw new ParserConfigurationException (
- e.getClass ().getName ()
- + ": "
- + e.getMessage ());
- }
- }
-
- public boolean getFeature (String name)
- throws
- ParserConfigurationException,
- SAXNotRecognizedException,
- SAXNotSupportedException
- {
- Boolean value = (Boolean) flags.get (name);
-
- if (value != null)
- return value.booleanValue ();
- else
- try {
- return new JaxpParser ().getXMLReader ().getFeature (name);
- } catch (SAXNotRecognizedException e) {
- throw new SAXNotRecognizedException (name);
- } catch (SAXNotSupportedException e) {
- throw new SAXNotSupportedException (name);
- } catch (SAXException e) {
- throw new ParserConfigurationException (
- e.getClass ().getName ()
- + ": "
- + e.getMessage ());
- }
- }
-
- private static class JaxpParser extends SAXParser
- {
- private XmlReader ae2 = new XmlReader ();
- private XMLReaderAdapter parser = null;
-
- JaxpParser () { }
-
- public void setProperty (String id, Object value)
- throws SAXNotRecognizedException, SAXNotSupportedException
- { ae2.setProperty (id, value); }
-
- public Object getProperty (String id)
- throws SAXNotRecognizedException, SAXNotSupportedException
- { return ae2.getProperty (id); }
-
- public Parser getParser ()
- throws SAXException
- {
- if (parser == null)
- parser = new XMLReaderAdapter (ae2);
- return parser;
- }
-
- public XMLReader getXMLReader ()
- throws SAXException
- { return ae2; }
-
- public boolean isNamespaceAware ()
- {
- try {
- return ae2.getFeature (SAXDriver.FEATURE + "namespaces");
- } catch (Exception e) {
- throw new Error ();
- }
- }
-
- public boolean isValidating ()
- {
- try {
- return ae2.getFeature (SAXDriver.FEATURE + "validation");
- } catch (Exception e) {
- throw new Error ();
- }
- }
+ }
- // TODO isXIncludeAware()
-
+ public void setProperty(String id, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ ae2.setProperty(id, value);
+ }
+
+ public Object getProperty(String id)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ return ae2.getProperty(id);
+ }
+
+ public Parser getParser()
+ throws SAXException
+ {
+ if (parser == null)
+ {
+ parser = new XMLReaderAdapter(ae2);
+ }
+ return parser;
}
+
+ public XMLReader getXMLReader ()
+ throws SAXException
+ {
+ return ae2;
+ }
+
+ public boolean isNamespaceAware()
+ {
+ try
+ {
+ return ae2.getFeature(SAXDriver.FEATURE + "namespaces");
+ }
+ catch (Exception e)
+ {
+ throw new Error();
+ }
+ }
+
+ public boolean isValidating()
+ {
+ try
+ {
+ return ae2.getFeature(SAXDriver.FEATURE + "validation");
+ }
+ catch (Exception e)
+ {
+ throw new Error();
+ }
+ }
+
+ // TODO isXIncludeAware()
+
+ }
+
}
+
Index: gnu/xml/aelfred2/SAXDriver.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/xml/aelfred2/SAXDriver.java,v
retrieving revision 1.2
diff -u -r1.2 SAXDriver.java
--- gnu/xml/aelfred2/SAXDriver.java 16 Feb 2005 19:25:02 -0000 1.2
+++ gnu/xml/aelfred2/SAXDriver.java 29 Mar 2005 19:50:35 -0000
@@ -60,15 +60,11 @@
import java.util.Locale;
import java.util.Stack;
-// maintaining 1.1 compatibility for now ... more portable, PJava, etc
-// Iterator, Hashmap and ArrayList ought to be faster
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
-import java.util.Vector;
import org.xml.sax.*;
import org.xml.sax.ext.*;
@@ -133,1276 +129,1494 @@
* @see org.xml.sax.Parser
*/
final public class SAXDriver
- implements Locator, Attributes2, XMLReader, Parser, AttributeList
+ 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;
- private 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;
- }
+
+ 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.");
- }
+ //
+ // 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>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>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>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>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>: 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>SAX2</b>: Returns the object used to report the logical
- * content of an XML document.
- */
- public ContentHandler getContentHandler ()
- {
- return contentHandler == base ? null : contentHandler;
- }
+ /**
+ * <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>: 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>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>: 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>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>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>: 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;
+ }
- /**
- * <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();
- }
- }
- }
+ // 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;
+ }
- /**
- * <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));
- }
+ // all PEs and GEs are reported
+ if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId))
+ {
+ return true;
+ }
- //
- // Implementation of SAX2 "XMLReader" interface
- //
- static final String FEATURE = "http://xml.org/sax/features/";
- static final String PROPERTY = "http://xml.org/sax/properties/";
+ // 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();
+ }
- /**
- * <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;
+ // optionally don't absolutize URIs in declarations
+ if ((FEATURE + "resolve-dtd-uris").equals(featureId))
+ {
+ return resolveAll;
+ }
- // 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);
- }
+ // 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
+ DeclHandler getDeclHandler()
+ {
+ return declHandler;
+ }
- // package private
- boolean resolveURIs () { return resolveAll; }
+ // 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)
+ /**
+ * <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 + "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);
- }
+ 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)
+ /**
+ * <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);
- }
+ {
+ 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");
+ }
- /**
- * <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);
+ 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;
+ }
- // Properties with a defined value, we just change it if we can.
+ if ((FEATURE + "namespaces").equals(featureId))
+ {
+ namespaces = value;
+ // forcibly prevent illegal parser state
+ if (!namespaces)
+ {
+ xmlNames = true;
+ }
+ return;
+ }
- 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 ;
- }
+ 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;
+ }
- throw new SAXNotSupportedException (propertyId);
- }
+ if ((FEATURE + "use-entity-resolver2").equals(featureId))
+ {
+ useResolver2 = value;
+ return;
+ }
+ throw new SAXNotRecognizedException(featureId);
+ }
- //
- // This is where the driver receives XmlParser callbacks and translates
- // them into SAX callbacks. Some more callbacks have been added for
- // SAX2 support.
- //
+ /**
+ * <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);
+ }
- void startDocument ()
- throws SAXException
- {
- contentHandler.setDocumentLocator (this);
- contentHandler.startDocument ();
- attributesList.clear ();
- }
+ //
+ // This is where the driver receives XmlParser callbacks and translates
+ // them into SAX callbacks. Some more callbacks have been added for
+ // SAX2 support.
+ //
+
+ void startDocument()
+ throws SAXException
+ {
+ contentHandler.setDocumentLocator(this);
+ contentHandler.startDocument();
+ attributesList.clear();
+ }
- void xmlDecl(String version,
- String encoding,
- boolean standalone,
- String inputEncoding)
- throws SAXException
- {
- if (contentHandler instanceof ContentHandler2)
- {
- ((ContentHandler2) contentHandler).xmlDecl(version,
- encoding,
- standalone,
- inputEncoding);
- }
- }
+ void xmlDecl(String version,
+ String encoding,
+ boolean standalone,
+ String inputEncoding)
+ throws SAXException
+ {
+ if (contentHandler instanceof ContentHandler2)
+ {
+ ((ContentHandler2) contentHandler).xmlDecl(version,
+ encoding,
+ standalone,
+ inputEncoding);
+ }
+ }
- void skippedEntity (String name)
+ void skippedEntity(String name)
throws SAXException
- { contentHandler.skippedEntity (name); }
+ {
+ contentHandler.skippedEntity(name);
+ }
- InputSource getExternalSubset (String name, String baseURI)
+ InputSource getExternalSubset(String name, String baseURI)
throws SAXException, IOException
- {
- if (resolver2 == null || !useResolver2 || !extPE)
- return null;
- return resolver2.getExternalSubset (name, baseURI);
- }
+ {
+ if (resolver2 == null || !useResolver2 || !extPE)
+ {
+ return null;
+ }
+ return resolver2.getExternalSubset(name, baseURI);
+ }
- InputSource resolveEntity (boolean isPE, String name,
- InputSource in, String baseURI)
+ InputSource resolveEntity(boolean isPE, String name,
+ InputSource in, String baseURI)
throws SAXException, IOException
- {
- InputSource source;
+ {
+ InputSource source;
+
+ // external entities might be skipped
+ if (isPE && !extPE)
+ {
+ return null;
+ }
+ if (!isPE && !extGE)
+ {
+ return null;
+ }
- // external entities might be skipped
- if (isPE && !extPE)
- return null;
- if (!isPE && !extGE)
- return null;
-
- // ... or not
- lexicalHandler.startEntity (name);
- if (resolver2 != null && useResolver2) {
- source = resolver2.resolveEntity (name, in.getPublicId (),
- baseURI, in.getSystemId ());
- if (source == null) {
- in.setSystemId (absolutize (baseURI,
- in.getSystemId (), false));
- source = in;
- }
- } else {
- in.setSystemId (absolutize (baseURI, in.getSystemId (), false));
- source = entityResolver.resolveEntity (in.getPublicId (),
- in.getSystemId ());
- if (source == null)
- source = in;
- }
- startExternalEntity (name, source.getSystemId (), true);
- return source;
- }
+ // ... or not
+ lexicalHandler.startEntity(name);
+ if (resolver2 != null && useResolver2)
+ {
+ source = resolver2.resolveEntity(name, in.getPublicId(),
+ baseURI, in.getSystemId());
+ if (source == null)
+ {
+ in.setSystemId(absolutize(baseURI,
+ in.getSystemId(), false));
+ source = in;
+ }
+ }
+ else
+ {
+ in.setSystemId(absolutize(baseURI, in.getSystemId(), false));
+ source = entityResolver.resolveEntity(in.getPublicId(),
+ in.getSystemId());
+ if (source == null)
+ {
+ source = in;
+ }
+ }
+ startExternalEntity(name, source.getSystemId(), true);
+ return source;
+ }
- // absolutize a system ID relative to the specified base URI
- // (temporarily) package-visible for external entity decls
- String absolutize (String baseURI, String systemId, boolean nice)
+ // 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) {
- 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;
- }
- }
+ {
+ // 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)
+ 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);
- }
+ {
+ // 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)
+ void endExternalEntity(String name)
throws SAXException
- {
- if (!"[document]".equals (name))
- lexicalHandler.endEntity (name);
- entityStack.pop ();
- }
+ {
+ if (!"[document]".equals(name))
+ {
+ lexicalHandler.endEntity(name);
+ }
+ entityStack.pop();
+ }
- void startInternalEntity (String name)
+ void startInternalEntity(String name)
throws SAXException
- {
- lexicalHandler.startEntity (name);
- }
+ {
+ lexicalHandler.startEntity(name);
+ }
- void endInternalEntity (String name)
+ void endInternalEntity(String name)
throws SAXException
- {
- lexicalHandler.endEntity (name);
- }
+ {
+ lexicalHandler.endEntity(name);
+ }
- void doctypeDecl (String name, String publicId, String systemId)
+ 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"
- }
+ {
+ 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 notationDecl (String name, String ids [])
+ void unparsedEntityDecl(String name, String publicId, String systemId,
+ String baseUri, String notation)
throws SAXException
- {
- try {
- dtdHandler.notationDecl (name, ids [0],
- (resolveAll && ids [1] != null)
- ? absolutize (ids [2], ids [1], true)
- : ids [1]);
- } catch (IOException e) {
- // "can't happen"
- throw new SAXParseException (e.getMessage (), this, e);
- }
- }
+ {
+ 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 unparsedEntityDecl (String name, String ids [], String notation)
+ void endDoctype()
throws SAXException
- {
- try {
- dtdHandler.unparsedEntityDecl (name, ids [0],
- resolveAll
- ? absolutize (ids [2], ids [1], true)
- : ids [1],
- notation);
- } catch (IOException e) {
- // "can't happen"
- throw new SAXParseException (e.getMessage (), this, e);
- }
- }
+ {
+ lexicalHandler.endDTD();
+ }
- void endDoctype ()
+ private void declarePrefix(String prefix, String uri)
throws SAXException
- {
- lexicalHandler.endDTD ();
- }
+ {
+ int index = uri.indexOf(':');
- 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);
+ }
- // 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);
- }
+ // 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)
+ 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 (getFeature (FEATURE + "string-interning")) {
- 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;
- }
+ {
+ 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));
+
}
- // remember this attribute ...
-
- attributeCount++;
-
- // attribute type comes from querying parser's DTD records
- attributesList.add(new Attribute(qname, value, isSpecified));
-
- }
-
- void startElement (String elname)
+
+ 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 (getFeature (FEATURE + "string-interning")) {
- 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;
- }
- }
+ {
+ ContentHandler handler = contentHandler;
- void endElement (String elname)
+ //
+ // 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;
+ {
+ 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 ();
- }
+ 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 ()
+ void startCDATA()
throws SAXException
- {
- lexicalHandler.startCDATA ();
- }
+ {
+ lexicalHandler.startCDATA();
+ }
- void charData (char ch[], int start, int length)
+ void charData(char[] ch, int start, int length)
throws SAXException
- {
- contentHandler.characters (ch, start, length);
- }
+ {
+ contentHandler.characters(ch, start, length);
+ }
- void endCDATA ()
+ void endCDATA()
throws SAXException
- {
- lexicalHandler.endCDATA ();
- }
+ {
+ lexicalHandler.endCDATA();
+ }
- void ignorableWhitespace (char ch[], int start, int length)
+ void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException
- {
- contentHandler.ignorableWhitespace (ch, start, length);
- }
+ {
+ contentHandler.ignorableWhitespace(ch, start, length);
+ }
- void processingInstruction (String target, String data)
+ void processingInstruction(String target, String data)
throws SAXException
- {
- contentHandler.processingInstruction (target, data);
- }
+ {
+ contentHandler.processingInstruction(target, data);
+ }
- void comment (char ch[], int start, int length)
+ void comment(char[] ch, int start, int length)
throws SAXException
- {
- if (lexicalHandler != base)
- lexicalHandler.comment (ch, start, length);
- }
+ {
+ if (lexicalHandler != base)
+ {
+ lexicalHandler.comment(ch, start, length);
+ }
+ }
- void fatal (String message)
+ 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;
- }
+ {
+ SAXParseException fatal;
+
+ fatal = new SAXParseException(message, this);
+ errorHandler.fatalError(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);
- }
+ // Even if the application can continue ... we can't!
+ throw fatal;
+ }
- void warn (String message)
+ // 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);
- }
-
+ {
+ SAXParseException err;
+
+ err = new SAXParseException(message, this);
+ errorHandler.warning(err);
+ }
- //
- // Implementation of org.xml.sax.Attributes.
- //
+ //
+ // 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>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 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 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>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</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 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>SAX1 AttributeList, SAX2 Attributes</b> method
- * (don't invoke on parser);
- */
- public String getValue (int index)
- {
- if (index < 0 || index >= attributesList.size())
+ /**
+ * <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 null;
+ return i;
}
- return ((Attribute) attributesList.get(index)).value;
- }
-
+ }
+ return -1;
+ }
- /**
- * <b>SAX2 Attributes</b> method (don't invoke on parser);
- */
- public int getIndex (String uri, String local)
- {
- int length = getLength();
+ /**
+ * <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);
+ }
- for (int i = 0; i < length; i++)
- {
- if (!getURI(i).equals(uri))
- {
- continue;
- }
- if (getLocalName(i).equals(local))
- {
- return i;
- }
- }
- return -1;
- }
+ /**
+ * <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>SAX2 Attributes</b> method (don't invoke on parser);
- */
- public int getIndex (String xmlName)
- {
- int length = getLength();
+ /**
+ * <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);
+ }
- for (int i = 0; i < length; i++)
- {
- if (getQName(i).equals(xmlName))
- {
- return i;
- }
- }
- return -1;
- }
+ //
+ // 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);
+ }
- /**
- * <b>SAX2 Attributes</b> method (don't invoke on parser);
- */
- public String getType (String uri, String local)
- {
- int index = getIndex(uri, local);
+ /** @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);
+ }
- if (index < 0)
- {
- return null;
- }
- return getType(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>SAX1 AttributeList, SAX2 Attributes</b> method
- * (don't invoke on parser);
- */
- public String getType (String xmlName)
- {
- int index = getIndex(xmlName);
+ /**
+ * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
+ */
+ public boolean isSpecified(String xmlName)
+ {
+ int index = getIndex (xmlName);
+ return isSpecified(index);
+ }
- if (index < 0)
- {
- return null;
- }
- return getType(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 Attributes</b> method (don't invoke on parser);
- */
- public String getValue (String uri, String local)
- {
- int index = getIndex(uri, local);
+ /**
+ * <b>SAX Locator</b> method (don't invoke on parser);
+ */
+ public int getLineNumber()
+ {
+ return parser.getLineNumber();
+ }
- if (index < 0)
- {
- return null;
- }
- return getValue(index);
- }
+ /**
+ * <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;
- /**
- * <b>SAX1 AttributeList, SAX2 Attributes</b> method
- * (don't invoke on parser);
- */
- public String getValue (String xmlName)
+ Adapter(DocumentHandler dh)
{
- int index = getIndex(xmlName);
-
- if (index < 0)
- {
- return null;
- }
- return getValue(index);
+ docHandler = dh;
}
-
- //
- // 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)
+ public void setDocumentLocator(Locator l)
{
- if (index < 0 || index >= attributeCount)
- throw new ArrayIndexOutOfBoundsException ();
- String type = parser.getAttributeType(elementName, getQName(index));
- return (type != null);
+ docHandler.setDocumentLocator(l);
}
-
- /** @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)
+
+ public void startDocument()
+ throws SAXException
{
- int index = getIndex (qName);
- if (index < 0)
- throw new IllegalArgumentException ();
- String type = parser.getAttributeType(elementName, qName);
- return (type != null);
+ docHandler.startDocument();
}
-
- /** @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)
+
+ public void processingInstruction(String target, String data)
+ throws SAXException
{
- int index = getIndex (uri, localName);
- return isDeclared(index);
+ docHandler.processingInstruction(target, data);
}
-
-
- /**
- * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
- */
- public boolean isSpecified (int index)
+
+ public void startPrefixMapping(String prefix, String uri)
{
- return ((Attribute) attributesList.get(index)).specified;
+ /* ignored */
}
- /**
- * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
- */
- public boolean isSpecified (String uri, String local)
+ public void startElement(String namespace,
+ String local,
+ String name,
+ Attributes attrs)
+ throws SAXException
{
- int index = getIndex (uri, local);
- return isSpecified(index);
+ docHandler.startElement(name, (AttributeList) attrs);
}
- /**
- * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
- */
- public boolean isSpecified (String xmlName)
+ public void characters(char[] buf, int offset, int len)
+ throws SAXException
{
- int index = getIndex (xmlName);
- return isSpecified(index);
+ docHandler.characters(buf, offset, len);
}
-
- //
- // Implementation of org.xml.sax.Locator.
- //
-
- /**
- * <b>SAX Locator</b> method (don't invoke on parser);
- */
- public String getPublicId ()
+ public void ignorableWhitespace(char[] buf, int offset, int len)
+ throws SAXException
{
- return null; // FIXME track public IDs too
+ docHandler.ignorableWhitespace(buf, offset, len);
}
- /**
- * <b>SAX Locator</b> method (don't invoke on parser);
- */
- public String getSystemId ()
+ public void skippedEntity(String name)
{
- if (entityStack.empty ())
- return null;
- else
- return (String) entityStack.peek ();
+ /* ignored */
}
- /**
- * <b>SAX Locator</b> method (don't invoke on parser);
- */
- public int getLineNumber ()
+ public void endElement(String u, String l, String name)
+ throws SAXException
{
- return parser.getLineNumber ();
+ docHandler.endElement(name);
}
- /**
- * <b>SAX Locator</b> method (don't invoke on parser);
- */
- public int getColumnNumber ()
+ public void endPrefixMapping(String prefix)
{
- return parser.getColumnNumber ();
+ /* ignored */
}
- // adapter between SAX2 content handler and SAX1 document handler callbacks
- private static class Adapter implements ContentHandler
+ public void endDocument()
+ throws SAXException
{
- 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 (); }
+ docHandler.endDocument();
}
-}
-
-class Attribute
-{
+ }
+ 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;
+ this.name = name;
+ this.value = value;
+ this.nameSpace = "";
+ this.specified = specified;
}
-}
+
+ }
+}
Index: gnu/xml/aelfred2/XmlParser.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/xml/aelfred2/XmlParser.java,v
retrieving revision 1.1
diff -u -r1.1 XmlParser.java
--- gnu/xml/aelfred2/XmlParser.java 2 Feb 2005 00:42:07 -0000 1.1
+++ gnu/xml/aelfred2/XmlParser.java 29 Mar 2005 19:50:36 -0000
@@ -53,6 +53,8 @@
package gnu.xml.aelfred2;
+import gnu.java.security.action.GetPropertyAction;
+
import java.io.BufferedInputStream;
import java.io.CharConversionException;
import java.io.EOFException;
@@ -63,12 +65,11 @@
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
+import java.security.AccessController;
-// maintaining 1.1 compatibility for now ...
-// Iterator and Hashmap ought to be faster
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Stack;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.LinkedList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -86,1511 +87,1838 @@
*/
final class XmlParser
{
- // avoid slow per-character readCh()
- private final static boolean USE_CHEATS = true;
+ // avoid slow per-character readCh()
+ private final static boolean USE_CHEATS = true;
- //////////////////////////////////////////////////////////////////////
- // Constructors.
- ////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
+ // Constants.
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // Constants for element content type.
+ //
+
+ /**
+ * Constant: an element has not been declared.
+ * @see #getElementContentType
+ */
+ public final static int CONTENT_UNDECLARED = 0;
+
+ /**
+ * Constant: the element has a content model of ANY.
+ * @see #getElementContentType
+ */
+ public final static int CONTENT_ANY = 1;
+
+ /**
+ * Constant: the element has declared content of EMPTY.
+ * @see #getElementContentType
+ */
+ public final static int CONTENT_EMPTY = 2;
+
+ /**
+ * Constant: the element has mixed content.
+ * @see #getElementContentType
+ */
+ public final static int CONTENT_MIXED = 3;
+
+ /**
+ * Constant: the element has element content.
+ * @see #getElementContentType
+ */
+ public final static int CONTENT_ELEMENTS = 4;
+
+
+ //
+ // Constants for the entity type.
+ //
+
+ /**
+ * Constant: the entity has not been declared.
+ * @see #getEntityType
+ */
+ public final static int ENTITY_UNDECLARED = 0;
+
+ /**
+ * Constant: the entity is internal.
+ * @see #getEntityType
+ */
+ public final static int ENTITY_INTERNAL = 1;
+
+ /**
+ * Constant: the entity is external, non-parsable data.
+ * @see #getEntityType
+ */
+ public final static int ENTITY_NDATA = 2;
+
+ /**
+ * Constant: the entity is external XML data.
+ * @see #getEntityType
+ */
+ public final static int ENTITY_TEXT = 3;
+
+ //
+ // Attribute type constants are interned literal strings.
+ //
+
+ //
+ // Constants for supported encodings. "external" is just a flag.
+ //
+ private final static int ENCODING_EXTERNAL = 0;
+ private final static int ENCODING_UTF_8 = 1;
+ private final static int ENCODING_ISO_8859_1 = 2;
+ private final static int ENCODING_UCS_2_12 = 3;
+ private final static int ENCODING_UCS_2_21 = 4;
+ private final static int ENCODING_UCS_4_1234 = 5;
+ private final static int ENCODING_UCS_4_4321 = 6;
+ private final static int ENCODING_UCS_4_2143 = 7;
+ private final static int ENCODING_UCS_4_3412 = 8;
+ private final static int ENCODING_ASCII = 9;
+
+ //
+ // Constants for attribute default value.
+ //
+
+ /**
+ * Constant: the attribute is not declared.
+ * @see #getAttributeDefaultValueType
+ */
+ public final static int ATTRIBUTE_DEFAULT_UNDECLARED = 30;
+
+ /**
+ * Constant: the attribute has a literal default value specified.
+ * @see #getAttributeDefaultValueType
+ * @see #getAttributeDefaultValue
+ */
+ public final static int ATTRIBUTE_DEFAULT_SPECIFIED = 31;
+
+ /**
+ * Constant: the attribute was declared #IMPLIED.
+ * @see #getAttributeDefaultValueType
+ */
+ public final static int ATTRIBUTE_DEFAULT_IMPLIED = 32;
+
+ /**
+ * Constant: the attribute was declared #REQUIRED.
+ * @see #getAttributeDefaultValueType
+ */
+ public final static int ATTRIBUTE_DEFAULT_REQUIRED = 33;
+
+ /**
+ * Constant: the attribute was declared #FIXED.
+ * @see #getAttributeDefaultValueType
+ * @see #getAttributeDefaultValue
+ */
+ public final static int ATTRIBUTE_DEFAULT_FIXED = 34;
+
+ //
+ // Constants for input.
+ //
+ private final static int INPUT_NONE = 0;
+ private final static int INPUT_INTERNAL = 1;
+ private final static int INPUT_STREAM = 3;
+ private final static int INPUT_READER = 5;
+
+ //
+ // Flags for reading literals.
+ //
+ // expand general entity refs (attribute values in dtd and content)
+ private final static int LIT_ENTITY_REF = 2;
+ // normalize this value (space chars) (attributes, public ids)
+ private final static int LIT_NORMALIZE = 4;
+ // literal is an attribute value
+ private final static int LIT_ATTRIBUTE = 8;
+ // don't expand parameter entities
+ private final static int LIT_DISABLE_PE = 16;
+ // don't expand [or parse] character refs
+ private final static int LIT_DISABLE_CREF = 32;
+ // don't parse general entity refs
+ private final static int LIT_DISABLE_EREF = 64;
+ // literal is a public ID value
+ private final static int LIT_PUBID = 256;
+
+ //
+ // Flags affecting PE handling in DTDs (if expandPE is true).
+ // PEs expand with space padding, except inside literals.
+ //
+ private final static int CONTEXT_NORMAL = 0;
+ private final static int CONTEXT_LITERAL = 1;
+
+ // Emit warnings for relative URIs with no base URI.
+ static boolean uriWarnings;
+ static
+ {
+ String key = "gnu.xml.aelfred2.XmlParser.uriWarnings";
+ GetPropertyAction a = new GetPropertyAction(key);
+ uriWarnings = "true".equals(AccessController.doPrivileged(a));
+ }
+
+ //
+ // The current XML handler interface.
+ //
+ private SAXDriver handler;
+
+ //
+ // I/O information.
+ //
+ private Reader reader; // current reader
+ private InputStream is; // current input stream
+ private int line; // current line number
+ private int column; // current column number
+ private int sourceType; // type of input source
+ private LinkedList inputStack; // stack of input soruces
+ private URLConnection externalEntity; // current external entity
+ private int encoding; // current character encoding
+ private int currentByteCount; // bytes read from current source
+ private InputSource scratch; // temporary
+
+ //
+ // Buffers for decoded but unparsed character input.
+ //
+ private char[] readBuffer;
+ private int readBufferPos;
+ private int readBufferLength;
+ private int readBufferOverflow; // overflow from last data chunk.
+
+ //
+ // Buffer for undecoded raw byte input.
+ //
+ private final static int READ_BUFFER_MAX = 16384;
+ private byte[] rawReadBuffer;
+
+
+ //
+ // Buffer for attribute values, char refs, DTD stuff.
+ //
+ private static int DATA_BUFFER_INITIAL = 4096;
+ private char[] dataBuffer;
+ private int dataBufferPos;
+
+ //
+ // Buffer for parsed names.
+ //
+ private static int NAME_BUFFER_INITIAL = 1024;
+ private char[] nameBuffer;
+ private int nameBufferPos;
+
+ //
+ // Save any standalone flag
+ //
+ private boolean docIsStandalone;
+
+ //
+ // Hashtables for DTD information on elements, entities, and notations.
+ // Populated until we start ignoring decls (because of skipping a PE)
+ //
+ private HashMap elementInfo;
+ private HashMap entityInfo;
+ private HashMap notationInfo;
+ private boolean skippedPE;
+
+ //
+ // Element type currently in force.
+ //
+ private String currentElement;
+ private int currentElementContent;
+
+ //
+ // Stack of entity names, to detect recursion.
+ //
+ private LinkedList entityStack;
+
+ //
+ // PE expansion is enabled in most chunks of the DTD, not all.
+ // When it's enabled, literals are treated differently.
+ //
+ private boolean inLiteral;
+ private boolean expandPE;
+ private boolean peIsError;
+
+ //
+ // can't report entity expansion inside two constructs:
+ // - attribute expansions (internal entities only)
+ // - markup declarations (parameter entities only)
+ //
+ private boolean doReport;
+
+ //
+ // Symbol table, for caching interned names.
+ //
+ // These show up wherever XML names or nmtokens are used: naming elements,
+ // attributes, PIs, notations, entities, and enumerated attribute values.
+ //
+ // NOTE: This hashtable doesn't grow. The default size is intended to be
+ // rather large for most documents. Example: one snapshot of the DocBook
+ // XML 4.1 DTD used only about 350 such names. As a rule, only pathological
+ // documents (ones that don't reuse names) should ever see much collision.
+ //
+ // Be sure that SYMBOL_TABLE_LENGTH always stays prime, for best hashing.
+ // "2039" keeps the hash table size at about two memory pages on typical
+ // 32 bit hardware.
+ //
+ private final static int SYMBOL_TABLE_LENGTH = 2039;
+
+ private Object[][] symbolTable;
+
+ //
+ // Hash table of attributes found in current start tag.
+ //
+ private String[] tagAttributes;
+ private int tagAttributePos;
+
+ //
+ // Utility flag: have we noticed a CR while reading the last
+ // data chunk? If so, we will have to go back and normalise
+ // CR or CR/LF line ends.
+ //
+ private boolean sawCR;
+
+ //
+ // Utility flag: are we in CDATA? If so, whitespace isn't ignorable.
+ //
+ private boolean inCDATA;
+
+ //
+ // Xml version.
+ //
+ private static final int XML_10 = 0;
+ private static final int XML_11 = 1;
+ private int xmlVersion = XML_10;
+
+ //////////////////////////////////////////////////////////////////////
+ // Constructors.
+ ////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Construct a new parser with no associated handler.
+ * @see #setHandler
+ * @see #parse
+ */
+ // package private
+ XmlParser()
+ {
+ }
+ /**
+ * Set the handler that will receive parsing events.
+ * @param handler The handler to receive callback events.
+ * @see #parse
+ */
+ // package private
+ void setHandler(SAXDriver handler)
+ {
+ this.handler = handler;
+ }
- /**
- * Construct a new parser with no associated handler.
- * @see #setHandler
- * @see #parse
- */
- // package private
- XmlParser ()
- {
- }
+ /**
+ * Parse an XML document from the character stream, byte stream, or URI
+ * that you provide (in that order of preference). Any URI that you
+ * supply will become the base URI for resolving relative URI, and may
+ * be used to acquire a reader or byte stream.
+ *
+ * <p> Only one thread at a time may use this parser; since it is
+ * private to this package, post-parse cleanup is done by the caller,
+ * which MUST NOT REUSE the parser (just null it).
+ *
+ * @param systemId Absolute URI of the document; should never be null,
+ * but may be so iff a reader <em>or</em> a stream is provided.
+ * @param publicId The public identifier of the document, or null.
+ * @param reader A character stream; must be null if stream isn't.
+ * @param stream A byte input stream; must be null if reader isn't.
+ * @param encoding The suggested encoding, or null if unknown.
+ * @exception java.lang.Exception Basically SAXException or IOException
+ */
+ // package private
+ void doParse(String systemId, String publicId, Reader reader,
+ InputStream stream, String encoding)
+ throws Exception
+ {
+ if (handler == null)
+ {
+ throw new IllegalStateException("no callback handler");
+ }
+ initializeVariables();
- /**
- * Set the handler that will receive parsing events.
- * @param handler The handler to receive callback events.
- * @see #parse
- */
- // package private
- void setHandler (SAXDriver handler)
- {
- this.handler = handler;
- }
+ // predeclare the built-in entities here (replacement texts)
+ // we don't need to intern(), since we're guaranteed literals
+ // are always (globally) interned.
+ setInternalEntity("amp", "&");
+ setInternalEntity("lt", "<");
+ setInternalEntity("gt", ">");
+ setInternalEntity("apos", "'");
+ setInternalEntity("quot", """);
+
+ try
+ {
+ // pushURL first to ensure locator is correct in startDocument
+ // ... it might report an IO or encoding exception.
+ handler.startDocument();
+ pushURL(false, "[document]",
+ // default baseURI: null
+ new ExternalIdentifiers(publicId, systemId, null),
+ reader, stream, encoding, false);
+
+ parseDocument();
+ }
+ catch (EOFException e)
+ {
+ //empty input
+ error("empty document, with no root element.");
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ try
+ {
+ reader.close();
+ }
+ catch (IOException e)
+ {
+ /* ignore */
+ }
+ }
+ if (stream != null)
+ {
+ try
+ {
+ stream.close();
+ }
+ catch (IOException e)
+ {
+ /* ignore */
+ }
+ }
+ if (is != null)
+ {
+ try
+ {
+ is.close();
+ }
+ catch (IOException e)
+ {
+ /* ignore */
+ }
+ }
+ scratch = null;
+ }
+ }
+ //////////////////////////////////////////////////////////////////////
+ // Error reporting.
+ //////////////////////////////////////////////////////////////////////
+
+ /**
+ * Report an error.
+ * @param message The error message.
+ * @param textFound The text that caused the error (or null).
+ * @see SAXDriver#error
+ * @see #line
+ */
+ private void error(String message, String textFound, String textExpected)
+ throws SAXException
+ {
+ if (textFound != null)
+ {
+ message = message + " (found \"" + textFound + "\")";
+ }
+ if (textExpected != null)
+ {
+ message = message + " (expected \"" + textExpected + "\")";
+ }
+ handler.fatal(message);
+
+ // "can't happen"
+ throw new SAXException(message);
+ }
- /**
- * Parse an XML document from the character stream, byte stream, or URI
- * that you provide (in that order of preference). Any URI that you
- * supply will become the base URI for resolving relative URI, and may
- * be used to acquire a reader or byte stream.
- *
- * <p> Only one thread at a time may use this parser; since it is
- * private to this package, post-parse cleanup is done by the caller,
- * which MUST NOT REUSE the parser (just null it).
- *
- * @param systemId Absolute URI of the document; should never be null,
- * but may be so iff a reader <em>or</em> a stream is provided.
- * @param publicId The public identifier of the document, or null.
- * @param reader A character stream; must be null if stream isn't.
- * @param stream A byte input stream; must be null if reader isn't.
- * @param encoding The suggested encoding, or null if unknown.
- * @exception java.lang.Exception Basically SAXException or IOException
- */
- // package private
- void doParse (
- String systemId,
- String publicId,
- Reader reader,
- InputStream stream,
- String encoding
- ) throws Exception
- {
- if (handler == null)
- throw new IllegalStateException ("no callback handler");
+ /**
+ * Report a serious error.
+ * @param message The error message.
+ * @param textFound The text that caused the error (or null).
+ */
+ private void error(String message, char textFound, String textExpected)
+ throws SAXException
+ {
+ error(message, new Character(textFound).toString(), textExpected);
+ }
- initializeVariables ();
+ /**
+ * Report typical case fatal errors.
+ */
+ private void error(String message)
+ throws SAXException
+ {
+ handler.fatal(message);
+ }
- // predeclare the built-in entities here (replacement texts)
- // we don't need to intern(), since we're guaranteed literals
- // are always (globally) interned.
- setInternalEntity ("amp", "&");
- setInternalEntity ("lt", "<");
- setInternalEntity ("gt", ">");
- setInternalEntity ("apos", "'");
- setInternalEntity ("quot", """);
-
- try {
- // pushURL first to ensure locator is correct in startDocument
- // ... it might report an IO or encoding exception.
- handler.startDocument ();
- pushURL (false, "[document]",
- // default baseURI: null
- new String [] { publicId, systemId, null},
- reader, stream, encoding, false);
-
- parseDocument ();
- } catch (EOFException e){
- //empty input
- error("empty document, with no root element.");
- }finally {
- if (reader != null)
- try { reader.close ();
- } catch (IOException e) { /* ignore */ }
- if (stream != null)
- try { stream.close ();
- } catch (IOException e) { /* ignore */ }
- if (is != null)
- try { is.close ();
- } catch (IOException e) { /* ignore */ }
- if (reader != null)
- try {
- reader.close ();
- } catch (IOException e) { /* ignore */
- }
- scratch = null;
- }
- }
+ //////////////////////////////////////////////////////////////////////
+ // Major syntactic productions.
+ //////////////////////////////////////////////////////////////////////
+ /**
+ * Parse an XML document.
+ * <pre>
+ * [1] document ::= prolog element Misc*
+ * </pre>
+ * <p>This is the top-level parsing function for a single XML
+ * document. As a minimum, a well-formed document must have
+ * a document element, and a valid document must have a prolog
+ * (one with doctype) as well.
+ */
+ private void parseDocument()
+ throws Exception
+ {
+ try
+ { // added by MHK
+ boolean sawDTD = parseProlog();
+ require('<');
+ parseElement(!sawDTD);
+ }
+ catch (EOFException ee)
+ { // added by MHK
+ error("premature end of file", "[EOF]", null);
+ }
+
+ try
+ {
+ parseMisc(); //skip all white, PIs, and comments
+ char c = readCh(); //if this doesn't throw an exception...
+ error("unexpected characters after document end", c, null);
+ }
+ catch (EOFException e)
+ {
+ return;
+ }
+ }
+
+ static final char[] startDelimComment = { '<', '!', '-', '-' };
+ static final char[] endDelimComment = { '-', '-' };
- ////////////////////////////////////////////////////////////////////////
- // Constants.
- ////////////////////////////////////////////////////////////////////////
+ /**
+ * Skip a comment.
+ * <pre>
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* "-->"
+ * </pre>
+ * <p> (The <code><!--</code> has already been read.)
+ */
+ private void parseComment()
+ throws Exception
+ {
+ char c;
+ boolean saved = expandPE;
+
+ expandPE = false;
+ parseUntil(endDelimComment);
+ require('>');
+ expandPE = saved;
+ handler.comment(dataBuffer, 0, dataBufferPos);
+ dataBufferPos = 0;
+ }
+
+ static final char[] startDelimPI = { '<', '?' };
+ static final char[] endDelimPI = { '?', '>' };
- //
- // Constants for element content type.
- //
+ /**
+ * Parse a processing instruction and do a call-back.
+ * <pre>
+ * [16] PI ::= '<?' PITarget
+ * (S (Char* - (Char* '?>' Char*)))?
+ * '?>'
+ * [17] PITarget ::= Name - ( ('X'|'x') ('M'|m') ('L'|l') )
+ * </pre>
+ * <p> (The <code><?</code> has already been read.)
+ */
+ private void parsePI()
+ throws SAXException, IOException
+ {
+ String name;
+ boolean saved = expandPE;
+
+ expandPE = false;
+ name = readNmtoken(true);
+ //NE08
+ if (name.indexOf(':') >= 0)
+ {
+ error("Illegal character(':') in processing instruction name ",
+ name, null);
+ }
+ if ("xml".equalsIgnoreCase(name))
+ {
+ error("Illegal processing instruction target", name, null);
+ }
+ if (!tryRead(endDelimPI))
+ {
+ requireWhitespace();
+ parseUntil(endDelimPI);
+ }
+ expandPE = saved;
+ handler.processingInstruction(name, dataBufferToString());
+ }
+
+ static final char[] endDelimCDATA = { ']', ']', '>' };
- /**
- * Constant: an element has not been declared.
- * @see #getElementContentType
- */
- public final static int CONTENT_UNDECLARED = 0;
+ private boolean isDirtyCurrentElement;
- /**
- * Constant: the element has a content model of ANY.
- * @see #getElementContentType
- */
- public final static int CONTENT_ANY = 1;
+ /**
+ * Parse a CDATA section.
+ * <pre>
+ * [18] CDSect ::= CDStart CData CDEnd
+ * [19] CDStart ::= '<![CDATA['
+ * [20] CData ::= (Char* - (Char* ']]>' Char*))
+ * [21] CDEnd ::= ']]>'
+ * </pre>
+ * <p> (The '<![CDATA[' has already been read.)
+ */
+ private void parseCDSect()
+ throws Exception
+ {
+ parseUntil(endDelimCDATA);
+ dataBufferFlush();
+ }
- /**
- * Constant: the element has declared content of EMPTY.
- * @see #getElementContentType
- */
- public final static int CONTENT_EMPTY = 2;
+ /**
+ * Parse the prolog of an XML document.
+ * <pre>
+ * [22] prolog ::= XMLDecl? Misc* (Doctypedecl Misc*)?
+ * </pre>
+ * <p>We do not look for the XML declaration here, because it was
+ * handled by pushURL ().
+ * @see pushURL
+ * @return true if a DTD was read.
+ */
+ private boolean parseProlog()
+ throws Exception
+ {
+ parseMisc();
- /**
- * Constant: the element has mixed content.
- * @see #getElementContentType
- */
- public final static int CONTENT_MIXED = 3;
+ if (tryRead("<!DOCTYPE"))
+ {
+ parseDoctypedecl();
+ parseMisc();
+ return true;
+ }
+ return false;
+ }
- /**
- * Constant: the element has element content.
- * @see #getElementContentType
- */
- public final static int CONTENT_ELEMENTS = 4;
+ private void checkLegalVersion(String version)
+ throws SAXException
+ {
+ int len = version.length();
+ for (int i = 0; i < len; i++)
+ {
+ char c = version.charAt(i);
+ if ('0' <= c && c <= '9')
+ {
+ continue;
+ }
+ if (c == '_' || c == '.' || c == ':' || c == '-')
+ {
+ continue;
+ }
+ if ('a' <= c && c <= 'z')
+ {
+ continue;
+ }
+ if ('A' <= c && c <= 'Z')
+ {
+ continue;
+ }
+ error ("illegal character in version", version, "1.0");
+ }
+ }
+ /**
+ * Parse the XML declaration.
+ * <pre>
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ * [24] VersionInfo ::= S 'version' Eq
+ * ("'" VersionNum "'" | '"' VersionNum '"' )
+ * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')*
+ * [32] SDDecl ::= S 'standalone' Eq
+ * ( "'"" ('yes' | 'no') "'"" | '"' ("yes" | "no") '"' )
+ * [80] EncodingDecl ::= S 'encoding' Eq
+ * ( "'" EncName "'" | "'" EncName "'" )
+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
+ * </pre>
+ * <p> (The <code><?xml</code> and whitespace have already been read.)
+ * @return the encoding in the declaration, uppercased; or null
+ * @see #parseTextDecl
+ * @see #setupDecoding
+ */
+ private String parseXMLDecl(boolean ignoreEncoding)
+ throws SAXException, IOException
+ {
+ String version;
+ String encodingName = null;
+ String standalone = null;
+ int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
+ String inputEncoding = null;
+
+ switch (this.encoding)
+ {
+ case ENCODING_EXTERNAL:
+ case ENCODING_UTF_8:
+ inputEncoding = "UTF-8";
+ break;
+ case ENCODING_ISO_8859_1:
+ inputEncoding = "ISO-8859-1";
+ break;
+ case ENCODING_UCS_2_12:
+ inputEncoding = "UTF-16BE";
+ break;
+ case ENCODING_UCS_2_21:
+ inputEncoding = "UTF-16LE";
+ break;
+ }
+
+ // Read the version.
+ require("version");
+ parseEq();
+ checkLegalVersion(version = readLiteral(flags));
+ if (!version.equals("1.0"))
+ {
+ if (version.equals("1.1"))
+ {
+ handler.warn("expected XML version 1.0, not: " + version);
+ xmlVersion = XML_11;
+ }
+ else
+ {
+ error("illegal XML version", version, "1.0 or 1.1");
+ }
+ }
+ else
+ {
+ xmlVersion = XML_10;
+ }
+ // Try reading an encoding declaration.
+ boolean white = tryWhitespace();
+
+ if (tryRead("encoding"))
+ {
+ if (!white)
+ {
+ error("whitespace required before 'encoding='");
+ }
+ parseEq();
+ encodingName = readLiteral(flags);
+ if (!ignoreEncoding)
+ {
+ setupDecoding(encodingName);
+ }
+ }
+
+ // Try reading a standalone declaration
+ if (encodingName != null)
+ {
+ white = tryWhitespace();
+ }
+ if (tryRead("standalone"))
+ {
+ if (!white)
+ {
+ error("whitespace required before 'standalone='");
+ }
+ parseEq();
+ standalone = readLiteral(flags);
+ if ("yes".equals(standalone))
+ {
+ docIsStandalone = true;
+ }
+ else if (!"no".equals(standalone))
+ {
+ error("standalone flag must be 'yes' or 'no'");
+ }
+ }
- //
- // Constants for the entity type.
- //
+ skipWhitespace();
+ require("?>");
- /**
- * Constant: the entity has not been declared.
- * @see #getEntityType
- */
- public final static int ENTITY_UNDECLARED = 0;
+ if (inputEncoding == null)
+ {
+ inputEncoding = encodingName;
+ }
+ handler.xmlDecl(version, encodingName, docIsStandalone,
+ inputEncoding);
+
+ return encodingName;
+ }
- /**
- * Constant: the entity is internal.
- * @see #getEntityType
- */
- public final static int ENTITY_INTERNAL = 1;
+ /**
+ * Parse a text declaration.
+ * <pre>
+ * [79] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
+ * [80] EncodingDecl ::= S 'encoding' Eq
+ * ( '"' EncName '"' | "'" EncName "'" )
+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
+ * </pre>
+ * <p> (The <code><?xml</code>' and whitespace have already been read.)
+ * @return the encoding in the declaration, uppercased; or null
+ * @see #parseXMLDecl
+ * @see #setupDecoding
+ */
+ private String parseTextDecl(boolean ignoreEncoding)
+ throws SAXException, IOException
+ {
+ String encodingName = null;
+ int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
- /**
- * Constant: the entity is external, non-parsable data.
- * @see #getEntityType
- */
- public final static int ENTITY_NDATA = 2;
+ // Read an optional version.
+ if (tryRead ("version"))
+ {
+ String version;
+ parseEq();
+ checkLegalVersion(version = readLiteral(flags));
+
+ if (version.equals("1.1"))
+ {
+ if (xmlVersion == XML_10)
+ {
+ error("external subset has later version number.", "1.0",
+ version);
+ }
+ handler.warn("expected XML version 1.0, not: " + version);
+ xmlVersion = XML_11;
+ }
+ else if (!version.equals("1.0"))
+ {
+ error("illegal XML version", version, "1.0 or 1.1");
+ }
+ requireWhitespace();
+ }
+
+ // Read the encoding.
+ require("encoding");
+ parseEq();
+ encodingName = readLiteral(flags);
+ if (!ignoreEncoding)
+ {
+ setupDecoding(encodingName);
+ }
+ skipWhitespace();
+ require("?>");
+
+ return encodingName;
+ }
- /**
- * Constant: the entity is external XML data.
- * @see #getEntityType
+ /**
+ * Sets up internal state so that we can decode an entity using the
+ * specified encoding. This is used when we start to read an entity
+ * and we have been given knowledge of its encoding before we start to
+ * read any data (e.g. from a SAX input source or from a MIME type).
+ *
+ * <p> It is also used after autodetection, at which point only very
+ * limited adjustments to the encoding may be used (switching between
+ * related builtin decoders).
+ *
+ * @param encodingName The name of the encoding specified by the user.
+ * @exception IOException if the encoding isn't supported either
+ * internally to this parser, or by the hosting JVM.
+ * @see #parseXMLDecl
+ * @see #parseTextDecl
*/
- public final static int ENTITY_TEXT = 3;
-
-
- //
- // Attribute type constants are interned literal strings.
- //
-
- //
- // Constants for supported encodings. "external" is just a flag.
- //
- private final static int ENCODING_EXTERNAL = 0;
- private final static int ENCODING_UTF_8 = 1;
- private final static int ENCODING_ISO_8859_1 = 2;
- private final static int ENCODING_UCS_2_12 = 3;
- private final static int ENCODING_UCS_2_21 = 4;
- private final static int ENCODING_UCS_4_1234 = 5;
- private final static int ENCODING_UCS_4_4321 = 6;
- private final static int ENCODING_UCS_4_2143 = 7;
- private final static int ENCODING_UCS_4_3412 = 8;
- private final static int ENCODING_ASCII = 9;
-
-
- //
- // Constants for attribute default value.
- //
-
- /**
- * Constant: the attribute is not declared.
- * @see #getAttributeDefaultValueType
- */
- public final static int ATTRIBUTE_DEFAULT_UNDECLARED = 30;
-
- /**
- * Constant: the attribute has a literal default value specified.
- * @see #getAttributeDefaultValueType
- * @see #getAttributeDefaultValue
- */
- public final static int ATTRIBUTE_DEFAULT_SPECIFIED = 31;
-
- /**
- * Constant: the attribute was declared #IMPLIED.
- * @see #getAttributeDefaultValueType
- */
- public final static int ATTRIBUTE_DEFAULT_IMPLIED = 32;
-
- /**
- * Constant: the attribute was declared #REQUIRED.
- * @see #getAttributeDefaultValueType
- */
- public final static int ATTRIBUTE_DEFAULT_REQUIRED = 33;
-
- /**
- * Constant: the attribute was declared #FIXED.
- * @see #getAttributeDefaultValueType
- * @see #getAttributeDefaultValue
- */
- public final static int ATTRIBUTE_DEFAULT_FIXED = 34;
-
-
- //
- // Constants for input.
- //
- private final static int INPUT_NONE = 0;
- private final static int INPUT_INTERNAL = 1;
- private final static int INPUT_STREAM = 3;
- private final static int INPUT_READER = 5;
-
-
- //
- // Flags for reading literals.
- //
- // expand general entity refs (attribute values in dtd and content)
- private final static int LIT_ENTITY_REF = 2;
- // normalize this value (space chars) (attributes, public ids)
- private final static int LIT_NORMALIZE = 4;
- // literal is an attribute value
- private final static int LIT_ATTRIBUTE = 8;
- // don't expand parameter entities
- private final static int LIT_DISABLE_PE = 16;
- // don't expand [or parse] character refs
- private final static int LIT_DISABLE_CREF = 32;
- // don't parse general entity refs
- private final static int LIT_DISABLE_EREF = 64;
- // literal is a public ID value
- private final static int LIT_PUBID = 256;
-
-
- //
- // Flags affecting PE handling in DTDs (if expandPE is true).
- // PEs expand with space padding, except inside literals.
- //
- private final static int CONTEXT_NORMAL = 0;
- private final static int CONTEXT_LITERAL = 1;
-
-
- //////////////////////////////////////////////////////////////////////
- // Error reporting.
- //////////////////////////////////////////////////////////////////////
-
-
- /**
- * Report an error.
- * @param message The error message.
- * @param textFound The text that caused the error (or null).
- * @see SAXDriver#error
- * @see #line
- */
- private void error (String message, String textFound, String textExpected)
- throws SAXException
- {
- if (textFound != null) {
- message = message + " (found \"" + textFound + "\")";
- }
- if (textExpected != null) {
- message = message + " (expected \"" + textExpected + "\")";
- }
- handler.fatal (message);
-
- // "can't happen"
- throw new SAXException (message);
- }
-
-
- /**
- * Report a serious error.
- * @param message The error message.
- * @param textFound The text that caused the error (or null).
- */
- private void error (String message, char textFound, String textExpected)
- throws SAXException
- {
- error (message, new Character (textFound).toString (), textExpected);
- }
-
- /** Report typical case fatal errors. */
- private void error (String message)
- throws SAXException
- {
- handler.fatal (message);
- }
-
-
- //////////////////////////////////////////////////////////////////////
- // Major syntactic productions.
- //////////////////////////////////////////////////////////////////////
-
-
- /**
- * Parse an XML document.
- * <pre>
- * [1] document ::= prolog element Misc*
- * </pre>
- * <p>This is the top-level parsing function for a single XML
- * document. As a minimum, a well-formed document must have
- * a document element, and a valid document must have a prolog
- * (one with doctype) as well.
- */
- private void parseDocument ()
- throws Exception
- {
- try { // added by MHK
- boolean sawDTD = parseProlog ();
- require ('<');
- parseElement (!sawDTD);
- } catch (EOFException ee) { // added by MHK
- error("premature end of file", "[EOF]", null);
- }
-
- try {
- parseMisc (); //skip all white, PIs, and comments
- char c = readCh (); //if this doesn't throw an exception...
- error ("unexpected characters after document end", c, null);
- } catch (EOFException e) {
- return;
- }
- }
-
- static final char startDelimComment [] = { '<', '!', '-', '-' };
- static final char endDelimComment [] = { '-', '-' };
-
- /**
- * Skip a comment.
- * <pre>
- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* "-->"
- * </pre>
- * <p> (The <code><!--</code> has already been read.)
- */
- private void parseComment ()
- throws Exception
- {
- char c;
- boolean saved = expandPE;
-
- expandPE = false;
- parseUntil (endDelimComment);
- require ('>');
- expandPE = saved;
- handler.comment (dataBuffer, 0, dataBufferPos);
- dataBufferPos = 0;
- }
-
- static final char startDelimPI [] = { '<', '?' };
- static final char endDelimPI [] = { '?', '>' };
-
- /**
- * Parse a processing instruction and do a call-back.
- * <pre>
- * [16] PI ::= '<?' PITarget
- * (S (Char* - (Char* '?>' Char*)))?
- * '?>'
- * [17] PITarget ::= Name - ( ('X'|'x') ('M'|m') ('L'|l') )
- * </pre>
- * <p> (The <code><?</code> has already been read.)
- */
- private void parsePI ()
+ private void setupDecoding(String encodingName)
throws SAXException, IOException
- {
- String name;
- boolean saved = expandPE;
-
- expandPE = false;
- name = readNmtoken (true);
- //NE08
- if (name.indexOf(':') >= 0)
- error ("Illegal character(':') in processing instruction name ", name, null);
- if ("xml".equalsIgnoreCase (name))
- error ("Illegal processing instruction target", name, null);
- if (!tryRead (endDelimPI)) {
- requireWhitespace ();
- parseUntil (endDelimPI);
- }
- expandPE = saved;
- handler.processingInstruction (name, dataBufferToString ());
- }
-
-
- static final char endDelimCDATA [] = { ']', ']', '>' };
-
- private boolean isDirtyCurrentElement;
-
- /**
- * Parse a CDATA section.
- * <pre>
- * [18] CDSect ::= CDStart CData CDEnd
- * [19] CDStart ::= '<![CDATA['
- * [20] CData ::= (Char* - (Char* ']]>' Char*))
- * [21] CDEnd ::= ']]>'
- * </pre>
- * <p> (The '<![CDATA[' has already been read.)
- */
- private void parseCDSect ()
+ {
+ encodingName = encodingName.toUpperCase();
+
+ // ENCODING_EXTERNAL indicates an encoding that wasn't
+ // autodetected ... we can use builtin decoders, or
+ // ones from the JVM (InputStreamReader).
+
+ // Otherwise we can only tweak what was autodetected, and
+ // only for single byte (ASCII derived) builtin encodings.
+
+ // ASCII-derived encodings
+ if (encoding == ENCODING_UTF_8 || encoding == ENCODING_EXTERNAL)
+ {
+ if (encodingName.equals("ISO-8859-1")
+ || encodingName.equals("8859_1")
+ || encodingName.equals("ISO8859_1"))
+ {
+ encoding = ENCODING_ISO_8859_1;
+ return;
+ }
+ else if (encodingName.equals("US-ASCII")
+ || encodingName.equals("ASCII"))
+ {
+ encoding = ENCODING_ASCII;
+ return;
+ }
+ else if (encodingName.equals("UTF-8")
+ || encodingName.equals("UTF8"))
+ {
+ encoding = ENCODING_UTF_8;
+ return;
+ }
+ else if (encoding != ENCODING_EXTERNAL)
+ {
+ // used to start with a new reader ...
+ throw new UnsupportedEncodingException(encodingName);
+ }
+ // else fallthrough ...
+ // it's ASCII-ish and something other than a builtin
+ }
+
+ // Unicode and such
+ if (encoding == ENCODING_UCS_2_12 || encoding == ENCODING_UCS_2_21)
+ {
+ if (!(encodingName.equals("ISO-10646-UCS-2")
+ || encodingName.equals("UTF-16")
+ || encodingName.equals("UTF-16BE")
+ || encodingName.equals("UTF-16LE")))
+ {
+ error("unsupported Unicode encoding", encodingName, "UTF-16");
+ }
+ return;
+ }
+
+ // four byte encodings
+ if (encoding == ENCODING_UCS_4_1234
+ || encoding == ENCODING_UCS_4_4321
+ || encoding == ENCODING_UCS_4_2143
+ || encoding == ENCODING_UCS_4_3412)
+ {
+ // Strictly: "UCS-4" == "UTF-32BE"; also, "UTF-32LE" exists
+ if (!encodingName.equals("ISO-10646-UCS-4"))
+ {
+ error("unsupported 32-bit encoding", encodingName,
+ "ISO-10646-UCS-4");
+ }
+ return;
+ }
+
+ // assert encoding == ENCODING_EXTERNAL
+ // if (encoding != ENCODING_EXTERNAL)
+ // throw new RuntimeException ("e