286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * The Apache Software License, Version 1.1
286N/A *
286N/A *
286N/A * Copyright (c) 1999-2002 The Apache Software Foundation.
286N/A * All rights reserved.
286N/A *
286N/A * Redistribution and use in source and binary forms, with or without
286N/A * modification, are permitted provided that the following conditions
286N/A * are met:
286N/A *
286N/A * 1. Redistributions of source code must retain the above copyright
286N/A * notice, this list of conditions and the following disclaimer.
286N/A *
286N/A * 2. Redistributions in binary form must reproduce the above copyright
286N/A * notice, this list of conditions and the following disclaimer in
286N/A * the documentation and/or other materials provided with the
286N/A * distribution.
286N/A *
286N/A * 3. The end-user documentation included with the redistribution,
286N/A * if any, must include the following acknowledgment:
286N/A * "This product includes software developed by the
286N/A * Apache Software Foundation (http://www.apache.org/)."
286N/A * Alternately, this acknowledgment may appear in the software itself,
286N/A * if and wherever such third-party acknowledgments normally appear.
286N/A *
286N/A * 4. The names "Xerces" and "Apache Software Foundation" must
286N/A * not be used to endorse or promote products derived from this
286N/A * software without prior written permission. For written
286N/A * permission, please contact apache@apache.org.
286N/A *
286N/A * 5. Products derived from this software may not be called "Apache",
286N/A * nor may "Apache" appear in their name, without prior written
286N/A * permission of the Apache Software Foundation.
286N/A *
286N/A * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
286N/A * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
286N/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
286N/A * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
286N/A * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
286N/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
286N/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
286N/A * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
286N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
286N/A * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
286N/A * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
286N/A * SUCH DAMAGE.
286N/A * ====================================================================
286N/A *
286N/A * This software consists of voluntary contributions made by many
286N/A * individuals on behalf of the Apache Software Foundation and was
286N/A * originally based on software copyright (c) 1999, International
286N/A * Business Machines, Inc., http://www.apache.org. For more
286N/A * information on the Apache Software Foundation, please see
286N/A * <http://www.apache.org/>.
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xerces.internal.impl.dtd;
286N/A
286N/Aimport java.util.ArrayList;
286N/Aimport java.util.HashMap;
286N/Aimport java.util.Iterator;
286N/Aimport java.util.Locale;
286N/Aimport java.util.Map;
286N/Aimport java.util.StringTokenizer;
286N/A
286N/Aimport com.sun.org.apache.xerces.internal.impl.Constants;
286N/Aimport com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
286N/Aimport com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
286N/Aimport com.sun.org.apache.xerces.internal.util.SymbolTable;
286N/Aimport com.sun.org.apache.xerces.internal.util.XMLChar;
286N/Aimport com.sun.org.apache.xerces.internal.util.XMLSymbols;
286N/Aimport com.sun.org.apache.xerces.internal.xni.Augmentations;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLLocator;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLString;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XNIException;
286N/Aimport com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
286N/Aimport com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
286N/Aimport com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelFilter;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDFilter;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
286N/A
286N/A/**
286N/A * The DTD processor. The processor implements a DTD
286N/A * filter: receiving DTD events from the DTD scanner; validating
286N/A * the content and structure; building a grammar, if applicable;
286N/A * and notifying the DTDHandler of the information resulting from the
286N/A * process.
286N/A * <p>
286N/A * This component requires the following features and properties from the
286N/A * component manager that uses it:
286N/A * <ul>
286N/A * <li>http://xml.org/sax/features/namespaces</li>
286N/A * <li>http://apache.org/xml/properties/internal/symbol-table</li>
286N/A * <li>http://apache.org/xml/properties/internal/error-reporter</li>
286N/A * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
286N/A * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
286N/A * </ul>
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A * @author Neil Graham, IBM
286N/A *
286N/A * @version $Id: XMLDTDProcessor.java,v 1.5 2010-11-01 04:39:42 joehw Exp $
286N/A */
286N/Apublic class XMLDTDProcessor
286N/A implements XMLComponent, XMLDTDFilter, XMLDTDContentModelFilter {
286N/A
286N/A //
286N/A // Constants
286N/A //
286N/A
286N/A /** Top level scope (-1). */
286N/A private static final int TOP_LEVEL_SCOPE = -1;
286N/A
286N/A // feature identifiers
286N/A
286N/A /** Feature identifier: validation. */
286N/A protected static final String VALIDATION =
286N/A Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
286N/A
286N/A /** Feature identifier: notify character references. */
286N/A protected static final String NOTIFY_CHAR_REFS =
286N/A Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
286N/A
286N/A /** Feature identifier: warn on duplicate attdef */
286N/A protected static final String WARN_ON_DUPLICATE_ATTDEF =
286N/A Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
286N/A
286N/A /** Feature identifier: warn on undeclared element referenced in content model. */
286N/A protected static final String WARN_ON_UNDECLARED_ELEMDEF =
286N/A Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
286N/A
286N/A protected static final String PARSER_SETTINGS =
286N/A Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
286N/A
286N/A // property identifiers
286N/A
286N/A /** Property identifier: symbol table. */
286N/A protected static final String SYMBOL_TABLE =
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
286N/A
286N/A /** Property identifier: error reporter. */
286N/A protected static final String ERROR_REPORTER =
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
286N/A
286N/A /** Property identifier: grammar pool. */
286N/A protected static final String GRAMMAR_POOL =
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
286N/A
286N/A /** Property identifier: validator . */
286N/A protected static final String DTD_VALIDATOR =
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
286N/A
286N/A // recognized features and properties
286N/A
286N/A /** Recognized features. */
286N/A private static final String[] RECOGNIZED_FEATURES = {
286N/A VALIDATION,
286N/A WARN_ON_DUPLICATE_ATTDEF,
286N/A WARN_ON_UNDECLARED_ELEMDEF,
286N/A NOTIFY_CHAR_REFS,
286N/A };
286N/A
286N/A /** Feature defaults. */
286N/A private static final Boolean[] FEATURE_DEFAULTS = {
286N/A null,
286N/A Boolean.FALSE,
286N/A Boolean.FALSE,
286N/A null,
286N/A };
286N/A
286N/A /** Recognized properties. */
286N/A private static final String[] RECOGNIZED_PROPERTIES = {
286N/A SYMBOL_TABLE,
286N/A ERROR_REPORTER,
286N/A GRAMMAR_POOL,
286N/A DTD_VALIDATOR,
286N/A };
286N/A
286N/A /** Property defaults. */
286N/A private static final Object[] PROPERTY_DEFAULTS = {
286N/A null,
286N/A null,
286N/A null,
286N/A null,
286N/A };
286N/A
286N/A // debugging
286N/A
286N/A //
286N/A // Data
286N/A //
286N/A
286N/A // features
286N/A
286N/A /** Validation. */
286N/A protected boolean fValidation;
286N/A
286N/A /** Validation against only DTD */
286N/A protected boolean fDTDValidation;
286N/A
286N/A /** warn on duplicate attribute definition, this feature works only when validation is true */
286N/A protected boolean fWarnDuplicateAttdef;
286N/A
286N/A /** warn on undeclared element referenced in content model, this feature only works when valiation is true */
286N/A protected boolean fWarnOnUndeclaredElemdef;
286N/A
286N/A // properties
286N/A
286N/A /** Symbol table. */
286N/A protected SymbolTable fSymbolTable;
286N/A
286N/A /** Error reporter. */
286N/A protected XMLErrorReporter fErrorReporter;
286N/A
286N/A /** Grammar bucket. */
286N/A protected DTDGrammarBucket fGrammarBucket;
286N/A
286N/A // the validator to which we look for our grammar bucket (the
286N/A // validator needs to hold the bucket so that it can initialize
286N/A // the grammar with details like whether it's for a standalone document...
286N/A protected XMLDTDValidator fValidator;
286N/A
286N/A // the grammar pool we'll try to add the grammar to:
286N/A protected XMLGrammarPool fGrammarPool;
286N/A
286N/A // what's our Locale?
286N/A protected Locale fLocale;
286N/A
286N/A // handlers
286N/A
286N/A /** DTD handler. */
286N/A protected XMLDTDHandler fDTDHandler;
286N/A
286N/A /** DTD source. */
286N/A protected XMLDTDSource fDTDSource;
286N/A
286N/A /** DTD content model handler. */
286N/A protected XMLDTDContentModelHandler fDTDContentModelHandler;
286N/A
286N/A /** DTD content model source. */
286N/A protected XMLDTDContentModelSource fDTDContentModelSource;
286N/A
286N/A // grammars
286N/A
286N/A /** DTD Grammar. */
286N/A protected DTDGrammar fDTDGrammar;
286N/A
286N/A // state
286N/A
286N/A /** Perform validation. */
286N/A private boolean fPerformValidation;
286N/A
286N/A /** True if in an ignore conditional section of the DTD. */
286N/A protected boolean fInDTDIgnore;
286N/A
286N/A // information regarding the current element
286N/A
286N/A // validation states
286N/A
286N/A /** Mixed. */
286N/A private boolean fMixed;
286N/A
286N/A // temporary variables
286N/A
286N/A /** Temporary entity declaration. */
286N/A private final XMLEntityDecl fEntityDecl = new XMLEntityDecl();
286N/A
286N/A /** Notation declaration hash. */
286N/A private final HashMap fNDataDeclNotations = new HashMap();
286N/A
286N/A /** DTD element declaration name. */
286N/A private String fDTDElementDeclName = null;
286N/A
286N/A /** Mixed element type "hash". */
286N/A private final ArrayList fMixedElementTypes = new ArrayList();
286N/A
286N/A /** Element declarations in DTD. */
286N/A private final ArrayList fDTDElementDecls = new ArrayList();
286N/A
286N/A // to check for duplicate ID or ANNOTATION attribute declare in
286N/A // ATTLIST, and misc VCs
286N/A
286N/A /** ID attribute names. */
286N/A private HashMap fTableOfIDAttributeNames;
286N/A
286N/A /** NOTATION attribute names. */
286N/A private HashMap fTableOfNOTATIONAttributeNames;
286N/A
286N/A /** NOTATION enumeration values. */
286N/A private HashMap fNotationEnumVals;
286N/A
286N/A //
286N/A // Constructors
286N/A //
286N/A
286N/A /** Default constructor. */
286N/A public XMLDTDProcessor() {
286N/A
286N/A // initialize data
286N/A
286N/A } // <init>()
286N/A
286N/A //
286N/A // XMLComponent methods
286N/A //
286N/A
286N/A /*
286N/A * Resets the component. The component can query the component manager
286N/A * about any features and properties that affect the operation of the
286N/A * component.
286N/A *
286N/A * @param componentManager The component manager.
286N/A *
286N/A * @throws SAXException Thrown by component on finitialization error.
286N/A * For example, if a feature or property is
286N/A * required for the operation of the component, the
286N/A * component manager may throw a
286N/A * SAXNotRecognizedException or a
286N/A * SAXNotSupportedException.
286N/A */
286N/A public void reset(XMLComponentManager componentManager) throws XMLConfigurationException {
286N/A
286N/A boolean parser_settings = componentManager.getFeature(PARSER_SETTINGS, true);
286N/A
286N/A if (!parser_settings) {
286N/A // parser settings have not been changed
286N/A reset();
286N/A return;
286N/A }
286N/A
286N/A // sax features
286N/A fValidation = componentManager.getFeature(VALIDATION, false);
286N/A
286N/A fDTDValidation =
286N/A !(componentManager
286N/A .getFeature(
286N/A Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE, false));
286N/A
286N/A // Xerces features
286N/A
286N/A fWarnDuplicateAttdef = componentManager.getFeature(WARN_ON_DUPLICATE_ATTDEF, false);
286N/A fWarnOnUndeclaredElemdef = componentManager.getFeature(WARN_ON_UNDECLARED_ELEMDEF, false);
286N/A
286N/A // get needed components
286N/A fErrorReporter =
286N/A (XMLErrorReporter) componentManager.getProperty(
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);
286N/A fSymbolTable =
286N/A (SymbolTable) componentManager.getProperty(
286N/A Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY);
286N/A
286N/A fGrammarPool = (XMLGrammarPool) componentManager.getProperty(GRAMMAR_POOL, null);
286N/A
286N/A try {
286N/A fValidator = (XMLDTDValidator) componentManager.getProperty(DTD_VALIDATOR, null);
286N/A } catch (ClassCastException e) {
286N/A fValidator = null;
286N/A }
286N/A // we get our grammarBucket from the validator...
286N/A if (fValidator != null) {
286N/A fGrammarBucket = fValidator.getGrammarBucket();
286N/A } else {
286N/A fGrammarBucket = null;
286N/A }
286N/A reset();
286N/A
286N/A } // reset(XMLComponentManager)
286N/A
286N/A protected void reset() {
286N/A // clear grammars
286N/A fDTDGrammar = null;
286N/A // initialize state
286N/A fInDTDIgnore = false;
286N/A
286N/A fNDataDeclNotations.clear();
286N/A
286N/A // datatype validators
286N/A if (fValidation) {
286N/A
286N/A if (fNotationEnumVals == null) {
286N/A fNotationEnumVals = new HashMap();
286N/A }
286N/A fNotationEnumVals.clear();
286N/A
286N/A fTableOfIDAttributeNames = new HashMap();
286N/A fTableOfNOTATIONAttributeNames = new HashMap();
286N/A }
286N/A
286N/A }
286N/A /**
286N/A * Returns a list of feature identifiers that are recognized by
286N/A * this component. This method may return null if no features
286N/A * are recognized by this component.
286N/A */
286N/A public String[] getRecognizedFeatures() {
286N/A return (String[])(RECOGNIZED_FEATURES.clone());
286N/A } // getRecognizedFeatures():String[]
286N/A
286N/A /**
286N/A * Sets the state of a feature. This method is called by the component
286N/A * manager any time after reset when a feature changes state.
286N/A * <p>
286N/A * <strong>Note:</strong> Components should silently ignore features
286N/A * that do not affect the operation of the component.
286N/A *
286N/A * @param featureId The feature identifier.
286N/A * @param state The state of the feature.
286N/A *
286N/A * @throws SAXNotRecognizedException The component should not throw
286N/A * this exception.
286N/A * @throws SAXNotSupportedException The component should not throw
286N/A * this exception.
286N/A */
286N/A public void setFeature(String featureId, boolean state)
286N/A throws XMLConfigurationException {
286N/A } // setFeature(String,boolean)
286N/A
286N/A /**
286N/A * Returns a list of property identifiers that are recognized by
286N/A * this component. This method may return null if no properties
286N/A * are recognized by this component.
286N/A */
286N/A public String[] getRecognizedProperties() {
286N/A return (String[])(RECOGNIZED_PROPERTIES.clone());
286N/A } // getRecognizedProperties():String[]
286N/A
286N/A /**
286N/A * Sets the value of a property. This method is called by the component
286N/A * manager any time after reset when a property changes value.
286N/A * <p>
286N/A * <strong>Note:</strong> Components should silently ignore properties
286N/A * that do not affect the operation of the component.
286N/A *
286N/A * @param propertyId The property identifier.
286N/A * @param value The value of the property.
286N/A *
286N/A * @throws SAXNotRecognizedException The component should not throw
286N/A * this exception.
286N/A * @throws SAXNotSupportedException The component should not throw
286N/A * this exception.
286N/A */
286N/A public void setProperty(String propertyId, Object value)
286N/A throws XMLConfigurationException {
286N/A } // setProperty(String,Object)
286N/A
286N/A /**
286N/A * Returns the default state for a feature, or null if this
286N/A * component does not want to report a default value for this
286N/A * feature.
286N/A *
286N/A * @param featureId The feature identifier.
286N/A *
286N/A * @since Xerces 2.2.0
286N/A */
286N/A public Boolean getFeatureDefault(String featureId) {
286N/A for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
286N/A if (RECOGNIZED_FEATURES[i].equals(featureId)) {
286N/A return FEATURE_DEFAULTS[i];
286N/A }
286N/A }
286N/A return null;
286N/A } // getFeatureDefault(String):Boolean
286N/A
286N/A /**
286N/A * Returns the default state for a property, or null if this
286N/A * component does not want to report a default value for this
286N/A * property.
286N/A *
286N/A * @param propertyId The property identifier.
286N/A *
286N/A * @since Xerces 2.2.0
286N/A */
286N/A public Object getPropertyDefault(String propertyId) {
286N/A for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
286N/A if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
286N/A return PROPERTY_DEFAULTS[i];
286N/A }
286N/A }
286N/A return null;
286N/A } // getPropertyDefault(String):Object
286N/A
286N/A //
286N/A // XMLDTDSource methods
286N/A //
286N/A
286N/A /**
286N/A * Sets the DTD handler.
286N/A *
286N/A * @param dtdHandler The DTD handler.
286N/A */
286N/A public void setDTDHandler(XMLDTDHandler dtdHandler) {
286N/A fDTDHandler = dtdHandler;
286N/A } // setDTDHandler(XMLDTDHandler)
286N/A
286N/A /**
286N/A * Returns the DTD handler.
286N/A *
286N/A * @return The DTD handler.
286N/A */
286N/A public XMLDTDHandler getDTDHandler() {
286N/A return fDTDHandler;
286N/A } // getDTDHandler(): XMLDTDHandler
286N/A
286N/A //
286N/A // XMLDTDContentModelSource methods
286N/A //
286N/A
286N/A /**
286N/A * Sets the DTD content model handler.
286N/A *
286N/A * @param dtdContentModelHandler The DTD content model handler.
286N/A */
286N/A public void setDTDContentModelHandler(XMLDTDContentModelHandler dtdContentModelHandler) {
286N/A fDTDContentModelHandler = dtdContentModelHandler;
286N/A } // setDTDContentModelHandler(XMLDTDContentModelHandler)
286N/A
286N/A /**
286N/A * Gets the DTD content model handler.
286N/A *
286N/A * @return dtdContentModelHandler The DTD content model handler.
286N/A */
286N/A public XMLDTDContentModelHandler getDTDContentModelHandler() {
286N/A return fDTDContentModelHandler;
286N/A } // getDTDContentModelHandler(): XMLDTDContentModelHandler
286N/A
286N/A //
286N/A // XMLDTDContentModelHandler and XMLDTDHandler methods
286N/A //
286N/A
286N/A /**
286N/A * The start of the DTD external subset.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startExternalSubset(XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.startExternalSubset(identifier, augs);
286N/A if(fDTDHandler != null){
286N/A fDTDHandler.startExternalSubset(identifier, augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * The end of the DTD external subset.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endExternalSubset(Augmentations augs) throws XNIException {
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.endExternalSubset(augs);
286N/A if(fDTDHandler != null){
286N/A fDTDHandler.endExternalSubset(augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Check standalone entity reference.
286N/A * Made static to make common between the validator and loader.
286N/A *
286N/A * @param name
286N/A *@param grammar grammar to which entity belongs
286N/A * @param tempEntityDecl empty entity declaration to put results in
286N/A * @param errorReporter error reporter to send errors to
286N/A *
286N/A * @throws XNIException Thrown by application to signal an error.
286N/A */
286N/A protected static void checkStandaloneEntityRef(String name, DTDGrammar grammar,
286N/A XMLEntityDecl tempEntityDecl, XMLErrorReporter errorReporter) throws XNIException {
286N/A // check VC: Standalone Document Declartion, entities references appear in the document.
286N/A int entIndex = grammar.getEntityDeclIndex(name);
286N/A if (entIndex > -1) {
286N/A grammar.getEntityDecl(entIndex, tempEntityDecl);
286N/A if (tempEntityDecl.inExternal) {
286N/A errorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE",
286N/A new Object[]{name}, XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * A comment.
286N/A *
286N/A * @param text The text in the comment.
286N/A * @param augs Additional information that may include infoset augmentations
286N/A *
286N/A * @throws XNIException Thrown by application to signal an error.
286N/A */
286N/A public void comment(XMLString text, Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.comment(text, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.comment(text, augs);
286N/A }
286N/A
286N/A } // comment(XMLString)
286N/A
286N/A
286N/A /**
286N/A * A processing instruction. Processing instructions consist of a
286N/A * target name and, optionally, text data. The data is only meaningful
286N/A * to the application.
286N/A * <p>
286N/A * Typically, a processing instruction's data will contain a series
286N/A * of pseudo-attributes. These pseudo-attributes follow the form of
286N/A * element attributes but are <strong>not</strong> parsed or presented
286N/A * to the application as anything other than text. The application is
286N/A * responsible for parsing the data.
286N/A *
286N/A * @param target The target.
286N/A * @param data The data or null if none specified.
286N/A * @param augs Additional information that may include infoset augmentations
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void processingInstruction(String target, XMLString data, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.processingInstruction(target, data, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.processingInstruction(target, data, augs);
286N/A }
286N/A } // processingInstruction(String,XMLString)
286N/A
286N/A //
286N/A // XMLDTDHandler methods
286N/A //
286N/A
286N/A /**
286N/A * The start of the DTD.
286N/A *
286N/A * @param locator The document locator, or null if the document
286N/A * location cannot be reported during the parsing of
286N/A * the document DTD. However, it is <em>strongly</em>
286N/A * recommended that a locator be supplied that can
286N/A * at least report the base system identifier of the
286N/A * DTD.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
286N/A
286N/A
286N/A // initialize state
286N/A fNDataDeclNotations.clear();
286N/A fDTDElementDecls.clear();
286N/A
286N/A // the grammar bucket's DTDGrammar will now be the
286N/A // one we want, whether we're constructing it or not.
286N/A // if we're not constructing it, then we should not have a reference
286N/A // to it!
286N/A if( !fGrammarBucket.getActiveGrammar().isImmutable()) {
286N/A fDTDGrammar = fGrammarBucket.getActiveGrammar();
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.startDTD(locator, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.startDTD(locator, augs);
286N/A }
286N/A
286N/A } // startDTD(XMLLocator)
286N/A
286N/A /**
286N/A * Characters within an IGNORE conditional section.
286N/A *
286N/A * @param text The ignored text.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void ignoredCharacters(XMLString text, Augmentations augs) throws XNIException {
286N/A
286N/A // ignored characters in DTD
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.ignoredCharacters(text, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.ignoredCharacters(text, augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Notifies of the presence of a TextDecl line in an entity. If present,
286N/A * this method will be called immediately following the startParameterEntity call.
286N/A * <p>
286N/A * <strong>Note:</strong> This method is only called for external
286N/A * parameter entities referenced in the DTD.
286N/A *
286N/A * @param version The XML version, or null if not specified.
286N/A * @param encoding The IANA encoding name of the entity.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void textDecl(String version, String encoding, Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.textDecl(version, encoding, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.textDecl(version, encoding, augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * This method notifies of the start of a parameter entity. The parameter
286N/A * entity name start with a '%' character.
286N/A *
286N/A * @param name The name of the parameter entity.
286N/A * @param identifier The resource identifier.
286N/A * @param encoding The auto-detected IANA encoding name of the entity
286N/A * stream. This value will be null in those situations
286N/A * where the entity encoding is not auto-detected (e.g.
286N/A * internal parameter entities).
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startParameterEntity(String name,
286N/A XMLResourceIdentifier identifier,
286N/A String encoding,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A if (fPerformValidation && fDTDGrammar != null &&
286N/A fGrammarBucket.getStandalone()) {
286N/A checkStandaloneEntityRef(name, fDTDGrammar, fEntityDecl, fErrorReporter);
286N/A }
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.startParameterEntity(name, identifier, encoding, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.startParameterEntity(name, identifier, encoding, augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * This method notifies the end of a parameter entity. Parameter entity
286N/A * names begin with a '%' character.
286N/A *
286N/A * @param name The name of the parameter entity.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endParameterEntity(String name, Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.endParameterEntity(name, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.endParameterEntity(name, augs);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * An element declaration.
286N/A *
286N/A * @param name The name of the element.
286N/A * @param contentModel The element content model.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void elementDecl(String name, String contentModel, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A //check VC: Unique Element Declaration
286N/A if (fValidation) {
286N/A if (fDTDElementDecls.contains(name)) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_ELEMENT_ALREADY_DECLARED",
286N/A new Object[]{ name},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A else {
286N/A fDTDElementDecls.add(name);
286N/A }
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.elementDecl(name, contentModel, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.elementDecl(name, contentModel, augs);
286N/A }
286N/A
286N/A } // elementDecl(String,String)
286N/A
286N/A /**
286N/A * The start of an attribute list.
286N/A *
286N/A * @param elementName The name of the element that this attribute
286N/A * list is associated with.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startAttlist(String elementName, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null )
286N/A fDTDGrammar.startAttlist(elementName, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.startAttlist(elementName, augs);
286N/A }
286N/A
286N/A } // startAttlist(String)
286N/A
286N/A /**
286N/A * An attribute declaration.
286N/A *
286N/A * @param elementName The name of the element that this attribute
286N/A * is associated with.
286N/A * @param attributeName The name of the attribute.
286N/A * @param type The attribute type. This value will be one of
286N/A * the following: "CDATA", "ENTITY", "ENTITIES",
286N/A * "ENUMERATION", "ID", "IDREF", "IDREFS",
286N/A * "NMTOKEN", "NMTOKENS", or "NOTATION".
286N/A * @param enumeration If the type has the value "ENUMERATION" or
286N/A * "NOTATION", this array holds the allowed attribute
286N/A * values; otherwise, this array is null.
286N/A * @param defaultType The attribute default type. This value will be
286N/A * one of the following: "#FIXED", "#IMPLIED",
286N/A * "#REQUIRED", or null.
286N/A * @param defaultValue The attribute default value, or null if no
286N/A * default value is specified.
286N/A * @param nonNormalizedDefaultValue The attribute default value with no normalization
286N/A * performed, or null if no default value is specified.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void attributeDecl(String elementName, String attributeName,
286N/A String type, String[] enumeration,
286N/A String defaultType, XMLString defaultValue,
286N/A XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
286N/A
286N/A if (type != XMLSymbols.fCDATASymbol && defaultValue != null) {
286N/A normalizeDefaultAttrValue(defaultValue);
286N/A }
286N/A
286N/A if (fValidation) {
286N/A
286N/A boolean duplicateAttributeDef = false ;
286N/A
286N/A //Get Grammar index to grammar array
286N/A DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar:fGrammarBucket.getActiveGrammar());
286N/A int elementIndex = grammar.getElementDeclIndex( elementName);
286N/A if (grammar.getAttributeDeclIndex(elementIndex, attributeName) != -1) {
286N/A //more than one attribute definition is provided for the same attribute of a given element type.
286N/A duplicateAttributeDef = true ;
286N/A
286N/A //this feature works only when validation is true.
286N/A if(fWarnDuplicateAttdef){
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_DUPLICATE_ATTRIBUTE_DEFINITION",
286N/A new Object[]{ elementName, attributeName },
286N/A XMLErrorReporter.SEVERITY_WARNING );
286N/A }
286N/A }
286N/A
286N/A
286N/A //
286N/A // a) VC: One ID per Element Type, If duplicate ID attribute
286N/A // b) VC: ID attribute Default. if there is a declareared attribute
286N/A // default for ID it should be of type #IMPLIED or #REQUIRED
286N/A if (type == XMLSymbols.fIDSymbol) {
286N/A if (defaultValue != null && defaultValue.length != 0) {
286N/A if (defaultType == null ||
286N/A !(defaultType == XMLSymbols.fIMPLIEDSymbol ||
286N/A defaultType == XMLSymbols.fREQUIREDSymbol)) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "IDDefaultTypeInvalid",
286N/A new Object[]{ attributeName},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A
286N/A if (!fTableOfIDAttributeNames.containsKey(elementName)) {
286N/A fTableOfIDAttributeNames.put(elementName, attributeName);
286N/A }
286N/A else {
286N/A //we should not report an error, when there is duplicate attribute definition for given element type
286N/A //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
286N/A //element type, the first declaration is binding and later declaration are *ignored*. So processor should
286N/A //ignore the second declarations, however an application would be warned of the duplicate attribute defintion
286N/A // if http://apache.org/xml/features/validation/warn-on-duplicate-attdef feature is set to true,
286N/A // one typical case where this could be a problem, when any XML file
286N/A // provide the ID type information through internal subset so that it is available to the parser which read
286N/A //only internal subset. Now that attribute declaration(ID Type) can again be part of external parsed entity
286N/A //referenced. At that time if parser doesn't make this distinction it will throw an error for VC One ID per
286N/A //Element Type, which (second defintion) actually should be ignored. Application behavior may differ on the
286N/A //basis of error or warning thrown. - nb.
286N/A
286N/A if(!duplicateAttributeDef){
286N/A String previousIDAttributeName = (String)fTableOfIDAttributeNames.get( elementName );//rule a)
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_MORE_THAN_ONE_ID_ATTRIBUTE",
286N/A new Object[]{ elementName, previousIDAttributeName, attributeName},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A }
286N/A
286N/A //
286N/A // VC: One Notation Per Element Type, should check if there is a
286N/A // duplicate NOTATION attribute
286N/A
286N/A if (type == XMLSymbols.fNOTATIONSymbol) {
286N/A // VC: Notation Attributes: all notation names in the
286N/A // (attribute) declaration must be declared.
286N/A for (int i=0; i<enumeration.length; i++) {
286N/A fNotationEnumVals.put(enumeration[i], attributeName);
286N/A }
286N/A
286N/A if (fTableOfNOTATIONAttributeNames.containsKey( elementName ) == false) {
286N/A fTableOfNOTATIONAttributeNames.put( elementName, attributeName);
286N/A }
286N/A else {
286N/A //we should not report an error, when there is duplicate attribute definition for given element type
286N/A //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
286N/A //element type, the first declaration is binding and later declaration are *ignored*. So processor should
286N/A //ignore the second declarations, however an application would be warned of the duplicate attribute definition
286N/A // if http://apache.org/xml/features/validation/warn-on-duplicate-attdef feature is set to true, Application behavior may differ on the basis of error or
286N/A //warning thrown. - nb.
286N/A
286N/A if(!duplicateAttributeDef){
286N/A
286N/A String previousNOTATIONAttributeName = (String) fTableOfNOTATIONAttributeNames.get( elementName );
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE",
286N/A new Object[]{ elementName, previousNOTATIONAttributeName, attributeName},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A }
286N/A
286N/A // VC: No Duplicate Tokens
286N/A // XML 1.0 SE Errata - E2
286N/A if (type == XMLSymbols.fENUMERATIONSymbol || type == XMLSymbols.fNOTATIONSymbol) {
286N/A outer:
286N/A for (int i = 0; i < enumeration.length; ++i) {
286N/A for (int j = i + 1; j < enumeration.length; ++j) {
286N/A if (enumeration[i].equals(enumeration[j])) {
286N/A // Only report the first uniqueness violation. There could be others,
286N/A // but additional overhead would be incurred tracking unique tokens
286N/A // that have already been encountered. -- mrglavas
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A type == XMLSymbols.fENUMERATIONSymbol
286N/A ? "MSG_DISTINCT_TOKENS_IN_ENUMERATION"
286N/A : "MSG_DISTINCT_NOTATION_IN_ENUMERATION",
286N/A new Object[]{ elementName, enumeration[i], attributeName },
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A break outer;
286N/A }
286N/A }
286N/A }
286N/A }
286N/A
286N/A // VC: Attribute Default Legal
286N/A boolean ok = true;
286N/A if (defaultValue != null &&
286N/A (defaultType == null ||
286N/A (defaultType != null && defaultType == XMLSymbols.fFIXEDSymbol))) {
286N/A
286N/A String value = defaultValue.toString();
286N/A if (type == XMLSymbols.fNMTOKENSSymbol ||
286N/A type == XMLSymbols.fENTITIESSymbol ||
286N/A type == XMLSymbols.fIDREFSSymbol) {
286N/A
286N/A StringTokenizer tokenizer = new StringTokenizer(value," ");
286N/A if (tokenizer.hasMoreTokens()) {
286N/A while (true) {
286N/A String nmtoken = tokenizer.nextToken();
286N/A if (type == XMLSymbols.fNMTOKENSSymbol) {
286N/A if (!isValidNmtoken(nmtoken)) {
286N/A ok = false;
286N/A break;
286N/A }
286N/A }
286N/A else if (type == XMLSymbols.fENTITIESSymbol ||
286N/A type == XMLSymbols.fIDREFSSymbol) {
286N/A if (!isValidName(nmtoken)) {
286N/A ok = false;
286N/A break;
286N/A }
286N/A }
286N/A if (!tokenizer.hasMoreTokens()) {
286N/A break;
286N/A }
286N/A }
286N/A }
286N/A
286N/A }
286N/A else {
286N/A if (type == XMLSymbols.fENTITYSymbol ||
286N/A type == XMLSymbols.fIDSymbol ||
286N/A type == XMLSymbols.fIDREFSymbol ||
286N/A type == XMLSymbols.fNOTATIONSymbol) {
286N/A
286N/A if (!isValidName(value)) {
286N/A ok = false;
286N/A }
286N/A
286N/A }
286N/A else if (type == XMLSymbols.fNMTOKENSymbol ||
286N/A type == XMLSymbols.fENUMERATIONSymbol) {
286N/A
286N/A if (!isValidNmtoken(value)) {
286N/A ok = false;
286N/A }
286N/A }
286N/A
286N/A if (type == XMLSymbols.fNOTATIONSymbol ||
286N/A type == XMLSymbols.fENUMERATIONSymbol) {
286N/A ok = false;
286N/A for (int i=0; i<enumeration.length; i++) {
286N/A if (defaultValue.equals(enumeration[i])) {
286N/A ok = true;
286N/A }
286N/A }
286N/A }
286N/A
286N/A }
286N/A if (!ok) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_ATT_DEFAULT_INVALID",
286N/A new Object[]{attributeName, value},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.attributeDecl(elementName, attributeName,
286N/A type, enumeration,
286N/A defaultType, defaultValue, nonNormalizedDefaultValue, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.attributeDecl(elementName, attributeName,
286N/A type, enumeration,
286N/A defaultType, defaultValue, nonNormalizedDefaultValue, augs);
286N/A }
286N/A
286N/A } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
286N/A
286N/A /**
286N/A * The end of an attribute list.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endAttlist(Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.endAttlist(augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.endAttlist(augs);
286N/A }
286N/A
286N/A } // endAttlist()
286N/A
286N/A /**
286N/A * An internal entity declaration.
286N/A *
286N/A * @param name The name of the entity. Parameter entity names start with
286N/A * '%', whereas the name of a general entity is just the
286N/A * entity name.
286N/A * @param text The value of the entity.
286N/A * @param nonNormalizedText The non-normalized value of the entity. This
286N/A * value contains the same sequence of characters that was in
286N/A * the internal entity declaration, without any entity
286N/A * references expanded.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void internalEntityDecl(String name, XMLString text,
286N/A XMLString nonNormalizedText,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar: fGrammarBucket.getActiveGrammar());
286N/A int index = grammar.getEntityDeclIndex(name) ;
286N/A
286N/A //If the same entity is declared more than once, the first declaration
286N/A //encountered is binding, SAX requires only effective(first) declaration
286N/A //to be reported to the application
286N/A
286N/A //REVISIT: Does it make sense to pass duplicate Entity information across
286N/A //the pipeline -- nb?
286N/A
286N/A //its a new entity and hasn't been declared.
286N/A if(index == -1){
286N/A //store internal entity declaration in grammar
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.internalEntityDecl(name, text, nonNormalizedText, augs);
286N/A // call handlers
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.internalEntityDecl(name, text, nonNormalizedText, augs);
286N/A }
286N/A }
286N/A
286N/A } // internalEntityDecl(String,XMLString,XMLString)
286N/A
286N/A
286N/A /**
286N/A * An external entity declaration.
286N/A *
286N/A * @param name The name of the entity. Parameter entity names start
286N/A * with '%', whereas the name of a general entity is just
286N/A * the entity name.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this external entity.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void externalEntityDecl(String name, XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar: fGrammarBucket.getActiveGrammar());
286N/A int index = grammar.getEntityDeclIndex(name) ;
286N/A
286N/A //If the same entity is declared more than once, the first declaration
286N/A //encountered is binding, SAX requires only effective(first) declaration
286N/A //to be reported to the application
286N/A
286N/A //REVISIT: Does it make sense to pass duplicate entity information across
286N/A //the pipeline -- nb?
286N/A
286N/A //its a new entity and hasn't been declared.
286N/A if(index == -1){
286N/A //store external entity declaration in grammar
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.externalEntityDecl(name, identifier, augs);
286N/A // call handlers
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.externalEntityDecl(name, identifier, augs);
286N/A }
286N/A }
286N/A
286N/A } // externalEntityDecl(String,XMLResourceIdentifier, Augmentations)
286N/A
286N/A /**
286N/A * An unparsed entity declaration.
286N/A *
286N/A * @param name The name of the entity.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this entity.
286N/A * @param notation The name of the notation.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
286N/A String notation,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A // VC: Notation declared, in the production of NDataDecl
286N/A if (fValidation) {
286N/A fNDataDeclNotations.put(name, notation);
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.unparsedEntityDecl(name, identifier, notation, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.unparsedEntityDecl(name, identifier, notation, augs);
286N/A }
286N/A
286N/A } // unparsedEntityDecl(String,XMLResourceIdentifier,String,Augmentations)
286N/A
286N/A /**
286N/A * A notation declaration
286N/A *
286N/A * @param name The name of the notation.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this notation.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void notationDecl(String name, XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A // VC: Unique Notation Name
286N/A if (fValidation) {
286N/A DTDGrammar grammar = (fDTDGrammar != null ? fDTDGrammar : fGrammarBucket.getActiveGrammar());
286N/A if (grammar.getNotationDeclIndex(name) != -1) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "UniqueNotationName",
286N/A new Object[]{name},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.notationDecl(name, identifier, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.notationDecl(name, identifier, augs);
286N/A }
286N/A
286N/A } // notationDecl(String,XMLResourceIdentifier, Augmentations)
286N/A
286N/A /**
286N/A * The start of a conditional section.
286N/A *
286N/A * @param type The type of the conditional section. This value will
286N/A * either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #CONDITIONAL_INCLUDE
286N/A * @see #CONDITIONAL_IGNORE
286N/A */
286N/A public void startConditional(short type, Augmentations augs) throws XNIException {
286N/A
286N/A // set state
286N/A fInDTDIgnore = type == XMLDTDHandler.CONDITIONAL_IGNORE;
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.startConditional(type, augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.startConditional(type, augs);
286N/A }
286N/A
286N/A } // startConditional(short)
286N/A
286N/A /**
286N/A * The end of a conditional section.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endConditional(Augmentations augs) throws XNIException {
286N/A
286N/A // set state
286N/A fInDTDIgnore = false;
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.endConditional(augs);
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.endConditional(augs);
286N/A }
286N/A
286N/A } // endConditional()
286N/A
286N/A /**
286N/A * The end of the DTD.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endDTD(Augmentations augs) throws XNIException {
286N/A
286N/A
286N/A // save grammar
286N/A if(fDTDGrammar != null) {
286N/A fDTDGrammar.endDTD(augs);
286N/A if(fGrammarPool != null)
286N/A fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD, new Grammar[] {fDTDGrammar});
286N/A }
286N/A if (fValidation) {
286N/A DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar: fGrammarBucket.getActiveGrammar());
286N/A
286N/A // VC : Notation Declared. for external entity declaration [Production 76].
286N/A Iterator entities = fNDataDeclNotations.entrySet().iterator();
286N/A while (entities.hasNext()) {
286N/A Map.Entry entry = (Map.Entry) entities.next();
286N/A String notation = (String) entry.getValue();
286N/A if (grammar.getNotationDeclIndex(notation) == -1) {
286N/A String entity = (String) entry.getKey();
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL",
286N/A new Object[]{entity, notation},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A
286N/A // VC: Notation Attributes:
286N/A // all notation names in the (attribute) declaration must be declared.
286N/A Iterator notationVals = fNotationEnumVals.entrySet().iterator();
286N/A while (notationVals.hasNext()) {
286N/A Map.Entry entry = (Map.Entry) notationVals.next();
286N/A String notation = (String) entry.getKey();
286N/A if (grammar.getNotationDeclIndex(notation) == -1) {
286N/A String attributeName = (String) entry.getValue();
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE",
286N/A new Object[]{attributeName, notation},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A
286N/A // VC: No Notation on Empty Element
286N/A // An attribute of type NOTATION must not be declared on an element declared EMPTY.
286N/A Iterator elementsWithNotations = fTableOfNOTATIONAttributeNames.entrySet().iterator();
286N/A while (elementsWithNotations.hasNext()) {
286N/A Map.Entry entry = (Map.Entry) elementsWithNotations.next();
286N/A String elementName = (String) entry.getKey();
286N/A int elementIndex = grammar.getElementDeclIndex(elementName);
286N/A if (grammar.getContentSpecType(elementIndex) == XMLElementDecl.TYPE_EMPTY) {
286N/A String attributeName = (String) entry.getValue();
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "NoNotationOnEmptyElement",
286N/A new Object[]{elementName, attributeName},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A }
286N/A
286N/A // should be safe to release these references
286N/A fTableOfIDAttributeNames = null;
286N/A fTableOfNOTATIONAttributeNames = null;
286N/A
286N/A // check whether each element referenced in a content model is declared
286N/A if (fWarnOnUndeclaredElemdef) {
286N/A checkDeclaredElements(grammar);
286N/A }
286N/A }
286N/A
286N/A // call handlers
286N/A if (fDTDHandler != null) {
286N/A fDTDHandler.endDTD(augs);
286N/A }
286N/A
286N/A } // endDTD()
286N/A
286N/A // sets the XMLDTDSource of this handler
286N/A public void setDTDSource(XMLDTDSource source ) {
286N/A fDTDSource = source;
286N/A } // setDTDSource(XMLDTDSource)
286N/A
286N/A // returns the XMLDTDSource of this handler
286N/A public XMLDTDSource getDTDSource() {
286N/A return fDTDSource;
286N/A } // getDTDSource(): XMLDTDSource
286N/A
286N/A //
286N/A // XMLDTDContentModelHandler methods
286N/A //
286N/A
286N/A // sets the XMLContentModelDTDSource of this handler
286N/A public void setDTDContentModelSource(XMLDTDContentModelSource source ) {
286N/A fDTDContentModelSource = source;
286N/A } // setDTDContentModelSource(XMLDTDContentModelSource)
286N/A
286N/A // returns the XMLDTDSource of this handler
286N/A public XMLDTDContentModelSource getDTDContentModelSource() {
286N/A return fDTDContentModelSource;
286N/A } // getDTDContentModelSource(): XMLDTDContentModelSource
286N/A
286N/A
286N/A /**
286N/A * The start of a content model. Depending on the type of the content
286N/A * model, specific methods may be called between the call to the
286N/A * startContentModel method and the call to the endContentModel method.
286N/A *
286N/A * @param elementName The name of the element.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startContentModel(String elementName, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A if (fValidation) {
286N/A fDTDElementDeclName = elementName;
286N/A fMixedElementTypes.clear();
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.startContentModel(elementName, augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.startContentModel(elementName, augs);
286N/A }
286N/A
286N/A } // startContentModel(String)
286N/A
286N/A /**
286N/A * A content model of ANY.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #empty
286N/A * @see #startGroup
286N/A */
286N/A public void any(Augmentations augs) throws XNIException {
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.any(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.any(augs);
286N/A }
286N/A } // any()
286N/A
286N/A /**
286N/A * A content model of EMPTY.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #any
286N/A * @see #startGroup
286N/A */
286N/A public void empty(Augmentations augs) throws XNIException {
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.empty(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.empty(augs);
286N/A }
286N/A } // empty()
286N/A
286N/A /**
286N/A * A start of either a mixed or children content model. A mixed
286N/A * content model will immediately be followed by a call to the
286N/A * <code>pcdata()</code> method. A children content model will
286N/A * contain additional groups and/or elements.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #any
286N/A * @see #empty
286N/A */
286N/A public void startGroup(Augmentations augs) throws XNIException {
286N/A
286N/A fMixed = false;
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.startGroup(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.startGroup(augs);
286N/A }
286N/A
286N/A } // startGroup()
286N/A
286N/A /**
286N/A * The appearance of "#PCDATA" within a group signifying a
286N/A * mixed content model. This method will be the first called
286N/A * following the content model's <code>startGroup()</code>.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #startGroup
286N/A */
286N/A public void pcdata(Augmentations augs) {
286N/A fMixed = true;
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.pcdata(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.pcdata(augs);
286N/A }
286N/A } // pcdata()
286N/A
286N/A /**
286N/A * A referenced element in a mixed or children content model.
286N/A *
286N/A * @param elementName The name of the referenced element.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void element(String elementName, Augmentations augs) throws XNIException {
286N/A
286N/A // check VC: No duplicate Types, in a single mixed-content declaration
286N/A if (fMixed && fValidation) {
286N/A if (fMixedElementTypes.contains(elementName)) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "DuplicateTypeInMixedContent",
286N/A new Object[]{fDTDElementDeclName, elementName},
286N/A XMLErrorReporter.SEVERITY_ERROR);
286N/A }
286N/A else {
286N/A fMixedElementTypes.add(elementName);
286N/A }
286N/A }
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.element(elementName, augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.element(elementName, augs);
286N/A }
286N/A
286N/A } // childrenElement(String)
286N/A
286N/A /**
286N/A * The separator between choices or sequences of a mixed or children
286N/A * content model.
286N/A *
286N/A * @param separator The type of children separator.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #SEPARATOR_CHOICE
286N/A * @see #SEPARATOR_SEQUENCE
286N/A */
286N/A public void separator(short separator, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.separator(separator, augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.separator(separator, augs);
286N/A }
286N/A
286N/A } // separator(short)
286N/A
286N/A /**
286N/A * The occurrence count for a child in a children content model or
286N/A * for the mixed content model group.
286N/A *
286N/A * @param occurrence The occurrence count for the last element
286N/A * or group.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #OCCURS_ZERO_OR_ONE
286N/A * @see #OCCURS_ZERO_OR_MORE
286N/A * @see #OCCURS_ONE_OR_MORE
286N/A */
286N/A public void occurrence(short occurrence, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.occurrence(occurrence, augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.occurrence(occurrence, augs);
286N/A }
286N/A
286N/A } // occurrence(short)
286N/A
286N/A /**
286N/A * The end of a group for mixed or children content models.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endGroup(Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.endGroup(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.endGroup(augs);
286N/A }
286N/A
286N/A } // endGroup()
286N/A
286N/A /**
286N/A * The end of a content model.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endContentModel(Augmentations augs) throws XNIException {
286N/A
286N/A // call handlers
286N/A if(fDTDGrammar != null)
286N/A fDTDGrammar.endContentModel(augs);
286N/A if (fDTDContentModelHandler != null) {
286N/A fDTDContentModelHandler.endContentModel(augs);
286N/A }
286N/A
286N/A } // endContentModel()
286N/A
286N/A //
286N/A // Private methods
286N/A //
286N/A
286N/A /**
286N/A * Normalize the attribute value of a non CDATA default attribute
286N/A * collapsing sequences of space characters (x20)
286N/A *
286N/A * @param value The value to normalize
286N/A * @return Whether the value was changed or not.
286N/A */
286N/A private boolean normalizeDefaultAttrValue(XMLString value) {
286N/A
286N/A boolean skipSpace = true; // skip leading spaces
286N/A int current = value.offset;
286N/A int end = value.offset + value.length;
286N/A for (int i = value.offset; i < end; i++) {
286N/A if (value.ch[i] == ' ') {
286N/A if (!skipSpace) {
286N/A // take the first whitespace as a space and skip the others
286N/A value.ch[current++] = ' ';
286N/A skipSpace = true;
286N/A }
286N/A else {
286N/A // just skip it.
286N/A }
286N/A }
286N/A else {
286N/A // simply shift non space chars if needed
286N/A if (current != i) {
286N/A value.ch[current] = value.ch[i];
286N/A }
286N/A current++;
286N/A skipSpace = false;
286N/A }
286N/A }
286N/A if (current != end) {
286N/A if (skipSpace) {
286N/A // if we finished on a space trim it
286N/A current--;
286N/A }
286N/A // set the new value length
286N/A value.length = current - value.offset;
286N/A return true;
286N/A }
286N/A return false;
286N/A }
286N/A
286N/A protected boolean isValidNmtoken(String nmtoken) {
286N/A return XMLChar.isValidNmtoken(nmtoken);
286N/A } // isValidNmtoken(String): boolean
286N/A
286N/A protected boolean isValidName(String name) {
286N/A return XMLChar.isValidName(name);
286N/A } // isValidName(String): boolean
286N/A
286N/A /**
286N/A * Checks that all elements referenced in content models have
286N/A * been declared. This method calls out to the error handler
286N/A * to indicate warnings.
286N/A */
286N/A private void checkDeclaredElements(DTDGrammar grammar) {
286N/A int elementIndex = grammar.getFirstElementDeclIndex();
286N/A XMLContentSpec contentSpec = new XMLContentSpec();
286N/A while (elementIndex >= 0) {
286N/A int type = grammar.getContentSpecType(elementIndex);
286N/A if (type == XMLElementDecl.TYPE_CHILDREN || type == XMLElementDecl.TYPE_MIXED) {
286N/A checkDeclaredElements(grammar,
286N/A elementIndex,
286N/A grammar.getContentSpecIndex(elementIndex),
286N/A contentSpec);
286N/A }
286N/A elementIndex = grammar.getNextElementDeclIndex(elementIndex);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Does a recursive (if necessary) check on the specified element's
286N/A * content spec to make sure that all children refer to declared
286N/A * elements.
286N/A */
286N/A private void checkDeclaredElements(DTDGrammar grammar, int elementIndex,
286N/A int contentSpecIndex, XMLContentSpec contentSpec) {
286N/A grammar.getContentSpec(contentSpecIndex, contentSpec);
286N/A if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A String value = (String) contentSpec.value;
286N/A if (value != null && grammar.getElementDeclIndex(value) == -1) {
286N/A fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
286N/A "UndeclaredElementInContentSpec",
286N/A new Object[]{grammar.getElementDeclName(elementIndex).rawname, value},
286N/A XMLErrorReporter.SEVERITY_WARNING);
286N/A }
286N/A }
286N/A // It's not a leaf, so we have to recurse its left and maybe right
286N/A // nodes. Save both values before we recurse and trash the node.
286N/A else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
286N/A || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
286N/A final int leftNode = ((int[])contentSpec.value)[0];
286N/A final int rightNode = ((int[])contentSpec.otherValue)[0];
286N/A // Recurse on both children.
286N/A checkDeclaredElements(grammar, elementIndex, leftNode, contentSpec);
286N/A checkDeclaredElements(grammar, elementIndex, rightNode, contentSpec);
286N/A }
286N/A else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
286N/A || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
286N/A || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
286N/A final int leftNode = ((int[])contentSpec.value)[0];
286N/A checkDeclaredElements(grammar, elementIndex, leftNode, contentSpec);
286N/A }
286N/A }
286N/A
286N/A} // class XMLDTDProcessor