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...@locus.apache.org on 2000/05/02 04:26:06 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/framework XMLDocumentScanner.java XMLDTDScanner.java

andyc       00/05/01 19:26:06

  Modified:    java/src/org/apache/xerces/framework Tag: schemawork
                        XMLDocumentScanner.java XMLDTDScanner.java
  Log:
  Removed scanning methods from EventHandler inner interfaces
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.3.2.2   +278 -98   xml-xerces/java/src/org/apache/xerces/framework/XMLDocumentScanner.java
  
  Index: XMLDocumentScanner.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/framework/XMLDocumentScanner.java,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- XMLDocumentScanner.java	2000/04/17 21:40:54	1.3.2.1
  +++ XMLDocumentScanner.java	2000/05/02 02:26:05	1.3.2.2
  @@ -58,8 +58,10 @@
   package org.apache.xerces.framework;
   
   import org.apache.xerces.readers.XMLEntityHandler;
  +import org.apache.xerces.utils.ChunkyCharArray;
   import org.apache.xerces.utils.QName;
   import org.apache.xerces.utils.StringPool;
  +import org.apache.xerces.utils.XMLCharacterProperties;
   import org.apache.xerces.utils.XMLMessages;
   
   import org.xml.sax.Locator;
  @@ -77,7 +79,7 @@
    * "connecting" that method to the corresponding method provided
    * by the XMLDTDScanner class.
    *
  - * @version $Id: XMLDocumentScanner.java,v 1.3.2.1 2000/04/17 21:40:54 jeffreyr Exp $
  + * @version $Id: XMLDocumentScanner.java,v 1.3.2.2 2000/05/02 02:26:05 andyc Exp $
    */
   public final class XMLDocumentScanner {
       //
  @@ -147,6 +149,13 @@
       //
       // Instance Variables
       //
  +    /***
  +    // NOTE: Used by old implementation of scanElementType method. -Ac
  +    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
  +    /***/
  +    XMLDTDScanner fDTDScanner = null;
  +    boolean fNamespacesEnabled = false;
  +    boolean fValidationEnabled = false;
       QName fElementQName = new QName();
       QName fAttributeQName = new QName();
       QName fCurrentElementQName = new QName();
  @@ -181,54 +190,6 @@
        */
       public interface EventHandler {
           /**
  -         * Scan an element type.
  -         *
  -         * If namespaces are supported, this method should scan a QName instead of a
  -         * Name and report any related well-formedness errors.
  -         *
  -         * @param entityReader The entity reader.
  -         * @param fastchar A likely non-name character that might terminate the element type.
  -         * <!--
  -         * @return The handle in the string pool for the element type scanned, or -1 if
  -         *         we were not able to scan an element type at the current location.
  -         * -->
  -         * @exception java.lang.Exception
  -         */
  -        public void scanElementType(XMLEntityHandler.EntityReader entityReader, 
  -                                   char fastchar, QName element) throws Exception;
  -        /**
  -         * Scan the expected element type.
  -         *
  -         * This method is used to scan the matching end tag for the element type at the current
  -         * nesting depth of the document.
  -         *
  -         * @param entityReader The entity reader.
  -         * @param fastchar A likely non-name character that might terminate the element type.
  -         * @return <code>true</code> if we scanned the expected element type; otherwise
  -         *         <code>false</code> if we were not able to scan an element type at the
  -         *         current location, or if that element type was not the one we expected to
  -         *         find.
  -         * @exception java.lang.Exception
  -         */
  -        public boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader, 
  -                                               char fastchar, QName element) throws Exception;
  -        /**
  -         * Scan an attribute name.
  -         *
  -         * If namespaces are supported, this method should scan a QName instead of a
  -         * Name and report any related well-formedness errors.
  -         *
  -         * @param entityReader The entity reader.
  -         * @param elementType The element type for this attribute.
  -         * <!--
  -         * @return The handle in the string pool for the attribute name scanned, or -1 if
  -         *         we were not able to scan an attribute name at the current location.
  -         * -->
  -         * @exception java.lang.Exception
  -         */
  -        public void scanAttributeName(XMLEntityHandler.EntityReader entityReader, 
  -                                     QName element, QName attribute) throws Exception;
  -        /**
            * Signal the start of a document
            *
            * @exception java.lang.Exception
  @@ -272,22 +233,6 @@
            */
           public void callEndElement(int readerId) throws Exception;
           /**
  -         * Check for a valid XML version number
  -         *
  -         * @param version a string representing an XML version number
  -         * @return true if the parser can process this version of XML
  -         * @exception java.lang.Exception
  -         */
  -        public boolean validVersionNum(String version) throws Exception;
  -        /**
  -         * Check for a valid encoding name
  -         *
  -         * @param encoding a string containing an encoding naem
  -         * @return true if the encoding name is valid
  -         * @exception java.lang.Exception
  -         */
  -        public boolean validEncName(String encoding) throws Exception;
  -        /**
            * Signal the start of a CDATA section
            * @exception java.lang.Exception
            */
  @@ -319,26 +264,6 @@
            * @exception java.lang.Exception
            */
           public void callComment(int data) throws Exception;
  -        /**
  -         * Scan the document type declaration
  -         *
  -         * @param standalone true if there was a standalone document declaration in
  -         *        the XMLDecl
  -         * @exception java.lang.Exception
  -         */
  -        public void scanDoctypeDecl(boolean standalone) throws Exception;
  -        /**
  -         * Scan the value of an attribute and include it in the set of specified
  -         * attributes for the element.
  -         *
  -         * @param elementType handle for the element type of the attribute.
  -         * @param attrName handle for the attribute name.
  -         * @return XMLDocumentScanner.RESULT_SUCCESS if the attribute was created,
  -         *         XMLDocumentScanner.RESULT_NOT_WELL_FORMED if the scan failed, or
  -         *         XMLDocumentScanner.RESULT_DUPLICATE_ATTR if the attribute is a duplicate.
  -         * @exception java.lang.Exception
  -         */
  -        public int scanAttValue(QName element, QName attribute) throws Exception;
       }
   
       /**
  @@ -797,7 +722,7 @@
                           if (fEntityReader.skippedString(doctype_string)) {
                               setScannerState(SCANNER_STATE_DOCTYPE);
                               fSeenDoctypeDecl = true;
  -                            fEventHandler.scanDoctypeDecl(fStandalone); // scan through the closing '>'
  +                            scanDoctypeDecl(fStandalone); // scan through the closing '>'
                               fScannerMarkupDepth--;
                               fDispatcher = new PrologDispatcher();
                               restoreScannerState(SCANNER_STATE_PROLOG);
  @@ -904,7 +829,7 @@
                               if (!fSeenDoctypeDecl && fEntityReader.skippedString(doctype_string)) {
                                   setScannerState(SCANNER_STATE_DOCTYPE);
                                   fSeenDoctypeDecl = true;
  -                                fEventHandler.scanDoctypeDecl(fStandalone); // scan through the closing '>'
  +                                scanDoctypeDecl(fStandalone); // scan through the closing '>'
                                   fScannerMarkupDepth--;
                               } else {
                                   abortMarkup(XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_PROLOG,
  @@ -997,7 +922,7 @@
                   switch (fScannerState) {
                   case SCANNER_STATE_ROOT_ELEMENT:
                   {
  -                    fEventHandler.scanElementType(fEntityReader, '>', fElementQName);
  +                    scanElementType(fEntityReader, '>', fElementQName);
                       if (fElementQName.rawname != -1) {
                           //
                           // root element
  @@ -1094,7 +1019,7 @@
                               //
                               // [42] ETag ::= '</' Name S? '>'
                               //
  -                            if (!fEventHandler.scanExpectedElementType(fEntityReader, '>', fElementQName)) {
  +                            if (!scanExpectedElementType(fEntityReader, '>', fElementQName)) {
                                   abortMarkup(XMLMessages.MSG_ETAG_REQUIRED,
                                               XMLMessages.P39_UNTERMINATED,
                                               fCurrentElementType);
  @@ -1122,7 +1047,7 @@
                                   }
                               }
                           } else {
  -                            fEventHandler.scanElementType(fEntityReader, '>', fElementQName);
  +                            scanElementType(fEntityReader, '>', fElementQName);
                               if (fElementQName.rawname != -1) {
                                   //
                                   // element
  @@ -1208,7 +1133,7 @@
                           //
                           // [42] ETag ::= '</' Name S? '>'
                           //
  -                        if (!fEventHandler.scanExpectedElementType(fEntityReader, '>', fElementQName)) {
  +                        if (!scanExpectedElementType(fEntityReader, '>', fElementQName)) {
                               abortMarkup(XMLMessages.MSG_ETAG_REQUIRED,
                                           XMLMessages.P39_UNTERMINATED,
                                           fCurrentElementType);
  @@ -1241,7 +1166,7 @@
                       {
                           fScannerMarkupDepth++;
                           fParseTextDecl = false;
  -                        fEventHandler.scanElementType(fEntityReader, '>', fElementQName);
  +                        scanElementType(fEntityReader, '>', fElementQName);
                           if (fElementQName.rawname != -1) {
                               if (fEntityReader.lookingAtChar('>', true)) {
                                   fEventHandler.callStartElement(fElementQName);
  @@ -1689,7 +1614,7 @@
                   version = result;
                   String versionString = fStringPool.toString(version);
                   if (!"1.0".equals(versionString)) {
  -                    if (!fEventHandler.validVersionNum(versionString)) {
  +                    if (!validVersionNum(versionString)) {
                           abortMarkup(XMLMessages.MSG_VERSIONINFO_INVALID,
                                               XMLMessages.P26_INVALID_VALUE,
                                               versionString);
  @@ -1722,7 +1647,7 @@
                   //
                   encoding = result;
                   String encodingString = fStringPool.toString(encoding);
  -                if (!fEventHandler.validEncName(encodingString)) {
  +                if (!validEncName(encodingString)) {
                       abortMarkup(XMLMessages.MSG_ENCODINGDECL_INVALID,
                                   XMLMessages.P81_INVALID_VALUE,
                                   encodingString);
  @@ -1815,8 +1740,7 @@
                   // Name
                   //
                   setScannerState(SCANNER_STATE_ATTRIBUTE_NAME);
  -                fEventHandler.scanAttributeName(fEntityReader, 
  -                                                element, fAttributeQName);
  +                scanAttributeName(fEntityReader, element, fAttributeQName);
                   if (fAttributeQName.rawname == -1) {
                       break;
                   }
  @@ -1835,7 +1759,7 @@
                   }
                   fEntityReader.skipPastSpaces();
                   //int result = fEventHandler.scanAttValue(prefixIndex, elementType, 
  -                int result = fEventHandler.scanAttValue(element,  fAttributeQName);
  +                int result = scanAttValue(element,  fAttributeQName);
                   if (result == RESULT_FAILURE) {
                       if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
                           skipPastEndOfCurrentMarkup();
  @@ -2038,5 +1962,261 @@
           int piData = piDataLength == 0 ?
                        StringPool.EMPTY_STRING : fEntityReader.addString(piDataOffset, piDataLength);
           fEventHandler.callProcessingInstruction(piTarget, piData);
  +    }
  +
  +    /** Sets whether the parser preprocesses namespaces. */
  +    public void setNamespacesEnabled(boolean enabled) {
  +        fNamespacesEnabled = enabled;
  +    }
  +
  +    /** Returns whether the parser processes namespaces. */
  +    public boolean getNamespacesEnabled() {
  +        return fNamespacesEnabled;
  +    }
  +
  +    /** Sets whether the parser validates. */
  +    public void setValidationEnabled(boolean enabled) {
  +        fValidationEnabled = enabled;
  +    }
  +
  +    /** Returns true if validation is turned on. */
  +    public boolean getValidationEnabled() {
  +        return fValidationEnabled;
  +    }
  +
  +    // old EventHandler methods pushed back into scanner
  +
  +    /** Scans element type. */
  +    private void scanElementType(XMLEntityHandler.EntityReader entityReader, 
  +                                char fastchar, QName element) throws Exception {
  +
  +        if (!fNamespacesEnabled) {
  +            element.clear();
  +            element.localpart = entityReader.scanName(fastchar);
  +            element.rawname = element.localpart;
  +        } 
  +        else {
  +            entityReader.scanQName(fastchar, element);
  +            if (entityReader.lookingAtChar(':', false)) {
  +                fErrorReporter.reportError(fErrorReporter.getLocator(),
  +                                           XMLMessages.XML_DOMAIN,
  +                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
  +                                           XMLMessages.P5_INVALID_CHARACTER,
  +                                           null,
  +                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
  +                 entityReader.skipPastNmtoken(' ');
  +            }
  +        }
  +
  +    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
  +
  +    /** Scans expected element type. */
  +    private boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader, 
  +                                           char fastchar, QName element) 
  +        throws Exception {
  +
  +        /***
  +        // REVISIT: Why aren't we using the 'element' parameter? -Ac
  +        if (fCurrentElementCharArrayRange == null) {
  +            fCurrentElementCharArrayRange = fStringPool.createCharArrayRange();
  +        }
  +        fStringPool.getCharArrayRange(fCurrentElement.rawname, fCurrentElementCharArrayRange);
  +        return entityReader.scanExpectedName(fastchar, fCurrentElementCharArrayRange);
  +        /***/
  +        entityReader.scanQName(fastchar, element);
  +        return true;
  +        /***/
  +
  +    } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
  +
  +    /** Scans attribute name. */
  +    private void scanAttributeName(XMLEntityHandler.EntityReader entityReader, 
  +                                  QName element, QName attribute) 
  +        throws Exception {
  +
  +        /***
  +        // REVISIT: What's this check for?
  +        if (!fSeenRootElement) {
  +            fSeenRootElement = true;
  +            rootElementSpecified(element);
  +            fStringPool.resetShuffleCount();
  +        }
  +        /***/
  +
  +        if (!fNamespacesEnabled) {
  +            attribute.clear();
  +            attribute.localpart = entityReader.scanName('=');
  +            attribute.rawname = attribute.localpart;
  +        } 
  +        else {
  +            entityReader.scanQName('=', attribute);
  +            if (entityReader.lookingAtChar(':', false)) {
  +                fErrorReporter.reportError(fErrorReporter.getLocator(),
  +                                           XMLMessages.XML_DOMAIN,
  +                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
  +                                           XMLMessages.P5_INVALID_CHARACTER,
  +                                           null,
  +                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
  +                entityReader.skipPastNmtoken(' ');
  +            }
  +        }
  +
  +    } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)
  +
  +    /** Scan doctype declaration. */
  +    private void scanDoctypeDecl(boolean standalone) throws Exception {
  +
  +        /***
  +        fScanningDTD = true;
  +        fCheckedForSchema = true;
  +        /***/
  +        fSeenDoctypeDecl = true;
  +        /***
  +        fStandaloneReader = standalone ? fEntityHandler.getReaderId() : -1;
  +        fDeclsAreExternal = false;
  +        if (fDTDImporter == null) {
  +            fDTDImporter = new DTDImporter(fStringPool, fErrorReporter, fEntityHandler, this);
  +        } 
  +        else {
  +            fDTDImporter.reset(fStringPool);
  +        }
  +        fDTDImporter.initHandlers(fDTDHandler);
  +        fDTDImporter.setValidating(fValidating);
  +        fDTDImporter.setNamespacesEnabled(fNamespacesEnabled);
  +        if (fDTDImporter.scanDoctypeDecl(standalone) && fValidating) {
  +            // check declared elements
  +            if (fWarningOnUndeclaredElements) {
  +                // REVISIT: comment out because won't compile 
  +                // checkDeclaredElements();
  +            }
  +
  +            // check required notations
  +            fEntityHandler.checkRequiredNotations();
  +        }
  +        fScanningDTD = false;
  +        /***/
  +        if (fDTDScanner == null) {
  +            fDTDScanner = new XMLDTDScanner(fStringPool, fErrorReporter, fEntityHandler, new ChunkyCharArray(fStringPool));
  +        }
  +        else {
  +            fDTDScanner.reset(fStringPool, new ChunkyCharArray(fStringPool));
  +        }
  +        // REVISIT: What about standalone?
  +        if (fDTDScanner.scanDoctypeDecl()) {
  +            if (fDTDScanner.getReadingExternalEntity()) {
  +                fDTDScanner.scanDecls(true);
  +            }
  +            // REVISIT: What about validation and checking stuff?
  +        }
  +        /***/
  +
  +    } // scanDoctypeDecl(boolean)
  +
  +    /** Scan attribute value. */
  +    private int scanAttValue(QName element, QName attribute) throws Exception {
  +
  +        //fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
  +        int attValue = scanAttValue(element, attribute, fValidationEnabled);
  +        if (attValue == -1) {
  +            return XMLDocumentScanner.RESULT_FAILURE;
  +        }
  +
  +        //
  +        // Check for Schema and load
  +        //
  +
  +        /*
  +        if (!fCheckedForSchema) {
  +            fCheckedForSchema = true;
  +            if (attrName == fStringPool.addSymbol("xmlns")) { // default namespacedecl
  +                                
  +                if (fSchemaImporter == null) {
  +                    fSchemaImporter = new SchemaImporter(fStringPool, fErrorReporter, fEntityHandler, this);
  +                } else {
  +                    fSchemaImporter.reset(fStringPool);
  +                }
  +                String fs = fEntityHandler.expandSystemId(fStringPool.toString(attValue));
  +                EntityResolver resolver = fEntityHandler.getEntityResolver();
  +                InputSource is = resolver == null ? null : resolver.resolveEntity(null, fs);
  +                if (is == null) {
  +                    is = new InputSource(fs);
  +                }
  +
  +                fSchemaImporter.loadSchema(is);
  +                fSchemaDocument = fSchemaImporter.getSchemaDocument();
  +            }
  +        }
  +        */
  +
  +        /***
  +        // REVISIT: This is validation related.
  +        if (!fValidating && fAttDefCount == 0) {
  +            int attType = fCDATASymbol;
  +            if (fAttrListHandle == -1)
  +                fAttrListHandle = fAttrList.startAttrList();
  +            // REVISIT: Should this be localpart or rawname?
  +            if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
  +                return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
  +            }
  +            return XMLDocumentScanner.RESULT_SUCCESS;
  +        }
  +
  +        // REVISIT: Validation. What should these be?
  +        int attDefIndex = getAttDef(element, attribute);
  +        if (attDefIndex == -1) {
  +            if (fValidating) {
  +                // REVISIT - cache the elem/attr tuple so that we only give
  +                //  this error once for each unique occurrence
  +                Object[] args = { fStringPool.toString(element.rawname),
  +                                  fStringPool.toString(attribute.rawname) };
  +                fErrorReporter.reportError(fAttrNameLocator,
  +                                           XMLMessages.XML_DOMAIN,
  +                                           XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
  +                                           XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
  +                                           args,
  +                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
  +            }
  +            int attType = fCDATASymbol;
  +            if (fAttrListHandle == -1) {
  +                fAttrListHandle = fAttrList.startAttrList();
  +            }
  +            // REVISIT: Validation. What should the name be?
  +            if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
  +                return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
  +            }
  +            return XMLDocumentScanner.RESULT_SUCCESS;
  +        }
  +
  +        int attType = getAttType(attDefIndex);
  +        if (attType != fCDATASymbol) {
  +            AttributeValidator av = getAttributeValidator(attDefIndex);
  +            int enumHandle = getEnumeration(attDefIndex);
  +            // REVISIT: Validation. What should these be?
  +            attValue = av.normalize(element, attribute, 
  +                                    attValue, attType, enumHandle);
  +        }
  +
  +        if (fAttrListHandle == -1) {
  +            fAttrListHandle = fAttrList.startAttrList();
  +        }
  +        // REVISIT: Validation. What should the name be?
  +        if (fAttrList.addAttr(attribute, attValue, attType, true, true) == -1) {
  +            return XMLDocumentScanner.RESULT_DUPLICATE_ATTR;
  +        }
  +        /***/
  +
  +        return XMLDocumentScanner.RESULT_SUCCESS;
  +
  +    } // scanAttValue(QName,QName):int
  +
  +    /** Returns true if the version number is valid. */
  +    private boolean validVersionNum(String version) {
  +        return XMLCharacterProperties.validVersionNum(version);
       }
  -}
  +
  +    /** Returns true if the encoding name is valid. */
  +    private boolean validEncName(String encoding) {
  +        return XMLCharacterProperties.validEncName(encoding);
  +    }
  +
  +} // class XMLDocumentScanner
  
  
  
  1.6.2.3   +181 -143  xml-xerces/java/src/org/apache/xerces/framework/XMLDTDScanner.java
  
  Index: XMLDTDScanner.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/framework/XMLDTDScanner.java,v
  retrieving revision 1.6.2.2
  retrieving revision 1.6.2.3
  diff -u -r1.6.2.2 -r1.6.2.3
  --- XMLDTDScanner.java	2000/04/29 00:03:35	1.6.2.2
  +++ XMLDTDScanner.java	2000/05/02 02:26:05	1.6.2.3
  @@ -60,6 +60,7 @@
   import org.apache.xerces.readers.XMLEntityHandler;
   import org.apache.xerces.utils.QName;
   import org.apache.xerces.utils.StringPool;
  +import org.apache.xerces.utils.XMLCharacterProperties;
   import org.apache.xerces.utils.XMLMessages;
   
   import org.xml.sax.Locator;
  @@ -82,7 +83,7 @@
    * </ol>
    *
    * @see XMLDTDScanner.EventHandler
  - * @version $Id: XMLDTDScanner.java,v 1.6.2.2 2000/04/29 00:03:35 andyc Exp $
  + * @version $Id: XMLDTDScanner.java,v 1.6.2.3 2000/05/02 02:26:05 andyc Exp $
    */
   public final class XMLDTDScanner {
       //
  @@ -173,6 +174,7 @@
       //
       // Instance Variables
       //
  +    private boolean fNamespacesEnabled = false;
       private QName fElementQName = new QName();
       private QName fAttributeQName = new QName();
       private QName fElementRefQName = new QName();
  @@ -368,36 +370,12 @@
       public interface EventHandler {
   
           /** Start of DTD. */
  -        public void startDTD() throws Exception;
  +        public void callStartDTD() throws Exception;
   
           /** End of DTD. */
  -        public void endDTD() throws Exception;
  +        public void callEndDTD() throws Exception;
   
           /**
  -         * Determine whether a string is a valid XML version number
  -         *  
  -         * @param version string to be checked
  -         * @return true if version is a valid XML version number
  -         * @exception java.lang.Exception
  -         */
  -        public boolean validVersionNum(String version) throws Exception;
  -        /**
  -         * Determine whether a string is a valid encoding name
  -         *
  -         * @param encoding string to be checked
  -         * @return true if encoding is a valid encoding name
  -         * @exception java.lang.Exception
  -         */
  -        public boolean validEncName(String encoding) throws Exception;
  -        /**
  -         * Determine if a string is a valid public identifier
  -         *
  -         * @param publicId string to be checked
  -         * @return true if publicId is a valid public identifier
  -         * @exception java.lang.Exception
  -         */
  -        public int validPublicId(String publicId) throws Exception;
  -        /**
            * Signal the Text declaration of an external entity.
            *
            * @param version the handle in the string pool for the version number
  @@ -415,20 +393,6 @@
            */
           public void doctypeDecl(QName rootElement, int publicId, int systemId) throws Exception;
           /**
  -         * Called when the DTDScanner starts reading from the external subset
  -         *
  -         * @param publicId StringPool handle of the public id
  -         * @param systemId StringPool handle of the system id
  -         * @exception java.lang.Exception
  -         */
  -        public void startReadingFromExternalSubset(int publicId, int systemId) throws Exception;
  -        /**
  -         * Called when the DTDScanner stop reading from the external subset
  -         *
  -         * @exception java.lang.Exception
  -         */
  -        public void stopReadingFromExternalSubset() throws Exception;
  -        /**
            * Add an element declaration (forward reference)
            *
            * @param handle to the name of the element being declared
  @@ -606,89 +570,6 @@
            */
           public void callProcessingInstruction(int piTarget, int piData) throws Exception;
           /**
  -         * Scan an element type
  -         *
  -         * @param entityReader reader to read from
  -         * @param fastchar hint - character likely to terminate the element type
  -         * <!--
  -         * @return StringPool handle for the element type
  -         * -->
  -         * @exception java.lang.Exception
  -         */
  -        public void scanElementType(XMLEntityHandler.EntityReader entityReader, 
  -                                    char fastchar, QName element) throws Exception;
  -        /**
  -         * Scan for an element type at a point in the grammar where parameter
  -         * entity references are allowed.  If such a reference is encountered,
  -         * the replacement text will be scanned, skipping any white space that
  -         * may be found, expanding references in this manner until an element
  -         * type is scanned, or we fail to find one.
  -         *
  -         * @param entityReader reader to read from
  -         * @param fastchar hint - character likely to terminate the element type
  -         * <!--
  -         * @return StringPool handle for the element type
  -         * -->
  -         * @exception java.lang.Exception
  -         */
  -        public void checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader entityReader, 
  -                                                       char fastchar, QName element) throws Exception;
  -        /**
  -         * Scan for an attribute name at a point in the grammar where parameter
  -         * entity references are allowed.  If such a reference is encountered,
  -         * the replacement text will be scanned, skipping any white space that
  -         * may be found, expanding references in this manner until an attribute
  -         * name is scanned, or we fail to find one.
  -         *
  -         * @param entityReader reader to read from
  -         * @param fastchar hint - character likely to terminate the attribute name
  -         * <!--
  -         * @return StringPool handle for the attribute name
  -         * -->
  -         * @exception java.lang.Exception
  -         */
  -        public void checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader entityReader, 
  -                                                         char fastcheck, QName attribute) throws Exception;
  -        /**
  -         * Scan for a Name at a point in the grammar where parameter entity
  -         * references are allowed.  If such a reference is encountered, the
  -         * replacement text will be scanned, skipping any white space that
  -         * may be found, expanding references in this manner until a name
  -         * is scanned, or we fail to find one.
  -         *
  -         * @param entityReader reader to read from
  -         * @param fastcheck hint - character likely to terminate the name
  -         * @return StringPool handle for the name
  -         * @exception java.lang.Exception
  -         */
  -        public int checkForNameWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception;
  -        /**
  -         * Scan for a name token at a point in the grammar where parameter
  -         * entity references are allowed.  If such a reference is encountered,
  -         * the replacement text will be scanned, skipping any white space that
  -         * may be found, expanding references in this manner until a name
  -         * token is scanned, or we fail to find one.
  -         *
  -         * @param entityReader reader to read from
  -         * @param fastcheck hint - character likely to terminate the name token
  -         * @return StringPool handle for the name token
  -         * @exception java.lang.Exception
  -         */
  -        public int checkForNmtokenWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception;
  -        /**
  -         * Scan the default value for an attribute
  -         * 
  -         * @param elementType handle to the element type that owns the attribute
  -         * @param attrName StringPool handle to the name of the attribute
  -         * @param attType the attribute type
  -         * @param enumeration StringPool handle to a string list containing enumeration values
  -         * @return StringPool handle to the default value
  -         * @exception java.lang.Exception
  -         */
  -        public int scanDefaultAttValue(QName element, QName attribute, 
  -                                       int attType, 
  -                                       int enumeration) throws Exception;
  -        /**
            * Supports DOM Level 2 internalSubset additions.
            * Called when the internal subset is completely scanned.
            */
  @@ -1106,7 +987,7 @@
               return false;
           }
           fEntityReader.skipPastSpaces();
  -        fEventHandler.scanElementType(fEntityReader, ' ', fElementQName);
  +        scanElementType(fEntityReader, ' ', fElementQName);
           if (fElementQName.rawname == -1) {
               abortMarkup(XMLMessages.MSG_ROOT_ELEMENT_TYPE_REQUIRED,
                           XMLMessages.P28_ROOT_ELEMENT_TYPE_REQUIRED);
  @@ -1146,8 +1027,11 @@
           }
           decreaseMarkupDepth();
   
  +        /***
  +        // REVISIT: What is this for?
           if (scanExternalSubset)
  -            fEventHandler.startReadingFromExternalSubset(publicId, systemId);
  +            startReadingFromExternalSubset(publicId, systemId);
  +        /***/
   
           return true;
       }
  @@ -1331,7 +1215,7 @@
               int dataLength = fLiteralData.length() - dataOffset;
               fPubidLiteral = fLiteralData.addString(dataOffset, dataLength);
               String publicId = fStringPool.toString(fPubidLiteral);
  -            int invCharIndex = fEventHandler.validPublicId(publicId);
  +            int invCharIndex = validPublicId(publicId);
               if (invCharIndex >= 0) {
                   reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
                                       XMLMessages.P12_INVALID_CHARACTER,
  @@ -1513,8 +1397,11 @@
               }
               parseTextDecl = newParseTextDecl;
           }
  +        /***
  +        // REVISIT: What is this for?
           if (extSubset)
  -            fEventHandler.stopReadingFromExternalSubset();
  +            stopReadingFromExternalSubset();
  +        /***/
       }
       //
       // [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
  @@ -1637,7 +1524,7 @@
                   version = result;
                   String versionString = fStringPool.toString(version);
                   if (!"1.0".equals(versionString)) {
  -                    if (!fEventHandler.validVersionNum(versionString)) {
  +                    if (!validVersionNum(versionString)) {
                           abortMarkup(XMLMessages.MSG_VERSIONINFO_INVALID,
                                       XMLMessages.P26_INVALID_VALUE,
                                       versionString);
  @@ -1669,7 +1556,7 @@
                   //
                   encoding = result;
                   String encodingString = fStringPool.toString(encoding);
  -                if (!fEventHandler.validEncName(encodingString)) {
  +                if (!validEncName(encodingString)) {
                       abortMarkup(XMLMessages.MSG_ENCODINGDECL_INVALID,
                                   XMLMessages.P81_INVALID_VALUE,
                                   encodingString);
  @@ -1705,7 +1592,7 @@
                           XMLMessages.P45_SPACE_REQUIRED);
               return;
           }
  -        fEventHandler.checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
  +        checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
           if (fElementQName.rawname == -1) {
               abortMarkup(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL,
                           XMLMessages.P45_ELEMENT_TYPE_REQUIRED);
  @@ -1818,7 +1705,7 @@
               }
               starRequired = true;
               checkForPEReference(false);
  -            fEventHandler.checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
  +            checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
               valueIndex = fElementRefQName.rawname;
               if (valueIndex == -1) {
                   reportFatalXMLError(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT,
  @@ -1851,7 +1738,7 @@
                   initializeContentModelStack(depth);
                   continue;
               }
  -            fEventHandler.checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
  +            checkForElementTypeWithPEReference(fEntityReader, ')', fElementRefQName);
               int valueIndex = fElementRefQName.rawname;
               if (valueIndex == -1) {
                   reportFatalXMLError(XMLMessages.MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN,
  @@ -1924,7 +1811,7 @@
                           XMLMessages.P52_SPACE_REQUIRED);
               return;
           }
  -        fEventHandler.checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
  +        checkForElementTypeWithPEReference(fEntityReader, ' ', fElementQName);
           int elementTypeIndex = fElementQName.rawname;
           if (elementTypeIndex == -1) {
               abortMarkup(XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL,
  @@ -1954,7 +1841,7 @@
               return;
           }
           while (true) {
  -            fEventHandler.checkForAttributeNameWithPEReference(fEntityReader, ' ', fAttributeQName);
  +            checkForAttributeNameWithPEReference(fEntityReader, ' ', fAttributeQName);
               int attDefName = fAttributeQName.rawname;
               if (attDefName == -1) {
                   abortMarkup(XMLMessages.MSG_ATTRIBUTE_NAME_REQUIRED_IN_ATTDEF,
  @@ -2056,9 +1943,9 @@
                       attDefDefaultType = fDEFAULT;
                   fElementQName.setValues(-1, elementTypeIndex, elementTypeIndex);
                   fAttributeQName.setValues(-1, attDefName, attDefName);
  -                attDefDefaultValue = fEventHandler.scanDefaultAttValue(fElementQName, fAttributeQName, 
  -                                                                       attDefType, 
  -                                                                       attDefEnumeration);
  +                attDefDefaultValue = scanDefaultAttValue(fElementQName, fAttributeQName, 
  +                                                         attDefType, 
  +                                                         attDefEnumeration);
                   if (attDefDefaultValue == -1) {
                       skipPastEndOfCurrentMarkup();
                       return;
  @@ -2116,8 +2003,8 @@
           while (true) {
               checkForPEReference(false);
               int nameIndex = isNotationType ?
  -                            fEventHandler.checkForNameWithPEReference(fEntityReader, ')') :
  -                            fEventHandler.checkForNmtokenWithPEReference(fEntityReader, ')');
  +                            checkForNameWithPEReference(fEntityReader, ')') :
  +                            checkForNmtokenWithPEReference(fEntityReader, ')');
               if (nameIndex == -1) {
                   if (isNotationType) {
                       reportFatalXMLError(XMLMessages.MSG_NAME_REQUIRED_IN_NOTATIONTYPE,
  @@ -2312,7 +2199,7 @@
                           XMLMessages.P82_SPACE_REQUIRED);
               return;
           }
  -        int notationName = fEventHandler.checkForNameWithPEReference(fEntityReader, ' ');
  +        int notationName = checkForNameWithPEReference(fEntityReader, ' ');
           if (notationName == -1) {
               abortMarkup(XMLMessages.MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL,
                           XMLMessages.P82_NAME_REQUIRED);
  @@ -2416,7 +2303,7 @@
                   }
               }
           }
  -        int entityName = fEventHandler.checkForNameWithPEReference(fEntityReader, ' ');
  +        int entityName = checkForNameWithPEReference(fEntityReader, ' ');
           if (entityName == -1) {
               abortMarkup(XMLMessages.MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL,
                           XMLMessages.P70_REQUIRED_NAME);
  @@ -2740,5 +2627,156 @@
           fOpStack[depth] = -1;
           fNodeIndexStack[depth] = -1;
           fPrevNodeIndexStack[depth] = -1;
  +    }
  +
  +    private boolean validVersionNum(String version) {
  +        return XMLCharacterProperties.validVersionNum(version);
  +    }
  +
  +    private boolean validEncName(String encoding) {
  +        return XMLCharacterProperties.validEncName(encoding);
       }
  -}
  +
  +    private int validPublicId(String publicId) {
  +        return XMLCharacterProperties.validPublicId(publicId);
  +    }
  +
  +    /***
  +    private void startReadingFromExternalSubset(int publicId, int systemId) throws Exception {
  +        fEntityHandler.startReadingFromExternalSubset(fStringPool.toString(publicId),
  +                                                      fStringPool.toString(systemId),
  +                                                      markupDepth());
  +    }
  +
  +    private void stopReadingFromExternalSubset() throws Exception {
  +        fEntityHandler.stopReadingFromExternalSubset();
  +    }
  +    /***/
  +
  +    private void scanElementType(XMLEntityHandler.EntityReader entityReader, 
  +                                char fastchar, QName element) throws Exception {
  +
  +        if (!fNamespacesEnabled) {
  +            element.clear();
  +            element.localpart = entityReader.scanName(fastchar);
  +            element.rawname = element.localpart;
  +            return;
  +        }
  +        entityReader.scanQName(fastchar, element);
  +        if (entityReader.lookingAtChar(':', false)) {
  +            fErrorReporter.reportError(fErrorReporter.getLocator(),
  +                                       XMLMessages.XML_DOMAIN,
  +                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
  +                                       XMLMessages.P5_INVALID_CHARACTER,
  +                                       null,
  +                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
  +            entityReader.skipPastNmtoken(' ');
  +        }
  +
  +    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
  +
  +    public void checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader entityReader, 
  +                                                   char fastchar, QName element) throws Exception {
  +
  +        if (!fNamespacesEnabled) {
  +            element.clear();
  +            element.localpart = entityReader.scanName(fastchar);
  +            element.rawname = element.localpart;
  +            return;
  +        }
  +        entityReader.scanQName(fastchar, element);
  +        if (entityReader.lookingAtChar(':', false)) {
  +            fErrorReporter.reportError(fErrorReporter.getLocator(),
  +                                       XMLMessages.XML_DOMAIN,
  +                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
  +                                       XMLMessages.P5_INVALID_CHARACTER,
  +                                       null,
  +                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
  +            entityReader.skipPastNmtoken(' ');
  +        }
  +
  +    } // checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader,char,QName)
  +
  +    public void checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader entityReader, 
  +                                                     char fastchar, QName attribute) throws Exception {
  +
  +        if (!fNamespacesEnabled) {
  +            attribute.clear();
  +            attribute.localpart = entityReader.scanName(fastchar);
  +            attribute.rawname = attribute.localpart;
  +            return;
  +        }
  +
  +        entityReader.scanQName(fastchar, attribute);
  +        if (entityReader.lookingAtChar(':', false)) {
  +            fErrorReporter.reportError(fErrorReporter.getLocator(),
  +                                       XMLMessages.XML_DOMAIN,
  +                                       XMLMessages.MSG_TWO_COLONS_IN_QNAME,
  +                                       XMLMessages.P5_INVALID_CHARACTER,
  +                                       null,
  +                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
  +            entityReader.skipPastNmtoken(' ');
  +        }
  +
  +    } // checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader,char,QName)
  +
  +    public int checkForNameWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception {
  +        //
  +        // REVISIT - what does this have to do with PE references?
  +        //
  +        int valueIndex = entityReader.scanName(fastcheck);
  +        return valueIndex;
  +    }
  +
  +    public int checkForNmtokenWithPEReference(XMLEntityHandler.EntityReader entityReader, char fastcheck) throws Exception {
  +        //
  +        // REVISIT - what does this have to do with PE references?
  +        //
  +        int nameOffset = entityReader.currentOffset();
  +        entityReader.skipPastNmtoken(fastcheck);
  +        int nameLength = entityReader.currentOffset() - nameOffset;
  +        if (nameLength == 0)
  +            return -1;
  +        int valueIndex = entityReader.addSymbol(nameOffset, nameLength);
  +        return valueIndex;
  +    }
  +
  +    public int scanDefaultAttValue(QName element, QName attribute, 
  +                                   int attType, int enumeration) throws Exception {
  +        /***
  +        if (fValidating && attType == fIDSymbol) {
  +            reportRecoverableXMLError(XMLMessages.MSG_ID_DEFAULT_TYPE_INVALID,
  +                                      XMLMessages.VC_ID_ATTRIBUTE_DEFAULT,
  +                                      attribute.rawname);
  +        }
  +        /***/
  +        int defaultAttValue = scanDefaultAttValue(element, attribute);
  +        if (defaultAttValue == -1)
  +            return -1;
  +        // REVISIT
  +        /***
  +        if (attType != fCDATASymbol) {
  +            // REVISIT: Validation. Should we pass in the element or is this
  +            //          default attribute value normalization?
  +            defaultAttValue = fValidator.normalizeAttValue(null, attribute, defaultAttValue, attType, enumeration);
  +        }
  +        /***/
  +        return defaultAttValue;
  +    }
  +
  +    /***
  +    public boolean scanDoctypeDecl(boolean standalone) throws Exception {
  +        fStandaloneReader = standalone ? fEntityHandler.getReaderId() : -1;
  +        fDeclsAreExternal = false;
  +        if (!fDTDScanner.scanDoctypeDecl()) {
  +            return false;
  +        }
  +        if (fDTDScanner.getReadingExternalEntity()) {
  +            fDTDScanner.scanDecls(true);
  +        }
  +        fDTDHandler.endDTD();
  +        return true;
  +    }
  +    /***/
  +
  +} // class XMLDTDScanner