You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by an...@apache.org on 2001/01/05 07:30:22 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/impl XMLNamespaceBinder.java XMLValidator.java

andyc       01/01/04 22:30:22

  Modified:    java/src/org/apache/xerces/impl Tag: xerces_j_2
                        XMLNamespaceBinder.java XMLValidator.java
  Log:
  1) Starting to clean up and comment XMLValidator class. There's
     still a lot to do.
  2) Replaced String#equals calls with symbol reference comparisons.
     Every little change like this across the whole system should
     yield some nice performance gains.
  3) Fixed bug in NamespaceSupport so that prefixes are returned
     correctly. This fixes the endPrefixMapping callbacks from
     the parser.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.3   +2 -2      xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLNamespaceBinder.java
  
  Index: XMLNamespaceBinder.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLNamespaceBinder.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- XMLNamespaceBinder.java	2000/12/28 09:41:15	1.1.2.2
  +++ XMLNamespaceBinder.java	2001/01/05 06:30:21	1.1.2.3
  @@ -93,7 +93,7 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: XMLNamespaceBinder.java,v 1.1.2.2 2000/12/28 09:41:15 andyc Exp $
  + * @version $Id: XMLNamespaceBinder.java,v 1.1.2.3 2001/01/05 06:30:21 andyc Exp $
    */
   public class XMLNamespaceBinder 
       implements XMLComponent, XMLDocumentFilter {
  @@ -569,7 +569,7 @@
           // end prefix mappings
           if (fDocumentHandler != null) {
               int count = fNamespaceSupport.getDeclaredPrefixCount();
  -            for (int i = count; i > 0; i--) {
  +            for (int i = count - 1; i >= 0; i--) {
                   String prefix = fNamespaceSupport.getDeclaredPrefixAt(i);
                   fDocumentHandler.endPrefixMapping(prefix);
               }
  
  
  
  1.1.2.62  +520 -405  xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLValidator.java
  
  Index: XMLValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLValidator.java,v
  retrieving revision 1.1.2.61
  retrieving revision 1.1.2.62
  diff -u -r1.1.2.61 -r1.1.2.62
  --- XMLValidator.java	2001/01/04 08:17:00	1.1.2.61
  +++ XMLValidator.java	2001/01/05 06:30:21	1.1.2.62
  @@ -2,8 +2,8 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
  - * reserved.
  + * Copyright (c) 1999,2000,2001 The Apache Software Foundation.  
  + * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
  @@ -60,6 +60,7 @@
   import org.apache.xerces.impl.XMLErrorReporter;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.impl.validation.ContentModelValidator;
  +import org.apache.xerces.impl.validation.DatatypeValidator;
   import org.apache.xerces.impl.validation.DatatypeValidatorFactory;
   import org.apache.xerces.impl.validation.Grammar;
   import org.apache.xerces.impl.validation.GrammarPool;
  @@ -67,9 +68,19 @@
   import org.apache.xerces.impl.validation.XMLElementDecl;
   import org.apache.xerces.impl.validation.XMLEntityDecl;
   import org.apache.xerces.impl.validation.XMLSimpleType ;
  +import org.apache.xerces.impl.validation.datatypes.DatatypeValidatorFactoryImpl;
  +import org.apache.xerces.impl.validation.datatypes.ENTITYDatatypeValidator;
  +import org.apache.xerces.impl.validation.datatypes.IDDatatypeValidator;
  +import org.apache.xerces.impl.validation.datatypes.IDREFDatatypeValidator;
  +import org.apache.xerces.impl.validation.datatypes.ListDatatypeValidator;
  +import org.apache.xerces.impl.validation.datatypes.NOTATIONDatatypeValidator;
  +import org.apache.xerces.impl.validation.InvalidDatatypeFacetException;
  +import org.apache.xerces.impl.validation.InvalidDatatypeValueException;
   import org.apache.xerces.impl.validation.grammars.DTDGrammar;
  +
   import org.apache.xerces.util.SymbolTable;
   import org.apache.xerces.util.XMLChar;
  +
   import org.apache.xerces.xni.QName;
   import org.apache.xerces.xni.XMLComponent;
   import org.apache.xerces.xni.XMLComponentManager;
  @@ -82,16 +93,6 @@
   import org.apache.xerces.xni.XMLDTDContentModelFilter;
   import org.apache.xerces.xni.XMLDTDContentModelHandler;
   
  -import org.apache.xerces.impl.validation.DatatypeValidator;
  -import org.apache.xerces.impl.validation.datatypes.DatatypeValidatorFactoryImpl;
  -import org.apache.xerces.impl.validation.datatypes.ENTITYDatatypeValidator;
  -import org.apache.xerces.impl.validation.datatypes.IDDatatypeValidator;
  -import org.apache.xerces.impl.validation.datatypes.IDREFDatatypeValidator;
  -import org.apache.xerces.impl.validation.datatypes.ListDatatypeValidator;
  -import org.apache.xerces.impl.validation.datatypes.NOTATIONDatatypeValidator;
  -import org.apache.xerces.impl.validation.InvalidDatatypeFacetException;
  -import org.apache.xerces.impl.validation.InvalidDatatypeValueException;
  -
   import org.xml.sax.SAXException;
   import org.xml.sax.SAXNotRecognizedException;
   import org.xml.sax.SAXNotSupportedException;
  @@ -102,47 +103,86 @@
   import java.util.StringTokenizer;
   
   /**
  + * The universal validator. The validator implements a document
  + * filter: receiving document events from the scanner; validating
  + * the content and structure; augmenting the InfoSet, if applicable;
  + * and notifying the parser of the information resulting from the
  + * validation 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://xml.org/sax/features/validation</li>
  + *  <li>http://apache.org/xml/features/validation/dynamic</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 Eric Ye, IBM
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000
    * @author Andy Clark, IBM
    * @author Jeffrey Rodriguez IBM
    *
  - * @version $Id: XMLValidator.java,v 1.1.2.61 2001/01/04 08:17:00 andyc Exp $
  + * @version $Id: XMLValidator.java,v 1.1.2.62 2001/01/05 06:30:21 andyc Exp $
    */
   public class XMLValidator
  -implements XMLComponent, 
  -XMLDocumentFilter, XMLDTDFilter, XMLDTDContentModelFilter {
  +    implements XMLComponent, 
  +               XMLDocumentFilter, XMLDTDFilter, XMLDTDContentModelFilter 
  +    {
  +
  +    //
  +    // Constants
  +    //
  +
  +    /** Top level scope (-1). */
  +    private static final int TOP_LEVEL_SCOPE = -1;
  +    
  +    // debugging
   
  +    /** Compile to true to debug attributes. */
  +    private static final boolean DEBUG_ATTRIBUTES = false;
  +
  +    /** Compile to true to debug element children. */
  +    private static final boolean DEBUG_ELEMENT_CHILDREN = false;
  +
       //        
       // Data
       //
   
       // components
   
  -    /** fSymbolTable */
  +    /** Symbol table. */
       protected SymbolTable fSymbolTable;
   
  -    /** fErrorReporter */
  +    /** Error reporter. */
       protected XMLErrorReporter fErrorReporter;
   
  -    /** fGrammarPool */
  +    /** Grammar pool. */
       protected GrammarPool fGrammarPool;
   
  -    /** fNamespaceBinder */
  -    protected XMLNamespaceBinder fNamespaceBinder;
  -
       /** Datatype validator factory. */
       protected DatatypeValidatorFactory fDatatypeValidatorFactory;
   
  +    // utility component
  +
  +    /** Namespace binder. */
  +    protected XMLNamespaceBinder fNamespaceBinder;
  +
       // features
   
  -    /** fNamespaces */
  +    /** Namespaces. */
       protected boolean fNamespaces;
   
  -    /** fValidation */
  +    /** Validation. */
       protected boolean fValidation;
   
  -    /** fDynamicValidation */
  +    /** 
  +     * Dynamic validation. This state of this feature is only useful when
  +     * the validation feature is set to <code>true</code>.
  +     */
       protected boolean fDynamicValidation;
   
       // handlers
  @@ -160,12 +200,22 @@
   
       /** Current grammar. */
       protected Grammar fCurrentGrammar;
  +
  +    // REVISIT: There should be a way of specifying this information
  +    //          without actually binding it directly to these two
  +    //          instances of grammars. A careful look at what operations
  +    //          the validator performs on the grammar objects will tell
  +    //          us how we can make a clean separation here. -Ac
  +
  +    /** True if the current grammar is DTD. */
       protected boolean fCurrentGrammarIsDTD;
  -    protected boolean fCurrentGrammarIsSchema;
   
       /** DTD Grammar. */
       protected DTDGrammar fDTDGrammar;
   
  +    /** True if the current grammar is Schema. */
  +    protected boolean fCurrentGrammarIsSchema;
  +
       // state
   
       /** True if currently in the DTD. */
  @@ -173,100 +223,217 @@
   
       /** True if in an ignore conditional section of the DTD. */
       protected boolean fInDTDIgnore;
  +
  +    // information regarding the current element
   
  -    /** Cache all infor regarding the current element */
  -    private QName fCurrentElement = new QName();
  +    /** Current element name. */
  +    private final QName fCurrentElement = new QName();
  +
  +    /** Current element index. */
       private int fCurrentElementIndex = -1;
  +
  +    /** Current content spec type. */
       private int fCurrentContentSpecType = -1;
  -    private boolean fNamespacesEnabled = false;
  -    private int fNamespacesPrefix = -1;
  -    private QName fRootElement = new QName();
  +
  +    /** The root element name. */
  +    private final QName fRootElement = new QName();
  +
  +    /** True if seen DOCTYPE declaration. */
       private boolean fSeenDoctypeDecl = false;
   
  -    private final int TOP_LEVEL_SCOPE = -1;
  -    private int fEmptyURI = - 1; 
  +    // element stack
   
  -    /** element stack */
  +    /** Element index stack. */
       private int[] fElementIndexStack = new int[8];
  +
  +    /** Content spec type stack. */
       private int[] fContentSpecTypeStack = new int[8];
  -    private QName[] fElementQNamePartsStack      = new QName[8];
  +
  +    /** Element name stack. */
  +    private QName[] fElementQNamePartsStack = new QName[8];
   
  -    /** childrent list and offset stack */
  +    // children list and offset stack
  +
  +    /** 
  +     * Element children. This data structure is a growing stack that
  +     * holds the children of elements from the root to the current
  +     * element depth. This structure never gets "deeper" than the
  +     * deepest element. Space is re-used once each element is closed.
  +     * <p>
  +     * <strong>Note:</strong> This is much more efficient use of memory
  +     * than creating new arrays for each element depth.
  +     * <p>
  +     * <strong>Note:</strong> The use of this data structure is for
  +     * validation "on the way out". If the validation model changes to
  +     * "on the way in", then this data structure is not needed.
  +     */
       private QName[] fElementChildren = new QName[32];
  +
  +    /** Element children count. */
       private int fElementChildrenLength = 0;
  +
  +    /** 
  +     * Element children offset stack. This stack refers to offsets
  +     * into the <code>fElementChildren</code> array.
  +     * @see #fElementChildren
  +     */
       private int[] fElementChildrenOffsetStack = new int[32];
  +
  +    /** Element depth. */
       private int fElementDepth = -1;
  +
  +    // validation states
   
  -    /** validation states */
  +    /** Validation of a standalone document. */
       private boolean fStandaloneIsYes = false;
  +
  +    /** True if seen the root element. */
       private boolean fSeenRootElement = false;
  +
  +    /** True if buffer the datatype values. */
       private boolean fBufferDatatype = false;
  +
  +    /** True if inside of element content. */
       private boolean fInElementContent = false;
  +
  +    // temporary variables
   
  -    /** temporary variables so that we create less objects */
  +    /** Temporary element declaration. */
       private XMLElementDecl fTempElementDecl = new XMLElementDecl();
  +
  +    /** Temporary atribute declaration. */
       private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
  +
  +    /** Temporary entity declaration. */
       private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
  +
  +    /** Temporary qualified name. */
       private QName fTempQName = new QName();
  +
  +    /** Temporary string buffer for buffering datatype value. */
       private StringBuffer fDatatypeBuffer = new StringBuffer();
   
  -    /** ndata notation hash */
  +    /** Notation declaration hash. */
       private Hashtable fNDataDeclNotations = new Hashtable();
   
  -    /** mixed element type hash */
  +    /** DTD element declaration name. */
       private String fDTDElementDeclName = null;
  +    
  +    /** Mixed element type "hash". */
       private Vector fMixedElementTypes = new Vector();
   
  -    /** elementDecls in DTD */
  +    /** Element declarations in DTD. */
       private Vector fDTDElementDecls = new Vector();
  +
  +    /** Temporary string buffer. */
  +    private StringBuffer fBuffer = new StringBuffer();
  +
  +    // symbols: general
  +
  +    /** Symbol: "EMPTY". */
  +    private String fEMPTYSymbol;
  +
  +    /** Symbol: "ANY". */
  +    private String fANYSymbol;
   
  -    // symbols
  +    /** Symbol: "MIXED". */
  +    private String fMIXEDSymbol;
   
  -    private String fEMPTYSymbol ;
  -    private String fANYSymbol ;
  -    private String fMIXEDSymbol ;
  -    private String fCHILDRENSymbol ;
  -    private String fCDATASymbol ;
  -    private String fIDSymbol ;
  -    private String fIDREFSymbol ;
  -    private String fIDREFSSymbol ;
  -    private String fENTITYSymbol ;
  -    private String fENTITIESSymbol ;
  -    private String fNMTOKENSymbol ;
  -    private String fNMTOKENSSymbol ;
  -    private String fNOTATIONSymbol ;
  -    private String fENUMERATIONSymbol ;
  -    private String fREQUIREDSymbol ;
  -    private String fFIXEDSymbol ;
  -    private String fDATATYPESymbol ;
  -
  -
  -    /** Datatype Registry and attribute validators */
  -
  -    //private DatatypeValidatorFactoryImpl fDataTypeReg;
  -    private IDDatatypeValidator          fValID;
  -    private IDREFDatatypeValidator       fValIDRef;
  -    private ListDatatypeValidator        fValIDRefs;
  -    private ENTITYDatatypeValidator      fValENTITY;
  -    private ListDatatypeValidator        fValENTITIES;
  -    private DatatypeValidator            fValNMTOKEN;
  -    private DatatypeValidator            fValNMTOKENS;
  -    private NOTATIONDatatypeValidator    fValNOTATION;
  -
  -    private Hashtable fTableOfIDs; //This table has to be own by instance of XMLValidator and shared among ID, IDREF and IDREFS
  -                                   //Only ID has read/write access
  -                                   //Should revisit and replace with a ligther structure
  -
  -    /** DEBUG flags */
  -    private boolean DEBUG_ATTRIBUTES;
  -    private boolean DEBUG_ELEMENT_CHILDREN;
  +    /** Symbol: "CHILDREN". */
  +    private String fCHILDRENSymbol;
   
  -    /** to check for duplicate ID or ANNOTATION attribute declare in ATTLIST, and misc VCs*/
  +    // 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. */
  +    private IDDatatypeValidator fValID;
  +
  +    /** Datatype validator: IDREF. */
  +    private IDREFDatatypeValidator fValIDRef;
  +
  +    /** Datatype validator: IDREFS. */
  +    private ListDatatypeValidator fValIDRefs;
  +
  +    /** Datatype validator: ENTITY. */
  +    private ENTITYDatatypeValidator fValENTITY;
  +
  +    /** Datatype validator: ENTITIES. */
  +    private ListDatatypeValidator fValENTITIES;
  +
  +    /** Datatype validator: NMTOKEN. */
  +    private DatatypeValidator fValNMTOKEN;
  +
  +    /** Datatype validator: NMTOKENS. */
  +    private DatatypeValidator fValNMTOKENS;
  +
  +    /** Datatype validator: NOTATION. */
  +    private NOTATIONDatatypeValidator fValNOTATION;
  +
  +    /**
  +     * This table has to be own by instance of XMLValidator and shared
  +     * among ID, IDREF and IDREFS. 
  +     * <p>
  +     * <strong>Note:</strong> Only ID has read/write access.
  +     * <p>
  +     * <strong>Note:</strong> Should revisit and replace with a ligther
  +     * structure.
  +     */
  +    private Hashtable fTableOfIDs; 
  +
  +    // 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;
  -    private Hashtable fNotationEnumVals;
   
  +    /** NOTATION enumeration values. */
  +    private Hashtable fNotationEnumVals;
   
       //
       // Constructors
  @@ -275,6 +442,11 @@
       /** Default constructor. */
       public XMLValidator() {
           
  +        // initialize data
  +        for (int i = 0; i < fElementQNamePartsStack.length; i++) {
  +            fElementQNamePartsStack[i] = new QName();
  +        }
  +
           // setup namespace binder
           fNamespaceBinder = new XMLNamespaceBinder();
           fNamespaceBinder.setOnlyPassPrefixMappingEvents(true);
  @@ -333,10 +505,6 @@
           fGrammarPool = (GrammarPool)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.GRAMMAR_POOL_PROPERTY);
           fDatatypeValidatorFactory = (DatatypeValidatorFactory)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY);
   
  -        for (int i = 0; i < fElementQNamePartsStack.length; i++) {
  -            fElementQNamePartsStack[i] = new QName();
  -        }
  -
           // reset namespace binder
           fNamespaceBinder.reset(componentManager);
   
  @@ -361,7 +529,7 @@
        *                                  this exception.
        */
       public void setFeature(String featureId, boolean state)
  -    throws SAXNotRecognizedException, SAXNotSupportedException {
  +        throws SAXNotRecognizedException, SAXNotSupportedException {
       } // setFeature(String,boolean)
   
       /**
  @@ -380,7 +548,7 @@
        *                                  this exception.
        */
       public void setProperty(String propertyId, Object value)
  -    throws SAXNotRecognizedException, SAXNotSupportedException {
  +        throws SAXNotRecognizedException, SAXNotSupportedException {
       } // setProperty(String,Object)
   
       //
  @@ -454,14 +622,12 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void xmlDecl(String version, String encoding, String standalone)
  -    throws SAXException {
  -
  -        if (standalone != null)
  -            if (standalone.equals("yes")) {
  -                fStandaloneIsYes = true;
  -            }
  +        throws SAXException {
   
  -            // call handlers
  +        // save standalone state
  +        fStandaloneIsYes = standalone != null && standalone.equals("yes");
  +            
  +        // call handlers
           if (fDocumentHandler != null) {
               fDocumentHandler.xmlDecl(version, encoding, standalone);
           }
  @@ -480,8 +646,9 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void doctypeDecl(String rootElement, String publicId, String systemId)
  -    throws SAXException {
  +        throws SAXException {
   
  +        // save root element state
           fRootElement.setValues(null, rootElement, rootElement, null);
   
           // call handlers
  @@ -501,7 +668,7 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void startPrefixMapping(String prefix, String uri)
  -    throws SAXException {
  +        throws SAXException {
   
           // call handlers
           if (fDocumentHandler != null) {
  @@ -521,16 +688,18 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void startElement(QName element, XMLAttributes attributes)
  -    throws SAXException {
  +        throws SAXException {
   
           // VC: Root Element Type
           // see if the root element's name matches the one in DoctypeDecl 
           if (!fSeenRootElement) {
               fSeenRootElement = true;
  -            rootElementSpecified(element);
  +            if (fCurrentGrammarIsDTD) {
  +                rootElementSpecified(element);
  +            }
           }
   
  -        //if fCurrentGrammar is Schema, do namespace binding here.
  +        // bind namespaces, if current grammar is Schema
           if (fNamespaces && fCurrentGrammarIsSchema) {
               fNamespaceBinder.startElement(element, attributes);
           }
  @@ -539,44 +708,40 @@
               fCurrentElementIndex = -1;
               fCurrentContentSpecType = -1;
               fInElementContent = false;
  -        } else {
  +        } 
  +        else if (fCurrentGrammarIsDTD) {
  +            //  resolve the element
  +            fCurrentElementIndex = fCurrentGrammar.getElementDeclIndex(element, -1);
   
  -            if (fCurrentGrammarIsDTD) {
  -                //  resolve the element
  -                fCurrentElementIndex = fCurrentGrammar.getElementDeclIndex(element, -1);
  -
  -                fCurrentContentSpecType = getContentSpecType(fCurrentElementIndex);
  -                if (fCurrentElementIndex == -1 && fValidation) {
  -                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 
  -                                               "MSG_ELEMENT_NOT_DECLARED",
  -                                               new Object[]{ element.rawname},
  -                                               XMLErrorReporter.SEVERITY_ERROR);
  -                } else {
  -                    //  0. insert default attributes
  -                    //  1. normalize the attributes
  -                    //  2. validate the attrivute list.
  -                    // TO DO: 
  -                    // 
  -                    addDTDDefaultAttrsAndValidate(fCurrentElementIndex, attributes);
  -                }
  -            }
  -            // fCurrentGrammar Is a Schema
  +            fCurrentContentSpecType = getContentSpecType(fCurrentElementIndex);
  +            if (fCurrentElementIndex == -1 && fValidation) {
  +                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 
  +                                           "MSG_ELEMENT_NOT_DECLARED",
  +                                           new Object[]{ element.rawname},
  +                                           XMLErrorReporter.SEVERITY_ERROR);
  +            } 
               else {
  +                //  0. insert default attributes
  +                //  1. normalize the attributes
  +                //  2. validate the attrivute list.
  +                // TO DO: 
  +                // 
  +                addDTDDefaultAttrsAndValidate(fCurrentElementIndex, attributes);
               }
  -
           }
  -
  +        
  +        // buffer datatype value for Schema datatype validation
           if (fValidation && fCurrentContentSpecType == XMLElementDecl.TYPE_SIMPLE) {
               fBufferDatatype = true;
               fDatatypeBuffer.setLength(0);
           }
   
  -        fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
  +        // set element content state
  +        fInElementContent = fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN;
   
           // increment the element depth, add this element's 
           // QName to its enclosing element 's children list
           fElementDepth++;
  -        //if (fElementDepth >= 0) {
           if (fValidation) {
               // push current length onto stack
               if (fElementChildrenOffsetStack.length < fElementDepth) {
  @@ -601,16 +766,15 @@
               }
               qname.setValues(element);
               fElementChildrenLength++;
  -
           }
   
  -        //if fCurrentGrammar is DTD, do namespace binding here.
  +        // bind namespaces, if current grammar is DTD
           if (fNamespaces && fCurrentGrammarIsDTD) {
               fNamespaceBinder.startElement(element, attributes);
           }
   
  +        // save current element information
           fCurrentElement.setValues(element);
  -        
           ensureStackCapacity(fElementDepth);
           fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement); 
           fElementIndexStack[fElementDepth] = fCurrentElementIndex;
  @@ -633,6 +797,9 @@
       public void characters(XMLString text) throws SAXException {
           boolean callNextCharacters = true;
   
  +        // REVISIT: [Q] Is there a more efficient way of doing this?
  +        //          Perhaps if the scanner told us so we don't have to
  +        //          look at the characters again. -Ac
           boolean allWhiteSpace = true;
           for (int i=text.offset; i< text.offset+text.length; i++) {
               if (!XMLChar.isSpace(text.ch[i])) {
  @@ -641,7 +808,7 @@
               }
           }
   
  -        // if in children model, and all charaters are white spaces, call the ignoreableWhiteSpace callback.
  +        // call the ignoreableWhiteSpace callback
           if (fInElementContent && allWhiteSpace) {
               if (fDocumentHandler != null) {
                   fDocumentHandler.ignorableWhitespace(text);
  @@ -649,6 +816,7 @@
               }
           }
   
  +        // validate
           if (fValidation) {
               if (fInElementContent) {
                   if (fCurrentGrammarIsDTD && 
  @@ -672,6 +840,7 @@
                   fDatatypeBuffer.append(text.ch, text.offset, text.length);
               }
           }
  +
           // call handlers
           if (callNextCharacters && fDocumentHandler != null) {
               fDocumentHandler.characters(text);
  @@ -709,8 +878,10 @@
        */
       public void endElement(QName element) throws SAXException {
   
  +        // decrease element depth
           fElementDepth--;
   
  +        // validate
           if (fValidation) {
               int elementIndex = fCurrentElementIndex;
               if (elementIndex != -1 && fCurrentContentSpecType != -1) {
  @@ -720,7 +891,6 @@
                   int result = checkContent(elementIndex, 
                                             children, childrenOffset, childrenLength);
   
  -
                   if (result != -1) {
                       fCurrentGrammar.getElementDecl(elementIndex, fTempElementDecl);
                       if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
  @@ -728,7 +898,8 @@
                                                      "MSG_CONTENT_INVALID",
                                                      new Object[]{ element.rawname, "EMPTY"},
                                                      XMLErrorReporter.SEVERITY_ERROR);
  -                    } else {
  +                    } 
  +                    else {
                           String messageKey = result != childrenLength ? 
                                               "MSG_CONTENT_INVALID" : "MSG_CONTENT_INCOMPLETE";
                           fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 
  @@ -774,12 +945,12 @@
               // (1) check that there was an element with a matching id for every
               //   IDREF and IDREFS attr (V_IDREF0)
               //
  -
               if (fValidation) {
                   try {
                       fValIDRef.validate();//Do final validation of IDREFS against IDs
                       fValIDRefs.validate();
  -                } catch (InvalidDatatypeValueException ex) {
  +                } 
  +                catch (InvalidDatatypeValueException ex) {
                       String  key = ex.getKeyIntoReporter();
   
                       fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  @@ -792,14 +963,16 @@
               return;
           }
   
  -        if (fNamespaces) { //If Namespace enable then localName != rawName
  +        // If Namespace enable then localName != rawName
  +        fCurrentElement.setValues(fElementQNamePartsStack[fElementDepth]);
  +        if (fNamespaces) { 
               fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].localpart;
  -        } else {//REVISIT - jeffreyr - This is so we still do old behavior when namespace is off 
  +        } 
  +        // REVISIT: jeffreyr - This is so we still do old behavior when 
  +        //          namespace is off 
  +        else {
               fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].rawname;
           }
  -        fCurrentElement.rawname      = fElementQNamePartsStack[fElementDepth].rawname;
  -        fCurrentElement.uri          = fElementQNamePartsStack[fElementDepth].uri;
  -        fCurrentElement.prefix       = fElementQNamePartsStack[fElementDepth].prefix;
   
           fCurrentElementIndex = fElementIndexStack[fElementDepth];
           fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
  @@ -838,6 +1011,7 @@
           if (fValidation && fInElementContent) {
               charDataInContent();
           }
  +        
           // call handlers
           if (fDocumentHandler != null) {
               fDocumentHandler.startCDATA();
  @@ -911,13 +1085,15 @@
        */
       public void startEntity(String name, String publicId, String systemId,
                               String encoding) throws SAXException {
  +        
           // call handlers
           if (fInDTD) {
               fDTDGrammar.startEntity(name, publicId, systemId, encoding);
               if (fDTDHandler != null) {
                   fDTDHandler.startEntity(name, publicId, systemId, encoding);
               }
  -        } else {
  +        } 
  +        else {
               // check VC: Standalone Document Declartion, entities references appear in the document.
               if (fValidation && fCurrentGrammar != null) {
                   if (fStandaloneIsYes && !name.startsWith("[")) {
  @@ -964,7 +1140,8 @@
               if (fDTDHandler != null) {
                   fDTDHandler.textDecl(version, encoding);
               }
  -        } else {
  +        } 
  +        else {
               if (fDocumentHandler != null) {
                   fDocumentHandler.textDecl(version, encoding);
               }
  @@ -987,7 +1164,8 @@
               if (fDTDHandler != null) {
                   fDTDHandler.comment(text);
               }
  -        } else {
  +        } 
  +        else {
               if (fDocumentHandler != null) {
                   fDocumentHandler.comment(text);
               }
  @@ -1012,7 +1190,7 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void processingInstruction(String target, XMLString data)
  -    throws SAXException {
  +        throws SAXException {
   
           // call handlers
           if (fInDTD) {
  @@ -1020,7 +1198,8 @@
               if (fDTDHandler != null) {
                   fDTDHandler.processingInstruction(target, data);
               }
  -        } else {
  +        } 
  +        else {
               if (fDocumentHandler != null) {
                   fDocumentHandler.processingInstruction(target, data);
               }
  @@ -1060,7 +1239,8 @@
               if (fDTDHandler != null) {
                   fDTDHandler.endEntity(name);
               }
  -        } else {
  +        } 
  +        else {
               if (fDocumentHandler != null) {
                   fDocumentHandler.endEntity(name);
               }
  @@ -1090,7 +1270,6 @@
           // REVISIT: should we use the systemId as the key instead?
           fGrammarPool.putGrammar("", fDTDGrammar);
   
  -
           // call handlers
           fDTDGrammar.startDTD();
           if (fDTDHandler != null) {
  @@ -1108,7 +1287,7 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void elementDecl(String name, String contentModel)
  -    throws SAXException {
  +        throws SAXException {
   
           //check VC: Unique Element Declaration
           if (fValidation) {
  @@ -1117,7 +1296,8 @@
                                              "MSG_ELEMENT_ALREADY_DECLARED",
                                              new Object[]{ name},
                                              XMLErrorReporter.SEVERITY_ERROR);
  -            } else {
  +            } 
  +            else {
                   fDTDElementDecls.addElement(name);
               }
           }
  @@ -1139,8 +1319,8 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void startAttlist(String elementName) throws SAXException {
  +        
           // call handlers
  -
           fDTDGrammar.startAttlist(elementName);
           if (fDTDHandler != null) {
               fDTDHandler.startAttlist(elementName);
  @@ -1169,22 +1349,20 @@
        *
        * @throws SAXException Thrown by handler to signal an error.
        */
  -    String fnameOfElement;
  -
       public void attributeDecl(String elementName, String attributeName, 
                                 String type, String[] enumeration, 
                                 String defaultType, XMLString defaultValue)
  -    throws SAXException {
  +        throws SAXException {
   
           if (fValidation) {
               //
               // 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.equals("ID")) {
  -
  +            if (type == fIDSymbol) {
                   if (defaultValue != null) {
                       if (defaultValue.length != 0) {
  -                        if (defaultType == null || ! ( defaultType.equals("#IMPLIED") || defaultType.equals("#REQUIRED" ) )) {
  +                        if (defaultType == null || 
  +                            !(defaultType == fIMPLIEDSymbol || defaultType == fREQUIREDSymbol)) {
                               fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                          "IDDefaultTypeInvalid",
                                                          new Object[]{ attributeName},
  @@ -1193,10 +1371,11 @@
                       }
                   }
   
  -                if (fTableOfIDAttributeNames.containsKey( elementName ) == false) {
  -                    fTableOfIDAttributeNames.put( elementName, attributeName);
  -                } else {
  -                    String previousIDAttributeName = (String) fTableOfIDAttributeNames.get( elementName );//rule a)
  +                if (!fTableOfIDAttributeNames.containsKey(elementName)) {
  +                    fTableOfIDAttributeNames.put(elementName, attributeName);
  +                } 
  +                else {
  +                    String previousIDAttributeName = (String)fTableOfIDAttributeNames.get( elementName );//rule a)
                       fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                  "MSG_MORE_THAN_ONE_ID_ATTRIBUTE",
                                                  new Object[]{ elementName, previousIDAttributeName, attributeName},
  @@ -1207,7 +1386,7 @@
               //
               //  VC: One Notaion Per Element Type, should check if there is a duplicate NOTATION attribute 
   
  -            if (type.equals("NOTATION")) {
  +            if (type == fNOTATIONSymbol) {
                   // VC: Notation Attributes:
                   //     all notation names in the (attribute) declaration must be declared.
                   for (int i=0; i<enumeration.length; i++) {
  @@ -1216,7 +1395,8 @@
   
                   if (fTableOfNOTATIONAttributeNames.containsKey( elementName ) == false) {
                       fTableOfNOTATIONAttributeNames.put( elementName, attributeName);
  -                } else {
  +                } 
  +                else {
                       String previousNOTATIONAttributeName = (String) fTableOfNOTATIONAttributeNames.get( elementName );
                       fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                  "MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE",
  @@ -1228,25 +1408,27 @@
               // VC: Attribute Default Legal
               boolean ok = true;
               if (defaultValue != null && 
  -                (defaultType==null || (defaultType != null && defaultType.equals("#FIXED"))))
  -                if (type.equals("NMTOKENS") || type.equals("ENTITIES") || type.equals("IDREFS")) {
  +                (defaultType==null || (defaultType != null && defaultType == fFIXEDSymbol)))
  +                if (type == fNMTOKENSSymbol || type == fENTITIESSymbol || type == fIDREFSSymbol) {
   
                       // Since the default value has been normalized, there should be any leading or trailing spaces
                       String trimmedValue = defaultValue.toString().trim();
   
                       if (trimmedValue.length() == 0 || ! defaultValue.equals(trimmedValue)) {
                           ok = false;
  -                    } else {
  +                    } 
  +                    else {
                           StringTokenizer tokenizer = new StringTokenizer(trimmedValue);
                           if (tokenizer.hasMoreTokens()) {
                               while (true) {
                                   String nmtoken = tokenizer.nextToken();
  -                                if (type.equals("NMTOKENS")) {
  +                                if (type == fNMTOKENSSymbol) {
                                       if (!XMLChar.isValidNmtoken(nmtoken)) {
                                           ok = false;
                                           break;
                                       }
  -                                } else if (type.equals("ENTITIES")||type.equals("IDREFS")) {
  +                                } 
  +                                else if (type == fENTITIESSymbol || type == fIDREFSSymbol) {
                                       if (!XMLChar.isValidName(nmtoken)) {
                                           ok = false;
                                           break;
  @@ -1259,27 +1441,28 @@
                           }
                       }
   
  -                } else {
  -                    if (type.equals("ENTITY") ||
  -                        type.equals("ID") ||
  -                        type.equals("IDREF") ||
  -                        type.equals("NOTATION")) {
  +                } 
  +                else {
  +                    if (type == fENTITYSymbol ||
  +                        type == fIDSymbol ||
  +                        type == fIDREFSymbol ||
  +                        type == fNOTATIONSymbol) {
   
   
                           if (!XMLChar.isValidName( defaultValue.toString())) {
                               ok = false;
                           }
   
  -                    } else if (type.equals("NMTOKEN") ||
  -                               type.equals("ENUMERATION")) {
  +                    } else if (type == fNMTOKENSymbol ||
  +                               type == fENUMERATIONSymbol) {
   
                           if (!XMLChar.isValidNmtoken( defaultValue.toString())) {
                               ok = false;
                           }
                       }
   
  -                    if (type.equals("NOTATION") ||
  -                        type.equals("ENUMERATION")) {
  +                    if (type == fNOTATIONSymbol ||
  +                        type == fENUMERATIONSymbol) {
                           ok = false;
                           for (int i=0; i<enumeration.length; i++) {
                               if (defaultValue.equals(enumeration[i])) {
  @@ -1317,9 +1500,7 @@
        */
       public void endAttlist() throws SAXException {
   
  -
           // call handlers
  -
           fDTDGrammar.endAttlist();
           if (fDTDHandler != null) {
               fDTDHandler.endAttlist();
  @@ -1338,7 +1519,7 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void internalEntityDecl(String name, XMLString text) 
  -    throws SAXException {
  +        throws SAXException {
   
           // call handlers
           fDTDGrammar.internalEntityDecl(name, text);
  @@ -1360,9 +1541,8 @@
        *
        * @throws SAXException Thrown by handler to signal an error.
        */
  -    public void externalEntityDecl(String name, 
  -                                   String publicId, String systemId) 
  -    throws SAXException {
  +    public void externalEntityDecl(String name, String publicId, 
  +                                   String systemId) throws SAXException {
   
           // call handlers
           fDTDGrammar.externalEntityDecl(name, publicId, systemId);
  @@ -1413,7 +1593,7 @@
        * @throws SAXException Thrown by handler to signal an error.
        */
       public void notationDecl(String name, String publicId, String systemId)
  -    throws SAXException {
  +        throws SAXException {
   
           // call handlers
           fDTDGrammar.notationDecl(name, publicId, systemId);
  @@ -1546,7 +1726,7 @@
        * @see TYPE_CHILDREN
        */
       public void startContentModel(String elementName, short type)
  -    throws SAXException {
  +        throws SAXException {
   
           if (fValidation) {
               fDTDElementDeclName = elementName;
  @@ -1577,6 +1757,7 @@
        * @see TYPE_MIXED
        */
       public void mixedElement(String elementName) throws SAXException {
  +
           // check VC: No duplicate Types, in a single mixed-content declaration
           if (fValidation) {
               if (fMixedElementTypes.contains(elementName)) {
  @@ -1723,24 +1904,22 @@
   
       } // endContentModel()
   
  -
  -
  -    //
       //
  -    //private methods
  +    // Private methods
       //
  -    //
  -
   
  -    /** addDTDDefaultAttributes. */
  -    private void addDTDDefaultAttrsAndValidate( int elementIndex, XMLAttributes attributes) throws SAXException {
  +    /** Add default attributes and validate. */
  +    private void addDTDDefaultAttrsAndValidate(int elementIndex, 
  +                                               XMLAttributes attributes) 
  +        throws SAXException {
   
  +        // is there anything to do?
           if (elementIndex == -1) {
  -            return ;
  +            return;
           }
   
  +        // get element info
           fCurrentGrammar.getElementDecl(elementIndex,fTempElementDecl);
  -
           QName element = fTempElementDecl.name;
   
           //
  @@ -1771,7 +1950,7 @@
               String attPrefix = fTempAttDecl.name.prefix;
               String attRawName = fTempAttDecl.name.rawname;
               String attLocalpart = fTempAttDecl.name.localpart;
  -            String attType = attributeTypeName(fTempAttDecl);
  +            String attType = getAttributeTypeName(fTempAttDecl);
               int attDefaultType =fTempAttDecl.simpleType.defaultType;
               String attValue = null;
   
  @@ -1871,12 +2050,13 @@
                           fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                      "MSG_ATTRIBUTE_NOT_DECLARED",
                                                      args,XMLErrorReporter.SEVERITY_ERROR);   
  -                    } else {
  +                    } 
  +                    else {
   
                           // fTempAttDecl should have the right value set now, so the following is not needed
                           // fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl); 
   
  -                        String attributeType = attributeTypeName(fTempAttDecl);
  +                        String attributeType = getAttributeTypeName(fTempAttDecl);
                           attributes.setType(i, attributeType);
                       }
                   }
  @@ -1913,108 +2093,84 @@
                   }
               } // for all attributes
           } // if validation
  -
  -        return;
   
  -    } // addDTDDefaultAttrsAndValidate(int,XMLAttrList,int,boolean,boolean):int
  +    } // addDTDDefaultAttrsAndValidate(int,XMLAttrList)
   
       /**
  -    * Validate attributes in DTD fashion.
  -    * @return normalized attribute value
  -    */
  +     * Validate attributes in DTD fashion.
  +     * @return normalized attribute value
  +     */
       private String validateDTDattribute(QName element, String attValue, 
  -                                        XMLAttributeDecl attributeDecl) throws SAXException {
  -        //AttributeValidator av = null;
  -
  +                                        XMLAttributeDecl attributeDecl) 
  +        throws SAXException {
   
           switch (attributeDecl.simpleType.type) {
  -        
  -        case XMLSimpleType.TYPE_ENTITY:
  -            {
  -                boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef
  +            case XMLSimpleType.TYPE_ENTITY: {                            
  +                // NOTE: Save this information because invalidStandaloneAttDef
  +                boolean isAlistAttribute = attributeDecl.simpleType.list;
                   String  unTrimValue      = attValue;
                   String  value            = unTrimValue.trim();
   
  -
                   if (fValidation) {
                       if (value != unTrimValue) {
                           if (invalidStandaloneAttDef(element, attributeDecl.name)) {
  -                            fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                                                        "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE",
  -                                                        new Object[]{ value, attributeDecl.name.rawname, unTrimValue},
  -                                                        XMLErrorReporter.SEVERITY_ERROR );
  +                            fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                                       "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE",
  +                                                       new Object[]{ value, attributeDecl.name.rawname, unTrimValue},
  +                                                       XMLErrorReporter.SEVERITY_ERROR );
                           }
                       }
                   }
   
                   try {
                       if (isAlistAttribute) {
  -                        fValENTITIES.validate( value, null );
  -                    } else {
  -                        fValENTITY.validate( value, null );
  +                        fValENTITIES.validate(value, null);
  +                    } 
  +                    else {
  +                        fValENTITY.validate(value, null);
                       }
  -                } catch (InvalidDatatypeValueException ex) {
  +                } 
  +                catch (InvalidDatatypeValueException ex) {
                       String  key = ex.getKeyIntoReporter();
  -
  -                    fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                                                key,
  -                                                new Object[]{ ex.getMessage()},
  -                                                XMLErrorReporter.SEVERITY_ERROR );
  +                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                               key,
  +                                               new Object[]{ ex.getMessage()},
  +                                               XMLErrorReporter.SEVERITY_ERROR );
   
                   }
  +                break;
  +            }
   
  -                /*if (attributeDecl.list) {
  -                    av = fAttValidatorENTITIES;
  -                }
  -                else {
  -                    av = fAttValidatorENTITY;
  -                }*/
  -                /*
  -                if (fNormalizeAttributeValues) {
  -                    if (attributeDecl.list) {
  -                        attValue = normalizeListAttribute(value, attValue, unTrimValue);
  -                    } else {
  -                        if (value != unTrimValue) {
  -                            attValue = value;
  +            case XMLSimpleType.TYPE_NOTATION:
  +            case XMLSimpleType.TYPE_ENUMERATION: {
  +                boolean found = false;
  +                String [] enumVals = attributeDecl.simpleType.enumeration;
  +                if (enumVals == null) {
  +                    found = false;
  +                }
  +                else
  +                    for (int i = 0; i < enumVals.length; i++) {
  +                        if (attValue == enumVals[i] || attValue.equals(enumVals[i])) {
  +                            found = true;
  +                            break;
                           }
                       }
  +    
  +                if (!found) {
  +                    StringBuffer enumValueString = new StringBuffer();
  +                    if (enumVals != null)
  +                        for (int i = 0; i < enumVals.length; i++) {
  +                            enumValueString.append(enumVals[i]+" ");
  +                        }
  +                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 
  +                                               "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST",
  +                                               new Object[]{attributeDecl.name.rawname, attValue, enumValueString},
  +                                               XMLErrorReporter.SEVERITY_ERROR);
                   }
  -                */
  -
  -            }
  -
  -            break;
  -
  -        case XMLSimpleType.TYPE_NOTATION:
  -        case XMLSimpleType.TYPE_ENUMERATION:
  -            boolean found = false;
  -            String [] enumVals = attributeDecl.simpleType.enumeration;
  -            if (enumVals == null) {
  -                found = false;
  +                break;
               }
  -            else
  -                for (int i=0; i<enumVals.length; i++) {
  -                    if (attValue == enumVals[i] || attValue.equals(enumVals[i])) {
  -                        found = true;
  -                        break;
  -                    }
  -                }
  -
  -            if (!found ) {
  -                StringBuffer enumValueString = new StringBuffer();
  -                if (enumVals != null)
  -                    for (int i=0; i<enumVals.length; i++) {
  -                        enumValueString.append(enumVals[i]+" ");
  -                    }
   
  -                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 
  -                                           "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST",
  -                                           new Object[]{attributeDecl.name.rawname, attValue, enumValueString},
  -                                           XMLErrorReporter.SEVERITY_ERROR);
  -            }
  -            break;
  -        case XMLSimpleType.TYPE_ID:
  -            {
  +            case XMLSimpleType.TYPE_ID: {
                   String  unTrimValue = attValue;
                   String  value       = unTrimValue.trim();
                   if (fValidation) {
  @@ -2029,23 +2185,19 @@
                       }
                   }
                   try {
  -                    fValID.validate( value, null );
  -                } catch (InvalidDatatypeValueException ex) {
  +                    fValID.validate(value, null);
  +                } 
  +                catch (InvalidDatatypeValueException ex) {
                       String  key = ex.getKeyIntoReporter();
  -
  -                    fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                                                key,
  -                                                new Object[]{ ex.getMessage()},
  -                                                XMLErrorReporter.SEVERITY_ERROR );
  +                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                               key,
  +                                               new Object[] { ex.getMessage() },
  +                                               XMLErrorReporter.SEVERITY_ERROR );
                   }
  -                /*
  -                if (fNormalizeAttributeValues && value != unTrimValue) {
  -                    attValue = value;
  -                } */
  -            }
  -            break;
  -        case XMLSimpleType.TYPE_IDREF:
  -            {
  +                break;
  +            }
  +        
  +            case XMLSimpleType.TYPE_IDREF: {
                   String  unTrimValue = attValue;
                   String  value       = unTrimValue.trim();
                   boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef
  @@ -2062,38 +2214,29 @@
                       }
                   }
                   try {
  -                    if (isAlistAttribute == true) {
  +                    if (isAlistAttribute) {
                           //System.out.println("values = >>" + value + "<<" );
  -                        fValIDRefs.validate(value, null );
  -                    } else {
  -                        fValIDRef.validate(value, null );
  -                    }
  -                } catch (InvalidDatatypeValueException ex) {
  -                    String  key = ex.getKeyIntoReporter();
  -                    
  -                    if( key == null ){
  +                        fValIDRefs.validate(value, null);
  +                    } 
  +                    else {
  +                        fValIDRef.validate(value, null);
  +                    }
  +                } 
  +                catch (InvalidDatatypeValueException ex) {
  +                    String key = ex.getKeyIntoReporter();
  +                    if (key == null){
                           key = "IDREFSInvalid";
                       }
  -                    fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                                                key,
  -                                                new Object[]{ ex.getMessage()},
  -                                                XMLErrorReporter.SEVERITY_ERROR );
  +                    fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                               key,
  +                                               new Object[]{ ex.getMessage()},
  +                                               XMLErrorReporter.SEVERITY_ERROR );
   
                   }
  -                /*
  -                if (fNormalizeAttributeValues) {
  -                    if (attributeDecl.list) {
  -                        attValue = normalizeListAttribute(value, attValue, unTrimValue);
  -                    } else {
  -                        if (value != unTrimValue) {
  -                            attValue = value;
  -                        }
  -                    }
  -                } */
  +                break;
               }
  -            break;
  -        case XMLSimpleType.TYPE_NMTOKEN:
  -            {
  +
  +            case XMLSimpleType.TYPE_NMTOKEN: {
                   String  unTrimValue = attValue;
                   String  value       = unTrimValue.trim();
                   boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef
  @@ -2110,54 +2253,39 @@
                       }
                   }
                   try {
  -                    if (isAlistAttribute == true ) {
  -                        fValNMTOKENS.validate( value, null );
  -                    } else {
  -                        fValNMTOKEN.validate( value, null );
  -                    }
  -                } catch (InvalidDatatypeValueException ex) {
  -
  -                    //System.out.println("ex = " + ex.getMessage() );
  -                    if( isAlistAttribute == true ){
  -                        fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                        "NMTOKENSInvalid",
  -                        new Object[]{ value },
  -                        XMLErrorReporter.SEVERITY_ERROR );
  -                    } else{
  -                        fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
  -                        "NMTOKENInvalid",
  -                         new Object[]{ value },
  -                         XMLErrorReporter.SEVERITY_ERROR );
  +                    if (isAlistAttribute) {
  +                        fValNMTOKENS.validate(value, null);
  +                    } 
  +                    else {
  +                        fValNMTOKEN.validate(value, null);
  +                    }
  +                } 
  +                catch (InvalidDatatypeValueException ex) {
  +                    if (isAlistAttribute){
  +                        fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                                   "NMTOKENSInvalid",
  +                                                   new Object[] { value },
  +                                                   XMLErrorReporter.SEVERITY_ERROR);
  +                    } 
  +                    else {
  +                        fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
  +                                                   "NMTOKENInvalid",
  +                                                   new Object[] { value },
  +                                                   XMLErrorReporter.SEVERITY_ERROR);
                       }
                   }
  -
  -                /*
  -                if (fNormalizeAttributeValues) {
  -                    if (attributeDecl.list) {
  -                        attValue = normalizeListAttribute(value, attValue, unTrimValue);
  -                    } else {
  -                        if (value != unTrimValue) {
  -                            attValue = value;
  -                        }
  -                    }
  -                } */
  +                break;
               }
  -            break;
  -        }
  -        /*
  -        if (av != null) {
  -            int newValue = av.normalize(element, attributeDecl.name, attValue, 
  -                                        attributeDecl.type, attributeDecl.enumeration);
  -            if (fNormalizeAttributeValues)
  -                attValue = newValue;
  -        }
  -        */
  +
  +        } // switch
  +        
           return attValue;
  -    }
   
  +    } // validateDTDattribute(QName,String,XMLAttributeDecl):String
   
       /** Returns true if invalid standalone attribute definition. */
       boolean invalidStandaloneAttDef(QName element, QName attribute) {
  +        // REVISIT: This obviously needs to be fixed! -Ac
           boolean state = true;
           /*
          if (fStandaloneReader == -1) {
  @@ -2172,12 +2300,11 @@
           return state;
       }
   
  -
  -
  -
  -    StringBuffer fBuffer = new StringBuffer("");
       /** normalize the attribute in the attributes, index is the position */
  +    /***
       private void normalizeAttrValue(XMLAttributes attributes, int index) {
  +
  +        // vars
           String attrValue = attributes.getValue(index);
           char[] attValue = new char[attrValue.length()];
           boolean isCDATA = attributes.getType(index) == fCDATASymbol;
  @@ -2186,20 +2313,21 @@
           attrValue.getChars(0, attrValue.length(), attValue, 0);
   
           if (isCDATA) {
  -            for (int i=0; i<attValue.length; i++) {
  +            for (int i = 0; i < attValue.length; i++) {
                   if (attValue[i] == '\r' || attValue[i] == '\n' || attValue[i] == ' ') {
                       attValue[i] = ' ';
                   }
                   fBuffer.append(attValue[i]);
               }
  -        } else {
  +        } 
  +        else {
               boolean leadingSpace = true;
               boolean spaceStart = false;
               boolean readingNonSpace = false;
               int count = 0;
               int eaten = 0;
   
  -            for (int i=0; i<attValue.length; i++) {
  +            for (int i = 0; i < attValue.length; i++) {
   
                   if (attValue[i] == '\r' || attValue[i] == '\n' || attValue[i] == ' ') {
                       attValue[i] = ' ';
  @@ -2214,7 +2342,8 @@
                           spaceStart = false;
                           fBuffer.append(attValue[i]);
                           count++;
  -                    } else {
  +                    } 
  +                    else {
                           if (leadingSpace || !spaceStart) {
                               eaten ++;
                               int entityCount = attributes.getEntityCount(index);
  @@ -2226,7 +2355,8 @@
                                           if (length > 0)
                                               length--;
                                       }
  -                                } else {
  +                                } 
  +                                else {
                                       if (offset > 0)
                                           offset--;
                                   }
  @@ -2236,7 +2366,8 @@
                           }
                       }
   
  -                } else {
  +                } 
  +                else {
                       readingNonSpace = true;
                       spaceStart = false;
                       leadingSpace = false;
  @@ -2244,6 +2375,7 @@
                       count++;
                   }
               }
  +
               // check if the last appended character is a space.
               if (count > 0 && fBuffer.charAt(count-1) == ' ') {
                   fBuffer.setLength(count-1);
  @@ -2255,7 +2387,8 @@
                           if (offset+length == count) {
                               length--;
                           }
  -                    } else {
  +                    } 
  +                    else {
                           offset--;
                       }
                       attributes.setEntityOffset(index, j, offset);
  @@ -2266,8 +2399,10 @@
           }
           attributes.setValue(index, fBuffer.toString());
       }
  +    /***/
   
       /** normalize the default attribute value with such a type */
  +    /***
       private String normalizeDefaultAttrValue(String defaultValue, short type) {
   
           char[] attValue = new char[defaultValue.length()];
  @@ -2277,19 +2412,20 @@
           defaultValue.getChars(0, defaultValue.length(), attValue, 0);
   
           if (isCDATA) {
  -            for (int i=0; i<attValue.length; i++) {
  +            for (int i = 0; i < attValue.length; i++) {
                   if (attValue[i] == '\r' || attValue[i] == '\n' || attValue[i] == ' ') {
                       attValue[i] = ' ';
                   }
                   fBuffer.append(attValue[i]);
               }
  -        } else {
  +        } 
  +        else {
               boolean leadingSpace = true;
               boolean spaceStart = false;
               boolean readingNonSpace = false;
               int count = 0;
   
  -            for (int i=0; i<attValue.length; i++) {
  +            for (int i = 0; i < attValue.length; i++) {
   
                   if (attValue[i] == '\r' || attValue[i] == '\n' || attValue[i] == ' ') {
                       attValue[i] = ' ';
  @@ -2303,11 +2439,13 @@
                           spaceStart = false;
                           fBuffer.append(attValue[i]);
                           count++;
  -                    } else {
  +                    } 
  +                    else {
                           // just skip it.
                       }
   
  -                } else {
  +                } 
  +                else {
                       readingNonSpace = true;
                       spaceStart = false;
                       leadingSpace = false;
  @@ -2318,7 +2456,7 @@
           }
           return fBuffer.toString();
       }
  -
  +    /***/
   
       /** Root element specified. */
       private void rootElementSpecified(QName rootElement) throws SAXException {
  @@ -2334,7 +2472,6 @@
           }
       } // rootElementSpecified(QName)
   
  -
       /**
        * Check that the content of an element is valid.
        * <p>
  @@ -2436,7 +2573,6 @@
   
       } // checkContent(int,int,QName[]):int
   
  -
       /** Returns the content spec type for an element index. */
       private int getContentSpecType(int elementIndex) {
   
  @@ -2473,12 +2609,13 @@
       } // charDataInCount()
   
       /** convert attribute type from ints to strings */
  -    private String attributeTypeName(XMLAttributeDecl attrDecl) {
  +    private String getAttributeTypeName(XMLAttributeDecl attrDecl) {
  +
           switch (attrDecl.simpleType.type) {
  -        case XMLSimpleType.TYPE_ENTITY: {
  +            case XMLSimpleType.TYPE_ENTITY: {
                   return attrDecl.simpleType.list ? fENTITIESSymbol : fENTITYSymbol;
               }
  -        case XMLSimpleType.TYPE_ENUMERATION: {
  +            case XMLSimpleType.TYPE_ENUMERATION: {
                   StringBuffer buffer = new StringBuffer();
                   for (int i=0; i<attrDecl.simpleType.enumeration.length ; i++) {
                       if (i > 0) {
  @@ -2488,30 +2625,27 @@
                   }
                   return fSymbolTable.addSymbol(buffer.toString());
               }
  -        case XMLSimpleType.TYPE_ID: {
  +            case XMLSimpleType.TYPE_ID: {
                   return fIDSymbol;
               }
  -        case XMLSimpleType.TYPE_IDREF: {
  +            case XMLSimpleType.TYPE_IDREF: {
                   return attrDecl.simpleType.list ? fIDREFSSymbol : fIDREFSymbol;
               }
  -        case XMLSimpleType.TYPE_NMTOKEN: {
  +            case XMLSimpleType.TYPE_NMTOKEN: {
                   return attrDecl.simpleType.list ? fNMTOKENSSymbol : fNMTOKENSSymbol;
               }
  -        case XMLSimpleType.TYPE_NOTATION: {
  +            case XMLSimpleType.TYPE_NOTATION: {
                   return fNOTATIONSymbol;
               }
  -
           }
           return fCDATASymbol;
  -    }
  +
  +    } // getAttributeTypeName(XMLAttributeDecl):String
   
       /** intialization */
       private void init() {
   
  -        //fEmptyURI = fSymbolTable.addSymbol("");
  -        //fXsiURI = fSymbolTable.addSymbol(SchemaSymbols.URI_XSI);
  -
  -
  +        // symbols
           fEMPTYSymbol = fSymbolTable.addSymbol("EMPTY");
           fANYSymbol = fSymbolTable.addSymbol("ANY");
           fMIXEDSymbol = fSymbolTable.addSymbol("MIXED");
  @@ -2527,31 +2661,13 @@
           fNMTOKENSSymbol = fSymbolTable.addSymbol("NMTOKENS");
           fNOTATIONSymbol = fSymbolTable.addSymbol("NOTATION");
           fENUMERATIONSymbol = fSymbolTable.addSymbol("ENUMERATION");
  +        fIMPLIEDSymbol = fSymbolTable.addSymbol("#IMPLIED");
           fREQUIREDSymbol = fSymbolTable.addSymbol("#REQUIRED");
           fFIXEDSymbol = fSymbolTable.addSymbol("#FIXED");
           fDATATYPESymbol = fSymbolTable.addSymbol("<<datatype>>");
   
  -        //Initialize Validators
  -        //Datatype Registry
  -
  -        if (fValidation == true) {
  -            /* uncomment when using Registry with no Singleton
  -            fDataTypeReg = new DatatypeValidatorFactoryImpl();
  -            */
  -
  -            /***
  -            fDataTypeReg = DatatypeValidatorFactoryImpl.getDatatypeRegistry();//To be commented or deleted  when no Singleton
  -            fDataTypeReg.initializeDTDRegistry();
  -            
  -            fValID       = (IDDatatypeValidator) fDataTypeReg.getDatatypeValidator("ID" );
  -            fValIDRef    = (IDREFDatatypeValidator) fDataTypeReg.getDatatypeValidator("IDREF" );
  -            fValIDRefs   = (ListDatatypeValidator) fDataTypeReg.getDatatypeValidator("IDREFS" );
  -            fValENTITY   = (ENTITYDatatypeValidator) fDataTypeReg.getDatatypeValidator("ENTITY" );
  -            fValENTITIES = (ListDatatypeValidator) fDataTypeReg.getDatatypeValidator("ENTITIES" );
  -            fValNMTOKEN  = fDataTypeReg.getDatatypeValidator("NMTOKEN");
  -            fValNMTOKENS = fDataTypeReg.getDatatypeValidator("NMTOKENS");
  -            fValNOTATION = (NOTATIONDatatypeValidator) fDataTypeReg.getDatatypeValidator("NOTATION" );
  -            /***/
  +        // datatype validators
  +        if (fValidation) {
               try {
                   fValID       = (IDDatatypeValidator)fDatatypeValidatorFactory.createDatatypeValidator("ID", null, null, false);
                   fValIDRef    = (IDREFDatatypeValidator) fDatatypeValidatorFactory.createDatatypeValidator("IDREF", null, null, false);
  @@ -2566,7 +2682,6 @@
                   // should never happen
                   e.printStackTrace(System.err);
               }
  -            /***/
   
               //Initialize ID, IDREF, IDREFS validators
               if (fTableOfIDs == null) {
  @@ -2585,8 +2700,9 @@
               fTableOfIDAttributeNames = new Hashtable();
               fTableOfNOTATIONAttributeNames = new Hashtable();
           }
  -    }
   
  +    } // init()
  +
       /** ensure element stack capacity */
       private void ensureStackCapacity ( int newElementDepth) {
           if (newElementDepth == fElementQNamePartsStack.length) {
  @@ -2613,7 +2729,6 @@
   
           }
       } // ensureStackCapacity
  -
   
       //
       // Protected methods