Commit 8d06274e by Tom Tromey

[multiple changes]

2005-03-26  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.

From-SVN: r97200
parent 1fff69c9
2005-03-26 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.
2005-03-28 Alexandre Oliva <aoliva@redhat.com> 2005-03-28 Alexandre Oliva <aoliva@redhat.com>
* configure.ac: Revert 2005-03-25's patch. Propagate MULTIlib * configure.ac: Revert 2005-03-25's patch. Propagate MULTIlib
......
...@@ -60,137 +60,172 @@ import javax.xml.parsers.SAXParserFactory; ...@@ -60,137 +60,172 @@ import javax.xml.parsers.SAXParserFactory;
* *
* @author David Brownell * @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. * Constructs a factory which normally returns a non-validating
*/ * parser.
public JAXPFactory () { } */
public JAXPFactory()
public SAXParser newSAXParser () {
}
public SAXParser newSAXParser()
throws ParserConfigurationException, SAXException 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 setProperty(String id, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException
{
ae2.setProperty(id, value);
}
public void setFeature (String name, boolean value) public Object getProperty(String id)
throws throws SAXNotRecognizedException, SAXNotSupportedException
ParserConfigurationException,
SAXNotRecognizedException,
SAXNotSupportedException
{ {
try { return ae2.getProperty(id);
// 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) public Parser getParser()
throws throws SAXException
ParserConfigurationException,
SAXNotRecognizedException,
SAXNotSupportedException
{ {
Boolean value = (Boolean) flags.get (name); if (parser == null)
{
if (value != null) parser = new XMLReaderAdapter(ae2);
return value.booleanValue (); }
else return parser;
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 public XMLReader getXMLReader ()
throws SAXException
{ {
private XmlReader ae2 = new XmlReader (); return ae2;
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 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()
}
} }
...@@ -60,15 +60,11 @@ import java.net.URL; ...@@ -60,15 +60,11 @@ import java.net.URL;
import java.util.Locale; import java.util.Locale;
import java.util.Stack; 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.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Vector;
import org.xml.sax.*; import org.xml.sax.*;
import org.xml.sax.ext.*; import org.xml.sax.ext.*;
...@@ -133,1276 +129,1494 @@ import org.xml.sax.helpers.NamespaceSupport; ...@@ -133,1276 +129,1494 @@ import org.xml.sax.helpers.NamespaceSupport;
* @see org.xml.sax.Parser * @see org.xml.sax.Parser
*/ */
final public class SAXDriver 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 final DefaultHandler2 base = new DefaultHandler2();
private XmlParser parser;
private EntityResolver entityResolver = base;
private EntityResolver2 resolver2 = null; private EntityResolver entityResolver = base;
private ContentHandler contentHandler = base; private EntityResolver2 resolver2 = null;
private DTDHandler dtdHandler = base; private ContentHandler contentHandler = base;
private ErrorHandler errorHandler = base; private DTDHandler dtdHandler = base;
private DeclHandler declHandler = base; private ErrorHandler errorHandler = base;
private LexicalHandler lexicalHandler = base; private DeclHandler declHandler = base;
private LexicalHandler lexicalHandler = base;
private String elementName;
private Stack entityStack; private String elementName;
private Stack entityStack;
// one vector (of object/struct): faster, smaller
private List attributesList; // one vector (of object/struct): faster, smaller
private List attributesList;
private boolean namespaces = true;
private boolean xmlNames = false; private boolean namespaces = true;
private boolean extGE = true; private boolean xmlNames = false;
private boolean extPE = true; private boolean extGE = true;
private boolean resolveAll = true; private boolean extPE = true;
private boolean useResolver2 = true; private boolean resolveAll = true;
private boolean stringInterning = true; private boolean useResolver2 = true;
private int attributeCount; // package private to allow (read-only) access in XmlParser
private boolean attributes; boolean stringInterning = true;
private String nsTemp [];
private NamespaceSupport prefixStack; private int attributeCount;
private boolean attributes;
private String[] nsTemp;
private NamespaceSupport prefixStack;
//
// Constructor.
//
/**
* Constructs a SAX Parser.
*/
public SAXDriver()
{
reset();
}
// private void reset()
// Constructor. {
// elementName = null;
entityStack = new Stack();
attributesList = Collections.synchronizedList(new ArrayList());
attributeCount = 0;
attributes = false;
nsTemp = new String[3];
prefixStack = null;
}
/** Constructs a SAX Parser. */
public SAXDriver ()
{
reset ();
}
private void reset () //
{ // Implementation of org.xml.sax.Parser.
elementName = null; //
entityStack = new Stack ();
attributesList = Collections.synchronizedList(new ArrayList());
attributeCount = 0;
attributes = false;
nsTemp = new String[3];
prefixStack = null;
}
/**
* <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>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</b>: Sets the locale used for diagnostics; currently, * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.
* only locales using the English language are supported. * @param handler The object to receive entity events.
* @param locale The locale for which diagnostics will be generated */
*/ public void setEntityResolver(EntityResolver resolver)
public void setLocale (Locale locale) {
throws SAXException if (resolver instanceof EntityResolver2)
{ {
if ("en".equals (locale.getLanguage ())) resolver2 = (EntityResolver2) resolver;
return ; }
else
{
resolver2 = null;
}
if (resolver == null)
{
resolver = base;
}
entityResolver = resolver;
}
throw new SAXException ("AElfred2 only supports English locales."); /**
} * <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 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. * <b>SAX1</b>: Set the document handler for this parser. If a
* @param handler The object to receive entity events. * content handler was set, this document handler will supplant it.
*/ * The parser is set to report all XML 1.0 names rather than to
public void setEntityResolver (EntityResolver resolver) * filter out "xmlns" attributes (the "namespace-prefixes" feature
{ * is set to true).
if (resolver instanceof EntityResolver2) *
resolver2 = (EntityResolver2) resolver; * @deprecated SAX2 programs should use the XMLReader interface
else * and a ContentHandler.
resolver2 = null; *
if (resolver == null) * @param handler The object to receive document events.
resolver = base; */
entityResolver = resolver; public void setDocumentHandler(DocumentHandler handler)
} {
contentHandler = new Adapter(handler);
xmlNames = true;
}
/**
* <b>SAX2</b>: Returns the object used to report the logical
* content of an XML document.
*/
public ContentHandler getContentHandler()
{
return (contentHandler == base) ? null : contentHandler;
}
/** /**
* <b>SAX2</b>: Returns the object used to process declarations related * <b>SAX2</b>: Assigns the object used to report the logical
* to notations and unparsed entities. * content of an XML document. If a document handler was set,
*/ * this content handler will supplant it (but XML 1.0 style name
public DTDHandler getDTDHandler () * reporting may remain enabled).
{ */
return (dtdHandler == base) ? null : dtdHandler; public void setContentHandler(ContentHandler handler)
} {
if (handler == null)
{
handler = base;
}
contentHandler = handler;
}
/** /**
* <b>SAX1, SAX2</b>: Set the DTD handler for this parser. * <b>SAX1, SAX2</b>: Set the error handler for this parser.
* @param handler The object to receive DTD events. * @param handler The object to receive error events.
*/ */
public void setDTDHandler (DTDHandler handler) public void setErrorHandler(ErrorHandler handler)
{ {
if (handler == null) if (handler == null)
handler = base; {
this.dtdHandler = handler; handler = base;
} }
this.errorHandler = handler;
}
/**
* <b>SAX2</b>: Returns the object used to receive callbacks for XML
* errors of all levels (fatal, nonfatal, warning); this is never null;
*/
public ErrorHandler getErrorHandler()
{
return (errorHandler == base) ? null : errorHandler;
}
/** /**
* <b>SAX1</b>: Set the document handler for this parser. If a * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
* content handler was set, this document handler will supplant it. * when no URI is available.
* The parser is set to report all XML 1.0 names rather than to * If you want anything useful to happen, you should set
* filter out "xmlns" attributes (the "namespace-prefixes" feature * at least one type of handler.
* is set to true). * @param source The XML input source. Don't set 'encoding' unless
* * you know for a fact that it's correct.
* @deprecated SAX2 programs should use the XMLReader interface * @see #setEntityResolver
* and a ContentHandler. * @see #setDTDHandler
* * @see #setContentHandler
* @param handler The object to receive document events. * @see #setErrorHandler
*/ * @exception SAXException The handlers may throw any SAXException,
public void setDocumentHandler (DocumentHandler handler) * and the parser normally throws SAXParseException objects.
{ * @exception IOException IOExceptions are normally through through
contentHandler = new Adapter (handler); * the parser if there are problems reading the source document.
xmlNames = true; */
} 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 report the logical * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a
* content of an XML document. * system identifier (URI).
*/ */
public ContentHandler getContentHandler () public void parse(String systemId)
{ throws SAXException, IOException
return contentHandler == base ? null : contentHandler; {
} parse(new InputSource(systemId));
}
/** //
* <b>SAX2</b>: Assigns the object used to report the logical // Implementation of SAX2 "XMLReader" interface
* content of an XML document. If a document handler was set, //
* this content handler will supplant it (but XML 1.0 style name static final String FEATURE = "http://xml.org/sax/features/";
* reporting may remain enabled). static final String PROPERTY = "http://xml.org/sax/properties/";
*/
public void setContentHandler (ContentHandler handler) /**
{ * <b>SAX2</b>: Tells the value of the specified feature flag.
if (handler == null) *
handler = base; * @exception SAXNotRecognizedException thrown if the feature flag
contentHandler = handler; * is neither built in, nor yet assigned.
} */
public boolean getFeature(String featureId)
throws SAXNotRecognizedException, SAXNotSupportedException
{
if ((FEATURE + "validation").equals(featureId))
{
return false;
}
/** // external entities (both types) are optionally included
* <b>SAX1, SAX2</b>: Set the error handler for this parser. if ((FEATURE + "external-general-entities").equals(featureId))
* @param handler The object to receive error events. {
*/ return extGE;
public void setErrorHandler (ErrorHandler handler) }
{ if ((FEATURE + "external-parameter-entities").equals(featureId))
if (handler == null) {
handler = base; return extPE;
this.errorHandler = handler; }
}
// element/attribute names are as written in document; no mangling
if ((FEATURE + "namespace-prefixes").equals(featureId))
{
return xmlNames;
}
/** // report element/attribute namespaces?
* <b>SAX2</b>: Returns the object used to receive callbacks for XML if ((FEATURE + "namespaces").equals(featureId))
* errors of all levels (fatal, nonfatal, warning); this is never null; {
*/ return namespaces;
public ErrorHandler getErrorHandler () }
{ return errorHandler == base ? null : errorHandler; }
/**
* <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
* when no URI is available.
* If you want anything useful to happen, you should set
* at least one type of handler.
* @param source The XML input source. Don't set 'encoding' unless
* you know for a fact that it's correct.
* @see #setEntityResolver
* @see #setDTDHandler
* @see #setContentHandler
* @see #setErrorHandler
* @exception SAXException The handlers may throw any SAXException,
* and the parser normally throws SAXParseException objects.
* @exception IOException IOExceptions are normally through through
* the parser if there are problems reading the source document.
*/
public void parse (InputSource source)
throws SAXException, IOException
{
synchronized (base) {
parser = new XmlParser ();
if (namespaces)
prefixStack = new NamespaceSupport ();
else if (!xmlNames)
throw new IllegalStateException ();
parser.setHandler (this);
try {
Reader r = source.getCharacterStream();
InputStream in = source.getByteStream();
parser.doParse (source.getSystemId (),
source.getPublicId (),
r,
in,
source.getEncoding ());
} catch (SAXException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new SAXParseException (e.getMessage (), this, e);
} finally {
contentHandler.endDocument ();
reset();
}
}
}
// all PEs and GEs are reported
if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId))
{
return true;
}
/** // default is true
* <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a if ((FEATURE + "string-interning").equals(featureId))
* system identifier (URI). {
*/ return stringInterning;
public void parse (String systemId) }
throws SAXException, IOException
{ // EXTENSIONS 1.1
parse (new InputSource (systemId));
} // 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
// Implementation of SAX2 "XMLReader" interface if ((FEATURE + "resolve-dtd-uris").equals(featureId))
// {
static final String FEATURE = "http://xml.org/sax/features/"; return resolveAll;
static final String PROPERTY = "http://xml.org/sax/properties/"; }
/** // optionally use resolver2 interface methods, if possible
* <b>SAX2</b>: Tells the value of the specified feature flag. if ((FEATURE + "use-entity-resolver2").equals(featureId))
* {
* @exception SAXNotRecognizedException thrown if the feature flag return useResolver2;
* is neither built in, nor yet assigned. }
*/
public boolean getFeature (String featureId) throw new SAXNotRecognizedException(featureId);
throws SAXNotRecognizedException, SAXNotSupportedException }
{
if ((FEATURE + "validation").equals (featureId))
return false;
// external entities (both types) are optionally included
if ((FEATURE + "external-general-entities").equals (featureId))
return extGE;
if ((FEATURE + "external-parameter-entities") .equals (featureId))
return extPE;
// element/attribute names are as written in document; no mangling
if ((FEATURE + "namespace-prefixes").equals (featureId))
return xmlNames;
// report element/attribute namespaces?
if ((FEATURE + "namespaces").equals (featureId))
return namespaces;
// all PEs and GEs are reported
if ((FEATURE + "lexical-handler/parameter-entities").equals (featureId))
return true;
// default is true
if ((FEATURE + "string-interning").equals (featureId))
return stringInterning;
// EXTENSIONS 1.1
// always returns isSpecified info
if ((FEATURE + "use-attributes2").equals (featureId))
return true;
// meaningful between startDocument/endDocument
if ((FEATURE + "is-standalone").equals (featureId)) {
if (parser == null)
throw new SAXNotSupportedException (featureId);
return parser.isStandalone ();
}
// optionally don't absolutize URIs in declarations
if ((FEATURE + "resolve-dtd-uris").equals (featureId))
return resolveAll;
// optionally use resolver2 interface methods, if possible
if ((FEATURE + "use-entity-resolver2").equals (featureId))
return useResolver2;
throw new SAXNotRecognizedException (featureId);
}
// package private // package private
DeclHandler getDeclHandler () { return declHandler; } DeclHandler getDeclHandler()
{
return declHandler;
}
// package private // package private
boolean resolveURIs () { return resolveAll; } boolean resolveURIs()
{
return resolveAll;
}
/** /**
* <b>SAX2</b>: Returns the specified property. * <b>SAX2</b>: Returns the specified property.
* *
* @exception SAXNotRecognizedException thrown if the property value * @exception SAXNotRecognizedException thrown if the property value
* is neither built in, nor yet stored. * is neither built in, nor yet stored.
*/ */
public Object getProperty (String propertyId) public Object getProperty(String propertyId)
throws SAXNotRecognizedException throws SAXNotRecognizedException
{ {
if ((PROPERTY + "declaration-handler").equals (propertyId)) if ((PROPERTY + "declaration-handler").equals(propertyId))
return declHandler == base ? null : declHandler; {
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))
* <b>SAX2</b>: Sets the state of feature flags in this parser. Some {
* built-in feature flags are mutable. return (lexicalHandler == base) ? null : lexicalHandler;
*/ }
public void setFeature (String featureId, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException // unknown properties
{ throw new SAXNotRecognizedException(propertyId);
boolean state; }
// Features with a defined value, we just change it if we can.
state = getFeature (featureId);
if (state == value)
return;
if (parser != null)
throw new SAXNotSupportedException ("not while parsing");
if ((FEATURE + "namespace-prefixes").equals (featureId)) {
// in this implementation, this only affects xmlns reporting
xmlNames = value;
// forcibly prevent illegal parser state
if (!xmlNames)
namespaces = true;
return;
}
if ((FEATURE + "namespaces").equals (featureId)) {
namespaces = value;
// forcibly prevent illegal parser state
if (!namespaces)
xmlNames = true;
return;
}
if ((FEATURE + "external-general-entities").equals (featureId)) {
extGE = value;
return;
}
if ((FEATURE + "external-parameter-entities") .equals (featureId)) {
extPE = value;
return;
}
if ((FEATURE + "resolve-dtd-uris").equals (featureId)) {
resolveAll = value;
return;
}
if ((FEATURE + "use-entity-resolver2").equals (featureId)) {
useResolver2 = value;
return;
}
throw new SAXNotRecognizedException (featureId);
}
/** /**
* <b>SAX2</b>: Assigns the specified property. Like SAX1 handlers, * <b>SAX2</b>: Sets the state of feature flags in this parser. Some
* these may be changed at any time. * built-in feature flags are mutable.
*/ */
public void setProperty (String propertyId, Object value) public void setFeature(String featureId, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
// see if the property is recognized boolean state;
getProperty (propertyId);
// Features with a defined value, we just change it if we can.
// Properties with a defined value, we just change it if we can. state = getFeature (featureId);
if ((PROPERTY + "declaration-handler").equals (propertyId)) { if (state == value)
if (value == null) {
declHandler = base; return;
else if (! (value instanceof DeclHandler)) }
throw new SAXNotSupportedException (propertyId); if (parser != null)
else {
declHandler = (DeclHandler) value; throw new SAXNotSupportedException("not while parsing");
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);
}
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))
// This is where the driver receives XmlParser callbacks and translates {
// them into SAX callbacks. Some more callbacks have been added for namespaces = value;
// SAX2 support. // 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;
}
void startDocument () if ((FEATURE + "use-entity-resolver2").equals(featureId))
{
useResolver2 = value;
return;
}
throw new SAXNotRecognizedException(featureId);
}
/**
* <b>SAX2</b>: Assigns the specified property. Like SAX1 handlers,
* these may be changed at any time.
*/
public void setProperty(String propertyId, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException
{
// see if the property is recognized
getProperty(propertyId);
// Properties with a defined value, we just change it if we can.
if ((PROPERTY + "declaration-handler").equals(propertyId))
{
if (value == null)
{
declHandler = base;
}
else if (!(value instanceof DeclHandler))
{
throw new SAXNotSupportedException(propertyId);
}
else
{
declHandler = (DeclHandler) value;
}
return ;
}
if ((PROPERTY + "lexical-handler").equals(propertyId))
{
if (value == null)
{
lexicalHandler = base;
}
else if (!(value instanceof LexicalHandler))
{
throw new SAXNotSupportedException(propertyId);
}
else
{
lexicalHandler = (LexicalHandler) value;
}
return;
}
throw new SAXNotSupportedException(propertyId);
}
//
// This is where the driver receives XmlParser callbacks and translates
// them into SAX callbacks. Some more callbacks have been added for
// SAX2 support.
//
void startDocument()
throws SAXException throws SAXException
{ {
contentHandler.setDocumentLocator (this); contentHandler.setDocumentLocator(this);
contentHandler.startDocument (); contentHandler.startDocument();
attributesList.clear (); attributesList.clear();
} }
void xmlDecl(String version, void xmlDecl(String version,
String encoding, String encoding,
boolean standalone, boolean standalone,
String inputEncoding) String inputEncoding)
throws SAXException throws SAXException
{ {
if (contentHandler instanceof ContentHandler2) if (contentHandler instanceof ContentHandler2)
{ {
((ContentHandler2) contentHandler).xmlDecl(version, ((ContentHandler2) contentHandler).xmlDecl(version,
encoding, encoding,
standalone, standalone,
inputEncoding); inputEncoding);
} }
} }
void skippedEntity (String name) void skippedEntity(String name)
throws SAXException throws SAXException
{ contentHandler.skippedEntity (name); } {
contentHandler.skippedEntity(name);
}
InputSource getExternalSubset (String name, String baseURI) InputSource getExternalSubset(String name, String baseURI)
throws SAXException, IOException throws SAXException, IOException
{ {
if (resolver2 == null || !useResolver2 || !extPE) if (resolver2 == null || !useResolver2 || !extPE)
return null; {
return resolver2.getExternalSubset (name, baseURI); return null;
} }
return resolver2.getExternalSubset(name, baseURI);
}
InputSource resolveEntity (boolean isPE, String name, InputSource resolveEntity(boolean isPE, String name,
InputSource in, String baseURI) InputSource in, String baseURI)
throws SAXException, IOException throws SAXException, IOException
{ {
InputSource source; InputSource source;
// external entities might be skipped // external entities might be skipped
if (isPE && !extPE) if (isPE && !extPE)
return null; {
if (!isPE && !extGE) return null;
return null; }
if (!isPE && !extGE)
// ... or not {
lexicalHandler.startEntity (name); return null;
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 // ... or not
// (temporarily) package-visible for external entity decls lexicalHandler.startEntity(name);
String absolutize (String baseURI, String systemId, boolean nice) if (resolver2 != null && useResolver2)
{
source = resolver2.resolveEntity(name, in.getPublicId(),
baseURI, in.getSystemId());
if (source == null)
{
in.setSystemId(absolutize(baseURI,
in.getSystemId(), false));
source = in;
}
}
else
{
in.setSystemId(absolutize(baseURI, in.getSystemId(), false));
source = entityResolver.resolveEntity(in.getPublicId(),
in.getSystemId());
if (source == null)
{
source = in;
}
}
startExternalEntity(name, source.getSystemId(), true);
return source;
}
// absolutize a system ID relative to the specified base URI
// (temporarily) package-visible for external entity decls
String absolutize(String baseURI, String systemId, boolean nice)
throws MalformedURLException, SAXException throws MalformedURLException, SAXException
{ {
// FIXME normalize system IDs -- when? // FIXME normalize system IDs -- when?
// - Convert to UTF-8 // - Convert to UTF-8
// - Map reserved and non-ASCII characters to %HH // - Map reserved and non-ASCII characters to %HH
try { try
if (baseURI == null) { {
warn ("No base URI; hope this SYSTEM id is absolute: " if (baseURI == null)
+ systemId); {
return new URL (systemId).toString (); if (XmlParser.uriWarnings)
} else {
return new URL (new URL (baseURI), systemId).toString (); warn ("No base URI; hope this SYSTEM id is absolute: "
+ systemId);
} catch (MalformedURLException e) { }
return new URL(systemId).toString();
// Let unknown URI schemes pass through unless we need }
// the JVM to map them to i/o streams for us... else
if (!nice) {
throw e; return new URL(new URL(baseURI), systemId).toString();
}
// sometimes sysids for notations or unparsed entities }
// aren't really URIs... catch (MalformedURLException e)
warn ("Can't absolutize SYSTEM id: " + e.getMessage ()); {
return systemId; // 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, void startExternalEntity(String name, String systemId, boolean stackOnly)
boolean stackOnly)
throws SAXException throws SAXException
{ {
// The following warning was deleted because the application has the // The following warning was deleted because the application has the
// option of not setting systemId. Sun's JAXP or Xerces seems to // option of not setting systemId. Sun's JAXP or Xerces seems to
// ignore this case. // ignore this case.
/* /*
if (systemId == null) if (systemId == null)
warn ("URI was not reported to parser for entity " + name); warn ("URI was not reported to parser for entity " + name);
*/ */
if (!stackOnly) // spliced [dtd] needs startEntity if (!stackOnly) // spliced [dtd] needs startEntity
lexicalHandler.startEntity (name); {
entityStack.push (systemId); lexicalHandler.startEntity(name);
} }
entityStack.push(systemId);
}
void endExternalEntity (String name) void endExternalEntity(String name)
throws SAXException throws SAXException
{ {
if (!"[document]".equals (name)) if (!"[document]".equals(name))
lexicalHandler.endEntity (name); {
entityStack.pop (); lexicalHandler.endEntity(name);
} }
entityStack.pop();
}
void startInternalEntity (String name) void startInternalEntity(String name)
throws SAXException throws SAXException
{ {
lexicalHandler.startEntity (name); lexicalHandler.startEntity(name);
} }
void endInternalEntity (String name) void endInternalEntity(String name)
throws SAXException 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 throws SAXException
{ {
lexicalHandler.startDTD (name, publicId, systemId); lexicalHandler.startDTD(name, publicId, systemId);
// ... the "name" is a declaration and should be given // ... the "name" is a declaration and should be given
// to the DeclHandler (but sax2 doesn't). // to the DeclHandler (but sax2 doesn't).
// the IDs for the external subset are lexical details, // the IDs for the external subset are lexical details,
// as are the contents of the internal subset; but sax2 // as are the contents of the internal subset; but sax2
// doesn't provide the internal subset "pre-parse" // doesn't provide the internal subset "pre-parse"
} }
void notationDecl (String name, String ids []) void notationDecl(String name, String publicId, String systemId,
String baseUri)
throws SAXException throws SAXException
{ {
try { try
dtdHandler.notationDecl (name, ids [0], {
(resolveAll && ids [1] != null) dtdHandler.notationDecl(name, publicId,
? absolutize (ids [2], ids [1], true) (resolveAll && systemId != null)
: ids [1]); ? absolutize(baseUri, systemId, true)
} catch (IOException e) { : systemId);
// "can't happen" }
throw new SAXParseException (e.getMessage (), this, e); catch (IOException e)
} {
} // "can't happen"
throw new SAXParseException(e.getMessage(), this, e);
}
}
void unparsedEntityDecl (String name, String ids [], String notation) void unparsedEntityDecl(String name, String publicId, String systemId,
String baseUri, String notation)
throws SAXException throws SAXException
{ {
try { try
dtdHandler.unparsedEntityDecl (name, ids [0], {
resolveAll dtdHandler.unparsedEntityDecl(name, publicId,
? absolutize (ids [2], ids [1], true) resolveAll
: ids [1], ? absolutize(baseUri, systemId, true)
notation); : systemId,
} catch (IOException e) { notation);
// "can't happen" }
throw new SAXParseException (e.getMessage (), this, e); catch (IOException e)
} {
} // "can't happen"
throw new SAXParseException(e.getMessage(), this, e);
}
}
void endDoctype () void endDoctype()
throws SAXException throws SAXException
{ {
lexicalHandler.endDTD (); lexicalHandler.endDTD();
} }
private void declarePrefix (String prefix, String uri) private void declarePrefix(String prefix, String uri)
throws SAXException throws SAXException
{ {
int index = uri.indexOf (':'); int index = uri.indexOf(':');
// many versions of nwalsh docbook stylesheets // many versions of nwalsh docbook stylesheets
// have bogus URLs; so this can't be an error... // have bogus URLs; so this can't be an error...
if (index < 1 && uri.length () != 0) if (index < 1 && uri.length() != 0)
warn ("relative URI for namespace: " + uri); {
warn("relative URI for namespace: " + uri);
// FIXME: char [0] must be ascii alpha; chars [1..index] }
// must be ascii alphanumeric or in "+-." [RFC 2396]
//Namespace Constraints
//name for xml prefix must be http://www.w3.org/XML/1998/namespace
boolean prefixEquality = prefix.equals("xml");
boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");
if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
fatal ("xml is by definition bound to the namespace name " +
"http://www.w3.org/XML/1998/namespace");
//xmlns prefix declaration is illegal but xml prefix declaration is llegal...
if (prefixEquality && uriEquality)
return;
//name for xmlns prefix must be http://www.w3.org/2000/xmlns/
prefixEquality = prefix.equals("xmlns");
uriEquality = uri.equals("http://www.w3.org/2000/xmlns/");
if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
fatal("http://www.w3.org/2000/xmlns/ is by definition bound" +
" to prefix xmlns");
//even if the uri is http://www.w3.org/2000/xmlns/ it is illegal to declare it
if (prefixEquality && uriEquality)
fatal ("declaring the xmlns prefix is illegal");
uri = uri.intern ();
prefixStack.declarePrefix (prefix, uri);
contentHandler.startPrefixMapping (prefix, uri);
}
void attribute (String qname, String value, boolean isSpecified) // FIXME: char [0] must be ascii alpha; chars [1..index]
throws SAXException // must be ascii alphanumeric or in "+-." [RFC 2396]
{
if (!attributes) { //Namespace Constraints
attributes = true; //name for xml prefix must be http://www.w3.org/XML/1998/namespace
if (namespaces) boolean prefixEquality = prefix.equals("xml");
prefixStack.pushContext (); boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");
} if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
{
// process namespace decls immediately; fatal("xml is by definition bound to the namespace name " +
// then maybe forget this as an attribute "http://www.w3.org/XML/1998/namespace");
if (namespaces) { }
int index;
//xmlns prefix declaration is illegal but xml prefix declaration is llegal...
// default NS declaration? if (prefixEquality && uriEquality)
if (getFeature (FEATURE + "string-interning")) { {
if ("xmlns" == qname) { return;
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;
}
} }
//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);
} }
// 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 attribute(String qname, String value, boolean isSpecified)
throws SAXException throws SAXException
{ {
ContentHandler handler = contentHandler; if (!attributes)
{
// attributes = true;
// NOTE: this implementation of namespace support adds something if (namespaces)
// like six percent to parsing CPU time, in a large (~50 MB) {
// document that doesn't use namespaces at all. (Measured by PC prefixStack.pushContext();
// 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 // process namespace decls immediately;
// costs are the prefix stack calling Hashtable.get() (2%), // then maybe forget this as an attribute
// String.hashCode() (1.5%) and about 1.3% each for pushing if (namespaces)
// the context, and two chunks of name processing. {
// int index;
if (!attributes) { // default NS declaration?
if (namespaces) if (stringInterning)
prefixStack.pushContext (); {
} else if (namespaces) { if ("xmlns" == qname)
{
// now we can patch up namespace refs; we saw all the declarePrefix("", value);
// declarations, so now we'll do the Right Thing if (!xmlNames)
Iterator itt = attributesList.iterator (); {
while(itt.hasNext()) return;
{ }
Attribute attribute = (Attribute) itt.next(); }
String qname = attribute.name; // NS prefix declaration?
int index; else if ((index = qname.indexOf(':')) == 5
&& qname.startsWith("xmlns"))
// default NS declaration? {
if (getFeature (FEATURE + "string-interning")) { String prefix = qname.substring(6);
if ("xmlns" == qname)
continue; if (prefix.equals(""))
} else { {
if ("xmlns".equals(qname)) fatal("missing prefix " +
continue; "in namespace declaration attribute");
} }
//Illegal in the new Namespaces Draft if (value.length() == 0)
//should it be only in 1.1 docs?? {
if (qname.equals (":")) verror("missing URI in namespace declaration attribute: "
fatal ("namespace names consisting of a single colon " + + qname);
"character are invalid"); }
index = qname.indexOf (':'); else
{
// NS prefix declaration? declarePrefix(prefix, value);
if (index == 5 && qname.startsWith ("xmlns")) }
continue; if (!xmlNames)
{
// it's not a NS decl; patch namespace info items return;
if (prefixStack.processName (qname, nsTemp, true) == null) }
fatal ("undeclared attribute prefix in: " + qname); }
else { }
attribute.nameSpace = nsTemp[0]; else
attribute.localName = nsTemp[1]; {
} if ("xmlns".equals(qname))
} {
} declarePrefix("", value);
if (!xmlNames)
// save element name so attribute callbacks work {
elementName = elname; return;
if (namespaces) { }
if (prefixStack.processName (elname, nsTemp, false) == null) { }
fatal ("undeclared element prefix in: " + elname); // NS prefix declaration?
nsTemp [0] = nsTemp [1] = ""; else if ((index = qname.indexOf(':')) == 5
} && qname.startsWith("xmlns"))
handler.startElement (nsTemp [0], nsTemp [1], elname, this); {
} else String prefix = qname.substring(6);
handler.startElement ("", "", elname, this);
// elementName = null; if (value.length() == 0)
{
// elements with no attributes are pretty common! verror("missing URI in namespace decl attribute: "
if (attributes) { + qname);
attributesList.clear(); }
attributeCount = 0; else
attributes = false; {
} declarePrefix(prefix, value);
} }
if (!xmlNames)
void endElement (String elname) {
return;
}
}
}
}
// remember this attribute ...
attributeCount++;
// attribute type comes from querying parser's DTD records
attributesList.add(new Attribute(qname, value, isSpecified));
}
void startElement(String elname)
throws SAXException 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 (); //
// 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;
while (prefixes.hasMoreElements ()) if (!namespaces)
handler.endPrefixMapping ((String) prefixes.nextElement ()); {
prefixStack.popContext (); 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 throws SAXException
{ {
lexicalHandler.startCDATA (); lexicalHandler.startCDATA();
} }
void charData (char ch[], int start, int length) void charData(char[] ch, int start, int length)
throws SAXException throws SAXException
{ {
contentHandler.characters (ch, start, length); contentHandler.characters(ch, start, length);
} }
void endCDATA () void endCDATA()
throws SAXException throws SAXException
{ {
lexicalHandler.endCDATA (); lexicalHandler.endCDATA();
} }
void ignorableWhitespace (char ch[], int start, int length) void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException 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 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 throws SAXException
{ {
if (lexicalHandler != base) if (lexicalHandler != base)
lexicalHandler.comment (ch, start, length); {
} lexicalHandler.comment(ch, start, length);
}
}
void fatal (String message) void fatal(String message)
throws SAXException throws SAXException
{ {
SAXParseException fatal; SAXParseException fatal;
fatal = new SAXParseException (message, this); fatal = new SAXParseException(message, this);
errorHandler.fatalError (fatal); errorHandler.fatalError(fatal);
// Even if the application can continue ... we can't! // Even if the application can continue ... we can't!
throw fatal; throw fatal;
} }
// We can safely report a few validity errors that // We can safely report a few validity errors that
// make layered SAX2 DTD validation more conformant // make layered SAX2 DTD validation more conformant
void verror (String message) void verror(String message)
throws SAXException throws SAXException
{ {
SAXParseException err; SAXParseException err;
err = new SAXParseException (message, this); err = new SAXParseException(message, this);
errorHandler.error (err); errorHandler.error(err);
} }
void warn (String message) void warn(String message)
throws SAXException throws SAXException
{ {
SAXParseException err; SAXParseException err;
err = new SAXParseException (message, this); err = new SAXParseException(message, this);
errorHandler.warning (err); errorHandler.warning(err);
} }
//
// Implementation of org.xml.sax.Attributes.
//
/**
* <b>SAX1 AttributeList, SAX2 Attributes</b> method
* (don't invoke on parser);
*/
public int getLength()
{
return attributesList.size();
}
// /**
// Implementation of org.xml.sax.Attributes. * <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>SAX1 AttributeList, SAX2 Attributes</b> method * <b>SAX2 Attributes</b> method (don't invoke on parser);
* (don't invoke on parser); */
*/ public String getLocalName(int index)
public int getLength () {
{ if (index < 0 || index >= attributesList.size())
return 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); * <b>SAX2 Attributes</b> method (don't invoke on parser);
*/ */
public String getURI (int index) public String getQName(int index)
{ {
if (index < 0 || index >= attributesList.size()) if (index < 0 || index >= attributesList.size())
{ {
return null; return null;
} }
return ((Attribute) attributesList.get(index)).nameSpace; Attribute attr = (Attribute) attributesList.get(index);
} return (attr.name == null) ? "" : attr.name;
}
/** /**
* <b>SAX2 Attributes</b> method (don't invoke on parser); * <b>SAX1 AttributeList</b> method (don't invoke on parser);
*/ */
public String getLocalName (int index) public String getName(int index)
{ {
if (index < 0 || index >= attributesList.size()) return getQName(index);
{ }
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); * <b>SAX1 AttributeList, SAX2 Attributes</b> method
*/ * (don't invoke on parser);
public String getQName (int index) */
{ public String getType(int index)
if (index < 0 || index >= attributesList.size()) {
{ if (index < 0 || index >= attributesList.size())
return null; {
} return null;
Attribute attr = (Attribute) attributesList.get(index); }
return (attr.name == null) ? "" : attr.name; 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</b> method (don't invoke on parser); * <b>SAX1 AttributeList, SAX2 Attributes</b> method
*/ * (don't invoke on parser);
public String getName (int index) */
{ public String getValue(int index)
return getQName(index); {
} if (index < 0 || index >= attributesList.size())
{
return null;
}
return ((Attribute) attributesList.get(index)).value;
}
/** /**
* <b>SAX1 AttributeList, SAX2 Attributes</b> method * <b>SAX2 Attributes</b> method (don't invoke on parser);
* (don't invoke on parser); */
*/ public int getIndex(String uri, String local)
public String getType (int index)
{ {
if (index < 0 || index >= attributesList.size()) int length = getLength();
{
return null; for (int i = 0; i < length; i++)
} {
String type = parser.getAttributeType(elementName, getQName(index)); if (!getURI(i).equals(uri))
if (type == null) {
{ continue;
return "CDATA"; }
} if (getLocalName(i).equals(local))
// ... use DeclHandler.attributeDecl to see enumerations {
if (type == "ENUMERATION") return i;
{ }
return "NMTOKEN"; }
} return -1;
return type; }
}
/** /**
* <b>SAX1 AttributeList, SAX2 Attributes</b> method * <b>SAX2 Attributes</b> method (don't invoke on parser);
* (don't invoke on parser); */
*/ public int getIndex(String xmlName)
public String getValue (int index) {
{ int length = getLength();
if (index < 0 || index >= attributesList.size())
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 String getType(String uri, String local)
{
int index = getIndex(uri, local);
if (index < 0)
{
return null;
}
return getType(index);
}
/** /**
* <b>SAX2 Attributes</b> method (don't invoke on parser); * <b>SAX1 AttributeList, SAX2 Attributes</b> method
*/ * (don't invoke on parser);
public int getIndex (String uri, String local) */
{ public String getType(String xmlName)
int length = getLength(); {
int index = getIndex(xmlName);
if (index < 0)
{
return null;
}
return getType(index);
}
for (int i = 0; i < length; i++) /**
{ * <b>SAX Attributes</b> method (don't invoke on parser);
if (!getURI(i).equals(uri)) */
{ public String getValue(String uri, String local)
continue; {
} int index = getIndex(uri, local);
if (getLocalName(i).equals(local))
{ if (index < 0)
return i; {
} return null;
} }
return -1; return getValue(index);
} }
/**
* <b>SAX1 AttributeList, SAX2 Attributes</b> method
* (don't invoke on parser);
*/
public String getValue(String xmlName)
{
int index = getIndex(xmlName);
if (index < 0)
{
return null;
}
return getValue(index);
}
/** //
* <b>SAX2 Attributes</b> method (don't invoke on parser); // Implementation of org.xml.sax.ext.Attributes2
*/ //
public int getIndex (String xmlName)
{ /** @return false unless the attribute was declared in the DTD.
int length = getLength(); * @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);
}
for (int i = 0; i < length; i++) /** @return false unless the attribute was declared in the DTD.
{ * @throws java.lang.IllegalArgumentException
if (getQName(i).equals(xmlName)) * When the supplied names do not identify an attribute.
{ */
return i; public boolean isDeclared(String qName)
} {
} int index = getIndex(qName);
return -1; if (index < 0)
} {
throw new IllegalArgumentException();
}
String type = parser.getAttributeType(elementName, qName);
return (type != null);
}
/** @return false unless the attribute was declared in the DTD.
* @throws java.lang.IllegalArgumentException
* When the supplied names do not identify an attribute.
*/
public boolean isDeclared(String uri, String localName)
{
int index = getIndex(uri, localName);
return isDeclared(index);
}
/** /**
* <b>SAX2 Attributes</b> method (don't invoke on parser); * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
*/ */
public String getType (String uri, String local) public boolean isSpecified(int index)
{ {
int index = getIndex(uri, local); return ((Attribute) attributesList.get(index)).specified;
}
if (index < 0) /**
{ * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
return null; */
} public boolean isSpecified(String uri, String local)
return getType(index); {
} int index = getIndex (uri, local);
return isSpecified(index);
}
/**
* <b>SAX-ext Attributes2</b> method (don't invoke on parser);
*/
public boolean isSpecified(String xmlName)
{
int index = getIndex (xmlName);
return isSpecified(index);
}
/** //
* <b>SAX1 AttributeList, SAX2 Attributes</b> method // Implementation of org.xml.sax.Locator.
* (don't invoke on parser); //
*/
public String getType (String xmlName)
{
int index = getIndex(xmlName);
if (index < 0) /**
{ * <b>SAX Locator</b> method (don't invoke on parser);
return null; */
} public String getPublicId()
return getType(index); {
} 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); * <b>SAX Locator</b> method (don't invoke on parser);
*/ */
public String getValue (String uri, String local) public int getLineNumber()
{ {
int index = getIndex(uri, local); return parser.getLineNumber();
}
if (index < 0) /**
{ * <b>SAX Locator</b> method (don't invoke on parser);
return null; */
} public int getColumnNumber()
return getValue(index); {
} return parser.getColumnNumber();
}
// adapter between SAX2 content handler and SAX1 document handler callbacks
private static class Adapter
implements ContentHandler
{
private DocumentHandler docHandler;
/** Adapter(DocumentHandler dh)
* <b>SAX1 AttributeList, SAX2 Attributes</b> method
* (don't invoke on parser);
*/
public String getValue (String xmlName)
{ {
int index = getIndex(xmlName); docHandler = dh;
if (index < 0)
{
return null;
}
return getValue(index);
} }
public void setDocumentLocator(Locator l)
//
// 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) docHandler.setDocumentLocator(l);
throw new ArrayIndexOutOfBoundsException ();
String type = parser.getAttributeType(elementName, getQName(index));
return (type != null);
} }
/** @return false unless the attribute was declared in the DTD. public void startDocument()
* @throws java.lang.IllegalArgumentException throws SAXException
* When the supplied names do not identify an attribute.
*/
public boolean isDeclared (String qName)
{ {
int index = getIndex (qName); docHandler.startDocument();
if (index < 0)
throw new IllegalArgumentException ();
String type = parser.getAttributeType(elementName, qName);
return (type != null);
} }
/** @return false unless the attribute was declared in the DTD. public void processingInstruction(String target, String data)
* @throws java.lang.IllegalArgumentException throws SAXException
* When the supplied names do not identify an attribute.
*/
public boolean isDeclared (String uri, String localName)
{ {
int index = getIndex (uri, localName); docHandler.processingInstruction(target, data);
return isDeclared(index);
} }
public void startPrefixMapping(String prefix, String uri)
/**
* <b>SAX-ext Attributes2</b> method (don't invoke on parser);
*/
public boolean isSpecified (int index)
{ {
return ((Attribute) attributesList.get(index)).specified; /* ignored */
} }
/** public void startElement(String namespace,
* <b>SAX-ext Attributes2</b> method (don't invoke on parser); String local,
*/ String name,
public boolean isSpecified (String uri, String local) Attributes attrs)
throws SAXException
{ {
int index = getIndex (uri, local); docHandler.startElement(name, (AttributeList) attrs);
return isSpecified(index);
} }
/** public void characters(char[] buf, int offset, int len)
* <b>SAX-ext Attributes2</b> method (don't invoke on parser); throws SAXException
*/
public boolean isSpecified (String xmlName)
{ {
int index = getIndex (xmlName); docHandler.characters(buf, offset, len);
return isSpecified(index);
} }
public void ignorableWhitespace(char[] buf, int offset, int len)
// throws SAXException
// 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 docHandler.ignorableWhitespace(buf, offset, len);
} }
/** public void skippedEntity(String name)
* <b>SAX Locator</b> method (don't invoke on parser);
*/
public String getSystemId ()
{ {
if (entityStack.empty ()) /* ignored */
return null;
else
return (String) entityStack.peek ();
} }
/** public void endElement(String u, String l, String name)
* <b>SAX Locator</b> method (don't invoke on parser); throws SAXException
*/
public int getLineNumber ()
{ {
return parser.getLineNumber (); docHandler.endElement(name);
} }
/** public void endPrefixMapping(String prefix)
* <b>SAX Locator</b> method (don't invoke on parser);
*/
public int getColumnNumber ()
{ {
return parser.getColumnNumber (); /* ignored */
} }
// adapter between SAX2 content handler and SAX1 document handler callbacks public void endDocument()
private static class Adapter implements ContentHandler throws SAXException
{ {
private DocumentHandler docHandler; docHandler.endDocument();
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 (); }
} }
} }
class Attribute
{
private static class Attribute
{
String name; String name;
String value; String value;
String nameSpace; String nameSpace;
String localName; String localName;
boolean specified; boolean specified;
Attribute(String name, String value, boolean specified) Attribute(String name, String value, boolean specified)
{ {
this.name = name; this.name = name;
this.value = value; this.value = value;
this.nameSpace = ""; this.nameSpace = "";
this.specified = specified; this.specified = specified;
} }
}
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -70,246 +70,305 @@ import gnu.xml.pipeline.ValidationConsumer; ...@@ -70,246 +70,305 @@ import gnu.xml.pipeline.ValidationConsumer;
* *
* @author David Brownell * @author David Brownell
*/ */
public final class XmlReader implements XMLReader public final class XmlReader
implements XMLReader
{ {
private SAXDriver aelfred2 = new SAXDriver ();
private EventFilter filter = new EventFilter ();
private boolean isValidating;
private boolean active;
static class FatalErrorHandler
/** Constructs a SAX Parser. */ extends DefaultHandler2
public XmlReader () {
{ }
public void error(SAXParseException e)
/** throws SAXException
* Constructs a SAX Parser, optionally treating validity errors
* as if they were fatal errors.
*/
public XmlReader (boolean invalidIsFatal)
{
if (invalidIsFatal)
setErrorHandler (new DefaultHandler2 () {
public void error (SAXParseException e)
throws SAXException
{ throw e; }
});
}
/**
* <b>SAX2</b>: Returns the object used to report the logical
* content of an XML document.
*/
public ContentHandler getContentHandler ()
{ return filter.getContentHandler (); }
/**
* <b>SAX2</b>: Assigns the object used to report the logical
* content of an XML document.
* @exception IllegalStateException if called mid-parse
*/
public void setContentHandler (ContentHandler handler)
{ {
if (active) throw e;
throw new IllegalStateException ("already parsing");
filter.setContentHandler (handler);
} }
/** }
* <b>SAX2</b>: Returns the object used to process declarations related
* to notations and unparsed entities. private SAXDriver aelfred2 = new SAXDriver();
*/ private EventFilter filter = new EventFilter();
public DTDHandler getDTDHandler () private boolean isValidating;
{ return filter.getDTDHandler (); } private boolean active;
/** /**
* <b>SAX1</b> Assigns DTD handler * Constructs a SAX Parser.
* @exception IllegalStateException if called mid-parse */
*/ public XmlReader()
public void setDTDHandler (DTDHandler handler) {
{ }
if (active)
throw new IllegalStateException ("already parsing"); /**
filter.setDTDHandler (handler); * Constructs a SAX Parser, optionally treating validity errors
} * as if they were fatal errors.
*/
/** public XmlReader(boolean invalidIsFatal)
* <b>SAX2</b>: Returns the object used when resolving external {
* entities during parsing (both general and parameter entities). if (invalidIsFatal)
*/ {
public EntityResolver getEntityResolver () setErrorHandler(new FatalErrorHandler());
{ return aelfred2.getEntityResolver (); } }
}
/** <b>SAX1</b> Assigns parser's entity resolver */
public void setEntityResolver (EntityResolver handler) /**
{ aelfred2.setEntityResolver (handler); } * <b>SAX2</b>: Returns the object used to report the logical
* content of an XML document.
/** */
* <b>SAX2</b>: Returns the object used to receive callbacks for XML public ContentHandler getContentHandler()
* errors of all levels (fatal, nonfatal, warning); this is never null; {
*/ return filter.getContentHandler();
public ErrorHandler getErrorHandler () }
{ return aelfred2.getErrorHandler (); }
/**
/** * <b>SAX2</b>: Assigns the object used to report the logical
* <b>SAX1</b> Assigns error handler * content of an XML document.
* @exception IllegalStateException if called mid-parse * @exception IllegalStateException if called mid-parse
*/ */
public void setErrorHandler (ErrorHandler handler) public void setContentHandler(ContentHandler handler)
{ {
if (active) if (active)
throw new IllegalStateException ("already parsing"); {
aelfred2.setErrorHandler (handler); throw new IllegalStateException("already parsing");
} }
filter.setContentHandler(handler);
/** }
* <b>SAX2</b>: Assigns the specified property.
* @exception IllegalStateException if called mid-parse /**
*/ * <b>SAX2</b>: Returns the object used to process declarations related
public void setProperty (String propertyId, Object value) * to notations and unparsed entities.
*/
public DTDHandler getDTDHandler()
{
return filter.getDTDHandler();
}
/**
* <b>SAX1</b> Assigns DTD handler
* @exception IllegalStateException if called mid-parse
*/
public void setDTDHandler(DTDHandler handler)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
filter.setDTDHandler(handler);
}
/**
* <b>SAX2</b>: Returns the object used when resolving external
* entities during parsing (both general and parameter entities).
*/
public EntityResolver getEntityResolver()
{
return aelfred2.getEntityResolver();
}
/**
* <b>SAX1</b> Assigns parser's entity resolver
*/
public void setEntityResolver(EntityResolver handler)
{
aelfred2.setEntityResolver(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 aelfred2.getErrorHandler();
}
/**
* <b>SAX1</b> Assigns error handler
* @exception IllegalStateException if called mid-parse
*/
public void setErrorHandler(ErrorHandler handler)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
aelfred2.setErrorHandler(handler);
}
/**
* <b>SAX2</b>: Assigns the specified property.
* @exception IllegalStateException if called mid-parse
*/
public void setProperty(String propertyId, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
if (active) if (active)
throw new IllegalStateException ("already parsing"); {
if (getProperty (propertyId) != value) throw new IllegalStateException("already parsing");
filter.setProperty (propertyId, value); }
} if (getProperty(propertyId) != value)
{
/** filter.setProperty(propertyId, value);
* <b>SAX2</b>: Returns the specified property. }
*/ }
public Object getProperty (String propertyId)
/**
* <b>SAX2</b>: Returns the specified property.
*/
public Object getProperty(String propertyId)
throws SAXNotRecognizedException throws SAXNotRecognizedException
{ {
if ((SAXDriver.PROPERTY + "declaration-handler") if ((SAXDriver.PROPERTY + "declaration-handler").equals(propertyId)
.equals (propertyId) || (SAXDriver.PROPERTY + "lexical-handler").equals(propertyId))
|| (SAXDriver.PROPERTY + "lexical-handler") {
.equals (propertyId)) return filter.getProperty(propertyId);
return filter.getProperty (propertyId); }
throw new SAXNotRecognizedException (propertyId); throw new SAXNotRecognizedException(propertyId);
} }
private void forceValidating () private void forceValidating()
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
aelfred2.setFeature ( aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
SAXDriver.FEATURE + "namespace-prefixes", true);
true); aelfred2.setFeature(SAXDriver.FEATURE + "external-general-entities",
aelfred2.setFeature ( true);
SAXDriver.FEATURE + "external-general-entities", aelfred2.setFeature(SAXDriver.FEATURE + "external-parameter-entities",
true); true);
aelfred2.setFeature ( }
SAXDriver.FEATURE + "external-parameter-entities",
true); /**
} * <b>SAX2</b>: Sets the state of features supported in this parser.
* Note that this parser requires reporting of namespace prefixes when
/** * validating.
* <b>SAX2</b>: Sets the state of features supported in this parser. */
* Note that this parser requires reporting of namespace prefixes when public void setFeature(String featureId, boolean state)
* validating.
*/
public void setFeature (String featureId, boolean state)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
boolean value = getFeature (featureId); boolean value = getFeature(featureId);
if (state == value) if (state == value)
return; {
return;
if ((SAXDriver.FEATURE + "validation").equals (featureId)) { }
if (active)
throw new SAXNotSupportedException ("already parsing"); if ((SAXDriver.FEATURE + "validation").equals(featureId))
if (state) {
forceValidating (); if (active)
isValidating = state; {
} else throw new SAXNotSupportedException("already parsing");
aelfred2.setFeature (featureId, state); }
} if (state)
{
/** forceValidating();
* <b>SAX2</b>: Tells whether this parser supports the specified feature. }
* At this time, this directly parallels the underlying SAXDriver, isValidating = state;
* except that validation is optionally supported. }
* else
* @see SAXDriver {
*/ aelfred2.setFeature(featureId, state);
public boolean getFeature (String featureId) }
}
/**
* <b>SAX2</b>: Tells whether this parser supports the specified feature.
* At this time, this directly parallels the underlying SAXDriver,
* except that validation is optionally supported.
*
* @see SAXDriver
*/
public boolean getFeature(String featureId)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
if ((SAXDriver.FEATURE + "validation").equals (featureId)) if ((SAXDriver.FEATURE + "validation").equals(featureId))
return isValidating; {
return isValidating;
return aelfred2.getFeature (featureId); }
}
return aelfred2.getFeature(featureId);
/** }
* <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 * <b>SAX1</b>: Sets the locale used for diagnostics; currently,
*/ * only locales using the English language are supported.
public void setLocale (Locale locale) * @param locale The locale for which diagnostics will be generated
*/
public void setLocale(Locale locale)
throws SAXException throws SAXException
{ aelfred2.setLocale (locale); } {
aelfred2.setLocale(locale);
}
/** /**
* <b>SAX1</b>: Preferred API to parse an XML document, using a * <b>SAX1</b>: Preferred API to parse an XML document, using a
* system identifier (URI). * system identifier (URI).
*/ */
public void parse (String systemId) public void parse(String systemId)
throws SAXException, IOException throws SAXException, IOException
{ {
parse (new InputSource (systemId)); parse(new InputSource(systemId));
} }
/** /**
* <b>SAX1</b>: Underlying API to parse an XML document, used * <b>SAX1</b>: Underlying API to parse an XML document, used
* directly when no URI is available. When this is invoked, * directly when no URI is available. When this is invoked,
* and the parser is set to validate, some features will be * and the parser is set to validate, some features will be
* automatically reset to appropriate values: for reporting * automatically reset to appropriate values: for reporting
* namespace prefixes, and incorporating external entities. * namespace prefixes, and incorporating external entities.
* *
* @param source The XML input source. * @param source The XML input source.
* *
* @exception IllegalStateException if called mid-parse * @exception IllegalStateException if called mid-parse
* @exception SAXException The handlers may throw any SAXException, * @exception SAXException The handlers may throw any SAXException,
* and the parser normally throws SAXParseException objects. * and the parser normally throws SAXParseException objects.
* @exception IOException IOExceptions are normally through through * @exception IOException IOExceptions are normally through through
* the parser if there are problems reading the source document. * the parser if there are problems reading the source document.
*/ */
public void parse (InputSource source) public void parse(InputSource source)
throws SAXException, IOException throws SAXException, IOException
{ {
EventFilter next; EventFilter next;
boolean nsdecls; boolean nsdecls;
synchronized (aelfred2) { synchronized (aelfred2)
if (active) {
throw new IllegalStateException ("already parsing"); if (active)
active = true; {
} throw new IllegalStateException("already parsing");
}
// set up the output pipeline active = true;
if (isValidating) { }
forceValidating ();
next = new ValidationConsumer (filter); // set up the output pipeline
} else if (isValidating)
next = filter; {
forceValidating();
// connect pipeline and error handler next = new ValidationConsumer(filter);
// don't let _this_ call to bind() affect xmlns* attributes }
nsdecls = aelfred2.getFeature ( else
SAXDriver.FEATURE + "namespace-prefixes"); {
EventFilter.bind (aelfred2, next); next = filter;
if (!nsdecls) }
aelfred2.setFeature (
SAXDriver.FEATURE + "namespace-prefixes", // connect pipeline and error handler
false); // don't let _this_ call to bind() affect xmlns* attributes
nsdecls = aelfred2.getFeature(SAXDriver.FEATURE + "namespace-prefixes");
// parse, clean up EventFilter.bind(aelfred2, next);
try { if (!nsdecls)
aelfred2.parse (source); {
} finally { aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
active = false; false);
} }
}
// parse, clean up
try
{
aelfred2.parse(source);
}
finally
{
active = false;
}
}
} }
...@@ -1686,13 +1686,16 @@ public abstract class DomNode ...@@ -1686,13 +1686,16 @@ public abstract class DomNode
{ {
continue; continue;
} }
if (count < notificationSet.length) if (count >= notificationSet.length)
{ {
notificationSet[count++] = rec; // very simple growth algorithm
int len = Math.max(notificationSet.length, 1);
ListenerRecord[] tmp = new ListenerRecord[len * 2];
System.arraycopy(notificationSet, 0, tmp, 0,
notificationSet.length);
notificationSet = tmp;
} }
else notificationSet[count++] = rec;
// XXX fire up some cheap growth algorithm
throw new RuntimeException("Event notification set size exceeded");
} }
// Notify just those listeners // Notify just those listeners
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment