You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by Jerry Lawson <je...@virtualsummit.com> on 2000/10/31 22:36:07 UTC

patch submission for propogating user's EntityResolver

The following are my submission for having the user-defined
EntityResolver
apply to <include and <import declarations in schema files.
XMLValidator.resolveSchemaGrammar() passes the local DOMParser's
entityResolver
to TraverseSchema. Note that the DOMParser's entityResolver is actually
static class TraverseSchema.Resolver, which attempts to use the
user-defined
EntityResolver, or the entityHandler.expandSystemId(), as needed.

TraverseSchema.traverseInclude() and TraverseSchema.traverseImport()
attempt to use the entityResolver (provided by XMLValidator) to resolve
the include/import schema location. The parser.parse() in these methods
were also changed to use the InputSource, rather than String, version.
I have also attached the files in their entirety.
Please check over these submissions and cvs commit them if they are
acceptable.
thanks.

Index: XMLValidator.java
===================================================================
RCS file: /home/cvspublic/xml-xerces/java/src/org/apache/xerces/validators/common/XMLValidator.java,v
retrieving revision 1.90
diff -u -r1.90 XMLValidator.java
--- XMLValidator.java   2000/10/31 17:40:36     1.90
+++ XMLValidator.java   2000/10/31 20:48:53
@@ -2246,7 +2246,11 @@
                }
                grammar = new SchemaGrammar();
                grammar.setGrammarDocument(document);
-               tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId());
+
+                  // pass parser's entity resolver (local Resolver), which also has reference
to user's
+                  // entity resolver, and also can fall-back to entityhandler's expandSystemId()
+
+               tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId(), currentER);
                fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targetNamespace"), grammar);
             }
          } catch (Exception e) {

Index: TraverseSchema.java
===================================================================
RCS file: /home/cvspublic/xml-xerces/java/src/org/apache/xerces/validators/schema/TraverseSchema.java,v
retrieving revision 1.54
diff -u -r1.54 TraverseSchema.java
--- TraverseSchema.java 2000/10/18 18:27:14     1.54
+++ TraverseSchema.java 2000/10/31 21:18:04
@@ -426,7 +426,9 @@
     private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
     private XMLElementDecl fTempElementDecl = new XMLElementDecl();

-    // REVISIT: maybe need to be moved into SchemaGrammar class
+    private EntityResolver     fEntityResolver = null;
+
+   // REVISIT: maybe need to be moved into SchemaGrammar class
     public class ComplexTypeInfo {
         public String typeName;

@@ -490,6 +492,19 @@
                            SchemaGrammar schemaGrammar,
                            GrammarResolver grammarResolver,
                            XMLErrorReporter errorReporter,
+                           String schemaURL,
+                                  EntityResolver entityResolver
+                           ) throws Exception {
+        fErrorReporter = errorReporter;
+        fCurrentSchemaURL = schemaURL;
+       fEntityResolver = entityResolver;
+        doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
+    }
+
+    public  TraverseSchema(Element root, StringPool stringPool,
+                           SchemaGrammar schemaGrammar,
+                           GrammarResolver grammarResolver,
+                           XMLErrorReporter errorReporter,
                            String schemaURL
                            ) throws Exception {
         fErrorReporter = errorReporter;
@@ -772,8 +787,25 @@

         //TO DO: !!!!! location needs to be resolved first.

-        String location = includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
-        location = expandSystemId(location, fCurrentSchemaURL);
+
+       String location = includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
+
+         // expand it before passing it to the parser
+         InputSource source = null;
+         if (fEntityResolver != null) {
+            source = fEntityResolver.resolveEntity("", location);
+         }
+         if (source == null) {
+            location = expandSystemId(location, fCurrentSchemaURL);
+            source = new InputSource(location);
+         }
+         else {
+               // create a string for uniqueness of this included schema in fIncludeLocations
+               if (source.getPublicId () != null)
+                       location = source.getPublicId ();
+
+               location += (',' + source.getSystemId ());
+         }

         if (fIncludeLocations.contains((Object)location)) {
             return;
@@ -798,7 +830,7 @@
         }

         try {
-            parser.parse( location);
+            parser.parse( source );
         }catch( IOException e ) {
             e.printStackTrace();
         }catch( SAXException e ) {
@@ -920,21 +952,36 @@
     }

     private void traverseImport(Element importDecl)  throws Exception {
-        String location = importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
-        location = expandSystemId(location, fCurrentSchemaURL);
-
-
-        String namespaceString = importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
-        SchemaGrammar importedGrammar = new SchemaGrammar();
-        if (fGrammarResolver.getGrammar(namespaceString) != null) {
-            importedGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(namespaceString);
-        }
+       String location = importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
+        // expand it before passing it to the parser
+         InputSource source = null;
+         if (fEntityResolver != null) {
+            source = fEntityResolver.resolveEntity("", location);
+         }
+         if (source == null) {
+            location = expandSystemId(location, fCurrentSchemaURL);
+            source = new InputSource(location);
+         }
+         else {
+               // create a string for uniqueness of this imported schema in fImportLocations
+               if (source.getPublicId () != null)
+                       location = source.getPublicId ();
+
+               location += (',' + source.getSystemId ());
+         }

-        if (fImportLocations.contains((Object)location)) {
+         if (fImportLocations.contains((Object)location)) {
             return;
         }
         fImportLocations.addElement((Object)location);

+       String namespaceString = importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
+       SchemaGrammar importedGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(namespaceString);
+
+       if (importedGrammar == null) {
+               importedGrammar = new SchemaGrammar();
+       }
+
         DOMParser parser = new DOMParser() {
             public void ignorableWhitespace(char ch[], int start, int length) {}
             public void ignorableWhitespace(int dataIdx) {}
@@ -953,7 +1000,7 @@
         }

         try {
-            parser.parse( location);
+            parser.parse( source );
         }catch( IOException e ) {
             e.printStackTrace();
         }catch( SAXException e ) {

--
___________________________________________________
Jerry Lawson                   Virtual Summit, Inc.
Virtual Programmer   jerry.lawson@virtualsummit.com



Re: patch submission for propogating user's EntityResolver

Posted by Eric Ye <er...@locus.apache.org>.
> 1.  Am I right that this fix is to the current development code base,
> and does not apply to Xerces 1.2.1?

Yes

> 
> 2.  When do you expect a Xerces release that incorporates it?
> 

probably beginning of December.

 _____
 
 Eric Ye * IBM, JTC - Silicon Valley * ericye@locus.apache.org



Re: patch submission for propogating user's EntityResolver

Posted by Ken Bandes <ke...@entransit.com>.
Eric Ye wrote:
> 
> I've check in your changes to the CVS repository, thanks very much for the
> patch, this bug should have been fixed long time ago.

I also have an interest in this fix.  I have two questions:

1.  Am I right that this fix is to the current development code base,
and does not apply to Xerces 1.2.1?

2.  When do you expect a Xerces release that incorporates it?

> _____
> 
> Eric Ye * IBM, JTC - Silicon Valley * ericye@locus.apache.org
> 
> ----- Original Message -----
> From: "Jerry Lawson" <je...@virtualsummit.com>
> To: <xe...@xml.apache.org>
> Sent: Tuesday, October 31, 2000 1:36 PM
> Subject: patch submission for propogating user's EntityResolver
> 
> > The following are my submission for having the user-defined
> > EntityResolver
> > apply to <include and <import declarations in schema files.
> > XMLValidator.resolveSchemaGrammar() passes the local DOMParser's
> > entityResolver
> > to TraverseSchema. Note that the DOMParser's entityResolver is actually
> > static class TraverseSchema.Resolver, which attempts to use the
> > user-defined
> > EntityResolver, or the entityHandler.expandSystemId(), as needed.

[very long patch snipped]

Thanks,
Ken Bandes

Re: patch submission for propogating user's EntityResolver

Posted by Eric Ye <er...@locus.apache.org>.
I've check in your changes to the CVS repository, thanks very much for the
patch, this bug should have been fixed long time ago.
_____


Eric Ye * IBM, JTC - Silicon Valley * ericye@locus.apache.org

----- Original Message -----
From: "Jerry Lawson" <je...@virtualsummit.com>
To: <xe...@xml.apache.org>
Sent: Tuesday, October 31, 2000 1:36 PM
Subject: patch submission for propogating user's EntityResolver


> The following are my submission for having the user-defined
> EntityResolver
> apply to <include and <import declarations in schema files.
> XMLValidator.resolveSchemaGrammar() passes the local DOMParser's
> entityResolver
> to TraverseSchema. Note that the DOMParser's entityResolver is actually
> static class TraverseSchema.Resolver, which attempts to use the
> user-defined
> EntityResolver, or the entityHandler.expandSystemId(), as needed.
>
> TraverseSchema.traverseInclude() and TraverseSchema.traverseImport()
> attempt to use the entityResolver (provided by XMLValidator) to resolve
> the include/import schema location. The parser.parse() in these methods
> were also changed to use the InputSource, rather than String, version.
> I have also attached the files in their entirety.
> Please check over these submissions and cvs commit them if they are
> acceptable.
> thanks.
>
> Index: XMLValidator.java
> ===================================================================
> RCS file:
/home/cvspublic/xml-xerces/java/src/org/apache/xerces/validators/common/XMLV
alidator.java,v
> retrieving revision 1.90
> diff -u -r1.90 XMLValidator.java
> --- XMLValidator.java   2000/10/31 17:40:36     1.90
> +++ XMLValidator.java   2000/10/31 20:48:53
> @@ -2246,7 +2246,11 @@
>                 }
>                 grammar = new SchemaGrammar();
>                 grammar.setGrammarDocument(document);
> -               tst = new TraverseSchema( root, fStringPool,
(SchemaGrammar)grammar, fGrammarResolver, fErrorReporter,
source.getSystemId());
> +
> +                  // pass parser's entity resolver (local Resolver),
which also has reference
> to user's
> +                  // entity resolver, and also can fall-back to
entityhandler's expandSystemId()
> +
> +               tst = new TraverseSchema( root, fStringPool,
(SchemaGrammar)grammar, fGrammarResolver, fErrorReporter,
source.getSystemId(), currentER);
>
fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targ
etNamespace"), grammar);
>              }
>           } catch (Exception e) {
>
> Index: TraverseSchema.java
> ===================================================================
> RCS file:
/home/cvspublic/xml-xerces/java/src/org/apache/xerces/validators/schema/Trav
erseSchema.java,v
> retrieving revision 1.54
> diff -u -r1.54 TraverseSchema.java
> --- TraverseSchema.java 2000/10/18 18:27:14     1.54
> +++ TraverseSchema.java 2000/10/31 21:18:04
> @@ -426,7 +426,9 @@
>      private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
>      private XMLElementDecl fTempElementDecl = new XMLElementDecl();
>
> -    // REVISIT: maybe need to be moved into SchemaGrammar class
> +    private EntityResolver     fEntityResolver = null;
> +
> +   // REVISIT: maybe need to be moved into SchemaGrammar class
>      public class ComplexTypeInfo {
>          public String typeName;
>
> @@ -490,6 +492,19 @@
>                             SchemaGrammar schemaGrammar,
>                             GrammarResolver grammarResolver,
>                             XMLErrorReporter errorReporter,
> +                           String schemaURL,
> +                                  EntityResolver entityResolver
> +                           ) throws Exception {
> +        fErrorReporter = errorReporter;
> +        fCurrentSchemaURL = schemaURL;
> +       fEntityResolver = entityResolver;
> +        doTraverseSchema(root, stringPool, schemaGrammar,
grammarResolver);
> +    }
> +
> +    public  TraverseSchema(Element root, StringPool stringPool,
> +                           SchemaGrammar schemaGrammar,
> +                           GrammarResolver grammarResolver,
> +                           XMLErrorReporter errorReporter,
>                             String schemaURL
>                             ) throws Exception {
>          fErrorReporter = errorReporter;
> @@ -772,8 +787,25 @@
>
>          file://TO DO: !!!!! location needs to be resolved first.
>
> -        String location =
includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
> -        location = expandSystemId(location, fCurrentSchemaURL);
> +
> +       String location =
includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
> +
> +         // expand it before passing it to the parser
> +         InputSource source = null;
> +         if (fEntityResolver != null) {
> +            source = fEntityResolver.resolveEntity("", location);
> +         }
> +         if (source == null) {
> +            location = expandSystemId(location, fCurrentSchemaURL);
> +            source = new InputSource(location);
> +         }
> +         else {
> +               // create a string for uniqueness of this included schema
in fIncludeLocations
> +               if (source.getPublicId () != null)
> +                       location = source.getPublicId ();
> +
> +               location += (',' + source.getSystemId ());
> +         }
>
>          if (fIncludeLocations.contains((Object)location)) {
>              return;
> @@ -798,7 +830,7 @@
>          }
>
>          try {
> -            parser.parse( location);
> +            parser.parse( source );
>          }catch( IOException e ) {
>              e.printStackTrace();
>          }catch( SAXException e ) {
> @@ -920,21 +952,36 @@
>      }
>
>      private void traverseImport(Element importDecl)  throws Exception {
> -        String location =
importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
> -        location = expandSystemId(location, fCurrentSchemaURL);
> -
> -
> -        String namespaceString =
importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
> -        SchemaGrammar importedGrammar = new SchemaGrammar();
> -        if (fGrammarResolver.getGrammar(namespaceString) != null) {
> -            importedGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(namespaceString);
> -        }
> +       String location =
importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
> +        // expand it before passing it to the parser
> +         InputSource source = null;
> +         if (fEntityResolver != null) {
> +            source = fEntityResolver.resolveEntity("", location);
> +         }
> +         if (source == null) {
> +            location = expandSystemId(location, fCurrentSchemaURL);
> +            source = new InputSource(location);
> +         }
> +         else {
> +               // create a string for uniqueness of this imported schema
in fImportLocations
> +               if (source.getPublicId () != null)
> +                       location = source.getPublicId ();
> +
> +               location += (',' + source.getSystemId ());
> +         }
>
> -        if (fImportLocations.contains((Object)location)) {
> +         if (fImportLocations.contains((Object)location)) {
>              return;
>          }
>          fImportLocations.addElement((Object)location);
>
> +       String namespaceString =
importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
> +       SchemaGrammar importedGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(namespaceString);
> +
> +       if (importedGrammar == null) {
> +               importedGrammar = new SchemaGrammar();
> +       }
> +
>          DOMParser parser = new DOMParser() {
>              public void ignorableWhitespace(char ch[], int start, int
length) {}
>              public void ignorableWhitespace(int dataIdx) {}
> @@ -953,7 +1000,7 @@
>          }
>
>          try {
> -            parser.parse( location);
> +            parser.parse( source );
>          }catch( IOException e ) {
>              e.printStackTrace();
>          }catch( SAXException e ) {
>
> --
> ___________________________________________________
> Jerry Lawson                   Virtual Summit, Inc.
> Virtual Programmer   jerry.lawson@virtualsummit.com
>
>
>


----------------------------------------------------------------------------
----


> /*
>  * The Apache Software License, Version 1.1
>  *
>  *
>  * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution,
>  *    if any, must include the following acknowledgment:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowledgment may appear in the software itself,
>  *    if and wherever such third-party acknowledgments normally appear.
>  *
>  * 4. The names "Xerces" and "Apache Software Foundation" must
>  *    not be used to endorse or promote products derived from this
>  *    software without prior written permission. For written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache",
>  *    nor may "Apache" appear in their name, without prior written
>  *    permission of the Apache Software Foundation.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation and was
>  * originally based on software copyright (c) 1999, International
>  * Business Machines, Inc., http://www.apache.org.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
>
> package org.apache.xerces.validators.common;
>
> import org.apache.xerces.framework.XMLAttrList;
> import org.apache.xerces.framework.XMLContentSpec;
> import org.apache.xerces.framework.XMLDocumentHandler;
> import org.apache.xerces.framework.XMLDocumentScanner;
> import org.apache.xerces.framework.XMLErrorReporter;
> import org.apache.xerces.readers.DefaultEntityHandler;
> import org.apache.xerces.readers.XMLEntityHandler;
> import org.apache.xerces.utils.ChunkyCharArray;
> import org.apache.xerces.utils.Hash2intTable;
> import org.apache.xerces.utils.NamespacesScope;
> 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.apache.xerces.utils.ImplementationMessages;
>
> import org.apache.xerces.parsers.DOMParser;
>
> import org.w3c.dom.Document;
> import org.w3c.dom.Element;
>
> import org.xml.sax.InputSource;
> import org.xml.sax.EntityResolver;
> import org.xml.sax.Locator;
> import org.xml.sax.helpers.LocatorImpl;
> import org.xml.sax.SAXException;
> import org.xml.sax.SAXParseException;
>
> import java.io.IOException;
>
> import java.util.Enumeration;
> import java.util.Hashtable;
> import java.util.StringTokenizer;
> import java.util.Vector;
>
> import org.apache.xerces.validators.dtd.DTDGrammar;
>
> import org.apache.xerces.validators.schema.EquivClassComparator;
> import org.apache.xerces.validators.schema.SchemaGrammar;
> import org.apache.xerces.validators.schema.SchemaMessageProvider;
> import org.apache.xerces.validators.schema.SchemaSymbols;
> import org.apache.xerces.validators.schema.TraverseSchema;
>
> import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
> import org.apache.xerces.validators.datatype.DatatypeValidator;
> import
org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
> import org.apache.xerces.validators.datatype.StateMessageDatatype;
> import org.apache.xerces.validators.datatype.IDREFDatatypeValidator;
> import org.apache.xerces.validators.datatype.IDDatatypeValidator;
> import org.apache.xerces.validators.datatype.ENTITYDatatypeValidator;
>
> /**
>  * This class is the super all-in-one validator used by the parser.
>  *
>  * @version $Id: XMLValidator.java,v 1.90 2000/10/31 17:40:36 jeffreyr Exp
$
>  */
> public final class XMLValidator
> implements DefaultEntityHandler.EventHandler,
> XMLEntityHandler.CharDataHandler,
> XMLDocumentScanner.EventHandler,
> NamespacesScope.NamespacesHandler {
>
>    //
>    // Constants
>    //
>
>    // debugging
>
>    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
>    private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
>    private static final boolean DEBUG_PRINT_CONTENT = false;
>    private static final boolean DEBUG_SCHEMA_VALIDATION = false;
>    private static final boolean DEBUG_ELEMENT_CHILDREN = false;
>
>    // Chunk size constants
>
>    private static final int CHUNK_SHIFT = 8;           // 2^8 = 256
>    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
>    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
>    private static final int INITIAL_CHUNK_COUNT = (1 << (10 -
CHUNK_SHIFT));   // 2^10 = 1k
>
>    private Hashtable fIdDefs = null;
>
>
>    private  StateMessageDatatype fStoreIDRef = new StateMessageDatatype()
{
>       private Hashtable fIdDefs;
>       public Object getDatatypeObject(){
>          return(Object) fIdDefs;
>       }
>       public int    getDatatypeState(){
>          return IDREFDatatypeValidator.IDREF_STORE;
>       }
>       public void setDatatypeObject( Object data ){
>          fIdDefs = (Hashtable) data;
>       }
>    };
>
>    private StateMessageDatatype fResetID = new StateMessageDatatype() {
>       public Object getDatatypeObject(){
>          return(Object) null;
>       }
>       public int    getDatatypeState(){
>          return IDDatatypeValidator.ID_CLEAR;
>       }
>       public void setDatatypeObject( Object data ){
>       }
>    };
>
>
>    private StateMessageDatatype fResetIDRef = new StateMessageDatatype() {
>       public Object getDatatypeObject(){
>          return(Object) null;
>       }
>       public int    getDatatypeState(){
>          return IDREFDatatypeValidator.IDREF_CLEAR;
>       }
>       public void setDatatypeObject( Object data ){
>       }
>    };
>
>    private  StateMessageDatatype fValidateIDRef = new
StateMessageDatatype() {
>       public Object getDatatypeObject(){
>          return(Object) null;
>       }
>       public int    getDatatypeState(){
>          return IDREFDatatypeValidator.IDREF_VALIDATE;
>       }
>       public void setDatatypeObject( Object data ){
>       }
>    };
>
>
>    private  StateMessageDatatype fValidateENTITYMsg = new
StateMessageDatatype() {
>       private  Object  packagedMessage = null;
>       public Object getDatatypeObject(){
>          return packagedMessage;
>       }
>       public int    getDatatypeState(){
>          return ENTITYDatatypeValidator.ENTITY_INITIALIZE;//No state
>       }
>       public void setDatatypeObject( Object data ){
>          packagedMessage = data;// Set Entity Handler
>       }
>    };
>
>    /*
>    private  StateMessageDatatype fValidateNOTATIONMsg = new
StateMessageDatatype() {
>        private  Object  packagedMessage = null;
>        public Object getDatatypeObject(){
>            return packagedMessage;
>        }
>        public int    getDatatypeState(){
>            return NOTATIONDatatypeValidator.ENTITY_INITIALIZE;//No state
>        }
>        public void setDatatypeObject( Object data ){
>            packagedMessage = data;// Set Entity Handler
>        }
>    };
>    */
>
>
>
>
>
>    //
>    // Data
>    //
>
>    // REVISIT: The data should be regrouped and re-organized so that
>    //          it's easier to find a meaningful field.
>
>    // debugging
>
> //    private static boolean DEBUG = false;
>
>    // other
>
>    // attribute validators
>
>    private AttributeValidator fAttValidatorNOTATION = new
AttValidatorNOTATION();
>    private AttributeValidator fAttValidatorENUMERATION = new
AttValidatorENUMERATION();
>    private AttributeValidator fAttValidatorDATATYPE = null;
>
>    // Package access for use by AttributeValidator classes.
>
>    StringPool fStringPool = null;
>    boolean fValidating = false;
>    boolean fInElementContent = false;
>    int fStandaloneReader = -1;
>
>
>    // settings
>
>    private boolean fValidationEnabled = false;
>    private boolean fDynamicValidation = false;
>    private boolean fSchemaValidation = true;
>    private boolean fValidationEnabledByDynamic = false;
>    private boolean fDynamicDisabledByValidation = false;
>    private boolean fWarningOnDuplicateAttDef = false;
>    private boolean fWarningOnUndeclaredElements = false;
>    private boolean fNormalizeAttributeValues = true;
>    private boolean fLoadDTDGrammar = true;
>
>    // declarations
>
>    private int fDeclaration[];
>    private XMLErrorReporter fErrorReporter = null;
>    private DefaultEntityHandler fEntityHandler = null;
>    private QName fCurrentElement = new QName();
>
>    private ContentLeafNameTypeVector[] fContentLeafStack = new
ContentLeafNameTypeVector[8];
>    private int[] fValidationFlagStack = new int[8];
>
>    private int[] fScopeStack = new int[8];
>    private int[] fGrammarNameSpaceIndexStack = new int[8];
>
>    private int[] fElementEntityStack = new int[8];
>    private int[] fElementIndexStack = new int[8];
>    private int[] fContentSpecTypeStack = new int[8];
>
>    private static final int sizeQNameParts      = 8;
>    private QName[] fElementQNamePartsStack      = new
QName[sizeQNameParts];
>
>    private QName[] fElementChildren = new QName[32];
>    private int fElementChildrenLength = 0;
>    private int[] fElementChildrenOffsetStack = new int[32];
>    private int fElementDepth = -1;
>
>    private boolean fNamespacesEnabled = false;
>    private NamespacesScope fNamespacesScope = null;
>    private int fNamespacesPrefix = -1;
>    private QName fRootElement = new QName();
>    private int fAttrListHandle = -1;
>    private int fCurrentElementEntity = -1;
>    private int fCurrentElementIndex = -1;
>    private int fCurrentContentSpecType = -1;
>    private boolean fSeenDoctypeDecl = false;
>
>    private final int TOP_LEVEL_SCOPE = -1;
>    private int fCurrentScope = TOP_LEVEL_SCOPE;
>    private int fCurrentSchemaURI = -1;
>    private int fEmptyURI = - 1;
>    private int fXsiPrefix = - 1;
>    private int fXsiURI = -2;
>    private int fXsiTypeAttValue = -1;
>    private DatatypeValidator fXsiTypeValidator = null;
>
>    private Grammar fGrammar = null;
>    private int fGrammarNameSpaceIndex = -1;
>    private GrammarResolver fGrammarResolver = null;
>
>    // state and stuff
>
>    private boolean fScanningDTD = false;
>    private XMLDocumentScanner fDocumentScanner = null;
>    private boolean fCalledStartDocument = false;
>    private XMLDocumentHandler fDocumentHandler = null;
>    private XMLDocumentHandler.DTDHandler fDTDHandler = null;
>    private boolean fSeenRootElement = false;
>    private XMLAttrList fAttrList = null;
>    private int fXMLLang = -1;
>    private LocatorImpl fAttrNameLocator = null;
>    private boolean fCheckedForSchema = false;
>    private boolean fDeclsAreExternal = false;
>    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
>    private char[] fCharRefData = null;
>    private boolean fSendCharDataAsCharArray = false;
>    private boolean fBufferDatatype = false;
>    private StringBuffer fDatatypeBuffer = new StringBuffer();
>
>    private QName fTempQName = new QName();
>    private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
>    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
>    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
>
>    private boolean fGrammarIsDTDGrammar = false;
>    private boolean fGrammarIsSchemaGrammar = false;
>
>    private boolean fNeedValidationOff = false;
>
>    // symbols
>
>    private int fEMPTYSymbol = -1;
>    private int fANYSymbol = -1;
>    private int fMIXEDSymbol = -1;
>    private int fCHILDRENSymbol = -1;
>    private int fCDATASymbol = -1;
>    private int fIDSymbol = -1;
>    private int fIDREFSymbol = -1;
>    private int fIDREFSSymbol = -1;
>    private int fENTITYSymbol = -1;
>    private int fENTITIESSymbol = -1;
>    private int fNMTOKENSymbol = -1;
>    private int fNMTOKENSSymbol = -1;
>    private int fNOTATIONSymbol = -1;
>    private int fENUMERATIONSymbol = -1;
>    private int fREQUIREDSymbol = -1;
>    private int fFIXEDSymbol = -1;
>    private int fDATATYPESymbol = -1;
>    private int fEpsilonIndex = -1;
>
>
>    file://Datatype Registry
>
>    private DatatypeValidatorFactoryImpl fDataTypeReg = null;
>    private DatatypeValidator            fValID   = null;
>    private DatatypeValidator            fValIDRef    = null;
>    private DatatypeValidator            fValIDRefs   = null;
>    private DatatypeValidator            fValENTITY   = null;
>    private DatatypeValidator            fValENTITIES = null;
>    private DatatypeValidator            fValNMTOKEN  = null;
>    private DatatypeValidator            fValNMTOKENS = null;
>    private DatatypeValidator            fValNOTATION = null;
>
>
>    //
>    // Constructors
>    //
>
>    /** Constructs an XML validator. */
>    public XMLValidator(StringPool stringPool,
>                        XMLErrorReporter errorReporter,
>                        DefaultEntityHandler entityHandler,
>                        XMLDocumentScanner documentScanner) {
>
>       // keep references
>       fStringPool = stringPool;
>       fErrorReporter = errorReporter;
>       fEntityHandler = entityHandler;
>       fDocumentScanner = documentScanner;
>
>       fEmptyURI = fStringPool.addSymbol("");
>       fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
>       // initialize
>       fAttrList = new XMLAttrList(fStringPool);
>       entityHandler.setEventHandler(this);
>       entityHandler.setCharDataHandler(this);
>       fDocumentScanner.setEventHandler(this);
>
>       for (int i = 0; i < sizeQNameParts; i++) {
>          fElementQNamePartsStack[i] = new QName();
>       }
>       init();
>
>    } //
<init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)
>
>    public void setGrammarResolver(GrammarResolver grammarResolver){
>       fGrammarResolver = grammarResolver;
>    }
>
>    //
>    // Public methods
>    //
>
>    // initialization
>
>    /** Set char data processing preference and handlers. */
>    public void initHandlers(boolean sendCharDataAsCharArray,
>                             XMLDocumentHandler docHandler,
>                             XMLDocumentHandler.DTDHandler dtdHandler) {
>
>       fSendCharDataAsCharArray = sendCharDataAsCharArray;
>       fEntityHandler.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
>       fDocumentHandler = docHandler;
>       fDTDHandler = dtdHandler;
>
>    } //
initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)
>
>    /** Reset or copy. */
>    public void resetOrCopy(StringPool stringPool) throws Exception {
>       fAttrList = new XMLAttrList(stringPool);
>       resetCommon(stringPool);
>    }
>
>    /** Reset. */
>    public void reset(StringPool stringPool) throws Exception {
>       fAttrList.reset(stringPool);
>       resetCommon(stringPool);
>    }
>
>
>    // settings
>
>    /**
>     * Turning on validation/dynamic turns on validation if it is off, and
>     * this is remembered.  Turning off validation DISABLES
validation/dynamic
>     * if it is on.  Turning off validation/dynamic DOES NOT turn off
>     * validation if it was explicitly turned on, only if it was turned on
>     * BECAUSE OF the call to turn validation/dynamic on.  Turning on
>     * validation will REENABLE and turn validation/dynamic back on if it
>     * was disabled by a call that turned off validation while
>     * validation/dynamic was enabled.
>     */
>    public void setValidationEnabled(boolean flag) throws Exception {
>       fValidationEnabled = flag;
>       fValidationEnabledByDynamic = false;
>       if (fValidationEnabled) {
>          if (fDynamicDisabledByValidation) {
>             fDynamicValidation = true;
>             fDynamicDisabledByValidation = false;
>          }
>       } else if (fDynamicValidation) {
>          fDynamicValidation = false;
>          fDynamicDisabledByValidation = true;
>       }
>       fValidating = fValidationEnabled;
>    }
>
>    /** Returns true if validation is enabled. */
>    public boolean getValidationEnabled() {
>       return fValidationEnabled;
>    }
>
>    /** Sets whether Schema support is on/off. */
>    public void setSchemaValidationEnabled(boolean flag) {
>       fSchemaValidation = flag;
>    }
>
>    /** Returns true if Schema support is on. */
>    public boolean getSchemaValidationEnabled() {
>       return fSchemaValidation;
>    }
>
>    /** Sets whether validation is dynamic. */
>    public void setDynamicValidationEnabled(boolean flag) throws Exception
{
>       fDynamicValidation = flag;
>       fDynamicDisabledByValidation = false;
>       if (!fDynamicValidation) {
>          if (fValidationEnabledByDynamic) {
>             fValidationEnabled = false;
>             fValidationEnabledByDynamic = false;
>          }
>       } else if (!fValidationEnabled) {
>          fValidationEnabled = true;
>          fValidationEnabledByDynamic = true;
>       }
>       fValidating = fValidationEnabled;
>    }
>
>    /** Returns true if validation is dynamic. */
>    public boolean getDynamicValidationEnabled() {
>       return fDynamicValidation;
>    }
>
>    /** Sets fNormalizeAttributeValues **/
>    public void setNormalizeAttributeValues(boolean normalize){
>       fNormalizeAttributeValues = normalize;
>    }
>
>    /** Sets fLoadDTDGrammar when validation is off **/
>    public void setLoadDTDGrammar(boolean loadDG){
>       if (fValidating) {
>          fLoadDTDGrammar = true;
>       } else {
>          fLoadDTDGrammar = loadDG;
>       }
>    }
>
>    /** Returns fLoadDTDGrammar **/
>    public boolean getLoadDTDGrammar() {
>       return fLoadDTDGrammar;
>    }
>
>    /** Sets whether namespaces are enabled. */
>    public void setNamespacesEnabled(boolean flag) {
>       fNamespacesEnabled = flag;
>    }
>
>    /** Returns true if namespaces are enabled. */
>    public boolean getNamespacesEnabled() {
>       return fNamespacesEnabled;
>    }
>
>    /** Sets whether duplicate attribute definitions signal a warning. */
>    public void setWarningOnDuplicateAttDef(boolean flag) {
>       fWarningOnDuplicateAttDef = flag;
>    }
>
>    /** Returns true if duplicate attribute definitions signal a warning.
*/
>    public boolean getWarningOnDuplicateAttDef() {
>       return fWarningOnDuplicateAttDef;
>    }
>
>    /** Sets whether undeclared elements signal a warning. */
>    public void setWarningOnUndeclaredElements(boolean flag) {
>       fWarningOnUndeclaredElements = flag;
>    }
>
>    /** Returns true if undeclared elements signal a warning. */
>    public boolean getWarningOnUndeclaredElements() {
>       return fWarningOnUndeclaredElements;
>    }
>
>    //
>    // DefaultEntityHandler.EventHandler methods
>    //
>
>    /** Start entity reference. */
>    public void startEntityReference(int entityName, int entityType, int
entityContext) throws Exception {
>       fDocumentHandler.startEntityReference(entityName, entityType,
entityContext);
>    }
>
>    /** End entity reference. */
>    public void endEntityReference(int entityName, int entityType, int
entityContext) throws Exception {
>       fDocumentHandler.endEntityReference(entityName, entityType,
entityContext);
>    }
>
>    /** Send end of input notification. */
>    public void sendEndOfInputNotifications(int entityName, boolean
moreToFollow) throws Exception {
>       fDocumentScanner.endOfInput(entityName, moreToFollow);
>       /***
>       if (fScanningDTD) {
>           fDTDImporter.sendEndOfInputNotifications(entityName,
moreToFollow);
>       }
>       /***/
>    }
>
>    /** Send reader change notifications. */
>    public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader
reader, int readerId) throws Exception {
>       fDocumentScanner.readerChange(reader, readerId);
>       /***
>       if (fScanningDTD) {
>           fDTDImporter.sendReaderChangeNotifications(reader, readerId);
>       }
>       /***/
>    }
>
>    /** External entity standalone check. */
>    public boolean externalEntityStandaloneCheck() {
>       return(fStandaloneReader != -1 && fValidating);
>    }
>
>    /** Return true if validating. */
>    public boolean getValidating() {
>       return fValidating;
>    }
>
>    //
>    // XMLEntityHandler.CharDataHandler methods
>    //
>
>    /** Process characters. */
>    public void processCharacters(char[] chars, int offset, int length)
throws Exception {
>       if (fValidating) {
>          if (fInElementContent || fCurrentContentSpecType ==
XMLElementDecl.TYPE_EMPTY) {
>             charDataInContent();
>          }
>          if (fBufferDatatype) {
>             fDatatypeBuffer.append(chars, offset, length);
>          }
>       }
>       fDocumentHandler.characters(chars, offset, length);
>    }
>
>    /** Process characters. */
>    public void processCharacters(int data) throws Exception {
>       if (fValidating) {
>          if (fInElementContent || fCurrentContentSpecType ==
XMLElementDecl.TYPE_EMPTY) {
>             charDataInContent();
>          }
>          if (fBufferDatatype) {
>             fDatatypeBuffer.append(fStringPool.toString(data));
>          }
>       }
>       fDocumentHandler.characters(data);
>    }
>
>    /** Process whitespace. */
>    public void processWhitespace(char[] chars, int offset, int length)
>    throws Exception {
>
>       if (fInElementContent) {
>          if (fStandaloneReader != -1 && fValidating &&
getElementDeclIsExternal(fCurrentElementIndex)) {
>
reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHE
N_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
>          }
>          fDocumentHandler.ignorableWhitespace(chars, offset, length);
>       } else {
>          if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
>             charDataInContent();
>          }
>          fDocumentHandler.characters(chars, offset, length);
>       }
>
>    } // processWhitespace(char[],int,int)
>
>    /** Process whitespace. */
>    public void processWhitespace(int data) throws Exception {
>
>       if (fInElementContent) {
>          if (fStandaloneReader != -1 && fValidating &&
getElementDeclIsExternal(fCurrentElementIndex)) {
>
reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHE
N_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
>          }
>          fDocumentHandler.ignorableWhitespace(data);
>       } else {
>          if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
>             charDataInContent();
>          }
>          fDocumentHandler.characters(data);
>       }
>
>    } // processWhitespace(int)
>
>    //
>    // XMLDocumentScanner.EventHandler methods
>    //
>
>    /** Scans element type. */
>    public 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. */
>    public boolean scanExpectedElementType(XMLEntityHandler.EntityReader
entityReader,
>                                           char fastchar, QName element)
>    throws Exception {
>
>       if (fCurrentElementCharArrayRange == null) {
>          fCurrentElementCharArrayRange =
fStringPool.createCharArrayRange();
>       }
>       fStringPool.getCharArrayRange(fCurrentElement.rawname,
fCurrentElementCharArrayRange);
>       return entityReader.scanExpectedName(fastchar,
fCurrentElementCharArrayRange);
>
>    } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
>
>    /** Scans attribute name. */
>    public void scanAttributeName(XMLEntityHandler.EntityReader
entityReader,
>                                  QName element, QName attribute)
>    throws Exception {
>
>       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)
>
>    /** Call start document. */
>    public void callStartDocument() throws Exception {
>
>       if (!fCalledStartDocument) {
>          fDocumentHandler.startDocument();
>          fCalledStartDocument = true;
>       }
>    }
>
>    /** Call end document. */
>    public void callEndDocument() throws Exception {
>
>       if (fCalledStartDocument) {
>          fDocumentHandler.endDocument();
>       }
>    }
>
>    /** Call XML declaration. */
>    public void callXMLDecl(int version, int encoding, int standalone)
throws Exception {
>       fDocumentHandler.xmlDecl(version, encoding, standalone);
>    }
>    public void callStandaloneIsYes() throws Exception {
>       // standalone = "yes". said XMLDocumentScanner.
>       fStandaloneReader = fEntityHandler.getReaderId() ;
>
>    }
>
>
>
>    /** Call text declaration. */
>    public void callTextDecl(int version, int encoding) throws Exception {
>       fDocumentHandler.textDecl(version, encoding);
>    }
>
>    /**
>     * Signal the scanning of an element name in a start element tag.
>     *
>     * @param element Element name scanned.
>     */
>    public void element(QName element) throws Exception {
>       fAttrListHandle = -1;
>    }
>    /**
>     * Signal the scanning of an attribute associated to the previous
>     * start element tag.
>     *
>     * @param element Element name scanned.
>     * @param attrName Attribute name scanned.
>     * @param attrValue The string pool index of the attribute value.
>     */
>    public boolean attribute(QName element, QName attrName, int attrValue)
throws Exception {
>       if (fAttrListHandle == -1) {
>          fAttrListHandle = fAttrList.startAttrList();
>       }
>
>       // if fAttrList.addAttr returns -1, indicates duplicate att in start
tag of an element.
>       // specified: true, search : true
>       return fAttrList.addAttr(attrName, attrValue, fCDATASymbol, true,
true) == -1;
>    }
>
>    /** Call start element. */
>    public void callStartElement(QName element) throws Exception {
>
>       if ( DEBUG_SCHEMA_VALIDATION )
>          System.out.println("\n=======StartElement : " +
fStringPool.toString(element.localpart));
>
>
>       //
>       // Check after all specified attrs are scanned
>       // (1) report error for REQUIRED attrs that are missing (V_TAGc)
>       // (2) add default attrs (FIXED and NOT_FIXED)
>       //
>
>       if (!fSeenRootElement) {
>          fSeenRootElement = true;
>          rootElementSpecified(element);
>          fStringPool.resetShuffleCount();
>       }
>
>       if (fGrammar != null && fGrammarIsDTDGrammar) {
>          fAttrListHandle = addDTDDefaultAttributes(element, fAttrList,
fAttrListHandle, fValidating, fStandaloneReader != -1);
>       }
>
>       fCheckedForSchema = true;
>       if (fNamespacesEnabled) {
>          bindNamespacesToElementAndAttributes(element, fAttrList);
>       }
>
>       validateElementAndAttributes(element, fAttrList);
>       if (fAttrListHandle != -1) {
>          fAttrList.endAttrList();
>       }
>
>       fDocumentHandler.startElement(element, fAttrList, fAttrListHandle);
>       fAttrListHandle = -1;
>
>       file://before we increment the element depth, add this element's
QName to its enclosing element 's children list
>       fElementDepth++;
>       file://if (fElementDepth >= 0) {
>       if (fValidating) {
>          // push current length onto stack
>          if (fElementChildrenOffsetStack.length <= fElementDepth) {
>             int newarray[] = new int[fElementChildrenOffsetStack.length *
2];
>             System.arraycopy(fElementChildrenOffsetStack, 0, newarray, 0,
fElementChildrenOffsetStack.length);
>             fElementChildrenOffsetStack = newarray;
>          }
>          fElementChildrenOffsetStack[fElementDepth] =
fElementChildrenLength;
>
>          // add this element to children
>          if (fElementChildren.length <= fElementChildrenLength) {
>             QName[] newarray = new QName[fElementChildrenLength * 2];
>             System.arraycopy(fElementChildren, 0, newarray, 0,
fElementChildren.length);
>             fElementChildren = newarray;
>          }
>          QName qname = fElementChildren[fElementChildrenLength];
>          if (qname == null) {
>             for (int i = fElementChildrenLength; i <
fElementChildren.length; i++) {
>                fElementChildren[i] = new QName();
>             }
>             qname = fElementChildren[fElementChildrenLength];
>          }
>          qname.setValues(element);
>          fElementChildrenLength++;
>
>          if (DEBUG_ELEMENT_CHILDREN) {
>             printChildren();
>             printStack();
>          }
>       }
>
>       // One more level of depth
>       file://fElementDepth++;
>
>       ensureStackCapacity(fElementDepth);
>       fCurrentElement.setValues(element);
>       fCurrentElementEntity = fEntityHandler.getReaderId();
>
>       fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement);
>
>       fElementEntityStack[fElementDepth] = fCurrentElementEntity;
>       fElementIndexStack[fElementDepth] = fCurrentElementIndex;
>       fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
>
>       if (fNeedValidationOff) {
>          fValidating = false;
>          fNeedValidationOff = false;
>       }
>
>       if (fValidating && fGrammarIsSchemaGrammar) {
>          pushContentLeafStack();
>       }
>
>       fValidationFlagStack[fElementDepth] = fValidating ? 0 : -1;
>
>       fScopeStack[fElementDepth] = fCurrentScope;
>       fGrammarNameSpaceIndexStack[fElementDepth] = fGrammarNameSpaceIndex;
>
>    } // callStartElement(QName)
>
>    private void pushContentLeafStack() throws Exception {
>       int contentType = getContentSpecType(fCurrentElementIndex);
>       if ( contentType == XMLElementDecl.TYPE_CHILDREN) {
>          XMLContentModel cm =
getElementContentModel(fCurrentElementIndex);
>          ContentLeafNameTypeVector cv = cm.getContentLeafNameTypeVector();
>          if (cm != null) {
>             fContentLeafStack[fElementDepth] = cv;
>          }
>       }
>    }
>
>    private void ensureStackCapacity ( int newElementDepth) {
>
>       if (newElementDepth == fElementQNamePartsStack.length ) {
>          int[] newStack = new int[newElementDepth * 2];
>          System.arraycopy(fScopeStack, 0, newStack, 0, newElementDepth);
>          fScopeStack = newStack;
>
>          newStack = new int[newElementDepth * 2];
>          System.arraycopy(fGrammarNameSpaceIndexStack, 0, newStack, 0,
newElementDepth);
>          fGrammarNameSpaceIndexStack = newStack;
>
>          QName[] newStackOfQueue = new QName[newElementDepth * 2];
>          System.arraycopy(this.fElementQNamePartsStack, 0,
newStackOfQueue, 0, newElementDepth );
>          fElementQNamePartsStack      = newStackOfQueue;
>
>          QName qname = fElementQNamePartsStack[newElementDepth];
>          if (qname == null) {
>             for (int i = newElementDepth; i <
fElementQNamePartsStack.length; i++) {
>                fElementQNamePartsStack[i] = new QName();
>             }
>          }
>
>          newStack = new int[newElementDepth * 2];
>          System.arraycopy(fElementEntityStack, 0, newStack, 0,
newElementDepth);
>          fElementEntityStack = newStack;
>
>          newStack = new int[newElementDepth * 2];
>          System.arraycopy(fElementIndexStack, 0, newStack, 0,
newElementDepth);
>          fElementIndexStack = newStack;
>
>          newStack = new int[newElementDepth * 2];
>          System.arraycopy(fContentSpecTypeStack, 0, newStack, 0,
newElementDepth);
>          fContentSpecTypeStack = newStack;
>
>          newStack = new int[newElementDepth * 2];
>          System.arraycopy(fValidationFlagStack, 0, newStack, 0,
newElementDepth);
>          fValidationFlagStack = newStack;
>
>          ContentLeafNameTypeVector[] newStackV = new
ContentLeafNameTypeVector[newElementDepth * 2];
>          System.arraycopy(fContentLeafStack, 0, newStackV, 0,
newElementDepth);
>          fContentLeafStack = newStackV;
>       }
>    }
>
>    /** Call end element. */
>    public void callEndElement(int readerId) throws Exception {
>       if ( DEBUG_SCHEMA_VALIDATION )
>          System.out.println("=======EndElement : " +
fStringPool.toString(fCurrentElement.localpart)+"\n");
>
>       int prefixIndex = fCurrentElement.prefix;
>       int elementType = fCurrentElement.rawname;
>
>       if (fCurrentElementEntity != readerId) {
>          fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                     XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_ELEMENT_ENTITY_MISMATCH,
>                                     XMLMessages.P78_NOT_WELLFORMED,
>                                     new Object[]
 fStringPool.toString(elementType)},
>
XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
>       }
>
>       fElementDepth--;
>       if (fValidating) {
>          int elementIndex = fCurrentElementIndex;
>          if (elementIndex != -1 && fCurrentContentSpecType != -1) {
>             QName children[] = fElementChildren;
>             int childrenOffset = fElementChildrenOffsetStack[fElementDepth
+ 1] + 1;
>             int childrenLength = fElementChildrenLength - childrenOffset;
>             if (DEBUG_ELEMENT_CHILDREN) {
>
System.out.println("endElement("+fStringPool.toString(fCurrentElement.rawnam
e)+')');
>                System.out.println("fCurrentContentSpecType : " +
fCurrentContentSpecType );
>                System.out.print("offset: ");
>                System.out.print(childrenOffset);
>                System.out.print(", length: ");
>                System.out.print(childrenLength);
>                System.out.println();
>                printChildren();
>                printStack();
>             }
>             int result = checkContent(elementIndex,
>                                       children, childrenOffset,
childrenLength);
>
>             if ( DEBUG_SCHEMA_VALIDATION )
>                System.out.println("!!!!!!!!In XMLValidator, the return
value from checkContent : " + result);
>
>             if (result != -1) {
>                int majorCode = result != childrenLength ?
XMLMessages.MSG_CONTENT_INVALID : XMLMessages.MSG_CONTENT_INCOMPLETE;
>                fGrammar.getElementDecl(elementIndex, fTempElementDecl);
>                if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
>                   reportRecoverableXMLError(majorCode,
>                                             0,
>
fStringPool.toString(elementType),
>                                             "EMPTY");
>                } else
>                   reportRecoverableXMLError(majorCode,
>                                             0,
>
fStringPool.toString(elementType),
>
XMLContentSpec.toString(fGrammar, fStringPool,
fTempElementDecl.contentSpecIndex));
>             }
>          }
>          fElementChildrenLength =
fElementChildrenOffsetStack[fElementDepth + 1] + 1;
>       }
>       fDocumentHandler.endElement(fCurrentElement);
>       if (fNamespacesEnabled) {
>          fNamespacesScope.decreaseDepth();
>       }
>
>       // now pop this element off the top of the element stack
>       file://if (fElementDepth-- < 0) {
>       if (fElementDepth < -1) {
>          throw new RuntimeException("FWK008 Element stack underflow");
>       }
>       if (fElementDepth < 0) {
>          fCurrentElement.clear();
>          fCurrentElementEntity = -1;
>          fCurrentElementIndex = -1;
>          fCurrentContentSpecType = -1;
>          fInElementContent = false;
>          //
>          // Check after document is fully parsed
>          // (1) check that there was an element with a matching id for
every
>          //   IDREF and IDREFS attr (V_IDREF0)
>          //
>          if (fValidating ) {
>             try {
>                this.fValIDRef.validate( null, this.fValidateIDRef );
>                this.fValIDRefs.validate( null, this.fValidateIDRef );
>             } catch ( InvalidDatatypeValueException ex ) {
>                reportRecoverableXMLError( ex.getMajorCode(),
ex.getMinorCode(),
>                                           ex.getMessage() );
>
>
>             }
>          }
>
>          try {//Reset datatypes state
>             this.fValID.validate( null, this.fResetID );
>             this.fValIDRef.validate(null, this.fResetIDRef );
>             this.fValIDRefs.validate(null, this.fResetID );
>          } catch ( InvalidDatatypeValueException ex ) {
>             System.err.println("Error re-Initializing: ID,IDRef,IDRefs
pools" );
>          }
>          return;
>       }
>
>
>       file://restore enclosing element to all the "current" variables
>       // REVISIT: Validation. This information needs to be stored.
>       fCurrentElement.prefix = -1;
>
>
>       if (fNamespacesEnabled) { file://If Namespace enable then localName
!= rawName
>          fCurrentElement.localpart =
fElementQNamePartsStack[fElementDepth].localpart;
>       } else {//REVISIT - jeffreyr - This is so we still do old behavior
when namespace is off
>          fCurrentElement.localpart =
fElementQNamePartsStack[fElementDepth].rawname;
>       }
>       fCurrentElement.rawname      =
fElementQNamePartsStack[fElementDepth].rawname;
>       fCurrentElement.uri          =
fElementQNamePartsStack[fElementDepth].uri;
>       fCurrentElement.prefix       =
fElementQNamePartsStack[fElementDepth].prefix;
>
>
>       fCurrentElementEntity = fElementEntityStack[fElementDepth];
>       fCurrentElementIndex = fElementIndexStack[fElementDepth];
>       fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
>
>       fValidating = fValidationFlagStack[fElementDepth] == 0 ? true :
false;
>
>       fCurrentScope = fScopeStack[fElementDepth];
>
>       file://if ( DEBUG_SCHEMA_VALIDATION ) {
>
> /****
> System.out.println("+++++ currentElement : " +
fStringPool.toString(elementType)+
>                    "\n fCurrentElementIndex : " + fCurrentElementIndex +
>                    "\n fCurrentScope : " + fCurrentScope +
>                    "\n fCurrentContentSpecType : " +
fCurrentContentSpecType +
>                    "\n++++++++++++++++++++++++++++++++++++++++++++++++" );
> /****/
>       file://}
>
>       // if enclosing element's Schema is different, need to switch
"context"
>       if ( fGrammarNameSpaceIndex !=
fGrammarNameSpaceIndexStack[fElementDepth] ) {
>          fGrammarNameSpaceIndex =
fGrammarNameSpaceIndexStack[fElementDepth];
>          if ( fValidating && fGrammarIsSchemaGrammar )
>             if ( !switchGrammar(fGrammarNameSpaceIndex) ) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
XMLMessages.SCHEMA_GENERIC_ERROR,
>                                          "Grammar with uri 1: " +
fStringPool.toString(fGrammarNameSpaceIndex)
>                                          + " , can not found");
>             }
>       }
>
>       if (fValidating) {
>          fBufferDatatype = false;
>       }
>       fInElementContent = (fCurrentContentSpecType ==
XMLElementDecl.TYPE_CHILDREN);
>
>    } // callEndElement(int)
>
>    /** Call start CDATA section. */
>    public void callStartCDATA() throws Exception {
>       fDocumentHandler.startCDATA();
>    }
>
>    /** Call end CDATA section. */
>    public void callEndCDATA() throws Exception {
>       fDocumentHandler.endCDATA();
>    }
>
>    /** Call characters. */
>    public void callCharacters(int ch) throws Exception {
>
>       if (fCharRefData == null) {
>          fCharRefData = new char[2];
>       }
>       int count = (ch < 0x10000) ? 1 : 2;
>       if (count == 1) {
>          fCharRefData[0] = (char)ch;
>       } else {
>          fCharRefData[0] = (char)(((ch-0x00010000)>>10)+0xd800);
>          fCharRefData[1] = (char)(((ch-0x00010000)&0x3ff)+0xdc00);
>       }
>       if (fValidating && (fInElementContent || fCurrentContentSpecType ==
XMLElementDecl.TYPE_EMPTY)) {
>          charDataInContent();
>       }
>       if (fValidating) {
>          if (fBufferDatatype) {
>             fDatatypeBuffer.append(fCharRefData,0,1);
>          }
>       }
>       if (fSendCharDataAsCharArray) {
>          fDocumentHandler.characters(fCharRefData, 0, count);
>       } else {
>          int index = fStringPool.addString(new String(fCharRefData, 0,
count));
>          fDocumentHandler.characters(index);
>       }
>
>    } // callCharacters(int)
>
>    /** Call processing instruction. */
>    public void callProcessingInstruction(int target, int data) throws
Exception {
>       fDocumentHandler.processingInstruction(target, data);
>    }
>
>    /** Call comment. */
>    public void callComment(int comment) throws Exception {
>       fDocumentHandler.comment(comment);
>    }
>
>    //
>    // NamespacesScope.NamespacesHandler methods
>    //
>
>    /** Start a new namespace declaration scope. */
>    public void startNamespaceDeclScope(int prefix, int uri) throws
Exception {
>       fDocumentHandler.startNamespaceDeclScope(prefix, uri);
>    }
>
>    /** End a namespace declaration scope. */
>    public void endNamespaceDeclScope(int prefix) throws Exception {
>       fDocumentHandler.endNamespaceDeclScope(prefix);
>    }
>
>    // attributes
>
>
>    // other
>
>    /** Sets the root element. */
>    public void setRootElementType(QName rootElement) {
>       fRootElement.setValues(rootElement);
>    }
>
>    /**
>     * Returns true if the element declaration is external.
>     * <p>
>     * <strong>Note:</strong> This method is primarilly useful for
>     * DTDs with internal and external subsets.
>     */
>    private boolean getElementDeclIsExternal(int elementIndex) {
>       /*if (elementIndex < 0 || elementIndex >= fElementCount) {
>           return false;
>       }
>       int chunk = elementIndex >> CHUNK_SHIFT;
>       int index = elementIndex & CHUNK_MASK;
>       return (fElementDeclIsExternal[chunk][index] != 0);
>       */
>
>       if (fGrammarIsDTDGrammar ) {
>          return((DTDGrammar)
fGrammar).getElementDeclIsExternal(elementIndex);
>       }
>       return false;
>    }
>
>    /** Returns the content spec type for an element index. */
>    public int getContentSpecType(int elementIndex) {
>
>       int contentSpecType = -1;
>       if ( elementIndex > -1) {
>          if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
>             contentSpecType = fTempElementDecl.type;
>          }
>       }
>       return contentSpecType;
>    }
>
>    /** Returns the content spec handle for an element index. */
>    public int getContentSpecHandle(int elementIndex) {
>       int contentSpecHandle = -1;
>       if ( elementIndex > -1) {
>          if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
>             contentSpecHandle = fTempElementDecl.contentSpecIndex;
>          }
>       }
>       return contentSpecHandle;
>    }
>
>    //
>    // Protected methods
>    //
>
>    // error reporting
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode)
>    throws Exception {
>
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  null,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int)
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode,
>                                             int stringIndex1)
>    throws Exception {
>
>       Object[] args = { fStringPool.toString(stringIndex1)};
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int,int)
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode,
>                                             String string1) throws
Exception {
>
>       Object[] args = { string1};
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int,String)
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode,
>                                             int stringIndex1, int
stringIndex2)
>    throws Exception {
>
>       Object[] args = { fStringPool.toString(stringIndex1),
fStringPool.toString(stringIndex2)};
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int,int,int)
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode,
>                                             String string1, String
string2)
>    throws Exception {
>
>       Object[] args = { string1, string2};
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int,String,String)
>
>    /** Report a recoverable xml error. */
>    protected void reportRecoverableXMLError(int majorCode, int minorCode,
>                                             String string1, String
string2,
>                                             String string3) throws
Exception {
>
>       Object[] args = { string1, string2, string3};
>       fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                  XMLMessages.XML_DOMAIN,
>                                  majorCode,
>                                  minorCode,
>                                  args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>    } // reportRecoverableXMLError(int,int,String,String,String)
>
>    // content spec
>
>    /**
>     * Returns information about which elements can be placed at a
particular point
>     * in the passed element's content model.
>     * <p>
>     * Note that the incoming content model to test must be valid at least
up to
>     * the insertion point. If not, then -1 will be returned and the info
object
>     * will not have been filled in.
>     * <p>
>     * If, on return, the info.isValidEOC flag is set, then the 'insert
after'
>     * elemement is a valid end of content, i.e. nothing needs to be
inserted
>     * after it to make the parent element's content model valid.
>     *
>     * @param elementIndex The index within the
<code>ElementDeclPool</code> of the
>     *                     element which is being querying.
>     * @param fullyValid Only return elements that can be inserted and
still
>     *                   maintain the validity of subsequent elements past
the
>     *                   insertion point (if any).  If the insertion point
is at
>     *                   the end, and this is true, then only elements that
can
>     *                   be legal final states will be returned.
>     * @param info An object that contains the required input data for the
method,
>     *             and which will contain the output information if
successful.
>     *
>     * @return The value -1 if fully valid, else the 0 based index of the
child
>     *         that first failed before the insertion point. If the value
>     *         returned is equal to the number of children, then the
specified
>     *         children are valid but additional content is required to
reach a
>     *         valid ending state.
>     *
>     * @exception Exception Thrown on error.
>     *
>     * @see InsertableElementsInfo
>     */
>    protected int whatCanGoHere(int elementIndex, boolean fullyValid,
>                                InsertableElementsInfo info) throws
Exception {
>
>       //
>       //  Do some basic sanity checking on the info packet. First, make
sure
>       //  that insertAt is not greater than the child count. It can be
equal,
>       //  which means to get appendable elements, but not greater. Or, if
>       //  the current children array is null, that's bad too.
>       //
>       //  Since the current children array must have a blank spot for
where
>       //  the insert is going to be, the child count must always be at
least
>       //  one.
>       //
>       //  Make sure that the child count is not larger than the current
children
>       //  array. It can be equal, which means get appendable elements, but
not
>       //  greater.
>       //
>       if (info.insertAt > info.childCount || info.curChildren == null ||
>           info.childCount < 1 || info.childCount >
info.curChildren.length) {
>          fErrorReporter.reportError(fErrorReporter.getLocator(),
>
ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
>                                     ImplementationMessages.VAL_WCGHI,
>                                     0,
>                                     null,
>
XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
>       }
>
>       int retVal = 0;
>       try {
>          // Get the content model for this element
>          final XMLContentModel cmElem =
getElementContentModel(elementIndex);
>
>          // And delegate this call to it
>          retVal = cmElem.whatCanGoHere(fullyValid, info);
>       } catch (CMException excToCatch) {
>          // REVISIT - Translate caught error to the protected error
handler interface
>          int majorCode = excToCatch.getErrorCode();
>          fErrorReporter.reportError(fErrorReporter.getLocator(),
>
ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
>                                     majorCode,
>                                     0,
>                                     null,
>
XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
>          throw excToCatch;
>       }
>       return retVal;
>
>    } // whatCanGoHere(int,boolean,InsertableElementsInfo):int
>
>    // attribute information
>
>    /** Protected for use by AttributeValidator classes. */
>    protected boolean getAttDefIsExternal(QName element, QName attribute) {
>       int attDefIndex = getAttDef(element, attribute);
>       if (fGrammarIsDTDGrammar ) {
>          return((DTDGrammar)
fGrammar).getAttributeDeclIsExternal(attDefIndex);
>       }
>       return false;
>    }
>
>
>
>    //
>    // Private methods
>    //
>
>    // other
>
>    /** Returns true if using a standalone reader. */
>    private boolean usingStandaloneReader() {
>       return fStandaloneReader == -1 || fEntityHandler.getReaderId() ==
fStandaloneReader;
>    }
>
>    /** Returns a locator implementation. */
>    private LocatorImpl getLocatorImpl(LocatorImpl fillin) {
>
>       Locator here = fErrorReporter.getLocator();
>       if (fillin == null)
>          return new LocatorImpl(here);
>       fillin.setPublicId(here.getPublicId());
>       fillin.setSystemId(here.getSystemId());
>       fillin.setLineNumber(here.getLineNumber());
>       fillin.setColumnNumber(here.getColumnNumber());
>       return fillin;
>
>    } // getLocatorImpl(LocatorImpl):LocatorImpl
>
>
>    // initialization
>
>    /** Reset pool. */
>    private void poolReset() {
>       try {
>          file://System.out.println("We reset" );
>          this.fValID.validate( null, this.fResetID );
>          this.fValIDRef.validate(null, this.fResetIDRef );
>          this.fValIDRefs.validate(null, this.fResetIDRef );
>       } catch ( InvalidDatatypeValueException ex ) {
>          System.err.println("Error re-Initializing: ID,IDRef,IDRefs
pools" );
>       }
>    } // poolReset()
>
>    /** Reset common. */
>    private void resetCommon(StringPool stringPool) throws Exception {
>
>       fStringPool = stringPool;
>       fValidating = fValidationEnabled;
>       fValidationEnabledByDynamic = false;
>       fDynamicDisabledByValidation = false;
>       poolReset();
>       fCalledStartDocument = false;
>       fStandaloneReader = -1;
>       fElementChildrenLength = 0;
>       fElementDepth = -1;
>       fSeenRootElement = false;
>       fSeenDoctypeDecl = false;
>       fNamespacesScope = null;
>       fNamespacesPrefix = -1;
>       fRootElement.clear();
>       fAttrListHandle = -1;
>       fCheckedForSchema = false;
>
>       fCurrentScope = TOP_LEVEL_SCOPE;
>       fCurrentSchemaURI = -1;
>       fEmptyURI = - 1;
>       fXsiPrefix = - 1;
>       fXsiTypeValidator = null;
>
>       fGrammar = null;
>       fGrammarNameSpaceIndex = -1;
>       file://fGrammarResolver = null;
>       if (fGrammarResolver != null) {
>          fGrammarResolver.clearGrammarResolver();
>       }
>       fGrammarIsDTDGrammar = false;
>       fGrammarIsSchemaGrammar = false;
>
>
>       init();
>
>    } // resetCommon(StringPool)
>
>    /** Initialize. */
>    private void init() {
>
>       fEmptyURI = fStringPool.addSymbol("");
>       fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
>
>
>       fEMPTYSymbol = fStringPool.addSymbol("EMPTY");
>       fANYSymbol = fStringPool.addSymbol("ANY");
>       fMIXEDSymbol = fStringPool.addSymbol("MIXED");
>       fCHILDRENSymbol = fStringPool.addSymbol("CHILDREN");
>
>       fCDATASymbol = fStringPool.addSymbol("CDATA");
>       fIDSymbol = fStringPool.addSymbol("ID");
>       fIDREFSymbol = fStringPool.addSymbol("IDREF");
>       fIDREFSSymbol = fStringPool.addSymbol("IDREFS");
>       fENTITYSymbol = fStringPool.addSymbol("ENTITY");
>       fENTITIESSymbol = fStringPool.addSymbol("ENTITIES");
>       fNMTOKENSymbol = fStringPool.addSymbol("NMTOKEN");
>       fNMTOKENSSymbol = fStringPool.addSymbol("NMTOKENS");
>       fNOTATIONSymbol = fStringPool.addSymbol("NOTATION");
>       fENUMERATIONSymbol = fStringPool.addSymbol("ENUMERATION");
>       fREQUIREDSymbol = fStringPool.addSymbol("#REQUIRED");
>       fFIXEDSymbol = fStringPool.addSymbol("#FIXED");
>       fDATATYPESymbol = fStringPool.addSymbol("<<datatype>>");
>       fEpsilonIndex = fStringPool.addSymbol("<<CMNODE_EPSILON>>");
>       fXMLLang = fStringPool.addSymbol("xml:lang");
>
>       try {
>          file://Initialize Validators
>          file://Datatype Registry
>
>          fDataTypeReg =
>          DatatypeValidatorFactoryImpl.getDatatypeRegistry();
>          fDataTypeReg.resetRegistry();
>          file://fDatatypeReg.resetRegistry();
>
>          fValID       = this.fDataTypeReg.getDatatypeValidator("ID" );
>          fValIDRef    = this.fDataTypeReg.getDatatypeValidator("IDREF" );
>          fValIDRefs   = this.fDataTypeReg.getDatatypeValidator("IDREFS" );
>          fValENTITY   = this.fDataTypeReg.getDatatypeValidator("ENTITY" );
>          fValENTITIES =
this.fDataTypeReg.getDatatypeValidator("ENTITIES" );
>          fValNMTOKEN  = this.fDataTypeReg.getDatatypeValidator("NMTOKEN");
>          fValNMTOKENS =
this.fDataTypeReg.getDatatypeValidator("NMTOKENS");
>          fValNOTATION =
this.fDataTypeReg.getDatatypeValidator("NOTATION" );
>
>
>          file://Initialize ENTITY & ENTITIES Validatorh
>          Object[] packageArgsEntityVal = { (Object) this.fEntityHandler,
>             (Object) this.fStringPool};
>          fValidateENTITYMsg.setDatatypeObject( (Object )
packageArgsEntityVal);
>          fValENTITY.validate( null, fValidateENTITYMsg );
>          fValENTITIES.validate( null, fValidateENTITYMsg );
>       } catch ( InvalidDatatypeValueException ex ) {
>          System.err.println("Error: " +
ex.getLocalizedMessage() );//Should not happen
>       }
>
>
>    } // init()
>
>    // other
>
>    // default attribute
>
>    /** addDefaultAttributes. */
>    private int addDefaultAttributes(int elementIndex, XMLAttrList
attrList, int attrIndex, boolean validationEnabled, boolean standalone)
throws Exception {
>
>       file://System.out.println("XMLValidator#addDefaultAttributes");
>       file://System.out.print("  ");
>       file://fGrammar.printAttributes(elementIndex);
>
>       //
>       // Check after all specified attrs are scanned
>       // (1) report error for REQUIRED attrs that are missing (V_TAGc)
>       // (2) check that FIXED attrs have matching value (V_TAGd)
>       // (3) add default attrs (FIXED and NOT_FIXED)
>       //
>       fGrammar.getElementDecl(elementIndex,fTempElementDecl);
>
>       int elementNameIndex = fTempElementDecl.name.localpart;
>       int attlistIndex =
fGrammar.getFirstAttributeDeclIndex(elementIndex);
>       int firstCheck = attrIndex;
>       int lastCheck = -1;
>       while (attlistIndex != -1) {
>          fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
>
>
>          int attPrefix = fTempAttDecl.name.prefix;
>          int attName = fTempAttDecl.name.localpart;
>          int attType = attributeTypeName(fTempAttDecl);
>          int attDefType =fTempAttDecl.defaultType;
>          int attValue = -1 ;
>          if (fTempAttDecl.defaultValue != null ) {
>             attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
>          }
>
>          boolean specified = false;
>          boolean required = attDefType ==
XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
>
>          if (firstCheck != -1) {
>             boolean cdata = attType == fCDATASymbol;
>             if (!cdata || required || attValue != -1) {
>                int i = attrList.getFirstAttr(firstCheck);
>                while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
>
>                   if ( (fGrammarIsDTDGrammar && (attrList.getAttrName(i)
== fTempAttDecl.name.rawname)) ||
>
 fStringPool.equalNames(attrList.getAttrLocalpart(i), attName)
>                           &&
fStringPool.equalNames(attrList.getAttrURI(i), fTempAttDecl.name.uri) ) ) {
>
>                      if (validationEnabled && attDefType ==
XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
>                         int alistValue = attrList.getAttValue(i);
>                         if (alistValue != attValue &&
>
!fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
>                            Object[] args =
 fStringPool.toString(elementNameIndex),
>                               fStringPool.toString(attName),
>                               fStringPool.toString(alistValue),
>                               fStringPool.toString(attValue)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
>
XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
>                                                       args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                         }
>                      }
>                      specified = true;
>                      break;
>                   }
>                   i = attrList.getNextAttr(i);
>                }
>             }
>          }
>
>          if (!specified) {
>             if (required) {
>                if (validationEnabled) {
>                   Object[] args =
 fStringPool.toString(elementNameIndex),
>                      fStringPool.toString(attName)};
>                   fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                              XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
>
XMLMessages.VC_REQUIRED_ATTRIBUTE,
>                                              args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                }
>             } else if (attValue != -1) {
>                if (validationEnabled && standalone )
>                   if ( fGrammarIsDTDGrammar
>                        && ((DTDGrammar)
fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
>
>                      Object[] args =
 fStringPool.toString(elementNameIndex),
>                         fStringPool.toString(attName)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                                 XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>                                                 args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                   }
>                if (attType == fIDREFSymbol) {
>                   this.fValIDRef.validate( fStringPool.toString(attValue),
this.fStoreIDRef );
>                } else if (attType == fIDREFSSymbol) {
>
his.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
>                }
>                if (attrIndex == -1) {
>                   attrIndex = attrList.startAttrList();
>                }
>                // REVISIT: Validation. What should the prefix be?
>                fTempQName.setValues(attPrefix, attName, attName,
fTempAttDecl.name.uri);
>                int newAttr = attrList.addAttr(fTempQName,
>                                               attValue, attType,
>                                               false, false);
>                if (lastCheck == -1) {
>                   lastCheck = newAttr;
>                }
>             }
>          }
>          attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
>       }
>       return attrIndex;
>
>    } // addDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
>
>    /** addDTDDefaultAttributes. */
>    private int addDTDDefaultAttributes(QName element, XMLAttrList
attrList, int attrIndex, boolean validationEnabled, boolean standalone)
throws Exception {
>
>
>       //
>       // Check after all specified attrs are scanned
>       // (1) report error for REQUIRED attrs that are missing (V_TAGc)
>       // (2) check that FIXED attrs have matching value (V_TAGd)
>       // (3) add default attrs (FIXED and NOT_FIXED)
>       //
>
>       int elementIndex = fGrammar.getElementDeclIndex(element, -1);
>
>       if (elementIndex == -1) {
>          return attrIndex;
>       }
>
>       fGrammar.getElementDecl(elementIndex,fTempElementDecl);
>
>
>       int elementNameIndex = fTempElementDecl.name.rawname;
>       int attlistIndex =
fGrammar.getFirstAttributeDeclIndex(elementIndex);
>       int firstCheck = attrIndex;
>       int lastCheck = -1;
>       while (attlistIndex != -1) {
>
>          fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
>
>          // TO DO: For ericye Debug only
>          /***
>          if (fTempAttDecl != null) {
>              XMLElementDecl element = new XMLElementDecl();
>              fGrammar.getElementDecl(elementIndex, element);
>              System.out.println("element:
"+fStringPool.toString(element.name.localpart));
>              System.out.println("attlistIndex " + attlistIndex + "\n"+
>                  "attName :
'"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
>                                 + "attType : "+fTempAttDecl.type + "\n"
>                                 + "attDefaultType :
"+fTempAttDecl.defaultType + "\n"
>                                 + "attDefaultValue :
'"+fTempAttDecl.defaultValue + "'\n"
>                                 + attrList.getLength() +"\n"
>                                 );
>          }
>          /***/
>
>          int attPrefix = fTempAttDecl.name.prefix;
>          int attName = fTempAttDecl.name.rawname;
>          int attLocalpart = fTempAttDecl.name.localpart;
>          int attType = attributeTypeName(fTempAttDecl);
>          int attDefType =fTempAttDecl.defaultType;
>          int attValue = -1 ;
>          if (fTempAttDecl.defaultValue != null ) {
>             attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
>          }
>          boolean specified = false;
>          boolean required = attDefType ==
XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
>
>
>          /****
>          if (fValidating && fGrammar != null && fGrammarIsDTDGrammar &&
attValue != -1) {
>              normalizeAttValue(null, fTempAttDecl.name,
>                                attValue,attType,fTempAttDecl.list,
>                                fTempAttDecl.enumeration);
>          }
>          /****/
>
>          if (firstCheck != -1) {
>             boolean cdata = attType == fCDATASymbol;
>             if (!cdata || required || attValue != -1) {
>                int i = attrList.getFirstAttr(firstCheck);
>                while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
>
>                   if ( attrList.getAttrName(i) ==
fTempAttDecl.name.rawname ) {
>
>                      if (validationEnabled && attDefType ==
XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
>                         int alistValue = attrList.getAttValue(i);
>                         if (alistValue != attValue &&
>
!fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
>                            Object[] args =
 fStringPool.toString(elementNameIndex),
>                               fStringPool.toString(attName),
>                               fStringPool.toString(alistValue),
>                               fStringPool.toString(attValue)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
>
XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
>                                                       args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                         }
>                      }
>                      specified = true;
>                      break;
>                   }
>                   i = attrList.getNextAttr(i);
>                }
>             }
>          }
>
>          if (!specified) {
>             if (required) {
>                if (validationEnabled) {
>                   Object[] args =
 fStringPool.toString(elementNameIndex),
>                      fStringPool.toString(attName)};
>                   fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                              XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
>
XMLMessages.VC_REQUIRED_ATTRIBUTE,
>                                              args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                }
>             } else if (attValue != -1) {
>                if (validationEnabled && standalone )
>                   if ( fGrammarIsDTDGrammar
>                        && ((DTDGrammar)
fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
>
>                      Object[] args =
 fStringPool.toString(elementNameIndex),
>                         fStringPool.toString(attName)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                                 XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>                                                 args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                   }
>                if (attType == fIDREFSymbol) {
>                   this.fValIDRef.validate( fStringPool.toString(attValue),
this.fStoreIDRef );
>                } else if (attType == fIDREFSSymbol) {
>
his.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
>                }
>                if (attrIndex == -1) {
>                   attrIndex = attrList.startAttrList();
>                }
>
>                fTempQName.setValues(attPrefix, attLocalpart, attName,
fTempAttDecl.name.uri);
>                int newAttr = attrList.addAttr(fTempQName,
>                                               attValue, attType,
>                                               false, false);
>                if (lastCheck == -1) {
>                   lastCheck = newAttr;
>                }
>             }
>          }
>          attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
>       }
>       return attrIndex;
>
>    } // addDTDDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
>
>    // content models
>
>    /** Queries the content model for the specified element index. */
>    private XMLContentModel getElementContentModel(int elementIndex) throws
CMException {
>       XMLContentModel contentModel = null;
>       if ( elementIndex > -1) {
>          if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
>             contentModel = fGrammar.getElementContentModel(elementIndex);
>          }
>       }
>       file://return fGrammar.getElementContentModel(elementIndex);
>       return contentModel;
>    }
>
>
>
>    // query attribute information
>
>    /** Returns an attribute definition for an element type. */
>    // this is only used by DTD validation.
>    private int getAttDef(QName element, QName attribute) {
>       if (fGrammar != null) {
>          int scope = fCurrentScope;
>          if (element.uri > -1) {
>             scope = TOP_LEVEL_SCOPE;
>          }
>          int elementIndex = fGrammar.getElementDeclIndex(element,scope);
>          if (elementIndex == -1) {
>             return -1;
>          }
>          int attDefIndex =
fGrammar.getFirstAttributeDeclIndex(elementIndex);
>          while (attDefIndex != -1) {
>             fGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
>             if (fTempAttributeDecl.name.localpart == attribute.localpart
&&
>                 fTempAttributeDecl.name.uri == attribute.uri ) {
>                return attDefIndex;
>             }
>             attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
>          }
>       }
>       return -1;
>
>    } // getAttDef(QName,QName)
>
>    /** Returns an attribute definition for an element type. */
>    private int getAttDefByElementIndex(int elementIndex, QName attribute)
{
>       if (fGrammar != null && elementIndex > -1) {
>          if (elementIndex == -1) {
>             return -1;
>          }
>          int attDefIndex =
fGrammar.getFirstAttributeDeclIndex(elementIndex);
>          while (attDefIndex != -1) {
>             fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);
>
>             if (fGrammarIsDTDGrammar) {
>                if (fTempAttDecl.name.rawname == attribute.rawname )
>                   return attDefIndex;
>             } else
>                if (fTempAttDecl.name.localpart == attribute.localpart &&
>                    fTempAttDecl.name.uri == attribute.uri ) {
>                return attDefIndex;
>             }
>
>             if (fGrammarIsSchemaGrammar) {
>                if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY) {
>                   return attDefIndex;
>                } else if (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_LOCAL) {
>                   if (attribute.uri == -1) {
>                      return attDefIndex;
>                   }
>                } else if (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_OTHER) {
>                   if (attribute.uri != fTempAttDecl.name.uri) {
>                      return attDefIndex;
>                   }
>                } else if (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_LIST) {
>                   if (fStringPool.stringInList(fTempAttDecl.enumeration,
attribute.uri)) {
>                      return attDefIndex;
>                   }
>                }
>             }
>
>             attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
>          }
>       }
>       return -1;
>
>    } // getAttDef(QName,QName)
>
>    // validation
>
>    /** Root element specified. */
>    private void rootElementSpecified(QName rootElement) throws Exception {
>
>       // this is what it used to be
>       file://if  (fDynamicValidation && !fSeenDoctypeDecl) {
>       file://fValidating = false;
>       file://}
>
>
>       if ( fLoadDTDGrammar )
>          // initialize the grammar to be the default one,
>          // it definitely should be a DTD Grammar at this case;
>          if (fGrammar == null) {
>
>             fGrammar = fGrammarResolver.getGrammar("");
>
>             file://TO DO, for ericye debug only
>             if (fGrammar == null && DEBUG_SCHEMA_VALIDATION) {
>                System.out.println("Oops! no grammar is found for
validation");
>             }
>
>             if (fDynamicValidation && fGrammar==null) {
>                fValidating = false;
>             }
>
>             if (fGrammar != null) {
>                if (fGrammar instanceof DTDGrammar) {
>                   fGrammarIsDTDGrammar = true;
>                   fGrammarIsSchemaGrammar = false;
>                } else if ( fGrammar instanceof SchemaGrammar ) {
>                   fGrammarIsSchemaGrammar = true;
>                   fGrammarIsDTDGrammar = false;
>                }
>
>                fGrammarNameSpaceIndex = fEmptyURI;
>             }
>          }
>
>       if (fValidating) {
>          if ( fGrammarIsDTDGrammar &&
>               ((DTDGrammar) fGrammar).getRootElementQName(fRootElement) )
{
>
>             String root1 = fStringPool.toString(fRootElement.rawname);
>             String root2 = fStringPool.toString(rootElement.rawname);
>             if (!root1.equals(root2)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ROOT_ELEMENT_TYPE,
>                                          XMLMessages.VC_ROOT_ELEMENT_TYPE,
>                                          fRootElement.rawname,
>                                          rootElement.rawname);
>             }
>          }
>       }
>
>       if (fNamespacesEnabled) {
>          if (fNamespacesScope == null) {
>             fNamespacesScope = new NamespacesScope(this);
>             fNamespacesPrefix = fStringPool.addSymbol("xmlns");
>             fNamespacesScope.setNamespaceForPrefix(fNamespacesPrefix, -1);
>             int xmlSymbol = fStringPool.addSymbol("xml");
>             int xmlNamespace =
fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace");
>             fNamespacesScope.setNamespaceForPrefix(xmlSymbol,
xmlNamespace);
>          }
>       }
>
>    } // rootElementSpecified(QName)
>
>    /** Switchs to correct validating symbol tables when Schema changes.*/
>
>    private boolean switchGrammar(int newGrammarNameSpaceIndex) throws
Exception {
>       Grammar tempGrammar =
fGrammarResolver.getGrammar(fStringPool.toString(newGrammarNameSpaceIndex));
>       if (tempGrammar == null) {
>          // This is a case where namespaces is on with a DTD grammar.
>          tempGrammar = fGrammarResolver.getGrammar("");
>       }
>       if (tempGrammar == null) {
>          return false;
>       } else {
>          fGrammar = tempGrammar;
>          if (fGrammar instanceof DTDGrammar) {
>             fGrammarIsDTDGrammar = true;
>             fGrammarIsSchemaGrammar = false;
>          } else if ( fGrammar instanceof SchemaGrammar ) {
>             fGrammarIsSchemaGrammar = true;
>             fGrammarIsDTDGrammar = false;
>          }
>
>          return true;
>       }
>    }
>
>    /** Binds namespaces to the element and attributes. */
>    private void bindNamespacesToElementAndAttributes(QName element,
>                                                      XMLAttrList attrList)
>    throws Exception {
>
>       fNamespacesScope.increaseDepth();
>
>       file://Vector schemaCandidateURIs = null;
>       Hashtable locationUriPairs = null;
>
>       if (fAttrListHandle != -1) {
>          int index = attrList.getFirstAttr(fAttrListHandle);
>          while (index != -1) {
>             int attName = attrList.getAttrName(index);
>             int attPrefix = attrList.getAttrPrefix(index);
>             if (fStringPool.equalNames(attName, fXMLLang)) {
>                /***
>                // NOTE: This check is done in the
validateElementsAndAttributes
>                //       method.
>
fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
>                /***/
>             } else if (fStringPool.equalNames(attName, fNamespacesPrefix))
{
>                int uri =
fStringPool.addSymbol(attrList.getAttValue(index));
>
fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, uri);
>             } else {
>                if (attPrefix == fNamespacesPrefix) {
>                   int nsPrefix = attrList.getAttrLocalpart(index);
>                   int uri =
fStringPool.addSymbol(attrList.getAttValue(index));
>                   fNamespacesScope.setNamespaceForPrefix(nsPrefix, uri);
>
>                   if (fValidating && fSchemaValidation) {
>                      boolean seeXsi = false;
>                      String attrValue =
fStringPool.toString(attrList.getAttValue(index));
>
>                      if (attrValue.equals(SchemaSymbols.URI_XSI)) {
>                         fXsiPrefix = nsPrefix;
>                         seeXsi = true;
>                      }
>
>                      if (!seeXsi) {
>                         /***
>                         if (schemaCandidateURIs == null) {
>                             schemaCandidateURIs = new Vector();
>                         }
>
chemaCandidateURIs.addElement( fStringPool.toString(uri) );
>                         /***/
>                      }
>                   }
>                }
>             }
>             index = attrList.getNextAttr(index);
>          }
>          // if validating, walk through the list again to deal with
"xsi:...."
>          if (fValidating && fSchemaValidation) {
>             fXsiTypeAttValue = -1;
>             index = attrList.getFirstAttr(fAttrListHandle);
>             while (index != -1) {
>
>                int attName = attrList.getAttrName(index);
>                int attPrefix = attrList.getAttrPrefix(index);
>
>                if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
>                   // REVISIT
>                } else {
>                   if ( DEBUG_SCHEMA_VALIDATION ) {
>                      System.out.println("deal with XSI");
>                      System.out.println("before find XSI:
"+fStringPool.toString(attPrefix)
>
+","+fStringPool.toString(fXsiPrefix) );
>                   }
>                   if ( fXsiPrefix != -1 && attPrefix == fXsiPrefix ) {
>
>                      if (DEBUG_SCHEMA_VALIDATION) {
>                         System.out.println("find XSI:
"+fStringPool.toString(attPrefix)
>
+","+fStringPool.toString(attName) );
>                      }
>
>
>                      int localpart = attrList.getAttrLocalpart(index);
>                      if (localpart ==
fStringPool.addSymbol(SchemaSymbols.XSI_SCHEMALOCACTION)) {
>                         if (locationUriPairs == null) {
>                            locationUriPairs = new Hashtable();
>                         }
>
parseSchemaLocation(fStringPool.toString(attrList.getAttValue(index)),
locationUriPairs);
>                      } else if (localpart ==
fStringPool.addSymbol(SchemaSymbols.XSI_NONAMESPACESCHEMALOCACTION)) {
>                         if (locationUriPairs == null) {
>                            locationUriPairs = new Hashtable();
>                         }
>
locationUriPairs.put(fStringPool.toString(attrList.getAttValue(index)), "");
>                         if (fNamespacesScope != null) {
>                            file://bind prefix "" to URI "" in this case
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
>
fStringPool.addSymbol(""));
>                         }
>                      } else if (localpart ==
fStringPool.addSymbol(SchemaSymbols.XSI_TYPE)) {
>                         fXsiTypeAttValue = attrList.getAttValue(index);
>                      }
>                      // REVISIT: should we break here?
>                      file://break;
>                   }
>                }
>                index = attrList.getNextAttr(index);
>             }
>
>             // try to resolve all the grammars here
>             if (locationUriPairs != null) {
>                Enumeration locations = locationUriPairs.keys();
>
>                while (locations.hasMoreElements()) {
>                   String loc = (String) locations.nextElement();
>                   String uri = (String) locationUriPairs.get(loc);
>                   resolveSchemaGrammar( loc, uri);
>                   file://schemaCandidateURIs.removeElement(uri);
>                }
>             }
>
>             file://TO DO: This should be a feature that can be turned on
or off
>             /*****
>             for (int i=0; i< schemaCandidateURIs.size(); i++) {
>
>                 String uri = (String) schemaCandidateURIs.elementAt(i);
>                 resolveSchemaGrammar(uri);
>             }
>             /*****/
>
>          }
>
>       }
>
>       // bind element to URI
>       int prefix = element.prefix != -1 ? element.prefix : 0;
>       int uri    = fNamespacesScope.getNamespaceForPrefix(prefix);
>       if (element.prefix != -1 || uri != -1) {
>          element.uri = uri;
>          if (element.uri == -1) {
>             Object[] args = { fStringPool.toString(element.prefix)};
>             fErrorReporter.reportError(fErrorReporter.getLocator(),
>                                        XMLMessages.XMLNS_DOMAIN,
>                                        XMLMessages.MSG_PREFIX_DECLARED,
>                                        XMLMessages.NC_PREFIX_DECLARED,
>                                        args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>          }
>       }
>
>
>       if (fAttrListHandle != -1) {
>          int index = attrList.getFirstAttr(fAttrListHandle);
>          while (index != -1) {
>             int attName = attrList.getAttrName(index);
>             if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
>                int attPrefix = attrList.getAttrPrefix(index);
>                if (attPrefix != fNamespacesPrefix) {
>                   if (attPrefix != -1 ) {
>                      int attrUri =
fNamespacesScope.getNamespaceForPrefix(attPrefix);
>                      if (attrUri == -1) {
>                         Object[] args =
 fStringPool.toString(attPrefix)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
XMLMessages.XMLNS_DOMAIN,
>
XMLMessages.MSG_PREFIX_DECLARED,
>
XMLMessages.NC_PREFIX_DECLARED,
>                                                    args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                      }
>                      attrList.setAttrURI(index, attrUri);
>                   }
>                }
>             }
>             index = attrList.getNextAttr(index);
>          }
>       }
>
>    } // bindNamespacesToElementAndAttributes(QName,XMLAttrList)
>
>    void parseSchemaLocation(String schemaLocationStr, Hashtable
locationUriPairs){
>       if (locationUriPairs != null) {
>          StringTokenizer tokenizer = new
StringTokenizer(schemaLocationStr, " \n\t\r", false);
>          int tokenTotal = tokenizer.countTokens();
>          if (tokenTotal % 2 != 0 ) {
>             // TO DO: report warning - malformed schemaLocation string
>          } else {
>             while (tokenizer.hasMoreTokens()) {
>                String uri = tokenizer.nextToken();
>                String location = tokenizer.nextToken();
>
>                locationUriPairs.put(location, uri);
>             }
>          }
>       } else {
>          // TO DO: should report internal error here
>       }
>
>    }// parseSchemaLocaltion(String, Hashtable)
>    private void resolveSchemaGrammar( String loc, String uri) throws
Exception {
>
>       SchemaGrammar grammar = (SchemaGrammar)
fGrammarResolver.getGrammar(uri);
>
>       if (grammar == null) {
>          DOMParser parser = new DOMParser();
>          parser.setEntityResolver( new Resolver(fEntityHandler) );
>          parser.setErrorHandler(  new ErrorHandler() );
>
>          try {
>             parser.setFeature("http://xml.org/sax/features/validation",
false);
>             parser.setFeature("http://xml.org/sax/features/namespaces",
true);
>
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
false);
>          } catch (  org.xml.sax.SAXNotRecognizedException e ) {
>             e.printStackTrace();
>          } catch ( org.xml.sax.SAXNotSupportedException e ) {
>             e.printStackTrace();
>          }
>
>          // expand it before passing it to the parser
>          InputSource source = null;
>          EntityResolver currentER = parser.getEntityResolver();
>          if (currentER != null) {
>             source = currentER.resolveEntity("", loc);
>          }
>          if (source == null) {
>             loc = fEntityHandler.expandSystemId(loc);
>             source = new InputSource(loc);
>          }
>          try {
>             parser.parse( source );
>          } catch ( IOException e ) {
>             e.printStackTrace();
>          } catch ( SAXException e ) {
>             file://System.out.println("loc = "+loc);
>             file://e.printStackTrace();
>
eportRecoverableXMLError( XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
>                                        XMLMessages.SCHEMA_GENERIC_ERROR,
e.getMessage() );
>          }
>
>          Document     document   = parser.getDocument(); file://Our
Grammar
>
>          TraverseSchema tst = null;
>          try {
>             if (DEBUG_SCHEMA_VALIDATION) {
>                System.out.println("I am geting the Schema Document");
>             }
>
>             Element root   = document.getDocumentElement();// This is what
we pass to TraverserSchema
>             if (root == null) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
XMLMessages.SCHEMA_GENERIC_ERROR, "Can't get back Schema document's root
element :" + loc);
>             } else {
>                if (uri == null ||
!uri.equals(root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE)) ) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
XMLMessages.SCHEMA_GENERIC_ERROR, "Schema in " + loc + " has a different
target namespace " +
>                                             "from the one specified in the
instance document :" + uri);
>                }
>                grammar = new SchemaGrammar();
>                grammar.setGrammarDocument(document);
>
>             // pass parser's entity resolver (local Resolver), which also
has reference to user's
>             // entity resolver, and also can fall-back to entityhandler's
expandSystemId()
>
>                tst = new TraverseSchema( root, fStringPool,
(SchemaGrammar)grammar, fGrammarResolver, fErrorReporter,
source.getSystemId(), currentER);
>
fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targ
etNamespace"), grammar);
>             }
>          } catch (Exception e) {
>             e.printStackTrace(System.err);
>          }
>       }
>
>    }
>
>    private void resolveSchemaGrammar(String uri) throws Exception{
>
>       resolveSchemaGrammar(uri, uri);
>
>    }
>
>    static class Resolver implements EntityResolver {
>
>       //
>       // Constants
>       //
>
>       private static final String SYSTEM[] = {
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
>       };
>       private static final String PATH[] = {
>          "structures.dtd",
>          "datatypes.dtd",
>          "versionInfo.ent",
>       };
>
>       //
>       // Data
>       //
>
>       private DefaultEntityHandler fEntityHandler;
>
>       //
>       // Constructors
>       //
>
>       public Resolver(DefaultEntityHandler handler) {
>          fEntityHandler = handler;
>       }
>
>       //
>       // EntityResolver methods
>       //
>
>       public InputSource resolveEntity(String publicId, String systemId)
>       throws IOException, SAXException {
>
>          // looking for the schema DTDs?
>          for (int i = 0; i < SYSTEM.length; i++) {
>             if (systemId.equals(SYSTEM[i])) {
>                InputSource source = new
InputSource(getClass().getResourceAsStream(PATH[i]));
>                source.setPublicId(publicId);
>                source.setSystemId(systemId);
>                return source;
>             }
>          }
>
>          // first try to resolve using user's entity resolver
>          EntityResolver resolver = fEntityHandler.getEntityResolver();
>          if (resolver != null) {
>             InputSource source = resolver.resolveEntity(publicId,
systemId);
>             if (source != null) {
>                return source;
>             }
>          }
>
>          // use default resolution
>          return new InputSource(fEntityHandler.expandSystemId(systemId));
>
>       } // resolveEntity(String,String):InputSource
>
>    } // class Resolver
>
>    static class ErrorHandler implements org.xml.sax.ErrorHandler {
>
>       /** Warning. */
>       public void warning(SAXParseException ex) {
>          System.err.println("[Warning] "+
>                             getLocationString(ex)+": "+
>                             ex.getMessage());
>       }
>
>       /** Error. */
>       public void error(SAXParseException ex) {
>          System.err.println("[Error] "+
>                             getLocationString(ex)+": "+
>                             ex.getMessage());
>       }
>
>       /** Fatal error. */
>       public void fatalError(SAXParseException ex)  {
>          System.err.println("[Fatal Error] "+
>                             getLocationString(ex)+": "+
>                             ex.getMessage());
>          file://throw ex;
>       }
>
>       //
>       // Private methods
>       //
>
>       /** Returns a string of the location. */
>       private String getLocationString(SAXParseException ex) {
>          StringBuffer str = new StringBuffer();
>
>          String systemId_ = ex.getSystemId();
>          if (systemId_ != null) {
>             int index = systemId_.lastIndexOf('/');
>             if (index != -1)
>                systemId_ = systemId_.substring(index + 1);
>             str.append(systemId_);
>          }
>          str.append(':');
>          str.append(ex.getLineNumber());
>          str.append(':');
>          str.append(ex.getColumnNumber());
>
>          return str.toString();
>
>       } // getLocationString(SAXParseException):String
>    }
>
>    private int attributeTypeName(XMLAttributeDecl attrDecl) {
>       switch (attrDecl.type) {
>       case XMLAttributeDecl.TYPE_ENTITY: {
>             return attrDecl.list ? fENTITIESSymbol : fENTITYSymbol;
>          }
>       case XMLAttributeDecl.TYPE_ENUMERATION: {
>             String enumeration =
fStringPool.stringListAsString(attrDecl.enumeration);
>             return fStringPool.addString(enumeration);
>          }
>       case XMLAttributeDecl.TYPE_ID: {
>             return fIDSymbol;
>          }
>       case XMLAttributeDecl.TYPE_IDREF: {
>             return attrDecl.list ? fIDREFSSymbol : fIDREFSymbol;
>          }
>       case XMLAttributeDecl.TYPE_NMTOKEN: {
>             return attrDecl.list ? fNMTOKENSSymbol : fNMTOKENSSymbol;
>          }
>       case XMLAttributeDecl.TYPE_NOTATION: {
>             return fNOTATIONSymbol;
>          }
>       }
>       return fCDATASymbol;
>    }
>
>    /** Validates element and attributes. */
>    private void validateElementAndAttributes(QName element,
>                                              XMLAttrList attrList)
>    throws Exception {
>
>       if ((fElementDepth >= 0 && fValidationFlagStack[fElementDepth] !=
0 )||
>           (fGrammar == null && !fValidating && !fNamespacesEnabled) ) {
>          fCurrentElementIndex = -1;
>          fCurrentContentSpecType = -1;
>          fInElementContent = false;
>          if (fAttrListHandle != -1) {
>             fAttrList.endAttrList();
>             int index = fAttrList.getFirstAttr(fAttrListHandle);
>             while (index != -1) {
>                if (fStringPool.equalNames(fAttrList.getAttrName(index),
fXMLLang)) {
>
fDocumentScanner.checkXMLLangAttributeValue(fAttrList.getAttValue(index));
>                   break;
>                }
>                index = fAttrList.getNextAttr(index);
>             }
>          }
>          return;
>       }
>
>       int elementIndex = -1;
>       int contentSpecType = -1;
>
>       boolean skipThisOne = false;
>       boolean laxThisOne = false;
>
>       if ( fGrammarIsSchemaGrammar && fContentLeafStack[fElementDepth] !=
null ) {
>          ContentLeafNameTypeVector cv = fContentLeafStack[fElementDepth];
>
>          QName[] fElemMap = cv.leafNames;
>          for (int i=0; i<cv.leafCount; i++) {
>             int type = cv.leafTypes[i]  ;
>             file://System.out.println("******* see a ANY_OTHER_SKIP,
"+type+","+element+","+fElemMap[i]+"\n*******");
>
>             if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
>                if (fElemMap[i].uri==element.uri
>                    && fElemMap[i].localpart == element.localpart)
>                   break;
>             } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
>                int uri = fElemMap[i].uri;
>                if (uri == -1 || uri == element.uri) {
>                   break;
>                }
>             } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
>                if (element.uri == -1) {
>                   break;
>                }
>             } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
>                if (fElemMap[i].uri != element.uri) {
>                   break;
>                }
>             } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_SKIP) {
>                int uri = fElemMap[i].uri;
>                if (uri == -1 || uri == element.uri) {
>                   skipThisOne = true;
>                   break;
>                }
>             } else if (type ==
XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP) {
>                if (element.uri == -1) {
>                   skipThisOne = true;
>                   break;
>                }
>             } else if (type ==
XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP) {
>                if (fElemMap[i].uri != element.uri) {
>                   skipThisOne = true;
>                   break;
>                }
>             } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LAX) {
>                int uri = fElemMap[i].uri;
>                if (uri == -1 || uri == element.uri) {
>                   laxThisOne = true;
>                   break;
>                }
>             } else if (type ==
XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX) {
>                if (element.uri == -1) {
>                   laxThisOne = true;
>                   break;
>                }
>             } else if (type ==
XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX) {
>                if (fElemMap[i].uri != element.uri) {
>                   laxThisOne = true;
>                   break;
>                }
>             }
>
>          }
>
>       }
>
>       if (skipThisOne) {
>          fNeedValidationOff = true;
>       } else {
>
>          file://REVISIT: is this the right place to check on if the Schema
has changed?
>
>          if ( fNamespacesEnabled && fValidating && element.uri !=
fGrammarNameSpaceIndex && element.uri != -1  ) {
>             fGrammarNameSpaceIndex = element.uri;
>
>             boolean success = switchGrammar(fGrammarNameSpaceIndex);
>
>             if (!success && !laxThisOne) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
XMLMessages.SCHEMA_GENERIC_ERROR,
>                                          "Grammar with uri 2: " +
fStringPool.toString(fGrammarNameSpaceIndex)
>                                          + " , can not found");
>             }
>          }
>
>
>          if ( fGrammar != null ) {
>             if (DEBUG_SCHEMA_VALIDATION) {
>                System.out.println("*******Lookup element: uri: " +
fStringPool.toString(element.uri)+
>                                   "localpart: '" +
fStringPool.toString(element.localpart)
>                                   +"' and scope : " + fCurrentScope+"\n");
>             }
>
>             elementIndex =
fGrammar.getElementDeclIndex(element,fCurrentScope);
>
>             if (elementIndex == -1 ) {
>                elementIndex = fGrammar.getElementDeclIndex(element,
TOP_LEVEL_SCOPE);
>             }
>
>             if (elementIndex == -1) {
>                // if validating based on a Schema, try to resolve the
element again by searching in its type's ancestor types
>                if (fGrammarIsSchemaGrammar && fCurrentElementIndex != -1)
{
>                   TraverseSchema.ComplexTypeInfo baseTypeInfo = null;
>                   baseTypeInfo =
((SchemaGrammar)fGrammar).getElementComplexTypeInfo(fCurrentElementIndex);
>                   int aGrammarNSIndex = fGrammarNameSpaceIndex;
>                   while (baseTypeInfo != null) {
>                      elementIndex = fGrammar.getElementDeclIndex(element,
baseTypeInfo.scopeDefined);
>                      if (elementIndex > -1 ) {
>                         // update the current Grammar NS index if
resolving element succeed.
>                         fGrammarNameSpaceIndex = aGrammarNSIndex;
>                         break;
>                      }
>                      baseTypeInfo = baseTypeInfo.baseComplexTypeInfo;
>                      if (baseTypeInfo != null) {
>                         String baseTName = baseTypeInfo.typeName;
>                         if (!baseTName.startsWith("#")) {
>                            int comma = baseTName.indexOf(',');
>                            aGrammarNSIndex =
fStringPool.addSymbol(baseTName.substring(0,comma).trim());
>                            if (aGrammarNSIndex != fGrammarNameSpaceIndex)
{
>                               if ( !switchGrammar(aGrammarNSIndex) ) {
>                                  break; file://exit the loop in this case
>                               }
>                            }
>                         }
>                      }
>                   }
>                   if (elementIndex == -1) {
>                      switchGrammar(fGrammarNameSpaceIndex);
>                   }
>                }
>                file://if still can't resolve it, try TOP_LEVEL_SCOPE AGAIN
>                /****
>                if ( element.uri == -1 && elementIndex == -1
>                && fNamespacesScope != null
>                &&
fNamespacesScope.getNamespaceForPrefix(StringPool.EMPTY_STRING) != -1 ) {
>                elementIndex =
fGrammar.getElementDeclIndex(element.localpart, TOP_LEVEL_SCOPE);
>                // REVISIT:
>                // this is a hack to handle the situation where namespace
prefix "" is bound to nothing, and there
>                // is a "noNamespaceSchemaLocation" specified, and element
>                element.uri = StringPool.EMPTY_STRING;
>                }
>                /****/
>
>                /****/
>                if (elementIndex == -1) {
>                   if (laxThisOne) {
>                      fNeedValidationOff = true;
>                   } else
>                      if (DEBUG_SCHEMA_VALIDATION)
>                      System.out.println("!!! can not find elementDecl in
the grammar, " +
>                                         " the element localpart: " +
element.localpart +
>
"["+fStringPool.toString(element.localpart) +"]" +
>                                         " the element uri: " + element.uri
+
>
"["+fStringPool.toString(element.uri) +"]" +
>                                         " and the current enclosing scope:
" + fCurrentScope );
>                }
>                /****/
>             }
>
>             if (DEBUG_SCHEMA_VALIDATION) {
>                fGrammar.getElementDecl(elementIndex, fTempElementDecl);
>                System.out.println("elementIndex: " + elementIndex+" \n and
itsName : '"
>                                   +
fStringPool.toString(fTempElementDecl.name.localpart)
>                                   +"' \n its ContentType:" +
fTempElementDecl.type
>                                   +"\n its ContentSpecIndex : " +
fTempElementDecl.contentSpecIndex +"\n"+
>                                   " and the current enclosing scope: " +
fCurrentScope);
>             }
>          }
>
>          contentSpecType =  getContentSpecType(elementIndex);
>
>          if (fGrammarIsSchemaGrammar && elementIndex != -1) {
>
>             // handle "xsi:type" right here
>             if (fXsiTypeAttValue > -1) {
>                String xsiType = fStringPool.toString(fXsiTypeAttValue);
>                int colonP = xsiType.indexOf(":");
>                String prefix = "";
>                String localpart = xsiType;
>                if (colonP > -1) {
>                   prefix = xsiType.substring(0,colonP);
>                   localpart = xsiType.substring(colonP+1);
>                }
>
>                String uri = "";
>                int uriIndex = -1;
>                if (fNamespacesScope != null) {
>                   uriIndex =
fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix));
>                   if (uriIndex > -1) {
>                      uri = fStringPool.toString(uriIndex);
>                      if (uriIndex != fGrammarNameSpaceIndex) {
>                         fGrammarNameSpaceIndex = fCurrentSchemaURI =
uriIndex;
>                         boolean success =
switchGrammar(fCurrentSchemaURI);
>                         if (!success && !fNeedValidationOff) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
>
XMLMessages.SCHEMA_GENERIC_ERROR,
>                                                      "Grammar with uri 3:
"
>                                                      +
fStringPool.toString(fCurrentSchemaURI)
>                                                      + " , can not
found");
>                         }
>                      }
>                   }
>                }
>
>
>                Hashtable complexRegistry =
((SchemaGrammar)fGrammar).getComplexTypeRegistry();
>                DatatypeValidatorFactoryImpl dataTypeReg =
((SchemaGrammar)fGrammar).getDatatypeRegistry();
>                if (complexRegistry==null || dataTypeReg == null) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
>
XMLMessages.SCHEMA_GENERIC_ERROR,
>
fErrorReporter.getLocator().getSystemId()
>                                             +"
line"+fErrorReporter.getLocator().getLineNumber()
>                                             +", canot resolve xsi:type = "
+ xsiType+"  ---2");
>                } else {
>                   TraverseSchema.ComplexTypeInfo typeInfo =
>                   (TraverseSchema.ComplexTypeInfo)
complexRegistry.get(uri+","+localpart);
>                   file://TO DO:
>                   //      here need to check if this substitution is legal
based on the current active grammar,
>                   //      this should be easy, cause we already saved
final, block and base type information in
>                   //      the SchemaGrammar.
>
>                   if (typeInfo==null) {
>                      if (uri.length() == 0 ||
uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ) {
>                         fXsiTypeValidator =
dataTypeReg.getDatatypeValidator(localpart);
>                      } else
>                         fXsiTypeValidator =
dataTypeReg.getDatatypeValidator(uri+","+localpart);
>                      if ( fXsiTypeValidator == null )
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
>
XMLMessages.SCHEMA_GENERIC_ERROR,
>                                                   "unresolved type :
"+uri+","+localpart
>                                                   +" found  in xsi:type
handling");
>                   } else
>                      elementIndex = typeInfo.templateElementIndex;
>                }
>
>                fXsiTypeAttValue = -1;
>             }
>
>             file://Change the current scope to be the one defined by this
element.
>             fCurrentScope = ((SchemaGrammar)
fGrammar).getElementDefinedScope(elementIndex);
>
>             //       here need to check if we need to switch Grammar by
asking SchemaGrammar whether
>             //       this element actually is of a type in another Schema.
>             String anotherSchemaURI =
((SchemaGrammar)fGrammar).getElementFromAnotherSchemaURI(elementIndex);
>             if (anotherSchemaURI != null) {
>                file://before switch Grammar, set the elementIndex to be
the template elementIndex of its type
>                 // but if the content type is empty, we don't bother
switching the grammar.
>                if (contentSpecType != -1
>                    && contentSpecType != XMLElementDecl.TYPE_EMPTY ) {
>                   TraverseSchema.ComplexTypeInfo typeInfo =
((SchemaGrammar) fGrammar).getElementComplexTypeInfo(elementIndex);
>                   if (typeInfo != null) {
>                      elementIndex = typeInfo.templateElementIndex;
>                   }
>
>                }
>
>                // now switch the grammar
>                fGrammarNameSpaceIndex = fCurrentSchemaURI =
fStringPool.addSymbol(anotherSchemaURI);
>                boolean success = switchGrammar(fCurrentSchemaURI);
>                if (!success && !fNeedValidationOff) {
>
reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
>
XMLMessages.SCHEMA_GENERIC_ERROR,
>                                             "Grammar with uri 4: "
>                                             +
fStringPool.toString(fCurrentSchemaURI)
>                                             + " , can not found");
>                }
>             }
>
>          }
>
>          // since the elementIndex could change since last time we query
the content type, so do it again.
>          contentSpecType =  getContentSpecType(elementIndex);
>
>          if (contentSpecType == -1 && fValidating && !fNeedValidationOff )
{
>
reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
>                                       XMLMessages.VC_ELEMENT_VALID,
>                                       element.rawname);
>          }
>          if (fGrammar != null && fGrammarIsSchemaGrammar && elementIndex
!= -1) {
>             fAttrListHandle = addDefaultAttributes(elementIndex, attrList,
fAttrListHandle, fValidating, fStandaloneReader != -1);
>          }
>          if (fAttrListHandle != -1) {
>             fAttrList.endAttrList();
>          }
>
>          if (DEBUG_PRINT_ATTRIBUTES) {
>             String elementStr = fStringPool.toString(element.rawname);
>             System.out.print("startElement: <" + elementStr);
>             if (fAttrListHandle != -1) {
>                int index = attrList.getFirstAttr(fAttrListHandle);
>                while (index != -1) {
>                   System.out.print(" " +
fStringPool.toString(attrList.getAttrName(index)) + "=\"" +
>
fStringPool.toString(attrList.getAttValue(index)) + "\"");
>                   index = attrList.getNextAttr(index);
>                }
>             }
>             System.out.println(">");
>          }
>          // REVISIT: Validation. Do we need to recheck for the xml:lang
>          //          attribute? It was already checked above -- perhaps
>          //          this is to check values that are defaulted in? If
>          //          so, this check could move to the attribute decl
>          //          callback so we can check the default value before
>          //          it is used.
>          if (fAttrListHandle != -1 && !fNeedValidationOff ) {
>             int index = fAttrList.getFirstAttr(fAttrListHandle);
>             while (index != -1) {
>                int attrNameIndex = attrList.getAttrName(index);
>
>                if (fStringPool.equalNames(attrNameIndex, fXMLLang)) {
>
fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
>                   // break;
>                }
>                // here, we validate every "user-defined" attributes
>                int _xmlns = fStringPool.addSymbol("xmlns");
>
>                if (attrNameIndex != _xmlns &&
attrList.getAttrPrefix(index) != _xmlns)
>                   if (fGrammar != null) {
>                      fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
>                      fTempQName.setValues(attrList.getAttrPrefix(index),
>
attrList.getAttrLocalpart(index),
>                                           attrList.getAttrName(index),
>                                           attrList.getAttrURI(index) );
>                      int attDefIndex =
getAttDefByElementIndex(elementIndex, fTempQName);
>
>                      if (fTempQName.uri != fXsiURI)
>                         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(attrList.getAttrName(index))};
>
>                               /*****/
>                               fErrorReporter.reportError(fAttrNameLocator,
>
XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
>
XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
>                                                          args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                               /******/
>                            }
>                         } else {
>
>                            fGrammar.getAttributeDecl(attDefIndex,
fTempAttDecl);
>
>                            int attributeType =
attributeTypeName(fTempAttDecl);
>                            attrList.setAttType(index, attributeType);
>
>                            if (fValidating) {
>
>                               if (fGrammarIsDTDGrammar &&
>                                   (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ENTITY ||
>                                    fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ENUMERATION ||
>                                    fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ID ||
>                                    fTempAttDecl.type ==
XMLAttributeDecl.TYPE_IDREF ||
>                                    fTempAttDecl.type ==
XMLAttributeDecl.TYPE_NMTOKEN ||
>                                    fTempAttDecl.type ==
XMLAttributeDecl.TYPE_NOTATION)
>                                  ) {
>                                   int normalizedValue =
validateDTDattribute(element, attrList.getAttValue(index), fTempAttDecl);
>                                   attrList.setAttValue(index,
normalizedValue);
>
>                               }
>
>                               // check to see if this attribute matched an
attribute wildcard
>                               else if ( fGrammarIsSchemaGrammar &&
>                                         (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_ANY
>                                          ||fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_LIST
>                                          ||fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_LOCAL
>                                          ||fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ANY_OTHER) ) {
>
>                                  if (fTempAttDecl.defaultType ==
XMLAttributeDecl.PROCESSCONTENTS_SKIP) {
>                                     // attribute should just be bypassed,
>                                  } else if ( fTempAttDecl.defaultType ==
XMLAttributeDecl.PROCESSCONTENTS_STRICT
>                                              || fTempAttDecl.defaultType
== XMLAttributeDecl.PROCESSCONTENTS_LAX) {
>
>                                     boolean reportError = false;
>                                     boolean processContentStrict =
>                                     fTempAttDecl.defaultType ==
XMLAttributeDecl.PROCESSCONTENTS_STRICT;
>
>                                     if (fTempQName.uri == -1) {
>                                        if (processContentStrict) {
>                                           reportError = true;
>                                        }
>                                     } else {
>                                        Grammar aGrammar =
>
fGrammarResolver.getGrammar(fStringPool.toString(fTempQName.uri));
>
>                                        if (aGrammar == null || !(aGrammar
instanceof SchemaGrammar) ) {
>                                           if (processContentStrict) {
>                                              reportError = true;
>                                           }
>                                        } else {
>                                           SchemaGrammar sGrammar =
(SchemaGrammar) aGrammar;
>                                           Hashtable attRegistry =
sGrammar.getAttirubteDeclRegistry();
>                                           if (attRegistry == null) {
>                                              if (processContentStrict) {
>                                                 reportError = true;
>                                              }
>                                           } else {
>                                              XMLAttributeDecl attDecl =
(XMLAttributeDecl)
attRegistry.get(fStringPool.toString(fTempQName.localpart));
>                                              if (attDecl == null) {
>                                                 if (processContentStrict)
{
>                                                    reportError = true;
>                                                 }
>                                              } else {
>                                                 DatatypeValidator attDV =
attDecl.datatypeValidator;
>                                                 if (attDV == null) {
>                                                    if
(processContentStrict) {
>                                                       reportError = true;
>                                                    }
>                                                 } else {
>                                                    try {
>                                                       String  unTrimValue
= fStringPool.toString(attrList.getAttValue(index));
>                                                       String  value
= unTrimValue.trim();
>                                                       if (attDecl.type ==
XMLAttributeDecl.TYPE_ID ) {
>
this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
>                                                       }
>                                                       if (attDecl.type ==
XMLAttributeDecl.TYPE_IDREF ) {
>
attDV.validate(value, this.fStoreIDRef );
>                                                       } else
>
attDV.validate(unTrimValue, null );
>                                                    } catch
(InvalidDatatypeValueException idve) {
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
SchemaMessageProvider.SCHEMA_DOMAIN,
>
SchemaMessageProvider.DatatypeError,
>
SchemaMessageProvider.MSG_NONE,
>
new Object [] { idve.getMessage()},
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                                                    }
>                                                 }
>                                              }
>                                           }
>                                        }
>                                     }
>                                     if (reportError) {
>                                        Object[] args =
 fStringPool.toString(element.rawname),
>
"ANY---"+fStringPool.toString(attrList.getAttrName(index))};
>
>
fErrorReporter.reportError(fAttrNameLocator,
>
XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
>
XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
>                                                                   args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>
>                                     }
>                                  }
>                               } else if (fTempAttDecl.datatypeValidator ==
null) {
>                                  Object[] args =
 fStringPool.toString(element.rawname),
>
fStringPool.toString(attrList.getAttrName(index))};
>
>                                  System.out.println("[Error]
Datatypevalidator for attribute " +
fStringPool.toString(attrList.getAttrName(index))
>                                                     + " not found in
element type " + fStringPool.toString(element.rawname));
>                                  file://REVISIT : is this the right
message?
>                                  /****/
>
fErrorReporter.reportError(fAttrNameLocator,
>
XMLMessages.XML_DOMAIN,
>
XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
>
XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
>                                                             args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                                  /****/
>                               } else {
>                                  try {
>                                     String  unTrimValue =
fStringPool.toString(attrList.getAttValue(index));
>                                     String  value       =
unTrimValue.trim();
>                                     if (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_ID ) {
>
his.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
>                                     } else if (fTempAttDecl.type ==
XMLAttributeDecl.TYPE_IDREF ) {
>
fTempAttDecl.datatypeValidator.validate(value, this.fStoreIDRef );
>                                     } else {
>
fTempAttDecl.datatypeValidator.validate(unTrimValue, null );
>                                     }
>
>                                  } catch (InvalidDatatypeValueException
idve) {
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
SchemaMessageProvider.SCHEMA_DOMAIN,
>
SchemaMessageProvider.DatatypeError,
>
SchemaMessageProvider.MSG_NONE,
>                                                                new Object
[] { idve.getMessage()},
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                                  }
>                               }
>                            } // end of if (fValidating)
>
>
>                         } // end of if (attDefIndex == -1) else
>
>                   }// end of if (fGrammar != null)
>                index = fAttrList.getNextAttr(index);
>             }
>          }
>       }
>       if (fAttrListHandle != -1) {
>          int index = attrList.getFirstAttr(fAttrListHandle);
>          while (index != -1) {
>             int attName = attrList.getAttrName(index);
>             if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
>                int attPrefix = attrList.getAttrPrefix(index);
>                if (attPrefix != fNamespacesPrefix) {
>                   if (attPrefix != -1) {
>                      int uri =
fNamespacesScope.getNamespaceForPrefix(attPrefix);
>                      if (uri == -1) {
>                         Object[] args =
 fStringPool.toString(attPrefix)};
>
fErrorReporter.reportError(fErrorReporter.getLocator(),
>
XMLMessages.XMLNS_DOMAIN,
>
XMLMessages.MSG_PREFIX_DECLARED,
>
XMLMessages.NC_PREFIX_DECLARED,
>                                                    args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>                      }
>                      attrList.setAttrURI(index, uri);
>                   }
>                }
>             }
>             index = attrList.getNextAttr(index);
>          }
>       }
>
>       fCurrentElementIndex = elementIndex;
>       fCurrentContentSpecType = contentSpecType;
>
>       if (fValidating && contentSpecType == XMLElementDecl.TYPE_SIMPLE) {
>          fBufferDatatype = true;
>          fDatatypeBuffer.setLength(0);
>       }
>
>       fInElementContent = (contentSpecType ==
XMLElementDecl.TYPE_CHILDREN);
>
>    } // validateElementAndAttributes(QName,XMLAttrList)
>
>
>    /**
>     * Validate attributes in DTD fashion.
>     * @return normalized attribute value
>     */
>    private int validateDTDattribute(QName element, int attValue,
>                                      XMLAttributeDecl attributeDecl)
throws Exception{
>       AttributeValidator av = null;
>       switch (attributeDecl.type) {
>       case XMLAttributeDecl.TYPE_ENTITY:
>          {
>             boolean isAlistAttribute = attributeDecl.list;//Caveat - Save
this information because invalidStandaloneAttDef
>             String  unTrimValue      = fStringPool.toString(attValue);
>             String  value            = unTrimValue.trim();
>             file://System.out.println("value = " + value );
>             file://changes fTempAttDef
>             if (fValidationEnabled) {
>                if (value != unTrimValue) {
>                   if (invalidStandaloneAttDef(element,
attributeDecl.name)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
>                   }
>                }
>             }
>
>             try {
>                if ( isAlistAttribute ) {
>                   fValENTITIES.validate( value, null );
>                } else {
>                   fValENTITY.validate( value, null );
>                }
>             } catch ( InvalidDatatypeValueException ex ) {
>                if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
>                   reportRecoverableXMLError(ex.getMajorCode(),
>                                             ex.getMinorCode(),
>
StringPool.toString( attributeDecl.name.rawname), value );
>                } else {
>                   System.err.println("Error: " +
ex.getLocalizedMessage() );//Should not happen
>                }
>             }
>
>             /*if (attributeDecl.list) {
>                 av = fAttValidatorENTITIES;
>             }
>             else {
>                 av = fAttValidatorENTITY;
>             }*/
>
>             if (fNormalizeAttributeValues) {
>                 if (attributeDecl.list) {
>                     attValue = normalizeListAttribute(value);
>                 } else {
>                     if (value != unTrimValue) {
>                         attValue = fStringPool.addSymbol(value);
>                     }
>                 }
>             }
>          }
>          break;
>       case XMLAttributeDecl.TYPE_ENUMERATION:
>          av = fAttValidatorENUMERATION;
>          break;
>       case XMLAttributeDecl.TYPE_ID:
>          {
>             String  unTrimValue = fStringPool.toString(attValue);
>             String  value       = unTrimValue.trim();
>             if (fValidationEnabled) {
>                if (value != unTrimValue) {
>                   if (invalidStandaloneAttDef(element,
attributeDecl.name)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
>                   }
>                }
>             }
>             try {
>                file://this.fIdDefs = (Hashtable) fValID.validate( value,
null );
>                file://System.out.println("this.fIdDefs = " +
this.fIdDefs );
>
>                this.fStoreIDRef.setDatatypeObject( fValID.validate( value,
null ) );
>                fValIDRef.validate( value, this.fStoreIDRef ); file://just
in case we called id after IDREF
>             } catch ( InvalidDatatypeValueException ex ) {
>                reportRecoverableXMLError(ex.getMajorCode(),
>                                          ex.getMinorCode(),
>
StringPool.toString( attributeDecl.name.rawname), value );
>             }
>
>             if (fNormalizeAttributeValues && value != unTrimValue) {
>                 attValue = fStringPool.addSymbol(value);
>             }
>          }
>          break;
>       case XMLAttributeDecl.TYPE_IDREF:
>          {
>             String  unTrimValue = fStringPool.toString(attValue);
>             String  value       = unTrimValue.trim();
>             boolean isAlistAttribute = attributeDecl.list;//Caveat - Save
this information because invalidStandaloneAttDef
>                                                           file://changes
fTempAttDef
>             if (fValidationEnabled) {
>                if (value != unTrimValue) {
>                   if (invalidStandaloneAttDef(element,
attributeDecl.name)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
>                   }
>                }
>             }
>             try {
>                if ( isAlistAttribute ) {
>                   fValIDRefs.validate( value, this.fStoreIDRef );
>                } else {
>                   fValIDRef.validate( value, this.fStoreIDRef );
>                }
>             } catch ( InvalidDatatypeValueException ex ) {
>                if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
>                   reportRecoverableXMLError(ex.getMajorCode(),
>                                             ex.getMinorCode(),
>
StringPool.toString( attributeDecl.name.rawname), value );
>                } else {
>                   System.err.println("Error: " +
ex.getLocalizedMessage() );//Should not happen
>                }
>             }
>
>             if (fNormalizeAttributeValues) {
>                 if (attributeDecl.list) {
>                     attValue = normalizeListAttribute(value);
>                 } else {
>                     if (value != unTrimValue) {
>                         attValue = fStringPool.addSymbol(value);
>                     }
>                 }
>             }
>          }
>          break;
>       case XMLAttributeDecl.TYPE_NOTATION:
>          {
>             /* WIP
>             String  unTrimValue = fStringPool.toString(attValue);
>          String  value       = unTrimValue.trim();
>          if (fValidationEnabled) {
>              if (value != unTrimValue) {
>                  if (invalidStandaloneAttDef(element, attributeDecl.name))
{
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
>                  }
>              }
>          }
>          try {
>              file://this.fIdDefs = (Hashtable) fValID.validate( value,
null );
>              file://System.out.println("this.fIdDefs = " + this.fIdDefs );
>
>              this.fStoreIDRef.setDatatypeObject( fValID.validate( value,
null ) );
>          } catch ( InvalidDatatypeValueException ex ) {
>              reportRecoverableXMLError(ex.getMajorCode(),
>                                        ex.getMinorCode(),
>
StringPool.toString( attributeDecl.name.rawname), value );
>          }
>       }
>         */
>             av = fAttValidatorNOTATION;
>
>
>          }
>          break;
>       case XMLAttributeDecl.TYPE_NMTOKEN:
>          {
>             String  unTrimValue = fStringPool.toString(attValue);
>             String  value       = unTrimValue.trim();
>             boolean isAlistAttribute = attributeDecl.list;//Caveat - Save
this information because invalidStandaloneAttDef
>             file://changes fTempAttDef
>             if (fValidationEnabled) {
>                if (value != unTrimValue) {
>                   if (invalidStandaloneAttDef(element,
attributeDecl.name)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
>                   }
>                }
>             }
>             try {
>                if ( isAlistAttribute ) {
>                   fValNMTOKENS.validate( value, null );
>                } else {
>                   fValNMTOKEN.validate( value, null );
>                }
>             } catch ( InvalidDatatypeValueException ex ) {
>                reportRecoverableXMLError(XMLMessages.MSG_NMTOKEN_INVALID,
>                                          XMLMessages.VC_NAME_TOKEN,
>
fStringPool.toString(attributeDecl.name.rawname), value);//TODO NMTOKENS
messge
>             }
>
>             if (fNormalizeAttributeValues) {
>                 if (attributeDecl.list) {
>                     attValue = normalizeListAttribute(value);
>                 } else {
>                     if (value != unTrimValue) {
>                         attValue = fStringPool.addSymbol(value);
>                     }
>                 }
>             }
>          }
>          break;
>       }
>       if ( av != null ) {
>           int newValue = av.normalize(element, attributeDecl.name,
attValue,
>                                   attributeDecl.type,
attributeDecl.enumeration);
>           if (fNormalizeAttributeValues)
>               attValue = newValue;
>       }
>       return attValue;
>    }
>
>    /**
>     * @param value This is already trimmed.
>     */
>    private int normalizeListAttribute(String value) {
>        int length = value.length();
>        StringBuffer buffer = null;
>        int state = 0;           // 0:non-S, 1: 1st S, 2: non-1st S
>        int copyStart = 0;
>        for (int i = 0;  i < length;  i++) {
>            int ch = value.charAt(i);
>            if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
>                if (state == 0) {
>                    state = 1;
>                } else if (state == 1) {
>                    state = 2;
>                    if (buffer == null)
>                        buffer = new StringBuffer(length);
>                    buffer.append(value.substring(copyStart, i));
>                }
>            } else {
>                if (state == 2)
>                    copyStart = i;
>                state = 0;
>            }
>        }
>        if (buffer == null)
>            return fStringPool.addSymbol(value);
>        buffer.append(value.substring(copyStart));
>        return fStringPool.addSymbol(new String(buffer));
>    }
>
>    /** Character data in content. */
>    private void charDataInContent() {
>
>       if (DEBUG_ELEMENT_CHILDREN) {
>          System.out.println("charDataInContent()");
>       }
>       if (fElementChildren.length <= fElementChildrenLength) {
>          QName[] newarray = new QName[fElementChildren.length * 2];
>          System.arraycopy(fElementChildren, 0, newarray, 0,
fElementChildren.length);
>          fElementChildren = newarray;
>       }
>       QName qname = fElementChildren[fElementChildrenLength];
>       if (qname == null) {
>          for (int i = fElementChildrenLength; i < fElementChildren.length;
i++) {
>             fElementChildren[i] = new QName();
>          }
>          qname = fElementChildren[fElementChildrenLength];
>       }
>       qname.clear();
>       fElementChildrenLength++;
>
>    } // charDataInCount()
>
>    /**
>     * Check that the content of an element is valid.
>     * <p>
>     * This is the method of primary concern to the validator. This method
is called
>     * upon the scanner reaching the end tag of an element. At that time,
the
>     * element's children must be structurally validated, so it calls this
method.
>     * The index of the element being checked (in the decl pool), is
provided as
>     * well as an array of element name indexes of the children. The
validator must
>     * confirm that this element can have these children in this order.
>     * <p>
>     * This can also be called to do 'what if' testing of content models
just to see
>     * if they would be valid.
>     * <p>
>     * Note that the element index is an index into the element decl pool,
whereas
>     * the children indexes are name indexes, i.e. into the string pool.
>     * <p>
>     * A value of -1 in the children array indicates a PCDATA node. All
other
>     * indexes will be positive and represent child elements. The count can
be
>     * zero, since some elements have the EMPTY content model and that must
be
>     * confirmed.
>     *
>     * @param elementIndex The index within the
<code>ElementDeclPool</code> of this
>     *                     element.
>     * @param childCount The number of entries in the <code>children</code>
array.
>     * @param children The children of this element.  Each integer is an
index within
>     *                 the <code>StringPool</code> of the child element
name.  An index
>     *                 of -1 is used to indicate an occurrence of
non-whitespace character
>     *                 data.
>     *
>     * @return The value -1 if fully valid, else the 0 based index of the
child
>     *         that first failed. If the value returned is equal to the
number
>     *         of children, then additional content is required to reach a
valid
>     *         ending state.
>     *
>     * @exception Exception Thrown on error.
>     */
>    private int checkContent(int elementIndex,
>                             QName[] children,
>                             int childOffset,
>                             int childCount) throws Exception {
>
>       // Get the element name index from the element
>       // REVISIT: Validation
>       final int elementType = fCurrentElement.rawname;
>
>       if (DEBUG_PRINT_CONTENT) {
>          String strTmp = fStringPool.toString(elementType);
>          System.out.println("Name: "+strTmp+", "+
>                             "Count: "+childCount+", "+
>                             "ContentSpecType: " +fCurrentContentSpecType);
file://+getContentSpecAsString(elementIndex));
>          for (int index = childOffset; index < (childOffset+childCount)
&& index < 10; index++) {
>             if (index == 0) {
>                System.out.print("  (");
>             }
>             String childName = (children[index].localpart == -1) ?
"#PCDATA" : fStringPool.toString(children[index].localpart);
>             if (index + 1 == childCount) {
>                System.out.println(childName + ")");
>             } else if (index + 1 == 10) {
>                System.out.println(childName + ",...)");
>             } else {
>                System.out.print(childName + ",");
>             }
>          }
>       }
>
>       // Get out the content spec for this element
>       final int contentType = fCurrentContentSpecType;
>
> // debugging
> file://System.out.println("~~~~~~in checkContent, fCurrentContentSpecType
: " + fCurrentContentSpecType);
>
>       //
>       //  Deal with the possible types of content. We try to optimized
here
>       //  by dealing specially with content models that don't require the
>       //  full DFA treatment.
>       //
>       if (contentType == XMLElementDecl.TYPE_EMPTY) {
>          //
>          //  If the child count is greater than zero, then this is
>          //  an error right off the bat at index 0.
>          //
>          if (childCount != 0) {
>             return 0;
>          }
>       } else if (contentType == XMLElementDecl.TYPE_ANY) {
>          //
>          //  This one is open game so we don't pass any judgement on it
>          //  at all. Its assumed to fine since it can hold anything.
>          //
>       } else if (contentType == XMLElementDecl.TYPE_MIXED ||
>                  contentType == XMLElementDecl.TYPE_CHILDREN) {
>          // Get the content model for this element, faulting it in if
needed
>          XMLContentModel cmElem = null;
>          try {
>             cmElem = getElementContentModel(elementIndex);
>             int result = cmElem.validateContent(children, childOffset,
childCount);
>             if (result != -1 && fGrammarIsSchemaGrammar) {
>                // REVISIT: not optimized for performance,
>                EquivClassComparator comparator = new
EquivClassComparator(fGrammarResolver, fStringPool);
>                cmElem.setEquivClassComparator(comparator);
>                result = cmElem.validateContentSpecial(children,
childOffset, childCount);
>             }
>             return result;
>          } catch (CMException excToCatch) {
>             // REVISIT - Translate the caught exception to the protected
error API
>             int majorCode = excToCatch.getErrorCode();
>             fErrorReporter.reportError(fErrorReporter.getLocator(),
>
ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
>                                        majorCode,
>                                        0,
>                                        null,
>
XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
>          }
>       } else if (contentType == -1) {
>          reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
>                                    XMLMessages.VC_ELEMENT_VALID,
>                                    elementType);
>       } else if (contentType == XMLElementDecl.TYPE_SIMPLE ) {
>
>          XMLContentModel cmElem = null;
>          if (childCount > 0) {
>             fErrorReporter.reportError(fErrorReporter.getLocator(),
>
SchemaMessageProvider.SCHEMA_DOMAIN,
>
SchemaMessageProvider.DatatypeError,
>                                        SchemaMessageProvider.MSG_NONE,
>                                        new Object [] { "In element
'"+fStringPool.toString(elementType)+"' : "+
>                                           "Can not have element children
within a simple type content"},
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>          } else {
>             try {
>
>                fGrammar.getElementDecl(elementIndex, fTempElementDecl);
>
>                DatatypeValidator dv = fTempElementDecl.datatypeValidator;
>
>                // If there is xsi:type validator, substitute it.
>                if ( fXsiTypeValidator != null ) {
>                   dv = fXsiTypeValidator;
>                   fXsiTypeValidator = null;
>                }
>
>                if (dv == null) {
>                   System.out.println("Internal Error: this element have a
simpletype "+
>                                      "but no datatypevalidator was found,
element "+fTempElementDecl.name
>                                      +",locapart:
"+fStringPool.toString(fTempElementDecl.name.localpart));
>                } else {
>                   dv.validate(fDatatypeBuffer.toString(), null);
>                }
>
>             } catch (InvalidDatatypeValueException idve) {
>                fErrorReporter.reportError(fErrorReporter.getLocator(),
>
SchemaMessageProvider.SCHEMA_DOMAIN,
>
SchemaMessageProvider.DatatypeError,
>                                           SchemaMessageProvider.MSG_NONE,
>                                           new Object [] { "In element
'"+fStringPool.toString(elementType)+"' : "+idve.getMessage()},
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>             }
>          }
>       } else {
>          fErrorReporter.reportError(fErrorReporter.getLocator(),
>
ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
>                                     ImplementationMessages.VAL_CST,
>                                     0,
>                                     null,
>
XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
>       }
>
>       // We succeeded
>       return -1;
>
>    } // checkContent(int,int,int[]):int
>
>
>    /**
>     * Checks that all declared elements refer to declared elements
>     * in their content models. This method calls out to the error
>     * handler to indicate warnings.
>     */
>    /*private void checkDeclaredElements() throws Exception {
>
>                file://****DEBUG****
>                if (DEBUG) print("(???)
XMLValidator.checkDeclaredElements\n");
>                file://****DEBUG****
>
>        for (int i = 0; i < fElementCount; i++) {
>            int type = fGrammar.getContentSpecType(i);
>            if (type == XMLElementDecl.TYPE_MIXED || type ==
XMLElementDecl.TYPE_CHILDREN) {
>                int chunk = i >> CHUNK_SHIFT;
>                int index = i &  CHUNK_MASK;
>                int contentSpecIndex = fContentSpec[chunk][index];
>                checkDeclaredElements(i, contentSpecIndex);
>            }
>        }
>    }
>    */
>
>    private void printChildren() {
>       if (DEBUG_ELEMENT_CHILDREN) {
>          System.out.print('[');
>          for (int i = 0; i < fElementChildrenLength; i++) {
>             System.out.print(' ');
>             QName qname = fElementChildren[i];
>             if (qname != null) {
>                System.out.print(fStringPool.toString(qname.rawname));
>             } else {
>                System.out.print("null");
>             }
>             if (i < fElementChildrenLength - 1) {
>                System.out.print(", ");
>             }
>             System.out.flush();
>          }
>          System.out.print(" ]");
>          System.out.println();
>       }
>    }
>
>    private void printStack() {
>       if (DEBUG_ELEMENT_CHILDREN) {
>          System.out.print('{');
>          for (int i = 0; i <= fElementDepth; i++) {
>             System.out.print(' ');
>             System.out.print(fElementChildrenOffsetStack[i]);
>             if (i < fElementDepth) {
>                System.out.print(", ");
>             }
>             System.out.flush();
>          }
>          System.out.print(" }");
>          System.out.println();
>       }
>    }
>
>
>    //
>    // Interfaces
>    //
>
>    /**
>     * AttributeValidator.
>     */
>    public interface AttributeValidator {
>
>       //
>       // AttributeValidator methods
>       //
>
>       /** Normalize. */
>       public int normalize(QName element, QName attribute,
>                            int attValue, int attType, int enumHandle)
>       throws Exception;
>
>    } // interface AttributeValidator
>
>
>    /** Returns true if invalid standalone attribute definition. */
>    boolean invalidStandaloneAttDef(QName element, QName attribute) {
>       if (fStandaloneReader == -1) {
>          return false;
>       }
>       // we are normalizing a default att value...  this ok?
>       if (element.rawname == -1) {
>          return false;
>       }
>       return getAttDefIsExternal(element, attribute);
>    }
>
>
>    //
>    // Classes
>    //
>
>
>    /**
>     * AttValidatorNOTATION.
>     */
>    final class AttValidatorNOTATION
>    implements AttributeValidator {
>
>       //
>       // AttributeValidator methods
>       //
>
>       /** Normalize. */
>       public int normalize(QName element, QName attribute,
>                            int attValueHandle, int attType,
>                            int enumHandle) throws Exception {
>          //
>          // Normalize attribute based upon attribute type...
>          //
>          String attValue = fStringPool.toString(attValueHandle);
>          String newAttValue = attValue.trim();
>          if (fValidating) {
>             // REVISIT - can we release the old string?
>             if (newAttValue != attValue) {
>                if (invalidStandaloneAttDef(element, attribute)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attribute.rawname), attValue, newAttValue);
>                }
>                attValueHandle = fStringPool.addSymbol(newAttValue);
>             } else {
>                attValueHandle = fStringPool.addSymbol(attValueHandle);
>             }
>             //
>             // NOTATION - check that the value is in the AttDef
enumeration (V_TAGo)
>             //
>             if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
>
XMLMessages.VC_NOTATION_ATTRIBUTES,
>
fStringPool.toString(attribute.rawname),
>                                          newAttValue,
fStringPool.stringListAsString(enumHandle));
>             }
>          } else if (newAttValue != attValue) {
>             // REVISIT - can we release the old string?
>             attValueHandle = fStringPool.addSymbol(newAttValue);
>          }
>          return attValueHandle;
>
>       } // normalize(QName,QName,int,int,int):int
>
>       //
>       // Package methods
>       //
>
>       /** Returns true if invalid standalone attribute definition. */
>       boolean invalidStandaloneAttDef(QName element, QName attribute) {
>          if (fStandaloneReader == -1) {
>             return false;
>          }
>          // we are normalizing a default att value...  this ok?
>          if (element.rawname == -1) {
>             return false;
>          }
>          return getAttDefIsExternal(element, attribute);
>       }
>
>    } // class AttValidatorNOTATION
>
>    /**
>     * AttValidatorENUMERATION.
>     */
>    final class AttValidatorENUMERATION
>    implements AttributeValidator {
>
>       //
>       // AttributeValidator methods
>       //
>
>       /** Normalize. */
>       public int normalize(QName element, QName attribute,
>                            int attValueHandle, int attType,
>                            int enumHandle) throws Exception {
>          //
>          // Normalize attribute based upon attribute type...
>          //
>          String attValue = fStringPool.toString(attValueHandle);
>          String newAttValue = attValue.trim();
>          if (fValidating) {
>             // REVISIT - can we release the old string?
>             if (newAttValue != attValue) {
>                if (invalidStandaloneAttDef(element, attribute)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZAT
ION_WHEN_STANDALONE,
>
XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
>
fStringPool.toString(attribute.rawname), attValue, newAttValue);
>                }
>                attValueHandle = fStringPool.addSymbol(newAttValue);
>             } else {
>                attValueHandle = fStringPool.addSymbol(attValueHandle);
>             }
>             //
>             // ENUMERATION - check that value is in the AttDef enumeration
(V_TAG9)
>             //
>             if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
>
reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
>                                          XMLMessages.VC_ENUMERATION,
>
fStringPool.toString(attribute.rawname),
>                                          newAttValue,
fStringPool.stringListAsString(enumHandle));
>             }
>          } else if (newAttValue != attValue) {
>             // REVISIT - can we release the old string?
>             attValueHandle = fStringPool.addSymbol(newAttValue);
>          }
>          return attValueHandle;
>
>       } // normalize(QName,QName,int,int,int):int
>
>       //
>       // Package methods
>       //
>
>       /** Returns true if invalid standalone attribute definition. */
>       boolean invalidStandaloneAttDef(QName element, QName attribute) {
>          if (fStandaloneReader == -1) {
>             return false;
>          }
>          // we are normalizing a default att value...  this ok?
>          if (element.rawname == -1) {
>             return false;
>          }
>          return getAttDefIsExternal(element, attribute);
>       }
>
>    } // class AttValidatorENUMERATION
>
> } // class XMLValidator
>


----------------------------------------------------------------------------
----


>
> /*
>  * The Apache Software License, Version 1.1
>  *
>  *
>  * Copyright (c) 2000 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution,
>  *    if any, must include the following acknowledgment:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowledgment may appear in the software itself,
>  *    if and wherever such third-party acknowledgments normally appear.
>  *
>  * 4. The names "Xerces" and "Apache Software Foundation" must
>  *    not be used to endorse or promote products derived from this
>  *    software without prior written permission. For written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache",
>  *    nor may "Apache" appear in their name, without prior written
>  *    permission of the Apache Software Foundation.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation and was
>  * originally based on software copyright (c) 1999, International
>  * Business Machines, Inc., http://www.apache.org.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
> package org.apache.xerces.validators.schema;
>
> import  org.apache.xerces.framework.XMLErrorReporter;
> import  org.apache.xerces.validators.common.Grammar;
> import  org.apache.xerces.validators.common.GrammarResolver;
> import  org.apache.xerces.validators.common.GrammarResolverImpl;
> import  org.apache.xerces.validators.common.XMLElementDecl;
> import  org.apache.xerces.validators.common.XMLAttributeDecl;
> import  org.apache.xerces.validators.schema.SchemaSymbols;
> import  org.apache.xerces.validators.schema.XUtil;
> import  org.apache.xerces.validators.datatype.DatatypeValidator;
> import
org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
> import
org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
> import  org.apache.xerces.utils.StringPool;
> import  org.w3c.dom.Element;
>
> file://REVISIT: for now, import everything in the DOM package
> import  org.w3c.dom.*;
> import java.util.*;
> import java.net.URL;
> import java.net.MalformedURLException;
>
> file://Unit Test
> import  org.apache.xerces.parsers.DOMParser;
> import  org.apache.xerces.validators.common.XMLValidator;
> import  org.apache.xerces.validators.datatype.DatatypeValidator.*;
> import
org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
> import  org.apache.xerces.framework.XMLContentSpec;
> import  org.apache.xerces.utils.QName;
> import  org.apache.xerces.utils.NamespacesScope;
> import  org.apache.xerces.parsers.SAXParser;
> import  org.apache.xerces.framework.XMLParser;
> import  org.apache.xerces.framework.XMLDocumentScanner;
>
> import  org.xml.sax.InputSource;
> import  org.xml.sax.SAXParseException;
> import  org.xml.sax.EntityResolver;
> import  org.xml.sax.ErrorHandler;
> import  org.xml.sax.SAXException;
> import  java.io.IOException;
> import  org.w3c.dom.Document;
> import  org.apache.xml.serialize.OutputFormat;
> import  org.apache.xml.serialize.XMLSerializer;
> import  org.apache.xerces.validators.schema.SchemaSymbols;
>
>
>
>
> /**
>  * Instances of this class get delegated to Traverse the Schema and
>  * to populate the Grammar internal representation by
>  * instances of Grammar objects.
>  * Traverse a Schema Grammar:
>      * As of April 07, 2000 the following is the
>      * XML Representation of Schemas and Schema components,
>      * Chapter 4 of W3C Working Draft.
>      * <schema
>      *   attributeFormDefault = qualified | unqualified
>      *   blockDefault = #all or (possibly empty) subset of {equivClass,
extension, restriction}
>      *   elementFormDefault = qualified | unqualified
>      *   finalDefault = #all or (possibly empty) subset of {extension,
restriction}
>      *   id = ID
>      *   targetNamespace = uriReference
>      *   version = string>
>      *   Content: ((include | import | annotation)* , ((simpleType |
complexType | element | group | attribute | attributeGroup | notation) ,
annotation*)+)
>      * </schema>
>      *
>      *
>      * <attribute
>      *   form = qualified | unqualified
>      *   id = ID
>      *   name = NCName
>      *   ref = QName
>      *   type = QName
>      *   use = default | fixed | optional | prohibited | required
>      *   value = string>
>      *   Content: (annotation? , simpleType?)
>      * </>
>      *
>      * <element
>      *   abstract = boolean
>      *   block = #all or (possibly empty) subset of {equivClass,
extension, restriction}
>      *   default = string
>      *   equivClass = QName
>      *   final = #all or (possibly empty) subset of {extension,
restriction}
>      *   fixed = string
>      *   form = qualified | unqualified
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger
>      *   name = NCName
>      *   nullable = boolean
>      *   ref = QName
>      *   type = QName>
>      *   Content: (annotation? , (simpleType | complexType)? , (unique |
key | keyref)*)
>      * </>
>      *
>      *
>      * <complexType
>      *   abstract = boolean
>      *   base = QName
>      *   block = #all or (possibly empty) subset of {extension,
restriction}
>      *   content = elementOnly | empty | mixed | textOnly
>      *   derivedBy = extension | restriction
>      *   final = #all or (possibly empty) subset of {extension,
restriction}
>      *   id = ID
>      *   name = NCName>
>      *   Content: (annotation? , (((minExclusive | minInclusive |
maxExclusive | maxInclusive | precision | scale | length | minLength |
maxLength | encoding | period | duration | enumeration | pattern)* |
(element | group | all | choice | sequence | any)*) , ((attribute |
attributeGroup)* , anyAttribute?)))
>      * </>
>      *
>      *
>      * <attributeGroup
>      *   id = ID
>      *   name = NCName
>      *   ref = QName>
>      *   Content: (annotation?, (attribute|attributeGroup), anyAttribute?)
>      * </>
>      *
>      * <anyAttribute
>      *   id = ID
>      *   namespace = ##any | ##other | ##local | list of {uri,
##targetNamespace}>
>      *   Content: (annotation?)
>      * </anyAttribute>
>      *
>      * <group
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger
>      *   name = NCName
>      *   ref = QName>
>      *   Content: (annotation? , (element | group | all | choice |
sequence | any)*)
>      * </>
>      *
>      * <all
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger>
>      *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>      * </all>
>      *
>      * <choice
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger>
>      *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>      * </choice>
>      *
>      * <sequence
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger>
>      *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>      * </sequence>
>      *
>      *
>      * <any
>      *   id = ID
>      *   maxOccurs = string
>      *   minOccurs = nonNegativeInteger
>      *   namespace = ##any | ##other | ##local | list of {uri,
##targetNamespace}
>      *   processContents = lax | skip | strict>
>      *   Content: (annotation?)
>      * </any>
>      *
>      * <unique
>      *   id = ID
>      *   name = NCName>
>      *   Content: (annotation? , (selector , field+))
>      * </unique>
>      *
>      * <key
>      *   id = ID
>      *   name = NCName>
>      *   Content: (annotation? , (selector , field+))
>      * </key>
>      *
>      * <keyref
>      *   id = ID
>      *   name = NCName
>      *   refer = QName>
>      *   Content: (annotation? , (selector , field+))
>      * </keyref>
>      *
>      * <selector>
>      *   Content: XPathExprApprox : An XPath expression
>      * </selector>
>      *
>      * <field>
>      *   Content: XPathExprApprox : An XPath expression
>      * </field>
>      *
>      *
>      * <notation
>      *   id = ID
>      *   name = NCName
>      *   public = A public identifier, per ISO 8879
>      *   system = uriReference>
>      *   Content: (annotation?)
>      * </notation>
>      *
>      * <annotation>
>      *   Content: (appinfo | documentation)*
>      * </annotation>
>      *
>      * <include
>      *   id = ID
>      *   schemaLocation = uriReference>
>      *   Content: (annotation?)
>      * </include>
>      *
>      * <import
>      *   id = ID
>      *   namespace = uriReference
>      *   schemaLocation = uriReference>
>      *   Content: (annotation?)
>      * </import>
>      *
>      * <simpleType
>      *   abstract = boolean
>      *   base = QName
>      *   derivedBy = | list | restriction  : restriction
>      *   id = ID
>      *   name = NCName>
>      *   Content: ( annotation? , ( minExclusive | minInclusive |
maxExclusive | maxInclusive | precision | scale | length | minLength |
maxLength | encoding | period | duration | enumeration | pattern )* )
>      * </simpleType>
>      *
>      * <length
>      *   id = ID
>      *   value = nonNegativeInteger>
>      *   Content: ( annotation? )
>      * </length>
>      *
>      * <minLength
>      *   id = ID
>      *   value = nonNegativeInteger>
>      *   Content: ( annotation? )
>      * </minLength>
>      *
>      * <maxLength
>      *   id = ID
>      *   value = nonNegativeInteger>
>      *   Content: ( annotation? )
>      * </maxLength>
>      *
>      *
>      * <pattern
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </pattern>
>      *
>      *
>      * <enumeration
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </enumeration>
>      *
>      * <maxInclusive
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </maxInclusive>
>      *
>      * <maxExclusive
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </maxExclusive>
>      *
>      * <minInclusive
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </minInclusive>
>      *
>      *
>      * <minExclusive
>      *   id = ID
>      *   value = string>
>      *   Content: ( annotation? )
>      * </minExclusive>
>      *
>      * <precision
>      *   id = ID
>      *   value = nonNegativeInteger>
>      *   Content: ( annotation? )
>      * </precision>
>      *
>      * <scale
>      *   id = ID
>      *   value = nonNegativeInteger>
>      *   Content: ( annotation? )
>      * </scale>
>      *
>      * <encoding
>      *   id = ID
>      *   value = | hex | base64 >
>      *   Content: ( annotation? )
>      * </encoding>
>      *
>      *
>      * <duration
>      *   id = ID
>      *   value = timeDuration>
>      *   Content: ( annotation? )
>      * </duration>
>      *
>      * <period
>      *   id = ID
>      *   value = timeDuration>
>      *   Content: ( annotation? )
>      * </period>
>      *
>  *
>  * @author Eric Ye, Jeffrey Rodriguez, Andy Clark
>  *
>  * @see                  org.apache.xerces.validators.common.Grammar
>  *
>  * @version $Id: TraverseSchema.java,v 1.54 2000/10/18 18:27:14 ericye Exp
$
>  */
>
> public class TraverseSchema implements
>                             NamespacesScope.NamespacesHandler{
>
>
>     file://CONSTANTS
>     private static final int TOP_LEVEL_SCOPE = -1;
>
>     file://debuggin
>     private static boolean DEBUGGING = false;
>
>     file://private data members
>
>
>     private XMLErrorReporter    fErrorReporter = null;
>     private StringPool          fStringPool    = null;
>
>     private GrammarResolver fGrammarResolver = null;
>     private SchemaGrammar fSchemaGrammar = null;
>
>     private Element fSchemaRootElement;
>
>     private DatatypeValidatorFactoryImpl fDatatypeRegistry =
>
DatatypeValidatorFactoryImpl.getDatatypeRegistry();
>
>     private Hashtable fComplexTypeRegistry = new Hashtable();
>     private Hashtable fAttributeDeclRegistry = new Hashtable();
>
>     private Vector fIncludeLocations = new Vector();
>     private Vector fImportLocations = new Vector();
>
>
>     private int fAnonTypeCount =0;
>     private int fScopeCount=0;
>     private int fCurrentScope=TOP_LEVEL_SCOPE;
>     private int fSimpleTypeAnonCount = 0;
>     private Stack fCurrentTypeNameStack = new Stack();
>     private Hashtable fElementRecurseComplex = new Hashtable();
>
>     private boolean fElementDefaultQualified = false;
>     private boolean fAttributeDefaultQualified = false;
>
>     private int fTargetNSURI;
>     private String fTargetNSURIString = "";
>     private NamespacesScope fNamespacesScope = null;
>     private String fCurrentSchemaURL = "";
>
>     private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
>     private XMLElementDecl fTempElementDecl = new XMLElementDecl();
>
>     private EntityResolver fEntityResolver = null;
>
>    // REVISIT: maybe need to be moved into SchemaGrammar class
>     public class ComplexTypeInfo {
>         public String typeName;
>
>         public DatatypeValidator baseDataTypeValidator;
>         public ComplexTypeInfo baseComplexTypeInfo;
>
>         public int derivedBy = 0;
>         public int blockSet = 0;
>         public int finalSet = 0;
>
>         public boolean isAbstract = false;
>
>         public int scopeDefined = -1;
>
>         public int contentType;
>         public int contentSpecHandle = -1;
>         public int templateElementIndex = -1;
>         public int attlistHead = -1;
>         public DatatypeValidator datatypeValidator;
>     }
>
>
>     file://REVISIT: verify the URI.
>     public final static String SchemaForSchemaURI =
"http://www.w3.org/TR-1/Schema";
>
>     private TraverseSchema( ) {
>         // new TraverseSchema() is forbidden;
>     }
>
>
>     public void setGrammarResolver(GrammarResolver grammarResolver){
>         fGrammarResolver = grammarResolver;
>     }
>     public void startNamespaceDeclScope(int prefix, int uri){
>         file://TO DO
>     }
>     public void endNamespaceDeclScope(int prefix){
>         file://TO DO, do we need to do anything here?
>     }
>
>
>
>     private String resolvePrefixToURI (String prefix) throws Exception  {
>         String uriStr =
fStringPool.toString(fNamespacesScope.getNamespaceForPrefix(fStringPool.addS
ymbol(prefix)));
>         if (uriStr == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError("prefix : [" + prefix +"] can not be
resolved to a URI");
>             return "";
>         }
>
>         file://REVISIT, !!!! a hack: needs to be updated later, cause now
we only use localpart to key build-in datatype.
>         if ( prefix.length()==0 &&
uriStr.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
>              && fTargetNSURIString.length() == 0) {
>             uriStr = "";
>         }
>
>         return uriStr;
>     }
>
>     public  TraverseSchema(Element root, StringPool stringPool,
>                            SchemaGrammar schemaGrammar,
>                            GrammarResolver grammarResolver,
>                            XMLErrorReporter errorReporter,
>                            String schemaURL,
>    EntityResolver entityResolver
>                            ) throws Exception {
>         fErrorReporter = errorReporter;
>         fCurrentSchemaURL = schemaURL;
> fEntityResolver = entityResolver;
>         doTraverseSchema(root, stringPool, schemaGrammar,
grammarResolver);
>     }
>
>     public  TraverseSchema(Element root, StringPool stringPool,
>                            SchemaGrammar schemaGrammar,
>                            GrammarResolver grammarResolver,
>                            XMLErrorReporter errorReporter,
>                            String schemaURL
>                            ) throws Exception {
>         fErrorReporter = errorReporter;
>         fCurrentSchemaURL = schemaURL;
>         doTraverseSchema(root, stringPool, schemaGrammar,
grammarResolver);
>     }
>
>     public  TraverseSchema(Element root, StringPool stringPool,
>                            SchemaGrammar schemaGrammar,
>                            GrammarResolver grammarResolver
>                            ) throws Exception {
>         doTraverseSchema(root, stringPool, schemaGrammar,
grammarResolver);
>     }
>
>     public  void doTraverseSchema(Element root, StringPool stringPool,
>                            SchemaGrammar schemaGrammar,
>                            GrammarResolver grammarResolver) throws
Exception {
>
>         fNamespacesScope = new NamespacesScope(this);
>
>         fSchemaRootElement = root;
>         fStringPool = stringPool;
>         fSchemaGrammar = schemaGrammar;
>         fGrammarResolver = grammarResolver;
>
>         if (root == null)

>             // REVISIT: Anything to do?
>             return;
>         }
>
>         file://Make sure namespace binding is defaulted
>         String rootPrefix = root.getPrefix();
>         if( rootPrefix == null || rootPrefix.length() == 0 ){
>             String xmlns = root.getAttribute("xmlns");
>             if( xmlns.length() == 0 )
>                 root.setAttribute("xmlns",
SchemaSymbols.URI_SCHEMAFORSCHEMA );
>         }
>
>         file://Retrieve the targetnamespace URI information
>         fTargetNSURIString =
root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
>         if (fTargetNSURIString==null) {
>             fTargetNSURIString="";
>         }
>         fTargetNSURI = fStringPool.addSymbol(fTargetNSURIString);
>
>         if (fGrammarResolver == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError("Internal error: don't have a
GrammarResolver for TraverseSchema");
>         }
>         else{
>             // for complex type registry, attribute decl registry and
>             // namespace mapping, needs to check whether the passed in
>             // Grammar was a newly instantiated one.
>             if (fSchemaGrammar.getComplexTypeRegistry() == null ) {
>
fSchemaGrammar.setComplexTypeRegistry(fComplexTypeRegistry);
>             }
>             else {
>                 fComplexTypeRegistry =
fSchemaGrammar.getComplexTypeRegistry();
>             }
>
>             if (fSchemaGrammar.getAttirubteDeclRegistry() == null ) {
>
fSchemaGrammar.setAttributeDeclRegistry(fAttributeDeclRegistry);
>             }
>             else {
>                 fAttributeDeclRegistry =
fSchemaGrammar.getAttirubteDeclRegistry();
>             }
>
>             if (fSchemaGrammar.getNamespacesScope() == null ) {
>                 fSchemaGrammar.setNamespacesScope(fNamespacesScope);
>             }
>             else {
>                 fNamespacesScope = fSchemaGrammar.getNamespacesScope();
>             }
>
>             fSchemaGrammar.setDatatypeRegistry(fDatatypeRegistry);
>             fSchemaGrammar.setTargetNamespaceURI(fTargetNSURIString);
>             fGrammarResolver.putGrammar(fTargetNSURIString,
fSchemaGrammar);
>         }
>
>
>
>         // Retrived the Namespace mapping from the schema element.
>         NamedNodeMap schemaEltAttrs = root.getAttributes();
>         int i = 0;
>         Attr sattr = null;
>
>         boolean seenXMLNS = false;
>         while ((sattr = (Attr)schemaEltAttrs.item(i++)) != null) {
>             String attName = sattr.getName();
>             if (attName.startsWith("xmlns:")) {
>                 String attValue = sattr.getValue();
>                 String prefix = attName.substring(attName.indexOf(":")+1);
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
>
fStringPool.addSymbol(attValue) );
>             }
>             if (attName.equals("xmlns")) {
>
>                 String attValue = sattr.getValue();
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
>
fStringPool.addSymbol(attValue) );
>                 seenXMLNS = true;
>             }
>
>         }
>         if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
>
fStringPool.addSymbol("") );
>         }
>
>         fElementDefaultQualified =
>
root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols
.ATTVAL_QUALIFIED);
>         fAttributeDefaultQualified =
>
root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbo
ls.ATTVAL_QUALIFIED);
>
>         file://REVISIT, really sticky when noTargetNamesapce, for now, we
assume everyting is in the same name space);
>         if (fTargetNSURI == StringPool.EMPTY_STRING) {
>             fElementDefaultQualified = true;
>             file://fAttributeDefaultQualified = true;
>         }
>
>
>         file://fScopeCount++;
>         fCurrentScope = -1;
>
>
>         checkTopLevelDuplicateNames(root);
>
>         file://extract all top-level attribute, attributeGroup, and group
Decls and put them in the 3 hasn table in the SchemaGrammar.
>         extractTopLevel3Components(root);
>
>         for (Element child = XUtil.getFirstChildElement(root); child !=
null;
>             child = XUtil.getNextSiblingElement(child)) {
>
>             String name = child.getNodeName();
>
>             if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
>                 traverseAnnotationDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
>                 traverseSimpleTypeDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
>                 traverseComplexTypeDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_ELEMENT ))

>                 traverseElementDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
>                 file://traverseAttributeGroupDecl(child);
>             } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
>                 traverseAttributeDecl( child, null );
>             } else if (name.equals(SchemaSymbols.ELT_GROUP) &&
child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
>                 file://traverseGroupDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
>                 ; file://TO DO
>             }
>             else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
>                 traverseInclude(child);
>             }
>             else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
>                 traverseImport(child);
>             }
>         } // for each child node
>
>     } // traverseSchema(Element)
>
>     private void checkTopLevelDuplicateNames(Element root) {
>         file://TO DO : !!!
>     }
>
>     private void extractTopLevel3Components(Element root){
>
>         for (Element child = XUtil.getFirstChildElement(root); child !=
null;
>             child = XUtil.getNextSiblingElement(child)) {
>
>             String name = child.getNodeName();
>
>             if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
>                 fSchemaGrammar.topLevelAttrGrpDecls.put(name, child);
>             } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
>                 fSchemaGrammar.topLevelAttrDecls.put(name, child);
>             } else if (name.equals(SchemaSymbols.ELT_GROUP) &&
child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
>                 fSchemaGrammar.topLevelGroupDecls.put(name, child);
>             }
>         } // for each child node
>     }
>
>     /**
>      * Expands a system id and returns the system id as a URL, if
>      * it can be expanded. A return value of null means that the
>      * identifier is already expanded. An exception thrown
>      * indicates a failure to expand the id.
>      *
>      * @param systemId The systemId to be expanded.
>      *
>      * @return Returns the URL object representing the expanded system
>      *         identifier. A null value indicates that the given
>      *         system identifier is already expanded.
>      *
>      */
>     private String expandSystemId(String systemId, String currentSystemId)
throws Exception{
>      String id = systemId;
>
>      // check for bad parameters id
>      if (id == null || id.length() == 0) {
>          return systemId;
>      }
>
>      // if id already expanded, return
>      try {
>          URL url = new URL(id);
>          if (url != null) {
>              return systemId;
>          }
>      }
>      catch (MalformedURLException e) {
>          // continue on...
>      }
>
>      // normalize id
>      id = fixURI(id);
>
>      // normalize base
>      URL base = null;
>      URL url = null;
>      try {
>          if (currentSystemId == null) {
>              String dir;
>              try {
>                  dir = fixURI(System.getProperty("user.dir"));
>              }
>              catch (SecurityException se) {
>                  dir = "";
>              }
>              if (!dir.endsWith("/")) {
>                  dir = dir + "/";
>              }
>              base = new URL("file", "", dir);
>          }
>          else {
>              base = new URL(currentSystemId);
>          }
>
>          // expand id
>          url = new URL(base, id);
>      }
>      catch (Exception e) {
>          // let it go through
>      }
>      if (url == null) {
>          return systemId;
>      }
>      return url.toString();
>     }
>     /**
>      * Fixes a platform dependent filename to standard URI form.
>      *
>      * @param str The string to fix.
>      *
>      * @return Returns the fixed URI string.
>      */
>     private static String fixURI(String str) {
>
>         // handle platform dependent strings
>         str = str.replace(java.io.File.separatorChar, '/');
>
>         // Windows fix
>         if (str.length() >= 2) {
>             char ch1 = str.charAt(1);
>             if (ch1 == ':') {
>                 char ch0 = Character.toUpperCase(str.charAt(0));
>                 if (ch0 >= 'A' && ch0 <= 'Z') {
>                     str = "/" + str;
>                 }
>             }
>         }
>
>         // done
>         return str;
>     }
>
>
>     private void traverseInclude(Element includeDecl) throws Exception {
>
>         file://TO DO: !!!!! location needs to be resolved first.
>
>
> String location =
includeDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
>
>          // expand it before passing it to the parser
>          InputSource source = null;
>          if (fEntityResolver != null) {
>             source = fEntityResolver.resolveEntity("", location);
>          }
>          if (source == null) {
>             location = expandSystemId(location, fCurrentSchemaURL);
>             source = new InputSource(location);
>          }
>          else {
>          // create a string for uniqueness of this included schema in
fIncludeLocations
>          if (source.getPublicId () != null)
>          location = source.getPublicId ();
>
>          location += (',' + source.getSystemId ());
>          }
>
>         if (fIncludeLocations.contains((Object)location)) {
>             return;
>         }
>         fIncludeLocations.addElement((Object)location);
>
>         DOMParser parser = new DOMParser() {
>             public void ignorableWhitespace(char ch[], int start, int
length) {}
>             public void ignorableWhitespace(int dataIdx) {}
>         };
>         parser.setEntityResolver( new Resolver() );
>         parser.setErrorHandler(  new ErrorHandler() );
>
>         try {
>             parser.setFeature("http://xml.org/sax/features/validation",
false);
>             parser.setFeature("http://xml.org/sax/features/namespaces",
true);
>
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
false);
>         }catch(  org.xml.sax.SAXNotRecognizedException e ) {
>             e.printStackTrace();
>         }catch( org.xml.sax.SAXNotSupportedException e ) {
>             e.printStackTrace();
>         }
>
>         try {
>             parser.parse( source );
>         }catch( IOException e ) {
>             e.printStackTrace();
>         }catch( SAXException e ) {
>             file://e.printStackTrace();
>         }
>
>         Document     document   = parser.getDocument(); file://Our Grammar
>         Element root = null;
>         if (document != null) {
>             root = document.getDocumentElement();
>         }
>
>         if (root != null) {
>             String targetNSURI =
root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
>             if (targetNSURI.length() > 0 &&
!targetNSURI.equals(fTargetNSURIString) ) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("included schema '"+location+"'
has a different targetNameSpace '"
>                                          +targetNSURI+"'");
>             }
>             else {
>                 boolean saveElementDefaultQualified =
fElementDefaultQualified;
>                 boolean saveAttributeDefaultQualified =
fAttributeDefaultQualified;
>                 int saveScope = fCurrentScope;
>                 String savedSchemaURL = fCurrentSchemaURL;
>                 Element saveRoot = fSchemaRootElement;
>                 fSchemaRootElement = root;
>                 fCurrentSchemaURL = location;
>                 traverseIncludedSchema(root);
>                 fCurrentSchemaURL = savedSchemaURL;
>                 fCurrentScope = saveScope;
>                 fElementDefaultQualified = saveElementDefaultQualified;
>                 fAttributeDefaultQualified =
saveAttributeDefaultQualified;
>                 fSchemaRootElement = saveRoot;
>             }
>
>         }
>
>     }
>
>     private void traverseIncludedSchema(Element root) throws Exception {
>         // Retrived the Namespace mapping from the schema element.
>         NamedNodeMap schemaEltAttrs = root.getAttributes();
>         int i = 0;
>         Attr sattr = null;
>
>         boolean seenXMLNS = false;
>         while ((sattr = (Attr)schemaEltAttrs.item(i++)) != null) {
>             String attName = sattr.getName();
>             if (attName.startsWith("xmlns:")) {
>                 String attValue = sattr.getValue();
>                 String prefix = attName.substring(attName.indexOf(":")+1);
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
>
fStringPool.addSymbol(attValue) );
>             }
>             if (attName.equals("xmlns")) {
>
>                 String attValue = sattr.getValue();
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
>
fStringPool.addSymbol(attValue) );
>                 seenXMLNS = true;
>             }
>
>         }
>         if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
>
NamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
>
fStringPool.addSymbol("") );
>         }
>
>         fElementDefaultQualified =
>
root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols
.ATTVAL_QUALIFIED);
>         fAttributeDefaultQualified =
>
root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbo
ls.ATTVAL_QUALIFIED);
>
>         file://REVISIT, really sticky when noTargetNamesapce, for now, we
assume everyting is in the same name space);
>         if (fTargetNSURI == StringPool.EMPTY_STRING) {
>             fElementDefaultQualified = true;
>             file://fAttributeDefaultQualified = true;
>         }
>
>         file://fScopeCount++;
>         fCurrentScope = -1;
>
>
>         checkTopLevelDuplicateNames(root);
>
>         file://extract all top-level attribute, attributeGroup, and group
Decls and put them in the 3 hasn table in the SchemaGrammar.
>         extractTopLevel3Components(root);
>
>         for (Element child = XUtil.getFirstChildElement(root); child !=
null;
>             child = XUtil.getNextSiblingElement(child)) {
>
>             String name = child.getNodeName();
>
>             if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
>                 traverseAnnotationDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
>                 traverseSimpleTypeDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
>                 traverseComplexTypeDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_ELEMENT ))

>                 traverseElementDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
>                 file://traverseAttributeGroupDecl(child);
>             } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
>                 traverseAttributeDecl( child, null );
>             } else if (name.equals(SchemaSymbols.ELT_GROUP) &&
child.getAttribute(SchemaSymbols.ATT_REF).equals("")) {
>                 file://traverseGroupDecl(child);
>             } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
>                 ; file://TO DO
>             }
>             else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
>                 traverseInclude(child);
>             }
>             else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
>                 traverseImport(child);
>             }
>         } // for each child node
>
>     }
>
>     private void traverseImport(Element importDecl)  throws Exception {
>   String location =
importDecl.getAttribute(SchemaSymbols.ATT_SCHEMALOCATION);
>         // expand it before passing it to the parser
>          InputSource source = null;
>          if (fEntityResolver != null) {
>             source = fEntityResolver.resolveEntity("", location);
>          }
>          if (source == null) {
>             location = expandSystemId(location, fCurrentSchemaURL);
>             source = new InputSource(location);
>          }
>          else {
>          // create a string for uniqueness of this imported schema in
fImportLocations
>          if (source.getPublicId () != null)
>          location = source.getPublicId ();
>
>          location += (',' + source.getSystemId ());
>          }
>
>          if (fImportLocations.contains((Object)location)) {
>             return;
>         }
>         fImportLocations.addElement((Object)location);
>
>   String namespaceString =
importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
> SchemaGrammar importedGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(namespaceString);
>
> if (importedGrammar == null) {
> importedGrammar = new SchemaGrammar();
> }
>
>         DOMParser parser = new DOMParser() {
>             public void ignorableWhitespace(char ch[], int start, int
length) {}
>             public void ignorableWhitespace(int dataIdx) {}
>         };
>         parser.setEntityResolver( new Resolver() );
>         parser.setErrorHandler(  new ErrorHandler() );
>
>         try {
>             parser.setFeature("http://xml.org/sax/features/validation",
false);
>             parser.setFeature("http://xml.org/sax/features/namespaces",
true);
>
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
false);
>         }catch(  org.xml.sax.SAXNotRecognizedException e ) {
>             e.printStackTrace();
>         }catch( org.xml.sax.SAXNotSupportedException e ) {
>             e.printStackTrace();
>         }
>
>         try {
>             parser.parse( source );
>         }catch( IOException e ) {
>             e.printStackTrace();
>         }catch( SAXException e ) {
>             e.printStackTrace();
>         }
>
>         Document     document   = parser.getDocument(); file://Our Grammar
>         Element root = null;
>         if (document != null) {
>             root = document.getDocumentElement();
>         }
>
>         if (root != null) {
>             String targetNSURI =
root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE);
>             if (!targetNSURI.equals(namespaceString) ) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("imported schema '"+location+"'
has a different targetNameSpace '"
>                                          +targetNSURI+"' from what is
declared '"+namespaceString+"'.");
>             }
>             else
>                 new TraverseSchema(root, fStringPool, importedGrammar,
fGrammarResolver, fErrorReporter, location);
>         }
>         else {
>             reportGenericSchemaError("Could not get the doc root for
imported Schema file: "+location);
>         }
>     }
>
> /**
>      * No-op - Traverse Annotation Declaration
>      *
>      * @param comment
>      */
>     private void traverseAnnotationDecl(Element comment) {
>         file://TO DO
>         return ;
>     }
>
>     /**
>      * Traverse SimpleType declaration:
>      * <simpleType
>      *         abstract = boolean
>      *         base = QName
>      *         derivedBy = | list | restriction  : restriction
>      *         id = ID
>      *         name = NCName>
>      *         Content: ( annotation? , ( minExclusive | minInclusive |
maxExclusive | maxInclusive | precision | scale | length | minLength |
maxLength | encoding | period | duration | enumeration | pattern )* )
>      *       </simpleType>
>      *
>      * @param simpleTypeDecl
>      * @return
>      */
>     private int traverseSimpleTypeDecl( Element simpleTypeDecl ) throws
Exception {
>
>         String varietyProperty       =
impleTypeDecl.getAttribute( SchemaSymbols.ATT_DERIVEDBY );
>         if (varietyProperty.length() == 0) {
>             varietyProperty = SchemaSymbols.ATTVAL_RESTRICTION;
>         }
>         String nameProperty          =
impleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME );
>         String baseTypeQNameProperty =
impleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE );
>         String abstractProperty      =
impleTypeDecl.getAttribute( SchemaSymbols.ATT_ABSTRACT );
>
>         int     newSimpleTypeName    = -1;
>
>
>         if ( nameProperty.equals("")) { // anonymous simpleType
>             newSimpleTypeName = fStringPool.addSymbol(
>                 "#S#"+fSimpleTypeAnonCount++ );
>
file://"http://www.apache.org/xml/xerces/internalDatatype"+fSimpleTypeAnonCo
unt++ );
>             } else
>             newSimpleTypeName       =
fStringPool.addSymbol( nameProperty );
>
>
>         int               basetype;
>         DatatypeValidator baseValidator = null;
>
>         if( baseTypeQNameProperty!= null ) {
>             basetype      =
fStringPool.addSymbol( baseTypeQNameProperty );
>             String prefix = "";
>             String localpart = baseTypeQNameProperty;
>             int colonptr = baseTypeQNameProperty.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = baseTypeQNameProperty.substring(0,colonptr);
>                 localpart = baseTypeQNameProperty.substring(colonptr+1);
>             }
>             String uri = resolvePrefixToURI(prefix);
>
>             baseValidator = getDatatypeValidator(uri, localpart);
>
>             if (baseValidator == null) {
>                 Element baseTypeNode =
getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
>                 if (baseTypeNode != null) {
>                     traverseSimpleTypeDecl( baseTypeNode );
>
>                     baseValidator = getDatatypeValidator(uri, localpart);
>
>                     if (baseValidator == null) {
>
reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
>                         new Object []
simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE ),
>
simpleTypeDecl.getAttribute(SchemaSymbols.ATT_NAME) });
>                         return -1;
>                         file://reportGenericSchemaError("Base type could
not be found : " + baseTypeQNameProperty);
>                     }
>
>                 }
>                 else {
>
reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
>                     new Object []
simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE ),
>
simpleTypeDecl.getAttribute(SchemaSymbols.ATT_NAME) });
>                     return -1;
>                     file://reportGenericSchemaError("Base type could not
be found : " + baseTypeQNameProperty);
>                 }
>
>             }
>         }
>         // Any Children if so then check Content otherwise bail out
>
>         Element   content   =
XUtil.getFirstChildElement( simpleTypeDecl );
>         int       numFacets = 0;
>         Hashtable facetData = null;
>
>         if( content != null ) {
>
>             file://Content follows: ( annotation? , facets* )
>
>             file://annotation ? ( 0 or 1 )
>



         if( content.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
>                 traverseAnnotationDecl( content );
>                 content                    =
XUtil.getNextSiblingElement(content);
>             }
>
>             file://TODO: If content is annotation again should raise
validation error
>             //
( content.getNodeName().equal( SchemaSymbols.ELT_ANNOTATIO ) {
>             //   throw ValidationException(); }
>             //
>
>             file://facets    * ( 0 or more )
>
>
>             int numEnumerationLiterals = 0;
>             facetData        = new Hashtable();
>             Vector enumData            = new Vector();
>
>             while (content != null) {
>                 if (content.getNodeType() == Node.ELEMENT_NODE) {
>                     Element facetElt = (Element) content;
>                     numFacets++;
>                     if
(facetElt.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION)) {
>                         numEnumerationLiterals++;
>                         String enumVal =
facetElt.getAttribute(SchemaSymbols.ATT_VALUE);
>                         enumData.addElement(enumVal);
>                         file://Enumerations can have annotations ? ( 0 |
1 )
>                         Element enumContent =
Util.getFirstChildElement( facetElt );
>                         if( enumContent != null && enumContent != null &&
enumContent.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
>                             traverseAnnotationDecl( content );
>                          }
>                         file://TODO: If enumContent is encounter  again
should raise validation error
>                         //  enumContent.getNextSibling();
>                         //
( enumContent.getNodeName().equal( SchemaSymbols.ELT_ANNOTATIO ) {
>                         //   throw ValidationException(); }
>                         //
>                     } else {
>
facetData.put(facetElt.getNodeName(),facetElt.getAttribute( SchemaSymbols.AT
T_VALUE ));
>                     }
>                 }
>                 file://content = (Element) content.getNextSibling();
>                 content = XUtil.getNextSiblingElement(content);
>             }
>             if (numEnumerationLiterals > 0) {
>                facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
>             }
>         }
>
>         // create & register validator for "generated" type if it doesn't
exist
>
>         String nameOfType = fStringPool.toString( newSimpleTypeName);
>         if (fTargetNSURIString.length () != 0) {
>             nameOfType = fTargetNSURIString+","+nameOfType;
>         }
>
>
>         try {
>
>            DatatypeValidator newValidator =
>                  fDatatypeRegistry.getDatatypeValidator( nameOfType );
>
>            if( newValidator == null ) { // not previously registered
>                boolean  derivedByList =
>                     varietyProperty.equals( SchemaSymbols.ATTVAL_LIST ) ?
true:false;
>
>                fDatatypeRegistry.createDatatypeValidator( nameOfType,
baseValidator,
>                               facetData, derivedByList );
>
>                }
>
>            } catch (Exception e) {
>                file://e.printStackTrace(System.err);
>                reportSchemaError(SchemaMessageProvider.DatatypeError,new
Object [] { e.getMessage() });
>            }
>         return fStringPool.addSymbol(nameOfType);
>     }
>
>     /*
>     * <any
>     *   id = ID
>     *   maxOccurs = string
>     *   minOccurs = nonNegativeInteger
>     *   namespace = ##any | ##other | ##local | list of {uri,
##targetNamespace}
>     *   processContents = lax | skip | strict>
>     *   Content: (annotation?)
>     * </any>
>     */
>     private int traverseAny(Element child) throws Exception {
>         int anyIndex = -1;
>         String namespace =
child.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
>         String processContents =
child.getAttribute("processContents").trim();
>
>         int processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY;
>         int processContentsAnyOther =
XMLContentSpec.CONTENTSPECNODE_ANY_OTHER;
>         int processContentsAnyLocal =
XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL;
>
>         if (processContents.length() > 0 &&
!processContents.equals("strict")) {
>             if (processContents.equals("lax")) {
>                 processContentsAny =
XMLContentSpec.CONTENTSPECNODE_ANY_LAX;
>                 processContentsAnyOther =
XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX;
>                 processContentsAnyLocal =
XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX;
>             }
>             else if (processContents.equals("skip")) {
>                 processContentsAny =
XMLContentSpec.CONTENTSPECNODE_ANY_SKIP;
>                 processContentsAnyOther =
XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP;
>                 processContentsAnyLocal =
XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP;
>             }
>         }
>
>         if (namespace.length() == 0 || namespace.equals("##any")) {
>             anyIndex =
fSchemaGrammar.addContentSpecNode(processContentsAny, -1, -1, false);
>         }
>         else if (namespace.equals("##other")) {
>             String uri =
child.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace"
);
>             int uriIndex = fStringPool.addSymbol(uri);
>             anyIndex =
fSchemaGrammar.addContentSpecNode(processContentsAnyOther, -1, uriIndex,
false);
>         }
>         else if (namespace.equals("##local")) {
>             anyIndex =
fSchemaGrammar.addContentSpecNode(processContentsAnyLocal, -1, -1, false);
>         }
>         else if (namespace.length() > 0) {
>             StringTokenizer tokenizer = new StringTokenizer(namespace);
>             Vector tokens = new Vector();
>             while (tokenizer.hasMoreElements()) {
>                 String token = tokenizer.nextToken();
>                 if (token.equals("##targetNamespace")) {
>                     token =
child.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace"
);
>                 }
>                 tokens.addElement(token);
>             }
>             String uri = (String)tokens.elementAt(0);
>             int uriIndex = fStringPool.addSymbol(uri);
>             int leafIndex =
fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
>             int valueIndex = leafIndex;
>             int count = tokens.size();
>             if (count > 1) {
>                 uri = (String)tokens.elementAt(1);
>                 uriIndex = fStringPool.addSymbol(uri);
>                 leafIndex =
fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
>                 int otherValueIndex = leafIndex;
>                 int choiceIndex =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE,
valueIndex, otherValueIndex, false);
>                 for (int i = 2; i < count; i++) {
>                     uri = (String)tokens.elementAt(i);
>                     uriIndex = fStringPool.addSymbol(uri);
>                     leafIndex =
fSchemaGrammar.addContentSpecNode(processContentsAny, -1, uriIndex, false);
>                     otherValueIndex = leafIndex;
>                     choiceIndex =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE,
choiceIndex, otherValueIndex, false);
>                 }
>                 anyIndex = choiceIndex;
>             }
>             else {
>                 anyIndex = leafIndex;
>             }
>         }
>         else {
>             // REVISIT: Localize
>             reportGenericSchemaError("Empty namespace attribute for any
element");
>         }
>
>         return anyIndex;
>     }
>
>
>     public DatatypeValidator getDatatypeValidator(String uri, String
localpart) {
>
>         DatatypeValidator dv = null;
>
>         if (uri.length()==0 ||
uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
>             dv = fDatatypeRegistry.getDatatypeValidator( localpart );
>         }
>         else {
>             dv =
fDatatypeRegistry.getDatatypeValidator( uri+","+localpart );
>         }
>
>         return dv;
>     }
>
>     /*
>     * <anyAttribute
>     *   id = ID
>     *   namespace = ##any | ##other | ##local | list of {uri,
##targetNamespace}>
>     *   Content: (annotation?)
>     * </anyAttribute>
>     */
>     private XMLAttributeDecl traverseAnyAttribute(Element
anyAttributeDecl) throws Exception {
>         XMLAttributeDecl anyAttDecl = new XMLAttributeDecl();
>         String processContents =
anyAttributeDecl.getAttribute(SchemaSymbols.ATT_PROCESSCONTENTS).trim();
>         String namespace =
anyAttributeDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
>         String curTargetUri =
anyAttributeDecl.getOwnerDocument().getDocumentElement().getAttribute("targe
tNamespace");
>
>         if ( namespace.length() == 0 ||
namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY) ) {
>             anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_ANY;
>         }
>         else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
>             anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_OTHER;
>             anyAttDecl.name.uri = fStringPool.addSymbol(curTargetUri);
>         }
>         else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
>             anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LOCAL;
>         }
>         else if (namespace.length() > 0){
>             anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LIST;
>
>             StringTokenizer tokenizer = new StringTokenizer(namespace);
>             int aStringList = fStringPool.startStringList();
>             Vector tokens = new Vector();
>             while (tokenizer.hasMoreElements()) {
>                 String token = tokenizer.nextToken();
>                 if (token.equals("##targetNamespace")) {
>                     token = curTargetUri;
>                 }
>                 if (!fStringPool.addStringToList(aStringList,
fStringPool.addSymbol(token))){
>                     reportGenericSchemaError("Internal StringPool error
when reading the "+
>                                              "namespace attribute for
anyattribute declaration");
>                 }
>             }
>             fStringPool.finishStringList(aStringList);
>
>             anyAttDecl.enumeration = aStringList;
>         }
>         else {
>             // REVISIT: Localize
>             reportGenericSchemaError("Empty namespace attribute for
anyattribute declaration");
>         }
>
>         // default processContents is "strict";
>         anyAttDecl.defaultType = XMLAttributeDecl.PROCESSCONTENTS_STRICT;
>
>         if (processContents.equals(SchemaSymbols.ATTVAL_SKIP)){
>             anyAttDecl.defaultType =
XMLAttributeDecl.PROCESSCONTENTS_SKIP;
>         }
>         else if (processContents.equals(SchemaSymbols.ATTVAL_LAX)) {
>             anyAttDecl.defaultType = XMLAttributeDecl.PROCESSCONTENTS_LAX;
>         }
>
>         return anyAttDecl;
>     }
>
>     private XMLAttributeDecl mergeTwoAnyAttribute(XMLAttributeDecl oneAny,
XMLAttributeDecl anotherAny) {
>         if (oneAny.type == -1) {
>             return oneAny;
>         }
>         if (anotherAny.type == -1) {
>             return anotherAny;
>         }
>
>         if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
>             return anotherAny;
>         }
>
>         if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
>             return oneAny;
>         }
>
>         if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
>             if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
>
>                 if ( anotherAny.name.uri == oneAny.name.uri ) {
>                     return oneAny;
>                 }
>                 else {
>                     oneAny.type = -1;
>                     return oneAny;
>                 }
>
>             }
>             else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
>                 return anotherAny;
>             }
>             else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
>                 if (!fStringPool.stringInList(anotherAny.enumeration,
oneAny.name.uri) ) {
>                     return anotherAny;
>                 }
>                 else {
>                     int[] anotherAnyURIs =
fStringPool.stringListAsIntArray(anotherAny.enumeration);
>                     int newList = fStringPool.startStringList();
>                     for (int i=0; i< anotherAnyURIs.length; i++) {
>                         if (anotherAnyURIs[i] != oneAny.name.uri ) {
>                             fStringPool.addStringToList(newList,
anotherAnyURIs[i]);
>                         }
>                     }
>                     fStringPool.finishStringList(newList);
>                     anotherAny.enumeration = newList;
>                     return anotherAny;
>                 }
>             }
>         }
>
>         if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
>             if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
>                 || anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
>                 return oneAny;
>             }
>             else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
>                 oneAny.type = -1;
>                 return oneAny;
>             }
>         }
>
>         if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
>             if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER){
>                 if (!fStringPool.stringInList(oneAny.enumeration,
anotherAny.name.uri) ) {
>                     return oneAny;
>                 }
>                 else {
>                     int[] oneAnyURIs =
fStringPool.stringListAsIntArray(oneAny.enumeration);
>                     int newList = fStringPool.startStringList();
>                     for (int i=0; i< oneAnyURIs.length; i++) {
>                         if (oneAnyURIs[i] != anotherAny.name.uri ) {
>                             fStringPool.addStringToList(newList,
oneAnyURIs[i]);
>                         }
>                     }
>                     fStringPool.finishStringList(newList);
>                     oneAny.enumeration = newList;
>                     return oneAny;
>                 }
>
>             }
>             else if ( anotherAny.type == XMLAttributeDecl.TYPE_ANY_LOCAL)
{
>                 oneAny.type = -1;
>                 return oneAny;
>             }
>             else if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
>                 int[] result =
ntersect2sets( fStringPool.stringListAsIntArray(oneAny.enumeration),
>
fStringPool.stringListAsIntArray(anotherAny.enumeration));
>                 int newList = fStringPool.startStringList();
>                 for (int i=0; i<result.length; i++) {
>                     fStringPool.addStringToList(newList, result[i]);
>                 }
>                 fStringPool.finishStringList(newList);
>                 oneAny.enumeration = newList;
>                 return oneAny;
>             }
>         }
>
>         // should never go there;
>         return oneAny;
>     }
>
>     int[] intersect2sets(int[] one, int[] theOther){
>         int[] result = new
int[(one.length>theOther.length?one.length:theOther.length)];
>
>         // simple implemention,
>         int count = 0;
>         for (int i=0; i<one.length; i++) {
>             for(int j=0; j<theOther.length; j++) {
>                 if (one[i]==theOther[j]) {
>                     result[count++] = one[i];
>                 }
>             }
>         }
>
>         int[] result2 = new int[count];
>         System.arraycopy(result, 0, result2, 0, count);
>
>         return result2;
>     }
>
>     /**
>      * Traverse ComplexType Declaration.
>      *
>      *       <complexType
>      *         abstract = boolean
>      *         base = QName
>      *         block = #all or (possibly empty) subset of {extension,
restriction}
>      *         content = elementOnly | empty | mixed | textOnly
>      *         derivedBy = extension | restriction
>      *         final = #all or (possibly empty) subset of {extension,
restriction}
>      *         id = ID
>      *         name = NCName>
>      *          Content: (annotation? , (((minExclusive | minInclusive |
maxExclusive
>      *                    | maxInclusive | precision | scale | length |
minLength
>      *                    | maxLength | encoding | period | duration |
enumeration
>      *                    | pattern)* | (element | group | all | choice |
sequence | any)*) ,
>      *                    ((attribute | attributeGroup)* ,
anyAttribute?)))
>      *        </complexType>
>      * @param complexTypeDecl
>      * @return
>      */
>
>     file://REVISIT: TO DO, base and derivation ???
>     private int traverseComplexTypeDecl( Element complexTypeDecl ) throws
Exception

>         String isAbstract =
omplexTypeDecl.getAttribute( SchemaSymbols.ATT_ABSTRACT );
>         String base =
complexTypeDecl.getAttribute(SchemaSymbols.ATT_BASE);
>         String blockSet =
omplexTypeDecl.getAttribute( SchemaSymbols.ATT_BLOCK );
>         String content =
complexTypeDecl.getAttribute(SchemaSymbols.ATT_CONTENT);
>         String derivedBy =
omplexTypeDecl.getAttribute( SchemaSymbols.ATT_DERIVEDBY );
>         String finalSet =
omplexTypeDecl.getAttribute( SchemaSymbols.ATT_FINAL );
>         String typeId =
omplexTypeDecl.getAttribute( SchemaSymbols.ATTVAL_ID );
>         String typeName =
complexTypeDecl.getAttribute(SchemaSymbols.ATT_NAME);
>         boolean isNamedType = false;
>
>         if ( DEBUGGING )
>             System.out.println("traversing complex Type : " + typeName
+","+base+","+content+".");
>
>         if (typeName.equals("")) { // gensym a unique name
>             file://typeName =
"http://www.apache.org/xml/xerces/internalType"+fTypeCount++;
>             typeName = "#"+fAnonTypeCount++;
>         }
>         else {
>             fCurrentTypeNameStack.push(typeName);
>             isNamedType = true;
>         }
>
>         if (isTopLevel(complexTypeDecl)) {
>
>             String fullName = fTargetNSURIString+","+typeName;
>             ComplexTypeInfo temp = (ComplexTypeInfo)
fComplexTypeRegistry.get(fullName);
>             if (temp != null ) {
>                 return fStringPool.addSymbol(fullName);
>             }
>         }
>
>         int scopeDefined = fScopeCount++;
>         int previousScope = fCurrentScope;
>         fCurrentScope = scopeDefined;
>
>         Element child = null;
>         int contentSpecType = -1;
>         int csnType = 0;
>         int left = -2;
>         int right = -2;
>
>         ComplexTypeInfo baseTypeInfo = null;  file://if base is a
complexType;
>         DatatypeValidator baseTypeValidator = null; file://if base is a
simple type or a complex type derived from a simpleType
>         DatatypeValidator simpleTypeValidator = null;
>         int baseTypeSymbol = -1;
>         String fullBaseName = "";
>
>         boolean baseIsSimpleSimple = false;
>         boolean baseIsComplexSimple = false;
>         boolean baseFromAnotherSchema = false;
>         String baseTypeSchemaURI = null;
>         boolean derivedByRestriction = true;
>         boolean derivedByExtension = false;
>         int baseContentSpecHandle = -1;
>         Element baseTypeNode = null;
>
>
>         file://int parsedderivedBy = parseComplexDerivedBy(derivedBy);
>         file://handle the inhreitance here.
>         if (base.length()>0) {
>
>             file://first check if derivedBy is present
>             if (derivedBy.length() == 0) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("derivedBy must be present when
base is present in "
>                                          +SchemaSymbols.ELT_COMPLEXTYPE
>                                          +" "+ typeName);
>                 derivedBy = SchemaSymbols.ATTVAL_EXTENSION;
>             }
>
>             if (derivedBy.equals(SchemaSymbols.ATTVAL_EXTENSION)) {
>                 derivedByRestriction = false;
>             }
>
>             String prefix = "";
>             String localpart = base;
>             int colonptr = base.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = base.substring(0,colonptr);
>                 localpart = base.substring(colonptr+1);
>             }
>             int localpartIndex = fStringPool.addSymbol(localpart);
>             String typeURI = resolvePrefixToURI(prefix);
>
>             // check if the base type is from the same Schema;
>             if ( ! typeURI.equals(fTargetNSURIString)
>                  && ! typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
>                  && typeURI.length() != 0 )  /*REVISIT, !!!! a hack: for
schema that has no target namespace, e.g. personal-schema.xml*/{
>                 baseFromAnotherSchema = true;
>                 baseTypeSchemaURI = typeURI;
>                 baseTypeInfo = getTypeInfoFromNS(typeURI, localpart);
>                 if (baseTypeInfo == null) {
>                     baseTypeValidator = getTypeValidatorFromNS(typeURI,
localpart);
>                     if (baseTypeValidator == null) {
>                         file://TO DO: report error here;
>                         System.out.println("Could not find base type "
+localpart
>                                            + " in schema " + typeURI);
>                     }
>                     else{
>                         baseIsSimpleSimple = true;
>                     }
>                 }
>             }
>             else {
>
>                 fullBaseName = typeURI+","+localpart;
>
>                 // assume the base is a complexType and try to locate the
base type first
>                 baseTypeInfo = (ComplexTypeInfo)
fComplexTypeRegistry.get(fullBaseName);
>
>                 // if not found, 2 possibilities: 1: ComplexType in
question has not been compiled yet;
>                 //                                2: base is SimpleTYpe;
>                 if (baseTypeInfo == null) {
>                     baseTypeValidator = getDatatypeValidator(typeURI,
localpart);
>
>                     if (baseTypeValidator == null) {
>                         baseTypeNode =
getTopLevelComponentByName(SchemaSymbols.ELT_COMPLEXTYPE,localpart);
>                         if (baseTypeNode != null) {
>                             baseTypeSymbol =
raverseComplexTypeDecl( baseTypeNode );
>                             baseTypeInfo = (ComplexTypeInfo)
>
fComplexTypeRegistry.get(fStringPool.toString(baseTypeSymbol));
file://REVISIT: should it be fullBaseName;
>                         }
>                         else {
>                             baseTypeNode =
getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
>                             if (baseTypeNode != null) {
>                                     baseTypeSymbol =
traverseSimpleTypeDecl( baseTypeNode );
>                                     simpleTypeValidator =
baseTypeValidator = getDatatypeValidator(typeURI, localpart);
>                                     if (simpleTypeValidator == null) {
>                                         file://TO DO: signal error here.
>                                     }
>
>                                     baseIsSimpleSimple = true;
>                             }
>                             else {
>                                 // REVISIT: Localize
>                                 reportGenericSchemaError("Base type could
not be found : " + base);
>                             }
>                         }
>                     }
>                     else {
>                         simpleTypeValidator = baseTypeValidator;
>                         baseIsSimpleSimple = true;
>                     }
>                 }
>             }
>             file://Schema Spec : 5.11: Complex Type Definition Properties
Correct : 2
>             if (baseIsSimpleSimple && derivedByRestriction) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("base is a simpledType, can't
derive by restriction in " + typeName);
>             }
>
>             file://if  the base is a complexType
>             if (baseTypeInfo != null ) {
>
>                 file://Schema Spec : 5.11: Derivation Valid ( Extension )
1.1.1
>                 //              5.11: Derivation Valid ( Restriction,
Complex ) 1.2.1
>                 if (derivedByRestriction) {
>                     file://REVISIT: check base Type's finalset does not
include "restriction"
>                 }
>                 else {
>                     file://REVISIT: check base Type's finalset doest not
include "extension"
>                 }
>
>                 if ( baseTypeInfo.contentSpecHandle > -1) {
>                     if (derivedByRestriction) {
>                         file://REVISIT: !!! really hairy staff to check
the particle derivation OK in 5.10
>                         checkParticleDerivationOK(complexTypeDecl,
baseTypeNode);
>                     }
>                     baseContentSpecHandle =
baseTypeInfo.contentSpecHandle;
>                 }
>                 else if ( baseTypeInfo.datatypeValidator != null ) {
>                     baseTypeValidator = baseTypeInfo.datatypeValidator;
>                     baseIsComplexSimple = true;
>                 }
>             }
>
>             file://Schema Spec : 5.11: Derivation Valid ( Extension )
1.1.1
>             if (baseIsComplexSimple && !derivedByRestriction ) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("base is ComplexSimple, can't
derive by extension in " + typeName);
>             }
>
>
>         } // END of if (base.length() > 0) {}
>
>         // skip refinement and annotations
>         child = null;
>
>         if (baseIsComplexSimple) {
>
>             contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>
>             int numEnumerationLiterals = 0;
>             int numFacets = 0;
>             Hashtable facetData        = new Hashtable();
>             Vector enumData            = new Vector();
>
>
>             file://REVISIT: there is a better way to do this,
>             for (child = XUtil.getFirstChildElement(complexTypeDecl);
>                  child != null &&
(child.getNodeName().equals(SchemaSymbols.ELT_MINEXCLUSIVE) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_MININCLUSIVE) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_MAXEXCLUSIVE) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_MAXINCLUSIVE) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_PRECISION) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_SCALE) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_LENGTH) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_MINLENGTH) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_MAXLENGTH) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_ENCODING) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_PERIOD) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_DURATION) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_PATTERN) ||
>
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION));
>                  child = XUtil.getNextSiblingElement(child))
>             {
>                 if ( child.getNodeType() == Node.ELEMENT_NODE ) {
>                     Element facetElt = (Element) child;
>                     numFacets++;
>                     if
(facetElt.getNodeName().equals(SchemaSymbols.ELT_ENUMERATION)) {
>                         numEnumerationLiterals++;
>
enumData.addElement(facetElt.getAttribute(SchemaSymbols.ATT_VALUE));
>                         file://Enumerations can have annotations ? ( 0 |
1 )
>                         Element enumContent =
Util.getFirstChildElement( facetElt );
>                         if( enumContent != null &&
enumContent.getNodeName().equals( SchemaSymbols.ELT_ANNOTATION ) ){
>                             traverseAnnotationDecl( child );
>                         }
>                         // TO DO: if Jeff check in new changes to
TraverseSimpleType, copy them over
>                     } else {
>
facetData.put(facetElt.getNodeName(),facetElt.getAttribute( SchemaSymbols.AT
T_VALUE ));
>                     }
>                 }
>             }
>             if (numEnumerationLiterals > 0) {
>                 facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
>             }
>
>             file://if (numFacets > 0)
>             //    baseTypeValidator.setFacets(facetData, derivedBy );
>             if (numFacets > 0) {
>                 simpleTypeValidator =
fDatatypeRegistry.createDatatypeValidator( typeName, baseTypeValidator,
>                                                            facetData,
false );
>             }
>             else
>                 simpleTypeValidator = baseTypeValidator;
>
>             if (child != null) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("Invalid child
'"+child.getNodeName()+"' in complexType : '" + typeName
>                                          + "', because it restricts
another complexSimpleType");
>             }
>         }
>
>             // if content = textonly, base is a datatype
>         if (content.equals(SchemaSymbols.ATTVAL_TEXTONLY)) {
>             file://TO DO
>             if (base.length() == 0) {
>                 simpleTypeValidator = baseTypeValidator =
getDatatypeValidator("", SchemaSymbols.ATTVAL_STRING);
>             }
>             else if ( baseTypeValidator == null
>                       && baseTypeInfo != null &&
baseTypeInfo.datatypeValidator==null ) // must be datatype
>
reportSchemaError(SchemaMessageProvider.NotADatatype,
>                                           new Object [] { base });
file://REVISIT check forward refs
>             file://handle datatypes
>             contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>             /****
>             left =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF,
>
fStringPool.addSymbol(base),
>                                                  -1, false);
>             /****/
>
>         }
>         else

>             if (!baseIsComplexSimple) {
>                 contentSpecType = XMLElementDecl.TYPE_CHILDREN;
>             }
>             csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
>             boolean mixedContent = false;
>             file://REVISIT: is the default content " elementOnly"
>             boolean elementContent = true;
>             boolean textContent = false;
>             boolean emptyContent = false;
>             left = -2;
>             right = -2;
>             boolean hadContent = false;
>
>             if (content.equals(SchemaSymbols.ATTVAL_EMPTY)) {
>                 contentSpecType = XMLElementDecl.TYPE_EMPTY;
>                 emptyContent = true;
>                 elementContent = false;
>                 left = -1; // no contentSpecNode needed
>             } else if (content.equals(SchemaSymbols.ATTVAL_MIXED) ) {
>                 contentSpecType = XMLElementDecl.TYPE_MIXED;
>                 mixedContent = true;
>                 elementContent = false;
>                 csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
>             } else if (content.equals(SchemaSymbols.ATTVAL_ELEMENTONLY) ||
content.equals("")) {
>                 elementContent = true;
>             } else if (content.equals(SchemaSymbols.ATTVAL_TEXTONLY)) {
>                 textContent = true;
>                 elementContent = false;
>             }
>
>             if (mixedContent) {
>                 // add #PCDATA leaf
>
>                 left =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                          -1, // -1 means
"#PCDATA" is name
>                                                          -1, false);
>                 csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
>             }
>
>             boolean seeParticle = false;
>             boolean seeOtherParticle = false;
>             boolean seeAll = false;
>
>             for (child = XUtil.getFirstChildElement(complexTypeDecl);
>                  child != null;
>                  child = XUtil.getNextSiblingElement(child)) {
>
>                 int index = -2;  // to save the particle's contentSpec
handle
>                 hadContent = true;
>
>                 seeParticle = false;
>
>                 String childName = child.getNodeName();
>
>                 if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                     if (mixedContent || elementContent) {
>                         if ( DEBUGGING )
>                             System.out.println(" child element name " +
child.getAttribute(SchemaSymbols.ATT_NAME));
>
>                         QName eltQName = traverseElementDecl(child);
>                         index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>
eltQName.localpart,
>
eltQName.uri,
>                                                                    false);
>                         seeParticle = true;
>                         seeOtherParticle = true;
>
>                     }
>                     else {
>
reportSchemaError(SchemaMessageProvider.EltRefOnlyInMixedElemOnly, null);
>                     }
>
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                     index = traverseGroupDecl(child);
>                     seeParticle = true;
>                     seeOtherParticle = true;
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_ALL)) {
>                     index = traverseAll(child);
>                     seeParticle = true;
>                     seeAll = true;
>
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                     index = traverseChoice(child);
>                     seeParticle = true;
>                     seeOtherParticle = true;
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                     index = traverseSequence(child);
>                     seeParticle = true;
>                     seeOtherParticle = true;
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE) ||
>
childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
>                     break; // attr processing is done later on in this
method
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>
>                     index = traverseAny(child);
>                     seeParticle = true;
>                     seeOtherParticle = true;
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_ANNOTATION)) {
>                     file://REVISIT, do nothing for annotation for now.
>                 }
>                 else if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE))
{
>                     break;
>                     file://REVISIT, do nothing for attribute wildcard for
now.
>                 }
>                 else { // datatype qual
>                     if (!baseIsComplexSimple )
>                     if (base.equals(""))
>
reportSchemaError(SchemaMessageProvider.GenericError,
>                                           new Object [] { "unrecognized
child '"+childName+"' in complex type "+typeName });
>                     else
>
reportSchemaError(SchemaMessageProvider.GenericError,
>                                           new Object [] { "unrecognized
child '"+childName+"' in complex type '"+typeName+"' with base "+base  });
>                 }
>
>                 // if base is complextype with simpleType content, can't
have any particle children at all.
>                 if (baseIsComplexSimple && seeParticle) {
>                     // REVISIT: Localize
>                     reportGenericSchemaError("In complexType "+typeName+",
base type is complexType with simpleType content, can't have any particle
children at all");
>                     hadContent = false;
>                     left = index = -2;
>                     contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>                     break;
>                 }
>
>
>                 if (seeAll && seeOtherParticle) {
>                     // REVISIT: Localize
>                     reportGenericSchemaError ( " 'All' group needs to be
the only child in Complextype : " + typeName);
>                 }
>
>                 if (seeAll) {
>                     file://TO DO: REVISIT
>                     file://check the minOccurs = 1 and maxOccurs = 1
>                 }
>
>                 // check the minOccurs and maxOccurs of the particle, and
fix the
>                 // contentspec accordingly
>                 if (seeParticle) {
>                     index = expandContentModel(index, child);
>                     if (index == -2 ) {
>                         continue;
>                     }
>                 } file://end of if (seeParticle)
>
>                 if (left == -2) {
>                     left = index;
>                 } else if (right == -2) {
>                     right = index;
>                 } else {
>                     left = fSchemaGrammar.addContentSpecNode(csnType,
left, right, false);
>                     right = index;
>                 }
>             } file://end looping through the children
>
>             if ( ! ( seeOtherParticle || seeAll ) && (elementContent ||
mixedContent)
>                  &&  (base.length() == 0 || ( base.length() > 0 &&
derivedByRestriction && !baseIsComplexSimple))  ) {
>                 contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>                 simpleTypeValidator = getDatatypeValidator("",
SchemaSymbols.ATTVAL_STRING);
>                 // REVISIT: Localize
>                 reportGenericSchemaError ( " complexType '"+typeName+"'
with a elementOnly or mixed content "
>                                            +"need to have at least one
particle child");
>             }
>
>             if (hadContent && right != -2)
>                 left = fSchemaGrammar.addContentSpecNode(csnType, left,
right, false);
>
>             if (mixedContent && hadContent) {
>                 // set occurrence count
>                 left =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MOR
E,
>                                                      left, -1, false);
>             }
>         }
>
>         // if derived by extension and base complextype has a content
model,
>         // compose the final content model by concatenating the base and
the
>         // current in sequence.
>         if (!derivedByRestriction && baseContentSpecHandle > -1 ) {
>             if (baseFromAnotherSchema ) {
>                 SchemaGrammar aGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(baseTypeSchemaURI);
>                 baseContentSpecHandle = importContentSpec(aGrammar,
baseContentSpecHandle);
>             }
>
>             if (left == -2) {
>                 left = baseContentSpecHandle;
>             }
>             else
>                 left =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>
baseContentSpecHandle,
>                                                          left,
>                                                          false);
>         }
>
>         // REVISIT: this is when sees a topelevel <complexType
name="abc">attrs*</complexType>
>         if (content.length() == 0 && base.length() == 0 && left == -2) {
>             contentSpecType = XMLElementDecl.TYPE_ANY;
>         }
>
>         if (content.length() == 0 && simpleTypeValidator == null && left
== -2 ) {
>             if (base.length() > 0 && baseTypeInfo != null
>                 && baseTypeInfo.contentType == XMLElementDecl.TYPE_EMPTY)
{
>                 contentSpecType = XMLElementDecl.TYPE_EMPTY;
>             }
>         }
>
>         if ( DEBUGGING )
>             System.out.println("!!!!!>>>>>" + typeName+", "+ baseTypeInfo
+ ", "
>                                + baseContentSpecHandle +", " + left +",
"+scopeDefined);
>
>         ComplexTypeInfo typeInfo = new ComplexTypeInfo();
>         typeInfo.baseComplexTypeInfo = baseTypeInfo;
>         typeInfo.baseDataTypeValidator = baseTypeValidator;
>         int derivedByInt = -1;
>         if (derivedBy.length() > 0) {
>             derivedByInt = parseComplexDerivedBy(derivedBy);
>         }
>         typeInfo.derivedBy = derivedByInt;
>         typeInfo.scopeDefined = scopeDefined;
>         typeInfo.contentSpecHandle = left;
>         typeInfo.contentType = contentSpecType;
>         typeInfo.datatypeValidator = simpleTypeValidator;
>         typeInfo.blockSet =
parseBlockSet(complexTypeDecl.getAttribute(SchemaSymbols.ATT_BLOCK));
>         typeInfo.finalSet =
parseFinalSet(complexTypeDecl.getAttribute(SchemaSymbols.ATT_FINAL));
>         typeInfo.isAbstract = isAbstract.equals(SchemaSymbols.ATTVAL_TRUE)
? true:false ;
>
>         file://add a template element to the grammar element decl pool.
>         int typeNameIndex = fStringPool.addSymbol(typeName);
>         int templateElementNameIndex =
fStringPool.addSymbol("$"+typeName);
>
>         typeInfo.templateElementIndex =
>             fSchemaGrammar.addElementDecl(new QName(-1,
templateElementNameIndex,typeNameIndex,fTargetNSURI),
>                                           (fTargetNSURI==-1) ? -1 :
fCurrentScope, scopeDefined,
>                                             contentSpecType, left,
>                                           -1, simpleTypeValidator);
>         typeInfo.attlistHead =
fSchemaGrammar.getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
>
>
>         // (attribute | attrGroupRef)*
>         XMLAttributeDecl attWildcard = null;
>         Vector anyAttDecls = new Vector();
>
>         for (child = XUtil.getFirstChildElement(complexTypeDecl);
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>
>             String childName = child.getNodeName();
>
>             if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
>                 if ((baseIsComplexSimple||baseIsSimpleSimple) &&
derivedByRestriction) {
>                     // REVISIT: Localize
>                     reportGenericSchemaError("In complexType "+typeName+
>                                              ", base type has simpleType
"+
>                                              "content and derivation
method is"+
>                                              " 'restriction', can't have
any "+
>                                              "attribute children at all");
>                     break;
>                 }
>                 traverseAttributeDecl(child, typeInfo);
>             }
>             else if ( childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) )
{ 
>                 if ((baseIsComplexSimple||baseIsSimpleSimple) && derivedByRestriction) {
>                     // REVISIT: Localize
>                     reportGenericSchemaError("In complexType "+typeName+", base "+
>                                              "type has simpleType content and "+
>                                              "derivation method is 'restriction',"+
>                                              " can't have any attribute children at all");
>                     break;
>                 }
>                 traverseAttributeGroupDecl(child,typeInfo,anyAttDecls);
>             }
>             else if ( childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) { 
>  
               attWildcard = traverseAnyAttribute(child);
>             }
>         }
>
>         if (attWildcard != null) {
>             XMLAttributeDecl fromGroup = null;
>             final int count = anyAttDecls.size();
>             if ( count > 0) {
>                 fromGroup = (XMLAttributeDecl) anyAttDecls.elementAt(0);
>                 for (int i=1; i<count; i++) {
>                     fromGroup =
mergeTwoAnyAttribute(fromGroup,(XMLAttributeDecl)anyAttDecls.elementAt(i));
>                 }
>             }
>             if (fromGroup != null) {
>                 int saveProcessContents = attWildcard.defaultType;
>                 attWildcard = mergeTwoAnyAttribute(attWildcard,
fromGroup);
>                 attWildcard.defaultType = saveProcessContents;
>             }
>         }
>         else {
>             file://REVISIT: unclear in the Scheme Structures 4.3.3 what to
do in this case
>         }
>
>         // merge in base type's attribute decls
>         XMLAttributeDecl baseAttWildcard = null;
>         if (baseTypeInfo != null && baseTypeInfo.attlistHead > -1 ) {
>             int attDefIndex = baseTypeInfo.attlistHead;
>             SchemaGrammar aGrammar = fSchemaGrammar;
>             if (baseFromAnotherSchema) {
>                 aGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(baseTypeSchemaURI);
>             }
>             if (aGrammar == null) {
>                 reportGenericSchemaError("In complexType "+typeName+", can
NOT find the grammar "+
>                                          "with targetNamespace" +
baseTypeSchemaURI+
>                                          "for the base type");
>             }
>             else
>             while ( attDefIndex > -1 ) {
>                 fTempAttributeDecl.clear();
>                 aGrammar.getAttributeDecl(attDefIndex,
fTempAttributeDecl);
>                 if (fTempAttributeDecl.type ==
XMLAttributeDecl.TYPE_ANY_ANY
>                     ||fTempAttributeDecl.type ==
XMLAttributeDecl.TYPE_ANY_LIST
>                     ||fTempAttributeDecl.type ==
XMLAttributeDecl.TYPE_ANY_LOCAL
>                     ||fTempAttributeDecl.type ==
XMLAttributeDecl.TYPE_ANY_OTHER ) {
>                     if (attWildcard == null) {
>                         baseAttWildcard = fTempAttributeDecl;
>                     }
>                     attDefIndex =
aGrammar.getNextAttributeDeclIndex(attDefIndex);
>                     continue;
>                 }
>                 // if found a duplicate, if it is derived by restriction.
then skip the one from the base type
>                 /**/
>                 int temp =
fSchemaGrammar.getAttributeDeclIndex(typeInfo.templateElementIndex,
fTempAttributeDecl.name);
>                 if ( temp > -1) {
>                     if (derivedByRestriction) {
>                         attDefIndex =
fSchemaGrammar.getNextAttributeDeclIndex(attDefIndex);
>                         continue;
>                     }
>                 }
>
>                 /**/
>                 fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
>                                           fTempAttributeDecl.name,
fTempAttributeDecl.type,
>                                           fTempAttributeDecl.enumeration,
fTempAttributeDecl.defaultType,
>                                           fTempAttributeDecl.defaultValue,
>
fTempAttributeDecl.datatypeValidator,
>                                           fTempAttributeDecl.list);
>                 attDefIndex =
aGrammar.getNextAttributeDeclIndex(attDefIndex);
>             }
>         }
>         // att wildcard will inserted after all attributes were processed
>         if (attWildcard != null) {
>             if (attWildcard.type != -1) {
>                 fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
>                                           attWildcard.name,
attWildcard.type,
>                                           attWildcard.enumeration,
attWildcard.defaultType,
>                                           attWildcard.defaultValue,
>                                           attWildcard.datatypeValidator,
>                                           attWildcard.list);
>             }
>             else {
>                 file://REVISIT: unclear in Schema spec if should report
error here.
>             }
>         }
>         else if (baseAttWildcard != null) {
>             fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
>                                       baseAttWildcard.name,
baseAttWildcard.type,
>                                       baseAttWildcard.enumeration,
baseAttWildcard.defaultType,
>                                       baseAttWildcard.defaultValue,
>                                       baseAttWildcard.datatypeValidator,
>                                       baseAttWildcard.list);
>         }
>
>         typeInfo.attlistHead =
fSchemaGrammar.getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
>
>         if (!typeName.startsWith("#")) {
>             typeName = fTargetNSURIString + "," + typeName;
>         }
>         typeInfo.typeName = new String(typeName);
>         if ( DEBUGGING )
>             System.out.println("add complex Type to Registry: " + typeName
+","+content+".");
>         fComplexTypeRegistry.put(typeName,typeInfo);
>
>         // before exit the complex type definition, restore the scope,
mainly for nested Anonymous Types
>         fCurrentScope = previousScope;
>         if (isNamedType) {
>             fCurrentTypeNameStack.pop();
>             checkRecursingComplexType();
>         }
>
>         file://set template element's typeInfo
>
fSchemaGrammar.setElementComplexTypeInfo(typeInfo.templateElementIndex,
typeInfo);
>
>         typeNameIndex = fStringPool.addSymbol(typeName);
>         return typeNameIndex;
>
>
>     } // end of method: traverseComplexTypeDecl
>
>
>     private void checkRecursingComplexType() throws Exception {
>         if ( fCurrentTypeNameStack.empty() ) {
>             if (! fElementRecurseComplex.isEmpty() ) {
>                 Enumeration e = fElementRecurseComplex.keys();
>                 while( e.hasMoreElements() ) {
>                     QName nameThenScope = (QName) e.nextElement();
>                     String typeName = (String)
fElementRecurseComplex.get(nameThenScope);
>
>                     int eltUriIndex = nameThenScope.uri;
>                     int eltNameIndex = nameThenScope.localpart;
>                     int enclosingScope = nameThenScope.prefix;
>                     ComplexTypeInfo typeInfo =
>                         (ComplexTypeInfo)
fComplexTypeRegistry.get(fTargetNSURIString+","+typeName);
>                     if (typeInfo==null) {
>                         throw new Exception ( "Internal Error in void
checkRecursingComplexType(). " );
>                     }
>                     else {
>                         int elementIndex =
fSchemaGrammar.addElementDecl(new QName(-1, eltNameIndex, eltNameIndex,
eltUriIndex),
>
enclosingScope, typeInfo.scopeDefined,
>
typeInfo.contentType,
>
typeInfo.contentSpecHandle,
>
typeInfo.attlistHead,
>
typeInfo.datatypeValidator);
>
fSchemaGrammar.setElementComplexTypeInfo(elementIndex, typeInfo);
>                     }
>
>                 }
>                 fElementRecurseComplex.clear();
>             }
>         }
>     }
>
>     private void checkParticleDerivationOK(Element derivedTypeNode,
Element baseTypeNode) {
>         file://TO DO: !!!
>     }
>
>     private int importContentSpec(SchemaGrammar aGrammar, int
contentSpecHead ) throws Exception {
>         XMLContentSpec ctsp = new XMLContentSpec();
>         aGrammar.getContentSpec(contentSpecHead, ctsp);
>         int left = -1;
>         int right = -1;
>         if ( ctsp.type == ctsp.CONTENTSPECNODE_LEAF
>              || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY
>              || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY_LOCAL
>              || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY_OTHER ) {
>             return fSchemaGrammar.addContentSpecNode(ctsp.type,
ctsp.value, ctsp.otherValue, false);
>         }
>         else {
>             if ( ctsp.value == -1 ) {
>                 left = -1;
>             }
>             else {
>                 left = importContentSpec(aGrammar, ctsp.value);
>             }
>
>             if ( ctsp.otherValue == -1 ) {
>                 right = -1;
>             }
>             else {
>                 right = importContentSpec(aGrammar, ctsp.otherValue);
>             }
>             return fSchemaGrammar.addContentSpecNode(ctsp.type, left,
right, false);
>
>         }
>     }
>
>     private int expandContentModel ( int index, Element particle) throws
Exception {
>
>         String minOccurs =
particle.getAttribute(SchemaSymbols.ATT_MINOCCURS).trim();
>         String maxOccurs =
particle.getAttribute(SchemaSymbols.ATT_MAXOCCURS).trim();
>
>         int min=1, max=1;
>
>         if(minOccurs.equals("0") && maxOccurs.equals("0")){
>             return -2;
>         }
>
>         if (minOccurs.equals("")) {
>             minOccurs = "1";
>         }
>         if (maxOccurs.equals("") ){
>             if ( minOccurs.equals("0")) {
>                 maxOccurs = "1";
>             }
>             else {
>                 maxOccurs = minOccurs;
>             }
>         }
>
>
>         int leafIndex = index;
>         file://REVISIT: !!! minoccurs, maxoccurs.
>         if (minOccurs.equals("1")&& maxOccurs.equals("1")) {
>
>         }
>         else if (minOccurs.equals("0")&& maxOccurs.equals("1")) {
>             file://zero or one
>             index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
,
>                                                    index,
>                                                    -1,
>                                                    false);
>         }
>         else if (minOccurs.equals("0")&& maxOccurs.equals("unbounded")) {
>             file://zero or more
>             index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MOR
E,
>                                                    index,
>                                                    -1,
>                                                    false);
>         }
>         else if (minOccurs.equals("1")&& maxOccurs.equals("unbounded")) {
>             file://one or more
>             index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
,
>                                                    index,
>                                                    -1,
>                                                    false);
>         }
>         else if (maxOccurs.equals("unbounded") ) {
>             // >=2 or more
>             try {
>                 min = Integer.parseInt(minOccurs);
>             }
>             catch (Exception e) {
>                 reportSchemaError(SchemaMessageProvider.GenericError,
>                                   new Object [] { "illegal value for
minOccurs : '" +e.getMessage()+ "' " });
>             }
>             if (min<2) {
>                 file://REVISIT: report Error here
>             }
>
>             // => a,a,..,a+
>             index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
,
>                    index,
>                    -1,
>                    false);
>
>             for (int i=0; i < (min-1); i++) {
>                 index =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                       leafIndex,
>                                                       index,
>                                                       false);
>             }
>
>         }
>         else {
>             // {n,m} => a,a,a,...(a),(a),...
>             try {
>                 min = Integer.parseInt(minOccurs);
>                 max = Integer.parseInt(maxOccurs);
>             }
>             catch (Exception e){
>                 reportSchemaError(SchemaMessageProvider.GenericError,
>                                   new Object [] { "illegal value for
minOccurs or maxOccurs : '" +e.getMessage()+ "' "});
>             }
>             if (min==0) {
>                 int optional =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
,
>
leafIndex,
>                                                                  -1,
>                                                                  false);
>                 index = optional;
>                 for (int i=0; i < (max-min-1); i++) {
>                     index =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                               index,
>                                                               optional,
>                                                               false);
>                 }
>             }
>             else {
>                 for (int i=0; i<(min-1); i++) {
>                     index =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                           index,
>                                                           leafIndex,
>                                                           false);
>                 }
>
>                 int optional =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
,
>
leafIndex,
>                                                                  -1,
>                                                                  false);
>                 for (int i=0; i < (max-min); i++) {
>                     index =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                               index,
>                                                               optional,
>                                                               false);
>                 }
>             }
>         }
>
>         return index;
>     }
>
>     /**
>      * Traverses Schema attribute declaration.
>      *
>      *       <attribute
>      *         form = qualified | unqualified
>      *         id = ID
>      *         name = NCName
>      *         ref = QName
>      *         type = QName
>      *         use = default | fixed | optional | prohibited | required
>      *         value = string>
>      *         Content: (annotation? , simpleType?)
>      *       <attribute/>
>      *
>      * @param attributeDecl
>      * @return
>      * @exception Exception
>      */
>     private int traverseAttributeDecl( Element attrDecl, ComplexTypeInfo
typeInfo ) throws Exception {
>         String attNameStr    =
attrDecl.getAttribute(SchemaSymbols.ATT_NAME);
>         int attName          = fStringPool.addSymbol(attNameStr);//
attribute name
>         String isQName       =
attrDecl.getAttribute(SchemaSymbols.ATT_FORM);//form attribute
>
>         DatatypeValidator dv = null;
>         // attribute type
>         int attType          = -1;
>         boolean attIsList    = false;
>         int dataTypeSymbol   = -1;
>
>         String ref       = attrDecl.getAttribute(SchemaSymbols.ATT_REF);
>         String datatype  = attrDecl.getAttribute(SchemaSymbols.ATT_TYPE);
>         String localpart = null;
>
>         if (!ref.equals("")) {
>             if (XUtil.getFirstChildElement(attrDecl) != null)
>                 reportSchemaError(SchemaMessageProvider.NoContentForRef,
null);
>             String prefix = "";
>             localpart = ref;
>             int colonptr = ref.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = ref.substring(0,colonptr);
>                 localpart = ref.substring(colonptr+1);
>             }
>             String uriStr = resolvePrefixToURI(prefix);
>
>             if (!uriStr.equals(fTargetNSURIString)) {
>                 addAttributeDeclFromAnotherSchema(localpart, uriStr,
typeInfo);
>
>                 return -1;
>             }
>
>             Element referredAttribute =
getTopLevelComponentByName(SchemaSymbols.ELT_ATTRIBUTE,localpart);
>             if (referredAttribute != null) {
>                 traverseAttributeDecl(referredAttribute, typeInfo);
>             }
>             else {
>
>                 if (fAttributeDeclRegistry.get(localpart) != null) {
>                     addAttributeDeclFromAnotherSchema(localpart, uriStr,
typeInfo);
>                 }
>                 else
>                     // REVISIT: Localize
>                     reportGenericSchemaError ( "Couldn't find top level
attribute " + ref);
>             }
>             return -1;
>         }
>
>
>         if (datatype.equals("")) {
>             Element child = XUtil.getFirstChildElement(attrDecl);
>
>             while (child != null &&
>
!child.getNodeName().equals(SchemaSymbols.ELT_SIMPLETYPE))
>                 child = XUtil.getNextSiblingElement(child);
>
>
>             if (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_SIMPLETYPE)) {
>                 attType        = XMLAttributeDecl.TYPE_SIMPLE;
>                 dataTypeSymbol = traverseSimpleTypeDecl(child);
>                 localpart = fStringPool.toString(dataTypeSymbol);
>             }
>             else {
>                 attType        = XMLAttributeDecl.TYPE_SIMPLE;
>                 localpart      = "string";
>                 dataTypeSymbol = fStringPool.addSymbol(localpart);
>             }
>             localpart = fStringPool.toString(dataTypeSymbol);
>
>             dv = fDatatypeRegistry.getDatatypeValidator(localpart);
>
>         } else {
>
>             String prefix = "";
>             localpart = datatype;
>             dataTypeSymbol = fStringPool.addSymbol(localpart);
>
>             int  colonptr = datatype.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = datatype.substring(0,colonptr);
>                 localpart = datatype.substring(colonptr+1);
>             }
>             String typeURI = resolvePrefixToURI(prefix);
>
>             if ( typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
>                  || typeURI.length()==0) {
>
>                 dv = getDatatypeValidator("", localpart);
>
>                 if (localpart.equals("ID")) {
>                     attType = XMLAttributeDecl.TYPE_ID;
>                 } else if (localpart.equals("IDREF")) {
>                     attType = XMLAttributeDecl.TYPE_IDREF;
>                 } else if (localpart.equals("IDREFS")) {
>                     attType = XMLAttributeDecl.TYPE_IDREF;
>                     attIsList = true;
>                 } else if (localpart.equals("ENTITY")) {
>                     attType = XMLAttributeDecl.TYPE_ENTITY;
>                 } else if (localpart.equals("ENTITIES")) {
>                     attType = XMLAttributeDecl.TYPE_ENTITY;
>                     attIsList = true;
>                 } else if (localpart.equals("NMTOKEN")) {
>                     attType = XMLAttributeDecl.TYPE_NMTOKEN;
>                 } else if (localpart.equals("NMTOKENS")) {
>                     attType = XMLAttributeDecl.TYPE_NMTOKEN;
>                     attIsList = true;
>                 } else if (localpart.equals(SchemaSymbols.ELT_NOTATION)) {
>                     attType = XMLAttributeDecl.TYPE_NOTATION;
>                 }
>                 else {
>                     attType = XMLAttributeDecl.TYPE_SIMPLE;
>                     if (dv == null && typeURI.length() == 0) {
>                         Element topleveltype =
getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
>                         if (topleveltype != null) {
>                             traverseSimpleTypeDecl( topleveltype );
>                             dv = getDatatypeValidator(typeURI, localpart);
>                         }else {
>                             // REVISIT: Localize
>                             reportGenericSchemaError("simpleType not found
: " + localpart);
>                         }
>                     }
>                 }
>             } else {
>
>                 // check if the type is from the same Schema
>
>                 dv = getDatatypeValidator(typeURI, localpart);
>                 if (dv == null && typeURI.equals(fTargetNSURIString) ) {
>                     Element topleveltype =
getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
>                     if (topleveltype != null) {
>                         traverseSimpleTypeDecl( topleveltype );
>                         dv = getDatatypeValidator(typeURI, localpart);
>                     }else {
>                         // REVISIT: Localize
>                         reportGenericSchemaError("simpleType not found : "
+ localpart);
>                     }
>                 }
>
>                 attType = XMLAttributeDecl.TYPE_SIMPLE;
>             }
>
>         }
>
>
>         // attribute default type
>         int attDefaultType = -1;
>         int attDefaultValue = -1;
>
>         String  use      = attrDecl.getAttribute(SchemaSymbols.ATT_USE);
>         boolean required = use.equals(SchemaSymbols.ATTVAL_REQUIRED);
>
>
>         if (dv == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError("could not resolve the type or get a
null validator for datatype : "
>                                      +
fStringPool.toString(dataTypeSymbol));
>         }
>
>         if (required) {
>             attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
>         } else {
>             if (use.equals(SchemaSymbols.ATTVAL_FIXED)) {
>                 String fixed =
attrDecl.getAttribute(SchemaSymbols.ATT_VALUE);
>                 if (!fixed.equals("")) {
>                     attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_FIXED;
>                     attDefaultValue = fStringPool.addString(fixed);
>                 }
>             }
>             else if (use.equals(SchemaSymbols.ATTVAL_DEFAULT)) {
>                 // attribute default value
>                 String defaultValue =
attrDecl.getAttribute(SchemaSymbols.ATT_VALUE);
>                 if (!defaultValue.equals("")) {
>                     attDefaultType =
XMLAttributeDecl.DEFAULT_TYPE_DEFAULT;
>                     attDefaultValue = fStringPool.addString(defaultValue);
>                 }
>             }
>             else if (use.equals(SchemaSymbols.ATTVAL_PROHIBITED)) {
>
>                 file://REVISIT, TO DO. !!!
>                 attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
>                 file://attDefaultValue = fStringPool.addString("");
>             }
>             else {
>                 attDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
>             }       // check default value is valid for the datatype.
>
>             if (attType == XMLAttributeDecl.TYPE_SIMPLE && attDefaultValue
!= -1) {
>                 try

>                     if (dv != null)
>                         file://REVISIT
>                         dv.validate(fStringPool.toString(attDefaultValue),
null);
>                     else
>
reportSchemaError(SchemaMessageProvider.NoValidatorFor,
>                                           new Object [] { datatype });
>                 } catch (InvalidDatatypeValueException idve) {
>
reportSchemaError(SchemaMessageProvider.IncorrectDefaultType,
>                                       new Object []
 attrDecl.getAttribute(SchemaSymbols.ATT_NAME), idve.getMessage() });
>                 } catch (Exception e) {
>                     e.printStackTrace();
>                     System.out.println("Internal error in attribute
datatype validation");
>                 }
>             }
>         }
>
>         int uriIndex = -1;
>         if ( isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
>              fAttributeDefaultQualified || isTopLevel(attrDecl) ) {
>             uriIndex = fTargetNSURI;
>         }
>
>         QName attQName = new QName(-1,attName,attName,uriIndex);
>         if ( DEBUGGING )
>             System.out.println(" the dataType Validator for " +
fStringPool.toString(attName) + " is " + dv);
>
>         file://put the top-levels in the attribute decl registry.
>         if (isTopLevel(attrDecl)) {
>             fTempAttributeDecl.datatypeValidator = dv;
>             fTempAttributeDecl.name.setValues(attQName);
>             fTempAttributeDecl.type = attType;
>             fTempAttributeDecl.defaultType = attDefaultType;
>             fTempAttributeDecl.list = attIsList;
>             if (attDefaultValue != -1 ) {
>                 fTempAttributeDecl.defaultValue = new
String(fStringPool.toString(attDefaultValue));
>             }
>             fAttributeDeclRegistry.put(attNameStr, new
XMLAttributeDecl(fTempAttributeDecl));
>         }
>
>         // add attribute to attr decl pool in fSchemaGrammar,
>         if (typeInfo != null) {
>             fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
>                                       attQName, attType,
>                                       dataTypeSymbol, attDefaultType,
>
StringPool.toString( attDefaultValue), dv, attIsList);
>         }
>         return -1;
>     } // end of method traverseAttribute
>
>     private int addAttributeDeclFromAnotherSchema( String name, String
uriStr, ComplexTypeInfo typeInfo) throws Exception {
>         SchemaGrammar aGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(uriStr);
>         if (uriStr == null || ! (aGrammar instanceof SchemaGrammar) ) {
>             // REVISIT: Localize
>             reportGenericSchemaError("!!Schema not found in
#addAttributeDeclFromAnotherSchema, schema uri : " + uriStr);
>             return -1;
>         }
>
>         Hashtable attrRegistry = aGrammar.getAttirubteDeclRegistry();
>         if (attrRegistry == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError("no attribute was defined in schema :
" + uriStr);
>             return -1;
>         }
>
>         XMLAttributeDecl tempAttrDecl = (XMLAttributeDecl)
attrRegistry.get(name);
>
>         if (tempAttrDecl == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError( "no attribute named \"" + name
>                                       + "\" was defined in schema : " +
uriStr);
>             return -1;
>         }
>
>
>         if (typeInfo!= null) {
>             fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
>                                       tempAttrDecl.name,
tempAttrDecl.type,
>                                       -1, tempAttrDecl.defaultType,
>                                       tempAttrDecl.defaultValue,
>                                       tempAttrDecl.datatypeValidator,
>                                       tempAttrDecl.list);
>         }
>
>
>         return 0;
>     }
>
>     /*
>     *
>     * <attributeGroup
>     *   id = ID
>     *   name = NCName
>     *   ref = QName>
>     *   Content: (annotation?, (attribute|attributeGroup), anyAttribute?)
>     * </>
>     *
>     */
>     private int traverseAttributeGroupDecl( Element attrGrpDecl,
ComplexTypeInfo typeInfo, Vector anyAttDecls ) throws Exception {
>         // attribute name
>         int attGrpName =
fStringPool.addSymbol(attrGrpDecl.getAttribute(SchemaSymbols.ATT_NAME));
>
>         String ref = attrGrpDecl.getAttribute(SchemaSymbols.ATT_REF);
>
>         // attribute type
>         int attType = -1;
>         int enumeration = -1;
>
>         if (!ref.equals("")) {
>             if (XUtil.getFirstChildElement(attrGrpDecl) != null)
>                 reportSchemaError(SchemaMessageProvider.NoContentForRef,
null);
>             String prefix = "";
>             String localpart = ref;
>             int colonptr = ref.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = ref.substring(0,colonptr);
>                 localpart = ref.substring(colonptr+1);
>             }
>             String uriStr = resolvePrefixToURI(prefix);
>             if (!uriStr.equals(fTargetNSURIString)) {
>
>                 traverseAttributeGroupDeclFromAnotherSchema(localpart,
uriStr, typeInfo, anyAttDecls);
>
>                 return -1;
>                 // TO DO
>                 // REVISIST: different NS, not supported yet.
>                 // REVISIT: Localize
>                 file://reportGenericSchemaError("Feature not supported:
see an attribute from different NS");
>             }
>             Element referredAttrGrp =
getTopLevelComponentByName(SchemaSymbols.ELT_ATTRIBUTEGROUP,localpart);
>             if (referredAttrGrp != null) {
>                 traverseAttributeGroupDecl(referredAttrGrp, typeInfo,
anyAttDecls);
>             }
>             else {
>                 // REVISIT: Localize
>                 reportGenericSchemaError ( "Couldn't find top level
attributegroup " + ref);
>             }
>             return -1;
>         }
>
>         for ( Element child = XUtil.getFirstChildElement(attrGrpDecl);
>              child != null ; child = XUtil.getNextSiblingElement(child)) {
>
>             if
( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTE) ){
>                 traverseAttributeDecl(child, typeInfo);
>             }
>             else if
 child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) {
>                 traverseAttributeGroupDecl(child, typeInfo,anyAttDecls);
>             }
>             else if
 child.getNodeName().equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) {
>                 anyAttDecls.addElement(traverseAnyAttribute(child));
>                 break;
>             }
>             else if
(child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION) ) {
>                 // REVISIT: what about appInfo
>             }
>         }
>         return -1;
>     } // end of method traverseAttributeGroup
>
>     private int traverseAttributeGroupDeclFromAnotherSchema( String
attGrpName , String uriStr,
>
ComplexTypeInfo typeInfo,
>                                                              Vector
anyAttDecls ) throws Exception {
>
>         SchemaGrammar aGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(uriStr);
>         if (uriStr == null || aGrammar == null || ! (aGrammar instanceof
SchemaGrammar) ) {
>             // REVISIT: Localize
>             reportGenericSchemaError("!!Schema not found in
#traverseAttributeGroupDeclFromAnotherSchema, schema uri : " + uriStr);
>             return -1;
>         }
>         // attribute name
>         Element attGrpDecl = (Element)
aGrammar.topLevelAttrGrpDecls.get((Object)attGrpName);
>         if (attGrpDecl == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError( "no attribute group named \"" +
attGrpName
>                                       + "\" was defined in schema : " +
uriStr);
>             return -1;
>         }
>
>         NamespacesScope saveNSMapping = fNamespacesScope;
>         int saveTargetNSUri = fTargetNSURI;
>         fTargetNSURI =
fStringPool.addSymbol(aGrammar.getTargetNamespaceURI());
>         fNamespacesScope = aGrammar.getNamespacesScope();
>
>         // attribute type
>         int attType = -1;
>         int enumeration = -1;
>
>
>         for ( Element child = XUtil.getFirstChildElement(attGrpDecl);
>              child != null ; child = XUtil.getNextSiblingElement(child)) {
>
>             file://child attribute couldn't be a top-level attribute
DEFINITION,
>             if
( child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTE) ){
>                 String childAttName =
child.getAttribute(SchemaSymbols.ATT_NAME);
>                 if ( childAttName.length() > 0 ) {
>                     Hashtable attDeclRegistry =
aGrammar.getAttirubteDeclRegistry();
>                     if (attDeclRegistry != null) {
>                         if (attDeclRegistry.get((Object)childAttName) !=
null ){
>
addAttributeDeclFromAnotherSchema(childAttName, uriStr, typeInfo);
>                             return -1;
>                         }
>                     }
>                 }
>                 else
>                     traverseAttributeDecl(child, typeInfo);
>             }
>             else if
 child.getNodeName().equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) {
>                 traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
>             }
>             else if
 child.getNodeName().equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) {
>                 anyAttDecls.addElement(traverseAnyAttribute(child));
>                 break;
>             }
>             else if
(child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION) ) {
>                 // REVISIT: what about appInfo
>             }
>         }
>
>         fNamespacesScope = saveNSMapping;
>         fTargetNSURI = saveTargetNSUri;
>         return -1;
>     } // end of method traverseAttributeGroupFromAnotherSchema
>
>
>     /**
>      * Traverse element declaration:
>      *  <element
>      *         abstract = boolean
>      *         block = #all or (possibly empty) subset of {equivClass,
extension, restriction}
>      *         default = string
>      *         equivClass = QName
>      *         final = #all or (possibly empty) subset of {extension,
restriction}
>      *         fixed = string
>      *         form = qualified | unqualified
>      *         id = ID
>      *         maxOccurs = string
>      *         minOccurs = nonNegativeInteger
>      *         name = NCName
>      *         nullable = boolean
>      *         ref = QName
>      *         type = QName>
>      *   Content: (annotation? , (simpleType | complexType)? , (unique |
key | keyref)*)
>      *   </element>
>      *
>      *
>      *       The following are identity-constraint definitions
>      *        <unique
>      *         id = ID
>      *         name = NCName>
>      *         Content: (annotation? , (selector , field+))
>      *       </unique>
>      *
>      *       <key
>      *         id = ID
>      *         name = NCName>
>      *         Content: (annotation? , (selector , field+))
>      *       </key>
>      *
>      *       <keyref
>      *         id = ID
>      *         name = NCName
>      *         refer = QName>
>      *         Content: (annotation? , (selector , field+))
>      *       </keyref>
>      *
>      *       <selector>
>      *         Content: XPathExprApprox : An XPath expression
>      *       </selector>
>      *
>      *       <field>
>      *         Content: XPathExprApprox : An XPath expression
>      *       </field>
>      *
>      *
>      * @param elementDecl
>      * @return
>      * @exception Exception
>      */
>     private QName traverseElementDecl(Element elementDecl) throws
Exception {
>
>         int contentSpecType      = -1;
>         int contentSpecNodeIndex = -1;
>         int typeNameIndex = -1;
>         int scopeDefined = -2; file://signal a error if -2 gets gets
through
>                                 file://cause scope can never be -2.
>         DatatypeValidator dv = null;
>
>
>
>         String name = elementDecl.getAttribute(SchemaSymbols.ATT_NAME);
>
>         if ( DEBUGGING )
>             System.out.println("traversing element decl : " + name );
>
>         String ref = elementDecl.getAttribute(SchemaSymbols.ATT_REF);
>         String type = elementDecl.getAttribute(SchemaSymbols.ATT_TYPE);
>         String minOccurs =
elementDecl.getAttribute(SchemaSymbols.ATT_MINOCCURS);
>         String maxOccurs =
elementDecl.getAttribute(SchemaSymbols.ATT_MAXOCCURS);
>         String dflt = elementDecl.getAttribute(SchemaSymbols.ATT_DEFAULT);
>         String fixed = elementDecl.getAttribute(SchemaSymbols.ATT_FIXED);
>         String equivClass =
elementDecl.getAttribute(SchemaSymbols.ATT_EQUIVCLASS);
>         // form attribute
>         String isQName = elementDecl.getAttribute(SchemaSymbols.ATT_FORM);
>
>         String fromAnotherSchema = null;
>
>         if (isTopLevel(elementDecl)) {
>
>             int nameIndex = fStringPool.addSymbol(name);
>             int eltKey = fSchemaGrammar.getElementDeclIndex(fTargetNSURI,
nameIndex,TOP_LEVEL_SCOPE);
>             if (eltKey > -1 ) {
>                 return new QName(-1,nameIndex,nameIndex,fTargetNSURI);
>             }
>         }
>
>         // parse out 'block', 'final', 'nullable', 'abstract'
>         int blockSet =
parseBlockSet(elementDecl.getAttribute(SchemaSymbols.ATT_BLOCK));
>         int finalSet =
parseFinalSet(elementDecl.getAttribute(SchemaSymbols.ATT_FINAL));
>         boolean isNullable = elementDecl.getAttribute
>
(SchemaSymbols.ATT_NULLABLE).equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
>         boolean isAbstract = elementDecl.getAttribute
>
(SchemaSymbols.ATT_ABSTRACT).equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
>         int elementMiscFlags = 0;
>         if (isNullable) {
>             elementMiscFlags += SchemaSymbols.NULLABLE;
>         }
>         if (isAbstract) {
>             elementMiscFlags += SchemaSymbols.ABSTRACT;
>         }
>
>         file://if this is a reference to a global element
>         int attrCount = 0;
>         if (!ref.equals("")) attrCount++;
>         if (!type.equals("")) attrCount++;
>                 file://REVISIT top level check for ref & archref
>         if (attrCount > 1)
>             reportSchemaError(SchemaMessageProvider.OneOfTypeRefArchRef,
null);
>
>         if (!ref.equals("")) {
>             if (XUtil.getFirstChildElement(elementDecl) != null)
>                 reportSchemaError(SchemaMessageProvider.NoContentForRef,
null);
>             String prefix = "";
>             String localpart = ref;
>             int colonptr = ref.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = ref.substring(0,colonptr);
>                 localpart = ref.substring(colonptr+1);
>             }
>             int localpartIndex = fStringPool.addSymbol(localpart);
>             String uriString = resolvePrefixToURI(prefix);
>             QName eltName = new QName(prefix != null ?
fStringPool.addSymbol(prefix) : -1,
>                                       localpartIndex,
>                                       fStringPool.addSymbol(ref),
>                                       uriString != null ?
fStringPool.addSymbol(uriString) : -1);
>
>             file://if from another schema, just return the element QName
>             if (! uriString.equals(fTargetNSURIString) ) {
>                 return eltName;
>             }
>
>             int elementIndex = fSchemaGrammar.getElementDeclIndex(eltName,
TOP_LEVEL_SCOPE);
>             file://if not found, traverse the top level element that if
referenced
>
>             if (elementIndex == -1 ) {
>                 Element targetElement =
getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT,localpart);
>                 if (targetElement == null ) {
>                     // REVISIT: Localize
>                     reportGenericSchemaError("Element " + localpart + "
not found in the Schema");
>                     file://REVISIT, for now, the QName anyway
>                     return eltName;
>                     file://return new
QName(-1,fStringPool.addSymbol(localpart), -1,
fStringPool.addSymbol(uriString));
>                 }
>                 else {
>                     // do nothing here, other wise would cause infinite
loop for
>                     //   <element name="recur"><complexType><element
ref="recur"> ...
>                     file://eltName= traverseElementDecl(targetElement);
>                 }
>             }
>             return eltName;
>         }
>
>         // Handle the equivClass
>         Element equivClassElementDecl = null;
>         int equivClassElementDeclIndex = -1;
>         boolean noErrorSoFar = true;
>         String equivClassUri = null;
>         String equivClassLocalpart = null;
>         String equivClassFullName = null;
>         ComplexTypeInfo equivClassEltTypeInfo = null;
>         DatatypeValidator equivClassEltDV = null;
>
>         if ( equivClass.length() > 0 ) {
>             equivClassUri =  resolvePrefixToURI(getPrefix(equivClass));
>             equivClassLocalpart = getLocalPart(equivClass);
>             equivClassFullName = equivClassUri+","+equivClassLocalpart;
>
>             if ( !equivClassUri.equals(fTargetNSURIString) )

>                 equivClassEltTypeInfo =
getElementDeclTypeInfoFromNS(equivClassUri, equivClassLocalpart);
>                 if (equivClassEltTypeInfo == null) {
>                     equivClassEltDV =
getElementDeclTypeValidatorFromNS(equivClassUri, equivClassLocalpart);
>                     if (equivClassEltDV == null) {
>                         file://TO DO: report error here;
>                         noErrorSoFar = false;
>                         reportGenericSchemaError("Could not find type for
element '" +equivClassLocalpart
>                                                  + "' in schema '" +
equivClassUri+"'");
>                     }
>                 }
>             }
>             else {
>                 equivClassElementDecl =
getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT, equivClassLocalpart);
>                 if (equivClassElementDecl == null) {
>                     equivClassElementDeclIndex =
>                         fSchemaGrammar.getElementDeclIndex(fTargetNSURI,
getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
>                     if ( equivClassElementDeclIndex == -1) {
>                         noErrorSoFar = false;
>                         // REVISIT: Localize
>                         reportGenericSchemaError("Equivclass affiliation
element "
>                                                   +equivClass
>                                                   +" in element
declaration "
>                                                   +name);
>                     }
>                 }
>                 else {
>                     equivClassElementDeclIndex =
>                         fSchemaGrammar.getElementDeclIndex(fTargetNSURI,
getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
>
>                     if ( equivClassElementDeclIndex == -1) {
>                         traverseElementDecl(equivClassElementDecl);
>                         equivClassElementDeclIndex =
>
fSchemaGrammar.getElementDeclIndex(fTargetNSURI,
getLocalPartIndex(equivClass),TOP_LEVEL_SCOPE);
>                     }
>                 }
>
>                 if (equivClassElementDeclIndex != -1) {
>                     equivClassEltTypeInfo =
fSchemaGrammar.getElementComplexTypeInfo( equivClassElementDeclIndex );
>                     if (equivClassEltTypeInfo == null) {
>
fSchemaGrammar.getElementDecl(equivClassElementDeclIndex, fTempElementDecl);
>                         equivClassEltDV =
fTempElementDecl.datatypeValidator;
>                         if (equivClassEltDV == null) {
>                             file://TO DO: report error here;
>                             noErrorSoFar = false;
>                             reportGenericSchemaError("Could not find type
for element '" +equivClassLocalpart
>                                                      + "' in schema '" +
equivClassUri+"'");
>                         }
>                     }
>                 }
>             }
>
>         }
>
>
>         //
>         // resolving the type for this element right here
>         //
>
>         ComplexTypeInfo typeInfo = null;
>
>         // element has a single child element, either a datatype or a
type, null if primitive
>         Element child = XUtil.getFirstChildElement(elementDecl);
>
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         boolean haveAnonType = false;
>
>         // Handle Anonymous type if there is one
>         if (child != null) {
>
>             String childName = child.getNodeName();
>
>             if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
>                 if (child.getAttribute(SchemaSymbols.ATT_NAME).length() >
0) {
>                     noErrorSoFar = false;
>                     // REVISIT: Localize
>                     reportGenericSchemaError("anonymous complexType in
element '" + name +"' has a name attribute");
>                 }
>                 else
>                     typeNameIndex = traverseComplexTypeDecl(child);
>                 if (typeNameIndex != -1 ) {
>                     typeInfo = (ComplexTypeInfo)
>
fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
>                 }
>                 else {
>                     noErrorSoFar = false;
>                     // REVISIT: Localize
>                     reportGenericSchemaError("traverse complexType error
in element '" + name +"'");
>                 }
>                 haveAnonType = true;
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
>                 //   TO DO:  the Default and fixed attribute handling
should be here.
>                 if (child.getAttribute(SchemaSymbols.ATT_NAME).length() >
0) {
>                     noErrorSoFar = false;
>                     // REVISIT: Localize
>                     reportGenericSchemaError("anonymous simpleType in
element '" + name +"' has a name attribute");
>                 }
>                 else
>                     typeNameIndex = traverseSimpleTypeDecl(child);
>                 if (typeNameIndex != -1) {
>                     dv =
fDatatypeRegistry.getDatatypeValidator(fStringPool.toString(typeNameIndex));
>                 }
>                 else {
>                     noErrorSoFar = false;
>                     // REVISIT: Localize
>                     reportGenericSchemaError("traverse simpleType error in
element '" + name +"'");
>                 }
>                 contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>                 haveAnonType = true;
>             } else if (type.equals("")) { // "ur-typed" leaf
>                 contentSpecType = XMLElementDecl.TYPE_ANY;
>                     file://REVISIT: is this right?
>                 file://contentSpecType = fStringPool.addSymbol("UR_TYPE");
>                 // set occurrence count
>                 contentSpecNodeIndex = -1;
>             } else {
>                 System.out.println("unhandled case in
TraverseElementDecl");
>             }
>         }
>
>         // handle type="" here
>         if (haveAnonType && (type.length()>0)) {
>             noErrorSoFar = false;
>             // REVISIT: Localize
>             reportGenericSchemaError( "Element '"+ name +
>                                       "' have both a type attribute and a
annoymous type child" );
>         }
>         // type specified as an attribute and no child is type decl.
>         else if (!type.equals(""))

>             if (equivClassElementDecl != null) {
>                 checkEquivClassOK(elementDecl, equivClassElementDecl);
>             }
>             String prefix = "";
>             String localpart = type;
>             int colonptr = type.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = type.substring(0,colonptr);
>                 localpart = type.substring(colonptr+1);
>             }
>             String typeURI = resolvePrefixToURI(prefix);
>
>             // check if the type is from the same Schema
>             if ( !typeURI.equals(fTargetNSURIString)
>                  && !typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
>                  && typeURI.length() != 0) {  // REVISIT, only needed
because of resolvePrifixToURI.
>                 fromAnotherSchema = typeURI;
>                 typeInfo = getTypeInfoFromNS(typeURI, localpart);
>                 if (typeInfo == null) {
>                     dv = getTypeValidatorFromNS(typeURI, localpart);
>                     if (dv == null) {
>                         file://TO DO: report error here;
>                         noErrorSoFar = false;
>                         reportGenericSchemaError("Could not find type "
+localpart
>                                            + " in schema " + typeURI);
>                     }
>                 }
>             }
>             else {
>                 typeInfo = (ComplexTypeInfo)
fComplexTypeRegistry.get(typeURI+","+localpart);
>                 if (typeInfo == null) {
>                     dv = getDatatypeValidator(typeURI, localpart);
>                     if (dv == null )
>                     if (typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
>                         &&
!fTargetNSURIString.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))
>                     {
>                         noErrorSoFar = false;
>                         // REVISIT: Localize
>                         reportGenericSchemaError("type not found : " +
typeURI+":"+localpart);
>                     }
>                     else {
>                         Element topleveltype =
getTopLevelComponentByName(SchemaSymbols.ELT_COMPLEXTYPE,localpart);
>                         if (topleveltype != null) {
>                             if
(fCurrentTypeNameStack.search((Object)localpart) > - 1) {
>                                 file://then we found a recursive element
using complexType.
>                                 // REVISIT: this will be broken when
recursing happens between 2 schemas
>                                 int uriInd = -1;
>                                 if
 isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
>                                      fElementDefaultQualified) {
>                                     uriInd = fTargetNSURI;
>                                 }
>                                 int nameIndex =
fStringPool.addSymbol(name);
>                                 QName tempQName = new QName(fCurrentScope,
nameIndex, nameIndex, uriInd);
>                                 fElementRecurseComplex.put(tempQName,
localpart);
>                                 return new QName(-1, nameIndex, nameIndex,
uriInd);
>                             }
>                             else {
>                                 typeNameIndex =
raverseComplexTypeDecl( topleveltype );
>                                 typeInfo = (ComplexTypeInfo)
>
fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
>                             }
>                         }
>                         else {
>                             topleveltype =
getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
>                             if (topleveltype != null) {
>                                 typeNameIndex =
raverseSimpleTypeDecl( topleveltype );
>                                 dv = getDatatypeValidator(typeURI,
localpart);
>                                 //   TO DO:  the Default and fixed
attribute handling should be here.
>                             }
>                             else {
>                                 noErrorSoFar = false;
>                                 // REVISIT: Localize
>                                 reportGenericSchemaError("type not found :
" + typeURI+":"+localpart);
>                             }
>
>                         }
>
>                     }
>                 }
>             }
>
>         }
>         else if (haveAnonType){
>             if (equivClassElementDecl != null ) {
>                 checkEquivClassOK(elementDecl, equivClassElementDecl);
>             }
>
>         }
>         // this element is ur-type, check its equivClass afficliation.
>         else {
>             // if there is equivClass affiliation and not type defintion
found for this element,
>             // then grab equivClass affiliation's type and give it to this
element
>             if ( typeInfo == null && dv == null ) typeInfo =
equivClassEltTypeInfo;
>             if ( typeInfo == null && dv == null ) dv = equivClassEltDV;
>         }
>
>         if (typeInfo == null && dv==null) {
>             if (noErrorSoFar) {
>                 // Actually this Element's type definition is ur-type;
>                 contentSpecType = XMLElementDecl.TYPE_ANY;
>                 // REVISIT, need to wait till we have wildcards
implementation.
>                 // ADD attribute wildcards here
>             }
>             else {
>                 noErrorSoFar = false;
>                 // REVISIT: Localize
>                 reportGenericSchemaError ("untyped element : " + name );
>             }
>         }
>         // if element belongs to a compelx type
>         if (typeInfo!=null) {
>             contentSpecNodeIndex = typeInfo.contentSpecHandle;
>             contentSpecType = typeInfo.contentType;
>             scopeDefined = typeInfo.scopeDefined;
>             dv = typeInfo.datatypeValidator;
>         }
>
>         // if element belongs to a simple type
>         if (dv!=null) {
>             contentSpecType = XMLElementDecl.TYPE_SIMPLE;
>             if (typeInfo == null) {
>                 fromAnotherSchema = null; // not to switch schema in this
case
>             }
>         }
>
>         //
>         // key/keyref/unique processing\
>         //
>
>         child = XUtil.getFirstChildElement(elementDecl);
>         Vector idConstraints = null;
>
>         while (child != null){
>             String childName = child.getNodeName();
>            /****
>             if ( childName.equals(SchemaSymbols.ELT_KEY) )

>                 traverseKey(child, idCnstrt);
>             }
>             else if ( childName.equals(SchemaSymbols.ELT_KEYREF) ) {
>                 traverseKeyRef(child, idCnstrt);
>             }
>             else if ( childName.equals(SchemaSymbols.ELT_UNIQUE) ) {
>                 traverseUnique(child, idCnstrt);
>             }
>
>             if (idCnstrt!= null) {
>                 if (idConstraints != null) {
>                     idConstraints = new Vector();
>                 }
>                 idConstraints.addElement(idCnstrt);
>             }
>             /****/
>             child = XUtil.getNextSiblingElement(child);
>         }
>
>         //
>         // Create element decl
>         //
>
>         int elementNameIndex     = fStringPool.addSymbol(name);
>         int localpartIndex = elementNameIndex;
>         int uriIndex = -1;
>         int enclosingScope = fCurrentScope;
>
>         if ( isQName.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
>              fElementDefaultQualified ) {
>             uriIndex = fTargetNSURI;
>         }
>
>         if ( isTopLevel(elementDecl)) {
>             uriIndex = fTargetNSURI;
>             enclosingScope = TOP_LEVEL_SCOPE;
>         }
>
>
>         file://There can never be two elements with the same name and
different type in the same scope.
>         int existSuchElementIndex =
fSchemaGrammar.getElementDeclIndex(uriIndex, localpartIndex,
enclosingScope);
>         if ( existSuchElementIndex > -1) {
>             fSchemaGrammar.getElementDecl(existSuchElementIndex,
fTempElementDecl);
>             DatatypeValidator edv = fTempElementDecl.datatypeValidator;
>             ComplexTypeInfo eTypeInfo =
fSchemaGrammar.getElementComplexTypeInfo(existSuchElementIndex);
>             if ( ((eTypeInfo != null)&&(eTypeInfo!=typeInfo))
>                  || ((edv != null)&&(edv != dv)) )  {
>                 noErrorSoFar = false;
>                 // REVISIT: Localize
>                 reportGenericSchemaError("duplicate element decl in the
same scope : " +
>
fStringPool.toString(localpartIndex));
>
>             }
>         }
>
>         QName eltQName = new
QName(-1,localpartIndex,elementNameIndex,uriIndex);
>
>         // add element decl to pool
>
>         int attrListHead = -1 ;
>
>         // copy up attribute decls from type object
>         if (typeInfo != null) {
>             attrListHead = typeInfo.attlistHead;
>         }
>         int elementIndex = fSchemaGrammar.addElementDecl(eltQName,
enclosingScope, scopeDefined,
>                                                          contentSpecType,
contentSpecNodeIndex,
>                                                          attrListHead,
dv);
>         if ( DEBUGGING ) {
>             /***/
>             System.out.println("########elementIndex:"+elementIndex+"
("+fStringPool.toString(eltQName.uri)+","
>                                + fStringPool.toString(eltQName.localpart)
+ ")"+
>                                " eltType:"+type+"
contentSpecType:"+contentSpecType+
>                                " SpecNodeIndex:"+ contentSpecNodeIndex +"
enclosingScope: " +enclosingScope +
>                                " scopeDefined: " +scopeDefined+"\n");
>              /***/
>         }
>
>         if (typeInfo != null) {
>             fSchemaGrammar.setElementComplexTypeInfo(elementIndex,
typeInfo);
>         }
>         else {
>             fSchemaGrammar.setElementComplexTypeInfo(elementIndex,
typeInfo);
>
>             // REVISIT: should we report error from here?
>         }
>
>         // mark element if its type belongs to different Schema.
>         fSchemaGrammar.setElementFromAnotherSchemaURI(elementIndex,
fromAnotherSchema);
>
>         // set BlockSet, FinalSet, Nullable and Abstract for this element
decl
>         fSchemaGrammar.setElementDeclBlockSet(elementIndex, blockSet);
>         fSchemaGrammar.setElementDeclFinalSet(elementIndex, finalSet);
>         fSchemaGrammar.setElementDeclMiscFlags(elementIndex,
elementMiscFlags);
>
>         // setEquivClassElementFullName
>
fSchemaGrammar.setElementDeclEquivClassElementFullName(elementIndex,
equivClassFullName);
>
>         return eltQName;
>
>     }// end of method traverseElementDecl(Element)
>
>
>     int getLocalPartIndex(String fullName){
>         int colonAt = fullName.indexOf(":");
>         String localpart = fullName;
>         if (  colonAt > -1 ) {
>             localpart = fullName.substring(colonAt+1);
>         }
>         return fStringPool.addSymbol(localpart);
>     }
>
>     String getLocalPart(String fullName){
>         int colonAt = fullName.indexOf(":");
>         String localpart = fullName;
>         if (  colonAt > -1 ) {
>             localpart = fullName.substring(colonAt+1);
>         }
>         return localpart;
>     }
>
>     int getPrefixIndex(String fullName){
>         int colonAt = fullName.indexOf(":");
>         String prefix = "";
>         if (  colonAt > -1 ) {
>             prefix = fullName.substring(0,colonAt);
>         }
>         return fStringPool.addSymbol(prefix);
>     }
>
>     String getPrefix(String fullName){
>         int colonAt = fullName.indexOf(":");
>         String prefix = "";
>         if (  colonAt > -1 ) {
>             prefix = fullName.substring(0,colonAt);
>         }
>         return prefix;
>     }
>
>     private void checkEquivClassOK(Element elementDecl, Element
equivClassElementDecl){
>         file://TO DO!!
>     }
>
>     private Element getTopLevelComponentByName(String componentCategory,
String name) throws Exception {
>         Element child = XUtil.getFirstChildElement(fSchemaRootElement);
>
>         if (child == null) {
>             return null;
>         }
>
>         while (child != null ){
>             if ( child.getNodeName().equals(componentCategory)) {
>                 if
(child.getAttribute(SchemaSymbols.ATT_NAME).equals(name)) {
>                     return child;
>                 }
>             }
>             child = XUtil.getNextSiblingElement(child);
>         }
>
>         return null;
>     }
>
>     private boolean isTopLevel(Element component) {
>         file://REVISIT, is this the right way to check ?
>         /****
>         if (component.getParentNode() == fSchemaRootElement ) {
>             return true;
>         }
>         /****/
>         if
(component.getParentNode().getNodeName().endsWith(SchemaSymbols.ELT_SCHEMA) 
) {
>             return true;
>         }
>         return false;
>     }
>
>     DatatypeValidator getTypeValidatorFromNS(String newSchemaURI, String
localpart) throws Exception {
>         // The following impl is for the case where every Schema Grammar
has its own instance of DatatypeRegistry.
>         // Now that we have only one DataTypeRegistry used by all schemas.
this is not needed.
>         /*****
>         Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
>         if (grammar != null && grammar instanceof SchemaGrammar) {
>             SchemaGrammar sGrammar = (SchemaGrammar) grammar;
>             DatatypeValidator dv = (DatatypeValidator)
fSchemaGrammar.getDatatypeRegistry().getDatatypeValidator(localpart);
>             return dv;
>         }
>         else {
>             reportGenericSchemaError("could not resolve URI : " +
newSchemaURI + " to a SchemaGrammar in getTypeValidatorFromNS");
>         }
>         return null;
>         /*****/
>         return getDatatypeValidator(newSchemaURI, localpart);
>     }
>
>     ComplexTypeInfo getTypeInfoFromNS(String newSchemaURI, String
localpart) throws Exception {
>         Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
>         if (grammar != null && grammar instanceof SchemaGrammar) {
>             SchemaGrammar sGrammar = (SchemaGrammar) grammar;
>             ComplexTypeInfo typeInfo = (ComplexTypeInfo)
sGrammar.getComplexTypeRegistry().get(newSchemaURI+","+localpart);
>             return typeInfo;
>         }
>         else {
>             reportGenericSchemaError("could not resolve URI : " +
newSchemaURI + " to a SchemaGrammar in getTypeInfoFromNS");
>         }
>         return null;
>     }
>
>     DatatypeValidator getElementDeclTypeValidatorFromNS(String
newSchemaURI, String localpart) throws Exception {
>         Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
>         if (grammar != null && grammar instanceof SchemaGrammar) {
>             SchemaGrammar sGrammar = (SchemaGrammar) grammar;
>             int eltIndex =
sGrammar.getElementDeclIndex(fStringPool.addSymbol(newSchemaURI),
>
fStringPool.addSymbol(localpart),
>                                                         TOP_LEVEL_SCOPE);
>
>             DatatypeValidator dv = null;
>             if (eltIndex>-1) {
>                 sGrammar.getElementDecl(eltIndex, fTempElementDecl);
>                 dv = fTempElementDecl.datatypeValidator;
>             }
>             else {
>                 reportGenericSchemaError("could not find global element :
'" + localpart
>                                          + " in the SchemaGrammar
"+newSchemaURI);
>             }
>             return dv;
>         }
>         else {
>             reportGenericSchemaError("could not resolve URI : " +
newSchemaURI
>                                       + " to a SchemaGrammar in
getELementDeclTypeValidatorFromNS");
>         }
>         return null;
>     }
>
>     ComplexTypeInfo getElementDeclTypeInfoFromNS(String newSchemaURI,
String localpart) throws Exception {
>         Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
>         if (grammar != null && grammar instanceof SchemaGrammar) {
>             SchemaGrammar sGrammar = (SchemaGrammar) grammar;
>             int eltIndex =
sGrammar.getElementDeclIndex(fStringPool.addSymbol(newSchemaURI),
>
fStringPool.addSymbol(localpart),
>
TOP_LEVEL_SCOPE);
>             ComplexTypeInfo typeInfo = null;
>             if (eltIndex>-1) {
>                  typeInfo = sGrammar.getElementComplexTypeInfo(eltIndex);
>             }
>             else {
>                 reportGenericSchemaError("could not find global element :
'" + localpart
>                                          + " in the SchemaGrammar
"+newSchemaURI);
>
>             }
>             return typeInfo;
>         }
>         else {
>             reportGenericSchemaError("could not resolve URI : " +
newSchemaURI
>                                      + " to a SchemaGrammar in
getElementDeclTypeInfoFromNS");
>         }
>         return null;
>     }
>
>     /**
>      * Traverse attributeGroup Declaration
>      *
>      *   <attributeGroup
>      *         id = ID
>      *         ref = QName>
>      *         Content: (annotation?)
>      *      </>
>      *
>      * @param elementDecl
>      * @exception Exception
>      */
>     /*private int traverseAttributeGroupDecl( Element attributeGroupDecl )
throws Exception {
>         int attributeGroupID         =  fStringPool.addSymbol(
>
attributeGroupDecl.getAttribute( SchemaSymbols.ATTVAL_ID ));
>
>         int attributeGroupName      =  fStringPool.addSymbol(
>
attributeGroupDecl.getAttribute( SchemaSymbols.ATT_NAME ));
>
>         return -1;
>     }*/
>
>
>     /**
>      * Traverse Group Declaration.
>      *
>      * <group
>      *         id = ID
>      *         maxOccurs = string
>      *         minOccurs = nonNegativeInteger
>      *         name = NCName
>      *         ref = QName>
>      *   Content: (annotation? , (element | group | all | choice |
sequence | any)*)
>      * <group/>
>      *
>      * @param elementDecl
>      * @return
>      * @exception Exception
>      */
>     private int traverseGroupDecl( Element groupDecl ) throws Exception {
>
>         String groupName = groupDecl.getAttribute(SchemaSymbols.ATT_NAME);
>         String ref = groupDecl.getAttribute(SchemaSymbols.ATT_REF);
>
>         if (!ref.equals("")) {
>             if (XUtil.getFirstChildElement(groupDecl) != null)
>                 reportSchemaError(SchemaMessageProvider.NoContentForRef,
null);
>             String prefix = "";
>             String localpart = ref;
>             int colonptr = ref.indexOf(":");
>             if ( colonptr > 0) {
>                 prefix = ref.substring(0,colonptr);
>                 localpart = ref.substring(colonptr+1);
>             }
>             int localpartIndex = fStringPool.addSymbol(localpart);
>
>             String uriStr = resolvePrefixToURI(prefix);
>
>             if (!uriStr.equals(fTargetNSURIString)) {
>                 return traverseGroupDeclFromAnotherSchema(localpart,
uriStr);
>             }
>
>             int contentSpecIndex = -1;
>             Element referredGroup =
getTopLevelComponentByName(SchemaSymbols.ELT_GROUP,localpart);
>             if (referredGroup == null) {
>                 // REVISIT: Localize
>                 reportGenericSchemaError("Group " + localpart + " not
found in the Schema");
>                 file://REVISIT, this should be some custom Exception
>                 throw new Exception("Group " + localpart + " not found in
the Schema");
>             }
>             else {
>                 contentSpecIndex = traverseGroupDecl(referredGroup);
>             }
>
>             return contentSpecIndex;
>         }
>
>         boolean traverseElt = true;
>         if (fCurrentScope == TOP_LEVEL_SCOPE) {
>             traverseElt = false;
>         }
>
>         Element child = XUtil.getFirstChildElement(groupDecl);
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         int contentSpecType = 0;
>         int csnType = 0;
>         int allChildren[] = null;
>         int allChildCount = 0;
>
>         csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
>         contentSpecType = XMLElementDecl.TYPE_CHILDREN;
>
>         int left = -2;
>         int right = -2;
>         boolean hadContent = false;
>         boolean seeAll = false;
>         boolean seeParticle = false;
>
>         for (;
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>             int index = -2;
>             hadContent = true;
>
>             boolean illegalChild = false;
>
>             String childName = child.getNodeName();
>             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                 QName eltQName = traverseElementDecl(child);
>                 index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                        eltQName.localpart,
>                                                        eltQName.uri,
>                                                        false);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                 index = traverseGroupDecl(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ALL)) {
>                 index = traverseAll(child);
>                 file://seeParticle = true;
>                 seeAll = true;
>             }
>             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                 index = traverseChoice(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                 index = traverseSequence(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>                 index = traverseAny(child);
>                 seeParticle = true;
>             }
>             else {
>                 illegalChild = true;
>
reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
>                                   new Object [] { "group", childName });
>             }
>
>             if ( ! illegalChild ) {
>                 index = expandContentModel( index, child);
>             }
>
>             if (seeParticle && seeAll) {
>
eportSchemaError( SchemaMessageProvider.GroupContentRestricted,
>                                    new Object [] { "'all' needs to be
'the' only Child", childName});
>             }
>
>             if (left == -2) {
>                 left = index;
>             } else if (right == -2) {
>                 right = index;
>             } else {
>                 left = fSchemaGrammar.addContentSpecNode(csnType, left,
right, false);
>                 right = index;
>             }
>         }
>         if (hadContent && right != -2)
>             left = fSchemaGrammar.addContentSpecNode(csnType, left, right,
false);
>
>
>         return left;
>     }
>
>     private int traverseGroupDeclFromAnotherSchema( String groupName ,
String uriStr ) throws Exception {
>
>         SchemaGrammar aGrammar = (SchemaGrammar)
fGrammarResolver.getGrammar(uriStr);
>         if (uriStr == null || aGrammar==null ||! (aGrammar instanceof
SchemaGrammar) ) {
>             // REVISIT: Localize
>             reportGenericSchemaError("!!Schema not found in
#traverseGroupDeclFromAnotherSchema, "+
>                                      "schema uri: " + uriStr
>                                      +", groupName: " + groupName);
>             return -1;
>         }
>
>
>         Element groupDecl = (Element)
aGrammar.topLevelGroupDecls.get((Object)groupName);
>         if (groupDecl == null) {
>             // REVISIT: Localize
>             reportGenericSchemaError( "no group named \"" + groupName
>                                       + "\" was defined in schema : " +
uriStr);
>             return -1;
>         }
>
>         NamespacesScope saveNSMapping = fNamespacesScope;
>         int saveTargetNSUri = fTargetNSURI;
>         fTargetNSURI =
fStringPool.addSymbol(aGrammar.getTargetNamespaceURI());
>         fNamespacesScope = aGrammar.getNamespacesScope();
>
>         boolean traverseElt = true;
>         if (fCurrentScope == TOP_LEVEL_SCOPE) {
>             traverseElt = false;
>         }
>
>         Element child = XUtil.getFirstChildElement(groupDecl);
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         int contentSpecType = 0;
>         int csnType = 0;
>         int allChildren[] = null;
>         int allChildCount = 0;
>
>         csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
>         contentSpecType = XMLElementDecl.TYPE_CHILDREN;
>
>         int left = -2;
>         int right = -2;
>         boolean hadContent = false;
>
>         for (;
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>             int index = -2;
>             hadContent = true;
>
>             boolean seeParticle = false;
>             String childName = child.getNodeName();
>             int childNameIndex = fStringPool.addSymbol(childName);
>             String formAttrVal =
child.getAttribute(SchemaSymbols.ATT_FORM);
>             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                 QName eltQName = traverseElementDecl(child);
>                 index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                        eltQName.localpart,
>                                                        eltQName.uri,
>                                                        false);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                 index = traverseGroupDecl(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ALL)) {
>                 index = traverseAll(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                 index = traverseChoice(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                 index = traverseSequence(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>                 index = traverseAny(child);
>                 seeParticle = true;
>             }
>             else {
>
reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
>                                   new Object [] { "group", childName });
>             }
>
>             if (seeParticle) {
>                 index = expandContentModel( index, child);
>             }
>             if (left == -2) {
>                 left = index;
>             } else if (right == -2) {
>                 right = index;
>             } else {
>                 left = fSchemaGrammar.addContentSpecNode(csnType, left,
right, false);
>                 right = index;
>             }
>         }
>         if (hadContent && right != -2)
>             left = fSchemaGrammar.addContentSpecNode(csnType, left, right,
false);
>
>         fNamespacesScope = saveNSMapping;
>         fTargetNSURI = saveTargetNSUri;
>         return left;
>
>
>     } // end of method traverseGroupDeclFromAnotherSchema
>
>     /**
>     *
>     * Traverse the Sequence declaration
>     *
>     * <sequence
>     *   id = ID
>     *   maxOccurs = string
>     *   minOccurs = nonNegativeInteger>
>     *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>     * </sequence>
>     *
>     **/
>     int traverseSequence (Element sequenceDecl) throws Exception {
>
>         Element child = XUtil.getFirstChildElement(sequenceDecl);
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         int contentSpecType = 0;
>         int csnType = 0;
>
>         csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
>         contentSpecType = XMLElementDecl.TYPE_CHILDREN;
>
>         int left = -2;
>         int right = -2;
>         boolean hadContent = false;
>
>         for (;
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>             int index = -2;
>             hadContent = true;
>
>             boolean seeParticle = false;
>             String childName = child.getNodeName();
>             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                 QName eltQName = traverseElementDecl(child);
>                 index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                        eltQName.localpart,
>                                                        eltQName.uri,
>                                                        false);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                 index = traverseGroupDecl(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                 index = traverseChoice(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                 index = traverseSequence(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>                 index = traverseAny(child);
>                 seeParticle = true;
>             }
>             else {
>
reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
>                                   new Object [] { "group", childName });
>             }
>
>             if (seeParticle) {
>                 index = expandContentModel( index, child);
>             }
>             if (left == -2) {
>                 left = index;
>             } else if (right == -2) {
>                 right = index;
>             } else {
>                 left = fSchemaGrammar.addContentSpecNode(csnType, left,
right, false);
>                 right = index;
>             }
>         }
>
>         if (hadContent && right != -2)
>             left = fSchemaGrammar.addContentSpecNode(csnType, left, right,
false);
>
>         return left;
>     }
>
>     /**
>     *
>     * Traverse the Sequence declaration
>     *
>     * <choice
>     *   id = ID
>     *   maxOccurs = string
>     *   minOccurs = nonNegativeInteger>
>     *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>     * </choice>
>     *
>     **/
>     int traverseChoice (Element choiceDecl) throws Exception {
>
>         // REVISIT: traverseChoice, traverseSequence can be combined
>         Element child = XUtil.getFirstChildElement(choiceDecl);
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         int contentSpecType = 0;
>         int csnType = 0;
>
>         csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
>         contentSpecType = XMLElementDecl.TYPE_CHILDREN;
>
>         int left = -2;
>         int right = -2;
>         boolean hadContent = false;
>
>         for (;
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>             int index = -2;
>             hadContent = true;
>
>             boolean seeParticle = false;
>             String childName = child.getNodeName();
>             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                 QName eltQName = traverseElementDecl(child);
>                 index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                        eltQName.localpart,
>                                                        eltQName.uri,
>                                                        false);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                 index = traverseGroupDecl(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                 index = traverseChoice(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                 index = traverseSequence(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>                 index = traverseAny(child);
>                 seeParticle = true;
>             }
>             else {
>
reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
>                                   new Object [] { "group", childName });
>             }
>
>             if (seeParticle) {
>                 index = expandContentModel( index, child);
>             }
>             if (left == -2) {
>                 left = index;
>             } else if (right == -2) {
>                 right = index;
>             } else {
>                 left = fSchemaGrammar.addContentSpecNode(csnType, left,
right, false);
>                 right = index;
>             }
>         }
>
>         if (hadContent && right != -2)
>             left = fSchemaGrammar.addContentSpecNode(csnType, left, right,
false);
>
>         return left;
>     }
>
>
>    /**
>     *
>     * Traverse the "All" declaration
>     *
>     * <all
>     *   id = ID
>     *   maxOccurs = string
>     *   minOccurs = nonNegativeInteger>
>     *   Content: (annotation? , (element | group | choice | sequence |
any)*)
>     * </all>
>     *
>     **/
>
>     int traverseAll( Element allDecl) throws Exception {
>
>         Element child = XUtil.getFirstChildElement(allDecl);
>
>         while (child != null &&
child.getNodeName().equals(SchemaSymbols.ELT_ANNOTATION))
>             child = XUtil.getNextSiblingElement(child);
>
>         int allChildren[] = null;
>         int allChildCount = 0;
>
>         int left = -2;
>
>         for (;
>              child != null;
>              child = XUtil.getNextSiblingElement(child)) {
>
>             int index = -2;
>             boolean seeParticle = false;
>
>             String childName = child.getNodeName();
>
>             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
>                 QName eltQName = traverseElementDecl(child);
>                 index =
SchemaGrammar.addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_LEAF,
>                                                        eltQName.localpart,
>                                                        eltQName.uri,
>                                                        false);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
>                 index = traverseGroupDecl(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
>                     index = traverseChoice(child);
>                     seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
>                 index = traverseSequence(child);
>                 seeParticle = true;
>
>             }
>             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
>                 index = traverseAny(child);
>                 seeParticle = true;
>             }
>             else {
>
reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
>                                   new Object [] { "group", childName });
>             }
>
>             if (seeParticle) {
>                 index = expandContentModel( index, child);
>             }
>             try {
>                 allChildren[allChildCount] = index;
>             }
>             catch (NullPointerException ne) {
>                 allChildren = new int[32];
>                 allChildren[allChildCount] = index;
>             }
>             catch (ArrayIndexOutOfBoundsException ae) {
>                 int[] newArray = new int[allChildren.length*2];
>                 System.arraycopy(allChildren, 0, newArray, 0,
allChildren.length);
>                 allChildren[allChildCount] = index;
>             }
>             allChildCount++;
>         }
>         left = buildAllModel(allChildren,allChildCount);
>
>         return left;
>     }
>
>     /** builds the all content model */
>     private int buildAllModel(int children[], int count) throws Exception
{
>
>         // build all model
>         if (count > 1) {
>
>             // create and initialize singletons
>             XMLContentSpec choice = new XMLContentSpec();
>
>             choice.type = XMLContentSpec.CONTENTSPECNODE_CHOICE;
>             choice.value = -1;
>             choice.otherValue = -1;
>
>             int[] exactChildren = new int[count];
>             System.arraycopy(children,0,exactChildren,0,count);
>             // build all model
>             sort(exactChildren, 0, count);
>             int index = buildAllModel(exactChildren, 0, choice);
>
>             return index;
>         }
>
>         if (count > 0) {
>             return children[0];
>         }
>
>         return -1;
>     }
>
>     /** Builds the all model. */
>     private int buildAllModel(int src[], int offset,
>                               XMLContentSpec choice) throws Exception {
>
>         // swap last two places
>         if (src.length - offset == 2) {
>             int seqIndex = createSeq(src);
>             if (choice.value == -1) {
>                 choice.value = seqIndex;
>             }
>             else {
>                 if (choice.otherValue != -1) {
>                     choice.value =
fSchemaGrammar.addContentSpecNode(choice.type, choice.value,
choice.otherValue, false);
>                 }
>                 choice.otherValue = seqIndex;
>             }
>             swap(src, offset, offset + 1);
>             seqIndex = createSeq(src);
>             if (choice.value == -1) {
>                 choice.value = seqIndex;
>             }
>             else {
>                 if (choice.otherValue != -1) {
>                     choice.value =
fSchemaGrammar.addContentSpecNode(choice.type, choice.value,
choice.otherValue, false);
>                 }
>                 choice.otherValue = seqIndex;
>             }
>             return fSchemaGrammar.addContentSpecNode(choice.type,
choice.value, choice.otherValue, false);
>         }
>
>         // recurse
>         for (int i = offset; i < src.length - 1; i++) {
>             choice.value = buildAllModel(src, offset + 1, choice);
>             choice.otherValue = -1;
>             sort(src, offset, src.length - offset);
>             shift(src, offset, i + 1);
>         }
>
>         int choiceIndex = buildAllModel(src, offset + 1, choice);
>         sort(src, offset, src.length - offset);
>
>         return choiceIndex;
>
>     } // buildAllModel(int[],int,ContentSpecNode,ContentSpecNode):int
>
>     /** Creates a sequence. */
>     private int createSeq(int src[]) throws Exception {
>
>         int left = src[0];
>         int right = src[1];
>
>         for (int i = 2; i < src.length; i++) {
>             left =
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                        left, right,
false);
>             right = src[i];
>         }
>
>         return
fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
>                                                    left, right, false);
>
>     } // createSeq(int[]):int
>
>     /** Shifts a value into position. */
>     private void shift(int src[], int pos, int offset) {
>
>         int temp = src[offset];
>         for (int i = offset; i > pos; i--) {
>             src[i] = src[i - 1];
>         }
>         src[pos] = temp;
>
>     } // shift(int[],int,int)
>
>     /** Simple sort. */
>     private void sort(int src[], final int offset, final int length) {
>
>         for (int i = offset; i < offset + length - 1; i++) {
>             int lowest = i;
>             for (int j = i + 1; j < offset + length; j++) {
>                 if (src[j] < src[lowest]) {
>                     lowest = j;
>                 }
>             }
>             if (lowest != i) {
>                 int temp = src[i];
>                 src[i] = src[lowest];
>                 src[lowest] = temp;
>             }
>         }
>
>     } // sort(int[],int,int)
>
>     /** Swaps two values. */
>     private void swap(int src[], int i, int j) {
>
>         int temp = src[i];
>         src[i] = src[j];
>         src[j] = temp;
>
>     } // swap(int[],int,int)
>
>
>
>     // utilities from Tom Watson's SchemaParser class
>     // TO DO: Need to make this more conformant with Schema int type
parsing
>
>     private int parseInt (String intString) throws Exception
>     {
>             if ( intString.equals("*") ) {
>                     return SchemaSymbols.INFINITY;
>             } else {
>                     return Integer.parseInt (intString);
>             }
>     }
>
>     private int parseSimpleDerivedBy (String derivedByString) throws
Exception
>     {
>             if ( derivedByString.equals (SchemaSymbols.ATTVAL_LIST) ) {
>                     return SchemaSymbols.LIST;
>             }
>             else if ( derivedByString.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                     return SchemaSymbols.RESTRICTION;
>             }
>             else {
>                 // REVISIT: Localize
>                     reportGenericSchemaError ("SimpleType: Invalid value
for 'derivedBy'");
>                     return -1;
>             }
>     }
>
>     private int parseComplexDerivedBy (String derivedByString)  throws
Exception
>     {
>             if ( derivedByString.equals (SchemaSymbols.ATTVAL_EXTENSION) )
{
>                     return SchemaSymbols.EXTENSION;
>             }
>             else if ( derivedByString.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                     return SchemaSymbols.RESTRICTION;
>             }
>             else {
>                 // REVISIT: Localize
>                     reportGenericSchemaError ( "ComplexType: Invalid value
for 'derivedBy'" );
>                     return -1;
>             }
>     }
>
>     private int parseSimpleFinal (String finalString) throws Exception
>     {
>             if ( finalString.equals (SchemaSymbols.ATTVAL_POUNDALL) ) {
>                     return
SchemaSymbols.ENUMERATION+SchemaSymbols.RESTRICTION+SchemaSymbols.LIST+Schem
aSymbols.REPRODUCTION;
>             } else {
>                     int enumerate = 0;
>                     int restrict = 0;
>                     int list = 0;
>                     int reproduce = 0;
>
>                     StringTokenizer t = new StringTokenizer (finalString,
" ");
>                     while (t.hasMoreTokens()) {
>                             String token = t.nextToken ();
>
>                             if ( token.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                                     if ( restrict == 0 ) {
>                                             restrict =
SchemaSymbols.RESTRICTION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
("restriction in set twice");
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_LIST) ) {
>                                     if ( list == 0 ) {
>                                             list = SchemaSymbols.LIST;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
("list in set twice");
>                                     }
>                             }
>                             else {
>                                 // REVISIT: Localize
>                                 reportGenericSchemaError (  "Invalid value
(" +
>                                                             finalString +
>                                                             ")" );
>                             }
>                     }
>
>                     return enumerate+restrict+list+reproduce;
>             }
>     }
>
>     private int parseComplexContent (String contentString)  throws
Exception
>     {
>             if ( contentString.equals (SchemaSymbols.ATTVAL_EMPTY) ) {
>                     return XMLElementDecl.TYPE_EMPTY;
>             } else if ( contentString.equals
(SchemaSymbols.ATTVAL_ELEMENTONLY) ) {
>                     return XMLElementDecl.TYPE_CHILDREN;
>             } else if ( contentString.equals
(SchemaSymbols.ATTVAL_TEXTONLY) ) {
>                     return XMLElementDecl.TYPE_SIMPLE;
>             } else if ( contentString.equals
(SchemaSymbols.ATTVAL_MIXED) ) {
>                     return XMLElementDecl.TYPE_MIXED;
>             } else {
>                 // REVISIT: Localize
>                     reportGenericSchemaError ( "Invalid value for
content" );
>                     return -1;
>             }
>     }
>
>     private int parseDerivationSet (String finalString)  throws Exception
>     {
>             if ( finalString.equals ("#all") ) {
>                     return
SchemaSymbols.EXTENSION+SchemaSymbols.RESTRICTION+SchemaSymbols.REPRODUCTION
;
>             } else {
>                     int extend = 0;
>                     int restrict = 0;
>                     int reproduce = 0;
>
>                     StringTokenizer t = new StringTokenizer (finalString,
" ");
>                     while (t.hasMoreTokens()) {
>                             String token = t.nextToken ();
>
>                             if ( token.equals
(SchemaSymbols.ATTVAL_EXTENSION) ) {
>                                     if ( extend == 0 ) {
>                                             extend =
SchemaSymbols.EXTENSION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "extension already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                                     if ( restrict == 0 ) {
>                                             restrict =
SchemaSymbols.RESTRICTION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "restriction already in set" );
>                                     }
>                             } else {
>                                 // REVISIT: Localize
>                                     reportGenericSchemaError ( "Invalid
final value (" + finalString + ")" );
>                             }
>                     }
>
>                     return extend+restrict+reproduce;
>             }
>     }
>
>     private int parseBlockSet (String finalString)  throws Exception
>     {
>             if ( finalString.equals ("#all") ) {
>                     return
SchemaSymbols.EQUIVCLASS+SchemaSymbols.EXTENSION+SchemaSymbols.LIST+SchemaSy
mbols.RESTRICTION+SchemaSymbols.REPRODUCTION;
>             } else {
>                     int extend = 0;
>                     int restrict = 0;
>                     int reproduce = 0;
>
>                     StringTokenizer t = new StringTokenizer (finalString,
" ");
>                     while (t.hasMoreTokens()) {
>                             String token = t.nextToken ();
>
>                             if ( token.equals
(SchemaSymbols.ATTVAL_EQUIVCLASS) ) {
>                                     if ( extend == 0 ) {
>                                             extend =
SchemaSymbols.EQUIVCLASS;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "'equivClass' already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_EXTENSION) ) {
>                                     if ( extend == 0 ) {
>                                             extend =
SchemaSymbols.EXTENSION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "extension already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_LIST) ) {
>                                     if ( extend == 0 ) {
>                                             extend = SchemaSymbols.LIST;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "'list' already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                                     if ( restrict == 0 ) {
>                                             restrict =
SchemaSymbols.RESTRICTION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "restriction already in set" );
>                                     }
>                             } else {
>                                 // REVISIT: Localize
>                                     reportGenericSchemaError ( "Invalid
final value (" + finalString + ")" );
>                             }
>                     }
>
>                     return extend+restrict+reproduce;
>             }
>     }
>
>     private int parseFinalSet (String finalString)  throws Exception
>     {
>             if ( finalString.equals ("#all") ) {
>                     return
SchemaSymbols.EQUIVCLASS+SchemaSymbols.EXTENSION+SchemaSymbols.LIST+SchemaSy
mbols.RESTRICTION+SchemaSymbols.REPRODUCTION;
>             } else {
>                     int extend = 0;
>                     int restrict = 0;
>                     int reproduce = 0;
>
>                     StringTokenizer t = new StringTokenizer (finalString,
" ");
>                     while (t.hasMoreTokens()) {
>                             String token = t.nextToken ();
>
>                             if ( token.equals
(SchemaSymbols.ATTVAL_EQUIVCLASS) ) {
>                                     if ( extend == 0 ) {
>                                             extend =
SchemaSymbols.EQUIVCLASS;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "'equivClass' already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_EXTENSION) ) {
>                                     if ( extend == 0 ) {
>                                             extend =
SchemaSymbols.EXTENSION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "extension already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_LIST) ) {
>                                     if ( extend == 0 ) {
>                                             extend = SchemaSymbols.LIST;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "'list' already in set" );
>                                     }
>                             } else if ( token.equals
(SchemaSymbols.ATTVAL_RESTRICTION) ) {
>                                     if ( restrict == 0 ) {
>                                             restrict =
SchemaSymbols.RESTRICTION;
>                                     } else {
>                                         // REVISIT: Localize
>                                             reportGenericSchemaError
 "restriction already in set" );
>                                     }
>                             } else {
>                                 // REVISIT: Localize
>                                     reportGenericSchemaError ( "Invalid
final value (" + finalString + ")" );
>                             }
>                     }
>
>                     return extend+restrict+reproduce;
>             }
>     }
>
>     private void reportGenericSchemaError (String error) throws Exception
{
>         if (fErrorReporter == null) {
>             System.err.println("__TraverseSchemaError__ : " + error);
>         }
>         else {
>             reportSchemaError (SchemaMessageProvider.GenericError, new
Object[] { error });
>         }
>     }
>
>
>     private void reportSchemaError(int major, Object args[]) throws
Exception {
>         if (fErrorReporter == null) {
>             System.out.println("__TraverseSchemaError__ : " +
SchemaMessageProvider.fgMessageKeys[major]);
>             for (int i=0; i< args.length ; i++) {
>                 System.out.println((String)args[i]);
>             }
>         }
>         else {
>             fErrorReporter.reportError(fErrorReporter.getLocator(),
>
SchemaMessageProvider.SCHEMA_DOMAIN,
>                                        major,
>                                        SchemaMessageProvider.MSG_NONE,
>                                        args,
>
XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
>         }
>     }
>
>     file://Unit Test here
>     public static void main(String args[] ) {
>
>         if( args.length != 1 ) {
>             System.out.println( "Error: Usage java TraverseSchema
yourFile.xsd" );
>             System.exit(0);
>         }
>
>         DOMParser parser = new DOMParser() {
>             public void ignorableWhitespace(char ch[], int start, int
length) {}
>             public void ignorableWhitespace(int dataIdx) {}
>         };
>         parser.setEntityResolver( new Resolver() );
>         parser.setErrorHandler(  new ErrorHandler() );
>
>         try {
>         parser.setFeature("http://xml.org/sax/features/validation",
false);
>
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
false);
>         }catch(  org.xml.sax.SAXNotRecognizedException e ) {
>             e.printStackTrace();
>         }catch( org.xml.sax.SAXNotSupportedException e ) {
>             e.printStackTrace();
>         }
>
>         try {
>         parser.parse( args[0]);
>         }catch( IOException e ) {
>             e.printStackTrace();
>         }catch( SAXException e ) {
>             e.printStackTrace();
>         }
>
>         Document     document   = parser.getDocument(); file://Our Grammar
>
>         OutputFormat    format  = new OutputFormat( document );
>         java.io.StringWriter outWriter = new java.io.StringWriter();
>         XMLSerializer    serial = new XMLSerializer( outWriter,format);
>
>         TraverseSchema tst = null;
>         try {
>             Element root   = document.getDocumentElement();// This is what
we pass to TraverserSchema
>             file://serial.serialize( root );
>             file://System.out.println(outWriter.toString());
>
>             tst = new TraverseSchema( root, new StringPool(), new
SchemaGrammar(), (GrammarResolver) new GrammarResolverImpl() );
>             }
>             catch (Exception e) {
>                 e.printStackTrace(System.err);
>             }
>
>             parser.getDocument();
>     }
>
>     static class Resolver implements EntityResolver {
>         private static final String SYSTEM[] = {
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
>
"http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
>         };
>         private static final String PATH[] = {
>             "structures.dtd",
>             "datatypes.dtd",
>             "versionInfo.ent",
>         };
>
>         public InputSource resolveEntity(String publicId, String systemId)
>         throws IOException {
>
>             // looking for the schema DTDs?
>             for (int i = 0; i < SYSTEM.length; i++) {
>                 if (systemId.equals(SYSTEM[i])) {
>                     InputSource source = new
InputSource(getClass().getResourceAsStream(PATH[i]));
>                     source.setPublicId(publicId);
>                     source.setSystemId(systemId);
>                     return source;
>                 }
>             }
>
>             // use default resolution
>             return null;
>
>         } // resolveEntity(String,String):InputSource
>
>     } // class Resolver
>
>     static class ErrorHandler implements org.xml.sax.ErrorHandler {
>
>         /** Warning. */
>         public void warning(SAXParseException ex) {
>             System.err.println("[Warning] "+
>                                getLocationString(ex)+": "+
>                                ex.getMessage());
>         }
>
>         /** Error. */
>         public void error(SAXParseException ex) {
>             System.err.println("[Error] "+
>                                getLocationString(ex)+": "+
>                                ex.getMessage());
>         }
>
>         /** Fatal error. */
>         public void fatalError(SAXParseException ex) throws SAXException {
>             System.err.println("[Fatal Error] "+
>                                getLocationString(ex)+": "+
>                                ex.getMessage());
>             throw ex;
>         }
>
>         //
>         // Private methods
>         //
>
>         /** Returns a string of the location. */
>         private String getLocationString(SAXParseException ex) {
>             StringBuffer str = new StringBuffer();
>
>             String systemId_ = ex.getSystemId();
>             if (systemId_ != null) {
>                 int index = systemId_.lastIndexOf('/');
>                 if (index != -1)
>                     systemId_ = systemId_.substring(index + 1);
>                 str.append(systemId_);
>             }
>             str.append(':');
>             str.append(ex.getLineNumber());
>             str.append(':');
>             str.append(ex.getColumnNumber());
>
>             return str.toString();
>
>         } // getLocationString(SAXParseException):String
>     }
>
>
> }
>
>
>
>
>
>
>


----------------------------------------------------------------------------
----


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