- /*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2000-2002 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.impl;
-
- import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
- import com.sun.org.apache.xerces.internal.util.SymbolTable;
- 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.XMLDocumentHandler;
- 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.XMLComponent;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
-
- /**
- * This class performs namespace binding on the startElement and endElement
- * method calls and passes all other methods through to the registered
- * document handler. This class can be configured to only pass the
- * start and end prefix mappings (start/endPrefixMapping).
- * <p>
- * This component requires the following features and properties from the
- * component manager that uses it:
- * <ul>
- * <li>http://xml.org/sax/features/namespaces</li>
- * <li>http://apache.org/xml/properties/internal/symbol-table</li>
- * <li>http://apache.org/xml/properties/internal/error-reporter</li>
- * </ul>
- *
- * @author Andy Clark, IBM
- *
- * @version $Id: XMLNamespaceBinder.java,v 1.33 2004/02/24 23:03:46 mrglavas Exp $
- */
- public class XMLNamespaceBinder
- implements XMLComponent, XMLDocumentFilter {
-
- //
- // Constants
- //
-
- // feature identifiers
-
- /** Feature identifier: namespaces. */
- protected static final String NAMESPACES =
- Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
-
- // property identifiers
-
- /** Property identifier: symbol table. */
- protected static final String SYMBOL_TABLE =
- Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
-
- /** Property identifier: error reporter. */
- protected static final String ERROR_REPORTER =
- Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
-
- // recognized features and properties
-
- /** Recognized features. */
- private static final String[] RECOGNIZED_FEATURES = {
- NAMESPACES,
- };
-
- /** Feature defaults. */
- private static final Boolean[] FEATURE_DEFAULTS = {
- null,
- };
-
- /** Recognized properties. */
- private static final String[] RECOGNIZED_PROPERTIES = {
- SYMBOL_TABLE,
- ERROR_REPORTER,
- };
-
- /** Property defaults. */
- private static final Object[] PROPERTY_DEFAULTS = {
- null,
- null,
- };
-
- //
- // Data
- //
-
- // features
-
- /** Namespaces. */
- protected boolean fNamespaces;
-
- // properties
-
- /** Symbol table. */
- protected SymbolTable fSymbolTable;
-
- /** Error reporter. */
- protected XMLErrorReporter fErrorReporter;
-
- // handlers
-
- /** Document handler. */
- protected XMLDocumentHandler fDocumentHandler;
-
- protected XMLDocumentSource fDocumentSource;
-
- // settings
-
- /** Only pass start and end prefix mapping events. */
- protected boolean fOnlyPassPrefixMappingEvents;
-
- // shared context
-
- /** Namespace context. */
- private NamespaceContext fNamespaceContext;
-
- // temp vars
-
- /** Attribute QName. */
- private QName fAttributeQName = new QName();
-
- //
- // Constructors
- //
-
- /** Default constructor. */
- public XMLNamespaceBinder() {
- } // <init>()
-
- //
- // Public methods
- //
-
- // settings
-
- /**
- * Sets whether the namespace binder only passes the prefix mapping
- * events to the registered document handler or passes all document
- * events.
- *
- * @param onlyPassPrefixMappingEvents True to pass only the prefix
- * mapping events; false to pass
- * all events.
- */
- public void setOnlyPassPrefixMappingEvents(boolean onlyPassPrefixMappingEvents) {
- fOnlyPassPrefixMappingEvents = onlyPassPrefixMappingEvents;
- } // setOnlyPassPrefixMappingEvents(boolean)
-
- /**
- * Returns true if the namespace binder only passes the prefix mapping
- * events to the registered document handler; false if the namespace
- * binder passes all document events.
- */
- public boolean getOnlyPassPrefixMappingEvents() {
- return fOnlyPassPrefixMappingEvents;
- } // getOnlyPassPrefixMappingEvents():boolean
-
- //
- // XMLComponent methods
- //
-
- /**
- * Resets the component. The component can query the component manager
- * about any features and properties that affect the operation of the
- * component.
- *
- * @param componentManager The component manager.
- *
- * @throws SAXException Thrown by component on initialization error.
- * For example, if a feature or property is
- * required for the operation of the component, the
- * component manager may throw a
- * SAXNotRecognizedException or a
- * SAXNotSupportedException.
- */
- public void reset(XMLComponentManager componentManager)
- throws XNIException {
-
- // features
- try {
- fNamespaces = componentManager.getFeature(NAMESPACES);
- }
- catch (XMLConfigurationException e) {
- fNamespaces = true;
- }
-
- // Xerces properties
- fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
- fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
-
- } // reset(XMLComponentManager)
-
- /**
- * Returns a list of feature identifiers that are recognized by
- * this component. This method may return null if no features
- * are recognized by this component.
- */
- public String[] getRecognizedFeatures() {
- return (String[])(RECOGNIZED_FEATURES.clone());
- } // getRecognizedFeatures():String[]
-
- /**
- * Sets the state of a feature. This method is called by the component
- * manager any time after reset when a feature changes state.
- * <p>
- * <strong>Note:</strong> Components should silently ignore features
- * that do not affect the operation of the component.
- *
- * @param featureId The feature identifier.
- * @param state The state of the feature.
- *
- * @throws SAXNotRecognizedException The component should not throw
- * this exception.
- * @throws SAXNotSupportedException The component should not throw
- * this exception.
- */
- public void setFeature(String featureId, boolean state)
- throws XMLConfigurationException {
- } // setFeature(String,boolean)
-
- /**
- * Returns a list of property identifiers that are recognized by
- * this component. This method may return null if no properties
- * are recognized by this component.
- */
- public String[] getRecognizedProperties() {
- return (String[])(RECOGNIZED_PROPERTIES.clone());
- } // getRecognizedProperties():String[]
-
- /**
- * Sets the value of a property during parsing.
- *
- * @param propertyId
- * @param value
- */
- public void setProperty(String propertyId, Object value)
- throws XMLConfigurationException {
-
- // Xerces properties
- if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
- final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
-
- if (suffixLength == Constants.SYMBOL_TABLE_PROPERTY.length() &&
- propertyId.endsWith(Constants.SYMBOL_TABLE_PROPERTY)) {
- fSymbolTable = (SymbolTable)value;
- }
- else if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() &&
- propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) {
- fErrorReporter = (XMLErrorReporter)value;
- }
- return;
- }
-
- } // setProperty(String,Object)
-
- /**
- * Returns the default state for a feature, or null if this
- * component does not want to report a default value for this
- * feature.
- *
- * @param featureId The feature identifier.
- *
- * @since Xerces 2.2.0
- */
- public Boolean getFeatureDefault(String featureId) {
- for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
- if (RECOGNIZED_FEATURES[i].equals(featureId)) {
- return FEATURE_DEFAULTS[i];
- }
- }
- return null;
- } // getFeatureDefault(String):Boolean
-
- /**
- * Returns the default state for a property, or null if this
- * component does not want to report a default value for this
- * property.
- *
- * @param propertyId The property identifier.
- *
- * @since Xerces 2.2.0
- */
- public Object getPropertyDefault(String propertyId) {
- for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
- if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
- return PROPERTY_DEFAULTS[i];
- }
- }
- return null;
- } // getPropertyDefault(String):Object
-
- //
- // XMLDocumentSource methods
- //
-
- /** Sets the document handler to receive information about the document. */
- public void setDocumentHandler(XMLDocumentHandler documentHandler) {
- fDocumentHandler = documentHandler;
- } // setDocumentHandler(XMLDocumentHandler)
-
- /** Returns the document handler */
- public XMLDocumentHandler getDocumentHandler() {
- return fDocumentHandler;
- } // setDocumentHandler(XMLDocumentHandler)
-
-
- //
- // XMLDocumentHandler methods
- //
-
- /** Sets the document source */
- public void setDocumentSource(XMLDocumentSource source){
- fDocumentSource = source;
- } // setDocumentSource
-
- /** Returns the document source */
- public XMLDocumentSource getDocumentSource (){
- return fDocumentSource;
- } // getDocumentSource
-
-
- /**
- * This method notifies the start of a general entity.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param name The name of the general 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 entities or a document entity that is
- * parsed from a java.io.Reader).
- * @param augs Additional information that may include infoset augmentations
- *
- * @exception XNIException Thrown by handler to signal an error.
- */
- public void startGeneralEntity(String name,
- XMLResourceIdentifier identifier,
- String encoding, Augmentations augs)
- throws XNIException {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs);
- }
- } // startEntity(String,String,String,String,String)
-
- /**
- * Notifies of the presence of a TextDecl line in an entity. If present,
- * this method will be called immediately following the startEntity call.
- * <p>
- * <strong>Note:</strong> This method will never be called for the
- * document entity; it is only called for external general entities
- * referenced in document content.
- * <p>
- * <strong>Note:</strong> This method is not called for entity references
- * appearing as part of attribute values.
- *
- * @param version The XML version, or null if not specified.
- * @param encoding The IANA encoding name of the entity.
- * @param augs Additional information that may include infoset augmentations
- *
- * @throws XNIException Thrown by handler to signal an error.
- */
- public void textDecl(String version, String encoding, Augmentations augs)
- throws XNIException {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.textDecl(version, encoding, augs);
- }
- } // textDecl(String,String)
-
- /**
- * The start of the document.
- *
- * @param locator 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 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;
-
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.startDocument(locator, encoding, namespaceContext, augs);
- }
- } // startDocument(XMLLocator,String)
-
- /**
- * 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.xmlDecl(version, encoding, standalone, augs);
- }
- } // 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
- }
- } // doctypeDecl(String,String,String)
-
- /**
- * 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.comment(text, augs);
- }
- } // 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.processingInstruction(target, data, augs);
- }
- } // processingInstruction(String,XMLString)
-
-
- /**
- * Binds the namespaces. This method will handle calling the
- * document handler to start the prefix mappings.
- * <p>
- * <strong>Note:</strong> This method makes use of the
- * fAttributeQName variable. Any contents of the variable will
- * be destroyed. Caller should copy the values out of this
- * temporary variable before calling this method.
- *
- * @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 {
-
- if (fNamespaces) {
- handleStartElement(element, attributes, augs, false);
- }
- else if (fDocumentHandler != null) {
- fDocumentHandler.startElement(element, attributes, augs);
- }
-
-
- } // startElement(QName,XMLAttributes)
-
- /**
- * An empty element.
- *
- * @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 emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
- throws XNIException {
-
- if (fNamespaces) {
- handleStartElement(element, attributes, augs, true);
- handleEndElement(element, augs, true);
- }
- else if (fDocumentHandler != null) {
- fDocumentHandler.emptyElement(element, attributes, augs);
- }
-
- } // emptyElement(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 (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.characters(text, augs);
- }
- } // 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.ignorableWhitespace(text, augs);
- }
- } // 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 {
-
- if (fNamespaces) {
- handleEndElement(element, augs, false);
- }
- else if (fDocumentHandler != null) {
- fDocumentHandler.endElement(element, augs);
- }
-
- } // 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.startCDATA(augs);
- }
- } // 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.endCDATA(augs);
- }
- } // endCDATA()
-
- /**
- * 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 {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.endDocument(augs);
- }
- } // endDocument()
-
- /**
- * This method notifies the end of a general entity.
- * <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
- *
- * @exception XNIException
- * Thrown by handler to signal an error.
- */
- public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- fDocumentHandler.endGeneralEntity(name, augs);
- }
- } // endEntity(String)
-
- //
- // Protected methods
- //
-
- /** Handles start element. */
- protected void handleStartElement(QName element, XMLAttributes attributes,
- Augmentations augs,
- boolean isEmpty) throws XNIException {
-
- // add new namespace context
- fNamespaceContext.pushContext();
-
- if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "ElementXMLNSPrefix",
- new Object[]{element.rawname},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // search for new namespace bindings
- int length = attributes.getLength();
- for (int i = 0; i < length; i++) {
- String localpart = attributes.getLocalName(i);
- String prefix = attributes.getPrefix(i);
- // when it's of form xmlns="..." or xmlns:prefix="...",
- // it's a namespace declaration. but prefix:xmlns="..." isn't.
- if (prefix == XMLSymbols.PREFIX_XMLNS ||
- prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
-
- // get the internalized value of this attribute
- String uri = fSymbolTable.addSymbol(attributes.getValue(i));
-
- // 1. "xmlns" can't be bound to any namespace
- if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXMLNS",
- new Object[]{attributes.getQName(i)},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // 2. the namespace for "xmlns" can't be bound to any prefix
- if (uri == NamespaceContext.XMLNS_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXMLNS",
- new Object[]{attributes.getQName(i)},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // 3. "xml" can't be bound to any other namespace than it's own
- if (localpart == XMLSymbols.PREFIX_XML) {
- if (uri != NamespaceContext.XML_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXML",
- new Object[]{attributes.getQName(i)},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
- // 4. the namespace for "xml" can't be bound to any other prefix
- else {
- if (uri ==NamespaceContext.XML_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXML",
- new Object[]{attributes.getQName(i)},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
-
- prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
-
- // http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix
- // We should only report an error if there is a prefix,
- // that is, the local part is not "xmlns". -SG
- // Since this is an error condition in XML 1.0,
- // and should be relatively uncommon in XML 1.1,
- // making this test into a method call to reuse code
- // should be acceptable. - NG
- if(prefixBoundToNullURI(uri, localpart)) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "EmptyPrefixedAttName",
- new Object[]{attributes.getQName(i)},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- continue;
- }
-
- // declare prefix in context
- fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
-
- }
- }
-
- // bind the element
- String prefix = element.prefix != null
- ? element.prefix : XMLSymbols.EMPTY_STRING;
- element.uri = fNamespaceContext.getURI(prefix);
- if (element.prefix == null && element.uri != null) {
- element.prefix = XMLSymbols.EMPTY_STRING;
- }
- if (element.prefix != null && element.uri == null) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "ElementPrefixUnbound",
- new Object[]{element.prefix, element.rawname},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // bind the attributes
- for (int i = 0; i < length; i++) {
- attributes.getName(i, fAttributeQName);
- String aprefix = fAttributeQName.prefix != null
- ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
- String arawname = fAttributeQName.rawname;
- if (arawname == XMLSymbols.PREFIX_XMLNS) {
- fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
- attributes.setName(i, fAttributeQName);
- }
- else if (aprefix != XMLSymbols.EMPTY_STRING) {
- fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
- if (fAttributeQName.uri == null) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "AttributePrefixUnbound",
- new Object[]{element.rawname,arawname,aprefix},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- attributes.setName(i, fAttributeQName);
- }
- }
-
- // verify that duplicate attributes don't exist
- // Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
- int attrCount = attributes.getLength();
- for (int i = 0; i < attrCount - 1; i++) {
- String auri = attributes.getURI(i);
- if (auri == null || auri == NamespaceContext.XMLNS_URI) {
- continue;
- }
- String alocalpart = attributes.getLocalName(i);
- for (int j = i + 1; j < attrCount; j++) {
- String blocalpart = attributes.getLocalName(j);
- String buri = attributes.getURI(j);
- if (alocalpart == blocalpart && auri == buri) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "AttributeNSNotUnique",
- new Object[]{element.rawname,alocalpart, auri},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
- }
-
- // call handler
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- if (isEmpty) {
- fDocumentHandler.emptyElement(element, attributes, augs);
- }
- else {
- fDocumentHandler.startElement(element, attributes, augs);
- }
- }
-
-
- } // handleStartElement(QName,XMLAttributes,boolean)
-
- /** Handles end element. */
- protected void handleEndElement(QName element, Augmentations augs, boolean isEmpty)
- throws XNIException {
-
- // bind element
- String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
- element.uri = fNamespaceContext.getURI(eprefix);
- if (element.uri != null) {
- element.prefix = eprefix;
- }
-
- // call handlers
- if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
- if (!isEmpty) {
- fDocumentHandler.endElement(element, augs);
- }
- }
-
- // pop context
- fNamespaceContext.popContext();
-
- } // handleEndElement(QName,boolean)
-
- // returns true iff the given prefix is bound to "" *and*
- // this is disallowed by the version of XML namespaces in use.
- protected boolean prefixBoundToNullURI(String uri, String localpart) {
- return (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS);
- } // prefixBoundToNullURI(String, String): boolean
-
- } // class XMLNamespaceBinder