diff options
Diffstat (limited to 'libjava/classpath/gnu/xml/aelfred2/SAXDriver.java')
-rw-r--r-- | libjava/classpath/gnu/xml/aelfred2/SAXDriver.java | 1609 |
1 files changed, 0 insertions, 1609 deletions
diff --git a/libjava/classpath/gnu/xml/aelfred2/SAXDriver.java b/libjava/classpath/gnu/xml/aelfred2/SAXDriver.java deleted file mode 100644 index 6ce1470..0000000 --- a/libjava/classpath/gnu/xml/aelfred2/SAXDriver.java +++ /dev/null @@ -1,1609 +0,0 @@ -/* SAXDriver.java -- - Copyright (C) 1999,2000,2001,2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. - -Portions derived from code which carried the following notice: - - Copyright (c) 1997, 1998 by Microstar Software Ltd. - - AElfred is free for both commercial and non-commercial use and - redistribution, provided that Microstar's copyright and disclaimer are - retained intact. You are free to modify AElfred for your own use and - to redistribute AElfred with your modifications, provided that the - modifications are clearly documented. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - merchantability or fitness for a particular purpose. Please use it AT - YOUR OWN RISK. -*/ - -package gnu.xml.aelfred2; - -import java.io.*; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Locale; -import java.util.Stack; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; - -import org.xml.sax.*; -import org.xml.sax.ext.*; -import org.xml.sax.helpers.NamespaceSupport; - - -/** - * An enhanced SAX2 version of Microstar's Ælfred XML parser. - * The enhancements primarily relate to significant improvements in - * conformance to the XML specification, and SAX2 support. Performance - * has been improved. See the package level documentation for more - * information. - * - * <table border="1" width='100%' cellpadding='3' cellspacing='0'> - * <tr bgcolor='#ccccff'> - * <th><font size='+1'>Name</font></th> - * <th><font size='+1'>Notes</font></th></tr> - * - * <tr><td colspan=2><center><em>Features ... URL prefix is - * <b>http://xml.org/sax/features/</b></em></center></td></tr> - * - * <tr><td>(URL)/external-general-entities</td> - * <td>Value defaults to <em>true</em></td></tr> - * <tr><td>(URL)/external-parameter-entities</td> - * <td>Value defaults to <em>true</em></td></tr> - * <tr><td>(URL)/is-standalone</td> - * <td>(PRELIMINARY) Returns true iff the document's parsing - * has started (some non-error event after <em>startDocument()</em> - * was reported) and the document's standalone flag is set.</td></tr> - * <tr><td>(URL)/namespace-prefixes</td> - * <td>Value defaults to <em>false</em> (but XML 1.0 names are - * always reported)</td></tr> - * <tr><td>(URL)/lexical-handler/parameter-entities</td> - * <td>Value is fixed at <em>true</em></td></tr> - * <tr><td>(URL)/namespaces</td> - * <td>Value defaults to <em>true</em></td></tr> - * <tr><td>(URL)/resolve-dtd-uris</td> - * <td>(PRELIMINARY) Value defaults to <em>true</em></td></tr> - * <tr><td>(URL)/string-interning</td> - * <td>Value is fixed at <em>true</em></td></tr> - * <tr><td>(URL)/use-attributes2</td> - * <td>(PRELIMINARY) Value is fixed at <em>true</em></td></tr> - * <tr><td>(URL)/use-entity-resolver2</td> - * <td>(PRELIMINARY) Value defaults to <em>true</em></td></tr> - * <tr><td>(URL)/validation</td> - * <td>Value is fixed at <em>false</em></td></tr> - * - * <tr><td colspan=2><center><em>Handler Properties ... URL prefix is - * <b>http://xml.org/sax/properties/</b></em></center></td></tr> - * - * <tr><td>(URL)/declaration-handler</td> - * <td>A declaration handler may be provided. </td></tr> - * <tr><td>(URL)/lexical-handler</td> - * <td>A lexical handler may be provided. </td></tr> - * </table> - * - * <p>This parser currently implements the SAX1 Parser API, but - * it may not continue to do so in the future. - * - * @author Written by David Megginson (version 1.2a from Microstar) - * @author Updated by David Brownell <dbrownell@users.sourceforge.net> - * @see org.xml.sax.Parser - */ -final public class SAXDriver - implements Locator, Attributes2, XMLReader, Parser, AttributeList -{ - - private final DefaultHandler2 base = new DefaultHandler2(); - private XmlParser parser; - - private EntityResolver entityResolver = base; - private EntityResolver2 resolver2 = null; - private ContentHandler contentHandler = base; - private DTDHandler dtdHandler = base; - private ErrorHandler errorHandler = base; - private DeclHandler declHandler = base; - private LexicalHandler lexicalHandler = base; - - private String elementName; - private Stack entityStack; - - // one vector (of object/struct): faster, smaller - private List attributesList; - - private boolean namespaces = true; - private boolean xmlNames = false; - private boolean extGE = true; - private boolean extPE = true; - private boolean resolveAll = true; - private boolean useResolver2 = true; - - // package private to allow (read-only) access in XmlParser - boolean stringInterning = true; - - private int attributeCount; - private boolean attributes; - private String[] nsTemp; - private NamespaceSupport prefixStack; - - // - // Constructor. - // - - /** - * Constructs a SAX Parser. - */ - public SAXDriver() - { - reset(); - } - - private void reset() - { - elementName = null; - entityStack = new Stack(); - attributesList = Collections.synchronizedList(new ArrayList()); - attributeCount = 0; - attributes = false; - nsTemp = new String[3]; - prefixStack = null; - } - - - // - // Implementation of org.xml.sax.Parser. - // - - /** - * <b>SAX1</b>: Sets the locale used for diagnostics; currently, - * only locales using the English language are supported. - * @param locale The locale for which diagnostics will be generated - */ - public void setLocale(Locale locale) - throws SAXException - { - if ("en".equals(locale.getLanguage())) - { - return; - } - throw new SAXException ("AElfred2 only supports English locales."); - } - - /** - * <b>SAX2</b>: Returns the object used when resolving external - * entities during parsing (both general and parameter entities). - */ - public EntityResolver getEntityResolver() - { - return (entityResolver == base) ? null : entityResolver; - } - - /** - * <b>SAX1, SAX2</b>: Set the entity resolver for this parser. - * @param handler The object to receive entity events. - */ - public void setEntityResolver(EntityResolver resolver) - { - if (resolver instanceof EntityResolver2) - { - resolver2 = (EntityResolver2) resolver; - } - else - { - resolver2 = null; - } - if (resolver == null) - { - resolver = base; - } - entityResolver = resolver; - } - - /** - * <b>SAX2</b>: Returns the object used to process declarations related - * to notations and unparsed entities. - */ - public DTDHandler getDTDHandler() - { - return (dtdHandler == base) ? null : dtdHandler; - } - - /** - * <b>SAX1, SAX2</b>: Set the DTD handler for this parser. - * @param handler The object to receive DTD events. - */ - public void setDTDHandler(DTDHandler handler) - { - if (handler == null) - { - handler = base; - } - this.dtdHandler = handler; - } - - - /** - * <b>SAX1</b>: Set the document handler for this parser. If a - * content handler was set, this document handler will supplant it. - * The parser is set to report all XML 1.0 names rather than to - * filter out "xmlns" attributes (the "namespace-prefixes" feature - * is set to true). - * - * @deprecated SAX2 programs should use the XMLReader interface - * and a ContentHandler. - * - * @param handler The object to receive document events. - */ - public void setDocumentHandler(DocumentHandler handler) - { - contentHandler = new Adapter(handler); - xmlNames = true; - } - - /** - * <b>SAX2</b>: Returns the object used to report the logical - * content of an XML document. - */ - public ContentHandler getContentHandler() - { - return (contentHandler == base) ? null : contentHandler; - } - - /** - * <b>SAX2</b>: Assigns the object used to report the logical - * content of an XML document. If a document handler was set, - * this content handler will supplant it (but XML 1.0 style name - * reporting may remain enabled). - */ - public void setContentHandler(ContentHandler handler) - { - if (handler == null) - { - handler = base; - } - contentHandler = handler; - } - - /** - * <b>SAX1, SAX2</b>: Set the error handler for this parser. - * @param handler The object to receive error events. - */ - public void setErrorHandler(ErrorHandler handler) - { - if (handler == null) - { - handler = base; - } - this.errorHandler = handler; - } - - /** - * <b>SAX2</b>: Returns the object used to receive callbacks for XML - * errors of all levels (fatal, nonfatal, warning); this is never null; - */ - public ErrorHandler getErrorHandler() - { - return (errorHandler == base) ? null : errorHandler; - } - - /** - * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly - * when no URI is available. - * If you want anything useful to happen, you should set - * at least one type of handler. - * @param source The XML input source. Don't set 'encoding' unless - * you know for a fact that it's correct. - * @see #setEntityResolver - * @see #setDTDHandler - * @see #setContentHandler - * @see #setErrorHandler - * @exception SAXException The handlers may throw any SAXException, - * and the parser normally throws SAXParseException objects. - * @exception IOException IOExceptions are normally through through - * the parser if there are problems reading the source document. - */ - public void parse(InputSource source) - throws SAXException, IOException - { - synchronized (base) - { - parser = new XmlParser(); - if (namespaces) - { - prefixStack = new NamespaceSupport(); - } - else if (!xmlNames) - { - throw new IllegalStateException(); - } - parser.setHandler(this); - - try - { - Reader r = source.getCharacterStream(); - InputStream in = source.getByteStream(); - - parser.doParse(source.getSystemId(), - source.getPublicId(), - r, - in, - source.getEncoding()); - } - catch (SAXException e) - { - throw e; - } - catch (IOException e) - { - throw e; - } - catch (RuntimeException e) - { - throw e; - } - catch (Exception e) - { - throw new SAXParseException(e.getMessage(), this, e); - } - finally - { - contentHandler.endDocument(); - reset(); - } - } - } - - /** - * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a - * system identifier (URI). - */ - public void parse(String systemId) - throws SAXException, IOException - { - parse(new InputSource(systemId)); - } - - // - // Implementation of SAX2 "XMLReader" interface - // - static final String FEATURE = "http://xml.org/sax/features/"; - static final String PROPERTY = "http://xml.org/sax/properties/"; - - /** - * <b>SAX2</b>: Tells the value of the specified feature flag. - * - * @exception SAXNotRecognizedException thrown if the feature flag - * is neither built in, nor yet assigned. - */ - public boolean getFeature(String featureId) - throws SAXNotRecognizedException, SAXNotSupportedException - { - if ((FEATURE + "validation").equals(featureId)) - { - return false; - } - - // external entities (both types) are optionally included - if ((FEATURE + "external-general-entities").equals(featureId)) - { - return extGE; - } - if ((FEATURE + "external-parameter-entities").equals(featureId)) - { - return extPE; - } - - // element/attribute names are as written in document; no mangling - if ((FEATURE + "namespace-prefixes").equals(featureId)) - { - return xmlNames; - } - - // report element/attribute namespaces? - if ((FEATURE + "namespaces").equals(featureId)) - { - return namespaces; - } - - // all PEs and GEs are reported - if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId)) - { - return true; - } - - // default is true - if ((FEATURE + "string-interning").equals(featureId)) - { - return stringInterning; - } - - // EXTENSIONS 1.1 - - // always returns isSpecified info - if ((FEATURE + "use-attributes2").equals(featureId)) - { - return true; - } - - // meaningful between startDocument/endDocument - if ((FEATURE + "is-standalone").equals(featureId)) - { - if (parser == null) - { - throw new SAXNotSupportedException(featureId); - } - return parser.isStandalone(); - } - - // optionally don't absolutize URIs in declarations - if ((FEATURE + "resolve-dtd-uris").equals(featureId)) - { - return resolveAll; - } - - // optionally use resolver2 interface methods, if possible - if ((FEATURE + "use-entity-resolver2").equals(featureId)) - { - return useResolver2; - } - - throw new SAXNotRecognizedException(featureId); - } - - // package private - DeclHandler getDeclHandler() - { - return declHandler; - } - - // package private - boolean resolveURIs() - { - return resolveAll; - } - - /** - * <b>SAX2</b>: Returns the specified property. - * - * @exception SAXNotRecognizedException thrown if the property value - * is neither built in, nor yet stored. - */ - public Object getProperty(String propertyId) - throws SAXNotRecognizedException - { - if ((PROPERTY + "declaration-handler").equals(propertyId)) - { - return (declHandler == base) ? null : declHandler; - } - - if ((PROPERTY + "lexical-handler").equals(propertyId)) - { - return (lexicalHandler == base) ? null : lexicalHandler; - } - - // unknown properties - throw new SAXNotRecognizedException(propertyId); - } - - /** - * <b>SAX2</b>: Sets the state of feature flags in this parser. Some - * built-in feature flags are mutable. - */ - public void setFeature(String featureId, boolean value) - throws SAXNotRecognizedException, SAXNotSupportedException - { - boolean state; - - // Features with a defined value, we just change it if we can. - state = getFeature (featureId); - - if (state == value) - { - return; - } - if (parser != null) - { - throw new SAXNotSupportedException("not while parsing"); - } - - if ((FEATURE + "namespace-prefixes").equals(featureId)) - { - // in this implementation, this only affects xmlns reporting - xmlNames = value; - // forcibly prevent illegal parser state - if (!xmlNames) - { - namespaces = true; - } - return; - } - - if ((FEATURE + "namespaces").equals(featureId)) - { - namespaces = value; - // forcibly prevent illegal parser state - if (!namespaces) - { - xmlNames = true; - } - return; - } - - if ((FEATURE + "external-general-entities").equals(featureId)) - { - extGE = value; - return; - } - if ((FEATURE + "external-parameter-entities").equals(featureId)) - { - extPE = value; - return; - } - if ((FEATURE + "resolve-dtd-uris").equals(featureId)) - { - resolveAll = value; - return; - } - - if ((FEATURE + "use-entity-resolver2").equals(featureId)) - { - useResolver2 = value; - return; - } - - throw new SAXNotRecognizedException(featureId); - } - - /** - * <b>SAX2</b>: Assigns the specified property. Like SAX1 handlers, - * these may be changed at any time. - */ - public void setProperty(String propertyId, Object value) - throws SAXNotRecognizedException, SAXNotSupportedException - { - // see if the property is recognized - getProperty(propertyId); - - // Properties with a defined value, we just change it if we can. - - if ((PROPERTY + "declaration-handler").equals(propertyId)) - { - if (value == null) - { - declHandler = base; - } - else if (!(value instanceof DeclHandler)) - { - throw new SAXNotSupportedException(propertyId); - } - else - { - declHandler = (DeclHandler) value; - } - return ; - } - - if ((PROPERTY + "lexical-handler").equals(propertyId)) - { - if (value == null) - { - lexicalHandler = base; - } - else if (!(value instanceof LexicalHandler)) - { - throw new SAXNotSupportedException(propertyId); - } - else - { - lexicalHandler = (LexicalHandler) value; - } - return; - } - - throw new SAXNotSupportedException(propertyId); - } - - // - // This is where the driver receives XmlParser callbacks and translates - // them into SAX callbacks. Some more callbacks have been added for - // SAX2 support. - // - - void startDocument() - throws SAXException - { - contentHandler.setDocumentLocator(this); - contentHandler.startDocument(); - attributesList.clear(); - } - - void skippedEntity(String name) - throws SAXException - { - contentHandler.skippedEntity(name); - } - - InputSource getExternalSubset(String name, String baseURI) - throws SAXException, IOException - { - if (resolver2 == null || !useResolver2 || !extPE) - { - return null; - } - return resolver2.getExternalSubset(name, baseURI); - } - - InputSource resolveEntity(boolean isPE, String name, - InputSource in, String baseURI) - throws SAXException, IOException - { - InputSource source; - - // external entities might be skipped - if (isPE && !extPE) - { - return null; - } - if (!isPE && !extGE) - { - return null; - } - - // ... or not - lexicalHandler.startEntity(name); - if (resolver2 != null && useResolver2) - { - source = resolver2.resolveEntity(name, in.getPublicId(), - baseURI, in.getSystemId()); - if (source == null) - { - in.setSystemId(absolutize(baseURI, - in.getSystemId(), false)); - source = in; - } - } - else - { - in.setSystemId(absolutize(baseURI, - in.getSystemId(), - entityResolver != base)); - source = entityResolver.resolveEntity(in.getPublicId(), - in.getSystemId()); - if (source == null) - { - source = in; - } - } - startExternalEntity(name, source.getSystemId(), true); - return source; - } - - // absolutize a system ID relative to the specified base URI - // (temporarily) package-visible for external entity decls - String absolutize(String baseURI, String systemId, boolean nice) - throws MalformedURLException, SAXException - { - // FIXME normalize system IDs -- when? - // - Convert to UTF-8 - // - Map reserved and non-ASCII characters to %HH - - try - { - if (baseURI == null) - { - if (XmlParser.uriWarnings) - { - warn ("No base URI; hope this SYSTEM id is absolute: " - + systemId); - } - return new URL(systemId).toString(); - } - else - { - return new URL(new URL(baseURI), systemId).toString(); - } - } - catch (MalformedURLException e) - { - // Let unknown URI schemes pass through unless we need - // the JVM to map them to i/o streams for us... - if (!nice) - { - throw e; - } - - // sometimes sysids for notations or unparsed entities - // aren't really URIs... - warn("Can't absolutize SYSTEM id: " + e.getMessage()); - return systemId; - } - } - - void startExternalEntity(String name, String systemId, boolean stackOnly) - throws SAXException - { - // The following warning was deleted because the application has the - // option of not setting systemId. Sun's JAXP or Xerces seems to - // ignore this case. - /* - if (systemId == null) - warn ("URI was not reported to parser for entity " + name); - */ - if (!stackOnly) // spliced [dtd] needs startEntity - { - lexicalHandler.startEntity(name); - } - entityStack.push(systemId); - } - - void endExternalEntity(String name) - throws SAXException - { - if (!"[document]".equals(name)) - { - lexicalHandler.endEntity(name); - } - entityStack.pop(); - } - - void startInternalEntity(String name) - throws SAXException - { - lexicalHandler.startEntity(name); - } - - void endInternalEntity(String name) - throws SAXException - { - lexicalHandler.endEntity(name); - } - - void doctypeDecl(String name, String publicId, String systemId) - throws SAXException - { - lexicalHandler.startDTD(name, publicId, systemId); - - // ... the "name" is a declaration and should be given - // to the DeclHandler (but sax2 doesn't). - - // the IDs for the external subset are lexical details, - // as are the contents of the internal subset; but sax2 - // doesn't provide the internal subset "pre-parse" - } - - void notationDecl(String name, String publicId, String systemId, - String baseUri) - throws SAXException - { - try - { - dtdHandler.notationDecl(name, publicId, - (resolveAll && systemId != null) - ? absolutize(baseUri, systemId, true) - : systemId); - } - catch (IOException e) - { - // "can't happen" - throw new SAXParseException(e.getMessage(), this, e); - } - } - - void unparsedEntityDecl(String name, String publicId, String systemId, - String baseUri, String notation) - throws SAXException - { - try - { - dtdHandler.unparsedEntityDecl(name, publicId, - resolveAll - ? absolutize(baseUri, systemId, true) - : systemId, - notation); - } - catch (IOException e) - { - // "can't happen" - throw new SAXParseException(e.getMessage(), this, e); - } - } - - void endDoctype() - throws SAXException - { - lexicalHandler.endDTD(); - } - - private void declarePrefix(String prefix, String uri) - throws SAXException - { - int index = uri.indexOf(':'); - - // many versions of nwalsh docbook stylesheets - // have bogus URLs; so this can't be an error... - if (index < 1 && uri.length() != 0) - { - warn("relative URI for namespace: " + uri); - } - - // FIXME: char [0] must be ascii alpha; chars [1..index] - // must be ascii alphanumeric or in "+-." [RFC 2396] - - //Namespace Constraints - //name for xml prefix must be http://www.w3.org/XML/1998/namespace - boolean prefixEquality = prefix.equals("xml"); - boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace"); - if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality)) - { - fatal("xml is by definition bound to the namespace name " + - "http://www.w3.org/XML/1998/namespace"); - } - - //xmlns prefix declaration is illegal but xml prefix declaration is llegal... - if (prefixEquality && uriEquality) - { - return; - } - - //name for xmlns prefix must be http://www.w3.org/2000/xmlns/ - prefixEquality = prefix.equals("xmlns"); - uriEquality = uri.equals("http://www.w3.org/2000/xmlns/"); - if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality)) - { - fatal("http://www.w3.org/2000/xmlns/ is by definition bound" + - " to prefix xmlns"); - } - - //even if the uri is http://www.w3.org/2000/xmlns/ - // it is illegal to declare it - if (prefixEquality && uriEquality) - { - fatal ("declaring the xmlns prefix is illegal"); - } - - uri = uri.intern(); - prefixStack.declarePrefix(prefix, uri); - contentHandler.startPrefixMapping(prefix, uri); - } - - void attribute(String qname, String value, boolean isSpecified) - throws SAXException - { - if (!attributes) - { - attributes = true; - if (namespaces) - { - prefixStack.pushContext(); - } - } - - // process namespace decls immediately; - // then maybe forget this as an attribute - if (namespaces) - { - int index; - - // default NS declaration? - if (stringInterning) - { - if ("xmlns" == qname) - { - declarePrefix("", value); - if (!xmlNames) - { - return; - } - } - // NS prefix declaration? - else if ((index = qname.indexOf(':')) == 5 - && qname.startsWith("xmlns")) - { - String prefix = qname.substring(6); - - if (prefix.equals("")) - { - fatal("missing prefix " + - "in namespace declaration attribute"); - } - if (value.length() == 0) - { - verror("missing URI in namespace declaration attribute: " - + qname); - } - else - { - declarePrefix(prefix, value); - } - if (!xmlNames) - { - return; - } - } - } - else - { - if ("xmlns".equals(qname)) - { - declarePrefix("", value); - if (!xmlNames) - { - return; - } - } - // NS prefix declaration? - else if ((index = qname.indexOf(':')) == 5 - && qname.startsWith("xmlns")) - { - String prefix = qname.substring(6); - - if (value.length() == 0) - { - verror("missing URI in namespace decl attribute: " - + qname); - } - else - { - declarePrefix(prefix, value); - } - if (!xmlNames) - { - return; - } - } - } - } - // remember this attribute ... - attributeCount++; - - // attribute type comes from querying parser's DTD records - attributesList.add(new Attribute(qname, value, isSpecified)); - - } - - void startElement(String elname) - throws SAXException - { - ContentHandler handler = contentHandler; - - // - // NOTE: this implementation of namespace support adds something - // like six percent to parsing CPU time, in a large (~50 MB) - // document that doesn't use namespaces at all. (Measured by PC - // sampling, with a bug where endElement processing was omitted.) - // [Measurement referred to older implementation, older JVM ...] - // - // It ought to become notably faster in such cases. Most - // costs are the prefix stack calling Hashtable.get() (2%), - // String.hashCode() (1.5%) and about 1.3% each for pushing - // the context, and two chunks of name processing. - // - - if (!attributes) - { - if (namespaces) - { - prefixStack.pushContext(); - } - } - else if (namespaces) - { - - // now we can patch up namespace refs; we saw all the - // declarations, so now we'll do the Right Thing - Iterator itt = attributesList.iterator(); - while (itt.hasNext()) - { - Attribute attribute = (Attribute) itt.next(); - String qname = attribute.name; - int index; - - // default NS declaration? - if (stringInterning) - { - if ("xmlns" == qname) - { - continue; - } - } - else - { - if ("xmlns".equals(qname)) - { - continue; - } - } - //Illegal in the new Namespaces Draft - //should it be only in 1.1 docs?? - if (qname.equals (":")) - { - fatal("namespace names consisting of a single colon " + - "character are invalid"); - } - index = qname.indexOf(':'); - - // NS prefix declaration? - if (index == 5 && qname.startsWith("xmlns")) - { - continue; - } - - // it's not a NS decl; patch namespace info items - if (prefixStack.processName(qname, nsTemp, true) == null) - { - fatal("undeclared attribute prefix in: " + qname); - } - else - { - attribute.nameSpace = nsTemp[0]; - attribute.localName = nsTemp[1]; - } - } - } - - // save element name so attribute callbacks work - elementName = elname; - if (namespaces) - { - if (prefixStack.processName(elname, nsTemp, false) == null) - { - fatal("undeclared element prefix in: " + elname); - nsTemp[0] = nsTemp[1] = ""; - } - handler.startElement(nsTemp[0], nsTemp[1], elname, this); - } - else - { - handler.startElement("", "", elname, this); - } - // elementName = null; - - // elements with no attributes are pretty common! - if (attributes) - { - attributesList.clear(); - attributeCount = 0; - attributes = false; - } - } - - void endElement(String elname) - throws SAXException - { - ContentHandler handler = contentHandler; - - if (!namespaces) - { - handler.endElement("", "", elname); - return; - } - prefixStack.processName(elname, nsTemp, false); - handler.endElement(nsTemp[0], nsTemp[1], elname); - - Enumeration prefixes = prefixStack.getDeclaredPrefixes(); - - while (prefixes.hasMoreElements()) - { - handler.endPrefixMapping((String) prefixes.nextElement()); - } - prefixStack.popContext(); - } - - void startCDATA() - throws SAXException - { - lexicalHandler.startCDATA(); - } - - void charData(char[] ch, int start, int length) - throws SAXException - { - contentHandler.characters(ch, start, length); - } - - void endCDATA() - throws SAXException - { - lexicalHandler.endCDATA(); - } - - void ignorableWhitespace(char[] ch, int start, int length) - throws SAXException - { - contentHandler.ignorableWhitespace(ch, start, length); - } - - void processingInstruction(String target, String data) - throws SAXException - { - contentHandler.processingInstruction(target, data); - } - - void comment(char[] ch, int start, int length) - throws SAXException - { - if (lexicalHandler != base) - { - lexicalHandler.comment(ch, start, length); - } - } - - void fatal(String message) - throws SAXException - { - SAXParseException fatal; - - fatal = new SAXParseException(message, this); - errorHandler.fatalError(fatal); - - // Even if the application can continue ... we can't! - throw fatal; - } - - // We can safely report a few validity errors that - // make layered SAX2 DTD validation more conformant - void verror(String message) - throws SAXException - { - SAXParseException err; - - err = new SAXParseException(message, this); - errorHandler.error(err); - } - - void warn(String message) - throws SAXException - { - SAXParseException err; - - err = new SAXParseException(message, this); - errorHandler.warning(err); - } - - // - // Implementation of org.xml.sax.Attributes. - // - - /** - * <b>SAX1 AttributeList, SAX2 Attributes</b> method - * (don't invoke on parser); - */ - public int getLength() - { - return attributesList.size(); - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public String getURI(int index) - { - if (index < 0 || index >= attributesList.size()) - { - return null; - } - return ((Attribute) attributesList.get(index)).nameSpace; - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public String getLocalName(int index) - { - if (index < 0 || index >= attributesList.size()) - { - return null; - } - Attribute attr = (Attribute) attributesList.get(index); - // FIXME attr.localName is sometimes null, why? - if (namespaces && attr.localName == null) - { - // XXX fix this here for now - int ci = attr.name.indexOf(':'); - attr.localName = (ci == -1) ? attr.name : - attr.name.substring(ci + 1); - } - return (attr.localName == null) ? "" : attr.localName; - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public String getQName(int index) - { - if (index < 0 || index >= attributesList.size()) - { - return null; - } - Attribute attr = (Attribute) attributesList.get(index); - return (attr.name == null) ? "" : attr.name; - } - - /** - * <b>SAX1 AttributeList</b> method (don't invoke on parser); - */ - public String getName(int index) - { - return getQName(index); - } - - /** - * <b>SAX1 AttributeList, SAX2 Attributes</b> method - * (don't invoke on parser); - */ - public String getType(int index) - { - if (index < 0 || index >= attributesList.size()) - { - return null; - } - String type = parser.getAttributeType(elementName, getQName(index)); - if (type == null) - { - return "CDATA"; - } - // ... use DeclHandler.attributeDecl to see enumerations - if (type == "ENUMERATION") - { - return "NMTOKEN"; - } - return type; - } - - /** - * <b>SAX1 AttributeList, SAX2 Attributes</b> method - * (don't invoke on parser); - */ - public String getValue(int index) - { - if (index < 0 || index >= attributesList.size()) - { - return null; - } - return ((Attribute) attributesList.get(index)).value; - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public int getIndex(String uri, String local) - { - int length = getLength(); - - for (int i = 0; i < length; i++) - { - if (!getURI(i).equals(uri)) - { - continue; - } - if (getLocalName(i).equals(local)) - { - return i; - } - } - return -1; - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public int getIndex(String xmlName) - { - int length = getLength(); - - for (int i = 0; i < length; i++) - { - if (getQName(i).equals(xmlName)) - { - return i; - } - } - return -1; - } - - /** - * <b>SAX2 Attributes</b> method (don't invoke on parser); - */ - public String getType(String uri, String local) - { - int index = getIndex(uri, local); - - if (index < 0) - { - return null; - } - return getType(index); - } - - /** - * <b>SAX1 AttributeList, SAX2 Attributes</b> method - * (don't invoke on parser); - */ - public String getType(String xmlName) - { - int index = getIndex(xmlName); - - if (index < 0) - { - return null; - } - return getType(index); - } - - /** - * <b>SAX Attributes</b> method (don't invoke on parser); - */ - public String getValue(String uri, String local) - { - int index = getIndex(uri, local); - - if (index < 0) - { - return null; - } - return getValue(index); - } - - /** - * <b>SAX1 AttributeList, SAX2 Attributes</b> method - * (don't invoke on parser); - */ - public String getValue(String xmlName) - { - int index = getIndex(xmlName); - - if (index < 0) - { - return null; - } - return getValue(index); - } - - // - // Implementation of org.xml.sax.ext.Attributes2 - // - - /** @return false unless the attribute was declared in the DTD. - * @throws java.lang.ArrayIndexOutOfBoundsException - * When the supplied index does not identify an attribute. - */ - public boolean isDeclared(int index) - { - if (index < 0 || index >= attributeCount) - { - throw new ArrayIndexOutOfBoundsException(); - } - String type = parser.getAttributeType(elementName, getQName(index)); - return (type != null); - } - - /** @return false unless the attribute was declared in the DTD. - * @throws java.lang.IllegalArgumentException - * When the supplied names do not identify an attribute. - */ - public boolean isDeclared(String qName) - { - int index = getIndex(qName); - if (index < 0) - { - throw new IllegalArgumentException(); - } - String type = parser.getAttributeType(elementName, qName); - return (type != null); - } - - /** @return false unless the attribute was declared in the DTD. - * @throws java.lang.IllegalArgumentException - * When the supplied names do not identify an attribute. - */ - public boolean isDeclared(String uri, String localName) - { - int index = getIndex(uri, localName); - return isDeclared(index); - } - - /** - * <b>SAX-ext Attributes2</b> method (don't invoke on parser); - */ - public boolean isSpecified(int index) - { - return ((Attribute) attributesList.get(index)).specified; - } - - /** - * <b>SAX-ext Attributes2</b> method (don't invoke on parser); - */ - public boolean isSpecified(String uri, String local) - { - int index = getIndex (uri, local); - return isSpecified(index); - } - - /** - * <b>SAX-ext Attributes2</b> method (don't invoke on parser); - */ - public boolean isSpecified(String xmlName) - { - int index = getIndex (xmlName); - return isSpecified(index); - } - - // - // Implementation of org.xml.sax.Locator. - // - - /** - * <b>SAX Locator</b> method (don't invoke on parser); - */ - public String getPublicId() - { - return null; // FIXME track public IDs too - } - - /** - * <b>SAX Locator</b> method (don't invoke on parser); - */ - public String getSystemId() - { - if (entityStack.empty()) - { - return null; - } - else - { - return (String) entityStack.peek(); - } - } - - /** - * <b>SAX Locator</b> method (don't invoke on parser); - */ - public int getLineNumber() - { - return parser.getLineNumber(); - } - - /** - * <b>SAX Locator</b> method (don't invoke on parser); - */ - public int getColumnNumber() - { - return parser.getColumnNumber(); - } - - // adapter between SAX2 content handler and SAX1 document handler callbacks - private static class Adapter - implements ContentHandler - { - - private DocumentHandler docHandler; - - Adapter(DocumentHandler dh) - { - docHandler = dh; - } - - public void setDocumentLocator(Locator l) - { - docHandler.setDocumentLocator(l); - } - - public void startDocument() - throws SAXException - { - docHandler.startDocument(); - } - - public void processingInstruction(String target, String data) - throws SAXException - { - docHandler.processingInstruction(target, data); - } - - public void startPrefixMapping(String prefix, String uri) - { - /* ignored */ - } - - public void startElement(String namespace, - String local, - String name, - Attributes attrs) - throws SAXException - { - docHandler.startElement(name, (AttributeList) attrs); - } - - public void characters(char[] buf, int offset, int len) - throws SAXException - { - docHandler.characters(buf, offset, len); - } - - public void ignorableWhitespace(char[] buf, int offset, int len) - throws SAXException - { - docHandler.ignorableWhitespace(buf, offset, len); - } - - public void skippedEntity(String name) - { - /* ignored */ - } - - public void endElement(String u, String l, String name) - throws SAXException - { - docHandler.endElement(name); - } - - public void endPrefixMapping(String prefix) - { - /* ignored */ - } - - public void endDocument() - throws SAXException - { - docHandler.endDocument(); - } - } - - private static class Attribute - { - - String name; - String value; - String nameSpace; - String localName; - boolean specified; - - Attribute(String name, String value, boolean specified) - { - this.name = name; - this.value = value; - this.nameSpace = ""; - this.specified = specified; - } - - } - -} |