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