You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2002/06/03 23:23:04 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/impl/dtd XMLDTDLoader.java XMLDTDValidator.java XMLDTDDescription.java DTDGrammarBucket.java DTDGrammar.java

neilg       2002/06/03 14:23:04

  Modified:    java/src/org/apache/xerces/parsers DTDConfiguration.java
               java/src/org/apache/xerces/impl/dtd XMLDTDValidator.java
                        XMLDTDDescription.java DTDGrammarBucket.java
                        DTDGrammar.java
  Added:       java/src/org/apache/xerces/impl/dtd XMLDTDLoader.java
  Log:
  Breaking XMLDTDValidator into two components:  one, thich implements DocumentHandler, does validation of instance documents given a grammar; the other, XMLDTDLoader, implements XMLDTDHandler and XMLDTDContentModelHandler and constructs the grammars.  All that now should be necessary to make DTD grammar caching work is for XMLDTDLoader to actually implement XMLGrammarLoader and to make the grammars it constructs available to the grammar pool.  Then it should be relatively straightforward to slap preparsing functionality on XMLDTDLoader by giving it the ability to talk appropriately with the DTD scanner.
  
  Revision  Changes    Path
  1.3       +28 -6     xml-xerces/java/src/org/apache/xerces/parsers/DTDConfiguration.java
  
  Index: DTDConfiguration.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/DTDConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DTDConfiguration.java	22 May 2002 13:06:19 -0000	1.2
  +++ DTDConfiguration.java	3 Jun 2002 21:23:03 -0000	1.3
  @@ -66,6 +66,7 @@
   import org.apache.xerces.impl.XMLErrorReporter;
   import org.apache.xerces.impl.XMLEntityManager;
   import org.apache.xerces.impl.dtd.XMLDTDValidator;
  +import org.apache.xerces.impl.dtd.XMLDTDLoader;
   import org.apache.xerces.impl.XMLNamespaceBinder;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.impl.validation.ValidationManager;
  @@ -120,7 +121,7 @@
    * @author Andy Clark, IBM
    * @author Neil Graham, IBM
    *
  - * @version $Id: DTDConfiguration.java,v 1.2 2002/05/22 13:06:19 neeraj Exp $
  + * @version $Id: DTDConfiguration.java,v 1.3 2002/06/03 21:23:03 neilg Exp $
    */
   public class DTDConfiguration
       extends BasicParserConfiguration 
  @@ -187,6 +188,10 @@
       protected static final String XMLGRAMMAR_POOL = 
           Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
       
  +    /** Property identifier: DTD loader. */
  +    protected static final String DTD_LOADER = 
  +        Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_LOADER_PROPERTY;
  +
       /** Property identifier: DTD validator. */
       protected static final String DTD_VALIDATOR = 
           Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
  @@ -237,6 +242,9 @@
       /** DTD scanner. */
       protected XMLDTDScanner fDTDScanner;
   
  +    /** DTD Loader . */
  +    protected XMLDTDLoader fDTDLoader;
  +
       /** DTD Validator. */
       protected XMLDTDValidator fDTDValidator;
   
  @@ -332,6 +340,7 @@
               ENTITY_MANAGER, 
               DOCUMENT_SCANNER,
               DTD_SCANNER,
  +            DTD_LOADER,
               DTD_VALIDATOR,
               NAMESPACE_BINDER,
               XMLGRAMMAR_POOL,   
  @@ -368,6 +377,14 @@
               }
           }
   
  +        fDTDLoader = createDTDLoader();
  +        if (fDTDLoader != null) {
  +            setProperty(DTD_LOADER, fDTDLoader);
  +            if (fDTDLoader instanceof XMLComponent) {
  +                addComponent((XMLComponent)fDTDLoader);
  +            }
  +        }
  +
           fDTDValidator = createDTDValidator();
           if (fDTDValidator != null) {
               setProperty(DTD_VALIDATOR, fDTDValidator);
  @@ -632,12 +649,12 @@
   
           // setup dtd pipeline
           if (fDTDScanner != null) {
  -            if (fDTDValidator != null) {
  -                fDTDScanner.setDTDHandler(fDTDValidator);
  -                fDTDValidator.setDTDHandler(fDTDHandler);
  +            if (fDTDLoader != null) {
  +                fDTDScanner.setDTDHandler(fDTDLoader);
  +                fDTDLoader.setDTDHandler(fDTDHandler);
                   
  -                fDTDScanner.setDTDContentModelHandler(fDTDValidator);
  -                fDTDValidator.setDTDContentModelHandler(fDTDContentModelHandler);
  +                fDTDScanner.setDTDContentModelHandler(fDTDLoader);
  +                fDTDLoader.setDTDContentModelHandler(fDTDContentModelHandler);
               }
               else {
                   fDTDScanner.setDTDHandler(fDTDHandler);
  @@ -782,6 +799,11 @@
       protected XMLDTDScanner createDTDScanner() {
           return new XMLDTDScannerImpl();
       } // createDTDScanner():XMLDTDScanner
  +
  +    /** Create a DTD loader . */
  +    protected XMLDTDLoader createDTDLoader() {
  +        return new XMLDTDLoader();
  +    } // createDTDLoader():XMLDTDLoader
   
       /** Create a DTD validator. */
       protected XMLDTDValidator createDTDValidator() {
  
  
  
  1.25      +237 -1277 xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDValidator.java
  
  Index: XMLDTDValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDValidator.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- XMLDTDValidator.java	21 May 2002 20:20:24 -0000	1.24
  +++ XMLDTDValidator.java	3 Jun 2002 21:23:03 -0000	1.25
  @@ -77,17 +77,16 @@
   import org.apache.xerces.xni.XMLString;
   import org.apache.xerces.xni.XMLAttributes;
   import org.apache.xerces.xni.XMLDocumentHandler;
  -import org.apache.xerces.xni.XMLDTDHandler;
  -import org.apache.xerces.xni.XMLDTDContentModelHandler;
   import org.apache.xerces.xni.XMLLocator;
   import org.apache.xerces.xni.XMLResourceIdentifier;
   import org.apache.xerces.xni.XNIException;
  +import org.apache.xerces.xni.grammars.XMLGrammarPool;
  +import org.apache.xerces.xni.grammars.XMLGrammarDescription;
  +import org.apache.xerces.xni.grammars.Grammar;
   import org.apache.xerces.xni.parser.XMLComponent;
   import org.apache.xerces.xni.parser.XMLComponentManager;
   import org.apache.xerces.xni.parser.XMLConfigurationException;
   import org.apache.xerces.xni.parser.XMLDocumentFilter;
  -import org.apache.xerces.xni.parser.XMLDTDFilter;
  -import org.apache.xerces.xni.parser.XMLDTDContentModelFilter;
   
   import java.util.Enumeration;
   import java.util.Hashtable;
  @@ -100,6 +99,11 @@
    * the content and structure; augmenting the InfoSet, if applicable;
    * and notifying the parser of the information resulting from the
    * validation process.
  + * <p> Formerly, this component also handled DTD events and grammar construction.
  + * To facilitate the development of a meaningful DTD grammar caching/preparsing
  + * framework, this functionality has been moved into the XMLDTDLoader
  + * class.  Therefore, this class no longer implements the DTDFilter
  + * or DTDContentModelFilter interfaces.
    * <p>
    * This component requires the following features and properties from the
    * component manager that uses it:
  @@ -116,17 +120,62 @@
    * @author Eric Ye, IBM
    * @author Andy Clark, IBM
    * @author Jeffrey Rodriguez IBM
  + * @author Neil Graham, IBM
    *
  - * @version $Id: XMLDTDValidator.java,v 1.24 2002/05/21 20:20:24 neilg Exp $
  + * @version $Id: XMLDTDValidator.java,v 1.25 2002/06/03 21:23:03 neilg Exp $
    */
   public class XMLDTDValidator
  -implements XMLComponent, 
  -XMLDocumentFilter, XMLDTDFilter, XMLDTDContentModelFilter {
  +        implements XMLComponent, XMLDocumentFilter {
   
       //
       // Constants
       //
   
  +    // REVISIT:  these should not be in Validator!
  +
  +    // symbols: DTD datatype
  +
  +    /** Symbol: "CDATA". */
  +    private String fCDATASymbol;
  +
  +    /** Symbol: "ID". */
  +    private String fIDSymbol;
  +
  +    /** Symbol: "IDREF". */
  +    private String fIDREFSymbol;
  +
  +    /** Symbol: "IDREFS". */
  +    private String fIDREFSSymbol;
  +
  +    /** Symbol: "ENTITY". */
  +    private String fENTITYSymbol;
  +
  +    /** Symbol: "ENTITIES". */
  +    private String fENTITIESSymbol;
  +
  +    /** Symbol: "NMTOKEN". */
  +    private String fNMTOKENSymbol;
  +
  +    /** Symbol: "NMTOKENS". */
  +    private String fNMTOKENSSymbol;
  +
  +    /** Symbol: "NOTATION". */
  +    private String fNOTATIONSymbol;
  +
  +    /** Symbol: "ENUMERATION". */
  +    private String fENUMERATIONSymbol;
  +
  +    /** Symbol: "#IMPLIED. */
  +    private String fIMPLIEDSymbol;
  +
  +    /** Symbol: "#REQUIRED". */
  +    private String fREQUIREDSymbol;
  +
  +    /** Symbol: "#FIXED". */
  +    private String fFIXEDSymbol;
  +
  +    /** Symbol: "&lt;&lt;datatypes>>". */
  +
       /** Top level scope (-1). */
       private static final int TOP_LEVEL_SCOPE = -1;
   
  @@ -184,7 +233,7 @@
       protected static final String[] RECOGNIZED_PROPERTIES = {
           SYMBOL_TABLE,       
           ERROR_REPORTER,
  -        GRAMMAR_POOL,       
  +        GRAMMAR_POOL,
           DATATYPE_VALIDATOR_FACTORY,
           VALIDATION_MANAGER
       };
  @@ -235,9 +284,15 @@
       /** Error reporter. */
       protected XMLErrorReporter fErrorReporter;
   
  +    // the grammar pool
  +    protected XMLGrammarPool fGrammarPool;
  +
       /** Grammar bucket. */
       protected DTDGrammarBucket fGrammarBucket;
   
  +    /* location of the document as passed in from startDocument call */
  +    protected XMLResourceIdentifier fDocLocation;
  +
       /** Datatype validator factory. */
       protected DTDDVFactory fDatatypeValidatorFactory;
   
  @@ -246,12 +301,6 @@
       /** Document handler. */
       protected XMLDocumentHandler fDocumentHandler;
   
  -    /** DTD handler. */
  -    protected XMLDTDHandler fDTDHandler;
  -
  -    /** DTD content model handler. */
  -    protected XMLDTDContentModelHandler fDTDContentModelHandler;
  -
       // grammars
   
       /** DTD Grammar. */
  @@ -265,12 +314,6 @@
       /** Skip validation. */
       private boolean fSkipValidation;
   
  -    /** True if in DTD. */
  -    protected boolean fInDTD;
  -
  -    /** True if in an ignore conditional section of the DTD. */
  -    protected boolean fInDTDIgnore;
  -
       // information regarding the current element
   
       /** Current element name. */
  @@ -332,18 +375,12 @@
   
       // validation states
   
  -    /** Validation of a standalone document. */
  -    private boolean fStandaloneIsYes = false;
  -
       /** True if seen the root element. */
       private boolean fSeenRootElement = false;
   
       /** True if inside of element content. */
       private boolean fInElementContent = false;
   
  -    /** Mixed. */
  -    private boolean fMixed;
  -
       // temporary variables
   
       /** Temporary element declaration. */
  @@ -358,82 +395,11 @@
       /** Temporary qualified name. */
       private QName fTempQName = new QName();
   
  -    /** Temporary string buffer for buffering datatype value. */
  -    //private StringBuffer fDatatypeBuffer = new StringBuffer();
  -
  -    /** Notation declaration hash. */
  -    private Hashtable fNDataDeclNotations = new Hashtable();
  -
  -    /** DTD element declaration name. */
  -    private String fDTDElementDeclName = null;
  -
  -    /** Mixed element type "hash". */
  -    private Vector fMixedElementTypes = new Vector();
  -
  -    /** Element declarations in DTD. */
  -    private Vector fDTDElementDecls = new Vector();
  -
       /** Temporary string buffers. */
       private StringBuffer fBuffer = new StringBuffer();
   
       // symbols: general
   
  -    /** Symbol: "EMPTY". */
  -    private String fEMPTYSymbol;
  -
  -    /** Symbol: "ANY". */
  -    private String fANYSymbol;
  -
  -    /** Symbol: "MIXED". */
  -    private String fMIXEDSymbol;
  -
  -    /** Symbol: "CHILDREN". */
  -    private String fCHILDRENSymbol;
  -
  -    // symbols: DTD datatype
  -
  -    /** Symbol: "CDATA". */
  -    private String fCDATASymbol;
  -
  -    /** Symbol: "ID". */
  -    private String fIDSymbol;
  -
  -    /** Symbol: "IDREF". */
  -    private String fIDREFSymbol;
  -
  -    /** Symbol: "IDREFS". */
  -    private String fIDREFSSymbol;
  -
  -    /** Symbol: "ENTITY". */
  -    private String fENTITYSymbol;
  -
  -    /** Symbol: "ENTITIES". */
  -    private String fENTITIESSymbol;
  -
  -    /** Symbol: "NMTOKEN". */
  -    private String fNMTOKENSymbol;
  -
  -    /** Symbol: "NMTOKENS". */
  -    private String fNMTOKENSSymbol;
  -
  -    /** Symbol: "NOTATION". */
  -    private String fNOTATIONSymbol;
  -
  -    /** Symbol: "ENUMERATION". */
  -    private String fENUMERATIONSymbol;
  -
  -    /** Symbol: "#IMPLIED. */
  -    private String fIMPLIEDSymbol;
  -
  -    /** Symbol: "#REQUIRED". */
  -    private String fREQUIREDSymbol;
  -
  -    /** Symbol: "#FIXED". */
  -    private String fFIXEDSymbol;
  -
  -    /** Symbol: "&lt;&lt;datatypes>>". */
  -    private String fDATATYPESymbol;
  -
       // attribute validators
   
       /** Datatype validator: ID. */
  @@ -463,15 +429,6 @@
       // to check for duplicate ID or ANNOTATION attribute declare in
       // ATTLIST, and misc VCs
   
  -    /** ID attribute names. */
  -    private Hashtable fTableOfIDAttributeNames;
  -
  -    /** NOTATION attribute names. */
  -    private Hashtable fTableOfNOTATIONAttributeNames;
  -
  -    /** NOTATION enumeration values. */
  -    private Hashtable fNotationEnumVals;
  -
       //
       // Constructors
       //
  @@ -483,9 +440,14 @@
           for (int i = 0; i < fElementQNamePartsStack.length; i++) {
               fElementQNamePartsStack[i] = new QName();
           }
  +        fGrammarBucket = new DTDGrammarBucket();
   
       } // <init>()
   
  +    DTDGrammarBucket getGrammarBucket() {
  +        return fGrammarBucket;
  +    } // getGrammarBucket():  DTDGrammarBucket
  +
       //
       // XMLComponent methods
       //
  @@ -512,9 +474,6 @@
           fSeenDoctypeDecl = false;
           fInCDATASection = false;
           // initialize state
  -        fInDTD = false;
  -        fInDTDIgnore = false;
  -        fStandaloneIsYes = false;
           fSeenRootElement = false;
           fInElementContent = false;
           fCurrentElementIndex = -1;
  @@ -523,8 +482,6 @@
   
           fRootElement.clear();
   
  -        fNDataDeclNotations.clear();
  -
           // sax features
           try {
               fNamespaces = componentManager.getFeature(NAMESPACES);
  @@ -569,7 +526,12 @@
           // get needed components
           fErrorReporter = (XMLErrorReporter)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.ERROR_REPORTER_PROPERTY);
           fSymbolTable = (SymbolTable)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY);
  -        fGrammarBucket = new DTDGrammarBucket();
  +        try {
  +            fGrammarPool= (XMLGrammarPool)componentManager.getProperty(GRAMMAR_POOL);
  +        } catch (XMLConfigurationException e) {
  +            fGrammarPool = null;
  +        }
  +        fGrammarBucket.clear();
           fDatatypeValidatorFactory = (DTDDVFactory)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY);
   
           fElementDepth = -1;                      
  @@ -647,32 +609,6 @@
       } // setDocumentHandler(XMLDocumentHandler)
   
       //
  -    // XMLDTDSource methods
  -    //
  -
  -    /**
  -     * Sets the DTD handler.
  -     * 
  -     * @param dtdHandler The DTD handler.
  -     */
  -    public void setDTDHandler(XMLDTDHandler dtdHandler) {
  -        fDTDHandler = dtdHandler;
  -    } // setDTDHandler(XMLDTDHandler)
  -
  -    //
  -    // XMLDTDContentModelSource methods
  -    //
  -
  -    /**
  -     * Sets the DTD content model handler.
  -     * 
  -     * @param dtdContentModelHandler The DTD content model handler.
  -     */
  -    public void setDTDContentModelHandler(XMLDTDContentModelHandler dtdContentModelHandler) {
  -        fDTDContentModelHandler = dtdContentModelHandler;
  -    } // setDTDContentModelHandler(XMLDTDContentModelHandler)
  -
  -    //
       // XMLDocumentHandler methods
       //
   
  @@ -694,6 +630,14 @@
       throws XNIException {
   
           // call handlers
  +        // get initial grammars
  +        if(fGrammarPool != null) {
  +            Grammar [] grammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_DTD);
  +            for(int i = 0; i<grammars.length; i++) {
  +                fGrammarBucket.putGrammar((DTDGrammar)grammars[i]);
  +            }
  +        }
  +        fDocLocation = locator;
           if (fDocumentHandler != null) {
               fDocumentHandler.startDocument(locator, encoding, augs);
           }
  @@ -717,7 +661,7 @@
       throws XNIException {
   
           // save standalone state
  -        fStandaloneIsYes = standalone != null && standalone.equals("yes");
  +        fGrammarBucket.setStandalone(standalone != null && standalone.equals("yes"));
   
           // call handlers
           if (fDocumentHandler != null) {
  @@ -745,13 +689,27 @@
           // save root element state
           fSeenDoctypeDecl = true;
           fRootElement.setValues(null, rootElement, rootElement, null);
  +        // find or create grammar:
  +        XMLDTDDescription grammarDesc = new XMLDTDDescription(fDocLocation, rootElement);
  +        fDTDGrammar = fGrammarBucket.getGrammar(grammarDesc);
  +        if(fDTDGrammar == null) {
  +            // give grammar pool a chance...
  +            if(fGrammarPool != null) {
  +                fDTDGrammar = (DTDGrammar)fGrammarPool.retrieveGrammar(grammarDesc);
  +            }
  +        }
  +        if(fDTDGrammar == null) {
  +            // we'll have to create it...
  +            fDTDGrammar = new DTDGrammar(fSymbolTable, grammarDesc);
  +        }
  +        fGrammarBucket.setActiveGrammar(fDTDGrammar);
   
           // call handlers
           if (fDocumentHandler != null) {
               fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
           }
   
  -    } // doctypeDecl(String,String,String)
  +    } // doctypeDecl(String,String,String, Augmentations)
   
       /**
        * The start of a namespace prefix mapping. This method will only be
  @@ -852,7 +810,7 @@
           // validate
           if (fPerformValidation) {
               if (fInElementContent) {
  -                if (fStandaloneIsYes &&
  +                if (fGrammarBucket.getStandalone() &&
                       fDTDGrammar.getElementDeclIsExternal(fCurrentElementIndex)) {
                       if (allWhiteSpace) {
                           fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  @@ -861,1177 +819,243 @@
                       }
                   }
                   if (!allWhiteSpace) {
  -                    charDataInContent();
  -                }
  -            }
  -
  -            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
  -                charDataInContent();
  -            }
  -        }
  -
  -        // call handlers
  -        if (callNextCharacters && fDocumentHandler != null) {
  -            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 {
  -
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            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 {
  -
  -        handleEndElement(element,  augs, false);
  -
  -    } // endElement(QName)
  -
  -    /**
  -     * The end of a namespace prefix mapping. This method will only be
  -     * called when namespace processing is enabled.
  -     * 
  -     * @param prefix The namespace prefix.
  -     * @param augs   Additional information that may include infoset augmentations
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void endPrefixMapping(String prefix, Augmentations augs) throws XNIException {
  -
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            fDocumentHandler.endPrefixMapping(prefix, augs);
  -        }
  -
  -    } // endPrefixMapping(String)
  -
  -    /** 
  -     * The start of a CDATA section. 
  -     * @param augs   Additional information that may include infoset augmentations
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void startCDATA(Augmentations augs) throws XNIException {
  -
  -        if (fPerformValidation && fInElementContent) {
  -            charDataInContent();
  -        }
  -        fInCDATASection = true;
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            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 {
  -
  -        fInCDATASection = false;
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            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 {
  -
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            fDocumentHandler.endDocument(augs);
  -        }
  -
  -    } // endDocument()
  -
  -    //
  -    // XMLDocumentHandler and XMLDTDHandler methods
  -    //
  -
  -    /**
  -     * The start of the DTD external subset.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void startExternalSubset(XMLResourceIdentifier identifier, 
  -                                    Augmentations augs) throws XNIException {
  -        fDTDGrammar.startExternalSubset(identifier, augs);
  -        if(fDTDHandler != null){
  -            fDTDHandler.startExternalSubset(identifier, augs);
  -        }
  -    }
  -
  -    /**
  -     * The end of the DTD external subset.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void endExternalSubset(Augmentations augs) throws XNIException {
  -        fDTDGrammar.endExternalSubset(augs);
  -        if(fDTDHandler != null){
  -            fDTDHandler.endExternalSubset(augs);
  -        }
  -    }
  -
  -    /**
  -     * 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 {
  -        checkStandaloneEntityRef(name);
  -        if (fDocumentHandler != null) {
  -            fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs);
  -        }
  -    }
  -
  -    /** 
  -     * Check standalone entity reference. 
  -     * 
  -     * @param name
  -     *
  -     * @throws XNIException Thrown by application to signal an error.
  -     */
  -    protected void checkStandaloneEntityRef(String name) throws XNIException {
  -        // check VC: Standalone Document Declartion, entities references appear in the document.
  -        if (fPerformValidation && fDTDGrammar != null) {
  -            if (fStandaloneIsYes) {
  -                int entIndex = fDTDGrammar.getEntityDeclIndex(name);
  -                if (entIndex > -1) {
  -                    fDTDGrammar.getEntityDecl(entIndex, fEntityDecl);
  -                    if (fEntityDecl.inExternal) {
  -                        fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                                                    "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE",
  -                                                    new Object[]{name}, XMLErrorReporter.SEVERITY_ERROR);
  -                    }
  -                }
  -            }
  -        }
  -    }
  -
  -    /**
  -     * 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 {
  -
  -        // call handlers
  -        if (fInDTD) {
  -            fDTDGrammar.comment(text, augs);
  -            if (fDTDHandler != null) {
  -                fDTDHandler.comment(text, augs);
  -            }
  -        }
  -        else {
  -            if (fDocumentHandler != null) {
  -                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 {
  -
  -        // call handlers
  -        if (fInDTD) {
  -            fDTDGrammar.processingInstruction(target, data, augs);
  -            if (fDTDHandler != null) {
  -                fDTDHandler.processingInstruction(target, data, augs);
  -            }
  -        }
  -        else {
  -            if (fDocumentHandler != null) {
  -                fDocumentHandler.processingInstruction(target, data, augs);
  -            }
  -        }
  -    } // processingInstruction(String,XMLString)
  -
  -
  -    /**
  -     * 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 {
  -        // call handlers
  -        if (fDocumentHandler != null) {
  -            fDocumentHandler.endGeneralEntity(name, augs);
  -        }
  -    } // endEntity(String)
  -
  -    //
  -    // XMLDTDHandler methods
  -    //
  -
  -    /**
  -     * The start of the DTD.
  -     *
  -     * @param locator  The document locator, or null if the document
  -     *                 location cannot be reported during the parsing of 
  -     *                 the document DTD. However, it is <em>strongly</em>
  -     *                 recommended that a locator be supplied that can 
  -     *                 at least report the base system identifier of the
  -     *                 DTD.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
  -
  -        fInDTD = true;
  -
  -        // initialize state
  -        fNDataDeclNotations.clear();
  -        fDTDElementDecls.removeAllElements();
  -
  -        // create DTD grammar
  -        fDTDGrammar = createDTDGrammar();
  -        //fDTDGrammar.setDatatypeValidatorFactory(fDatatypeValidatorFactory);
  -        // REVISIT: should we use the systemId as the key instead?
  -        fGrammarBucket.putGrammar("", fDTDGrammar);
  -
  -        // call handlers
  -        fDTDGrammar.startDTD(locator, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.startDTD(locator, augs);
  -        }
  -
  -    } // startDTD(XMLLocator)
  -
  -    /**
  -     * Characters within an IGNORE conditional section.
  -     *
  -     * @param text The ignored text.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void ignoredCharacters(XMLString text, Augmentations augs) throws XNIException {
  -
  -        // ignored characters in DTD
  -        if (fDTDHandler != null) {
  -            fDTDHandler.ignoredCharacters(text, augs);
  -        }
  -    }
  -
  -    /**
  -     * Notifies of the presence of a TextDecl line in an entity. If present,
  -     * this method will be called immediately following the startParameterEntity call.
  -     * <p>
  -     * <strong>Note:</strong> This method is only called for external
  -     * parameter entities referenced in the DTD.
  -     * 
  -     * @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 {
  -
  -        // call handlers
  -        if (fInDTD) {
  -            fDTDGrammar.textDecl(version, encoding, augs);
  -            if (fDTDHandler != null) {
  -                fDTDHandler.textDecl(version, encoding, augs);
  -            }
  -        }
  -        else {
  -            if (fDocumentHandler != null) {
  -                fDocumentHandler.textDecl(version, encoding, augs);
  -            }
  -        }
  -    }
  -
  -    /**
  -     * This method notifies of the start of a parameter entity. The parameter
  -     * entity name start with a '%' character.
  -     * 
  -     * @param name     The name of the parameter entity.
  -     * @param identifier The resource identifier.
  -     * @param encoding The auto-detected IANA encoding name of the entity
  -     *                 stream. This value will be null in those situations
  -     *                 where the entity encoding is not auto-detected (e.g.
  -     *                 internal parameter entities).
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void startParameterEntity(String name, 
  -                                     XMLResourceIdentifier identifier,
  -                                     String encoding,
  -                                     Augmentations augs) throws XNIException {
  -
  -        checkStandaloneEntityRef(name);
  -        // call handlers
  -        fDTDGrammar.startParameterEntity(name, identifier, encoding, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.startParameterEntity(name, identifier, encoding, augs);
  -        }
  -    }
  -
  -    /**
  -     * This method notifies the end of a parameter entity. Parameter entity
  -     * names begin with a '%' character.
  -     * 
  -     * @param name The name of the parameter entity.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void endParameterEntity(String name, Augmentations augs) throws XNIException {
  -
  -        // call handlers
  -        fDTDGrammar.endParameterEntity(name, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.endParameterEntity(name, augs);
  -        }
  -    } 
  -
  -    /**
  -     * An element declaration.
  -     * 
  -     * @param name         The name of the element.
  -     * @param contentModel The element content model.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void elementDecl(String name, String contentModel, Augmentations augs)
  -    throws XNIException {
  -
  -        //check VC: Unique Element Declaration
  -        if (fValidation) {
  -            if (fDTDElementDecls.contains(name)) {
  -                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                           "MSG_ELEMENT_ALREADY_DECLARED",
  -                                           new Object[]{ name},
  -                                           XMLErrorReporter.SEVERITY_ERROR);
  -            }
  -            else {
  -                fDTDElementDecls.addElement(name);
  -            }
  -        }
  -
  -        // call handlers
  -        fDTDGrammar.elementDecl(name, contentModel, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.elementDecl(name, contentModel, augs);
  -        }
  -
  -    } // elementDecl(String,String)
  -
  -    /**
  -     * The start of an attribute list.
  -     * 
  -     * @param elementName The name of the element that this attribute
  -     *                    list is associated with.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void startAttlist(String elementName, Augmentations augs) 
  -        throws XNIException {
  -
  -        // call handlers
  -        fDTDGrammar.startAttlist(elementName, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.startAttlist(elementName, augs);
  -        }
  -
  -    } // startAttlist(String)
  -
  -    /**
  -     * An attribute declaration.
  -     * 
  -     * @param elementName   The name of the element that this attribute
  -     *                      is associated with.
  -     * @param attributeName The name of the attribute.
  -     * @param type          The attribute type. This value will be one of
  -     *                      the following: "CDATA", "ENTITY", "ENTITIES",
  -     *                      "ENUMERATION", "ID", "IDREF", "IDREFS", 
  -     *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
  -     * @param enumeration   If the type has the value "ENUMERATION" or
  -     *                      "NOTATION", this array holds the allowed attribute
  -     *                      values; otherwise, this array is null.
  -     * @param defaultType   The attribute default type. This value will be
  -     *                      one of the following: "#FIXED", "#IMPLIED",
  -     *                      "#REQUIRED", or null.
  -     * @param defaultValue  The attribute default value, or null if no
  -     *                      default value is specified.
  -     * @param nonNormalizedDefaultValue  The attribute default value with no normalization 
  -     *                      performed, or null if no default value is specified.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void attributeDecl(String elementName, String attributeName, 
  -                              String type, String[] enumeration, 
  -                              String defaultType, XMLString defaultValue,
  -                              XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
  -
  -        if (type != fCDATASymbol && defaultValue != null) {
  -            normalizeDefaultAttrValue(defaultValue);
  -        }
  -
  -        if (fValidation) {
  -        
  -                boolean	duplicateAttributeDef = false ;
  -                                        
  -                //Get Grammar index to grammar array
  -                int elementIndex       = fDTDGrammar.getElementDeclIndex( elementName);
  -                if (fDTDGrammar.getAttributeDeclIndex(elementIndex, attributeName) != -1) {
  -                    //more than one attribute definition is provided for the same attribute of a given element type.
  -                    duplicateAttributeDef = true ;
  -
  -                    //this feature works only when validation is true.
  -                    if(fWarnDuplicateAttdef){
  -                        fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                                 "MSG_DUPLICATE_ATTRIBUTE_DEFINITION",
  -                                                 new Object[]{ elementName, attributeName },
  -                                                 XMLErrorReporter.SEVERITY_WARNING );
  -                    }
  -                }
  -
  -
  -            //
  -            // a) VC: One ID per Element Type, If duplicate ID attribute
  -            // b) VC: ID attribute Default. if there is a declareared attribute
  -            //        default for ID it should be of type #IMPLIED or #REQUIRED
  -            if (type == fIDSymbol) {
  -                if (defaultValue != null && defaultValue.length != 0) {
  -                    if (defaultType == null || 
  -                        !(defaultType == fIMPLIEDSymbol ||
  -                          defaultType == fREQUIREDSymbol)) {
  -                        fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                                   "IDDefaultTypeInvalid",
  -                                                   new Object[]{ attributeName},
  -                                                   XMLErrorReporter.SEVERITY_ERROR);
  -                    }
  -                }
  -
  -                if (!fTableOfIDAttributeNames.containsKey(elementName)) {
  -                    fTableOfIDAttributeNames.put(elementName, attributeName);
  -                }
  -                else {
  -                        //we should not report an error, when there is duplicate attribute definition for given element type
  -                        //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
  -                        //element type, the first declaration is binding and later declaration are *ignored*. So processor should 
  -                        //ignore the second declarations, however an application would be warned of the duplicate attribute defintion 
  -                        // if http://apache.org/xml/features/validation/warn-on-duplicate-attdef feature is set to true,
  -                        // one typical case where this could be a  problem, when any XML file  
  -                        // provide the ID type information through internal subset so that it is available to the parser which read 
  -                        //only internal subset. Now that attribute declaration(ID Type) can again be part of external parsed entity 
  -                        //referenced. At that time if parser doesn't make this distinction it will throw an error for VC One ID per 
  -                        //Element Type, which (second defintion) actually should be ignored. Application behavior may differ on the
  -                        //basis of error or warning thrown. - nb.
  -
  -                        if(!duplicateAttributeDef){
  -                                String previousIDAttributeName = (String)fTableOfIDAttributeNames.get( elementName );//rule a)
  -                                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                               "MSG_MORE_THAN_ONE_ID_ATTRIBUTE",
  -                                               new Object[]{ elementName, previousIDAttributeName, attributeName},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                        }
  -                }
  -            }
  -
  -            //
  -            //  VC: One Notaion Per Element Type, should check if there is a
  -            //      duplicate NOTATION attribute
  -
  -            if (type == fNOTATIONSymbol) {
  -                // VC: Notation Attributes: all notation names in the
  -                //     (attribute) declaration must be declared.
  -                for (int i=0; i<enumeration.length; i++) {
  -                    fNotationEnumVals.put(enumeration[i], attributeName);
  -                }
  -
  -                if (fTableOfNOTATIONAttributeNames.containsKey( elementName ) == false) {
  -                    fTableOfNOTATIONAttributeNames.put( elementName, attributeName);
  -                }
  -                else {
  -                        //we should not report an error, when there is duplicate attribute definition for given element type
  -                        //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
  -                        //element type, the first declaration is binding and later declaration are *ignored*. So processor should 
  -                        //ignore the second declarations, however an application would be warned of the duplicate attribute defintion 
  -                        // 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 
  -                        //warning thrown. - nb.
  -
  -                        if(!duplicateAttributeDef){
  -                
  -                                String previousNOTATIONAttributeName = (String) fTableOfNOTATIONAttributeNames.get( elementName );
  -                                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                               "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE",
  -                                               new Object[]{ elementName, previousNOTATIONAttributeName, attributeName},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                         }
  -                }
  -            }
  -
  -            // VC: Attribute Default Legal
  -            boolean ok = true;
  -            if (defaultValue != null && 
  -                (defaultType == null ||
  -                 (defaultType != null && defaultType == fFIXEDSymbol))) {
  -
  -                String value = defaultValue.toString();
  -                if (type == fNMTOKENSSymbol ||
  -                    type == fENTITIESSymbol || type == fIDREFSSymbol) {
  -
  -                    StringTokenizer tokenizer = new StringTokenizer(value);
  -                    if (tokenizer.hasMoreTokens()) {
  -                        while (true) {
  -                            String nmtoken = tokenizer.nextToken();
  -                            if (type == fNMTOKENSSymbol) {
  -                                if (!XMLChar.isValidNmtoken(nmtoken)) {
  -                                    ok = false;
  -                                    break;
  -                                }
  -                            }
  -                            else if (type == fENTITIESSymbol ||
  -                                     type == fIDREFSSymbol) {
  -                                if (!XMLChar.isValidName(nmtoken)) {
  -                                    ok = false;
  -                                    break;
  -                                }
  -                            }
  -                            if (!tokenizer.hasMoreTokens()) {
  -                                break;
  -                            }
  -                        }
  -                    }
  -
  -                }
  -                else {
  -                    if (type == fENTITYSymbol ||
  -                        type == fIDSymbol ||
  -                        type == fIDREFSymbol ||
  -                        type == fNOTATIONSymbol) {
  -
  -                        if (!XMLChar.isValidName(value)) {
  -                            ok = false;
  -                        }
  -
  -                    }
  -                    else if (type == fNMTOKENSymbol ||
  -                             type == fENUMERATIONSymbol) {
  -
  -                        if (!XMLChar.isValidNmtoken(value)) {
  -                            ok = false;
  -                        }
  -                    }
  -
  -                    if (type == fNOTATIONSymbol ||
  -                        type == fENUMERATIONSymbol) {
  -                        ok = false;
  -                        for (int i=0; i<enumeration.length; i++) {
  -                            if (defaultValue.equals(enumeration[i])) {
  -                                ok = true;
  -                            }
  -                        }
  -                    }
  -
  -                }
  -                if (!ok) {
  -                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                               "MSG_ATT_DEFAULT_INVALID",
  -                                               new Object[]{attributeName, value},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                }
  -            }
  -        }
  -
  -        // call handlers
  -        fDTDGrammar.attributeDecl(elementName, attributeName, 
  -                                  type, enumeration,
  -                                  defaultType, defaultValue, nonNormalizedDefaultValue, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.attributeDecl(elementName, attributeName, 
  -                                      type, enumeration, 
  -                                      defaultType, defaultValue, nonNormalizedDefaultValue, augs);
  -        }
  -
  -    } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
  -
  -    /**
  -     * The end of an attribute list.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void endAttlist(Augmentations augs) throws XNIException {
  -
  -        // call handlers
  -        fDTDGrammar.endAttlist(augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.endAttlist(augs);
  -        }
  -
  -    } // endAttlist()
  -
  -    /**
  -     * An internal entity declaration.
  -     * 
  -     * @param name The name of the entity. Parameter entity names start with
  -     *             '%', whereas the name of a general entity is just the 
  -     *             entity name.
  -     * @param text The value of the entity.
  -     * @param nonNormalizedText The non-normalized value of the entity. This
  -     *             value contains the same sequence of characters that was in 
  -     *             the internal entity declaration, without any entity
  -     *             references expanded.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void internalEntityDecl(String name, XMLString text,
  -                                   XMLString nonNormalizedText,
  -                                   Augmentations augs) throws XNIException {
  -
  -        int index = fDTDGrammar.getEntityDeclIndex(name) ;
  -
  -        //If the same entity is declared more than once, the first declaration
  -        //encountered is binding, SAX requires only effective(first) declaration
  -        //to be reported to the application
  -
  -        //REVISIT: Does it make sense to pass duplicate Entity information across
  -        //the pipeline -- nb?
  -
  -        //its a new entity and hasn't been declared.
  -        if(index == -1){
  -            //store internal entity declaration in grammar
  -            fDTDGrammar.internalEntityDecl(name, text, nonNormalizedText, augs);
  -            // call handlers
  -            if (fDTDHandler != null) {
  -                fDTDHandler.internalEntityDecl(name, text, nonNormalizedText, augs);
  -            }
  -        }
  -
  -    } // internalEntityDecl(String,XMLString,XMLString)
  -
  -
  -    /**
  -     * An external entity declaration.
  -     * 
  -     * @param name     The name of the entity. Parameter entity names start
  -     *                 with '%', whereas the name of a general entity is just
  -     *                 the entity name.
  -     * @param identifier    An object containing all location information 
  -     *                      pertinent to this external entity.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void externalEntityDecl(String name, XMLResourceIdentifier identifier,
  -                                   Augmentations augs) throws XNIException {
  -
  -        int index = fDTDGrammar.getEntityDeclIndex(name) ;
  -
  -        //If the same entity is declared more than once, the first declaration
  -        //encountered is binding, SAX requires only effective(first) declaration
  -        //to be reported to the application
  -
  -        //REVISIT: Does it make sense to pass duplicate entity information across
  -        //the pipeline -- nb?
  -
  -        //its a new entity and hasn't been declared.
  -        if(index == -1){
  -            //store external entity declaration in grammar
  -            fDTDGrammar.externalEntityDecl(name, identifier, augs);
  -            // call handlers
  -            if (fDTDHandler != null) {
  -                fDTDHandler.externalEntityDecl(name, identifier, augs);
  -            }
  -        }
  -
  -    } // externalEntityDecl(String,XMLResourceIdentifier, Augmentations)
  -
  -    /**
  -     * An unparsed entity declaration.
  -     * 
  -     * @param name     The name of the entity.
  -     * @param identifier    An object containing all location information 
  -     *                      pertinent to this entity.
  -     * @param notation The name of the notation.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     */
  -    public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
  -                                   String notation, 
  -                                   Augmentations augs) throws XNIException {
  +                    charDataInContent();
  +                }
  +            }
   
  -        // VC: Notation declared,  in the production of NDataDecl
  -        if (fValidation) {
  -            fNDataDeclNotations.put(name, notation);
  +            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
  +                charDataInContent();
  +            }
           }
   
           // call handlers
  -        fDTDGrammar.unparsedEntityDecl(name, identifier, notation, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.unparsedEntityDecl(name, identifier, notation, augs);
  +        if (callNextCharacters && fDocumentHandler != null) {
  +            fDocumentHandler.characters(text, augs);
           }
   
  -    } // unparsedEntityDecl(String,XMLResourceIdentifier,String,Augmentations)
  +    } // characters(XMLString)
  +
  +
   
       /**
  -     * A notation declaration
  +     * 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 name     The name of the notation.
  -     * @param identifier    An object containing all location information 
  -     *                      pertinent to this notation.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * @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 notationDecl(String name, XMLResourceIdentifier identifier,
  -                             Augmentations augs) throws XNIException {
  +    public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
   
           // call handlers
  -        fDTDGrammar.notationDecl(name, identifier, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.notationDecl(name, identifier, augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.ignorableWhitespace(text, augs);
           }
   
  -    } // notationDecl(String,XMLResourceIdentifier, Augmentations)
  +    } // ignorableWhitespace(XMLString)
   
       /**
  -     * The start of a conditional section.
  +     * The end of an element.
        * 
  -     * @param type The type of the conditional section. This value will
  -     *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * @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.
  -     *
  -     * @see #CONDITIONAL_INCLUDE
  -     * @see #CONDITIONAL_IGNORE
        */
  -    public void startConditional(short type, Augmentations augs) throws XNIException {
  -
  -        // set state
  -        fInDTDIgnore = type == XMLDTDHandler.CONDITIONAL_IGNORE;
  +    public void endElement(QName element, Augmentations augs) throws XNIException {
   
  -        // call handlers
  -        fDTDGrammar.startConditional(type, augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.startConditional(type, augs);
  -        }
  +        handleEndElement(element,  augs, false);
   
  -    } // startConditional(short)
  +    } // endElement(QName)
   
       /**
  -     * The end of a conditional section.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * The end of a namespace prefix mapping. This method will only be
  +     * called when namespace processing is enabled.
  +     * 
  +     * @param prefix The namespace prefix.
  +     * @param augs   Additional information that may include infoset augmentations
        *
        * @throws XNIException Thrown by handler to signal an error.
        */
  -    public void endConditional(Augmentations augs) throws XNIException {
  -
  -        // set state
  -        fInDTDIgnore = false;
  +    public void endPrefixMapping(String prefix, Augmentations augs) throws XNIException {
   
           // call handlers
  -        fDTDGrammar.endConditional(augs);
  -        if (fDTDHandler != null) {
  -            fDTDHandler.endConditional(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.endPrefixMapping(prefix, augs);
           }
   
  -    } // endConditional()
  +    } // endPrefixMapping(String)
   
  -    /**
  -     * The end of the DTD.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +    /** 
  +     * 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 endDTD(Augmentations augs) throws XNIException {
  -
  -        fInDTD = false;
  -
  -        // save grammar
  -        fDTDGrammar.endDTD(augs);
  -
  -        // check VC: Notation declared,  in the production of NDataDecl
  -        if (fValidation) {
  -
  -            // VC : Notation Declared. for external entity declaration [Production 76].
  -            Enumeration entities = fNDataDeclNotations.keys();
  -            while (entities.hasMoreElements()) {
  -                String entity = (String) entities.nextElement();
  -                String notation = (String) fNDataDeclNotations.get(entity);
  -                if (fDTDGrammar.getNotationDeclIndex(notation) == -1) {
  -                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                               "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL",
  -                                               new Object[]{entity, notation},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                }
  -            }
  -
  -            // VC: Notation Attributes:
  -            //     all notation names in the (attribute) declaration must be declared.
  -            Enumeration notationVals = fNotationEnumVals.keys();
  -            while (notationVals.hasMoreElements()) {
  -                String notation = (String) notationVals.nextElement();
  -                String attributeName = (String) fNotationEnumVals.get(notation);
  -                if (fDTDGrammar.getNotationDeclIndex(notation) == -1) {
  -                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                               "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE",
  -                                               new Object[]{attributeName, notation},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                }
  -            }
  +    public void startCDATA(Augmentations augs) throws XNIException {
   
  -            fTableOfIDAttributeNames = null;//should be safe to release these references
  -            fTableOfNOTATIONAttributeNames = null;
  +        if (fPerformValidation && fInElementContent) {
  +            charDataInContent();
           }
  -
  +        fInCDATASection = true;
           // call handlers
  -        if (fDTDHandler != null) {
  -            fDTDHandler.endDTD(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.startCDATA(augs);
           }
   
  -    } // endDTD()
  -
  -    //
  -    // XMLDTDContentModelHandler methods
  -    //
  +    } // startCDATA()
   
       /**
  -     * The start of a content model. Depending on the type of the content
  -     * model, specific methods may be called between the call to the
  -     * startContentModel method and the call to the endContentModel method.
  -     * 
  -     * @param elementName The name of the element.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * 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 startContentModel(String elementName, Augmentations augs) 
  -        throws XNIException {
  -
  -        if (fValidation) {
  -            fDTDElementDeclName = elementName;
  -            fMixedElementTypes.removeAllElements();
  -        }
  +    public void endCDATA(Augmentations augs) throws XNIException {
   
  +        fInCDATASection = false;
           // call handlers
  -        fDTDGrammar.startContentModel(elementName, augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.startContentModel(elementName, augs);
  -        }
  -
  -    } // startContentModel(String)
  -
  -    /** 
  -     * A content model of ANY. 
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     *
  -     * @see #empty
  -     * @see #startGroup
  -     */
  -    public void any(Augmentations augs) throws XNIException {
  -        fDTDGrammar.any(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.any(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.endCDATA(augs);
           }
  -    } // any()
   
  -    /**
  -     * A content model of EMPTY.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     *
  -     * @see #any
  -     * @see #startGroup
  -     */
  -    public void empty(Augmentations augs) throws XNIException {
  -        fDTDGrammar.empty(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.empty(augs);
  -        }
  -    } // empty()
  +    } // endCDATA()
   
       /**
  -     * A start of either a mixed or children content model. A mixed
  -     * content model will immediately be followed by a call to the
  -     * <code>pcdata()</code> method. A children content model will
  -     * contain additional groups and/or elements.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * The end of the document.
  +     * @param augs   Additional information that may include infoset augmentations
        *
        * @throws XNIException Thrown by handler to signal an error.
  -     *
  -     * @see #any
  -     * @see #empty
        */
  -    public void startGroup(Augmentations augs) throws XNIException {
  +    public void endDocument(Augmentations augs) throws XNIException {
   
  -        fMixed = false;
           // call handlers
  -        fDTDGrammar.startGroup(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.startGroup(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.endDocument(augs);
           }
   
  -    } // startGroup()
  -
  -    /**
  -     * The appearance of "#PCDATA" within a group signifying a
  -     * mixed content model. This method will be the first called
  -     * following the content model's <code>startGroup()</code>.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *     
  -     * @throws XNIException Thrown by handler to signal an error.
  -     *
  -     * @see #startGroup
  -     */
  -    public void pcdata(Augmentations augs) {
  -        fMixed = true;
  -        fDTDGrammar.pcdata(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.pcdata(augs);
  -        }
  -    } // pcdata()
  +    } // endDocument()
   
       /**
  -     * A referenced element in a mixed or children content model.
  +     * A comment.
        * 
  -     * @param elementName The name of the referenced element.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * @param text The text in the comment.
  +     * @param augs   Additional information that may include infoset augmentations
        *
  -     * @throws XNIException Thrown by handler to signal an error.
  +     * @throws XNIException Thrown by application to signal an error.
        */
  -    public void element(String elementName, Augmentations augs) throws XNIException {
  -
  -        // check VC: No duplicate Types, in a single mixed-content declaration
  -        if (fMixed && fValidation) {
  -            if (fMixedElementTypes.contains(elementName)) {
  -                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  -                                           "DuplicateTypeInMixedContent",
  -                                           new Object[]{fDTDElementDeclName, elementName},
  -                                           XMLErrorReporter.SEVERITY_ERROR);
  -            }
  -            else {
  -                fMixedElementTypes.addElement(elementName);
  -            }
  -        }
  +    public void comment(XMLString text, Augmentations augs) throws XNIException {
   
           // call handlers
  -        fDTDGrammar.element(elementName, augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.element(elementName, augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.comment(text, augs);
           }
   
  -    } // childrenElement(String)
  +    } // comment(XMLString)
  +
   
       /**
  -     * The separator between choices or sequences of a mixed or children
  -     * content model.
  +     * 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 separator The type of children separator.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  +     * @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.
  -     *
  -     * @see #SEPARATOR_CHOICE
  -     * @see #SEPARATOR_SEQUENCE
        */
  -    public void separator(short separator, Augmentations augs) 
  -        throws XNIException {
  +    public void processingInstruction(String target, XMLString data, Augmentations augs)
  +    throws XNIException {
   
           // call handlers
  -        fDTDGrammar.separator(separator, augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.separator(separator, augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.processingInstruction(target, data, augs);
           }
  -
  -    } // separator(short)
  +    } // processingInstruction(String,XMLString)
   
       /**
  -     * The occurrence count for a child in a children content model or
  -     * for the mixed content model group.
  +     * 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 occurrence The occurrence count for the last element
  -     *                   or group.
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  -     *
  -     * @see #OCCURS_ZERO_OR_ONE
  -     * @see #OCCURS_ZERO_OR_MORE
  -     * @see #OCCURS_ONE_OR_MORE
  +     * @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 occurrence(short occurrence, Augmentations augs) 
  -        throws XNIException {
  +    public void startGeneralEntity(String name, 
  +                                   XMLResourceIdentifier identifier,
  +                                   String encoding, 
  +                                   Augmentations augs) throws XNIException {
   
  -        // call handlers
  -        fDTDGrammar.occurrence(occurrence, augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.occurrence(occurrence, augs);
  +        if (fPerformValidation && fDTDGrammar != null &&
  +                fGrammarBucket.getStandalone()) {
  +            XMLDTDLoader.checkStandaloneEntityRef(name, fDTDGrammar, fEntityDecl, fErrorReporter);
           }
  -
  -    } // occurrence(short)
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs);
  +        }
  +    }
   
       /**
  -     * The end of a group for mixed or children content models.
  -     *
  -     * @param augs Additional information that may include infoset
  -     *                      augmentations.
  -     *
  -     * @throws XNIException Thrown by handler to signal an error.
  +     * 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 endGroup(Augmentations augs) throws XNIException {
  -
  +    public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
           // call handlers
  -        fDTDGrammar.endGroup(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.endGroup(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.endGeneralEntity(name, augs);
           }
  -
  -    } // endGroup()
  +    } // endEntity(String)
   
       /**
  -     * The end of a content model.
  -     *
  +     * Notifies of the presence of a TextDecl line in an entity. If present,
  +     * this method will be called immediately following the startParameterEntity call.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called for external
  +     * parameter entities referenced in the DTD.
  +     * 
  +     * @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 endContentModel(Augmentations augs) throws XNIException {
  +    public void textDecl(String version, String encoding, Augmentations augs) throws XNIException {
   
           // call handlers
  -        fDTDGrammar.endContentModel(augs);
  -        if (fDTDContentModelHandler != null) {
  -            fDTDContentModelHandler.endContentModel(augs);
  +        if (fDocumentHandler != null) {
  +            fDocumentHandler.textDecl(version, encoding, augs);
           }
  -
  -    } // endContentModel()
  +    }
   
       //
       // Private methods
  @@ -2110,7 +1134,7 @@
                       }
                   }
                   else if (attValue != null) {
  -                    if (fPerformValidation && fStandaloneIsYes) {
  +                    if (fPerformValidation && fGrammarBucket.getStandalone()) {
                           if (fDTDGrammar.getAttributeDeclIsExternal(attlistIndex)) {
   
                               Object[] args = { element.localpart, attRawName};
  @@ -2149,7 +1173,7 @@
               String attrRawName = attributes.getQName(i);
               boolean declared = false;
               if (fPerformValidation) {
  -                if (fStandaloneIsYes) {
  +                if (fGrammarBucket.getStandalone()) {
                       // check VC: Standalone Document Declaration, entities
                       // references appear in the document.
                       // REVISIT: this can be combined to a single check in
  @@ -2207,7 +1231,7 @@
               if (attributes.isSpecified(i) && type != fCDATASymbol) {
                   changedByNormalization = normalizeAttrValue(attributes, i);
                   attrValue = attributes.getValue(i);
  -                if (fPerformValidation && fStandaloneIsYes
  +                if (fPerformValidation && fGrammarBucket.getStandalone()
                       && changedByNormalization 
                       && fDTDGrammar.getAttributeDeclIsExternal(position)
                      ) {
  @@ -2514,52 +1538,6 @@
           return ! attrValue.equals(newValue);
       }
   
  -    /**
  -     * Normalize the attribute value of a non CDATA default attribute
  -     * collapsing sequences of space characters (x20)
  -     *
  -     * @param value The value to normalize
  -     * @return Whether the value was changed or not.
  -     */
  -    private boolean normalizeDefaultAttrValue(XMLString value) {
  -
  -        int oldLength = value.length;
  -
  -        boolean skipSpace = true; // skip leading spaces
  -        int current = value.offset;
  -        int end = value.offset + value.length;
  -        for (int i = value.offset; i < end; i++) {
  -            if (value.ch[i] == ' ') {
  -                if (!skipSpace) {
  -                    // take the first whitespace as a space and skip the others
  -                    value.ch[current++] = ' ';
  -                    skipSpace = true;
  -                }
  -                else {
  -                    // just skip it.
  -                }
  -            }
  -            else {
  -                // simply shift non space chars if needed
  -                if (current != i) {
  -                    value.ch[current] = value.ch[i];
  -                }
  -                current++;
  -                skipSpace = false;
  -            }
  -        }
  -        if (current != end) {
  -            if (skipSpace) {
  -                // if we finished on a space trim it
  -                current--;
  -            }
  -            // set the new value length
  -            value.length = current - value.offset;
  -            return true;
  -        }
  -        return false;
  -    }
  -
       /** Root element specified. */
       private void rootElementSpecified(QName rootElement) throws XNIException {
           if (fPerformValidation) {
  @@ -2755,11 +1733,6 @@
       private void init() {
   
           // symbols
  -        fEMPTYSymbol = fSymbolTable.addSymbol("EMPTY");
  -        fANYSymbol = fSymbolTable.addSymbol("ANY");
  -        fMIXEDSymbol = fSymbolTable.addSymbol("MIXED");
  -        fCHILDRENSymbol = fSymbolTable.addSymbol("CHILDREN");
  -
           fCDATASymbol = fSymbolTable.addSymbol("CDATA");
           fIDSymbol = fSymbolTable.addSymbol("ID");
           fIDREFSymbol = fSymbolTable.addSymbol("IDREF");
  @@ -2773,7 +1746,6 @@
           fIMPLIEDSymbol = fSymbolTable.addSymbol("#IMPLIED");
           fREQUIREDSymbol = fSymbolTable.addSymbol("#REQUIRED");
           fFIXEDSymbol = fSymbolTable.addSymbol("#FIXED");
  -        fDATATYPESymbol = fSymbolTable.addSymbol("<<datatype>>");
   
           // datatype validators
           if (fValidation) {
  @@ -2795,13 +1767,6 @@
                   e.printStackTrace(System.err);
               }
   
  -            if (fNotationEnumVals == null) {
  -                fNotationEnumVals = new Hashtable(); 
  -            }
  -            fNotationEnumVals.clear();
  -
  -            fTableOfIDAttributeNames = new Hashtable();
  -            fTableOfNOTATIONAttributeNames = new Hashtable();
           }
   
       } // init()
  @@ -3037,10 +2002,5 @@
           fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
   
       } // handleEndElement(QName,boolean)
  -
  -    /** Factory method for creating a DTD grammar. */
  -    protected DTDGrammar createDTDGrammar() {
  -        return new DTDGrammar(fSymbolTable);
  -    } // createDTDGrammar():DTDGrammar
   
   } // class XMLDTDValidator
  
  
  
  1.4       +82 -42    xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDDescription.java
  
  Index: XMLDTDDescription.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDDescription.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLDTDDescription.java	27 Feb 2002 17:47:35 -0000	1.3
  +++ XMLDTDDescription.java	3 Jun 2002 21:23:03 -0000	1.4
  @@ -58,68 +58,71 @@
   package org.apache.xerces.impl.dtd;
   
   import org.apache.xerces.xni.grammars.XMLGrammarDescription;
  +import org.apache.xerces.xni.XMLResourceIdentifier;
  +
  +import org.apache.xerces.util.XMLResourceIdentifierImpl;
  +import java.util.Vector;
   
   /*
    * All information specific to dTD grammars.  
    * 
    * @author Neil Graham, IBM
  - * @version $Id: XMLDTDDescription.java,v 1.3 2002/02/27 17:47:35 neeraj Exp $
  + * @version $Id: XMLDTDDescription.java,v 1.4 2002/06/03 21:23:03 neilg Exp $
    */
   
  -public class XMLDTDDescription implements XMLGrammarDescription {
  +public class XMLDTDDescription extends XMLResourceIdentifierImpl
  +        implements XMLGrammarDescription {
   
       // Data
   
  -    // basic information required by XMLGrammarDescription
  -    protected String fBaseURI = null;
  -    protected String fLiteralSystemId = null;
  -    protected String fExpandedSystemId = null;
  -    protected String fPublicId = null;
  -
       // pieces of information needed to make this usable as a Grammar key
  +    // if we know the root of this grammar, here's its name:
       protected String fRootName = null;
  -    protected String fInternalSubset = null;
   
  -    // XMLGrammarDescription methods
  +    // if we don't know the root name, this stores all elements that
  +    // could serve; fPossibleRoots and fRootName cannot both be non-null
  +    protected Vector fPossibleRoots = null;
  +
  +    // Constructors:
  +    public XMLDTDDescription(XMLResourceIdentifier id, String rootName) {
  +        this.setValues(id.getPublicId(), id.getLiteralSystemId(),
  +                id.getBaseSystemId(), id.getExpandedSystemId());
  +        this.fRootName = rootName;
  +        this.fPossibleRoots = null;
  +    } // init(XMLResourceIdentifier, String)
   
  -    public String getPublicId() {
  -        return fPublicId;
  -    } // getPublicId():  String
  -
  -    // get base URI against wihch literal systemId is expanded
  -    public String getBaseSystemId () {
  -        return fBaseURI;
  -    } // getBaseSystemId():  String
  -
  -    // get expanded systemId
  -    public String getExpandedSystemId () {
  -        return fExpandedSystemId;
  -    } // getExpandedSystemId():  String
  -
  -    // get systemId as found in entity decl
  -    public String getLiteralSystemId () {
  -        return fLiteralSystemId;
  -    } // getLiteralSystemId():  String
  +    // XMLGrammarDescription methods
   
       public String getGrammarType () {
           return XMLGrammarDescription.XML_DTD;
       } // getGrammarType():  String
   
       // return the root name of this DTD
  +    // returns null if root name is unknown
       public String getRootName() {
           return fRootName;
       } // getRootName():  String
   
  -    // return the internal subset.  Entities should not be expanded;
  -    // this is simply the raw string representation of the stuff
  -    // between [ and ]>
  -    public String getInternalSubset () {
  -        return fInternalSubset;
  -    } // getInternalSubset():  String
  -    
  +    // set the root name
  +    public void setRootName(String rootName) {
  +        fRootName = rootName;
  +        fPossibleRoots = null;
  +    }
  +
  +    // set possible roots
  +    public void setPossibleRoots(Vector possibleRoots) {
  +        fPossibleRoots = (Vector)possibleRoots.clone();
  +    } 
  +
       /**
        * Compares this grammar with the given grammar. Currently, we compare 
  -     * the root element names.
  +     * as follows:
  +     * - if grammar type not equal return false immediately
  +     * - try and find a common root name:
  +     *    - if both have roots, use them
  +     *    - else if one has a root, examine other's possible root's for a match;
  +     *    - else try all combinations
  +     *  - test fExpandedSystemId and fPublicId as above
        * 
        * @param desc The description of the grammar to be compared with
        * @return     True if they are equal, else false
  @@ -128,19 +131,56 @@
       	if (!getGrammarType().equals(desc.getGrammarType())) {
       	    return false;
       	}
  -    	if (fRootName.equals(((XMLDTDDescription)desc).getRootName())) {
  -    	    return true;
  -    	}
  -    	return false;
  +        // assume it's a DTDDescription
  +        XMLDTDDescription dtdDesc = (XMLDTDDescription)desc;
  +        if(fRootName != null) {
  +            if((dtdDesc.fRootName) != null && !dtdDesc.fRootName.equals(fRootName))
  +                return false;
  +            else if(dtdDesc.fPossibleRoots != null && !dtdDesc.fPossibleRoots.contains(fRootName)) 
  +                return false;
  +        } else if(fPossibleRoots != null) {
  +            if(dtdDesc.fRootName != null && !fPossibleRoots.contains(dtdDesc.fRootName))
  +                return false;
  +            if(dtdDesc.fPossibleRoots == null)
  +                return false;
  +            boolean found = false;
  +            for(int i = 0; i<fPossibleRoots.size(); i++) {
  +                String root = (String)fPossibleRoots.elementAt(i);
  +                found = dtdDesc.fPossibleRoots.contains(root);
  +                if(found) break;
  +            }
  +            if(!found) return false;
  +        }
  +        // if we got this far we've got a root match... try other two fields,
  +        // since so many different DTD's have roots in common:
  +        if(fExpandedSystemId != null) {
  +            if(!fExpandedSystemId.equals(dtdDesc.fExpandedSystemId)) 
  +                return false;
  +        } 
  +        else if(dtdDesc.fExpandedSystemId != null)
  +            return false;
  +        if(fPublicId != null) {
  +            if(!fPublicId.equals(dtdDesc.fPublicId)) 
  +                return false;
  +        } 
  +        else if(dtdDesc.fPublicId != null)
  +            return false;
  +    	return true;
       }
       
       /**
        * Returns the hash code of this grammar
  -     * 
  +     * Because our .equals method is so complex, we just return a very
  +     * simple hash that might avoid calls to the equals method a bit...
        * @return The hash code
        */
       public int hashCode() {
  -        return fRootName.hashCode();
  +        if(fExpandedSystemId != null)
  +            return fExpandedSystemId.hashCode();
  +        if(fPublicId != null)
  +            return fPublicId.hashCode();
  +        // give up; hope .equals can handle it:
  +        return 0;
       }
   } // class XMLDTDDescription
   
  
  
  
  1.4       +46 -10    xml-xerces/java/src/org/apache/xerces/impl/dtd/DTDGrammarBucket.java
  
  Index: DTDGrammarBucket.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dtd/DTDGrammarBucket.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DTDGrammarBucket.java	29 Jan 2002 01:15:10 -0000	1.3
  +++ DTDGrammarBucket.java	3 Jun 2002 21:23:03 -0000	1.4
  @@ -57,9 +57,8 @@
   
   package org.apache.xerces.impl.dtd;
   
  -import org.apache.xerces.xni.grammars.Grammar;
  +import org.apache.xerces.xni.grammars.XMLGrammarDescription;
   import java.util.Hashtable;
  -import java.util.Enumeration;
   
   /**
   * This very simple class is the skeleton of what the DTDValidator could use
  @@ -72,7 +71,7 @@
    *
    * @author Neil Graham, IBM
    *
  - * @version $Id: DTDGrammarBucket.java,v 1.3 2002/01/29 01:15:10 lehors Exp $
  + * @version $Id: DTDGrammarBucket.java,v 1.4 2002/06/03 21:23:03 neilg Exp $
    */
   public class DTDGrammarBucket {
   
  @@ -83,7 +82,14 @@
       //
   
       /** Grammars associated with element root name. */
  -    protected Hashtable fGrammars = new Hashtable();
  +    protected Hashtable fGrammars;
  +
  +    // the unique grammar from fGrammars (or that we're
  +    // building) that is used in validation.
  +    protected DTDGrammar fActiveGrammar;
  +
  +    // is the "active" grammar standalone?
  +    protected boolean fIsStandalone;
   
       //
       // Constructors
  @@ -91,6 +97,7 @@
   
       /** Default constructor. */
       public DTDGrammarBucket() {
  +        fGrammars = new Hashtable();
       } // <init>()
   
       //
  @@ -99,13 +106,42 @@
   
       /**
        * Puts the specified grammar into the grammar pool and associate it to
  -     * a root element name.
  +     * a root element name (this being internal, the lack of generality is irrelevant).
        * 
  -     * @param rootElement Root element name.
        * @param grammar     The grammar.
        */
  -    public void putGrammar(String rootElement, Grammar grammar) {
  -        fGrammars.put(rootElement, grammar);
  -    } // putGrammar(String,Grammar)
  -
  +    public void putGrammar(DTDGrammar grammar) {
  +        XMLDTDDescription desc = (XMLDTDDescription)grammar.getGrammarDescription();
  +        fGrammars.put(desc.getRootName(), grammar);
  +    } // putGrammar(DTDGrammar)
  +
  +    // retrieve a DTDGrammar given an XMLDTDDescription
  +    public DTDGrammar getGrammar(XMLGrammarDescription desc) {
  +        return (DTDGrammar)fGrammars.get(((XMLDTDDescription)desc).getRootName());
  +    } // putGrammar(DTDGrammar)
  +
  +    public void clear() {
  +        fGrammars.clear();
  +        fActiveGrammar = null;
  +        fIsStandalone = false;
  +    } // clear()
  +
  +    // is the active grammar standalone?  This must live here because
  +    // at the time the validator discovers this we don't yet know
  +    // what the active grammar should be (no info about root)
  +    void setStandalone(boolean standalone) {
  +        fIsStandalone = standalone;
  +    }
  +
  +    boolean getStandalone() {
  +        return fIsStandalone;
  +    }
  +
  +    // set the "active" grammar:
  +    void setActiveGrammar (DTDGrammar grammar) {
  +        fActiveGrammar = grammar;
  +    }
  +    DTDGrammar getActiveGrammar () {
  +        return fActiveGrammar;
  +    }
   } // class DTDGrammarBucket
  
  
  
  1.17      +12 -27    xml-xerces/java/src/org/apache/xerces/impl/dtd/DTDGrammar.java
  
  Index: DTDGrammar.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dtd/DTDGrammar.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- DTDGrammar.java	29 May 2002 17:59:37 -0000	1.16
  +++ DTDGrammar.java	3 Jun 2002 21:23:03 -0000	1.17
  @@ -107,7 +107,7 @@
    * @author Andy Clark, IBM
    * @author Neil Graham, IBM
    *
  - * @version $Id: DTDGrammar.java,v 1.16 2002/05/29 17:59:37 neilg Exp $
  + * @version $Id: DTDGrammar.java,v 1.17 2002/06/03 21:23:03 neilg Exp $
    */
   public class DTDGrammar 
       implements XMLDTDHandler, XMLDTDContentModelHandler, EntityState, Grammar {
  @@ -206,13 +206,16 @@
       /** Attribute declaration name. */
       private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
   
  +    // is this grammar immutable?  (fully constructed and not changeable)
  +    private boolean fIsImmutable = false;
  +
       /** 
        * Attribute declaration type.
        * @see XMLAttributeDecl
        */
       private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
   
  -    /** Attribute declaratoin enumeration values. */
  +    /** Attribute declaration enumeration values. */
       private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
       private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
       private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
  @@ -334,10 +337,9 @@
       //
   
       /** Default constructor. */
  -    public DTDGrammar(SymbolTable symbolTable) {
  +    public DTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) {
           fSymbolTable = symbolTable;
  -        // are there really situations in which this is a good idea???  - NG
  -        fGrammarDescription = new XMLDTDDescription();
  +        fGrammarDescription = desc;
       } // <init>(SymbolTable)
   
       // Grammar methods
  @@ -868,28 +870,7 @@
        * @throws XNIException Thrown by handler to signal an error.
        */
       public void endDTD(Augmentations augs) throws XNIException {
  -
  -        // REVISIT: What is this for? -Ac
  -        /*
  -        XMLElementDecl  elementDecl;
  -        Enumeration     elements       = fElementDeclTab.elements();
  -        int             elementDeclIdx = 0;
  -        while( elements.hasMoreElements() == true ) {
  -            elementDecl    = (XMLElementDecl) elements.nextElement();
  -            elementDeclIdx = getElementDeclIndex( elementDecl.name );
  -            System.out.println( "elementDeclIdx = " + elementDeclIndex );
  -            if( elementDeclIndex != -1 ) {
  -                elementDecl.contentModelValidator = this.getElementContentModelValidator(elementDeclIdx );
  -            }
  -            fCurrentElementIndex = createElementDecl();//create element decl
  -            if ( DEBUG == true ) {
  -                System.out.println(  "name = " + fElementDecl.name.localpart );
  -                System.out.println(  "Type = " + fElementDecl.type );
  -            }
  -            setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
  -        }
  -        */
  -
  +        fIsImmutable = true;
       } // endDTD()
   
       // no-op methods
  @@ -2038,6 +2019,10 @@
           fPrevNodeIndexStack[fDepth] = -1;
   
       } // initializeContentModelStack()
  +
  +    boolean isImmutable() {
  +        return fIsImmutable;
  +    }
   
       //
       // Private methods
  
  
  
  1.1                  xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java
  
  Index: XMLDTDLoader.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-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 org.apache.xerces.impl.dtd;
  
  import org.apache.xerces.impl.Constants;
  import org.apache.xerces.impl.XMLErrorReporter;
  import org.apache.xerces.impl.msg.XMLMessageFormatter;
  
  import org.apache.xerces.util.SymbolTable;
  import org.apache.xerces.util.XMLChar;
  
  import org.apache.xerces.xni.Augmentations;
  import org.apache.xerces.xni.QName;
  import org.apache.xerces.xni.XMLString;
  import org.apache.xerces.xni.XMLDTDHandler;
  import org.apache.xerces.xni.XMLDTDContentModelHandler;
  import org.apache.xerces.xni.XMLLocator;
  import org.apache.xerces.xni.XMLResourceIdentifier;
  import org.apache.xerces.xni.XNIException;
  import org.apache.xerces.xni.grammars.XMLGrammarPool;
  import org.apache.xerces.xni.parser.XMLComponent;
  import org.apache.xerces.xni.parser.XMLComponentManager;
  import org.apache.xerces.xni.parser.XMLConfigurationException;
  import org.apache.xerces.xni.parser.XMLDTDFilter;
  import org.apache.xerces.xni.parser.XMLDTDContentModelFilter;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.StringTokenizer;
  
  /**
   * The DTD loader. The loader implements a DTD
   * filter: receiving DTD events from the DTD scanner; validating
   * the content and structure; building a grammar, if applicable;
   * and notifying the DTDHandler of the information resulting from the
   * process.
   * <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>
   *  <li>http://apache.org/xml/properties/internal/grammar-pool</li>
   *  <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
   * </ul>
   *
   * @author Neil Graham, IBM
   *
   * @version $Id: XMLDTDLoader.java,v 1.1 2002/06/03 21:23:03 neilg Exp $
   */
  public class XMLDTDLoader
          implements XMLComponent, XMLDTDFilter, XMLDTDContentModelFilter {
  
      //
      // Constants
      //
  
      /** Top level scope (-1). */
      private static final int TOP_LEVEL_SCOPE = -1;
  
      // feature identifiers
  
      /** Feature identifier: validation. */
      protected static final String VALIDATION =
      Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  
      /** Feature identifier: dynamic validation. */
      protected static final String DYNAMIC_VALIDATION = 
      Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE;
  
      /** Feature identifier: warn on duplicate attdef */
      protected static final String WARN_ON_DUPLICATE_ATTDEF = 
      Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ATTDEF_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;
  
      /** Property identifier: grammar pool. */
      protected static final String GRAMMAR_POOL =
          Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  
      /** Property identifier: validator . */
      protected static final String DTD_VALIDATOR =
          Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
  
      // recognized features and properties
  
      /** Recognized features. */
      protected static final String[] RECOGNIZED_FEATURES = {
          VALIDATION,
          DYNAMIC_VALIDATION
      };
  
      /** Recognized properties. */
      protected static final String[] RECOGNIZED_PROPERTIES = {
          SYMBOL_TABLE,       
          ERROR_REPORTER,
          GRAMMAR_POOL,       
          DTD_VALIDATOR,
      };
  
      // debugging
  
      //        
      // Data
      //
  
      // features
  
      /** Validation. */
      protected boolean fValidation;
  
      /** Validation against only DTD */
      protected boolean fDTDValidation;
  
      /** 
       * Dynamic validation. This state of this feature is only useful when
       * the validation feature is set to <code>true</code>.
       */
      protected boolean fDynamicValidation;
  
      /** warn on duplicate attribute definition, this feature works only when validation is true */
      protected boolean fWarnDuplicateAttdef;
          
      // properties
  
      /** Symbol table. */
      protected SymbolTable fSymbolTable;
  
      /** Error reporter. */
      protected XMLErrorReporter fErrorReporter;
  
      /** Grammar bucket. */
      protected DTDGrammarBucket fGrammarBucket;
  
      // the validator to which we look for our grammar bucket (the
      // validator needs to hold the bucket so that it can initialize
      // the grammar with details like whether it's for a standalone document...
      protected XMLDTDValidator fValidator;
  
      // the grammar pool we'll try to add the grammar to:
      protected XMLGrammarPool fGrammarPool;
  
      // handlers
  
      /** DTD handler. */
      protected XMLDTDHandler fDTDHandler;
  
      /** DTD content model handler. */
      protected XMLDTDContentModelHandler fDTDContentModelHandler;
  
      // grammars
  
      /** DTD Grammar. */
      protected DTDGrammar fDTDGrammar;
  
      // state
  
      /** Perform validation. */
      private boolean fPerformValidation;
  
      /** True if in an ignore conditional section of the DTD. */
      protected boolean fInDTDIgnore;
  
      // information regarding the current element
  
      // validation states
  
      /** Mixed. */
      private boolean fMixed;
  
      // temporary variables
  
      /** Temporary entity declaration. */
      private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
  
      /** Notation declaration hash. */
      private Hashtable fNDataDeclNotations = new Hashtable();
  
      /** DTD element declaration name. */
      private String fDTDElementDeclName = null;
  
      /** Mixed element type "hash". */
      private Vector fMixedElementTypes = new Vector();
  
      /** Element declarations in DTD. */
      private Vector fDTDElementDecls = new Vector();
  
      // symbols: general
  
      /** Symbol: "EMPTY". */
      private String fEMPTYSymbol;
  
      /** Symbol: "ANY". */
      private String fANYSymbol;
  
      // symbols: DTD datatype
  
      /** Symbol: "CDATA". */
      private String fCDATASymbol;
  
      /** Symbol: "ID". */
      private String fIDSymbol;
  
      /** Symbol: "IDREF". */
      private String fIDREFSymbol;
  
      /** Symbol: "IDREFS". */
      private String fIDREFSSymbol;
  
      /** Symbol: "ENTITY". */
      private String fENTITYSymbol;
  
      /** Symbol: "ENTITIES". */
      private String fENTITIESSymbol;
  
      /** Symbol: "NMTOKEN". */
      private String fNMTOKENSymbol;
  
      /** Symbol: "NMTOKENS". */
      private String fNMTOKENSSymbol;
  
      /** Symbol: "NOTATION". */
      private String fNOTATIONSymbol;
  
      /** Symbol: "ENUMERATION". */
      private String fENUMERATIONSymbol;
  
      /** Symbol: "#IMPLIED. */
      private String fIMPLIEDSymbol;
  
      /** Symbol: "#REQUIRED". */
      private String fREQUIREDSymbol;
  
      /** Symbol: "#FIXED". */
      private String fFIXEDSymbol;
  
      // to check for duplicate ID or ANNOTATION attribute declare in
      // ATTLIST, and misc VCs
  
      /** ID attribute names. */
      private Hashtable fTableOfIDAttributeNames;
  
      /** NOTATION attribute names. */
      private Hashtable fTableOfNOTATIONAttributeNames;
  
      /** NOTATION enumeration values. */
      private Hashtable fNotationEnumVals;
  
      //
      // Constructors
      //
  
      /** Default constructor. */
      public XMLDTDLoader() {
  
          // initialize data
  
      } // <init>()
  
      //
      // 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 finitialization 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 XMLConfigurationException {
  
          // clear grammars
          fDTDGrammar = null;
          // initialize state
          fInDTDIgnore = false;
  
          fNDataDeclNotations.clear();
  
          // sax features
          try {
              fValidation = componentManager.getFeature(VALIDATION);
          }
          catch (XMLConfigurationException e) {
              fValidation = false;
          }
          try {
              fDTDValidation = !(componentManager.getFeature(Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE));
          }
          catch (XMLConfigurationException e) {
              // must be in a schema-less configuration!
              fDTDValidation = true;
          }
  
          // Xerces features
          try {
              fDynamicValidation = componentManager.getFeature(DYNAMIC_VALIDATION);
          }
          catch (XMLConfigurationException e) {
              fDynamicValidation = false;
          }
          
          try {
              fWarnDuplicateAttdef = componentManager.getFeature(WARN_ON_DUPLICATE_ATTDEF);
          }
          catch (XMLConfigurationException e) {
              fWarnDuplicateAttdef = false;
          }
  
  
          // get needed components
          fErrorReporter = (XMLErrorReporter)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.ERROR_REPORTER_PROPERTY);
          fSymbolTable = (SymbolTable)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY);
          try {
              fGrammarPool= (XMLGrammarPool)componentManager.getProperty(GRAMMAR_POOL);
          } catch (XMLConfigurationException e) {
              fGrammarPool = null;
          }
          try {
              fValidator = (XMLDTDValidator)componentManager.getProperty(DTD_VALIDATOR);
          } catch (XMLConfigurationException e) {
              fValidator = null;
          } catch (ClassCastException e) {
              fValidator = null;
          }
          // we get our grammarBucket from the validator...
          if(fValidator != null) {
              fGrammarBucket = fValidator.getGrammarBucket();
          } else {
              fGrammarBucket = null;
          }
  
          init();
  
      } // 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 RECOGNIZED_FEATURES;
      } // 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 RECOGNIZED_PROPERTIES;
      } // getRecognizedProperties():String[]
  
      /**
       * Sets the value of a property. This method is called by the component
       * manager any time after reset when a property changes value. 
       * <p>
       * <strong>Note:</strong> Components should silently ignore properties
       * that do not affect the operation of the component.
       * 
       * @param propertyId The property identifier.
       * @param value      The value of the property.
       *
       * @throws SAXNotRecognizedException The component should not throw
       *                                   this exception.
       * @throws SAXNotSupportedException The component should not throw
       *                                  this exception.
       */
      public void setProperty(String propertyId, Object value)
      throws XMLConfigurationException {
      } // setProperty(String,Object)
  
      //
      // XMLDTDSource methods
      //
  
      /**
       * Sets the DTD handler.
       * 
       * @param dtdHandler The DTD handler.
       */
      public void setDTDHandler(XMLDTDHandler dtdHandler) {
          fDTDHandler = dtdHandler;
      } // setDTDHandler(XMLDTDHandler)
  
      //
      // XMLDTDContentModelSource methods
      //
  
      /**
       * Sets the DTD content model handler.
       * 
       * @param dtdContentModelHandler The DTD content model handler.
       */
      public void setDTDContentModelHandler(XMLDTDContentModelHandler dtdContentModelHandler) {
          fDTDContentModelHandler = dtdContentModelHandler;
      } // setDTDContentModelHandler(XMLDTDContentModelHandler)
  
      //
      // XMLDTDContentModelHandler and XMLDTDHandler methods
      //
  
      /**
       * The start of the DTD external subset.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void startExternalSubset(XMLResourceIdentifier identifier, 
                                      Augmentations augs) throws XNIException {
          fDTDGrammar.startExternalSubset(identifier, augs);
          if(fDTDHandler != null){
              fDTDHandler.startExternalSubset(identifier, augs);
          }
      }
  
      /**
       * The end of the DTD external subset.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endExternalSubset(Augmentations augs) throws XNIException {
          fDTDGrammar.endExternalSubset(augs);
          if(fDTDHandler != null){
              fDTDHandler.endExternalSubset(augs);
          }
      }
  
      /** 
       * Check standalone entity reference. 
       * Made static to make common between the validator and loader.
       * 
       * @param name
       *@param grammar    grammar to which entity belongs
       * @param tempEntityDecl    empty entity declaration to put results in
       * @param errorReporter     error reporter to send errors to
       *
       * @throws XNIException Thrown by application to signal an error.
       */
      protected static void checkStandaloneEntityRef(String name, DTDGrammar grammar,
                      XMLEntityDecl tempEntityDecl, XMLErrorReporter errorReporter) throws XNIException {
          // check VC: Standalone Document Declartion, entities references appear in the document.
          int entIndex = grammar.getEntityDeclIndex(name);
          if (entIndex > -1) {
              grammar.getEntityDecl(entIndex, tempEntityDecl);
              if (tempEntityDecl.inExternal) {
                  errorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
                                              "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE",
                                              new Object[]{name}, XMLErrorReporter.SEVERITY_ERROR);
              }
          }
      }
  
      /**
       * 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 {
  
          // call handlers
          fDTDGrammar.comment(text, augs);
          if (fDTDHandler != null) {
              fDTDHandler.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 {
  
          // call handlers
          fDTDGrammar.processingInstruction(target, data, augs);
          if (fDTDHandler != null) {
              fDTDHandler.processingInstruction(target, data, augs);
          }
      } // processingInstruction(String,XMLString)
  
      //
      // XMLDTDHandler methods
      //
  
      /**
       * The start of the DTD.
       *
       * @param locator  The document locator, or null if the document
       *                 location cannot be reported during the parsing of 
       *                 the document DTD. However, it is <em>strongly</em>
       *                 recommended that a locator be supplied that can 
       *                 at least report the base system identifier of the
       *                 DTD.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
  
  
          // initialize state
          fNDataDeclNotations.clear();
          fDTDElementDecls.removeAllElements();
  
          // the grammar bucket's DTDGrammar will now be the
          // one we want, whether we're constructing it or not.
          // if we're not consructing it, then we should not have a reference
          // to it!
         if( !fGrammarBucket.getActiveGrammar().isImmutable()) {
              fDTDGrammar = fGrammarBucket.getActiveGrammar();
          }
  
          // call handlers
          fDTDGrammar.startDTD(locator, augs);
          if (fDTDHandler != null) {
              fDTDHandler.startDTD(locator, augs);
          }
  
      } // startDTD(XMLLocator)
  
      /**
       * Characters within an IGNORE conditional section.
       *
       * @param text The ignored text.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void ignoredCharacters(XMLString text, Augmentations augs) throws XNIException {
  
          // ignored characters in DTD
          fDTDGrammar.ignoredCharacters(text, augs);
          if (fDTDHandler != null) {
              fDTDHandler.ignoredCharacters(text, augs);
          }
      }
  
      /**
       * Notifies of the presence of a TextDecl line in an entity. If present,
       * this method will be called immediately following the startParameterEntity call.
       * <p>
       * <strong>Note:</strong> This method is only called for external
       * parameter entities referenced in the DTD.
       * 
       * @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 {
  
          // call handlers
          fDTDGrammar.textDecl(version, encoding, augs);
          if (fDTDHandler != null) {
              fDTDHandler.textDecl(version, encoding, augs);
          }
      }
  
      /**
       * This method notifies of the start of a parameter entity. The parameter
       * entity name start with a '%' character.
       * 
       * @param name     The name of the parameter entity.
       * @param identifier The resource identifier.
       * @param encoding The auto-detected IANA encoding name of the entity
       *                 stream. This value will be null in those situations
       *                 where the entity encoding is not auto-detected (e.g.
       *                 internal parameter entities).
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void startParameterEntity(String name, 
                                       XMLResourceIdentifier identifier,
                                       String encoding,
                                       Augmentations augs) throws XNIException {
  
          if (fPerformValidation && fDTDGrammar != null &&
                  fGrammarBucket.getStandalone()) {
              checkStandaloneEntityRef(name, fDTDGrammar, fEntityDecl, fErrorReporter);
          }
          // call handlers
          fDTDGrammar.startParameterEntity(name, identifier, encoding, augs);
          if (fDTDHandler != null) {
              fDTDHandler.startParameterEntity(name, identifier, encoding, augs);
          }
      }
  
      /**
       * This method notifies the end of a parameter entity. Parameter entity
       * names begin with a '%' character.
       * 
       * @param name The name of the parameter entity.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endParameterEntity(String name, Augmentations augs) throws XNIException {
  
          // call handlers
          fDTDGrammar.endParameterEntity(name, augs);
          if (fDTDHandler != null) {
              fDTDHandler.endParameterEntity(name, augs);
          }
      } 
  
      /**
       * An element declaration.
       * 
       * @param name         The name of the element.
       * @param contentModel The element content model.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void elementDecl(String name, String contentModel, Augmentations augs)
      throws XNIException {
  
          //check VC: Unique Element Declaration
          if (fValidation) {
              if (fDTDElementDecls.contains(name)) {
                  fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                             "MSG_ELEMENT_ALREADY_DECLARED",
                                             new Object[]{ name},
                                             XMLErrorReporter.SEVERITY_ERROR);
              }
              else {
                  fDTDElementDecls.addElement(name);
              }
          }
  
          // call handlers
          fDTDGrammar.elementDecl(name, contentModel, augs);
          if (fDTDHandler != null) {
              fDTDHandler.elementDecl(name, contentModel, augs);
          }
  
      } // elementDecl(String,String)
  
      /**
       * The start of an attribute list.
       * 
       * @param elementName The name of the element that this attribute
       *                    list is associated with.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void startAttlist(String elementName, Augmentations augs) 
          throws XNIException {
  
          // call handlers
          fDTDGrammar.startAttlist(elementName, augs);
          if (fDTDHandler != null) {
              fDTDHandler.startAttlist(elementName, augs);
          }
  
      } // startAttlist(String)
  
      /**
       * An attribute declaration.
       * 
       * @param elementName   The name of the element that this attribute
       *                      is associated with.
       * @param attributeName The name of the attribute.
       * @param type          The attribute type. This value will be one of
       *                      the following: "CDATA", "ENTITY", "ENTITIES",
       *                      "ENUMERATION", "ID", "IDREF", "IDREFS", 
       *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
       * @param enumeration   If the type has the value "ENUMERATION" or
       *                      "NOTATION", this array holds the allowed attribute
       *                      values; otherwise, this array is null.
       * @param defaultType   The attribute default type. This value will be
       *                      one of the following: "#FIXED", "#IMPLIED",
       *                      "#REQUIRED", or null.
       * @param defaultValue  The attribute default value, or null if no
       *                      default value is specified.
       * @param nonNormalizedDefaultValue  The attribute default value with no normalization 
       *                      performed, or null if no default value is specified.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void attributeDecl(String elementName, String attributeName, 
                                String type, String[] enumeration, 
                                String defaultType, XMLString defaultValue,
                                XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
  
          if (type != fCDATASymbol && defaultValue != null) {
              normalizeDefaultAttrValue(defaultValue);
          }
  
          if (fValidation) {
          
                  boolean	duplicateAttributeDef = false ;
                                          
                  //Get Grammar index to grammar array
                  int elementIndex       = fDTDGrammar.getElementDeclIndex( elementName);
                  if (fDTDGrammar.getAttributeDeclIndex(elementIndex, attributeName) != -1) {
                      //more than one attribute definition is provided for the same attribute of a given element type.
                      duplicateAttributeDef = true ;
  
                      //this feature works only when validation is true.
                      if(fWarnDuplicateAttdef){
                          fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                   "MSG_DUPLICATE_ATTRIBUTE_DEFINITION",
                                                   new Object[]{ elementName, attributeName },
                                                   XMLErrorReporter.SEVERITY_WARNING );
                      }
                  }
  
  
              //
              // a) VC: One ID per Element Type, If duplicate ID attribute
              // b) VC: ID attribute Default. if there is a declareared attribute
              //        default for ID it should be of type #IMPLIED or #REQUIRED
              if (type == fIDSymbol) {
                  if (defaultValue != null && defaultValue.length != 0) {
                      if (defaultType == null || 
                          !(defaultType == fIMPLIEDSymbol ||
                            defaultType == fREQUIREDSymbol)) {
                          fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                     "IDDefaultTypeInvalid",
                                                     new Object[]{ attributeName},
                                                     XMLErrorReporter.SEVERITY_ERROR);
                      }
                  }
  
                  if (!fTableOfIDAttributeNames.containsKey(elementName)) {
                      fTableOfIDAttributeNames.put(elementName, attributeName);
                  }
                  else {
                          //we should not report an error, when there is duplicate attribute definition for given element type
                          //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
                          //element type, the first declaration is binding and later declaration are *ignored*. So processor should 
                          //ignore the second declarations, however an application would be warned of the duplicate attribute defintion 
                          // if http://apache.org/xml/features/validation/warn-on-duplicate-attdef feature is set to true,
                          // one typical case where this could be a  problem, when any XML file  
                          // provide the ID type information through internal subset so that it is available to the parser which read 
                          //only internal subset. Now that attribute declaration(ID Type) can again be part of external parsed entity 
                          //referenced. At that time if parser doesn't make this distinction it will throw an error for VC One ID per 
                          //Element Type, which (second defintion) actually should be ignored. Application behavior may differ on the
                          //basis of error or warning thrown. - nb.
  
                          if(!duplicateAttributeDef){
                                  String previousIDAttributeName = (String)fTableOfIDAttributeNames.get( elementName );//rule a)
                                  fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                 "MSG_MORE_THAN_ONE_ID_ATTRIBUTE",
                                                 new Object[]{ elementName, previousIDAttributeName, attributeName},
                                                 XMLErrorReporter.SEVERITY_ERROR);
                          }
                  }
              }
  
              //
              //  VC: One Notaion Per Element Type, should check if there is a
              //      duplicate NOTATION attribute
  
              if (type == fNOTATIONSymbol) {
                  // VC: Notation Attributes: all notation names in the
                  //     (attribute) declaration must be declared.
                  for (int i=0; i<enumeration.length; i++) {
                      fNotationEnumVals.put(enumeration[i], attributeName);
                  }
  
                  if (fTableOfNOTATIONAttributeNames.containsKey( elementName ) == false) {
                      fTableOfNOTATIONAttributeNames.put( elementName, attributeName);
                  }
                  else {
                          //we should not report an error, when there is duplicate attribute definition for given element type
                          //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given
                          //element type, the first declaration is binding and later declaration are *ignored*. So processor should 
                          //ignore the second declarations, however an application would be warned of the duplicate attribute defintion 
                          // 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 
                          //warning thrown. - nb.
  
                          if(!duplicateAttributeDef){
                  
                                  String previousNOTATIONAttributeName = (String) fTableOfNOTATIONAttributeNames.get( elementName );
                                  fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                 "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE",
                                                 new Object[]{ elementName, previousNOTATIONAttributeName, attributeName},
                                                 XMLErrorReporter.SEVERITY_ERROR);
                           }
                  }
              }
  
              // VC: Attribute Default Legal
              boolean ok = true;
              if (defaultValue != null && 
                  (defaultType == null ||
                   (defaultType != null && defaultType == fFIXEDSymbol))) {
  
                  String value = defaultValue.toString();
                  if (type == fNMTOKENSSymbol ||
                      type == fENTITIESSymbol || type == fIDREFSSymbol) {
  
                      StringTokenizer tokenizer = new StringTokenizer(value);
                      if (tokenizer.hasMoreTokens()) {
                          while (true) {
                              String nmtoken = tokenizer.nextToken();
                              if (type == fNMTOKENSSymbol) {
                                  if (!XMLChar.isValidNmtoken(nmtoken)) {
                                      ok = false;
                                      break;
                                  }
                              }
                              else if (type == fENTITIESSymbol ||
                                       type == fIDREFSSymbol) {
                                  if (!XMLChar.isValidName(nmtoken)) {
                                      ok = false;
                                      break;
                                  }
                              }
                              if (!tokenizer.hasMoreTokens()) {
                                  break;
                              }
                          }
                      }
  
                  }
                  else {
                      if (type == fENTITYSymbol ||
                          type == fIDSymbol ||
                          type == fIDREFSymbol ||
                          type == fNOTATIONSymbol) {
  
                          if (!XMLChar.isValidName(value)) {
                              ok = false;
                          }
  
                      }
                      else if (type == fNMTOKENSymbol ||
                               type == fENUMERATIONSymbol) {
  
                          if (!XMLChar.isValidNmtoken(value)) {
                              ok = false;
                          }
                      }
  
                      if (type == fNOTATIONSymbol ||
                          type == fENUMERATIONSymbol) {
                          ok = false;
                          for (int i=0; i<enumeration.length; i++) {
                              if (defaultValue.equals(enumeration[i])) {
                                  ok = true;
                              }
                          }
                      }
  
                  }
                  if (!ok) {
                      fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                 "MSG_ATT_DEFAULT_INVALID",
                                                 new Object[]{attributeName, value},
                                                 XMLErrorReporter.SEVERITY_ERROR);
                  }
              }
          }
  
          // call handlers
          fDTDGrammar.attributeDecl(elementName, attributeName, 
                                    type, enumeration,
                                    defaultType, defaultValue, nonNormalizedDefaultValue, augs);
          if (fDTDHandler != null) {
              fDTDHandler.attributeDecl(elementName, attributeName, 
                                        type, enumeration, 
                                        defaultType, defaultValue, nonNormalizedDefaultValue, augs);
          }
  
      } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
  
      /**
       * The end of an attribute list.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endAttlist(Augmentations augs) throws XNIException {
  
          // call handlers
          fDTDGrammar.endAttlist(augs);
          if (fDTDHandler != null) {
              fDTDHandler.endAttlist(augs);
          }
  
      } // endAttlist()
  
      /**
       * An internal entity declaration.
       * 
       * @param name The name of the entity. Parameter entity names start with
       *             '%', whereas the name of a general entity is just the 
       *             entity name.
       * @param text The value of the entity.
       * @param nonNormalizedText The non-normalized value of the entity. This
       *             value contains the same sequence of characters that was in 
       *             the internal entity declaration, without any entity
       *             references expanded.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void internalEntityDecl(String name, XMLString text,
                                     XMLString nonNormalizedText,
                                     Augmentations augs) throws XNIException {
  
          int index = fDTDGrammar.getEntityDeclIndex(name) ;
  
          //If the same entity is declared more than once, the first declaration
          //encountered is binding, SAX requires only effective(first) declaration
          //to be reported to the application
  
          //REVISIT: Does it make sense to pass duplicate Entity information across
          //the pipeline -- nb?
  
          //its a new entity and hasn't been declared.
          if(index == -1){
              //store internal entity declaration in grammar
              fDTDGrammar.internalEntityDecl(name, text, nonNormalizedText, augs);
              // call handlers
              if (fDTDHandler != null) {
                  fDTDHandler.internalEntityDecl(name, text, nonNormalizedText, augs);
              }
          }
  
      } // internalEntityDecl(String,XMLString,XMLString)
  
  
      /**
       * An external entity declaration.
       * 
       * @param name     The name of the entity. Parameter entity names start
       *                 with '%', whereas the name of a general entity is just
       *                 the entity name.
       * @param identifier    An object containing all location information 
       *                      pertinent to this external entity.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void externalEntityDecl(String name, XMLResourceIdentifier identifier,
                                     Augmentations augs) throws XNIException {
  
          int index = fDTDGrammar.getEntityDeclIndex(name) ;
  
          //If the same entity is declared more than once, the first declaration
          //encountered is binding, SAX requires only effective(first) declaration
          //to be reported to the application
  
          //REVISIT: Does it make sense to pass duplicate entity information across
          //the pipeline -- nb?
  
          //its a new entity and hasn't been declared.
          if(index == -1){
              //store external entity declaration in grammar
              fDTDGrammar.externalEntityDecl(name, identifier, augs);
              // call handlers
              if (fDTDHandler != null) {
                  fDTDHandler.externalEntityDecl(name, identifier, augs);
              }
          }
  
      } // externalEntityDecl(String,XMLResourceIdentifier, Augmentations)
  
      /**
       * An unparsed entity declaration.
       * 
       * @param name     The name of the entity.
       * @param identifier    An object containing all location information 
       *                      pertinent to this entity.
       * @param notation The name of the notation.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
                                     String notation, 
                                     Augmentations augs) throws XNIException {
  
          // VC: Notation declared,  in the production of NDataDecl
          if (fValidation) {
              fNDataDeclNotations.put(name, notation);
          }
  
          // call handlers
          fDTDGrammar.unparsedEntityDecl(name, identifier, notation, augs);
          if (fDTDHandler != null) {
              fDTDHandler.unparsedEntityDecl(name, identifier, notation, augs);
          }
  
      } // unparsedEntityDecl(String,XMLResourceIdentifier,String,Augmentations)
  
      /**
       * A notation declaration
       * 
       * @param name     The name of the notation.
       * @param identifier    An object containing all location information 
       *                      pertinent to this notation.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void notationDecl(String name, XMLResourceIdentifier identifier,
                               Augmentations augs) throws XNIException {
  
          // call handlers
          fDTDGrammar.notationDecl(name, identifier, augs);
          if (fDTDHandler != null) {
              fDTDHandler.notationDecl(name, identifier, augs);
          }
  
      } // notationDecl(String,XMLResourceIdentifier, Augmentations)
  
      /**
       * The start of a conditional section.
       * 
       * @param type The type of the conditional section. This value will
       *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #CONDITIONAL_INCLUDE
       * @see #CONDITIONAL_IGNORE
       */
      public void startConditional(short type, Augmentations augs) throws XNIException {
  
          // set state
          fInDTDIgnore = type == XMLDTDHandler.CONDITIONAL_IGNORE;
  
          // call handlers
          fDTDGrammar.startConditional(type, augs);
          if (fDTDHandler != null) {
              fDTDHandler.startConditional(type, augs);
          }
  
      } // startConditional(short)
  
      /**
       * The end of a conditional section.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endConditional(Augmentations augs) throws XNIException {
  
          // set state
          fInDTDIgnore = false;
  
          // call handlers
          fDTDGrammar.endConditional(augs);
          if (fDTDHandler != null) {
              fDTDHandler.endConditional(augs);
          }
  
      } // endConditional()
  
      /**
       * The end of the DTD.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endDTD(Augmentations augs) throws XNIException {
  
  
          // save grammar
          fDTDGrammar.endDTD(augs);
  
          // check VC: Notation declared,  in the production of NDataDecl
          if (fValidation) {
  
              // VC : Notation Declared. for external entity declaration [Production 76].
              Enumeration entities = fNDataDeclNotations.keys();
              while (entities.hasMoreElements()) {
                  String entity = (String) entities.nextElement();
                  String notation = (String) fNDataDeclNotations.get(entity);
                  if (fDTDGrammar.getNotationDeclIndex(notation) == -1) {
                      fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                 "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL",
                                                 new Object[]{entity, notation},
                                                 XMLErrorReporter.SEVERITY_ERROR);
                  }
              }
  
              // VC: Notation Attributes:
              //     all notation names in the (attribute) declaration must be declared.
              Enumeration notationVals = fNotationEnumVals.keys();
              while (notationVals.hasMoreElements()) {
                  String notation = (String) notationVals.nextElement();
                  String attributeName = (String) fNotationEnumVals.get(notation);
                  if (fDTDGrammar.getNotationDeclIndex(notation) == -1) {
                      fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                 "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE",
                                                 new Object[]{attributeName, notation},
                                                 XMLErrorReporter.SEVERITY_ERROR);
                  }
              }
  
              fTableOfIDAttributeNames = null;//should be safe to release these references
              fTableOfNOTATIONAttributeNames = null;
          }
  
          // call handlers
          if (fDTDHandler != null) {
              fDTDHandler.endDTD(augs);
          }
  
      } // endDTD()
  
      //
      // XMLDTDContentModelHandler methods
      //
  
      /**
       * The start of a content model. Depending on the type of the content
       * model, specific methods may be called between the call to the
       * startContentModel method and the call to the endContentModel method.
       * 
       * @param elementName 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 startContentModel(String elementName, Augmentations augs) 
          throws XNIException {
  
          if (fValidation) {
              fDTDElementDeclName = elementName;
              fMixedElementTypes.removeAllElements();
          }
  
          // call handlers
          fDTDGrammar.startContentModel(elementName, augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.startContentModel(elementName, augs);
          }
  
      } // startContentModel(String)
  
      /** 
       * A content model of ANY. 
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #empty
       * @see #startGroup
       */
      public void any(Augmentations augs) throws XNIException {
          fDTDGrammar.any(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.any(augs);
          }
      } // any()
  
      /**
       * A content model of EMPTY.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #any
       * @see #startGroup
       */
      public void empty(Augmentations augs) throws XNIException {
          fDTDGrammar.empty(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.empty(augs);
          }
      } // empty()
  
      /**
       * A start of either a mixed or children content model. A mixed
       * content model will immediately be followed by a call to the
       * <code>pcdata()</code> method. A children content model will
       * contain additional groups and/or elements.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #any
       * @see #empty
       */
      public void startGroup(Augmentations augs) throws XNIException {
  
          fMixed = false;
          // call handlers
          fDTDGrammar.startGroup(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.startGroup(augs);
          }
  
      } // startGroup()
  
      /**
       * The appearance of "#PCDATA" within a group signifying a
       * mixed content model. This method will be the first called
       * following the content model's <code>startGroup()</code>.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *     
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #startGroup
       */
      public void pcdata(Augmentations augs) {
          fMixed = true;
          fDTDGrammar.pcdata(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.pcdata(augs);
          }
      } // pcdata()
  
      /**
       * A referenced element in a mixed or children content model.
       * 
       * @param elementName The name of the referenced element.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void element(String elementName, Augmentations augs) throws XNIException {
  
          // check VC: No duplicate Types, in a single mixed-content declaration
          if (fMixed && fValidation) {
              if (fMixedElementTypes.contains(elementName)) {
                  fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                             "DuplicateTypeInMixedContent",
                                             new Object[]{fDTDElementDeclName, elementName},
                                             XMLErrorReporter.SEVERITY_ERROR);
              }
              else {
                  fMixedElementTypes.addElement(elementName);
              }
          }
  
          // call handlers
          fDTDGrammar.element(elementName, augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.element(elementName, augs);
          }
  
      } // childrenElement(String)
  
      /**
       * The separator between choices or sequences of a mixed or children
       * content model.
       * 
       * @param separator The type of children separator.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #SEPARATOR_CHOICE
       * @see #SEPARATOR_SEQUENCE
       */
      public void separator(short separator, Augmentations augs) 
          throws XNIException {
  
          // call handlers
          fDTDGrammar.separator(separator, augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.separator(separator, augs);
          }
  
      } // separator(short)
  
      /**
       * The occurrence count for a child in a children content model or
       * for the mixed content model group.
       * 
       * @param occurrence The occurrence count for the last element
       *                   or group.
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       *
       * @see #OCCURS_ZERO_OR_ONE
       * @see #OCCURS_ZERO_OR_MORE
       * @see #OCCURS_ONE_OR_MORE
       */
      public void occurrence(short occurrence, Augmentations augs) 
          throws XNIException {
  
          // call handlers
          fDTDGrammar.occurrence(occurrence, augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.occurrence(occurrence, augs);
          }
  
      } // occurrence(short)
  
      /**
       * The end of a group for mixed or children content models.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endGroup(Augmentations augs) throws XNIException {
  
          // call handlers
          fDTDGrammar.endGroup(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.endGroup(augs);
          }
  
      } // endGroup()
  
      /**
       * The end of a content model.
       *
       * @param augs Additional information that may include infoset
       *                      augmentations.
       *
       * @throws XNIException Thrown by handler to signal an error.
       */
      public void endContentModel(Augmentations augs) throws XNIException {
  
          // call handlers
          fDTDGrammar.endContentModel(augs);
          if (fDTDContentModelHandler != null) {
              fDTDContentModelHandler.endContentModel(augs);
          }
  
      } // endContentModel()
  
      //
      // Private methods
      //
  
      /**
       * Normalize the attribute value of a non CDATA default attribute
       * collapsing sequences of space characters (x20)
       *
       * @param value The value to normalize
       * @return Whether the value was changed or not.
       */
      private boolean normalizeDefaultAttrValue(XMLString value) {
  
          int oldLength = value.length;
  
          boolean skipSpace = true; // skip leading spaces
          int current = value.offset;
          int end = value.offset + value.length;
          for (int i = value.offset; i < end; i++) {
              if (value.ch[i] == ' ') {
                  if (!skipSpace) {
                      // take the first whitespace as a space and skip the others
                      value.ch[current++] = ' ';
                      skipSpace = true;
                  }
                  else {
                      // just skip it.
                  }
              }
              else {
                  // simply shift non space chars if needed
                  if (current != i) {
                      value.ch[current] = value.ch[i];
                  }
                  current++;
                  skipSpace = false;
              }
          }
          if (current != end) {
              if (skipSpace) {
                  // if we finished on a space trim it
                  current--;
              }
              // set the new value length
              value.length = current - value.offset;
              return true;
          }
          return false;
      }
  
      /** initialization */
      private void init() {
  
          // symbols
          fEMPTYSymbol = fSymbolTable.addSymbol("EMPTY");
          fANYSymbol = fSymbolTable.addSymbol("ANY");
  
          fCDATASymbol = fSymbolTable.addSymbol("CDATA");
          fIDSymbol = fSymbolTable.addSymbol("ID");
          fIDREFSymbol = fSymbolTable.addSymbol("IDREF");
          fIDREFSSymbol = fSymbolTable.addSymbol("IDREFS");
          fENTITYSymbol = fSymbolTable.addSymbol("ENTITY");
          fENTITIESSymbol = fSymbolTable.addSymbol("ENTITIES");
          fNMTOKENSymbol = fSymbolTable.addSymbol("NMTOKEN");
          fNMTOKENSSymbol = fSymbolTable.addSymbol("NMTOKENS");
          fNOTATIONSymbol = fSymbolTable.addSymbol("NOTATION");
          fENUMERATIONSymbol = fSymbolTable.addSymbol("ENUMERATION");
          fIMPLIEDSymbol = fSymbolTable.addSymbol("#IMPLIED");
          fREQUIREDSymbol = fSymbolTable.addSymbol("#REQUIRED");
          fFIXEDSymbol = fSymbolTable.addSymbol("#FIXED");
  
          // datatype validators
          if (fValidation) {
  
              if (fNotationEnumVals == null) {
                  fNotationEnumVals = new Hashtable(); 
              }
              fNotationEnumVals.clear();
  
              fTableOfIDAttributeNames = new Hashtable();
              fTableOfNOTATIONAttributeNames = new Hashtable();
          }
  
      } // init()
  
  } // class XMLDTDLoader
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org