| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2001 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 org.apache.xerces.parsers; |
| |
| import java.io.InputStream; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.Hashtable; |
| import java.util.Locale; |
| |
| import org.apache.xerces.impl.Constants; |
| |
| import org.apache.xerces.util.EntityResolverWrapper; |
| import org.apache.xerces.util.ErrorHandlerWrapper; |
| import org.apache.xerces.util.SymbolTable; |
| |
| import org.apache.xerces.xni.Augmentations; |
| import org.apache.xerces.xni.QName; |
| import org.apache.xerces.xni.XMLAttributes; |
| import org.apache.xerces.xni.XMLLocator; |
| import org.apache.xerces.xni.XMLString; |
| import org.apache.xerces.xni.XNIException; |
| import org.apache.xerces.xni.parser.XMLParseException; |
| import org.apache.xerces.xni.parser.XMLConfigurationException; |
| import org.apache.xerces.xni.parser.XMLEntityResolver; |
| import org.apache.xerces.xni.parser.XMLErrorHandler; |
| import org.apache.xerces.xni.parser.XMLInputSource; |
| import org.apache.xerces.xni.parser.XMLParserConfiguration; |
| |
| import org.xml.sax.AttributeList; |
| import org.xml.sax.Attributes; |
| 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.Parser; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| import org.xml.sax.XMLReader; |
| import org.xml.sax.ext.DeclHandler; |
| 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 Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000 |
| * @author Arnaud Le Hors, IBM |
| * @author Andy Clark, IBM |
| * |
| * @version $Id$ |
| */ |
| public abstract class AbstractSAXParser |
| extends AbstractXMLDocumentParser |
| implements 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; |
| |
| // NOTE: The symbol table properties is for internal use. -Ac |
| |
| /** Property identifier: symbol table. */ |
| protected static final String SYMBOL_TABLE = |
| Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; |
| |
| // |
| // Data |
| // |
| |
| // features |
| |
| /** Namespaces. */ |
| protected boolean fNamespaces; |
| |
| /** Namespace prefixes. */ |
| protected boolean fNamespacePrefixes = false; |
| |
| // parser handlers |
| |
| /** Content handler. */ |
| protected ContentHandler fContentHandler; |
| |
| /** Document handler. */ |
| protected DocumentHandler fDocumentHandler; |
| |
| /** DTD handler. */ |
| protected org.xml.sax.DTDHandler fDTDHandler; |
| |
| /** Decl handler. */ |
| protected DeclHandler fDeclHandler; |
| |
| /** Lexical handler. */ |
| protected LexicalHandler fLexicalHandler; |
| |
| protected QName fQName = new QName(); |
| |
| // symbols |
| |
| /** Symbol: empty string (""). */ |
| private String fEmptySymbol; |
| private String fXmlnsSymbol; |
| |
| // 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; |
| |
| // temp vars |
| private final AttributesProxy fAttributesProxy = new AttributesProxy(); |
| |
| // |
| // Constructors |
| // |
| |
| /** Default constructor. */ |
| protected AbstractSAXParser(XMLParserConfiguration config) { |
| super(config); |
| |
| final String[] recognizedFeatures = { |
| NAMESPACES, |
| NAMESPACE_PREFIXES, |
| Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE, |
| }; |
| config.addRecognizedFeatures(recognizedFeatures); |
| |
| final String[] recognizedProperties = { |
| Constants.SAX_PROPERTY_PREFIX + Constants.LEXICAL_HANDLER_PROPERTY, |
| Constants.SAX_PROPERTY_PREFIX + Constants.DECLARATION_HANDLER_PROPERTY, |
| Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY, |
| }; |
| config.addRecognizedProperties(recognizedProperties); |
| |
| } // <init>(XMLParserConfiguration) |
| |
| // |
| // XMLDocumentHandler methods |
| // |
| |
| /** |
| * The start of the document. |
| * |
| * @param systemId The system identifier of the entity if the entity |
| * is external, null otherwise. |
| * @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 augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startDocument(XMLLocator locator, String encoding, Augmentations augs) |
| throws XNIException { |
| |
| try { |
| // SAX1 |
| if (fDocumentHandler != null) { |
| if (locator != null) { |
| fDocumentHandler.setDocumentLocator(new LocatorProxy(locator)); |
| } |
| fDocumentHandler.startDocument(); |
| } |
| |
| // SAX2 |
| if (fContentHandler != null) { |
| if (locator != null) { |
| fContentHandler.setDocumentLocator(new LocatorProxy(locator)); |
| } |
| fContentHandler.startDocument(); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // startDocument(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); |
| } |
| |
| } // 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 publicId The public identifier of the entity if the entity |
| * is external, null otherwise. |
| * @param systemId The system identifier of the entity if the entity |
| * is external, null otherwise. |
| * @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 startEntity(String name, String publicId, String systemId, |
| String baseSystemId, String encoding, Augmentations augs) |
| throws XNIException { |
| |
| startEntity(name, publicId, systemId, baseSystemId, encoding); |
| |
| } // startEntity(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 endEntity(String name, Augmentations augs) throws XNIException { |
| |
| endEntity(name); |
| |
| } // endEntity(String) |
| |
| /** |
| * The start of a namespace prefix mapping. This method will only be |
| * called when namespace processing is enabled. |
| * |
| * @param prefix The namespace prefix. |
| * @param uri The URI bound to the prefix. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startPrefixMapping(String prefix, String uri, Augmentations augs) |
| throws XNIException { |
| |
| try { |
| // SAX2 |
| if (fContentHandler != null) { |
| fContentHandler.startPrefixMapping(prefix, uri); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // startPrefixMapping(String prefix, String uri) |
| |
| /** |
| * 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) { |
| fAttributesProxy.setAttributes(attributes); |
| fDocumentHandler.startElement(element.rawname, fAttributesProxy); |
| } |
| |
| // SAX2 |
| if (fContentHandler != null) { |
| |
| int len = attributes.getLength(); |
| for (int i = len - 1; i >= 0; i--) { |
| attributes.getName(i, fQName); |
| if (fQName.prefix == fXmlnsSymbol || |
| fQName.rawname == fXmlnsSymbol) { |
| if (!fNamespacePrefixes) { |
| // remove namespace declaration attributes |
| attributes.removeAttributeAt(i); |
| } |
| else if (fNamespaces && fNamespacePrefixes) { |
| // localpart should be empty string as per SAX documentation: |
| // http://www.saxproject.org/?selected=namespaces |
| fQName.prefix = fEmptySymbol; |
| fQName.localpart = fEmptySymbol; |
| attributes.setName(i, fQName); |
| } |
| } |
| |
| } |
| |
| String uri = element.uri != null ? element.uri : fEmptySymbol; |
| String localpart = fNamespaces ? element.localpart : fEmptySymbol; |
| 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 { |
| |
| |
| try { |
| // SAX1 |
| if (fDocumentHandler != null) { |
| 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) { |
| String uri = element.uri != null ? element.uri : fEmptySymbol; |
| String localpart = fNamespaces ? element.localpart : fEmptySymbol; |
| fContentHandler.endElement(uri, localpart, |
| element.rawname); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // endElement(QName) |
| |
| /** |
| * The end of a namespace prefix mapping. This method will only be |
| * called when namespace processing is enabled. |
| * |
| * @param prefix The namespace prefix. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endPrefixMapping(String prefix, Augmentations augs) throws XNIException { |
| |
| try { |
| // SAX2 |
| if (fContentHandler != null) { |
| fContentHandler.endPrefixMapping(prefix); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // endPrefixMapping(String) |
| |
| /** |
| * 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 { |
| |
| comment (text); |
| |
| } // 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 { |
| |
| processingInstruction (target, data); |
| |
| } // 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 |
| // |
| |
| |
| /** |
| * 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. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void processingInstruction(String target, XMLString data) |
| 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) |
| |
| |
| |
| /** |
| * A comment. |
| * |
| * @param text The text in the comment. |
| * |
| * @throws XNIException Thrown by application to signal an error. |
| */ |
| public void comment(XMLString text) throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fLexicalHandler != null) { |
| fLexicalHandler.comment(text.ch, 0, text.length); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // comment(XMLString) |
| |
| |
| /** |
| * 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 publicId The public identifier of the entity if the entity |
| * is external, null otherwise. |
| * @param systemId The system identifier of the entity if the entity |
| * is external, null otherwise. |
| * @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). |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startEntity(String name, String publicId, String systemId, |
| String baseSystemId, String encoding) |
| throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fLexicalHandler != null) { |
| fLexicalHandler.startEntity(name); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // startEntity(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. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endEntity(String name) throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fLexicalHandler != null) { |
| 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. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void elementDecl(String name, String contentModel) |
| throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fDeclHandler != null) { |
| fDeclHandler.elementDecl(name, contentModel); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // elementDecl(String,String) |
| |
| /** |
| * 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. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void attributeDecl(String elementName, String attributeName, |
| String type, String[] enumeration, |
| String defaultType, XMLString defaultValue) |
| throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fDeclHandler != null) { |
| 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) |
| |
| /** |
| * 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. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void internalEntityDecl(String name, XMLString text, |
| XMLString nonNormalizedText) |
| 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 publicId The public identifier of the entity or null if the |
| * the entity was specified with SYSTEM. |
| * @param systemId The system identifier of the entity. |
| * @param baseSystemId The baseSystem identifier of the entity. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void externalEntityDecl(String name, String publicId, |
| String systemId, String baseSystemId) throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fDeclHandler != null) { |
| fDeclHandler.externalEntityDecl(name, publicId, systemId); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // externalEntityDecl(String,String,String,String) |
| |
| /** |
| * An unparsed entity declaration. |
| * |
| * @param name The name of the entity. |
| * @param publicId The public identifier of the entity, or null if not |
| * specified. |
| * @param systemId The system identifier of the entity, or null if not |
| * specified. |
| * @param notation The name of the notation. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void unparsedEntityDecl(String name, String publicId, |
| String systemId, String notation) |
| throws XNIException { |
| |
| try { |
| // SAX2 extension |
| if (fDTDHandler != null) { |
| fDTDHandler.unparsedEntityDecl(name, publicId, |
| systemId, notation); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // unparsedEntityDecl(String,String,String,String) |
| |
| /** |
| * A notation declaration |
| * |
| * @param name The name of the notation. |
| * @param publicId The public identifier of the notation, or null if not |
| * specified. |
| * @param systemId The system identifier of the notation, or null if not |
| * specified. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void notationDecl(String name, String publicId, String systemId) |
| throws XNIException { |
| |
| try { |
| // SAX1 and SAX2 |
| if (fDTDHandler != null) { |
| fDTDHandler.notationDecl(name, publicId, systemId); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // notationDecl(String,String,String) |
| |
| /** |
| * The end of the DTD. |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endDTD() throws XNIException { |
| fInDTD = false; |
| |
| try { |
| // SAX2 extension |
| if (fLexicalHandler != null) { |
| fLexicalHandler.endDTD(); |
| } |
| } |
| catch (SAXException e) { |
| throw new XNIException(e); |
| } |
| |
| } // 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 source The input source. |
| * |
| * @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 |
| LocatorImpl locatorImpl = new LocatorImpl(); |
| locatorImpl.setPublicId(e.getPublicId()); |
| locatorImpl.setSystemId(e.getSystemId()); |
| 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); |
| } |
| |
| // close stream opened by the parser |
| finally { |
| try { |
| Reader reader = source.getCharacterStream(); |
| if (reader != null) { |
| reader.close(); |
| } |
| else { |
| InputStream is = source.getByteStream(); |
| if (is != null) { |
| is.close(); |
| } |
| } |
| } |
| catch (IOException e) { |
| // ignore |
| } |
| } |
| |
| } // 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 |
| LocatorImpl locatorImpl = new LocatorImpl(); |
| locatorImpl.setPublicId(e.getPublicId()); |
| locatorImpl.setSystemId(e.getSystemId()); |
| 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(InputSource) |
| |
| /** |
| * Sets the resolver used to resolve external entities. The EntityResolver |
| * interface supports resolution of public and system identifiers. |
| * |
| * @param resolver The new entity resolver. Passing a null value will |
| * uninstall the currently installed resolver. |
| */ |
| public void setEntityResolver(EntityResolver resolver) { |
| |
| try { |
| fConfiguration.setProperty(ENTITY_RESOLVER, |
| new EntityResolverWrapper(resolver)); |
| } |
| catch (XMLConfigurationException e) { |
| // do nothing |
| } |
| |
| } // setEntityResolver(EntityResolver) |
| |
| /** |
| * Return the current entity resolver. |
| * |
| * @return The current entity resolver, or null if none |
| * has been registered. |
| * @see #setEntityResolver |
| */ |
| public EntityResolver getEntityResolver() { |
| |
| EntityResolver entityResolver = null; |
| try { |
| XMLEntityResolver xmlEntityResolver = |
| (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER); |
| if (xmlEntityResolver != null && |
| xmlEntityResolver instanceof EntityResolverWrapper) { |
| entityResolver = ((EntityResolverWrapper)xmlEntityResolver).getEntityResolver(); |
| } |
| } |
| catch (XMLConfigurationException e) { |
| // do nothing |
| } |
| return entityResolver; |
| |
| } // getEntityResolver():EntityResolver |
| |
| /** |
| * Allow an application to register an error event handler. |
| * |
| * <p>If the application does not register an error handler, all |
| * error events reported by the SAX parser will be silently |
| * ignored; however, normal processing may not continue. It is |
| * highly recommended that all SAX applications implement an |
| * error handler to avoid unexpected bugs.</p> |
| * |
| * <p>Applications may register a new or different handler in the |
| * middle of a parse, and the SAX parser must begin using the new |
| * handler immediately.</p> |
| * |
| * @param errorHandler The error handler. |
| * @exception java.lang.NullPointerException If the handler |
| * argument is null. |
| * @see #getErrorHandler |
| */ |
| public void setErrorHandler(ErrorHandler errorHandler) { |
| |
| try { |
| fConfiguration.setProperty(ERROR_HANDLER, |
| new ErrorHandlerWrapper(errorHandler)); |
| } |
| catch (XMLConfigurationException e) { |
| // do nothing |
| } |
| |
| } // setErrorHandler(ErrorHandler) |
| |
| /** |
| * Return the current error handler. |
| * |
| * @return The current error handler, or null if none |
| * has been registered. |
| * @see #setErrorHandler |
| */ |
| public ErrorHandler getErrorHandler() { |
| |
| ErrorHandler errorHandler = null; |
| try { |
| XMLErrorHandler xmlErrorHandler = |
| (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER); |
| if (xmlErrorHandler != null && |
| xmlErrorHandler instanceof ErrorHandlerWrapper) { |
| errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler(); |
| } |
| } |
| catch (XMLConfigurationException e) { |
| // do nothing |
| } |
| return errorHandler; |
| |
| } // getErrorHandler():ErrorHandler |
| |
| /** |
| * Set the locale to use for messages. |
| * |
| * @param locale The locale object to use for localization of messages. |
| * |
| * @exception SAXException An exception thrown if the parser does not |
| * support the specified locale. |
| * |
| * @see org.xml.sax.Parser |
| */ |
| public void setLocale(Locale locale) throws SAXException { |
| |
| fConfiguration.setLocale(locale); |
| |
| } // setLocale(Locale) |
| |
| /** |
| * Allow an application to register a DTD event handler. |
| * <p> |
| * If the application does not register a DTD handler, all DTD |
| * events reported by the SAX parser will be silently ignored. |
| * <p> |
| * Applications may register a new or different handler in the |
| * middle of a parse, and the SAX parser must begin using the new |
| * handler immediately. |
| * |
| * @param dtdHandler The DTD handler. |
| * |
| * @exception java.lang.NullPointerException If the handler |
| * argument is null. |
| * |
| * @see #getDTDHandler |
| */ |
| public void setDTDHandler(DTDHandler dtdHandler) { |
| // REVISIT: SAX1 doesn't require a null pointer exception |
| // to be thrown but SAX2 does. [Q] How do we |
| // resolve this? Currently I'm erring on the side |
| // of SAX2. -Ac |
| if (dtdHandler == null) { |
| throw new NullPointerException(); |
| } |
| fDTDHandler = dtdHandler; |
| } // setDTDHandler(DTDHandler) |
| |
| // |
| // Parser methods |
| // |
| |
| /** |
| * Allow an application to register a document event handler. |
| * <p> |
| * If the application does not register a document handler, all |
| * document events reported by the SAX parser will be silently |
| * ignored (this is the default behaviour implemented by |
| * HandlerBase). |
| * <p> |
| * Applications may register a new or different handler in the |
| * middle of a parse, and the SAX parser must begin using the new |
| * handler immediately. |
| * |
| * @param documentHandler The document handler. |
| */ |
| public void setDocumentHandler(DocumentHandler documentHandler) { |
| fDocumentHandler = documentHandler; |
| } // setDocumentHandler(DocumentHandler) |
| |
| // |
| // XMLReader methods |
| // |
| |
| /** |
| * Allow an application to register a content event handler. |
| * <p> |
| * If the application does not register a content handler, all |
| * content events reported by the SAX parser will be silently |
| * ignored. |
| * <p> |
| * Applications may register a new or different handler in the |
| * middle of a parse, and the SAX parser must begin using the new |
| * handler immediately. |
| * |
| * @param contentHandler The content handler. |
| * |
| * @exception java.lang.NullPointerException If the handler |
| * argument is null. |
| * |
| * @see #getContentHandler |
| */ |
| public void setContentHandler(ContentHandler contentHandler) { |
| fContentHandler = contentHandler; |
| } // setContentHandler(ContentHandler) |
| |
| /** |
| * Return the current content handler. |
| * |
| * @return The current content handler, or null if none |
| * has been registered. |
| * |
| * @see #setContentHandler |
| */ |
| public ContentHandler getContentHandler() { |
| return fContentHandler; |
| } // getContentHandler():ContentHandler |
| |
| /** |
| * Return the current DTD handler. |
| * |
| * @return The current DTD handler, or null if none |
| * has been registered. |
| * @see #setDTDHandler |
| */ |
| public DTDHandler getDTDHandler() { |
| return fDTDHandler; |
| } // getDTDHandler():DTDHandler |
| |
| /** |
| * Set the state of any feature in a SAX2 parser. The parser |
| * might not recognize the feature, and if it does recognize |
| * it, it might not be able to fulfill the request. |
| * |
| * @param featureId The unique identifier (URI) of the feature. |
| * @param state The requested state of the feature (true or false). |
| * |
| * @exception SAXNotRecognizedException If the |
| * requested feature is not known. |
| * @exception SAXNotSupportedException If the |
| * requested feature is known, but the requested |
| * state is not supported. |
| */ |
| public void setFeature(String featureId, boolean state) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| try { |
| // |
| // SAX2 Features |
| // |
| |
| if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) { |
| String feature = featureId.substring(Constants.SAX_FEATURE_PREFIX.length()); |
| |
| // http://xml.org/sax/features/namespaces |
| if (feature.equals(Constants.NAMESPACES_FEATURE)) { |
| fConfiguration.setFeature(featureId, state); |
| fNamespaces = state; |
| return; |
| } |
| // http://xml.org/sax/features/namespace-prefixes |
| // controls the reporting of raw prefixed names and Namespace |
| // declarations (xmlns* attributes): when this feature is false |
| // (the default), raw prefixed names may optionally be reported, |
| // and xmlns* attributes must not be reported. |
| // |
| if (feature.equals(Constants.NAMESPACE_PREFIXES_FEATURE)) { |
| fConfiguration.setFeature(featureId, state); |
| fNamespacePrefixes = state; |
| return; |
| } |
| // http://xml.org/sax/features/string-interning |
| // controls the use of java.lang.String#intern() for strings |
| // passed to SAX handlers. |
| // |
| if (feature.equals(Constants.STRING_INTERNING_FEATURE)) { |
| if (!state) { |
| // REVISIT: Localize this error message. -Ac |
| throw new SAXNotSupportedException( |
| "PAR018 " + state + " state for feature \"" + featureId |
| + "\" is not supported.\n" + state + '\t' + featureId); |
| } |
| return; |
| } |
| |
| // |
| // Drop through and perform default processing |
| // |
| } |
| |
| // |
| // Xerces Features |
| // |
| |
| /* |
| else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) { |
| String feature = featureId.substring(XERCES_FEATURES_PREFIX.length()); |
| // |
| // Drop through and perform default processing |
| // |
| } |
| */ |
| |
| // |
| // Default handling |
| // |
| |
| fConfiguration.setFeature(featureId, state); |
| } |
| catch (XMLConfigurationException e) { |
| String message = e.getMessage(); |
| if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { |
| throw new SAXNotRecognizedException(message); |
| } |
| else { |
| throw new SAXNotSupportedException(message); |
| } |
| } |
| |
| } // setFeature(String,boolean) |
| |
| /** |
| * Query the state of a feature. |
| * |
| * Query the current state of any feature in a SAX2 parser. The |
| * parser might not recognize the feature. |
| * |
| * @param featureId The unique identifier (URI) of the feature |
| * being set. |
| * @return The current state of the feature. |
| * @exception org.xml.sax.SAXNotRecognizedException If the |
| * requested feature is not known. |
| * @exception SAXNotSupportedException If the |
| * requested feature is known but not supported. |
| */ |
| public boolean getFeature(String featureId) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| try { |
| // |
| // SAX2 Features |
| // |
| |
| if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) { |
| String feature = |
| featureId.substring(Constants.SAX_FEATURE_PREFIX.length()); |
| |
| // http://xml.org/sax/features/namespace-prefixes |
| // controls the reporting of raw prefixed names and Namespace |
| // declarations (xmlns* attributes): when this feature is false |
| // (the default), raw prefixed names may optionally be reported, |
| // and xmlns* attributes must not be reported. |
| // |
| if (feature.equals(Constants.NAMESPACE_PREFIXES_FEATURE)) { |
| boolean state = fConfiguration.getFeature(featureId); |
| return state; |
| } |
| // http://xml.org/sax/features/string-interning |
| // controls the use of java.lang.String#intern() for strings |
| // passed to SAX handlers. |
| // |
| if (feature.equals(Constants.STRING_INTERNING_FEATURE)) { |
| return true; |
| } |
| |
| // |
| // Drop through and perform default processing |
| // |
| } |
| |
| // |
| // Xerces Features |
| // |
| |
| /* |
| else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) { |
| // |
| // Drop through and perform default processing |
| // |
| } |
| */ |
| |
| return fConfiguration.getFeature(featureId); |
| } |
| catch (XMLConfigurationException e) { |
| String message = e.getMessage(); |
| if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { |
| throw new SAXNotRecognizedException(message); |
| } |
| else { |
| throw new SAXNotSupportedException(message); |
| } |
| } |
| |
| } // getFeature(String):boolean |
| |
| /** |
| * Set the value of any property in a SAX2 parser. The parser |
| * might not recognize the property, and if it does recognize |
| * it, it might not support the requested value. |
| * |
| * @param propertyId The unique identifier (URI) of the property |
| * being set. |
| * @param Object The value to which the property is being set. |
| * |
| * @exception SAXNotRecognizedException If the |
| * requested property is not known. |
| * @exception SAXNotSupportedException If the |
| * requested property is known, but the requested |
| * value is not supported. |
| */ |
| public void setProperty(String propertyId, Object value) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| try { |
| // |
| // SAX2 core properties |
| // |
| |
| if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) { |
| String property = |
| propertyId.substring(Constants.SAX_PROPERTY_PREFIX.length()); |
| // |
| // http://xml.org/sax/properties/lexical-handler |
| // Value type: org.xml.sax.ext.LexicalHandler |
| // Access: read/write, pre-parse only |
| // Set the lexical event handler. |
| // |
| if (property.equals(Constants.LEXICAL_HANDLER_PROPERTY)) { |
| try { |
| setLexicalHandler((LexicalHandler)value); |
| } |
| catch (ClassCastException e) { |
| // REVISIT: Localize this error message. -ac |
| throw new SAXNotSupportedException( |
| "PAR012 For propertyID \"" |
| +propertyId+"\", the value \"" |
| +value+"\" cannot be cast to LexicalHandler." |
| +'\n'+propertyId+'\t'+value+"\tLexicalHandler"); |
| } |
| return; |
| } |
| // |
| // http://xml.org/sax/properties/declaration-handler |
| // Value type: org.xml.sax.ext.DeclHandler |
| // Access: read/write, pre-parse only |
| // Set the DTD declaration event handler. |
| // |
| if (property.equals(Constants.DECLARATION_HANDLER_PROPERTY)) { |
| try { |
| setDeclHandler((DeclHandler)value); |
| } |
| catch (ClassCastException e) { |
| // REVISIT: Localize this error message. -ac |
| throw new SAXNotSupportedException( |
| "PAR012 For propertyID \"" |
| +propertyId+"\", the value \"" |
| +value+"\" cannot be cast to DeclHandler." |
| +'\n'+propertyId+'\t'+value+"\tDeclHandler" |
| ); |
| } |
| return; |
| } |
| // |
| // http://xml.org/sax/properties/dom-node |
| // Value type: DOM Node |
| // Access: read-only |
| // Get the DOM node currently being visited, if the SAX parser is |
| // iterating over a DOM tree. If the parser recognises and |
| // supports this property but is not currently visiting a DOM |
| // node, it should return null (this is a good way to check for |
| // availability before the parse begins). |
| // |
| if (property.equals(Constants.DOM_NODE_PROPERTY)) { |
| // REVISIT: Localize this error message. -ac |
| throw new SAXNotSupportedException( |
| "PAR013 Property \""+propertyId+"\" is read only." |
| +'\n'+propertyId |
| ); // read-only property |
| } |
| // |
| // Drop through and perform default processing |
| // |
| } |
| |
| // |
| // Xerces Properties |
| // |
| |
| /* |
| else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) { |
| // |
| // Drop through and perform default processing |
| // |
| } |
| */ |
| |
| // |
| // Perform default processing |
| // |
| |
| fConfiguration.setProperty(propertyId, value); |
| } |
| catch (XMLConfigurationException e) { |
| String message = e.getMessage(); |
| if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { |
| throw new SAXNotRecognizedException(message); |
| } |
| else { |
| throw new SAXNotSupportedException(message); |
| } |
| } |
| |
| } // setProperty(String,Object) |
| |
| /** |
| * Query the value of a property. |
| * |
| * Return the current value of a property in a SAX2 parser. |
| * The parser might not recognize the property. |
| * |
| * @param propertyId The unique identifier (URI) of the property |
| * being set. |
| * @return The current value of the property. |
| * @exception org.xml.sax.SAXNotRecognizedException If the |
| * requested property is not known. |
| * @exception SAXNotSupportedException If the |
| * requested property is known but not supported. |
| */ |
| public Object getProperty(String propertyId) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| try { |
| // |
| // SAX2 core properties |
| // |
| |
| if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) { |
| String property = |
| propertyId.substring(Constants.SAX_PROPERTY_PREFIX.length()); |
| // |
| // http://xml.org/sax/properties/lexical-handler |
| // Value type: org.xml.sax.ext.LexicalHandler |
| // Access: read/write, pre-parse only |
| // Set the lexical event handler. |
| // |
| if (property.equals(Constants.LEXICAL_HANDLER_PROPERTY)) { |
| return getLexicalHandler(); |
| } |
| // |
| // http://xml.org/sax/properties/declaration-handler |
| // Value type: org.xml.sax.ext.DeclHandler |
| // Access: read/write, pre-parse only |
| // Set the DTD declaration event handler. |
| // |
| if (property.equals(Constants.DECLARATION_HANDLER_PROPERTY)) { |
| return getDeclHandler(); |
| } |
| // |
| // http://xml.org/sax/properties/dom-node |
| // Value type: DOM Node |
| // Access: read-only |
| // Get the DOM node currently being visited, if the SAX parser is |
| // iterating over a DOM tree. If the parser recognises and |
| // supports this property but is not currently visiting a DOM |
| // node, it should return null (this is a good way to check for |
| // availability before the parse begins). |
| // |
| if (property.equals(Constants.DOM_NODE_PROPERTY)) { |
| // REVISIT: Localize this error message. -Ac |
| throw new SAXNotSupportedException( |
| "PAR014 Cannot getProperty(\""+propertyId |
| +"\". No DOM Tree exists.\n"+propertyId |
| ); // we are not iterating a DOM tree |
| } |
| // |
| // Drop through and perform default processing |
| // |
| } |
| |
| // |
| // Xerces properties |
| // |
| |
| /* |
| else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) { |
| // |
| // Drop through and perform default processing |
| // |
| } |
| */ |
| |
| // |
| // Perform default processing |
| // |
| |
| return fConfiguration.getProperty(propertyId); |
| } |
| catch (XMLConfigurationException e) { |
| String message = e.getMessage(); |
| if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { |
| throw new SAXNotRecognizedException(message); |
| } |
| else { |
| throw new SAXNotSupportedException(message); |
| } |
| } |
| |
| } // getProperty(String):Object |
| |
| // |
| // Protected methods |
| // |
| |
| // SAX2 core properties |
| |
| /** |
| * Set the DTD declaration event handler. |
| * <p> |
| * This method is the equivalent to the property: |
| * <pre> |
| * http://xml.org/sax/properties/declaration-handler |
| * </pre> |
| * |
| * @param handler The new handler. |
| * |
| * @see #getDeclHandler |
| * @see #setProperty |
| */ |
| protected void setDeclHandler(DeclHandler handler) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| if (fParseInProgress) { |
| // REVISIT: Localize this error message. -Ac |
| throw new SAXNotSupportedException( |
| "PAR011 Feature: http://xml.org/sax/properties/declaration-handler" |
| +" is not supported during parse." |
| +"\nhttp://xml.org/sax/properties/declaration-handler"); |
| } |
| fDeclHandler = handler; |
| |
| } // setDeclHandler(DeclHandler) |
| |
| /** |
| * Returns the DTD declaration event handler. |
| * |
| * @see #setDeclHandler |
| */ |
| protected DeclHandler getDeclHandler() |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| return fDeclHandler; |
| } // getDeclHandler():DeclHandler |
| |
| /** |
| * Set the lexical event handler. |
| * <p> |
| * This method is the equivalent to the property: |
| * <pre> |
| * http://xml.org/sax/properties/lexical-handler |
| * </pre> |
| * |
| * @param handler lexical event handler |
| * |
| * @see #getLexicalHandler |
| * @see #setProperty |
| */ |
| protected void setLexicalHandler(LexicalHandler handler) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| |
| if (fParseInProgress) { |
| // REVISIT: Localize this error message. -Ac |
| throw new SAXNotSupportedException( |
| "PAR011 Feature: http://xml.org/sax/properties/lexical-handler" |
| +" is not supported during parse." |
| +"\nhttp://xml.org/sax/properties/lexical-handler"); |
| } |
| fLexicalHandler = handler; |
| |
| } // setLexicalHandler(LexicalHandler) |
| |
| /** |
| * Returns the lexical handler. |
| * |
| * @see #setLexicalHandler |
| */ |
| protected LexicalHandler getLexicalHandler() |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| return fLexicalHandler; |
| } // getLexicalHandler():LexicalHandler |
| |
| // |
| // XMLDocumentParser methods |
| // |
| |
| /** |
| * Reset all components before parsing. |
| * |
| * @throws XNIException Thrown if an error occurs during initialization. |
| */ |
| public void reset() throws XNIException { |
| super.reset(); |
| |
| // reset state |
| fInDTD = false; |
| |
| // features |
| fNamespaces = fConfiguration.getFeature(NAMESPACES); |
| fNamespacePrefixes = fConfiguration.getFeature(NAMESPACE_PREFIXES); |
| |
| // save needed symbols |
| SymbolTable symbolTable = (SymbolTable)fConfiguration.getProperty(SYMBOL_TABLE); |
| if (symbolTable != null) { |
| fEmptySymbol = symbolTable.addSymbol(""); |
| fXmlnsSymbol = symbolTable.addSymbol("xmlns"); |
| } |
| |
| } // reset() |
| |
| // |
| // Classes |
| // |
| |
| protected static class LocatorProxy |
| implements Locator { |
| |
| // |
| // Data |
| // |
| |
| /** XML locator. */ |
| protected XMLLocator fLocator; |
| |
| // |
| // Constructors |
| // |
| |
| /** Constructs an XML locator proxy. */ |
| public LocatorProxy(XMLLocator locator) { |
| fLocator = locator; |
| } |
| |
| // |
| // Locator methods |
| // |
| |
| /** Public identifier. */ |
| public String getPublicId() { |
| return fLocator.getPublicId(); |
| } |
| |
| /** System identifier. */ |
| public String getSystemId() { |
| return fLocator.getSystemId(); |
| } |
| /** Line number. */ |
| public int getLineNumber() { |
| return fLocator.getLineNumber(); |
| } |
| |
| /** Column number. */ |
| public int getColumnNumber() { |
| return fLocator.getColumnNumber(); |
| } |
| |
| } // class LocatorProxy |
| |
| protected static final class AttributesProxy |
| implements AttributeList, Attributes { |
| |
| // |
| // Data |
| // |
| |
| /** XML attributes. */ |
| protected XMLAttributes fAttributes; |
| |
| // |
| // Public methods |
| // |
| |
| /** Sets the XML attributes. */ |
| public void setAttributes(XMLAttributes attributes) { |
| fAttributes = attributes; |
| } // setAttributes(XMLAttributes) |
| |
| public int getLength() { |
| return fAttributes.getLength(); |
| } |
| |
| public String getName(int i) { |
| return fAttributes.getQName(i); |
| } |
| |
| public String getQName(int index) { |
| return fAttributes.getQName(index); |
| } |
| |
| public String getURI(int index) { |
| // REVISIT: this hides the fact that internally we use |
| // null instead of empty string |
| // SAX requires URI to be a string or an empty string |
| String uri= fAttributes.getURI(index); |
| return uri != null ? uri : ""; |
| } |
| |
| public String getLocalName(int index) { |
| return fAttributes.getLocalName(index); |
| } |
| |
| public String getType(int i) { |
| return fAttributes.getType(i); |
| } |
| |
| public String getType(String name) { |
| return fAttributes.getType(name); |
| } |
| |
| public String getType(String uri, String localName) { |
| return uri.equals("") ? fAttributes.getType(null, localName) : |
| fAttributes.getType(uri, localName); |
| } |
| |
| public String getValue(int i) { |
| return fAttributes.getValue(i); |
| } |
| |
| public String getValue(String name) { |
| return fAttributes.getValue(name); |
| } |
| |
| public String getValue(String uri, String localName) { |
| return uri.equals("") ? fAttributes.getValue(null, localName) : |
| fAttributes.getValue(uri, localName); |
| } |
| |
| public int getIndex(String qName) { |
| return fAttributes.getIndex(qName); |
| } |
| |
| public int getIndex(String uri, String localPart) { |
| return uri.equals("") ? fAttributes.getIndex(null, localPart) : |
| fAttributes.getIndex(uri, localPart); |
| } |
| |
| } // class AttributesProxy |
| |
| } // class AbstractSAXParser |