- /*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2001-2004 The Apache Software Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- package com.sun.org.apache.xerces.internal.parsers;
- import java.io.IOException;
- import java.util.Locale;
- import com.sun.org.apache.xerces.internal.impl.Constants;
- import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
- import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
- import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper;
- import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
- import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
- import com.sun.org.apache.xerces.internal.util.SymbolHash;
- import com.sun.org.apache.xerces.internal.util.XMLSymbols;
- import com.sun.org.apache.xerces.internal.xni.Augmentations;
- import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
- import com.sun.org.apache.xerces.internal.xni.QName;
- import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
- import com.sun.org.apache.xerces.internal.xni.XMLLocator;
- import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
- import com.sun.org.apache.xerces.internal.xni.XMLString;
- import com.sun.org.apache.xerces.internal.xni.XNIException;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
- import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
- import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
- import org.xml.sax.AttributeList;
- import org.xml.sax.Attributes;
- import org.xml.sax.ext.Attributes2;
- import org.xml.sax.ContentHandler;
- import org.xml.sax.DTDHandler;
- import org.xml.sax.DocumentHandler;
- import org.xml.sax.EntityResolver;
- import org.xml.sax.ErrorHandler;
- import org.xml.sax.InputSource;
- import org.xml.sax.Locator;
- import org.xml.sax.ext.Locator2Impl;
- import org.xml.sax.ext.Locator2;
- import org.xml.sax.Parser;
- import org.xml.sax.SAXException;
- import org.xml.sax.SAXNotRecognizedException;
- import org.xml.sax.SAXNotSupportedException;
- import org.xml.sax.SAXParseException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.ext.DeclHandler;
- import org.xml.sax.ext.EntityResolver2;
- import org.xml.sax.ext.LexicalHandler;
- import org.xml.sax.helpers.LocatorImpl;
- /**
- * This is the base class of all SAX parsers. It implements both the
- * SAX1 and SAX2 parser functionality, while the actual pipeline is
- * defined in the parser configuration.
- *
- * @author Arnaud Le Hors, IBM
- * @author Andy Clark, IBM
- *
- * @version $Id: AbstractSAXParser.java,v 1.54 2004/04/07 15:42:05 mrglavas Exp $
- */
- public abstract class AbstractSAXParser
- extends AbstractXMLDocumentParser
- implements PSVIProvider, // PSVI
- Parser, XMLReader // SAX1, SAX2
- {
- //
- // Constants
- //
- // features
- /** Feature identifier: namespaces. */
- protected static final String NAMESPACES =
- Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
- /** Feature identifier: namespace prefixes. */
- protected static final String NAMESPACE_PREFIXES =
- Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
- /** Feature id: string interning. */
- protected static final String STRING_INTERNING =
- Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
- /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
- // this is not meant to be a recognized feature, but we need it here to use
- // if it is already a recognized feature for the pipeline
- protected static final String ALLOW_UE_AND_NOTATION_EVENTS =
- Constants.SAX_FEATURE_PREFIX + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
- /** Recognized features. */
- private static final String[] RECOGNIZED_FEATURES = {
- NAMESPACES,
- NAMESPACE_PREFIXES,
- STRING_INTERNING,
- };
- // properties
- /** Property id: lexical handler. */
- protected static final String LEXICAL_HANDLER =
- Constants.SAX_PROPERTY_PREFIX + Constants.LEXICAL_HANDLER_PROPERTY;
- /** Property id: declaration handler. */
- protected static final String DECLARATION_HANDLER =
- Constants.SAX_PROPERTY_PREFIX + Constants.DECLARATION_HANDLER_PROPERTY;
- /** Property id: DOM node. */
- protected static final String DOM_NODE =
- Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY;
- /** Recognized properties. */
- private static final String[] RECOGNIZED_PROPERTIES = {
- LEXICAL_HANDLER,
- DECLARATION_HANDLER,
- DOM_NODE,
- };
- //
- // Data
- //
- // features
- /** Namespaces. */
- protected boolean fNamespaces;
- /** Namespace prefixes. */
- protected boolean fNamespacePrefixes = false;
- /** Lexical handler parameter entities. */
- protected boolean fLexicalHandlerParameterEntities = true;
- // parser handlers
- /** Content handler. */
- protected ContentHandler fContentHandler;
- /** Document handler. */
- protected DocumentHandler fDocumentHandler;
- /** Namespace context */
- protected NamespaceContext fNamespaceContext;
- /** DTD handler. */
- protected org.xml.sax.DTDHandler fDTDHandler;
- /** Decl handler. */
- protected DeclHandler fDeclHandler;
- /** Lexical handler. */
- protected LexicalHandler fLexicalHandler;
- protected QName fQName = new QName();
- protected boolean resolve_dtd_uris = true;
- protected boolean startDocumentCalled = false;
- protected boolean resolverType = true;
- protected boolean locatorType = false;
- protected boolean attributeType = true;
- protected boolean isStandalone = false;
- // state
- /**
- * True if a parse is in progress. This state is needed because
- * some features/properties cannot be set while parsing (e.g.
- * validation and namespaces).
- */
- protected boolean fParseInProgress = false;
- // track the version of the document being parsed
- protected String fVersion;
- // temp vars
- private final AttributesProxy fAttributesProxy = new AttributesProxy();
- private Augmentations fAugmentations = null;
- // temporary buffer for sending normalized values
- // REVISIT: what should be the size of the buffer?
- private static final int BUFFER_SIZE = 20;
- private char[] fCharBuffer = new char[BUFFER_SIZE];
- // allows us to keep track of whether an attribute has
- // been declared twice, so that we can avoid exposing the
- // second declaration to any registered DeclHandler
- protected SymbolHash fDeclaredAttrs = null;
- //
- // Constructors
- //
- /** Default constructor. */
- protected AbstractSAXParser(XMLParserConfiguration config) {
- super(config);
- config.addRecognizedFeatures(RECOGNIZED_FEATURES);
- config.addRecognizedProperties(RECOGNIZED_PROPERTIES);
- try {
- config.setFeature(ALLOW_UE_AND_NOTATION_EVENTS, false);
- }
- catch (XMLConfigurationException e) {
- // it wasn't a recognized feature, so we don't worry about it
- }
- } // <init>(XMLParserConfiguration)
- //
- // XMLDocumentHandler methods
- //
- /**
- * The start of the document.
- *
- * @param locator The document locator, or null if the document
- * location cannot be reported during the parsing
- * of this document. However, it is <em>strongly</em>
- * recommended that a locator be supplied that can
- * at least report the system identifier of the
- * document.
- * @param encoding The auto-detected IANA encoding name of the entity
- * stream. This value will be null in those situations
- * where the entity encoding is not auto-detected (e.g.
- * internal entities or a document entity that is
- * parsed from a java.io.Reader).
- * @param namespaceContext
- * The namespace context in effect at the
- * start of this document.
- * This object represents the current context.
- * Implementors of this class are responsible
- * for copying the namespace bindings from the
- * the current context (and its parent contexts)
- * if that information is important.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startDocument(XMLLocator locator, String encoding,
- NamespaceContext namespaceContext, Augmentations augs)
- throws XNIException {
- fNamespaceContext = namespaceContext;
- startDocumentCalled = true;
- try {
- // SAX1
- if (fDocumentHandler != null) {
- if (locator != null) {
- fDocumentHandler.setDocumentLocator(new LocatorProxy(locator));
- }
- fDocumentHandler.startDocument();
- }
- // SAX2
- if (fContentHandler != null) {
- if (locator != null) {
- locatorType = true;
- fContentHandler.setDocumentLocator(new LocatorProxy(locator));
- }
- fContentHandler.startDocument();
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // startDocument(locator,encoding,augs)
- /**
- * Notifies of the presence of an XMLDecl line in the document. If
- * present, this method will be called immediately following the
- * startDocument call.
- *
- * @param version The XML version.
- * @param encoding The IANA encoding name of the document, or null if
- * not specified.
- * @param standalone The standalone value, or null if not specified.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void xmlDecl(String version, String encoding, String standalone, Augmentations augs)
- throws XNIException {
- // the version need only be set once; if
- // document's XML 1.0|1.1, that's how it'll stay
- fVersion = version;
- if(standalone != null && standalone.equalsIgnoreCase("yes"))
- isStandalone = true;
- else
- isStandalone = false;
- } // xmlDecl(String,String,String)
- /**
- * Notifies of the presence of the DOCTYPE line in the document.
- *
- * @param rootElement The name of the root element.
- * @param publicId The public identifier if an external DTD or null
- * if the external DTD is specified using SYSTEM.
- * @param systemId The system identifier if an external DTD, null
- * otherwise.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void doctypeDecl(String rootElement,
- String publicId, String systemId, Augmentations augs)
- throws XNIException {
- fInDTD = true;
- try {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.startDTD(rootElement, publicId, systemId);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- // is there a DeclHandler?
- if(fDeclHandler != null) {
- fDeclaredAttrs = new SymbolHash();
- }
- } // doctypeDecl(String,String,String)
- /**
- * This method notifies of the start of an entity. The DTD has the
- * pseudo-name of "[dtd]" parameter entity names start with '%'; and
- * general entity names are just the entity name.
- * <p>
- * <strong>Note:</strong> Since the document is an entity, the handler
- * will be notified of the start of the document entity by calling the
- * startEntity method with the entity name "[xml]" <em>before</em> calling
- * the startDocument method. When exposing entity boundaries through the
- * SAX API, the document entity is never reported, however.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param name The name of the entity.
- * @param identifier The resource identifier.
- * @param encoding The auto-detected IANA encoding name of the entity
- * stream. This value will be null in those situations
- * where the entity encoding is not auto-detected (e.g.
- * internal parameter entities).
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startGeneralEntity(String name, XMLResourceIdentifier identifier,
- String encoding, Augmentations augs)
- throws XNIException {
- try {
- // Only report startEntity if this entity was actually read.
- if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
- // report skipped entity to content handler
- if (fContentHandler != null) {
- fContentHandler.skippedEntity(name);
- }
- }
- else {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.startEntity(name);
- }
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // startGeneralEntity(String,String,String,String,String)
- /**
- * This method notifies the end of an entity. The DTD has the pseudo-name
- * of "[dtd]" parameter entity names start with '%'; and general entity
- * names are just the entity name.
- * <p>
- * <strong>Note:</strong> Since the document is an entity, the handler
- * will be notified of the end of the document entity by calling the
- * endEntity method with the entity name "[xml]" <em>after</em> calling
- * the endDocument method. When exposing entity boundaries through the
- * SAX API, the document entity is never reported, however.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param name The name of the entity.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
- try {
- // Only report endEntity if this entity was actually read.
- if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.endEntity(name);
- }
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // endEntity(String)
- /**
- * The start of an element. If the document specifies the start element
- * by using an empty tag, then the startElement method will immediately
- * be followed by the endElement method, with no intervening methods.
- *
- * @param element The name of the element.
- * @param attributes The element attributes.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
- throws XNIException {
- try {
- // SAX1
- if (fDocumentHandler != null) {
- // REVISIT: should we support schema-normalized-value for SAX1 events
- //
- fAttributesProxy.setAttributes(attributes);
- fDocumentHandler.startElement(element.rawname, fAttributesProxy);
- }
- // SAX2
- if (fContentHandler != null) {
- if (fNamespaces) {
- // send prefix mapping events
- startNamespaceMapping();
- // REVISIT: It should not be necessary to iterate over the attribute
- // list when the set of [namespace attributes] is empty for this
- // element. This should be computable from the NamespaceContext, but
- // since we currently don't report the mappings for the xml prefix
- // we cannot use the declared prefix count for the current context
- // to skip this section. -- mrglavas
- int len = attributes.getLength();
- for (int i = len - 1; i >= 0; --i) {
- attributes.getName(i, fQName);
- if ((fQName.prefix == XMLSymbols.PREFIX_XMLNS) ||
- (fQName.rawname == XMLSymbols.PREFIX_XMLNS)) {
- if (!fNamespacePrefixes) {
- // remove namespace declaration attributes
- attributes.removeAttributeAt(i);
- }
- else {
- // localpart should be empty string as per SAX documentation:
- // http://www.saxproject.org/?selected=namespaces
- fQName.prefix = "";
- fQName.uri = "";
- fQName.localpart = "";
- attributes.setName(i, fQName);
- }
- }
- }
- }
- fAugmentations = augs;
- String uri = element.uri != null ? element.uri : "";
- String localpart = fNamespaces ? element.localpart : "";
- fAttributesProxy.setAttributes(attributes);
- fContentHandler.startElement(uri, localpart, element.rawname,
- fAttributesProxy);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // startElement(QName,XMLAttributes)
- /**
- * Character content.
- *
- * @param text The content.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void characters(XMLString text, Augmentations augs) throws XNIException {
- // if type is union (XML Schema) it is possible that we receive
- // character call with empty data
- if (text.length == 0) {
- return;
- }
- try {
- // SAX1
- if (fDocumentHandler != null) {
- // REVISIT: should we support schema-normalized-value for SAX1 events
- //
- fDocumentHandler.characters(text.ch, text.offset, text.length);
- }
- // SAX2
- if (fContentHandler != null) {
- fContentHandler.characters(text.ch, text.offset, text.length);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // characters(XMLString)
- /**
- * Ignorable whitespace. For this method to be called, the document
- * source must have some way of determining that the text containing
- * only whitespace characters should be considered ignorable. For
- * example, the validator can determine if a length of whitespace
- * characters in the document are ignorable based on the element
- * content model.
- *
- * @param text The ignorable whitespace.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
- try {
- // SAX1
- if (fDocumentHandler != null) {
- fDocumentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
- }
- // SAX2
- if (fContentHandler != null) {
- fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // ignorableWhitespace(XMLString)
- /**
- * The end of an element.
- *
- * @param element The name of the element.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endElement(QName element, Augmentations augs) throws XNIException {
- try {
- // SAX1
- if (fDocumentHandler != null) {
- fDocumentHandler.endElement(element.rawname);
- }
- // SAX2
- if (fContentHandler != null) {
- fAugmentations = augs;
- String uri = element.uri != null ? element.uri : "";
- String localpart = fNamespaces ? element.localpart : "";
- fContentHandler.endElement(uri, localpart,
- element.rawname);
- if (fNamespaces) {
- endNamespaceMapping();
- }
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // endElement(QName)
- /**
- * The start of a CDATA section.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startCDATA(Augmentations augs) throws XNIException {
- try {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.startCDATA();
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // startCDATA()
- /**
- * The end of a CDATA section.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endCDATA(Augmentations augs) throws XNIException {
- try {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.endCDATA();
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // endCDATA()
- /**
- * A comment.
- *
- * @param text The text in the comment.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by application to signal an error.
- */
- public void comment(XMLString text, Augmentations augs) throws XNIException {
- try {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.comment(text.ch, 0, text.length);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // comment(XMLString)
- /**
- * A processing instruction. Processing instructions consist of a
- * target name and, optionally, text data. The data is only meaningful
- * to the application.
- * <p>
- * Typically, a processing instruction's data will contain a series
- * of pseudo-attributes. These pseudo-attributes follow the form of
- * element attributes but are <strong>not</strong> parsed or presented
- * to the application as anything other than text. The application is
- * responsible for parsing the data.
- *
- * @param target The target.
- * @param data The data or null if none specified.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void processingInstruction(String target, XMLString data, Augmentations augs)
- throws XNIException {
- //
- // REVISIT - I keep running into SAX apps that expect
- // null data to be an empty string, which is contrary
- // to the comment for this method in the SAX API.
- //
- try {
- // SAX1
- if (fDocumentHandler != null) {
- fDocumentHandler.processingInstruction(target,
- data.toString());
- }
- // SAX2
- if (fContentHandler != null) {
- fContentHandler.processingInstruction(target, data.toString());
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // processingInstruction(String,XMLString)
- /**
- * The end of the document.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endDocument(Augmentations augs) throws XNIException {
- try {
- // SAX1
- if (fDocumentHandler != null) {
- fDocumentHandler.endDocument();
- }
- // SAX2
- if (fContentHandler != null) {
- fContentHandler.endDocument();
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // endDocument()
- //
- // XMLDTDHandler methods
- //
- /**
- * The start of the DTD external subset.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startExternalSubset(XMLResourceIdentifier identifier,
- Augmentations augs) throws XNIException {
- startParameterEntity("[dtd]", null, null, augs);
- }
- /**
- * The end of the DTD external subset.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endExternalSubset(Augmentations augs) throws XNIException {
- endParameterEntity("[dtd]", augs);
- }
- /**
- * This method notifies of the start of parameter entity. The DTD has the
- * pseudo-name of "[dtd]" parameter entity names start with '%'; and
- * general entity names are just the entity name.
- * <p>
- * <strong>Note:</strong> Since the document is an entity, the handler
- * will be notified of the start of the document entity by calling the
- * startEntity method with the entity name "[xml]" <em>before</em> calling
- * the startDocument method. When exposing entity boundaries through the
- * SAX API, the document entity is never reported, however.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param name The name of the parameter entity.
- * @param identifier The resource identifier.
- * @param encoding The auto-detected IANA encoding name of the entity
- * stream. This value will be null in those situations
- * where the entity encoding is not auto-detected (e.g.
- * internal parameter entities).
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void startParameterEntity(String name,
- XMLResourceIdentifier identifier,
- String encoding, Augmentations augs)
- throws XNIException {
- try {
- // Only report startEntity if this entity was actually read.
- if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
- // report skipped entity to content handler
- if (fContentHandler != null) {
- fContentHandler.skippedEntity(name);
- }
- }
- else {
- // SAX2 extension
- if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
- fLexicalHandler.startEntity(name);
- }
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // startParameterEntity(String,identifier,String,Augmentation)
- /**
- * This method notifies the end of an entity. The DTD has the pseudo-name
- * of "[dtd]" parameter entity names start with '%'; and general entity
- * names are just the entity name.
- * <p>
- * <strong>Note:</strong> Since the document is an entity, the handler
- * will be notified of the end of the document entity by calling the
- * endEntity method with the entity name "[xml]" <em>after</em> calling
- * the endDocument method. When exposing entity boundaries through the
- * SAX API, the document entity is never reported, however.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param name The name of the parameter entity.
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endParameterEntity(String name, Augmentations augs) throws XNIException {
- try {
- // Only report endEntity if this entity was actually read.
- if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
- // SAX2 extension
- if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
- fLexicalHandler.endEntity(name);
- }
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // endEntity(String)
- /**
- * An element declaration.
- *
- * @param name The name of the element.
- * @param contentModel The element content model.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void elementDecl(String name, String contentModel, Augmentations augs)
- throws XNIException {
- try {
- // SAX2 extension
- if (fDeclHandler != null) {
- fDeclHandler.elementDecl(name, contentModel);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // elementDecl(String,String, Augmentations)
- /**
- * An attribute declaration.
- *
- * @param elementName The name of the element that this attribute
- * is associated with.
- * @param attributeName The name of the attribute.
- * @param type The attribute type. This value will be one of
- * the following: "CDATA", "ENTITY", "ENTITIES",
- * "ENUMERATION", "ID", "IDREF", "IDREFS",
- * "NMTOKEN", "NMTOKENS", or "NOTATION".
- * @param enumeration If the type has the value "ENUMERATION" or
- * "NOTATION", this array holds the allowed attribute
- * values; otherwise, this array is null.
- * @param defaultType The attribute default type. This value will be
- * one of the following: "#FIXED", "#IMPLIED",
- * "#REQUIRED", or null.
- * @param defaultValue The attribute default value, or null if no
- * default value is specified.
- *
- * @param nonNormalizedDefaultValue The attribute default value with no normalization
- * performed, or null if no default value is specified.
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void attributeDecl(String elementName, String attributeName,
- String type, String[] enumeration,
- String defaultType, XMLString defaultValue,
- XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
- try {
- // SAX2 extension
- if (fDeclHandler != null) {
- // used as a key to detect duplicate attribute definitions.
- String elemAttr = new StringBuffer(elementName).append("<").append(attributeName).toString();
- if(fDeclaredAttrs.get(elemAttr) != null) {
- // we aren't permitted to return duplicate attribute definitions
- return;
- }
- fDeclaredAttrs.put(elemAttr, Boolean.TRUE);
- if (type.equals("NOTATION") ||
- type.equals("ENUMERATION")) {
- StringBuffer str = new StringBuffer();
- if (type.equals("NOTATION")) {
- str.append(type);
- str.append(" (");
- }
- else {
- str.append("(");
- }
- for (int i = 0; i < enumeration.length; i++) {
- str.append(enumeration[i]);
- if (i < enumeration.length - 1) {
- str.append('|');
- }
- }
- str.append(')');
- type = str.toString();
- }
- String value = (defaultValue==null) ? null : defaultValue.toString();
- fDeclHandler.attributeDecl(elementName, attributeName,
- type, defaultType, value);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
- /**
- * An internal entity declaration.
- *
- * @param name The name of the entity. Parameter entity names start with
- * '%', whereas the name of a general entity is just the
- * entity name.
- * @param text The value of the entity.
- * @param nonNormalizedText The non-normalized value of the entity. This
- * value contains the same sequence of characters that was in
- * the internal entity declaration, without any entity
- * references expanded.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void internalEntityDecl(String name, XMLString text,
- XMLString nonNormalizedText,
- Augmentations augs) throws XNIException {
- try {
- // SAX2 extensions
- if (fDeclHandler != null) {
- fDeclHandler.internalEntityDecl(name, text.toString());
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // internalEntityDecl(String,XMLString,XMLString)
- /**
- * An external entity declaration.
- *
- * @param name The name of the entity. Parameter entity names start
- * with '%', whereas the name of a general entity is just
- * the entity name.
- * @param identifier An object containing all location information
- * pertinent to this entity.
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void externalEntityDecl(String name, XMLResourceIdentifier identifier,
- Augmentations augs) throws XNIException {
- String publicId = identifier.getPublicId();
- String literalSystemId = identifier.getLiteralSystemId();
- String expandedSystemId = identifier.getExpandedSystemId();
- try {
- // SAX2 extension
- if (fDeclHandler != null) {
- fDeclHandler.externalEntityDecl(name, publicId, ((resolve_dtd_uris) ? expandedSystemId : literalSystemId));
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // externalEntityDecl(String,,XMLResourceIdentifier, Augmentations)
- /**
- * An unparsed entity declaration.
- *
- * @param name The name of the entity.
- * @param identifier An object containing all location information
- * pertinent to this entity.
- * @param notation The name of the notation.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
- String notation,
- Augmentations augs) throws XNIException {
- String publicId = identifier.getPublicId();
- String expandedSystemId = identifier.getExpandedSystemId();
- String literalSystemId = identifier.getLiteralSystemId();
- try {
- // SAX2 extension
- if (fDTDHandler != null) {
- fDTDHandler.unparsedEntityDecl(name, publicId,
- ((resolve_dtd_uris) ? expandedSystemId : literalSystemId), notation);
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // unparsedEntityDecl(String,XMLResourceIdentifier, String, Augmentations)
- /**
- * A notation declaration
- *
- * @param name The name of the notation.
- * @param identifier An object containing all location information
- * pertinent to this notation.
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void notationDecl(String name, XMLResourceIdentifier identifier,
- Augmentations augs) throws XNIException {
- String publicId = identifier.getPublicId();
- String expandedSystemId = identifier.getExpandedSystemId();
- String literalSystemId = identifier.getLiteralSystemId();
- try {
- // SAX1 and SAX2
- if (fDTDHandler != null) {
- fDTDHandler.notationDecl(name, publicId, ((resolve_dtd_uris) ? expandedSystemId : literalSystemId));
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- } // notationDecl(String,XMLResourceIdentifier, Augmentations)
- /**
- * The end of the DTD.
- *
- * @param augs Additional information that may include infoset
- * augmentations.
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void endDTD(Augmentations augs) throws XNIException {
- fInDTD = false;
- try {
- // SAX2 extension
- if (fLexicalHandler != null) {
- fLexicalHandler.endDTD();
- }
- }
- catch (SAXException e) {
- throw new XNIException(e);
- }
- if(fDeclaredAttrs != null) {
- // help out the GC
- fDeclaredAttrs.clear();
- }
- } // endDTD()
- //
- // Parser and XMLReader methods
- //
- /**
- * Parses the input source specified by the given system identifier.
- * <p>
- * This method is equivalent to the following:
- * <pre>
- * parse(new InputSource(systemId));
- * </pre>
- *
- * @param systemId The system identifier (URI).
- *
- * @exception org.xml.sax.SAXException Throws exception on SAX error.
- * @exception java.io.IOException Throws exception on i/o error.
- */
- public void parse(String systemId) throws SAXException, IOException {
- // parse document
- XMLInputSource source = new XMLInputSource(null, systemId, null);
- try {
- parse(source);
- }
- // wrap XNI exceptions as SAX exceptions
- catch (XMLParseException e) {
- Exception ex = e.getException();
- if (ex == null) {
- // must be a parser exception; mine it for locator info and throw
- // a SAXParseException
- locatorType = true;
- LocatorImpl locatorImpl = new LocatorImpl(){
- public String getXMLVersion() {
- return fVersion;
- }
- // since XMLParseExceptions know nothing about encoding,
- // we cannot return anything meaningful in this context.
- // We *could* consult the LocatorProxy, but the
- // application can do this itself if it wishes to possibly
- // be mislead.
- public String getEncoding() {
- return null;
- }
- };
- locatorImpl.setPublicId(e.getPublicId());
- locatorImpl.setSystemId(e.getExpandedSystemId());
- locatorImpl.setLineNumber(e.getLineNumber());
- locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), locatorImpl);
- }
- if (ex instanceof SAXException) {
- // why did we create an XMLParseException?
- throw (SAXException)ex;
- }
- if (ex instanceof IOException) {
- throw (IOException)ex;
- }
- throw new SAXException(ex);
- }
- catch (XNIException e) {
- Exception ex = e.getException();
- if (ex == null) {
- throw new SAXException(e.getMessage());
- }
- if (ex instanceof SAXException) {
- throw (SAXException)ex;
- }
- if (ex instanceof IOException) {
- throw (IOException)ex;
- }
- throw new SAXException(ex);
- }
- } // parse(String)
- /**
- * parse
- *
- * @param inputSource
- *
- * @exception org.xml.sax.SAXException
- * @exception java.io.IOException
- */
- public void parse(InputSource inputSource)
- throws SAXException, IOException {
- // parse document
- try {
- XMLInputSource xmlInputSource =
- new XMLInputSource(inputSource.getPublicId(),
- inputSource.getSystemId(),
- null);
- xmlInputSource.setByteStream(inputSource.getByteStream());
- xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
- xmlInputSource.setEncoding(inputSource.getEncoding());
- parse(xmlInputSource);
- }
- // wrap XNI exceptions as SAX exceptions
- catch (XMLParseException e) {
- Exception ex = e.getException();
- if (ex == null) {
- // must be a parser exception; mine it for locator info and throw
- // a SAXParseException
- locatorType = true;
- LocatorImpl locatorImpl = new LocatorImpl() {
- public String getXMLVersion() {
- return fVersion;
- }
- // since XMLParseExceptions know nothing about encoding,
- // we cannot return anything meaningful in this context.
- // We *could* consult the LocatorProxy, but the
- // application can do this itself if it wishes to possibly
- // be mislead.
- public String getEncoding() {
- return null;
- }
- };
- locatorImpl.setPublicId(e.getPublicId());
- locatorImpl.setSystemId(e.getExpandedSystemId());
- locatorImpl.setLineNumber(e.getLineNumber());
- locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), l