KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > schema > TraverseSchema


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2000,2001 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57 package org.enhydra.apache.xerces.validators.schema;
58
59 import java.io.IOException JavaDoc;
60 import java.net.MalformedURLException JavaDoc;
61 import java.net.URL JavaDoc;
62 import java.util.Enumeration JavaDoc;
63 import java.util.Hashtable JavaDoc;
64 import java.util.Stack JavaDoc;
65 import java.util.StringTokenizer JavaDoc;
66 import java.util.Vector JavaDoc;
67
68 import org.enhydra.apache.xerces.framework.XMLContentSpec;
69 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
70 import org.enhydra.apache.xerces.parsers.DOMParser;
71 import org.enhydra.apache.xerces.utils.NamespacesScope;
72 import org.enhydra.apache.xerces.utils.QName;
73 import org.enhydra.apache.xerces.utils.StringPool;
74 import org.enhydra.apache.xerces.validators.common.Grammar;
75 import org.enhydra.apache.xerces.validators.common.GrammarResolver;
76 import org.enhydra.apache.xerces.validators.common.XMLAttributeDecl;
77 import org.enhydra.apache.xerces.validators.common.XMLElementDecl;
78 import org.enhydra.apache.xerces.validators.datatype.AnySimpleType;
79 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidator;
80 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
81 import org.enhydra.apache.xerces.validators.datatype.IDDatatypeValidator;
82 import org.enhydra.apache.xerces.validators.datatype.InvalidDatatypeValueException;
83 import org.enhydra.apache.xerces.validators.datatype.ListDatatypeValidator;
84 import org.enhydra.apache.xerces.validators.datatype.NOTATIONDatatypeValidator;
85 import org.enhydra.apache.xerces.validators.datatype.StringDatatypeValidator;
86 import org.enhydra.apache.xerces.validators.datatype.UnionDatatypeValidator;
87 import org.enhydra.apache.xerces.validators.schema.identity.Field;
88 import org.enhydra.apache.xerces.validators.schema.identity.IdentityConstraint;
89 import org.enhydra.apache.xerces.validators.schema.identity.Key;
90 import org.enhydra.apache.xerces.validators.schema.identity.KeyRef;
91 import org.enhydra.apache.xerces.validators.schema.identity.Selector;
92 import org.enhydra.apache.xerces.validators.schema.identity.Unique;
93 import org.enhydra.apache.xerces.validators.schema.identity.XPathException;
94 import org.w3c.dom.Attr JavaDoc;
95 import org.w3c.dom.Document JavaDoc;
96 import org.w3c.dom.Element JavaDoc;
97 import org.w3c.dom.NamedNodeMap JavaDoc;
98 import org.w3c.dom.Node JavaDoc;
99 import org.xml.sax.EntityResolver JavaDoc;
100 import org.xml.sax.InputSource JavaDoc;
101 import org.xml.sax.SAXException JavaDoc;
102 import org.xml.sax.SAXParseException JavaDoc;
103
104 /**
105  * Instances of this class get delegated to Traverse the Schema and
106  * to populate the Grammar internal representation by
107  * instances of Grammar objects.
108  * Traverse a Schema Grammar:
109  *
110  * @author Eric Ye, IBM
111  * @author Jeffrey Rodriguez, IBM
112  * @author Andy Clark, IBM
113  *
114  * @see org.enhydra.apache.xerces.validators.common.Grammar
115  *
116  * @version $Id: TraverseSchema.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
117  */

118 public class TraverseSchema implements
119                             NamespacesScope.NamespacesHandler{
120
121     //CONSTANTS
122
private static final int TOP_LEVEL_SCOPE = -1;
123
124     /** Identity constraint keywords. */
125     private static final String JavaDoc[][] IDENTITY_CONSTRAINTS = {
126         { SchemaSymbols.URI_SCHEMAFORSCHEMA, SchemaSymbols.ELT_UNIQUE },
127         { SchemaSymbols.URI_SCHEMAFORSCHEMA, SchemaSymbols.ELT_KEY },
128         { SchemaSymbols.URI_SCHEMAFORSCHEMA, SchemaSymbols.ELT_KEYREF },
129     };
130     // hopefully a string people will not use in their names very often...
131
private static final String JavaDoc redefIdentifier = "_fn3dktizrknc9pi";
132     // fields to hold application-specified schemaLocations
133
private String JavaDoc fUnparsedExternalSchemas = null;
134     private Hashtable JavaDoc fExternalSchemas = null;
135     private String JavaDoc fExternalNoNamespaceSchema = null;
136     // Flags for handleOccurrences to indicate any special
137
// restrictions on minOccurs and maxOccurs relating to "all".
138
// NOT_ALL_CONTEXT - not processing an <all>
139
// PROCESSING_ALL_EL - processing an <element> in an <all>
140
// GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
141
// CHILD_OF_GROUP - processing a child of a model group definition
142
// PROCESSING_ALL_GP - processing an <all> group itself
143
private static final int NOT_ALL_CONTEXT = 0;
144     private static final int PROCESSING_ALL_EL = 1;
145     private static final int GROUP_REF_WITH_ALL = 2;
146     private static final int CHILD_OF_GROUP = 4;
147     private static final int PROCESSING_ALL_GP = 8;
148
149     //debugging
150
private static final boolean DEBUGGING = false;
151
152     /** Compile to true to debug identity constraints. */
153     private static final boolean DEBUG_IDENTITY_CONSTRAINTS = false;
154     private static final boolean DEBUG_NEW_GROUP = true;
155
156     /**
157      * Compile to true to debug datatype validator lookup for
158      * identity constraint support.
159      */

160     private static final boolean DEBUG_IC_DATATYPES = false;
161
162     //private data members
163

164     private boolean fFullConstraintChecking = false;
165
166     private XMLErrorReporter fErrorReporter = null;
167     private StringPool fStringPool = null;
168
169     private GrammarResolver fGrammarResolver = null;
170     private SchemaGrammar fSchemaGrammar = null;
171
172     private Element JavaDoc fSchemaRootElement;
173     // this is always set to refer to the root of the linked list containing the root info of schemas under redefinition.
174
private SchemaInfo fSchemaInfoListRoot = null;
175     private SchemaInfo fCurrentSchemaInfo = null;
176     private boolean fRedefineSucceeded;
177
178     private DatatypeValidatorFactoryImpl fDatatypeRegistry = null;
179
180     private Hashtable JavaDoc fComplexTypeRegistry = new Hashtable JavaDoc();
181     private Hashtable JavaDoc fAttributeDeclRegistry = new Hashtable JavaDoc();
182
183     // stores the names of groups that we've traversed so we can avoid multiple traversals
184
// qualified group names are keys and their contentSpecIndexes are values.
185
private Hashtable JavaDoc fGroupNameRegistry = new Hashtable JavaDoc();
186     // this Hashtable keeps track of whether a given redefined group does so by restriction.
187
private Hashtable JavaDoc fRestrictedRedefinedGroupRegistry = new Hashtable JavaDoc();
188
189     // stores "final" values of simpleTypes--no clean way to integrate this into the existing datatype validation structure...
190
private Hashtable JavaDoc fSimpleTypeFinalRegistry = new Hashtable JavaDoc();
191
192     // stores <notation> decl
193
private Hashtable JavaDoc fNotationRegistry = new Hashtable JavaDoc();
194
195     private Vector JavaDoc fIncludeLocations = new Vector JavaDoc();
196     private Vector JavaDoc fImportLocations = new Vector JavaDoc();
197     private Hashtable JavaDoc fRedefineLocations = new Hashtable JavaDoc();
198     private Vector JavaDoc fTraversedRedefineElements = new Vector JavaDoc();
199     // Hashtable associating attributeGroups within a <redefine> which
200
// restrict attributeGroups in the original schema with the
201
// new name for those groups in the modified redefined schema.
202
private Hashtable JavaDoc fRedefineAttributeGroupMap = null;
203
204     // simpleType data
205
private Hashtable JavaDoc fFacetData = new Hashtable JavaDoc(10);
206     private Stack JavaDoc fSimpleTypeNameStack = new Stack JavaDoc();
207     private String JavaDoc fListName = "";
208
209
210     private int fAnonTypeCount =0;
211     private int fScopeCount=0;
212     private int fCurrentScope=TOP_LEVEL_SCOPE;
213     private int fSimpleTypeAnonCount = 0;
214     private Stack JavaDoc fCurrentTypeNameStack = new Stack JavaDoc();
215     private Stack JavaDoc fBaseTypeNameStack = new Stack JavaDoc();
216     private Stack JavaDoc fCurrentGroupNameStack = new Stack JavaDoc();
217     private Vector JavaDoc fElementRecurseComplex = new Vector JavaDoc();
218     private Vector JavaDoc fTopLevelElementsRefdFromGroup = new Vector JavaDoc();
219     private Stack JavaDoc fCurrentAttrGroupNameStack = new Stack JavaDoc();
220
221     private Vector JavaDoc fSubstitutionGroupRecursionRegistry = new Vector JavaDoc();
222     private boolean fElementDefaultQualified = false;
223     private boolean fAttributeDefaultQualified = false;
224     private int fBlockDefault = 0;
225     private int fFinalDefault = 0;
226
227     private int fTargetNSURI;
228     private String JavaDoc fTargetNSURIString = "";
229     private NamespacesScope fNamespacesScope = null;
230     private String JavaDoc fCurrentSchemaURL = "";
231     private Stack JavaDoc fSchemaURLStack = new Stack JavaDoc();
232
233     private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
234     private XMLAttributeDecl fTemp2AttributeDecl = new XMLAttributeDecl();
235     private XMLElementDecl fTempElementDecl = new XMLElementDecl();
236     private XMLElementDecl fTempElementDecl2 = new XMLElementDecl();
237     private XMLContentSpec tempContentSpec1 = new XMLContentSpec();
238     private XMLContentSpec tempContentSpec2 = new XMLContentSpec();
239
240     private EntityResolver JavaDoc fEntityResolver = null;
241     private SubstitutionGroupComparator fSComp = null;
242
243     private Hashtable JavaDoc fIdentityConstraints = new Hashtable JavaDoc();
244     // Yet one more data structure; this one associates
245
// <unique> and <key> QNames with their corresponding objects,
246
// so that <keyRef>s can find them.
247
private Hashtable JavaDoc fIdentityConstraintNames = new Hashtable JavaDoc();
248
249     // General Attribute Checking
250
private GeneralAttrCheck fGeneralAttrCheck = null;
251     private int fXsiURI;
252
253    // REVISIT: maybe need to be moved into SchemaGrammar class
254
public class ComplexTypeInfo {
255         public String JavaDoc typeName;
256
257         public DatatypeValidator baseDataTypeValidator;
258         public ComplexTypeInfo baseComplexTypeInfo;
259
260         public int derivedBy = 0;
261         public int blockSet = 0;
262         public int finalSet = 0;
263
264         public int miscFlags=0;
265
266         public int scopeDefined = -1;
267
268         public int contentType;
269         public int contentSpecHandle = -1;
270         public int templateElementIndex = -1;
271         public int attlistHead = -1;
272         public DatatypeValidator datatypeValidator;
273
274         public boolean isAbstractType() {
275            return ((miscFlags & CT_IS_ABSTRACT)!=0);
276         }
277         public boolean containsAttrTypeID () {
278            return ((miscFlags & CT_CONTAINS_ATTR_TYPE_ID)!=0);
279         }
280         public boolean declSeen () {
281            return ((miscFlags & CT_DECL_SEEN)!=0);
282         }
283
284         public void setIsAbstractType() {
285            miscFlags |= CT_IS_ABSTRACT;
286         }
287         public void setContainsAttrTypeID() {
288            miscFlags |= CT_CONTAINS_ATTR_TYPE_ID;
289         }
290         public void setDeclSeen() {
291            miscFlags |= CT_DECL_SEEN;
292         }
293
294     }
295     private static final int CT_IS_ABSTRACT=1;
296     private static final int CT_CONTAINS_ATTR_TYPE_ID=2;
297     private static final int CT_DECL_SEEN=4; // indicates that the declaration was
298
// traversed as opposed to processed due
299
// to a forward reference
300

301     private class ComplexTypeRecoverableError extends Exception JavaDoc {
302         ComplexTypeRecoverableError() {super();}
303         ComplexTypeRecoverableError(String JavaDoc s) {super(s);}
304     }
305
306     private class ParticleRecoverableError extends Exception JavaDoc {
307         ParticleRecoverableError(String JavaDoc s) {super(s);}
308     }
309
310     private class GroupInfo {
311         int contentSpecIndex = -1;
312         int scope = -1;
313     }
314
315     private class ElementInfo {
316         int elementIndex;
317         String JavaDoc typeName;
318
319         private ElementInfo(int i, String JavaDoc name) {
320            elementIndex = i;
321            typeName = name;
322         }
323     }
324
325     //REVISIT: verify the URI.
326
public final static String JavaDoc SchemaForSchemaURI = "http://www.w3.org/TR-1/Schema";
327
328     private TraverseSchema( ) {
329         // new TraverseSchema() is forbidden;
330
}
331
332     public void setFullConstraintCheckingEnabled() {
333         fFullConstraintChecking = true;
334     }
335
336     public void setGrammarResolver(GrammarResolver grammarResolver){
337         fGrammarResolver = grammarResolver;
338     }
339     public void startNamespaceDeclScope(int prefix, int uri){
340         //TO DO
341
}
342     public void endNamespaceDeclScope(int prefix){
343         //TO DO, do we need to do anything here?
344
}
345
346     public boolean particleEmptiable(int contentSpecIndex) {
347
348        if (!fFullConstraintChecking) {
349            return true;
350        }
351        if (minEffectiveTotalRange(contentSpecIndex)==0)
352          return true;
353        else
354          return false;
355     }
356
357     public int minEffectiveTotalRange(int contentSpecIndex) {
358
359        fSchemaGrammar.getContentSpec(contentSpecIndex, tempContentSpec1);
360        int type = tempContentSpec1.type;
361        if (type == XMLContentSpec.CONTENTSPECNODE_SEQ ||
362            type == XMLContentSpec.CONTENTSPECNODE_ALL) {
363           return minEffectiveTotalRangeSeq(contentSpecIndex);
364        }
365        else if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
366           return minEffectiveTotalRangeChoice(contentSpecIndex);
367        }
368        else {
369           return(fSchemaGrammar.getContentSpecMinOccurs(contentSpecIndex));
370        }
371
372     }
373
374     private int minEffectiveTotalRangeSeq(int csIndex) {
375
376        fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
377        int type = tempContentSpec1.type;
378        int left = tempContentSpec1.value;
379        int right = tempContentSpec1.otherValue;
380        int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
381
382        int result;
383        if (right == -2)
384           result = min * minEffectiveTotalRange(left);
385        else
386           result = min * (minEffectiveTotalRange(left) + minEffectiveTotalRange(right));
387        return result;
388
389     }
390     private int minEffectiveTotalRangeChoice(int csIndex) {
391
392        fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
393        int type = tempContentSpec1.type;
394        int left = tempContentSpec1.value;
395        int right = tempContentSpec1.otherValue;
396        int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
397
398        int result;
399        if (right == -2)
400           result = min * minEffectiveTotalRange(left);
401        else {
402           int minLeft = minEffectiveTotalRange(left);
403           int minRight = minEffectiveTotalRange(right);
404           result = min * ((minLeft < minRight)?minLeft:minRight);
405        }
406        return result;
407     }
408
409     public int maxEffectiveTotalRange(int contentSpecIndex) {
410
411        fSchemaGrammar.getContentSpec(contentSpecIndex, tempContentSpec1);
412        int type = tempContentSpec1.type;
413        if (type == XMLContentSpec.CONTENTSPECNODE_SEQ ||
414            type == XMLContentSpec.CONTENTSPECNODE_ALL) {
415           return maxEffectiveTotalRangeSeq(contentSpecIndex);
416        }
417        else if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
418           return maxEffectiveTotalRangeChoice(contentSpecIndex);
419        }
420        else {
421           return(fSchemaGrammar.getContentSpecMaxOccurs(contentSpecIndex));
422        }
423
424     }
425
426     private int maxEffectiveTotalRangeSeq(int csIndex) {
427
428        fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
429        int type = tempContentSpec1.type;
430        int left = tempContentSpec1.value;
431        int right = tempContentSpec1.otherValue;
432        int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
433
434        if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
435          return SchemaSymbols.OCCURRENCE_UNBOUNDED;
436
437        int maxLeft = maxEffectiveTotalRange(left);
438        if (right == -2) {
439          if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
440            return SchemaSymbols.OCCURRENCE_UNBOUNDED;
441          else
442            return max * maxLeft;
443        }
444        else {
445          int maxRight = maxEffectiveTotalRange(right);
446          if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED ||
447             maxRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
448            return SchemaSymbols.OCCURRENCE_UNBOUNDED;
449          else
450            return max * (maxLeft + maxRight);
451        }
452     }
453
454     private int maxEffectiveTotalRangeChoice(int csIndex) {
455
456        fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
457        int type = tempContentSpec1.type;
458        int left = tempContentSpec1.value;
459        int right = tempContentSpec1.otherValue;
460        int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
461
462        if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
463          return SchemaSymbols.OCCURRENCE_UNBOUNDED;
464
465        int maxLeft = maxEffectiveTotalRange(left);
466        if (right == -2) {
467          if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
468            return SchemaSymbols.OCCURRENCE_UNBOUNDED;
469          else
470            return max * maxLeft;
471        }
472        else {
473          int maxRight = maxEffectiveTotalRange(right);
474          if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED ||
475             maxRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
476            return SchemaSymbols.OCCURRENCE_UNBOUNDED;
477          else
478            return max * ((maxLeft > maxRight)?maxLeft:maxRight);
479        }
480     }
481
482
483     private String JavaDoc resolvePrefixToURI (String JavaDoc prefix) throws Exception JavaDoc {
484         String JavaDoc uriStr = fStringPool.toString(fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix)));
485         if (uriStr.length() == 0 && prefix.length() > 0) {
486             // REVISIT: Localize
487
reportGenericSchemaError("prefix : [" + prefix +"] cannot be resolved to a URI");
488             return "";
489         }
490
491         return uriStr;
492     }
493
494     public TraverseSchema(Element JavaDoc root, StringPool stringPool,
495                            SchemaGrammar schemaGrammar,
496                            GrammarResolver grammarResolver,
497                            XMLErrorReporter errorReporter,
498                            String JavaDoc schemaURL,
499                            EntityResolver JavaDoc entityResolver,
500                            boolean fullChecking,
501                            GeneralAttrCheck generalAttrCheck,
502                            String JavaDoc externalSchemaLocations, String JavaDoc noNamespaceSchemaLocation
503                            ) throws Exception JavaDoc {
504         fErrorReporter = errorReporter;
505         fCurrentSchemaURL = schemaURL;
506         fFullConstraintChecking = fullChecking;
507         fEntityResolver = entityResolver;
508         fGeneralAttrCheck = generalAttrCheck;
509         fUnparsedExternalSchemas = externalSchemaLocations;
510         if(externalSchemaLocations != null) {
511             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(externalSchemaLocations, " \n\t\r", false);
512             int tokenTotal = tokenizer.countTokens();
513             if (tokenTotal % 2 == 0 ) {
514                 fExternalSchemas = new Hashtable JavaDoc();
515                 String JavaDoc uri = null;
516                 String JavaDoc location = null;
517                 while (tokenizer.hasMoreTokens()) {
518                     uri = tokenizer.nextToken();
519                     location = tokenizer.nextToken();
520                     fExternalSchemas.put(location, uri);
521                 }
522             }
523         }
524         fExternalNoNamespaceSchema = noNamespaceSchemaLocation;
525         doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
526     }
527
528     public TraverseSchema(Element JavaDoc root, StringPool stringPool,
529                            SchemaGrammar schemaGrammar,
530                            GrammarResolver grammarResolver,
531                            XMLErrorReporter errorReporter,
532                            String JavaDoc schemaURL,
533                            boolean fullChecking,
534                            GeneralAttrCheck generalAttrCheck
535                            ) throws Exception JavaDoc {
536         fErrorReporter = errorReporter;
537         fCurrentSchemaURL = schemaURL;
538         fFullConstraintChecking = fullChecking;
539         fGeneralAttrCheck = generalAttrCheck;
540         doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
541     }
542
543     public TraverseSchema(Element JavaDoc root, StringPool stringPool,
544                            SchemaGrammar schemaGrammar,
545                            GrammarResolver grammarResolver,
546                            boolean fullChecking,
547                            GeneralAttrCheck generalAttrCheck
548                            ) throws Exception JavaDoc {
549         fFullConstraintChecking = fullChecking;
550         fGeneralAttrCheck = generalAttrCheck;
551         doTraverseSchema(root, stringPool, schemaGrammar, grammarResolver);
552     }
553
554     public void doTraverseSchema(Element JavaDoc root, StringPool stringPool,
555                            SchemaGrammar schemaGrammar,
556                            GrammarResolver grammarResolver) throws Exception JavaDoc {
557
558
559         fSchemaRootElement = root;
560         fStringPool = stringPool;
561         fSchemaGrammar = schemaGrammar;
562         fNamespacesScope = new NamespacesScope(this);
563         fNamespacesScope.setNamespaceForPrefix(fStringPool.addSymbol("xml"), fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace"));
564
565         if (fFullConstraintChecking) {
566           fSchemaGrammar.setDeferContentSpecExpansion();
567           fSchemaGrammar.setCheckUniqueParticleAttribution();
568         }
569
570         fGrammarResolver = grammarResolver;
571         fDatatypeRegistry = (DatatypeValidatorFactoryImpl) fGrammarResolver.getDatatypeRegistry();
572
573         //Expand to registry type to contain all primitive datatype
574
fDatatypeRegistry.expandRegistryToFullSchemaSet();
575
576         fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
577
578         if (root == null) {
579             // REVISIT: Anything to do?
580
return;
581         }
582
583         // General Attribute Checking
584
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
585         Hashtable JavaDoc attrValues = generalCheck(root, scope);
586
587         //Retrieve the targetNamespace URI information
588
fTargetNSURIString = getTargetNamespaceString(root);
589         fTargetNSURI = fStringPool.addSymbol(fTargetNSURIString);
590
591         if (fGrammarResolver == null) {
592             // REVISIT: Localize
593
reportGenericSchemaError("Internal error: don't have a GrammarResolver for TraverseSchema");
594         }
595         else{
596             // for complex type registry, attribute decl registry and
597
// namespace mapping, needs to check whether the passed in
598
// Grammar was a newly instantiated one.
599
if (fSchemaGrammar.getComplexTypeRegistry() == null ) {
600                 fSchemaGrammar.setComplexTypeRegistry(fComplexTypeRegistry);
601             }
602             else {
603                 fComplexTypeRegistry = fSchemaGrammar.getComplexTypeRegistry();
604             }
605
606             if (fSchemaGrammar.getAttributeDeclRegistry() == null ) {
607                 fSchemaGrammar.setAttributeDeclRegistry(fAttributeDeclRegistry);
608             }
609             else {
610                 fAttributeDeclRegistry = fSchemaGrammar.getAttributeDeclRegistry();
611             }
612
613             if (fSchemaGrammar.getNamespacesScope() == null ) {
614                 fSchemaGrammar.setNamespacesScope(fNamespacesScope);
615             }
616             else {
617                 fNamespacesScope = fSchemaGrammar.getNamespacesScope();
618             }
619
620             fSchemaGrammar.setDatatypeRegistry(fDatatypeRegistry);
621             fSchemaGrammar.setTargetNamespaceURI(fTargetNSURIString);
622             fGrammarResolver.putGrammar(fTargetNSURIString, fSchemaGrammar);
623         }
624
625
626
627         // Retrived the Namespace mapping from the schema element.
628
NamedNodeMap JavaDoc schemaEltAttrs = root.getAttributes();
629         int i = 0;
630         Attr JavaDoc sattr = null;
631
632         boolean seenXMLNS = false;
633         while ((sattr = (Attr JavaDoc)schemaEltAttrs.item(i++)) != null) {
634             String JavaDoc attName = sattr.getName();
635             if (attName.startsWith("xmlns:")) {
636                 String JavaDoc attValue = sattr.getValue();
637                 String JavaDoc prefix = attName.substring(attName.indexOf(":")+1);
638                 fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
639                                                         fStringPool.addSymbol(attValue) );
640             }
641             if (attName.equals("xmlns")) {
642
643                 String JavaDoc attValue = sattr.getValue();
644                 fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
645                                                         fStringPool.addSymbol(attValue) );
646                 seenXMLNS = true;
647             }
648
649         }
650         if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
651             fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
652                                                     StringPool.EMPTY_STRING);
653         }
654
655         fElementDefaultQualified =
656             root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
657         fAttributeDefaultQualified =
658             root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
659         Attr JavaDoc blockAttr = root.getAttributeNode(SchemaSymbols.ATT_BLOCKDEFAULT);
660         if (blockAttr == null)
661             fBlockDefault = 0;
662         else
663             fBlockDefault =
664                 parseBlockSet(blockAttr.getValue());
665         Attr JavaDoc finalAttr = root.getAttributeNode(SchemaSymbols.ATT_FINALDEFAULT);
666         if (finalAttr == null)
667             fFinalDefault = 0;
668         else
669             fFinalDefault =
670                 parseFinalSet(finalAttr.getValue());
671
672         //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
673
if (fTargetNSURI == StringPool.EMPTY_STRING) {
674             //fElementDefaultQualified = true;
675
//fAttributeDefaultQualified = true;
676
}
677
678
679         //fScopeCount++;
680
// fCurrentScope = -1;
681

682
683         //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
684
extractTopLevel3Components(root);
685
686         // process <redefine>, <include> and <import> info items.
687
Element JavaDoc child = XUtil.getFirstChildElement(root);
688         for (; child != null;
689             child = XUtil.getNextSiblingElement(child)) {
690
691             String JavaDoc name = child.getLocalName();
692             if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
693                 traverseAnnotationDecl(child);
694             } else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
695                 fNamespacesScope.increaseDepth();
696                 traverseInclude(child);
697                 fNamespacesScope.decreaseDepth();
698             } else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
699                 traverseImport(child);
700             } else if (name.equals(SchemaSymbols.ELT_REDEFINE)) {
701                 fRedefineSucceeded = true; // presume worked until proven failed.
702
traverseRedefine(child);
703             } else
704                 break;
705         }
706
707         // child refers to the first info item which is not <annotation> or
708
// one of the schema inclusion/importation declarations.
709
for (; child != null;
710             child = XUtil.getNextSiblingElement(child)) {
711
712             String JavaDoc name = child.getLocalName();
713             if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
714                 traverseAnnotationDecl(child);
715             } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
716                 traverseSimpleTypeDecl(child);
717             } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
718                 traverseComplexTypeDecl(child);
719             } else if (name.equals(SchemaSymbols.ELT_ELEMENT )) {
720                 traverseElementDecl(child);
721             } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
722                 traverseAttributeGroupDecl(child, null, null);
723             } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
724                 traverseAttributeDecl( child, null, false );
725             } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
726                 traverseGroupDecl(child);
727             } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
728                 traverseNotationDecl(child); //TO DO
729
} else {
730                 // REVISIT: Localize
731
reportGenericSchemaError("error in content of <schema> element information item");
732             }
733         } // for each child node
734

735         // handle identity constraints
736
// we must traverse <key>s and <unique>s before we tackel<keyref>s,
737
// since all have global scope and may be declared anywhere in the schema.
738
Enumeration JavaDoc elementIndexes = fIdentityConstraints.keys();
739         while (elementIndexes.hasMoreElements()) {
740             Integer JavaDoc elementIndexObj = (Integer JavaDoc)elementIndexes.nextElement();
741             if (DEBUG_IC_DATATYPES) {
742                 System.out.println("<ICD>: traversing identity constraints for element: "+elementIndexObj);
743             }
744             Vector JavaDoc identityConstraints = (Vector JavaDoc)fIdentityConstraints.get(elementIndexObj);
745             if (identityConstraints != null) {
746                 int elementIndex = elementIndexObj.intValue();
747                 traverseIdentityNameConstraintsFor(elementIndex, identityConstraints);
748             }
749         }
750         elementIndexes = fIdentityConstraints.keys();
751         while (elementIndexes.hasMoreElements()) {
752             Integer JavaDoc elementIndexObj = (Integer JavaDoc)elementIndexes.nextElement();
753             if (DEBUG_IC_DATATYPES) {
754                 System.out.println("<ICD>: traversing identity constraints for element: "+elementIndexObj);
755             }
756             Vector JavaDoc identityConstraints = (Vector JavaDoc)fIdentityConstraints.get(elementIndexObj);
757             if (identityConstraints != null) {
758                 int elementIndex = elementIndexObj.intValue();
759                 traverseIdentityRefConstraintsFor(elementIndex, identityConstraints);
760             }
761         }
762
763         // At this point, we can do any remaining checking for cos-element-consistent
764
// that involves substitution group elements
765

766         if (fFullConstraintChecking) {
767             // Loop thru all of the top-level elements that were ref'd from groups or
768
// complexTypes, and ensure that:
769
// 1. they have consistent type as any local element potentially declared in
770
// the group/type
771
// 2. any substitutable elements are consistent wrt type given any
772
// similiarly named elements from the group scope
773
// Note: for a complexType, we don't check against base scope. Not clear if
774
// we need to.
775

776             for (int j = 0; j < fTopLevelElementsRefdFromGroup.size(); j+=2) {
777                QName eltName = (QName)fTopLevelElementsRefdFromGroup.elementAt(j);
778                int groupScope = ((Integer JavaDoc)fTopLevelElementsRefdFromGroup.elementAt(j+1)).intValue();
779                checkConsistentElements(eltName, groupScope);
780             }
781
782             // Loop thru all of the complexTypes, and for any derived by restriction,
783
// do particle derivation checking
784
int count = fComplexTypeRegistry.size();
785             Enumeration JavaDoc enumer = fComplexTypeRegistry.elements();
786
787             ComplexTypeInfo typeInfo,baseTypeInfo;
788             while (enumer.hasMoreElements ()) {
789                typeInfo = (TraverseSchema.ComplexTypeInfo)enumer.nextElement();
790                baseTypeInfo = typeInfo.baseComplexTypeInfo;
791
792                if (typeInfo.derivedBy == SchemaSymbols.RESTRICTION &&
793                    baseTypeInfo!=null &&
794                    typeInfo.contentSpecHandle>-1) {
795                  try {
796                     checkParticleDerivationOK(typeInfo.contentSpecHandle,
797                          typeInfo.scopeDefined, baseTypeInfo.contentSpecHandle,
798                          baseTypeInfo.scopeDefined,baseTypeInfo);
799                  }
800                  catch (ParticleRecoverableError e) {
801                     String JavaDoc message = e.getMessage();
802                     reportGenericSchemaError("ComplexType '" + typeInfo.typeName + "': " + message);
803                  }
804                }
805             }
806
807         }
808
809     } // traverseSchema(Element)
810

811
812     private void extractTopLevel3Components(Element JavaDoc root) throws Exception JavaDoc {
813
814         for (Element JavaDoc child = XUtil.getFirstChildElement(root); child != null;
815             child = XUtil.getNextSiblingElement(child)) {
816
817             String JavaDoc name = child.getLocalName();
818             String JavaDoc compName = child.getAttribute(SchemaSymbols.ATT_NAME);
819             if (name.equals(SchemaSymbols.ELT_ELEMENT)) {
820                 // Check if the element has already been declared
821
if (fSchemaGrammar.topLevelElemDecls.get(compName) != null) {
822                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for an element " +
823                                              compName);
824                 }
825                 else {
826                     fSchemaGrammar.topLevelElemDecls.put(compName, child);
827                 }
828             }
829             else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE) ||
830                      name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
831                  // Check for dublicate declaration
832
if (fSchemaGrammar.topLevelTypeDecls.get(compName) != null) {
833                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for a type " +
834                                              compName);
835                 }
836                 else {
837                     fSchemaGrammar.topLevelTypeDecls.put(compName, child);
838                 }
839             }
840             else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
841                  // Check for dublicate declaration
842
if (fSchemaGrammar.topLevelAttrGrpDecls.get(compName) != null) {
843                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for an attribute group " +
844                                              compName);
845                 }
846                 else {
847                 fSchemaGrammar.topLevelAttrGrpDecls.put(compName, child);
848                 }
849             } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
850                 // Check for dublicate declaration
851
if (fSchemaGrammar.topLevelAttrGrpDecls.get(compName) != null) {
852                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for an attribute " +
853                                              compName);
854                 }
855                 else {
856                     fSchemaGrammar.topLevelAttrGrpDecls.put(compName, child);
857                 }
858             } else if ( name.equals(SchemaSymbols.ELT_GROUP) ) {
859                 // Check if the group has already been declared
860
if (fSchemaGrammar.topLevelGroupDecls.get(compName) != null){
861                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for a group " +
862                                              compName);
863                 }
864                 else {
865                 fSchemaGrammar.topLevelGroupDecls.put(compName, child);
866                 }
867             } else if ( name.equals(SchemaSymbols.ELT_NOTATION) ) {
868                 // Check for dublicate declaration
869
if (fSchemaGrammar.topLevelNotationDecls.get(compName) != null) {
870                    reportGenericSchemaError("sch-props-correct: Duplicate declaration for a notation " +
871                                              compName);
872                 }
873                 else {
874                 fSchemaGrammar.topLevelNotationDecls.put(compName, child);
875             }
876             }
877         } // for each child node
878
}
879
880     private void checkConsistentElements(QName eltName, int scope) throws Exception JavaDoc {
881
882       // See if there is a declaration of an element with the same name at the
883
// given scope.
884
// This is required because any model group cannot have more than 1
885
// element with the same name, but different types (even if some are
886
// local, and others top-level)
887

888        fTempElementDecl.clear();
889        int topLevelElementNdx = fSchemaGrammar.getElementDeclIndex(eltName, TOP_LEVEL_SCOPE);
890        if (topLevelElementNdx < 0)
891            return;
892
893        fSchemaGrammar.getElementDecl(topLevelElementNdx, fTempElementDecl);
894        DatatypeValidator edv = fTempElementDecl.datatypeValidator;
895        ComplexTypeInfo eTypeInfo = fSchemaGrammar.getElementComplexTypeInfo(topLevelElementNdx);
896        int existingEltNdx = fSchemaGrammar.getElementDeclIndex(eltName.uri,
897                                               eltName.localpart,scope);
898        if (existingEltNdx > -1) {
899           if (!checkDuplicateElementTypes(existingEltNdx,eTypeInfo,edv))
900
901               reportGenericSchemaError("duplicate element decl in the same scope with different types : " +
902                                         fStringPool.toString(eltName.localpart));
903        }
904
905        Vector JavaDoc substitutableNames = fSchemaGrammar.getElementDeclAllSubstitutionGroupQNames(topLevelElementNdx, fGrammarResolver, fStringPool);
906
907        for (int i = 0; i < substitutableNames.size(); i++) {
908           SchemaGrammar.OneSubGroup subGroup = (SchemaGrammar.OneSubGroup)substitutableNames.elementAt(i);
909           QName substName = subGroup.name;
910           int substEltNdx = subGroup.eleIndex;
911
912           int localEltNdx = fSchemaGrammar.getElementDeclIndex(substName, scope);
913           if (localEltNdx > -1) {
914              fSchemaGrammar.getElementDecl(localEltNdx, fTempElementDecl);
915              edv = fTempElementDecl.datatypeValidator;
916              eTypeInfo = fSchemaGrammar.getElementComplexTypeInfo(localEltNdx);
917              if (!checkDuplicateElementTypes(substEltNdx,eTypeInfo,edv))
918                  reportGenericSchemaError("duplicate element decl in the same scope with different types : " +
919                   fStringPool.toString(substName.localpart));
920           }
921        }
922
923     }
924
925
926     /**
927      * Expands a system id and returns the system id as a URL, if
928      * it can be expanded. A return value of null means that the
929      * identifier is already expanded. An exception thrown
930      * indicates a failure to expand the id.
931      *
932      * @param systemId The systemId to be expanded.
933      *
934      * @return Returns the URL object representing the expanded system
935      * identifier. A null value indicates that the given
936      * system identifier is already expanded.
937      *
938      */

939     private String JavaDoc expandSystemId(String JavaDoc systemId, String JavaDoc currentSystemId) throws Exception JavaDoc{
940      String JavaDoc id = systemId;
941
942      // check for bad parameters id
943
if (id == null || id.length() == 0) {
944          return systemId;
945      }
946
947      // if id already expanded, return
948
try {
949          URL JavaDoc url = new URL JavaDoc(id);
950          if (url != null) {
951              return systemId;
952          }
953      }
954      catch (MalformedURLException JavaDoc e) {
955          // continue on...
956
}
957
958      // normalize id
959
id = fixURI(id);
960
961      // normalize base
962
URL JavaDoc base = null;
963      URL JavaDoc url = null;
964      try {
965          if (currentSystemId == null) {
966              String JavaDoc dir;
967              try {
968                  dir = fixURI(System.getProperty("user.dir"));
969              }
970              catch (SecurityException JavaDoc se) {
971                  dir = "";
972              }
973              if (!dir.endsWith("/")) {
974                  dir = dir + "/";
975              }
976              base = new URL JavaDoc("file", "", dir);
977          }
978          else {
979              base = new URL JavaDoc(currentSystemId);
980          }
981
982          // expand id
983
url = new URL JavaDoc(base, id);
984      }
985      catch (Exception JavaDoc e) {
986          // let it go through
987
}
988      if (url == null) {
989          return systemId;
990      }
991      return url.toString();
992     }
993     /**
994      * Fixes a platform dependent filename to standard URI form.
995      *
996      * @param str The string to fix.
997      *
998      * @return Returns the fixed URI string.
999      */

1000    private static String JavaDoc fixURI(String JavaDoc str) {
1001
1002        // handle platform dependent strings
1003
str = str.replace(java.io.File.separatorChar, '/');
1004
1005        // Windows fix
1006
if (str.length() >= 2) {
1007            char ch1 = str.charAt(1);
1008            if (ch1 == ':') {
1009                char ch0 = Character.toUpperCase(str.charAt(0));
1010                if (ch0 >= 'A' && ch0 <= 'Z') {
1011                    str = "/" + str;
1012                }
1013            }
1014        }
1015
1016        // done
1017
return str;
1018    }
1019
1020
1021    private void traverseInclude(Element JavaDoc includeDecl) throws Exception JavaDoc {
1022        // General Attribute Checking
1023
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
1024        Hashtable JavaDoc attrValues = generalCheck(includeDecl, scope);
1025        checkContent(includeDecl, XUtil.getFirstChildElement(includeDecl), true);
1026
1027        Attr JavaDoc locationAttr = includeDecl.getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
1028        if (locationAttr == null) {
1029            // REVISIT: Localize
1030
reportGenericSchemaError("a schemaLocation attribute must be specified on an <include> element");
1031            return;
1032        }
1033        String JavaDoc location = locationAttr.getValue();
1034        // expand it before passing it to the parser
1035
InputSource JavaDoc source = null;
1036
1037        // If fEntityResolver is not null and is not the default, only then use it - Gopal Sharma, Sun Microsystems Inc.
1038
if ( (fEntityResolver != null) &&
1039             !(fEntityResolver.getClass().getName().equals("org.enhydra.apache.xerces.validators.common.XMLValidator$Resolver")) ) {
1040            source = fEntityResolver.resolveEntity("", location);
1041        }
1042
1043        if (source == null) {
1044            location = expandSystemId(location, fCurrentSchemaURL);
1045            source = new InputSource JavaDoc(location);
1046        }
1047        // create a string for uniqueness of this included schema in fIncludeLocations
1048
// algorithm: string is pubId+sysId or if both null then filename
1049
String JavaDoc pubId = "";
1050        String JavaDoc sysId = "";
1051        if (source.getPublicId () != null)
1052            pubId = source.getPublicId ();
1053        if (source.getSystemId () != null)
1054            sysId = source.getSystemId ();
1055
1056        if(pubId.length() != 0 || sysId.length() != 0)
1057            location = pubId+sysId;
1058
1059        if (fIncludeLocations.contains((Object JavaDoc)location)) {
1060            return;
1061        }
1062        fIncludeLocations.addElement((Object JavaDoc)location);
1063
1064        DOMParser parser = new IgnoreWhitespaceParser();
1065        parser.setEntityResolver( (fEntityResolver != null)? (fEntityResolver):(new Resolver()) );
1066        parser.setErrorHandler( new ErrorHandler()
1067            {
1068                public void error(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
1069                    StringBuffer JavaDoc str = new StringBuffer JavaDoc();
1070                    String JavaDoc systemId_ = ex.getSystemId();
1071                    if (systemId_ != null) {
1072                        int index = systemId_.lastIndexOf('/');
1073                        if (index != -1)
1074                            systemId_ = systemId_.substring(index + 1);
1075                        str.append(systemId_);
1076                    }
1077                    str.append(':').append(ex.getLineNumber()).append(':').append(ex.getColumnNumber());
1078                    String JavaDoc message = ex.getMessage();
1079                    if(message.toLowerCase().trim().endsWith("not found.")) {
1080                        System.err.println("[Warning] "+
1081                               str.toString()+": "+ message);
1082                    } else { // do standard thing
1083
System.err.println("[Error] "+
1084                               str.toString()+":"+message);
1085                        throw ex;
1086                    }
1087                }
1088            });
1089
1090        try {
1091            parser.setFeature("http://xml.org/sax/features/validation", false);
1092            parser.setFeature("http://xml.org/sax/features/namespaces", true);
1093            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
1094            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
1095        }catch( org.xml.sax.SAXNotRecognizedException JavaDoc e ) {
1096            e.printStackTrace();
1097        }catch( org.xml.sax.SAXNotSupportedException JavaDoc e ) {
1098            e.printStackTrace();
1099        }
1100
1101        try {
1102            parser.parse( source );
1103        }catch( IOException JavaDoc e ) {
1104            // we already produce warnings on IOExceptions!
1105
// e.printStackTrace();
1106
}catch( SAXException JavaDoc e ) {
1107            //e.printStackTrace();
1108
}
1109
1110        Document JavaDoc document = parser.getDocument(); //Our Grammar
1111
Element JavaDoc root = null;
1112        if (document != null) {
1113            root = document.getDocumentElement();
1114        }
1115
1116        if (root != null) {
1117            String JavaDoc targetNSURI = getTargetNamespaceString(root);
1118            if (targetNSURI.length() > 0 && !targetNSURI.equals(fTargetNSURIString) ) {
1119                // REVISIT: Localize
1120
reportGenericSchemaError("included schema '"+location+"' has a different targetNameSpace '"
1121                                         +targetNSURI+"'");
1122            }
1123            else {
1124                // We not creating another TraverseSchema object to compile
1125
// the included schema file, because the scope count, anon-type count
1126
// should not be reset for a included schema, this can be fixed by saving
1127
// the counters in the Schema Grammar,
1128
if (fSchemaInfoListRoot == null) {
1129                    fSchemaInfoListRoot = new SchemaInfo(fElementDefaultQualified, fAttributeDefaultQualified,
1130                        fBlockDefault, fFinalDefault,
1131                        fCurrentSchemaURL, fSchemaRootElement,
1132                        fNamespacesScope, null, null);
1133                    fCurrentSchemaInfo = fSchemaInfoListRoot;
1134                }
1135                fSchemaRootElement = root;
1136                fSchemaURLStack.push(fCurrentSchemaURL);
1137                fCurrentSchemaURL = location;
1138                traverseIncludedSchemaHeader(root);
1139                //
1140
// Bug fix: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3272
1141
// For included schemas with no namespace we need to bind the default namespace
1142
// (empty string) to the target namespace of the including XML Schema.
1143
if((fTargetNSURIString.length() != 0) && (root.getAttributeNode("xmlns") == null)) {
1144                    fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, fTargetNSURI);
1145                }
1146                // and now we'd better save this stuff!
1147
fCurrentSchemaInfo = new SchemaInfo(fElementDefaultQualified, fAttributeDefaultQualified,
1148                        fBlockDefault, fFinalDefault,
1149                        fCurrentSchemaURL, fSchemaRootElement,
1150                        fNamespacesScope, fCurrentSchemaInfo.getNext(), fCurrentSchemaInfo);
1151                (fCurrentSchemaInfo.getPrev()).setNext(fCurrentSchemaInfo);
1152                traverseIncludedSchema(root);
1153                // there must always be a previous element!
1154
fCurrentSchemaInfo = fCurrentSchemaInfo.getPrev();
1155                fCurrentSchemaInfo.restore();
1156                fCurrentSchemaURL = (String JavaDoc)fSchemaURLStack.pop();
1157            }
1158
1159        }
1160
1161    }
1162
1163    private void traverseIncludedSchemaHeader(Element JavaDoc root) throws Exception JavaDoc {
1164        // General Attribute Checking
1165
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
1166        Hashtable JavaDoc attrValues = generalCheck(root, scope);
1167
1168        // Retrieved the Namespace mapping from the schema element.
1169
NamedNodeMap JavaDoc schemaEltAttrs = root.getAttributes();
1170        int i = 0;
1171        Attr JavaDoc sattr = null;
1172
1173        boolean seenXMLNS = false;
1174        while ((sattr = (Attr JavaDoc)schemaEltAttrs.item(i++)) != null) {
1175            String JavaDoc attName = sattr.getName();
1176            if (attName.startsWith("xmlns:")) {
1177                String JavaDoc attValue = sattr.getValue();
1178                String JavaDoc prefix = attName.substring(attName.indexOf(":")+1);
1179                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
1180                                                        fStringPool.addSymbol(attValue) );
1181            }
1182            if (attName.equals("xmlns")) {
1183
1184                String JavaDoc attValue = sattr.getValue();
1185                fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
1186                                                        fStringPool.addSymbol(attValue) );
1187                seenXMLNS = true;
1188            }
1189
1190        }
1191        if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
1192            fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
1193                                                    StringPool.EMPTY_STRING);
1194        }
1195
1196        fElementDefaultQualified =
1197            root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
1198        fAttributeDefaultQualified =
1199            root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
1200        Attr JavaDoc blockAttr = root.getAttributeNode(SchemaSymbols.ATT_BLOCKDEFAULT);
1201        if (blockAttr == null)
1202            fBlockDefault = 0;
1203        else
1204            fBlockDefault =
1205                parseBlockSet(blockAttr.getValue());
1206        Attr JavaDoc finalAttr = root.getAttributeNode(SchemaSymbols.ATT_FINALDEFAULT);
1207        if (finalAttr == null)
1208            fFinalDefault = 0;
1209        else
1210            fFinalDefault =
1211                parseFinalSet(finalAttr.getValue());
1212
1213        //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
1214
if (fTargetNSURI == StringPool.EMPTY_STRING) {
1215            fElementDefaultQualified = true;
1216            //fAttributeDefaultQualified = true;
1217
}
1218
1219        //fScopeCount++;
1220
//fCurrentScope = -1;
1221
} // traverseIncludedSchemaHeader
1222

1223    private void traverseIncludedSchema(Element JavaDoc root) throws Exception JavaDoc {
1224        // General Attribute Checking
1225
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
1226        Hashtable JavaDoc attrValues = generalCheck(root, scope);
1227
1228        //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
1229
extractTopLevel3Components(root);
1230
1231        // handle <redefine>, <include> and <import> elements.
1232
Element JavaDoc child = XUtil.getFirstChildElement(root);
1233        for (; child != null;
1234            child = XUtil.getNextSiblingElement(child)) {
1235
1236            String JavaDoc name = child.getLocalName();
1237
1238            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
1239                traverseAnnotationDecl(child);
1240            } else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
1241                fNamespacesScope.increaseDepth();
1242                traverseInclude(child);
1243                fNamespacesScope.decreaseDepth();
1244            } else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
1245                traverseImport(child);
1246            } else if (name.equals(SchemaSymbols.ELT_REDEFINE)) {
1247                fRedefineSucceeded = true; // presume worked until proven failed.
1248
traverseRedefine(child);
1249            } else
1250                break;
1251        }
1252
1253        // handle the rest of the schema elements.
1254
// BEWARE! this method gets called both from traverseRedefine and
1255
// traverseInclude; the preconditions (especially with respect to
1256
// groups and attributeGroups) are different!
1257
for (; child != null;
1258            child = XUtil.getNextSiblingElement(child)) {
1259
1260            String JavaDoc name = child.getLocalName();
1261
1262            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
1263                traverseAnnotationDecl(child);
1264            } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
1265                traverseSimpleTypeDecl(child);
1266            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
1267                traverseComplexTypeDecl(child);
1268            } else if (name.equals(SchemaSymbols.ELT_ELEMENT )) {
1269                traverseElementDecl(child);
1270            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1271                if(fRedefineAttributeGroupMap != null) {
1272                    String JavaDoc dName = child.getAttribute(SchemaSymbols.ATT_NAME);
1273                    String JavaDoc bName = (String JavaDoc)fRedefineAttributeGroupMap.get(dName);
1274                    if(bName != null) {
1275                        child.setAttribute(SchemaSymbols.ATT_NAME, bName);
1276                        // and make sure we wipe this out of the grammar!
1277
fSchemaGrammar.topLevelAttrGrpDecls.remove(dName);
1278                        // Now we reuse this location in the array to store info we'll need for validation...
1279
ComplexTypeInfo typeInfo = new ComplexTypeInfo();
1280                        int templateElementNameIndex = fStringPool.addSymbol("$"+bName);
1281                        int typeNameIndex = fStringPool.addSymbol("%"+bName);
1282                        typeInfo.scopeDefined = -2;
1283                        typeInfo.contentSpecHandle = -1;
1284                        typeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
1285                        typeInfo.datatypeValidator = null;
1286                        typeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
1287                            new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
1288                            (fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : -2, typeInfo.scopeDefined,
1289                            typeInfo.contentType,
1290                            typeInfo.contentSpecHandle, -1, typeInfo.datatypeValidator);
1291
1292                        Vector JavaDoc anyAttDecls = new Vector JavaDoc();
1293                        // need to determine how to initialize these babies; then
1294
// on the <redefine> traversing end, try
1295
// and cast the hash value into the right form;
1296
// failure indicates nothing to redefine; success
1297
// means we can feed checkAttribute... what it needs...
1298
traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
1299                        typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(
1300                                typeInfo.templateElementIndex);
1301                        fRedefineAttributeGroupMap.put(dName, new Object JavaDoc []{typeInfo, fSchemaGrammar, anyAttDecls});
1302                        continue;
1303                    }
1304                }
1305                traverseAttributeGroupDecl(child, null, null);
1306            } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
1307                traverseAttributeDecl( child, null , false);
1308            } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
1309                String JavaDoc dName = child.getAttribute(SchemaSymbols.ATT_NAME);
1310                if(fGroupNameRegistry.get(fTargetNSURIString + ","+dName) == null) {
1311                    // we've been renamed already
1312
traverseGroupDecl(child);
1313                    continue;
1314                }
1315                // if we're here: must have been a restriction.
1316
// we have yet to be renamed.
1317
try {
1318                    GroupInfo gi = (GroupInfo)fGroupNameRegistry.get(fTargetNSURIString + ","+dName);
1319                    // if that succeeded then we're done; were ref'd here in
1320
// an include most likely.
1321
continue;
1322                } catch (ClassCastException JavaDoc c) {
1323                    String JavaDoc s = (String JavaDoc)fGroupNameRegistry.get(fTargetNSURIString + ","+dName);
1324                    if (s == null) continue; // must have seen this already--somehow...
1325
};
1326                String JavaDoc bName = (String JavaDoc)fGroupNameRegistry.get(fTargetNSURIString +"," + dName);
1327                if(bName != null) {
1328                    child.setAttribute(SchemaSymbols.ATT_NAME, bName);
1329                    // Now we reuse this location in the array to store info we'll need for validation...
1330
// note that traverseGroupDecl will happily do that for us!
1331
}
1332                traverseGroupDecl(child);
1333            } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
1334                traverseNotationDecl(child);
1335            } else {
1336                // REVISIT: Localize
1337
reportGenericSchemaError("error in content of included <schema> element information item");
1338            }
1339        } // for each child node
1340

1341    }
1342
1343    // This method's job is to open a redefined schema and store away its root element, defaultElementQualified and other
1344
// such info, in order that it can be available when redefinition actually takes place.
1345
// It assumes that it will be called from the schema doing the redefining, and it assumes
1346
// that the other schema's info has already been saved, putting the info it finds into the
1347
// SchemaInfoList element that is passed in.
1348
private void openRedefinedSchema(Element JavaDoc redefineDecl, SchemaInfo store) throws Exception JavaDoc {
1349        Attr JavaDoc locationAttr = redefineDecl.getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
1350        if (locationAttr == null) {
1351            // REVISIT: Localize
1352
fRedefineSucceeded = false;
1353            reportGenericSchemaError("a schemaLocation attribute must be specified on a <redefine> element");
1354            return;
1355        }
1356        String JavaDoc location = locationAttr.getValue();
1357
1358        // expand it before passing it to the parser
1359
InputSource JavaDoc source = null;
1360        if (fEntityResolver != null) {
1361            source = fEntityResolver.resolveEntity("", location);
1362        }
1363
1364        if (source == null) {
1365            location = expandSystemId(location, fCurrentSchemaURL);
1366            source = new InputSource JavaDoc(location);
1367        }
1368        // Make sure we don't redefine the same schema twice; it's allowed
1369
// but the specs encourage us to avoid it.
1370
// algorithm: string is pubId+sysId or if both null then filename
1371
String JavaDoc pubId = "";
1372        String JavaDoc sysId = "";
1373        if (source.getPublicId () != null)
1374            pubId = source.getPublicId ();
1375        if (source.getSystemId () != null)
1376            sysId = source.getSystemId ();
1377
1378        if(pubId.length() != 0 || sysId.length() != 0)
1379            location += pubId+sysId;
1380
1381        // make sure we're not redefining ourselves!
1382
if(source.getSystemId().equals(fCurrentSchemaURL)) {
1383            // REVISIT: localize
1384
reportGenericSchemaError("src-redefine.2: a schema cannot redefine itself");
1385            fRedefineSucceeded = false;
1386            return;
1387        }
1388        if (fRedefineLocations.get((Object JavaDoc)location) != null) {
1389            // then we'd better make sure we're directed at that schema...
1390
fCurrentSchemaInfo = (SchemaInfo)(fRedefineLocations.get((Object JavaDoc)location));
1391            fCurrentSchemaInfo.restore();
1392            return;
1393        }
1394
1395        DOMParser parser = new IgnoreWhitespaceParser();
1396        parser.setEntityResolver( (fEntityResolver != null)? (fEntityResolver):(new Resolver()) );
1397        parser.setErrorHandler( new ErrorHandler() );
1398
1399        try {
1400            parser.setFeature("http://xml.org/sax/features/validation", false);
1401            parser.setFeature("http://xml.org/sax/features/namespaces", true);
1402            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
1403            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
1404        }catch( org.xml.sax.SAXNotRecognizedException JavaDoc e ) {
1405            e.printStackTrace();
1406        }catch( org.xml.sax.SAXNotSupportedException JavaDoc e ) {
1407            e.printStackTrace();
1408        }
1409
1410        try {
1411            parser.parse( source );
1412        }catch( IOException JavaDoc e ) {
1413            e.printStackTrace();
1414        }catch( SAXException JavaDoc e ) {
1415            //e.printStackTrace();
1416
}
1417
1418        Document JavaDoc document = parser.getDocument(); //Our Grammar to be redefined
1419
Element JavaDoc root = null;
1420        if (document != null) {
1421            root = document.getDocumentElement();
1422        }
1423
1424        if (root == null) { // nothing to be redefined, so just continue; specs disallow an error here.
1425
fRedefineSucceeded = false;
1426            return;
1427        }
1428
1429        // now if root isn't null, it'll contain the root of the schema we need to redefine.
1430
// We do this in two phases: first, we look through the children of
1431
// redefineDecl. Each one will correspond to an element of the
1432
// redefined schema that we need to redefine. To do this, we rename the
1433
// element of the redefined schema, and rework the base or ref tag of
1434
// the kid we're working on to refer to the renamed group or derive the
1435
// renamed type. Once we've done this, we actually go through the
1436
// schema being redefined and convert it to a grammar. Only then do we
1437
// run through redefineDecl's kids and put them in the grammar.
1438
//
1439
// This approach is kosher with the specs. It does raise interesting
1440
// questions about error reporting, and perhaps also about grammar
1441
// access, but it is comparatively efficient (we need make at most
1442
// only 2 traversals of any given information item) and moreover
1443
// we can use existing code to build the grammar structures once the
1444
// first pass is out of the way, so this should be quite robust.
1445

1446        // check to see if the targetNameSpace is right
1447
String JavaDoc redefinedTargetNSURIString = getTargetNamespaceString(root);
1448        if (redefinedTargetNSURIString.length() > 0 && !redefinedTargetNSURIString.equals(fTargetNSURIString) ) {
1449            // REVISIT: Localize
1450
fRedefineSucceeded = false;
1451            reportGenericSchemaError("redefined schema '"+location+"' has a different targetNameSpace '"
1452                                     +redefinedTargetNSURIString+"' from the original schema");
1453        }
1454        else {
1455            // targetNamespace is right, so let's do the renaming...
1456
// and let's keep in mind that the targetNamespace of the redefined
1457
// elements is that of the redefined schema!
1458
fSchemaRootElement = root;
1459            fCurrentSchemaURL = location;
1460            fNamespacesScope = new NamespacesScope(this);
1461            fNamespacesScope.setNamespaceForPrefix(fStringPool.addSymbol("xml"), fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace"));
1462            if((redefinedTargetNSURIString.length() == 0) && (root.getAttributeNode("xmlns") == null)) {
1463                fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, fTargetNSURI);
1464            } else {
1465            }
1466            // get default form xmlns bindings et al.
1467
traverseIncludedSchemaHeader(root);
1468            // and then save them...
1469
store.setNext(new SchemaInfo(fElementDefaultQualified, fAttributeDefaultQualified,
1470                    fBlockDefault, fFinalDefault,
1471                    fCurrentSchemaURL, fSchemaRootElement,
1472                    fNamespacesScope, null, store));
1473            (store.getNext()).setPrev(store);
1474            fCurrentSchemaInfo = store.getNext();
1475            fRedefineLocations.put((Object JavaDoc)location, store.getNext());
1476        } // end if
1477
} // end openRedefinedSchema
1478

1479    /****
1480     * <redefine
1481       * schemaLocation = uriReference
1482       * {any attributes with non-schema namespace . . .}>
1483       * Content: (annotation | (
1484     * attributeGroup | complexType | group | simpleType))*
1485     * </redefine>
1486     */

1487    private void traverseRedefine(Element JavaDoc redefineDecl) throws Exception JavaDoc {
1488        // General Attribute Checking
1489
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
1490        Hashtable JavaDoc attrValues = generalCheck(redefineDecl, scope);
1491
1492        // initialize storage areas...
1493
fRedefineAttributeGroupMap = new Hashtable JavaDoc();
1494        NamespacesScope saveNSScope = (NamespacesScope)fNamespacesScope.clone();
1495
1496        // only case in which need to save contents is when fSchemaInfoListRoot is null; otherwise we'll have
1497
// done this already one way or another.
1498
if (fSchemaInfoListRoot == null) {
1499            fSchemaInfoListRoot = new SchemaInfo(fElementDefaultQualified, fAttributeDefaultQualified,
1500                    fBlockDefault, fFinalDefault,
1501                    fCurrentSchemaURL, fSchemaRootElement,
1502                    fNamespacesScope, null, null);
1503            openRedefinedSchema(redefineDecl, fSchemaInfoListRoot);
1504            if(!fRedefineSucceeded)
1505                return;
1506            fCurrentSchemaInfo = fSchemaInfoListRoot.getNext();
1507            fNamespacesScope = (NamespacesScope)saveNSScope.clone();
1508            renameRedefinedComponents(redefineDecl,fSchemaInfoListRoot.getNext().getRoot(), fSchemaInfoListRoot.getNext());
1509        } else {
1510            // may have a chain here; need to be wary!
1511
SchemaInfo curr = fSchemaInfoListRoot;
1512            for(; curr.getNext() != null; curr = curr.getNext());
1513            fCurrentSchemaInfo = curr;
1514            fCurrentSchemaInfo.restore();
1515            openRedefinedSchema(redefineDecl, fCurrentSchemaInfo);
1516            if(!fRedefineSucceeded)
1517                return;
1518            fNamespacesScope = (NamespacesScope)saveNSScope.clone();
1519            renameRedefinedComponents(redefineDecl,fCurrentSchemaInfo.getRoot(), fCurrentSchemaInfo);
1520        }
1521        // Now we have to march through our nicely-renamed schemas from the
1522
// bottom up. When we do these traversals other <redefine>'s may
1523
// perhaps be encountered; we leave recursion to sort this out.
1524

1525        fCurrentSchemaInfo.restore();
1526        traverseIncludedSchema(fSchemaRootElement);
1527        fNamespacesScope = (NamespacesScope)saveNSScope.clone();
1528        // and last but not least: traverse our own <redefine>--the one all
1529
// this labour has been expended upon.
1530
for (Element JavaDoc child = XUtil.getFirstChildElement(redefineDecl); child != null;
1531                child = XUtil.getNextSiblingElement(child)) {
1532            String JavaDoc name = child.getLocalName();
1533
1534            // annotations can occur anywhere in <redefine>s!
1535
if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
1536                traverseAnnotationDecl(child);
1537            } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
1538                traverseSimpleTypeDecl(child);
1539            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
1540                traverseComplexTypeDecl(child);
1541            } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
1542                String JavaDoc dName = child.getAttribute(SchemaSymbols.ATT_NAME);
1543                if(fGroupNameRegistry.get(fTargetNSURIString +","+ dName) == null ||
1544                        ((fRestrictedRedefinedGroupRegistry.get(fTargetNSURIString+","+dName) != null) &&
1545                        !((Boolean JavaDoc)fRestrictedRedefinedGroupRegistry.get(fTargetNSURIString+","+dName)).booleanValue())) { // extension!
1546
traverseGroupDecl(child);
1547                    continue;
1548                }
1549                traverseGroupDecl(child);
1550                GroupInfo bGIObj = null;
1551                try {
1552                    bGIObj = (GroupInfo)fGroupNameRegistry.get(fTargetNSURIString +","+ dName+redefIdentifier);
1553                } catch(ClassCastException JavaDoc c) {
1554                    // if it's still a String, then we mustn't have found a corresponding attributeGroup in the redefined schema.
1555
// REVISIT: localize
1556
reportGenericSchemaError("src-redefine.6.2: a <group> within a <redefine> must either have a ref to a <group> with the same name or must restrict such an <group>");
1557                    continue;
1558                }
1559                if(bGIObj != null) { // we have something!
1560
int bCSIndex = bGIObj.contentSpecIndex;
1561                    GroupInfo dGIObj;
1562                    try {
1563                        dGIObj = (GroupInfo)fGroupNameRegistry.get(fTargetNSURIString+","+dName);
1564                    } catch (ClassCastException JavaDoc c) {
1565                        continue;
1566                    }
1567                    if(dGIObj == null) // something went wrong...
1568
continue;
1569                    int dCSIndex = dGIObj.contentSpecIndex;
1570                    try {
1571                      checkParticleDerivationOK(dCSIndex, -1, bCSIndex, -1, null);
1572                    }
1573                    catch (ParticleRecoverableError e) {
1574                      reportGenericSchemaError(e.getMessage());
1575                    }
1576                } else
1577                    // REVISIT: localize
1578
reportGenericSchemaError("src-redefine.6.2: a <group> within a <redefine> must either have a ref to a <group> with the same name or must restrict such an <group>");
1579            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1580                if(fRedefineAttributeGroupMap != null) {
1581                    String JavaDoc dName = child.getAttribute(SchemaSymbols.ATT_NAME);
1582                    Object JavaDoc [] bAttGrpStore = null;
1583                    try {
1584                        bAttGrpStore = (Object JavaDoc [])fRedefineAttributeGroupMap.get(dName);
1585                    } catch(ClassCastException JavaDoc c) {
1586                        // if it's still a String, then we mustn't have found a corresponding attributeGroup in the redefined schema.
1587
// REVISIT: localize
1588
reportGenericSchemaError("src-redefine.7.2: an <attributeGroup> within a <redefine> must either have a ref to an <attributeGroup> with the same name or must restrict such an <attributeGroup>");
1589                        continue;
1590                    }
1591                    if(bAttGrpStore != null) { // we have something!
1592
ComplexTypeInfo bTypeInfo = (ComplexTypeInfo)bAttGrpStore[0];
1593                        SchemaGrammar bSchemaGrammar = (SchemaGrammar)bAttGrpStore[1];
1594                        Vector JavaDoc bAnyAttDecls = (Vector JavaDoc)bAttGrpStore[2];
1595                        XMLAttributeDecl bAnyAttDecl =
1596                            (bAnyAttDecls.size()>0 )? (XMLAttributeDecl)bAnyAttDecls.elementAt(0):null;
1597                        ComplexTypeInfo dTypeInfo = new ComplexTypeInfo();
1598                        int templateElementNameIndex = fStringPool.addSymbol("$"+dName);
1599                        int dTypeNameIndex = fStringPool.addSymbol("%"+dName);
1600                        dTypeInfo.scopeDefined = -2;
1601                        dTypeInfo.contentSpecHandle = -1;
1602                        dTypeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
1603                        dTypeInfo.datatypeValidator = null;
1604                        dTypeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
1605                            new QName(-1, templateElementNameIndex,dTypeNameIndex,fTargetNSURI),
1606                            (fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : -2, dTypeInfo.scopeDefined,
1607                            dTypeInfo.contentType,
1608                            dTypeInfo.contentSpecHandle, -1, dTypeInfo.datatypeValidator);
1609
1610                        Vector JavaDoc dAnyAttDecls = new Vector JavaDoc();
1611                        XMLAttributeDecl dAnyAttDecl =
1612                            (dAnyAttDecls.size()>0 )? (XMLAttributeDecl)dAnyAttDecls.elementAt(0):null;
1613                        traverseAttributeGroupDecl(child, dTypeInfo, dAnyAttDecls);
1614                        dTypeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(
1615                                dTypeInfo.templateElementIndex);
1616                        try {
1617                            checkAttributesDerivationOKRestriction(dTypeInfo.attlistHead,fSchemaGrammar,
1618                                dAnyAttDecl,bTypeInfo.attlistHead,bSchemaGrammar,bAnyAttDecl);
1619                        }
1620                        catch (ComplexTypeRecoverableError e) {
1621                            String JavaDoc message = e.getMessage();
1622                            reportGenericSchemaError("src-redefine.7.2: redefinition failed because of " + message);
1623                        }
1624                        continue;
1625                    }
1626                }
1627                traverseAttributeGroupDecl(child, null, null);
1628            } // no else; error reported in the previous traversal
1629
} //for
1630

1631        // and restore the original globals
1632
fCurrentSchemaInfo = fCurrentSchemaInfo.getPrev();
1633        fCurrentSchemaInfo.restore();
1634    } // traverseRedefine
1635

1636    // the purpose of this method is twofold: 1. To find and appropriately modify all information items
1637
// in redefinedSchema with names that are redefined by children of
1638
// redefineDecl. 2. To make sure the redefine element represented by
1639
// redefineDecl is valid as far as content goes and with regard to
1640
// properly referencing components to be redefined. No traversing is done here!
1641
// This method also takes actions to find and, if necessary, modify the names
1642
// of elements in <redefine>'s in the schema that's being redefined.
1643
private void renameRedefinedComponents(Element JavaDoc redefineDecl, Element JavaDoc schemaToRedefine, SchemaInfo currSchemaInfo) throws Exception JavaDoc {
1644        for (Element JavaDoc child = XUtil.getFirstChildElement(redefineDecl);
1645                child != null;
1646                child = XUtil.getNextSiblingElement(child)) {
1647            String JavaDoc name = child.getLocalName();
1648            if (name.equals(SchemaSymbols.ELT_ANNOTATION) )
1649                continue;
1650            else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1651                String JavaDoc typeName = child.getAttribute( SchemaSymbols.ATT_NAME );
1652                if(fTraversedRedefineElements.contains(typeName))
1653                    continue;
1654                if(validateRedefineNameChange(SchemaSymbols.ELT_SIMPLETYPE, typeName, typeName+redefIdentifier, child)) {
1655                    fixRedefinedSchema(SchemaSymbols.ELT_SIMPLETYPE,
1656                        typeName, typeName+redefIdentifier,
1657                        schemaToRedefine, currSchemaInfo);
1658                }
1659            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1660                String JavaDoc typeName = child.getAttribute( SchemaSymbols.ATT_NAME );
1661                if(fTraversedRedefineElements.contains(typeName))
1662                    continue;
1663                if(validateRedefineNameChange(SchemaSymbols.ELT_COMPLEXTYPE, typeName, typeName+redefIdentifier, child)) {
1664                    fixRedefinedSchema(SchemaSymbols.ELT_COMPLEXTYPE,
1665                        typeName, typeName+redefIdentifier,
1666                        schemaToRedefine, currSchemaInfo);
1667                }
1668            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1669                String JavaDoc baseName = child.getAttribute( SchemaSymbols.ATT_NAME );
1670                if(fTraversedRedefineElements.contains(baseName))
1671                    continue;
1672                if(validateRedefineNameChange(SchemaSymbols.ELT_ATTRIBUTEGROUP, baseName, baseName+redefIdentifier, child)) {
1673                    fixRedefinedSchema(SchemaSymbols.ELT_ATTRIBUTEGROUP,
1674                        baseName, baseName+redefIdentifier,
1675                        schemaToRedefine, currSchemaInfo);
1676                }
1677            } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
1678                String JavaDoc baseName = child.getAttribute( SchemaSymbols.ATT_NAME );
1679                if(fTraversedRedefineElements.contains(baseName))
1680                    continue;
1681                if(validateRedefineNameChange(SchemaSymbols.ELT_GROUP, baseName, baseName+redefIdentifier, child)) {
1682                    fixRedefinedSchema(SchemaSymbols.ELT_GROUP,
1683                        baseName, baseName+redefIdentifier,
1684                        schemaToRedefine, currSchemaInfo);
1685                }
1686            } else {
1687                fRedefineSucceeded = false;
1688                // REVISIT: Localize
1689
reportGenericSchemaError("invalid top-level content for <redefine>");
1690                return;
1691            }
1692        } // for
1693
} // renameRedefinedComponents
1694

1695    // This function looks among the children of curr for an element of type elementSought.
1696
// If it finds one, it evaluates whether its ref attribute contains a reference
1697
// to originalName. If it does, it returns 1 + the value returned by
1698
// calls to itself on all other children. In all other cases it returns 0 plus
1699
// the sum of the values returned by calls to itself on curr's children.
1700
// It also resets the value of ref so that it will refer to the renamed type from the schema
1701
// being redefined.
1702
private int changeRedefineGroup(QName originalName, String JavaDoc elementSought, String JavaDoc newName, Element JavaDoc curr) throws Exception JavaDoc {
1703        int result = 0;
1704        for (Element JavaDoc child = XUtil.getFirstChildElement(curr);
1705                child != null; child = XUtil.getNextSiblingElement(child)) {
1706            String JavaDoc name = child.getLocalName();
1707            if (!name.equals(elementSought))
1708                result += changeRedefineGroup(originalName, elementSought, newName, child);
1709            else {
1710                String JavaDoc ref = child.getAttribute( SchemaSymbols.ATT_REF );
1711                if (ref.length() != 0) {
1712                    String JavaDoc prefix = "";
1713                    String JavaDoc localpart = ref;
1714                    int colonptr = ref.indexOf(":");
1715                    if ( colonptr > 0) {
1716                        prefix = ref.substring(0,colonptr);
1717                        localpart = ref.substring(colonptr+1);
1718                    }
1719                    String JavaDoc uriStr = resolvePrefixToURI(prefix);
1720                    if(originalName.equals(new QName(-1, fStringPool.addSymbol(localpart), fStringPool.addSymbol(localpart), fStringPool.addSymbol(uriStr)))) {
1721                        if(prefix.length() == 0)
1722                            child.setAttribute(SchemaSymbols.ATT_REF, newName);
1723                        else
1724                            child.setAttribute(SchemaSymbols.ATT_REF, prefix + ":" + newName);
1725                        result++;
1726                        if(elementSought.equals(SchemaSymbols.ELT_GROUP)) {
1727                            String JavaDoc minOccurs = child.getAttribute( SchemaSymbols.ATT_MINOCCURS );
1728                            String JavaDoc maxOccurs = child.getAttribute( SchemaSymbols.ATT_MAXOCCURS );
1729                            if(!((maxOccurs.length() == 0 || maxOccurs.equals("1"))
1730                                    && (minOccurs.length() == 0 || minOccurs.equals("1")))) {
1731                                //REVISIT: localize
1732
reportGenericSchemaError("src-redefine.6.1.2: the group " + ref + " which contains a reference to a group being redefined must have minOccurs = maxOccurs = 1");
1733                            }
1734                        }
1735                    }
1736                } // if ref was null some other stage of processing will flag the error
1737
}
1738        }
1739        return result;
1740    } // changeRedefineGroup
1741

1742    // This simple function looks for the first occurrence of an eltLocalname
1743
// schema information item and appropriately changes the value of
1744
// its name or type attribute from oldName to newName.
1745
// Root contains the root of the schema being operated upon.
1746
// If it turns out that what we're looking for is in a <redefine> though, then we
1747
// just rename it--and it's reference--to be the same and wait until
1748
// renameRedefineDecls can get its hands on it and do it properly.
1749
private void fixRedefinedSchema(String JavaDoc eltLocalname, String JavaDoc oldName, String JavaDoc newName, Element JavaDoc schemaToRedefine,
1750                SchemaInfo currSchema) throws Exception JavaDoc {
1751
1752        boolean foundIt = false;
1753        for (Element JavaDoc child = XUtil.getFirstChildElement(schemaToRedefine);
1754                child != null;
1755                child = XUtil.getNextSiblingElement(child)) {
1756            String JavaDoc name = child.getLocalName();
1757            if(name.equals(SchemaSymbols.ELT_REDEFINE)) { // need to search the redefine decl...
1758
for (Element JavaDoc redefChild = XUtil.getFirstChildElement(child);
1759                        redefChild != null;
1760                        redefChild = XUtil.getNextSiblingElement(redefChild)) {
1761                    String JavaDoc redefName = redefChild.getLocalName();
1762                    if (redefName.equals(eltLocalname) ) {
1763                        String JavaDoc infoItemName = redefChild.getAttribute( SchemaSymbols.ATT_NAME );
1764                        if(!infoItemName.equals(oldName))
1765                            continue;
1766                        else { // found it!
1767
foundIt = true;
1768                            openRedefinedSchema(child, currSchema);
1769                            if(!fRedefineSucceeded)
1770                                return;
1771                            NamespacesScope saveNSS = (NamespacesScope)fNamespacesScope.clone();
1772                            currSchema.restore();
1773                            if (validateRedefineNameChange(eltLocalname, oldName, newName+redefIdentifier, redefChild) &&
1774                                    (currSchema.getNext() != null)) {
1775                                currSchema.getNext().restore();
1776                                fixRedefinedSchema(eltLocalname, oldName, newName+redefIdentifier, fSchemaRootElement, currSchema.getNext());
1777                            }
1778                            fNamespacesScope = saveNSS;
1779                            redefChild.setAttribute( SchemaSymbols.ATT_NAME, newName );
1780                            // and we now know we will traverse this, so set fTraversedRedefineElements appropriately...
1781
fTraversedRedefineElements.addElement(newName);
1782                            currSchema.restore();
1783                            fCurrentSchemaInfo = currSchema;
1784                            break;
1785                        }
1786                    }
1787                } //for
1788
if (foundIt) break;
1789            }
1790            else if (name.equals(eltLocalname) ) {
1791                String JavaDoc infoItemName = child.getAttribute( SchemaSymbols.ATT_NAME );
1792                if(!infoItemName.equals(oldName))
1793                    continue;
1794                else { // found it!
1795
foundIt = true;
1796                    child.setAttribute( SchemaSymbols.ATT_NAME, newName );
1797                    break;
1798                }
1799            }
1800        } //for
1801
if(!foundIt) {
1802            fRedefineSucceeded = false;
1803            // REVISIT: localize
1804
reportGenericSchemaError("could not find a declaration in the schema to be redefined corresponding to " + oldName);
1805        }
1806    } // end fixRedefinedSchema
1807

1808    // this method returns true if the redefine component is valid, and if
1809
// it was possible to revise it correctly. The definition of
1810
// correctly will depend on whether renameRedefineDecls
1811
// or fixRedefineSchema is the caller.
1812
// this method also prepends a prefix onto newName if necessary; newName will never contain one.
1813
private boolean validateRedefineNameChange(String JavaDoc eltLocalname, String JavaDoc oldName, String JavaDoc newName, Element JavaDoc child) throws Exception JavaDoc {
1814        if (eltLocalname.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1815            QName processedTypeName = new QName(-1, fStringPool.addSymbol(oldName), fStringPool.addSymbol(oldName), fTargetNSURI);
1816            Element JavaDoc grandKid = XUtil.getFirstChildElement(child);
1817            if (grandKid == null) {
1818                fRedefineSucceeded = false;
1819                // REVISIT: Localize
1820
reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
1821            } else {
1822                String JavaDoc grandKidName = grandKid.getLocalName();
1823                if(grandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
1824                    grandKid = XUtil.getNextSiblingElement(grandKid);
1825                    grandKidName = grandKid.getLocalName();
1826                }
1827                if (grandKid == null) {
1828                    fRedefineSucceeded = false;
1829                    // REVISIT: Localize
1830
reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
1831                } else if(!grandKidName.equals(SchemaSymbols.ELT_RESTRICTION)) {
1832                    fRedefineSucceeded = false;
1833                    // REVISIT: Localize
1834
reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
1835                } else {
1836                    String JavaDoc derivedBase = grandKid.getAttribute( SchemaSymbols.ATT_BASE );
1837                    QName processedDerivedBase = parseBase(derivedBase);
1838                    if(!processedTypeName.equals(processedDerivedBase)) {
1839                        fRedefineSucceeded = false;
1840                        // REVISIT: Localize
1841
reportGenericSchemaError("the base attribute of the restriction child of a simpleType child of a redefine must have the same value as the simpleType's type attribute");
1842                    } else {
1843                        // now we have to do the renaming...
1844
String JavaDoc prefix = "";
1845                        int colonptr = derivedBase.indexOf(":");
1846                        if ( colonptr > 0)
1847                            prefix = derivedBase.substring(0,colonptr) + ":";
1848                        grandKid.setAttribute( SchemaSymbols.ATT_BASE, prefix + newName );
1849                        return true;
1850                    }
1851                }
1852            }
1853        } else if (eltLocalname.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1854            QName processedTypeName = new QName(-1, fStringPool.addSymbol(oldName), fStringPool.addSymbol(oldName), fTargetNSURI);
1855            Element JavaDoc grandKid = XUtil.getFirstChildElement(child);
1856            if (grandKid == null) {
1857                fRedefineSucceeded = false;
1858                // REVISIT: Localize
1859
reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
1860            } else {
1861                if(grandKid.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
1862                    grandKid = XUtil.getNextSiblingElement(grandKid);
1863                }
1864                if (grandKid == null) {
1865                    fRedefineSucceeded = false;
1866                    // REVISIT: Localize
1867
reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
1868                } else {
1869                    // have to go one more level down; let another pass worry whether complexType is valid.
1870
Element JavaDoc greatGrandKid = XUtil.getFirstChildElement(grandKid);
1871                    if (greatGrandKid == null) {
1872                        fRedefineSucceeded = false;
1873                        // REVISIT: Localize
1874
reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
1875                    } else {
1876                        String JavaDoc greatGrandKidName = greatGrandKid.getLocalName();
1877                        if(greatGrandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
1878                            greatGrandKid = XUtil.getNextSiblingElement(greatGrandKid);
1879                            greatGrandKidName = greatGrandKid.getLocalName();
1880                        }
1881                        if (greatGrandKid == null) {
1882                            fRedefineSucceeded = false;
1883                            // REVISIT: Localize
1884
reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
1885                        } else if(!greatGrandKidName.equals(SchemaSymbols.ELT_RESTRICTION) &&
1886                                !greatGrandKidName.equals(SchemaSymbols.ELT_EXTENSION)) {
1887                            fRedefineSucceeded = false;
1888                            // REVISIT: Localize
1889
reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
1890                        } else {
1891                            String JavaDoc derivedBase = greatGrandKid.getAttribute( SchemaSymbols.ATT_BASE );
1892                            QName processedDerivedBase = parseBase(derivedBase);
1893                            if(!processedTypeName.equals(processedDerivedBase)) {
1894                                fRedefineSucceeded = false;
1895                                // REVISIT: Localize
1896
reportGenericSchemaError("the base attribute of the restriction or extension grandchild of a complexType child of a redefine must have the same value as the complexType's type attribute");
1897                            } else {
1898                                // now we have to do the renaming...
1899
String JavaDoc prefix = "";
1900                                int colonptr = derivedBase.indexOf(":");
1901                                if ( colonptr > 0)
1902                                    prefix = derivedBase.substring(0,colonptr) + ":";
1903                                greatGrandKid.setAttribute( SchemaSymbols.ATT_BASE, prefix + newName );
1904                                return true;
1905                            }
1906                        }
1907                    }
1908                }
1909            }
1910        } else if (eltLocalname.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1911            QName processedBaseName = new QName(-1, fStringPool.addSymbol(oldName), fStringPool.addSymbol(oldName), fTargetNSURI);
1912            int attGroupRefsCount = changeRedefineGroup(processedBaseName, eltLocalname, newName, child);
1913            if(attGroupRefsCount > 1) {
1914                fRedefineSucceeded = false;
1915                // REVISIT: localize
1916
reportGenericSchemaError("if an attributeGroup child of a <redefine> element contains an attributeGroup ref'ing itself, it must have exactly 1; this one has " + attGroupRefsCount);
1917            } else if (attGroupRefsCount == 1) {
1918                return true;
1919            } else
1920                fRedefineAttributeGroupMap.put(oldName, newName);
1921        } else if (eltLocalname.equals(SchemaSymbols.ELT_GROUP)) {
1922            QName processedBaseName = new QName(-1, fStringPool.addSymbol(oldName), fStringPool.addSymbol(oldName), fTargetNSURI);
1923            int groupRefsCount = changeRedefineGroup(processedBaseName, eltLocalname, newName, child);
1924            String JavaDoc restrictedName = newName.substring(0, newName.length()-redefIdentifier.length());
1925            if(!fRedefineSucceeded) {
1926                fRestrictedRedefinedGroupRegistry.put(fTargetNSURIString+","+restrictedName, new Boolean JavaDoc(false));
1927            }
1928            if(groupRefsCount > 1) {
1929                fRedefineSucceeded = false;
1930                fRestrictedRedefinedGroupRegistry.put(fTargetNSURIString+","+restrictedName, new Boolean JavaDoc(false));
1931                // REVISIT: localize
1932
reportGenericSchemaError("if a group child of a <redefine> element contains a group ref'ing itself, it must have exactly 1; this one has " + groupRefsCount);
1933            } else if (groupRefsCount == 1) {
1934                fRestrictedRedefinedGroupRegistry.put(fTargetNSURIString+","+restrictedName, new Boolean JavaDoc(false));
1935                return true;
1936            } else {
1937                fGroupNameRegistry.put(fTargetNSURIString + "," + oldName, newName);
1938                fRestrictedRedefinedGroupRegistry.put(fTargetNSURIString+","+restrictedName, new Boolean JavaDoc(true));
1939            }
1940        } else {
1941            fRedefineSucceeded = false;
1942            // REVISIT: Localize
1943
reportGenericSchemaError("internal Xerces error; please submit a bug with schema as testcase");
1944        }
1945        // if we get here then we must have reported an error and failed somewhere...
1946
return false;
1947    } // validateRedefineNameChange
1948

1949    private void traverseImport(Element JavaDoc importDecl) throws Exception JavaDoc {
1950        // General Attribute Checking
1951
int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
1952        Hashtable JavaDoc attrValues = generalCheck(importDecl, scope);
1953        checkContent(importDecl, XUtil.getFirstChildElement(importDecl), true);
1954
1955         String JavaDoc namespaceString = importDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE);
1956         SchemaGrammar importedGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(namespaceString);
1957
1958         if ((importedGrammar == null) || namespaceString.trim().equals(fTargetNSURIString)) {
1959             importedGrammar = new SchemaGrammar();
1960         } else {
1961             return;
1962         }
1963
1964         Element JavaDoc root = null;
1965         if(namespaceString.length() == 0) {
1966            if(fTargetNSURI == StringPool.EMPTY_STRING) {
1967                // REVISIT: localize
1968
reportGenericSchemaError("src-import.1.2: if the namespace attribute on an <import> element is not present, the <import>ing schema must have a targetNamespace");
1969                // look in external-noNamespaceSchemaLocation property!
1970
if(fExternalNoNamespaceSchema != null) {
1971                    root = openImportedSchema(fExternalNoNamespaceSchema);
1972                }
1973            }
1974        } else {
1975            if(fTargetNSURIString.equals(namespaceString.trim())) {
1976                // REVISIT: localize
1977
reportGenericSchemaError("src-import.1.1: the namespace attribute of an <import> element must not be the same as the targetNamespace of the <import>ing schema");
1978                // look in external-schemaLocation property!
1979
if(fExternalSchemas != null) {
1980                    Enumeration JavaDoc externalNamespaces = fExternalSchemas.keys();
1981                    while(externalNamespaces.hasMoreElements()) {
1982                        String JavaDoc namespace = (String JavaDoc)externalNamespaces.nextElement();
1983                        if(namespace.trim().equals(namespaceString.trim())) {
1984                            root = openImportedSchema((String JavaDoc)fExternalSchemas.get(namespace));
1985                            break;
1986                        }
1987                    }
1988                }
1989            }
1990        }
1991        String JavaDoc location = "";
1992        if(root == null) { // try our own schemaLocation
1993
Attr JavaDoc locationAttr = importDecl.getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
1994            if(locationAttr != null) {
1995                location = locationAttr.getValue();
1996                root = openImportedSchema(location);
1997            }
1998         }
1999         if (root != null) {
2000             String JavaDoc targetNSURI = getTargetNamespaceString(root);
2001             if (!targetNSURI.equals(namespaceString) ) {
2002                 // REVISIT: Localize
2003
reportGenericSchemaError("imported schema '"+location+"' has a different targetNameSpace '"
2004                                          +targetNSURI+"' from what is declared '"+namespaceString+"'.");
2005             }
2006             else {
2007                 location = fCurrentSchemaURL;
2008                 TraverseSchema impSchema = new TraverseSchema(root, fStringPool, importedGrammar, fGrammarResolver, fErrorReporter, location, fEntityResolver, fFullConstraintChecking, fGeneralAttrCheck, fUnparsedExternalSchemas, fExternalNoNamespaceSchema);
2009                 fCurrentSchemaURL = (String JavaDoc)fSchemaURLStack.pop();
2010                 Enumeration JavaDoc ics = impSchema.fIdentityConstraints.keys();
2011                 while(ics.hasMoreElements()) {
2012                    Object JavaDoc icsKey = ics.nextElement();
2013                    fIdentityConstraints.put(icsKey, impSchema.fIdentityConstraints.get(icsKey));
2014                }
2015                 Enumeration JavaDoc icNames = impSchema.fIdentityConstraintNames.keys();
2016                 while(icNames.hasMoreElements()) {
2017                    String JavaDoc icsNameKey = (String JavaDoc)icNames.nextElement();
2018                    fIdentityConstraintNames.put(icsNameKey, impSchema.fIdentityConstraintNames.get(icsNameKey));
2019                }
2020            }
2021         }
2022    }
2023
2024    private Element JavaDoc openImportedSchema(String JavaDoc location) throws Exception JavaDoc {
2025        // expand it before passing it to the parser
2026
InputSource JavaDoc source = null;
2027
2028        // If fEntityResolver is not null and is not the default, only then use it - Gopal Sharma, Sun Microsystems Inc.
2029
if ( (fEntityResolver != null) &&
2030             !(fEntityResolver.getClass().getName().equals("org.enhydra.apache.xerces.validators.common.XMLValidator$Resolver")) ) {
2031            source = fEntityResolver.resolveEntity("", location);
2032        }
2033
2034        if (source == null) {
2035            location = expandSystemId(location, fCurrentSchemaURL);
2036            source = new InputSource JavaDoc(location);
2037        }
2038         // create a string for uniqueness of this imported schema in fImportLocations
2039
// algorithm: string is pubId+sysId or if both null then filename
2040
String JavaDoc pubId = "";
2041        String JavaDoc sysId = "";
2042        if (source.getPublicId () != null)
2043            pubId = source.getPublicId ();
2044        if (source.getSystemId () != null)
2045            sysId = source.getSystemId ();
2046
2047        if(pubId.length() != 0 || sysId.length() != 0)
2048            location = pubId+sysId;
2049
2050         if (fImportLocations.contains((Object JavaDoc)location)) {
2051             return null;
2052         }
2053        // check to make sure we're not importing ourselves...
2054
if(source.getSystemId().equals(fCurrentSchemaURL)) {
2055            // REVISIT: localize
2056
return null;
2057        }
2058
2059         DOMParser parser = new IgnoreWhitespaceParser();
2060         parser.setEntityResolver( (fEntityResolver != null)? (fEntityResolver):(new Resolver()) );
2061         parser.setErrorHandler( new ErrorHandler ()
2062            {
2063                public void error(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
2064                    StringBuffer JavaDoc str = new StringBuffer JavaDoc();
2065                    String JavaDoc systemId_ = ex.getSystemId();
2066                    if (systemId_ != null) {
2067                        int index = systemId_.lastIndexOf('/');
2068                        if (index != -1)
2069                            systemId_ = systemId_.substring(index + 1);
2070                        str.append(systemId_);
2071                    }
2072                    str.append(':').append(ex.getLineNumber()).append(':').append(ex.getColumnNumber());
2073                    String JavaDoc message = ex.getMessage();
2074                    if(message.toLowerCase().trim().endsWith("not found.")) {
2075                        System.err.println("[Warning] "+
2076                               str.toString()+": "+ message);
2077                    } else { // do standard thing
2078
System.err.println("[Error] "+
2079                               str.toString()+":"+message);
2080                        throw ex;
2081                    }
2082                }
2083            });
2084
2085         try {
2086             parser.setFeature("http://xml.org/sax/features/validation", false);
2087             parser.setFeature("http://xml.org/sax/features/namespaces", true);
2088             parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
2089             parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
2090         }catch( org.xml.sax.SAXNotRecognizedException JavaDoc e ) {
2091             e.printStackTrace();
2092         }catch( org.xml.sax.SAXNotSupportedException JavaDoc e ) {
2093             e.printStackTrace();
2094         }
2095
2096         try {
2097             parser.parse( source );
2098         }catch( IOException JavaDoc e ) {
2099             // e.printStackTrace();
2100
}catch( SAXException JavaDoc e ) {
2101             e.printStackTrace();
2102         }
2103
2104         Document JavaDoc document = parser.getDocument(); //Our Grammar
2105
Element JavaDoc root = null;
2106         if (document != null) {
2107             root = document.getDocumentElement();
2108         }
2109         if(root != null) {
2110            fImportLocations.addElement((Object JavaDoc)location);
2111        }
2112        fSchemaURLStack.push(fCurrentSchemaURL);
2113        fCurrentSchemaURL = location;
2114        return root;
2115    } // openImportedSchema
2116

2117    // utility method for finding the targetNamespace (and flagging errors if they occur)
2118
private String JavaDoc getTargetNamespaceString( Element JavaDoc root) throws Exception JavaDoc {
2119        String JavaDoc targetNSURI = "";
2120        Attr JavaDoc targetNSAttr = root.getAttributeNode(SchemaSymbols.ATT_TARGETNAMESPACE);
2121        if(targetNSAttr != null) {
2122            targetNSURI=targetNSAttr.getValue();
2123            if(targetNSURI.length() == 0) {
2124                // REVISIT: localize
2125
reportGenericSchemaError("sch-prop-correct.1: \"\" is not a legal value for the targetNamespace attribute; the attribute must either be absent or contain a nonempty value");
2126            }
2127        }
2128        return targetNSURI;
2129    } // end getTargetNamespaceString(Element)
2130

2131    /**
2132    * <annotation>(<appinfo> | <documentation>)*</annotation>
2133    *
2134    * @param annotationDecl: the DOM node corresponding to the <annotation> info item
2135    */

2136    private void traverseAnnotationDecl(Element JavaDoc annotationDecl) throws Exception JavaDoc {
2137
2138        // General Attribute Checking
2139
int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
2140        Hashtable JavaDoc attrValues = generalCheck(annotationDecl, scope);
2141
2142        for(Element JavaDoc child = XUtil.getFirstChildElement(annotationDecl); child != null;
2143                 child = XUtil.getNextSiblingElement(child)) {
2144            String JavaDoc name = child.getLocalName();
2145            if(!((name.equals(SchemaSymbols.ELT_APPINFO)) ||
2146                    (name.equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
2147                // REVISIT: Localize
2148
reportGenericSchemaError("an <annotation> can only contain <appinfo> and <documentation> elements");
2149            }
2150
2151            // General Attribute Checking
2152
attrValues = generalCheck(child, scope);
2153        }
2154    }
2155
2156
2157    //
2158
// Evaluates content of Annotation if present.
2159
//
2160
// @param: elm - top element
2161
// @param: content - content must be annotation? or some other simple content
2162
// @param: isEmpty: -- true if the content allowed is (annotation?) only
2163
// false if must have some element (with possible preceding <annotation?>)
2164
//
2165
//REVISIT: this function should be used in all traverse* methods!
2166
private Element JavaDoc checkContent( Element JavaDoc elm, Element JavaDoc content, boolean isEmpty ) throws Exception JavaDoc {
2167       //isEmpty = true-> means content can be null!
2168
if ( content == null) {
2169           if (!isEmpty) {
2170               reportSchemaError(SchemaMessageProvider.ContentError,
2171                                 new Object JavaDoc [] { elm.getAttribute( SchemaSymbols.ATT_NAME )});
2172           }
2173           return null;
2174       }
2175       if (content.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
2176           traverseAnnotationDecl( content );
2177           content = XUtil.getNextSiblingElement(content);
2178           if (content == null ) { //must be followed by <simpleType?>
2179
if (!isEmpty) {
2180                   reportSchemaError(SchemaMessageProvider.ContentError,
2181                                     new Object JavaDoc [] { elm.getAttribute( SchemaSymbols.ATT_NAME )});
2182               }
2183               return null;
2184           }
2185           if (content.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
2186               reportSchemaError(SchemaMessageProvider.AnnotationError,
2187                                 new Object JavaDoc [] { elm.getAttribute( SchemaSymbols.ATT_NAME )});
2188               return null;
2189           }
2190           //return null if expected only annotation?, else returns updated content
2191
}
2192       return content;
2193   }
2194
2195
2196   //@param: elm - top element
2197
//@param: baseTypeStr - type (base/itemType/memberTypes)
2198
//@param: baseRefContext: whether the caller is using this type as a base for restriction, union or list
2199
//return DatatypeValidator available for the baseTypeStr, null if not found or disallowed.
2200
// also throws an error if the base type won't allow itself to be used in this context.
2201
//REVISIT: this function should be used in some|all traverse* methods!
2202
private DatatypeValidator findDTValidator (Element JavaDoc elm, String JavaDoc baseTypeStr, int baseRefContext ) throws Exception JavaDoc{
2203        int baseType = fStringPool.addSymbol( baseTypeStr );
2204        String JavaDoc prefix = "";
2205        DatatypeValidator baseValidator = null;
2206        String JavaDoc localpart = baseTypeStr;
2207        int colonptr = baseTypeStr.indexOf(":");
2208        if ( colonptr > 0) {
2209            prefix = baseTypeStr.substring(0,colonptr);
2210            localpart = baseTypeStr.substring(colonptr+1);
2211        }
2212        String JavaDoc uri = resolvePrefixToURI(prefix);
2213        if (uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
2214            localpart.equals("anySimpleType") &&
2215            baseRefContext == SchemaSymbols.RESTRICTION) {
2216            reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
2217                              new Object JavaDoc [] { elm.getAttribute( SchemaSymbols.ATT_BASE ),
2218                                              elm.getAttribute(SchemaSymbols.ATT_NAME)});
2219            return null;
2220        }
2221        baseValidator = getDatatypeValidator(uri, localpart);
2222        if (baseValidator == null) {
2223            Element JavaDoc baseTypeNode = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
2224            if (baseTypeNode != null) {
2225                traverseSimpleTypeDecl( baseTypeNode );
2226
2227                baseValidator = getDatatypeValidator(uri, localpart);
2228            }
2229        }
2230        Integer JavaDoc finalValue;
2231        if ( baseValidator == null ) {
2232            reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
2233                              new Object JavaDoc [] { elm.getAttribute( SchemaSymbols.ATT_BASE ),
2234                                  elm.getAttribute(SchemaSymbols.ATT_NAME)});
2235        } else {
2236            finalValue =
2237                    ((Integer JavaDoc)fSimpleTypeFinalRegistry.get(uri + "," +localpart));
2238            if((finalValue != null) &&
2239                    ((finalValue.intValue() & baseRefContext) != 0)) {
2240                //REVISIT: localize
2241
reportGenericSchemaError("the base type " + baseTypeStr + " does not allow itself to be used as the base for a restriction and/or as a type in a list and/or union");
2242                return baseValidator;
2243            }
2244        }
2245       return baseValidator;
2246    }
2247
2248    private void checkEnumerationRequiredNotation(String JavaDoc name, String JavaDoc type) throws Exception JavaDoc{
2249        String JavaDoc localpart = type;
2250        int colonptr = type.indexOf(":");
2251        if ( colonptr > 0) {
2252            localpart = type.substring(colonptr+1);
2253        }
2254        if (localpart.equals("NOTATION")) {
2255          reportGenericSchemaError("[enumeration-required-notation] It is an error for NOTATION to be used "+
2256                                "directly in a schema in element/attribute '"+name+"'");
2257        }
2258
2259    }
2260
2261   // @used in traverseSimpleType
2262
// on return we need to pop the last simpleType name from
2263
// the name stack
2264
private int resetSimpleTypeNameStack(int returnValue){
2265       if (!fSimpleTypeNameStack.empty()) {
2266           fSimpleTypeNameStack.pop();
2267       }
2268       return returnValue;
2269    }
2270
2271    // @used in traverseSimpleType
2272
// report an error cos-list-of-atomic and reset the last name of the list datatype we traversing
2273
private void reportCosListOfAtomic () throws Exception JavaDoc{
2274       reportGenericSchemaError("cos-list-of-atomic: The itemType must have a {variety} of atomic or union (in which case all the {member type definitions} must be atomic)");
2275       fListName="";
2276    }
2277
2278    // @used in traverseSimpleType
2279
// find if union datatype validator has list datatype member.
2280
private boolean isListDatatype (DatatypeValidator validator){
2281       if (validator instanceof UnionDatatypeValidator) {
2282              Vector JavaDoc temp = ((UnionDatatypeValidator)validator).getBaseValidators();
2283              for (int i=0;i<temp.size();i++) {
2284                   if (temp.elementAt(i) instanceof ListDatatypeValidator) {
2285                       return true;
2286                   }
2287                   if (temp.elementAt(i) instanceof UnionDatatypeValidator) {
2288                       if (isListDatatype((DatatypeValidator)temp.elementAt(i))) {
2289                           return true;
2290                       }
2291                   }
2292              }
2293       }
2294       return false;
2295    }
2296
2297
2298
2299   /**
2300     * Traverse SimpleType declaration:
2301     * <simpleType
2302     * final = #all | list of (restriction, union or list)
2303     * id = ID
2304     * name = NCName>
2305     * Content: (annotation? , ((list | restriction | union)))
2306     * </simpleType>
2307     * traverse <list>|<restriction>|<union>
2308     *
2309     * @param simpleTypeDecl
2310     * @return
2311     */

2312    private int traverseSimpleTypeDecl( Element JavaDoc simpleTypeDecl ) throws Exception JavaDoc {
2313
2314        // General Attribute Checking
2315
int scope = isTopLevel(simpleTypeDecl)?
2316                    GeneralAttrCheck.ELE_CONTEXT_GLOBAL:
2317                    GeneralAttrCheck.ELE_CONTEXT_LOCAL;
2318        Hashtable JavaDoc attrValues = generalCheck(simpleTypeDecl, scope);
2319
2320        String JavaDoc nameProperty = simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME );
2321        String JavaDoc qualifiedName = nameProperty;
2322
2323
2324        //---------------------------------------------------
2325
// set qualified name
2326
//---------------------------------------------------
2327
if ( nameProperty.length() == 0) { // anonymous simpleType
2328
qualifiedName = fTargetNSURIString+","+"#S#"+(fSimpleTypeAnonCount++);
2329            fStringPool.addSymbol(qualifiedName);
2330        }
2331        else {
2332            // this behaviour has been changed so that we neither
2333
// process unqualified names as if they came from the schemaforschema namespace nor
2334
// fail to pick up unqualified names from schemas with no
2335
// targetnamespace. - NG
2336
//if (fTargetNSURIString.length () != 0) {
2337
qualifiedName = fTargetNSURIString+","+qualifiedName;
2338            //}
2339
fStringPool.addSymbol( nameProperty );
2340        }
2341
2342        //----------------------------------------------------------------------
2343
//check if we have already traversed the same simpleType decl
2344
//----------------------------------------------------------------------
2345
if (fDatatypeRegistry.getDatatypeValidator(qualifiedName)!=null) {
2346            return resetSimpleTypeNameStack(fStringPool.addSymbol(qualifiedName));
2347        }
2348        else {
2349           if (fSimpleTypeNameStack.search(qualifiedName) != -1 ){
2350               // cos-no-circular-unions && no circular definitions
2351
reportGenericSchemaError("cos-no-circular-unions: no circular definitions are allowed for an element '"+ nameProperty+"'");
2352               return resetSimpleTypeNameStack(-1);
2353           }
2354        }
2355
2356
2357        //----------------------------------------------------------
2358
// update _final_ registry
2359
//----------------------------------------------------------
2360
Attr JavaDoc finalAttr = simpleTypeDecl.getAttributeNode(SchemaSymbols.ATT_FINAL);
2361        int finalProperty = 0;
2362        if(finalAttr != null)
2363            finalProperty = parseFinalSet(finalAttr.getValue());
2364        else
2365            finalProperty = parseFinalSet(null);
2366
2367        // if we have a nonzero final , store it in the hash...
2368
if(finalProperty != 0)
2369            fSimpleTypeFinalRegistry.put(qualifiedName, new Integer JavaDoc(finalProperty));
2370
2371
2372        // -------------------------------
2373
// remember name being traversed to
2374
// avoid circular definitions in union
2375
// -------------------------------
2376
fSimpleTypeNameStack.push(qualifiedName);
2377
2378
2379        //----------------------------------------------------------------------
2380
//annotation?,(list|restriction|union)
2381
//----------------------------------------------------------------------
2382
Element JavaDoc content = XUtil.getFirstChildElement(simpleTypeDecl);
2383        content = checkContent(simpleTypeDecl, content, false);
2384        if (content == null) {
2385            return resetSimpleTypeNameStack(-1);
2386        }
2387
2388        // General Attribute Checking
2389
scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
2390        Hashtable JavaDoc contentAttrs = generalCheck(content, scope);
2391
2392        //----------------------------------------------------------------------
2393
//use content.getLocalName for the cases there "xsd:" is a prefix, ei. "xsd:list"
2394
//----------------------------------------------------------------------
2395
String JavaDoc varietyProperty = content.getLocalName();
2396        String JavaDoc baseTypeQNameProperty = null;
2397        Vector JavaDoc dTValidators = null;
2398        int size = 0;
2399        StringTokenizer JavaDoc unionMembers = null;
2400        boolean list = false;
2401        boolean union = false;
2402        boolean restriction = false;
2403        int numOfTypes = 0; //list/restriction = 1, union = "+"
2404

2405        if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) { //traverse List
2406
baseTypeQNameProperty = content.getAttribute( SchemaSymbols.ATT_ITEMTYPE );
2407           list = true;
2408           if (fListName.length() != 0) { // parent is <list> datatype
2409
reportCosListOfAtomic();
2410                    return resetSimpleTypeNameStack(-1);
2411           }
2412           else {
2413                fListName = qualifiedName;
2414           }
2415        }
2416        else if (varietyProperty.equals(SchemaSymbols.ELT_RESTRICTION)) { //traverse Restriction
2417
baseTypeQNameProperty = content.getAttribute( SchemaSymbols.ATT_BASE );
2418            restriction= true;
2419        }
2420        else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) { //traverse union
2421
union = true;
2422            baseTypeQNameProperty = content.getAttribute( SchemaSymbols.ATT_MEMBERTYPES);
2423            if (baseTypeQNameProperty.length() != 0) {
2424                unionMembers = new StringTokenizer JavaDoc( baseTypeQNameProperty );
2425                size = unionMembers.countTokens();
2426            }
2427            else {
2428                size = 1; //at least one must be seen as <simpleType> decl
2429
}
2430            dTValidators = new Vector JavaDoc (size, 2);
2431        }
2432        else {
2433             reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
2434                       new Object JavaDoc [] { varietyProperty });
2435                       return -1;
2436        }
2437        if(XUtil.getNextSiblingElement(content) != null) {
2438            // REVISIT: Localize
2439
reportGenericSchemaError("error in content of simpleType");
2440        }
2441
2442        int typeNameIndex;
2443        DatatypeValidator baseValidator = null;
2444
2445        if ( baseTypeQNameProperty.length() == 0 ) {
2446            //---------------------------
2447
//must 'see' <simpleType>
2448
//---------------------------
2449

2450            //content = {annotation?,simpleType?...}
2451
content = XUtil.getFirstChildElement(content);
2452
2453            //check content (annotation?, ...)
2454
content = checkContent(simpleTypeDecl, content, false);
2455            if (content == null) {
2456                return resetSimpleTypeNameStack(-1);
2457            }
2458            if (content.getLocalName().equals( SchemaSymbols.ELT_SIMPLETYPE )) {
2459              typeNameIndex = traverseSimpleTypeDecl(content);
2460              if (typeNameIndex!=-1) {
2461                  baseValidator=fDatatypeRegistry.getDatatypeValidator(fStringPool.toString(typeNameIndex));
2462                  if (baseValidator !=null && union) {
2463                      dTValidators.addElement((DatatypeValidator)baseValidator);
2464                  }
2465              }
2466              if ( typeNameIndex == -1 || baseValidator == null) {
2467                  reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
2468                                        new Object JavaDoc [] { content.getAttribute( SchemaSymbols.ATT_BASE ),
2469                                            content.getAttribute(SchemaSymbols.ATT_NAME) });
2470                      return resetSimpleTypeNameStack(-1);
2471              }
2472            }
2473            else {
2474                 reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2475                        new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2476                 return resetSimpleTypeNameStack(-1);
2477            }
2478        } //end - must see simpleType?
2479
else {
2480            //-----------------------------
2481
//base was provided - get proper validator.
2482
//-----------------------------
2483
numOfTypes = 1;
2484            if (union) {
2485                numOfTypes= size;
2486            }
2487            //--------------------------------------------------------------------
2488
// this loop is also where we need to find out whether the type being used as
2489
// a base (or itemType or whatever) allows such things.
2490
//--------------------------------------------------------------------
2491
int baseRefContext = (restriction? SchemaSymbols.RESTRICTION:0);
2492            baseRefContext = baseRefContext | (union? SchemaSymbols.UNION:0);
2493            baseRefContext = baseRefContext | (list ? SchemaSymbols.LIST:0);
2494            for (int i=0; i<numOfTypes; i++) { //find all validators
2495
if (union) {
2496                    baseTypeQNameProperty = unionMembers.nextToken();
2497                }
2498                baseValidator = findDTValidator ( simpleTypeDecl, baseTypeQNameProperty, baseRefContext);
2499                if ( baseValidator == null) {
2500                    return resetSimpleTypeNameStack(-1);
2501                }
2502                // ------------------------------
2503
// (variety is list)cos-list-of-atomic
2504
// ------------------------------
2505
if (fListName.length() != 0 ) {
2506                    if (baseValidator instanceof ListDatatypeValidator) {
2507                        reportCosListOfAtomic();
2508                        return resetSimpleTypeNameStack(-1);
2509                    }
2510                    //-----------------------------------------------------
2511
// if baseValidator is of type (union) need to look
2512
// at Union validators to make sure that List is not one of them
2513
//-----------------------------------------------------
2514
if (isListDatatype(baseValidator)) {
2515                        reportCosListOfAtomic();
2516                        return resetSimpleTypeNameStack(-1);
2517
2518                    }
2519
2520                }
2521                if (union) {
2522                    dTValidators.addElement((DatatypeValidator)baseValidator); //add validator to structure
2523
}
2524            }
2525        } //end - base is available
2526

2527
2528        // ------------------------------------------
2529
// move to next child
2530
// <base==empty)->[simpleType]->[facets] OR
2531
// <base!=empty)->[facets]
2532
// ------------------------------------------
2533
if (baseTypeQNameProperty.length() == 0) {
2534            content = XUtil.getNextSiblingElement( content );
2535        }
2536        else {
2537            content = XUtil.getFirstChildElement(content);
2538        }
2539
2540        // ------------------------------------------
2541
//get more types for union if any
2542
// ------------------------------------------
2543
if (union) {
2544            int index=size;
2545            if (baseTypeQNameProperty.length() != 0 ) {
2546                content = checkContent(simpleTypeDecl, content, true);
2547            }
2548            while (content!=null) {
2549                typeNameIndex = traverseSimpleTypeDecl(content);
2550                if (typeNameIndex!=-1) {
2551                    baseValidator=fDatatypeRegistry.getDatatypeValidator(fStringPool.toString(typeNameIndex));
2552                    if (baseValidator != null) {
2553                        if (fListName.length() != 0 && baseValidator instanceof ListDatatypeValidator) {
2554                            reportCosListOfAtomic();
2555                            return resetSimpleTypeNameStack(-1);
2556                        }
2557                        dTValidators.addElement((DatatypeValidator)baseValidator);
2558                    }
2559                }
2560                if ( baseValidator == null || typeNameIndex == -1) {
2561                     reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
2562                                      new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_BASE ),
2563                                          simpleTypeDecl.getAttribute(SchemaSymbols.ATT_NAME)});
2564                    return (-1);
2565                }
2566                content = XUtil.getNextSiblingElement( content );
2567            }
2568        } // end - traverse Union
2569

2570
2571        if (fListName.length() != 0) {
2572            // reset fListName, meaning that we are done with
2573
// traversing <list> and its itemType resolves to atomic value
2574
if (fListName.equals(qualifiedName)) {
2575                fListName = "";
2576            }
2577        }
2578
2579        int numFacets=0;
2580        fFacetData.clear();
2581        if (restriction && content != null) {
2582            short flags = 0; // flag facets that have fixed="true"
2583
int numEnumerationLiterals = 0;
2584            Vector JavaDoc enumData = new Vector JavaDoc();
2585            content = checkContent(simpleTypeDecl, content , true);
2586            StringBuffer JavaDoc pattern = null;
2587            String JavaDoc facet;
2588            while (content != null) {
2589                if (content.getNodeType() == Node.ELEMENT_NODE) {
2590                        // General Attribute Checking
2591
contentAttrs = generalCheck(content, scope);
2592                        numFacets++;
2593                        facet =content.getLocalName();
2594                        if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
2595                            numEnumerationLiterals++;
2596                            String JavaDoc enumVal = content.getAttribute(SchemaSymbols.ATT_VALUE);
2597                            String JavaDoc localName;
2598                            if (baseValidator instanceof NOTATIONDatatypeValidator) {
2599                                String JavaDoc prefix = "";
2600                                String JavaDoc localpart = enumVal;
2601                                int colonptr = enumVal.indexOf(":");
2602                                if ( colonptr > 0) {
2603                                        prefix = enumVal.substring(0,colonptr);
2604                                        localpart = enumVal.substring(colonptr+1);
2605                                }
2606                                String JavaDoc uriStr = (prefix.length() != 0)?resolvePrefixToURI(prefix):fTargetNSURIString;
2607                                nameProperty=uriStr + ":" + localpart;
2608                                localName = (String JavaDoc)fNotationRegistry.get(nameProperty);
2609                                if(localName == null){
2610                                       localName = traverseNotationFromAnotherSchema( localpart, uriStr);
2611                                       if (localName == null) {
2612                                            reportGenericSchemaError("Notation '" + localpart +
2613                                                                    "' not found in the grammar "+ uriStr);
2614
2615                                       }
2616                                }
2617                                enumVal=nameProperty;
2618                            }
2619                            enumData.addElement(enumVal);
2620                            checkContent(simpleTypeDecl, XUtil.getFirstChildElement( content ), true);
2621                        }
2622                        else if (facet.equals(SchemaSymbols.ELT_ANNOTATION) || facet.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
2623                                  reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2624                                  new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2625                        }
2626                        else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
2627                            if (pattern == null) {
2628                                pattern = new StringBuffer JavaDoc (content.getAttribute( SchemaSymbols.ATT_VALUE ));
2629                            }
2630                            else {
2631                                // ---------------------------------------------
2632
//datatypes: 5.2.4 pattern: src-multiple-pattern
2633
// ---------------------------------------------
2634
pattern.append("|");
2635                                pattern.append(content.getAttribute( SchemaSymbols.ATT_VALUE ));
2636                                checkContent(simpleTypeDecl, XUtil.getFirstChildElement( content ), true);
2637                            }
2638                        }
2639                        else {
2640                            if ( fFacetData.containsKey(facet) )
2641                                reportSchemaError(SchemaMessageProvider.DatatypeError,
2642                                                  new Object JavaDoc [] {"The facet '" + facet + "' is defined more than once."} );
2643                             fFacetData.put(facet,content.getAttribute( SchemaSymbols.ATT_VALUE ));
2644
2645                             if (content.getAttribute( SchemaSymbols.ATT_FIXED).equals(SchemaSymbols.ATTVAL_TRUE) ||
2646                                 content.getAttribute( SchemaSymbols.ATT_FIXED).equals(SchemaSymbols.ATTVAL_TRUE_1)){
2647                                 // --------------------------------------------
2648
// set fixed facet flags
2649
// length - must remain const through derivation
2650
// thus we don't care if it fixed
2651
// --------------------------------------------
2652
if ( facet.equals(SchemaSymbols.ELT_MINLENGTH) ) {
2653                                      flags |= DatatypeValidator.FACET_MINLENGTH;
2654                                  }
2655                                  else if (facet.equals(SchemaSymbols.ELT_MAXLENGTH)) {
2656                                      flags |= DatatypeValidator.FACET_MAXLENGTH;
2657                                  }
2658                                  else if (facet.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
2659                                      flags |= DatatypeValidator.FACET_MAXEXCLUSIVE;
2660                                  }
2661                                  else if (facet.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
2662                                      flags |= DatatypeValidator.FACET_MAXINCLUSIVE;
2663                                  }
2664                                  else if (facet.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
2665                                      flags |= DatatypeValidator.FACET_MINEXCLUSIVE;
2666                                  }
2667                                  else if (facet.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
2668                                      flags |= DatatypeValidator.FACET_MININCLUSIVE;
2669                                  }
2670                                  else if (facet.equals(SchemaSymbols.ELT_TOTALDIGITS)) {
2671                                      flags |= DatatypeValidator.FACET_TOTALDIGITS;
2672                                  }
2673                                  else if (facet.equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
2674                                      flags |= DatatypeValidator.FACET_FRACTIONDIGITS;
2675                                  }
2676                                  else if (facet.equals(SchemaSymbols.ELT_WHITESPACE) &&
2677                                           baseValidator instanceof StringDatatypeValidator) {
2678                                      flags |= DatatypeValidator.FACET_WHITESPACE;
2679                                  }
2680                              }
2681                             checkContent(simpleTypeDecl, XUtil.getFirstChildElement( content ), true);
2682                        }
2683                }
2684                    content = XUtil.getNextSiblingElement(content);
2685            }
2686            if (numEnumerationLiterals > 0) {
2687                  fFacetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
2688            }
2689            if (pattern !=null) {
2690                fFacetData.put(SchemaSymbols.ELT_PATTERN, pattern.toString());
2691            }
2692            if (flags != 0) {
2693                fFacetData.put(DatatypeValidator.FACET_FIXED, new Short JavaDoc(flags));
2694            }
2695        }
2696
2697
2698        else if (list && content!=null) {
2699            // report error - must not have any children!
2700
if (baseTypeQNameProperty.length() != 0) {
2701                content = checkContent(simpleTypeDecl, content, true);
2702                if (content!=null) {
2703                    reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2704                                      new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2705            }
2706            }
2707            else {
2708                reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2709                        new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2710                //REVISIT: should we return?
2711
}
2712        }
2713        else if (union && content!=null) {
2714            //report error - must not have any children!
2715
if (baseTypeQNameProperty.length() != 0) {
2716                content = checkContent(simpleTypeDecl, content, true);
2717                if (content!=null) {
2718                    reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2719                                            new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2720                }
2721            }
2722            else {
2723                reportSchemaError(SchemaMessageProvider.ListUnionRestrictionError,
2724                        new Object JavaDoc [] { simpleTypeDecl.getAttribute( SchemaSymbols.ATT_NAME )});
2725                //REVISIT: should we return?
2726
}
2727        }
2728
2729        // ----------------------------------------------------------------------
2730
// create & register validator for "generated" type if it doesn't exist
2731
// ----------------------------------------------------------------------
2732
try {
2733           DatatypeValidator newValidator =
2734                 fDatatypeRegistry.getDatatypeValidator( qualifiedName );
2735
2736           if( newValidator == null ) { // not previously registered
2737
if (list) {
2738                    fDatatypeRegistry.createDatatypeValidator( qualifiedName, baseValidator,
2739                                                               fFacetData,true);
2740               }
2741               else if (restriction) {
2742                   fDatatypeRegistry.createDatatypeValidator( qualifiedName, baseValidator,
2743                                                               fFacetData,false);
2744               }
2745               else { //union
2746
fDatatypeRegistry.createDatatypeValidator( qualifiedName, dTValidators);
2747               }
2748
2749           }
2750
2751           } catch (Exception JavaDoc e) {
2752               reportSchemaError(SchemaMessageProvider.DatatypeError,new Object JavaDoc [] { e.getMessage() });
2753           }
2754        return resetSimpleTypeNameStack(fStringPool.addSymbol(qualifiedName));
2755     }
2756
2757
2758    /*
2759    * <any
2760    * id = ID
2761    * maxOccurs = string
2762    * minOccurs = nonNegativeInteger
2763    * namespace = (##any | ##other) | List of (anyURI | (##targetNamespace | ##local))
2764    * processContents = lax | skip | strict>
2765    * Content: (annotation?)
2766    * </any>
2767    */

2768    private int traverseAny(Element JavaDoc child) throws Exception JavaDoc {
2769        // General Attribute Checking
2770
int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
2771        Hashtable JavaDoc attrValues = generalCheck(child, scope);
2772
2773        Element JavaDoc annotation = checkContent( child, XUtil.getFirstChildElement(child), true );
2774        if(annotation != null ) {
2775            // REVISIT: Localize
2776
reportGenericSchemaError("<any> elements can contain at most one <annotation> element in their children");
2777        }
2778        int anyIndex = -1;
2779        String JavaDoc namespace = child.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
2780        String JavaDoc processContents = child.getAttribute("processContents").trim();
2781
2782        int processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY;
2783        int processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER;
2784        int processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS;
2785
2786        if (processContents.length() > 0 && !processContents.equals("strict")) {
2787            if (processContents.equals("lax")) {
2788                processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_LAX;
2789                processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX;
2790                processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS_LAX;
2791            }
2792            else if (processContents.equals("skip")) {
2793                processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_SKIP;
2794                processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP;
2795                processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS_SKIP;
2796            }
2797        }
2798
2799        if (namespace.length() == 0 || namespace.equals("##any")) {
2800            anyIndex = fSchemaGrammar.addContentSpecNode(processContentsAny, -1, StringPool.EMPTY_STRING, false);
2801        }
2802        else if (namespace.equals("##other")) {
2803            String JavaDoc uri = fTargetNSURIString;
2804            int uriIndex = fStringPool.addSymbol(uri);
2805            anyIndex = fSchemaGrammar.addContentSpecNode(processContentsAnyOther, -1, uriIndex, false);
2806        }
2807        else if (namespace.length() > 0) {
2808            int uriIndex, leafIndex, choiceIndex;
2809
2810            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(namespace);
2811                String JavaDoc token = tokenizer.nextToken();
2812            if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
2813                uriIndex = StringPool.EMPTY_STRING;
2814            } else {
2815                if (token.equals("##targetNamespace"))
2816                    token = fTargetNSURIString;
2817                uriIndex = fStringPool.addSymbol(token);
2818            }
2819            choiceIndex = fSchemaGrammar.addContentSpecNode(processContentsAnyLocal, -1, uriIndex, false);
2820
2821            // store a list of seen uri, so that if there are duplicate
2822
// namespaces, we only add one of them to the content model
2823
int[] uriList = new int[8];
2824            uriList[0] = uriIndex;
2825            int uriCount = 1;
2826
2827            while (tokenizer.hasMoreElements()) {
2828                token = tokenizer.nextToken();
2829                if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
2830                    uriIndex = StringPool.EMPTY_STRING;
2831                } else {
2832                    if (token.equals("##targetNamespace"))
2833                        token = fTargetNSURIString;
2834                    uriIndex = fStringPool.addSymbol(token);
2835                }
2836                // check whether we have seen this namespace, if so, skip
2837
for (int i = 0; i < uriCount; i++) {
2838                    if (uriList[i] == uriIndex)
2839                        continue;
2840                }
2841                // add this namespace to the list
2842
if (uriList.length == uriCount) {
2843                    int[] newList = new int[uriCount*2];
2844                    System.arraycopy(uriList,0,newList,0,uriCount);
2845                    uriList = newList;
2846                }
2847                uriList[uriCount++] = uriIndex;
2848
2849                leafIndex = fSchemaGrammar.addContentSpecNode(processContentsAnyLocal, -1, uriIndex, false);
2850                choiceIndex = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, choiceIndex, leafIndex, false);
2851            }
2852            anyIndex = choiceIndex;
2853        }
2854        else {
2855            // REVISIT: Localize
2856
reportGenericSchemaError("Empty namespace attribute for any element");
2857        }
2858
2859        return anyIndex;
2860    }
2861
2862    public DatatypeValidator getDatatypeValidator(String JavaDoc uri, String JavaDoc localpart) {
2863
2864        DatatypeValidator dv = null;
2865
2866        if (uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
2867            dv = fDatatypeRegistry.getDatatypeValidator( localpart );
2868        }
2869        else {
2870            dv = fDatatypeRegistry.getDatatypeValidator( uri+","+localpart );
2871        }
2872
2873        return dv;
2874    }
2875
2876    /*
2877    * <anyAttribute
2878    * id = ID
2879    * namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace}>
2880    * Content: (annotation?)
2881    * </anyAttribute>
2882    */

2883    private XMLAttributeDecl traverseAnyAttribute(Element JavaDoc anyAttributeDecl) throws Exception JavaDoc {
2884        // General Attribute Checking
2885
int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
2886        Hashtable JavaDoc attrValues = generalCheck(anyAttributeDecl, scope);
2887
2888        Element JavaDoc annotation = checkContent( anyAttributeDecl, XUtil.getFirstChildElement(anyAttributeDecl), true );
2889        if(annotation != null ) {
2890            // REVISIT: Localize
2891
reportGenericSchemaError("<anyAttribute> elements can contain at most one <annotation> element in their children");
2892        }
2893        XMLAttributeDecl anyAttDecl = new XMLAttributeDecl();
2894        String JavaDoc processContents = anyAttributeDecl.getAttribute(SchemaSymbols.ATT_PROCESSCONTENTS).trim();
2895        String JavaDoc namespace = anyAttributeDecl.getAttribute(SchemaSymbols.ATT_NAMESPACE).trim();
2896        // simplify! NG
2897
//String curTargetUri = anyAttributeDecl.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace");
2898
String JavaDoc curTargetUri = fTargetNSURIString;
2899
2900        if ( namespace.length() == 0 || namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY) ) {
2901            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_ANY;
2902        }
2903        else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
2904            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_OTHER;
2905            anyAttDecl.name.uri = fStringPool.addSymbol(curTargetUri);
2906        }
2907        else if (namespace.length() > 0){
2908            anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LIST;
2909
2910            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(namespace);
2911            int aStringList = fStringPool.startStringList();
2912            Vector JavaDoc tokens = new Vector JavaDoc();
2913            int tokenStr;
2914            while (tokenizer.hasMoreElements()) {
2915                String JavaDoc token = tokenizer.nextToken();
2916                if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
2917                    tokenStr = StringPool.EMPTY_STRING;
2918                } else {
2919                    if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS))
2920                    token = curTargetUri;
2921                    tokenStr = fStringPool.addSymbol(token);
2922                }
2923                if (!fStringPool.addStringToList(aStringList, tokenStr)){
2924                    reportGenericSchemaError("Internal StringPool error when reading the "+
2925                                             "namespace attribute for anyattribute declaration");
2926                }
2927            }
2928            fStringPool.finishStringList(aStringList);
2929
2930            anyAttDecl.enumeration = aStringList;
2931        }
2932        else {
2933            // REVISIT: Localize
2934
reportGenericSchemaError("Empty namespace attribute for anyattribute declaration");
2935        }
2936
2937        // default processContents is "strict";
2938
if (processContents.equals(SchemaSymbols.ATTVAL_SKIP)){
2939            anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_SKIP;
2940        }
2941        else if (processContents.equals(SchemaSymbols.ATTVAL_LAX)) {
2942            anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_LAX;
2943        }
2944        else {
2945            anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_STRICT;
2946        }
2947
2948        return anyAttDecl;
2949    }
2950
2951    // Schema Component Constraint: Attribute Wildcard Intersection
2952
// For a wildcard's {namespace constraint} value to be the intensional intersection of two other such values (call them O1 and O2): the appropriate case among the following must be true:
2953
// 1 If O1 and O2 are the same value, then that value must be the value.
2954
// 2 If either O1 or O2 is any, then the other must be the value.
2955
// 3 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or ·absent·), then that set, minus the negated namespace name if it was in the set, must be the value.
2956
// 4 If both O1 and O2 are sets of (namespace names or ·absent·), then the intersection of those sets must be the value.
2957
// 5 If the two are negations of different namespace names, then the intersection is not expressible.
2958
// In the case where there are more than two values, the intensional intersection is determined by identifying the intensional intersection of two of the values as above, then the intensional intersection of that value with the third (providing the first intersection was expressible), and so on as required.
2959
private XMLAttributeDecl AWildCardIntersection(XMLAttributeDecl oneAny, XMLAttributeDecl anotherAny) {
2960        // if either one is not expressible, the result is still not expressible
2961
if (oneAny.type == -1) {
2962            return oneAny;
2963        }
2964        if (anotherAny.type == -1) {
2965            return anotherAny;
2966        }
2967
2968        // 1 If O1 and O2 are the same value, then that value must be the value.
2969
// this one is dealt with in different branches
2970

2971        // 2 If either O1 or O2 is any, then the other must be the value.
2972
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
2973            return anotherAny;
2974        }
2975        if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
2976            return oneAny;
2977        }
2978
2979        // 3 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or ·absent·), then that set, minus the negated namespace name if it was in the set, must be the value.
2980
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
2981            anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST ||
2982            oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST &&
2983            anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
2984            XMLAttributeDecl anyList, anyOther;
2985            if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
2986                anyList = oneAny;
2987                anyOther = anotherAny;
2988            } else {
2989                anyList = anotherAny;
2990                anyOther = oneAny;
2991                }
2992
2993            int[] uriList = fStringPool.stringListAsIntArray(anyList.enumeration);
2994            if (elementInSet(anyOther.name.uri, uriList)) {
2995                    int newList = fStringPool.startStringList();
2996                for (int i=0; i< uriList.length; i++) {
2997                    if (uriList[i] != anyOther.name.uri ) {
2998                        fStringPool.addStringToList(newList, uriList[i]);
2999                        }
3000                    }
3001                    fStringPool.finishStringList(newList);
3002                anyList.enumeration = newList;
3003                }
3004
3005            return anyList;
3006        }
3007
3008        // 4 If both O1 and O2 are sets of (namespace names or ·absent·), then the intersection of those sets must be the value.
3009
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST &&
3010            anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
3011            int[] result = intersect2sets(fStringPool.stringListAsIntArray(oneAny.enumeration),
3012                                          fStringPool.stringListAsIntArray(anotherAny.enumeration));
3013            int newList = fStringPool.startStringList();
3014            for (int i=0; i<result.length; i++) {
3015                fStringPool.addStringToList(newList, result[i]);
3016            }
3017            fStringPool.finishStringList(newList);
3018            oneAny.enumeration = newList;
3019                return oneAny;
3020            }
3021
3022        // 5 If the two are negations of different namespace names, then the intersection is not expressible.
3023
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
3024            anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
3025            if (oneAny.name.uri == anotherAny.name.uri) {
3026                return oneAny;
3027            } else {
3028                oneAny.type = -1;
3029                return oneAny;
3030            }
3031        }
3032
3033        // should never go there;
3034
return oneAny;
3035                }
3036
3037    // Schema Component Constraint: Attribute Wildcard Union
3038
// For a wildcard's {namespace constraint} value to be the intensional union of two other such values (call them O1 and O2): the appropriate case among the following must be true:
3039
// 1 If O1 and O2 are the same value, then that value must be the value.
3040
// 2 If either O1 or O2 is any, then any must be the value.
3041
// 3 If both O1 and O2 are sets of (namespace names or ·absent·), then the union of those sets must be the value.
3042
// 4 If the two are negations of different namespace names, then any must be the value.
3043
// 5 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or ·absent·), then The appropriate case among the following must be true:
3044
// 5.1 If the set includes the negated namespace name, then any must be the value.
3045
// 5.2 If the set does not include the negated namespace name, then whichever of O1 or O2 is a pair of not and a namespace name must be the value.
3046
// In the case where there are more than two values, the intensional union is determined by identifying the intensional union of two of the values as above, then the intensional union of that value with the third, and so on as required.
3047
private XMLAttributeDecl AWildCardUnion(XMLAttributeDecl oneAny, XMLAttributeDecl anotherAny) {
3048        // if either one is not expressible, the result is still not expressible
3049
if (oneAny.type == -1) {
3050                    return oneAny;
3051                }
3052        if (anotherAny.type == -1) {
3053            return anotherAny;
3054            }
3055
3056        // 1 If O1 and O2 are the same value, then that value must be the value.
3057
// this one is dealt with in different branches
3058

3059        // 2 If either O1 or O2 is any, then any must be the value.
3060
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
3061                return oneAny;
3062            }
3063        if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
3064            return anotherAny;
3065        }
3066
3067        // 3 If both O1 and O2 are sets of (namespace names or ·absent·), then the union of those sets must be the value.
3068
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST &&
3069            anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
3070            int[] result = union2sets(fStringPool.stringListAsIntArray(oneAny.enumeration),
3071                                               fStringPool.stringListAsIntArray(anotherAny.enumeration));
3072                int newList = fStringPool.startStringList();
3073                for (int i=0; i<result.length; i++) {
3074                    fStringPool.addStringToList(newList, result[i]);
3075                }
3076                fStringPool.finishStringList(newList);
3077                oneAny.enumeration = newList;
3078                return oneAny;
3079            }
3080
3081        // 4 If the two are negations of different namespace names, then any must be the value.
3082
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
3083            anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
3084            if (oneAny.name.uri == anotherAny.name.uri) {
3085                return oneAny;
3086            } else {
3087                oneAny.type = XMLAttributeDecl.TYPE_ANY_ANY;
3088                return oneAny;
3089            }
3090        }
3091
3092        // 5 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or ·absent·), then The appropriate case among the following must be true:
3093
if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
3094            anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST ||
3095            oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST &&
3096            anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
3097            XMLAttributeDecl anyList, anyOther;
3098            if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
3099                anyList = oneAny;
3100                anyOther = anotherAny;
3101            } else {
3102                anyList = anotherAny;
3103                anyOther = oneAny;
3104        }
3105            // 5.1 If the set includes the negated namespace name, then any must be the value.
3106
if (elementInSet(anyOther.name.uri,
3107                             fStringPool.stringListAsIntArray(anyList.enumeration))) {
3108                anyOther.type = XMLAttributeDecl.TYPE_ANY_ANY;
3109            }
3110            // 5.2 If the set does not include the negated namespace name, then whichever of O1 or O2 is a pair of not and a namespace name must be the value.
3111

3112            return anyOther;
3113        }
3114
3115        // should never go there;
3116
return oneAny;
3117    }
3118
3119    // Schema Component Constraint: Wildcard Subset
3120
// For a namespace constraint (call it sub) to be an intensional subset of another namespace constraint (call it super) one of the following must be true:
3121
// 1 super must be any.
3122
// 2 All of the following must be true:
3123
// 2.1 sub must be a pair of not and a namespace name or ·absent·.
3124
// 2.2 super must be a pair of not and the same value.
3125
// 3 All of the following must be true:
3126
// 3.1 sub must be a set whose members are either namespace names or ·absent·.
3127
// 3.2 One of the following must be true:
3128
// 3.2.1 super must be the same set or a superset thereof.
3129
// 3.2.2 super must be a pair of not and a namespace name or ·absent· and that value must not be in sub's set.
3130
private boolean AWildCardSubset(XMLAttributeDecl subAny, XMLAttributeDecl superAny) {
3131        // if either one is not expressible, it can't be a subset
3132
if (subAny.type == -1 || superAny.type == -1)
3133            return false;
3134
3135        // 1 super must be any.
3136
if (superAny.type == XMLAttributeDecl.TYPE_ANY_ANY)
3137            return true;
3138
3139        // 2 All of the following must be true:
3140
// 2.1 sub must be a pair of not and a namespace name or ·absent·.
3141
if (subAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
3142            // 2.2 super must be a pair of not and the same value.
3143
if (superAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
3144                subAny.name.uri == superAny.name.uri) {
3145                return true;
3146            }
3147        }
3148
3149        // 3 All of the following must be true:
3150
// 3.1 sub must be a set whose members are either namespace names or ·absent·.
3151
if (subAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
3152        // 3.2 One of the following must be true:
3153
// 3.2.1 super must be the same set or a superset thereof.
3154
if (superAny.type == XMLAttributeDecl.TYPE_ANY_LIST &&
3155                subset2sets(fStringPool.stringListAsIntArray(subAny.enumeration),
3156                            fStringPool.stringListAsIntArray(superAny.enumeration))) {
3157                return true;
3158            }
3159
3160            // 3.2.2 super must be a pair of not and a namespace name or ·absent· and that value must not be in sub's set.
3161
if (superAny.type == XMLAttributeDecl.TYPE_ANY_OTHER &&
3162                !elementInSet(superAny.name.uri, fStringPool.stringListAsIntArray(superAny.enumeration))) {
3163                return true;
3164            }
3165        }
3166
3167        return false;
3168    }
3169
3170    // Validation Rule: Wildcard allows Namespace Name
3171
// For a value which is either a namespace name or ·absent· to be ·valid· with respect to a wildcard constraint (the value of a {namespace constraint}) one of the following must be true:
3172
// 1 The constraint must be any.
3173
// 2 All of the following must be true:
3174
// 2.1 The constraint is a pair of not and a namespace name or ·absent· ([Definition:] call this the namespace test).
3175
// 2.2 The value must not be identical to the ·namespace test·.
3176
// 2.3 The value must not be ·absent·.
3177
// 3 The constraint is a set, and the value is identical to one of the members of the set.
3178
private boolean AWildCardAllowsNameSpace(XMLAttributeDecl wildcard, String JavaDoc uri) {
3179        // if the constrain is not expressible, then nothing is allowed
3180
if (wildcard.type == -1)
3181            return false;
3182
3183        // 1 The constraint must be any.
3184
if (wildcard.type == XMLAttributeDecl.TYPE_ANY_ANY)
3185            return true;
3186
3187        int uriStr = fStringPool.addString(uri);
3188
3189        // 2 All of the following must be true:
3190
// 2.1 The constraint is a pair of not and a namespace name or ·absent· ([Definition:] call this the namespace test).
3191
if (wildcard.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
3192            // 2.2 The value must not be identical to the ·namespace test·.
3193
// 2.3 The value must not be ·absent·.
3194
if (uriStr != wildcard.name.uri && uriStr != StringPool.EMPTY_STRING)
3195                return true;
3196        }
3197
3198        // 3 The constraint is a set, and the value is identical to one of the members of the set.
3199
if (wildcard.type == XMLAttributeDecl.TYPE_ANY_LIST) {
3200            if (elementInSet(uriStr, fStringPool.stringListAsIntArray(wildcard.enumeration)))
3201                return true;
3202        }
3203
3204        return false;
3205    }
3206
3207    private boolean isAWildCard(XMLAttributeDecl a) {
3208        if (a.type == XMLAttributeDecl.TYPE_ANY_ANY
3209            ||a.type == XMLAttributeDecl.TYPE_ANY_LIST
3210            ||a.type == XMLAttributeDecl.TYPE_ANY_OTHER )
3211            return true;
3212        else
3213            return false;
3214    }
3215
3216    int[] intersect2sets(int[] one, int[] theOther){
3217        int[] result = new int[(one.length>theOther.length?one.length:theOther.length)];
3218
3219        // simple implemention,
3220
int count = 0;
3221        for (int i=0; i<one.length; i++) {
3222            if (elementInSet(one[i], theOther))
3223                    result[count++] = one[i];
3224                }
3225
3226        int[] result2 = new int[count];
3227        System.arraycopy(result, 0, result2, 0, count);
3228
3229        return result2;
3230    }
3231
3232    int[] union2sets(int[] one, int[] theOther){
3233        int[] result1 = new int[one.length];
3234
3235        // simple implemention,
3236
int count = 0;
3237        for (int i=0; i<one.length; i++) {
3238            if (!elementInSet(one[i], theOther))
3239                result1[count++] = one[i];
3240        }
3241
3242        int[] result2 = new int[count+theOther.length];
3243        System.arraycopy(result1, 0, result2, 0, count);
3244        System.arraycopy(theOther, 0, result2, count, theOther.length);
3245
3246        return result2;
3247    }
3248
3249    boolean subset2sets(int[] subSet, int[] superSet){
3250        for (int i=0; i<subSet.length; i++) {
3251            if (!elementInSet(subSet[i], superSet))
3252                return false;
3253        }
3254
3255        return true;
3256    }
3257
3258    boolean elementInSet(int ele, int[] set){
3259        boolean found = false;
3260        for (int i=0; i<set.length && !found; i++) {
3261            if (ele==set[i])
3262                found = true;
3263        }
3264
3265        return found;
3266    }
3267
3268    // wrapper traverseComplexTypeDecl method
3269
private int traverseComplexTypeDecl( Element JavaDoc complexTypeDecl ) throws Exception JavaDoc {
3270        return traverseComplexTypeDecl (complexTypeDecl, false);
3271    }
3272
3273    /**
3274     * Traverse ComplexType Declaration - Rec Implementation.
3275     *
3276     * <complexType
3277     * abstract = boolean
3278     * block = #all or (possibly empty) subset of {extension, restriction}
3279     * final = #all or (possibly empty) subset of {extension, restriction}
3280     * id = ID
3281     * mixed = boolean : false
3282     * name = NCName>
3283     * Content: (annotation? , (simpleContent | complexContent |
3284     * ( (group | all | choice | sequence)? ,
3285     * ( (attribute | attributeGroup)* , anyAttribute?))))
3286     * </complexType>
3287     * @param complexTypeDecl
3288     * @param forwardRef
3289     * @return
3290     */

3291
3292    private int traverseComplexTypeDecl( Element JavaDoc complexTypeDecl, boolean forwardRef)
3293            throws Exception JavaDoc {
3294
3295        // General Attribute Checking
3296
int scope = isTopLevel(complexTypeDecl)?
3297                    GeneralAttrCheck.ELE_CONTEXT_GLOBAL:
3298                    GeneralAttrCheck.ELE_CONTEXT_LOCAL;
3299        Hashtable JavaDoc attrValues = generalCheck(complexTypeDecl, scope);
3300
3301        // ------------------------------------------------------------------
3302
// Get the attributes of the type
3303
// ------------------------------------------------------------------
3304
String JavaDoc isAbstract = complexTypeDecl.getAttribute( SchemaSymbols.ATT_ABSTRACT );
3305        String JavaDoc blockSet = null;
3306        Attr JavaDoc blockAttr = complexTypeDecl.getAttributeNode( SchemaSymbols.ATT_BLOCK );
3307        if (blockAttr != null)
3308            blockSet = blockAttr.getValue();
3309        String JavaDoc finalSet = null;
3310        Attr JavaDoc finalAttr = complexTypeDecl.getAttributeNode( SchemaSymbols.ATT_FINAL );
3311        if (finalAttr != null)
3312            finalSet = finalAttr.getValue();
3313        String JavaDoc typeId = complexTypeDecl.getAttribute( SchemaSymbols.ATTVAL_ID );
3314        String JavaDoc typeName = complexTypeDecl.getAttribute(SchemaSymbols.ATT_NAME);
3315        String JavaDoc mixed = complexTypeDecl.getAttribute(SchemaSymbols.ATT_MIXED);
3316        boolean isMixed = mixed.equals(SchemaSymbols.ATTVAL_TRUE) || mixed.equals(SchemaSymbols.ATTVAL_TRUE_1);
3317        boolean isNamedType = false;
3318        Stack JavaDoc savedGroupNameStack = null;
3319
3320        // ------------------------------------------------------------------
3321
// Generate a type name, if one wasn't specified
3322
// ------------------------------------------------------------------
3323
if (typeName.length() == 0) { // gensym a unique name
3324
typeName = genAnonTypeName(complexTypeDecl);
3325        }
3326
3327        if ( DEBUGGING )
3328            System.out.println("traversing complex Type : " + typeName);
3329
3330        int typeNameIndex = fStringPool.addSymbol(typeName);
3331
3332
3333        // ------------------------------------------------------------------
3334
// Check if the type has already been registered
3335
// ------------------------------------------------------------------
3336
if (isTopLevel(complexTypeDecl)) {
3337
3338            String JavaDoc fullName = fTargetNSURIString+","+typeName;
3339            ComplexTypeInfo temp = (ComplexTypeInfo) fComplexTypeRegistry.get(fullName);
3340            if (temp != null ) {
3341                // check for duplicate declarations
3342
if (!forwardRef) {
3343                   if (temp.declSeen())
3344                      reportGenericSchemaError("sch-props-correct: Duplicate declaration for complexType " +
3345                                                typeName);
3346                   else
3347                      temp.setDeclSeen();
3348
3349                }
3350                return fStringPool.addSymbol(fullName);
3351            }
3352            else {
3353              // check if the type is the name of a simple type
3354
if (getDatatypeValidator(fTargetNSURIString,typeName)!=null)
3355                reportGenericSchemaError("sch-props-correct: Duplicate type declaration - type is " +
3356                                                typeName);
3357
3358            }
3359        }
3360
3361        fCurrentTypeNameStack.push(typeName);
3362
3363        int scopeDefined = fScopeCount++;
3364        int previousScope = fCurrentScope;
3365        fCurrentScope = scopeDefined;
3366
3367        // Squirrel away the groupNameStack.
3368
// If we are in the middle of processing a group, and we hit the group again
3369
// because of a complexType for an element, it's not an error.
3370
if (!fCurrentGroupNameStack.isEmpty()) {
3371          savedGroupNameStack = fCurrentGroupNameStack;
3372          fCurrentGroupNameStack = new Stack JavaDoc();
3373        }
3374
3375        Element JavaDoc child = null;
3376        ComplexTypeInfo typeInfo = new ComplexTypeInfo();
3377        typeInfo.scopeDefined = scopeDefined;
3378
3379        try {
3380
3381          // ------------------------------------------------------------------
3382
// First, handle any ANNOTATION declaration and get next child
3383
// ------------------------------------------------------------------
3384
child = checkContent(complexTypeDecl,XUtil.getFirstChildElement(complexTypeDecl),
3385                               true);
3386
3387          // ------------------------------------------------------------------
3388
// Process the content of the complex type declaration
3389
// ------------------------------------------------------------------
3390
if (child==null) {
3391              //
3392
// EMPTY complexType with complexContent
3393
//
3394
processComplexContent(typeNameIndex, child, typeInfo, null, isMixed);
3395          }
3396          else {
3397              String JavaDoc childName = child.getLocalName();
3398              int index = -2;
3399
3400              if (childName.equals(SchemaSymbols.ELT_SIMPLECONTENT)) {
3401                  //
3402
// SIMPLE CONTENT element
3403
//
3404
traverseSimpleContentDecl(typeNameIndex, child, typeInfo);
3405                  if (XUtil.getNextSiblingElement(child) != null)
3406                     throw new ComplexTypeRecoverableError(
3407                      "Invalid child following the simpleContent child in the complexType");
3408              }
3409              else if (childName.equals(SchemaSymbols.ELT_COMPLEXCONTENT)) {
3410                  //
3411
// COMPLEX CONTENT element
3412
//
3413
traverseComplexContentDecl(typeNameIndex, child, typeInfo, isMixed);
3414                  if (XUtil.getNextSiblingElement(child) != null)
3415                     throw new ComplexTypeRecoverableError(
3416                      "Invalid child following the complexContent child in the complexType");
3417              }
3418              else {
3419                  //
3420
// We must have ....
3421
// GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
3422
// Note that it's possible that only attributes are specified.
3423
//
3424
processComplexContent(typeNameIndex, child, typeInfo, null, isMixed);
3425
3426              }
3427          }
3428          typeInfo.blockSet = parseBlockSet(blockSet);
3429          // make sure block's value was absent, #all or in {extension, restriction}
3430
if( (blockSet != null ) && blockSet.length() != 0 &&
3431                (!blockSet.equals(SchemaSymbols.ATTVAL_POUNDALL) &&
3432                (((typeInfo.blockSet & SchemaSymbols.RESTRICTION) == 0) &&
3433                ((typeInfo.blockSet & SchemaSymbols.EXTENSION) == 0))))
3434            throw new ComplexTypeRecoverableError("The values of the 'block' attribute of a complexType must be either #all or a list of 'restriction' and 'extension'; " + blockSet + " was found");
3435
3436          typeInfo.finalSet = parseFinalSet(finalSet);
3437          // make sure final's value was absent, #all or in {extension, restriction}
3438
if( (finalSet != null ) && finalSet.length() != 0 &&
3439                (!finalSet.equals(SchemaSymbols.ATTVAL_POUNDALL) &&
3440                (((typeInfo.finalSet & SchemaSymbols.RESTRICTION) == 0) &&
3441                ((typeInfo.finalSet & SchemaSymbols.EXTENSION) == 0))))
3442            throw new ComplexTypeRecoverableError("The values of the 'final' attribute of a complexType must be either #all or a list of 'restriction' and 'extension'; " + finalSet + " was found");
3443
3444        }
3445        catch (ComplexTypeRecoverableError e) {
3446           String JavaDoc message = e.getMessage();
3447           handleComplexTypeError(message,typeNameIndex,typeInfo);
3448        }
3449
3450
3451        // ------------------------------------------------------------------
3452
// Finish the setup of the typeInfo and register the type
3453
// ------------------------------------------------------------------
3454
if (isAbstract.equals(SchemaSymbols.ATTVAL_TRUE) ||
3455            isAbstract.equals(SchemaSymbols.ATTVAL_TRUE_1))
3456          typeInfo.setIsAbstractType();
3457        if (!forwardRef)
3458          typeInfo.setDeclSeen();
3459        typeName = fTargetNSURIString + "," + typeName;
3460        typeInfo.typeName = new String JavaDoc(typeName);
3461
3462        if ( DEBUGGING )
3463            System.out.println(">>>add complex Type to Registry: " + typeName +
3464                               " baseDTValidator=" + typeInfo.baseDataTypeValidator +
3465                               " baseCTInfo=" + typeInfo.baseComplexTypeInfo +
3466                               " derivedBy=" + typeInfo.derivedBy +
3467                             " contentType=" + typeInfo.contentType +
3468                               " contentSpecHandle=" + typeInfo.contentSpecHandle +
3469                               " datatypeValidator=" + typeInfo.datatypeValidator +
3470                               " scopeDefined=" + typeInfo.scopeDefined);
3471
3472        fComplexTypeRegistry.put(typeName,typeInfo);
3473
3474        // ------------------------------------------------------------------
3475
// Before exiting, restore the scope, mainly for nested anonymous types
3476
// ------------------------------------------------------------------
3477
fCurrentScope = previousScope;
3478        if (savedGroupNameStack != null)
3479          fCurrentGroupNameStack = savedGroupNameStack;
3480        fCurrentTypeNameStack.pop();
3481        checkRecursingComplexType();
3482
3483        //set template element's typeInfo
3484
fSchemaGrammar.setElementComplexTypeInfo(typeInfo.templateElementIndex, typeInfo);
3485
3486        typeNameIndex = fStringPool.addSymbol(typeName);
3487        return typeNameIndex;
3488
3489    } // end traverseComplexTypeDecl
3490

3491
3492    /**
3493     * Traverse SimpleContent Declaration
3494     *
3495     * <simpleContent
3496     * id = ID
3497     * {any attributes with non-schema namespace...}>
3498     *
3499     * Content: (annotation? , (restriction | extension))
3500     * </simpleContent>
3501     *
3502     * <restriction
3503     * base = QNAME
3504     * id = ID
3505     * {any attributes with non-schema namespace...}>
3506     *
3507     * Content: (annotation?,(simpleType?, (minExclusive|minInclusive|maxExclusive
3508     * | maxInclusive | totalDigits | fractionDigits | length | minLength
3509     * | maxLength | encoding | period | duration | enumeration
3510     * | pattern | whiteSpace)*) ? ,
3511     * ((attribute | attributeGroup)* , anyAttribute?))
3512     * </restriction>
3513     *
3514     * <extension
3515     * base = QNAME
3516     * id = ID
3517     * {any attributes with non-schema namespace...}>
3518     * Content: (annotation? , ((attribute | attributeGroup)* , anyAttribute?))
3519     * </extension>
3520     *
3521     * @param typeNameIndex
3522     * @param simpleContentTypeDecl
3523     * @param typeInfo
3524     * @return
3525     */

3526
3527    private void traverseSimpleContentDecl(int typeNameIndex,
3528               Element JavaDoc simpleContentDecl, ComplexTypeInfo typeInfo)
3529               throws Exception JavaDoc {
3530
3531
3532        // General Attribute Checking
3533
int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
3534        Hashtable JavaDoc attrValues = generalCheck(simpleContentDecl, scope);
3535
3536        String JavaDoc typeName = fStringPool.toString(typeNameIndex);
3537
3538        // -----------------------------------------------------------------------
3539
// Get attributes.
3540
// -----------------------------------------------------------------------
3541
String JavaDoc simpleContentTypeId = simpleContentDecl.getAttribute(SchemaSymbols.ATTVAL_ID);
3542
3543        // -----------------------------------------------------------------------
3544
// Set the content type to be simple, and initialize content spec handle
3545
// -----------------------------------------------------------------------
3546
typeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
3547        typeInfo.contentSpecHandle = -1;
3548
3549        Element JavaDoc simpleContent = checkContent(simpleContentDecl,
3550                                     XUtil.getFirstChildElement(simpleContentDecl),false);
3551
3552        // If there are no children, return
3553
if (simpleContent==null) {
3554          throw new ComplexTypeRecoverableError();
3555        }
3556
3557        // General Attribute Checking
3558
attrValues = generalCheck(simpleContent, scope);
3559
3560        // -----------------------------------------------------------------------
3561
// The content should be either "restriction" or "extension"
3562
// -----------------------------------------------------------------------
3563
String JavaDoc simpleContentName = simpleContent.getLocalName();
3564        if (simpleContentName.equals(SchemaSymbols.ELT_RESTRICTION))
3565          typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
3566        else if (simpleContentName.equals(SchemaSymbols.ELT_EXTENSION))
3567          typeInfo.derivedBy = SchemaSymbols.EXTENSION;
3568        else {
3569
3570          throw new ComplexTypeRecoverableError(
3571                     "The content of the simpleContent element is invalid. The " +
3572                     "content must be RESTRICTION or EXTENSION");
3573        }
3574
3575        // -----------------------------------------------------------------------
3576
// Get the attributes of the restriction/extension element
3577
// -----------------------------------------------------------------------
3578
String JavaDoc base = simpleContent.getAttribute(SchemaSymbols.ATT_BASE);
3579        String JavaDoc typeId = simpleContent.getAttribute(SchemaSymbols.ATTVAL_ID);
3580
3581
3582        // -----------------------------------------------------------------------
3583
// Skip over any annotations in the restriction or extension elements
3584
// -----------------------------------------------------------------------
3585
Element JavaDoc content = checkContent(simpleContent,
3586                              XUtil.getFirstChildElement(simpleContent),true);
3587
3588        // -----------------------------------------------------------------------
3589
// Handle the base type name
3590
// -----------------------------------------------------------------------
3591
if (base.length() == 0) {
3592          throw new ComplexTypeRecoverableError(
3593                  "The BASE attribute must be specified for the " +
3594                  "RESTRICTION or EXTENSION element");
3595        }
3596
3597        QName baseQName = parseBase(base);
3598        // check if we're extending a simpleType which has a "final" setting which precludes this
3599
Integer JavaDoc finalValue =
3600                ((Integer JavaDoc)fSimpleTypeFinalRegistry.get(fStringPool.toString(baseQName.uri) + "," +fStringPool.toString(baseQName.localpart)));
3601        if(finalValue != null &&
3602                (finalValue.intValue() == typeInfo.derivedBy))
3603            throw new ComplexTypeRecoverableError(
3604                  "The simpleType " + base + " that " + typeName + " uses has a value of \"final\" which does not permit extension");
3605
3606        String JavaDoc baseTypeURI = fStringPool.toString(baseQName.uri);
3607        String JavaDoc baseLocalName = fStringPool.toString(baseQName.localpart);
3608        if (baseTypeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
3609            baseLocalName.equals("anyType")) {
3610             throw new ComplexTypeRecoverableError(
3611             "The type '"+ base +"' specified as the " +
3612             "base in the simpleContent element must be a complex type with simple content");
3613        }
3614
3615        processBaseTypeInfo(baseQName,typeInfo);
3616
3617        // check that the base isn't a complex type with simple content
3618
if (typeInfo.baseComplexTypeInfo != null) {
3619             if (typeInfo.baseComplexTypeInfo.contentType != XMLElementDecl.TYPE_SIMPLE) {
3620                 throw new ComplexTypeRecoverableError(
3621                 "The type '"+ base +"' specified as the " +
3622                 "base in the simpleContent element must not have complexContent");
3623             }
3624        }
3625
3626        // -----------------------------------------------------------------------
3627
// Process the content of the derivation
3628
// -----------------------------------------------------------------------
3629
Element JavaDoc attrNode = null;
3630        //
3631
// RESTRICTION
3632
//
3633
if (typeInfo.derivedBy==SchemaSymbols.RESTRICTION) {
3634            //
3635
//Schema Spec : Complex Type Definition Properties Correct : 2
3636
//
3637
if (typeInfo.baseDataTypeValidator != null) {
3638                throw new ComplexTypeRecoverableError(
3639                 "ct-props-correct.2: The type '" + base +"' is a simple type. It cannot be used in a "+
3640                 "derivation by RESTRICTION for a complexType");
3641            }
3642            else {
3643                typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
3644            }
3645
3646            //
3647
// Check that the base's final set does not include RESTRICTION
3648
//
3649
if((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.RESTRICTION) != 0) {
3650               throw new ComplexTypeRecoverableError("Derivation by restriction is forbidden by either the base type " + base + " or the schema");
3651            }
3652
3653
3654            // -----------------------------------------------------------------------
3655
// There may be a simple type definition in the restriction element
3656
// The data type validator will be based on it, if specified
3657
// -----------------------------------------------------------------------
3658
if (content != null &&
3659                content.getLocalName().equals(SchemaSymbols.ELT_SIMPLETYPE )) {
3660                int simpleTypeNameIndex = traverseSimpleTypeDecl(content);
3661                if (simpleTypeNameIndex!=-1) {
3662                    DatatypeValidator dv=fDatatypeRegistry.getDatatypeValidator(
3663                       fStringPool.toString(simpleTypeNameIndex));
3664
3665                  //check that this datatype validator is validly derived from the base
3666
//according to derivation-ok-restriction 5.1.1
3667
if (!checkSimpleTypeDerivationOK(dv,typeInfo.baseDataTypeValidator)) {
3668                    throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.1.1: The content type is not a valid restriction of the content type of the base");
3669                  }
3670                  typeInfo.baseDataTypeValidator = dv;
3671                  content = XUtil.getNextSiblingElement(content);
3672                }
3673                else {
3674                  throw new ComplexTypeRecoverableError();
3675                }
3676            }
3677
3678
3679            //
3680
// Build up facet information
3681
//
3682
int numEnumerationLiterals = 0;
3683            int numFacets = 0;
3684            Hashtable JavaDoc facetData = new Hashtable JavaDoc();
3685            Vector JavaDoc enumData = new Vector JavaDoc();
3686            Element JavaDoc child;
3687
3688             // General Attribute Checking
3689
scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
3690            Hashtable JavaDoc contentAttrs;
3691
3692            //REVISIT: there is a better way to do this,
3693
for (child = content;
3694                 child != null && (child.getLocalName().equals(SchemaSymbols.ELT_MINEXCLUSIVE) ||
3695                           child.getLocalName().equals(SchemaSymbols.ELT_MININCLUSIVE) ||
3696                           child.getLocalName().equals(SchemaSymbols.ELT_MAXEXCLUSIVE) ||
3697                           child.getLocalName().equals(SchemaSymbols.ELT_MAXINCLUSIVE) ||
3698                           child.getLocalName().equals(SchemaSymbols.ELT_TOTALDIGITS) ||
3699                           child.getLocalName().equals(SchemaSymbols.ELT_FRACTIONDIGITS) ||
3700                           child.getLocalName().equals(SchemaSymbols.ELT_LENGTH) ||
3701                           child.getLocalName().equals(SchemaSymbols.ELT_MINLENGTH) ||
3702                           child.getLocalName().equals(SchemaSymbols.ELT_MAXLENGTH) ||
3703                           child.getLocalName().equals(SchemaSymbols.ELT_ENUMERATION) ||
3704                           child.getLocalName().equals(SchemaSymbols.ELT_PATTERN) ||
3705                           child.getLocalName().equals(SchemaSymbols.ELT_WHITESPACE) ||
3706                           child.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION));
3707                 child = XUtil.getNextSiblingElement(child))
3708            {
3709                if ( child.getNodeType() == Node.ELEMENT_NODE ) {
3710                    Element JavaDoc facetElt = (Element JavaDoc) child;
3711                    // General Attribute Checking
3712
contentAttrs = generalCheck(facetElt, scope);
3713                    numFacets++;
3714                    if (facetElt.getLocalName().equals(SchemaSymbols.ELT_ENUMERATION)) {
3715                        numEnumerationLiterals++;
3716                        enumData.addElement(facetElt.getAttribute(SchemaSymbols.ATT_VALUE));
3717                        //Enumerations can have annotations ? ( 0 | 1 )
3718
Element JavaDoc enumContent = XUtil.getFirstChildElement( facetElt );
3719                        if( enumContent != null &&
3720                            enumContent.getLocalName().equals
3721                                  ( SchemaSymbols.ELT_ANNOTATION )){
3722                            traverseAnnotationDecl( child );
3723                        }
3724                        // TO DO: if Jeff check in new changes to TraverseSimpleType, copy them over
3725
}
3726                    else {
3727                        facetData.put(facetElt.getLocalName(),
3728                              facetElt.getAttribute( SchemaSymbols.ATT_VALUE ));
3729                    }
3730                }
3731            } // end of for loop thru facets
3732

3733            if (numEnumerationLiterals > 0) {
3734                facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
3735            }
3736
3737            //
3738
// If there were facets, create a new data type validator, otherwise
3739
// the data type validator is from the base
3740
//
3741
if (numFacets > 0) {
3742              try{
3743                typeInfo.datatypeValidator = fDatatypeRegistry.createDatatypeValidator(
3744                                      typeName,
3745                                      typeInfo.baseDataTypeValidator, facetData, false);
3746              } catch (Exception JavaDoc e) {
3747                throw new ComplexTypeRecoverableError(e.getMessage());
3748              }
3749
3750            }
3751            else
3752                typeInfo.datatypeValidator =
3753                             typeInfo.baseDataTypeValidator;
3754
3755            if (child != null) {
3756               //
3757
// Check that we have attributes
3758
//
3759
if (!isAttrOrAttrGroup(child)) {
3760                  throw new ComplexTypeRecoverableError(
3761                     "Invalid child in the RESTRICTION element of simpleContent");
3762               }
3763               else
3764                  attrNode = child;
3765            }
3766
3767        } // end RESTRICTION
3768

3769        //
3770
// EXTENSION
3771
//
3772
else {
3773            if (typeInfo.baseComplexTypeInfo != null) {
3774               typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
3775              //
3776
// Check that the base's final set does not include EXTENSION
3777
//
3778
if((typeInfo.baseComplexTypeInfo.finalSet &
3779                   SchemaSymbols.EXTENSION) != 0) {
3780                 throw new ComplexTypeRecoverableError("Derivation by extension is forbidden by either the base type " + base + " or the schema");
3781              }
3782            }
3783
3784            typeInfo.datatypeValidator = typeInfo.baseDataTypeValidator;
3785
3786            //
3787
// Look for attributes
3788
//
3789
if (content != null) {
3790               //
3791
// Check that we have attributes
3792
//
3793
if (!isAttrOrAttrGroup(content)) {
3794                   throw new ComplexTypeRecoverableError(
3795                             "Only annotations and attributes are allowed in the " +
3796                             "content of an EXTENSION element for a complexType with simpleContent");
3797               }
3798               else {
3799                   attrNode = content;
3800               }
3801            }
3802
3803        }
3804
3805        // -----------------------------------------------------------------------
3806
// add a template element to the grammar element decl pool for the type
3807
// -----------------------------------------------------------------------
3808
int templateElementNameIndex = fStringPool.addSymbol("$"+typeName);
3809
3810        typeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
3811             new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
3812             (fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : fCurrentScope, typeInfo.scopeDefined,
3813             typeInfo.contentType,
3814             typeInfo.contentSpecHandle, -1, typeInfo.datatypeValidator);
3815        typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(
3816                                typeInfo.templateElementIndex);
3817
3818        // -----------------------------------------------------------------------
3819
// Process attributes
3820
// -----------------------------------------------------------------------
3821
processAttributes(attrNode,baseQName,typeInfo);
3822
3823        if (XUtil.getNextSiblingElement(simpleContent) != null)
3824            throw new ComplexTypeRecoverableError(
3825               "Invalid child following the RESTRICTION or EXTENSION element in the " +
3826               "complex type definition");
3827
3828    } // end traverseSimpleContentDecl
3829

3830    /**
3831     * Traverse complexContent Declaration
3832     *
3833     * <complexContent
3834     * id = ID
3835     * mixed = boolean
3836     * {any attributes with non-schema namespace...}>
3837     *
3838     * Content: (annotation? , (restriction | extension))
3839     * </complexContent>
3840     *
3841     * <restriction
3842     * base = QNAME
3843     * id = ID
3844     * {any attributes with non-schema namespace...}>
3845     *
3846     * Content: (annotation? , (group | all | choice | sequence)?,
3847     * ((attribute | attributeGroup)* , anyAttribute?))
3848     * </restriction>
3849     *
3850     * <extension
3851     * base = QNAME
3852     * id = ID
3853     * {any attributes with non-schema namespace...}>
3854     * Content: (annotation? , (group | all | choice | sequence)?,
3855     * ((attribute | attributeGroup)* , anyAttribute?))
3856     * </extension>
3857     *
3858     * @param typeNameIndex
3859     * @param simpleContentTypeDecl
3860     * @param typeInfo
3861     * @param mixedOnComplexTypeDecl
3862     * @return
3863     */

3864
3865    private void traverseComplexContentDecl(int typeNameIndex,
3866               Element JavaDoc complexContentDecl, ComplexTypeInfo typeInfo,
3867               boolean mixedOnComplexTypeDecl) throws Exception JavaDoc {
3868
3869         // General Attribute Checking
3870
int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
3871        Hashtable JavaDoc attrValues = generalCheck(complexContentDecl, scope);
3872
3873        String JavaDoc typeName = fStringPool.toString(typeNameIndex);
3874
3875        // -----------------------------------------------------------------------
3876
// Get the attributes
3877
// -----------------------------------------------------------------------
3878
String JavaDoc typeId = complexContentDecl.getAttribute(SchemaSymbols.ATTVAL_ID);
3879        String JavaDoc mixed = complexContentDecl.getAttribute(SchemaSymbols.ATT_MIXED);
3880
3881        // -----------------------------------------------------------------------
3882
// Determine whether the content is mixed, or element-only
3883
// Setting here overrides any setting on the complex type decl
3884
// -----------------------------------------------------------------------
3885
boolean isMixed = mixedOnComplexTypeDecl;
3886        if (mixed.equals(SchemaSymbols.ATTVAL_TRUE) ||
3887            mixed.equals(SchemaSymbols.ATTVAL_TRUE_1))
3888           isMixed = true;
3889        else if (mixed.equals(SchemaSymbols.ATTVAL_FALSE) ||
3890                 mixed.equals(SchemaSymbols.ATTVAL_FALSE_0))
3891           isMixed = false;
3892
3893        // -----------------------------------------------------------------------
3894
// Since the type must have complex content, set the simple type validators
3895
// to null
3896
// -----------------------------------------------------------------------
3897
typeInfo.datatypeValidator = null;
3898        typeInfo.baseDataTypeValidator = null;
3899
3900        Element JavaDoc complexContent = checkContent(complexContentDecl,
3901                                 XUtil.getFirstChildElement(complexContentDecl),false);
3902
3903        // If there are no children, return
3904
if (complexContent==null) {
3905           throw new ComplexTypeRecoverableError();
3906        }
3907
3908        // -----------------------------------------------------------------------
3909
// The content should be either "restriction" or "extension"
3910
// -----------------------------------------------------------------------
3911
String JavaDoc complexContentName = complexContent.getLocalName();
3912        if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION))
3913          typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
3914        else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION))
3915          typeInfo.derivedBy = SchemaSymbols.EXTENSION;
3916        else {
3917           throw new ComplexTypeRecoverableError(
3918                     "The content of the complexContent element is invalid. " +
3919                     "The content must be RESTRICTION or EXTENSION");
3920        }
3921
3922        // Get the attributes of the restriction/extension element
3923
String JavaDoc base = complexContent.getAttribute(SchemaSymbols.ATT_BASE);
3924        String JavaDoc complexContentTypeId=complexContent.getAttribute(SchemaSymbols.ATTVAL_ID);
3925
3926
3927        // Skip over any annotations in the restriction or extension elements
3928
Element JavaDoc content = checkContent(complexContent,
3929                              XUtil.getFirstChildElement(complexContent),true);
3930
3931        // -----------------------------------------------------------------------
3932
// Handle the base type name
3933
// -----------------------------------------------------------------------
3934
if (base.length() == 0) {
3935           throw new ComplexTypeRecoverableError(
3936                  "The BASE attribute must be specified for the " +
3937                  "RESTRICTION or EXTENSION element");
3938        }
3939
3940        QName baseQName = parseBase(base);
3941
3942        // -------------------------------------------------------------
3943
// check if the base is "anyType"
3944
// -------------------------------------------------------------
3945
String JavaDoc baseTypeURI = fStringPool.toString(baseQName.uri);
3946        String JavaDoc baseLocalName = fStringPool.toString(baseQName.localpart);
3947        if (!(baseTypeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
3948            baseLocalName.equals("anyType"))) {
3949
3950            processBaseTypeInfo(baseQName,typeInfo);
3951
3952            //Check that the base is a complex type
3953
if (typeInfo.baseComplexTypeInfo == null) {
3954                 throw new ComplexTypeRecoverableError(
3955                   "The base type specified in the complexContent element must be a complexType");
3956            }
3957        }
3958
3959        // -----------------------------------------------------------------------
3960
// Process the elements that make up the content
3961
// -----------------------------------------------------------------------
3962
processComplexContent(typeNameIndex,content,typeInfo,baseQName,isMixed);
3963
3964        if (XUtil.getNextSiblingElement(complexContent) != null)
3965            throw new ComplexTypeRecoverableError(
3966               "Invalid child following the RESTRICTION or EXTENSION element in the " +
3967               "complex type definition");
3968
3969    } // end traverseComplexContentDecl
3970

3971
3972    /**
3973     * Handle complexType error
3974     *
3975     * @param message
3976     * @param typeNameIndex
3977     * @param typeInfo
3978     * @return
3979     */

3980    private void handleComplexTypeError(String JavaDoc message, int typeNameIndex,
3981                                        ComplexTypeInfo typeInfo) throws Exception JavaDoc {
3982
3983        String JavaDoc typeName = fStringPool.toString(typeNameIndex);
3984        if (message != null) {
3985          if (typeName.startsWith("#"))
3986            reportGenericSchemaError("Anonymous complexType: " + message);
3987          else
3988            reportGenericSchemaError("ComplexType '" + typeName + "': " + message);
3989        }
3990
3991        //
3992
// Mock up the typeInfo structure so that there won't be problems during
3993
// validation
3994
//
3995
typeInfo.contentType = XMLElementDecl.TYPE_ANY; // this should match anything
3996
typeInfo.contentSpecHandle = -1;
3997        typeInfo.derivedBy = 0;
3998        typeInfo.datatypeValidator = null;
3999        typeInfo.attlistHead = -1;
4000
4001        int templateElementNameIndex = fStringPool.addSymbol("$"+typeName);
4002        typeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
4003            new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
4004            (fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : fCurrentScope, typeInfo.scopeDefined,
4005            typeInfo.contentType,
4006            typeInfo.contentSpecHandle, -1, typeInfo.datatypeValidator);
4007        return;
4008    }
4009
4010    /**
4011     * Generate a name for an anonymous type
4012     *
4013     * @param Element
4014     * @return String
4015     */

4016    private String JavaDoc genAnonTypeName(Element JavaDoc complexTypeDecl) throws Exception JavaDoc {
4017
4018        // Generate a unique name for the anonymous type by concatenating together the
4019
// names of parent nodes
4020
String JavaDoc typeName;
4021        Element JavaDoc node=complexTypeDecl;
4022        typeName="#AnonType_";
4023        while (!isTopLevel(node)) {
4024          node = (Element JavaDoc)node.getParentNode();
4025          typeName = typeName+node.getAttribute(SchemaSymbols.ATT_NAME);
4026        }
4027
4028        return typeName;
4029    }
4030    /**
4031     * Parse base string
4032     *
4033     * @param base
4034     * @return QName
4035     */

4036    private QName parseBase(String JavaDoc base) throws Exception JavaDoc {
4037
4038        String JavaDoc prefix = "";
4039        String JavaDoc localpart = base;
4040        int colonptr = base.indexOf(":");
4041        if ( colonptr > 0) {
4042            prefix = base.substring(0,colonptr);
4043            localpart = base.substring(colonptr+1);
4044        }
4045
4046        int nameIndex = fStringPool.addSymbol(base);
4047        int prefixIndex = fStringPool.addSymbol(prefix);
4048        int localpartIndex = fStringPool.addSymbol(localpart);
4049        int URIindex = fStringPool.addSymbol(resolvePrefixToURI(prefix));
4050        return new QName(prefixIndex,localpartIndex,nameIndex,URIindex);
4051    }
4052
4053    /**
4054     * Check if base is from another schema
4055     *
4056     * @param baseName
4057     * @return boolean
4058     */

4059    private boolean baseFromAnotherSchema(QName baseName) throws Exception JavaDoc {
4060
4061        String JavaDoc typeURI = fStringPool.toString(baseName.uri);
4062        if ( ! typeURI.equals(fTargetNSURIString)
4063             && ! typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
4064             && typeURI.length() != 0 )
4065             //REVISIT, !!!! a hack: for schema that has no
4066
//target namespace, e.g. personal-schema.xml
4067
return true;
4068        else
4069          return false;
4070
4071    }
4072
4073    /**
4074     * Process "base" information for a complexType
4075     *
4076     * @param baseTypeInfo
4077     * @param baseName
4078     * @param typeInfo
4079     * @return
4080     */

4081
4082    private void processBaseTypeInfo(QName baseName, ComplexTypeInfo typeInfo) throws Exception JavaDoc {
4083
4084        ComplexTypeInfo baseComplexTypeInfo = null;
4085        DatatypeValidator baseDTValidator = null;
4086
4087        String JavaDoc typeURI = fStringPool.toString(baseName.uri);
4088        String JavaDoc localpart = fStringPool.toString(baseName.localpart);
4089        String JavaDoc base = fStringPool.toString(baseName.rawname);
4090
4091
4092        // -------------------------------------------------------------
4093
// check if the base type is from another schema
4094
// -------------------------------------------------------------
4095
if (baseFromAnotherSchema(baseName)) {
4096            baseComplexTypeInfo = getTypeInfoFromNS(typeURI, localpart);
4097            if (baseComplexTypeInfo == null) {
4098                baseDTValidator = getTypeValidatorFromNS(typeURI, localpart);
4099            }
4100        }
4101
4102        // -------------------------------------------------------------
4103
// type must be from same schema
4104
// -------------------------------------------------------------
4105
else {
4106            String JavaDoc fullBaseName = typeURI+","+localpart;
4107
4108            // assume the base is a complexType and try to locate the base type first
4109
baseComplexTypeInfo= (ComplexTypeInfo) fComplexTypeRegistry.get(fullBaseName);
4110
4111            // if not found, 2 possibilities:
4112
// 1: ComplexType in question has not been compiled yet;
4113
// 2: base is SimpleTYpe;
4114
if (baseComplexTypeInfo == null) {
4115                baseDTValidator = getDatatypeValidator(typeURI, localpart);
4116
4117                if (baseDTValidator == null) {
4118                    int baseTypeSymbol;
4119                    Element JavaDoc baseTypeNode = getTopLevelComponentByName(
4120                                   SchemaSymbols.ELT_COMPLEXTYPE,localpart);
4121                    if (baseTypeNode != null) {
4122                        // Before traversing the base, make sure we're not already
4123
// doing so..
4124
// ct-props-correct 3
4125
if (fBaseTypeNameStack.search((Object JavaDoc)fullBaseName) > - 1) {
4126                            throw new ComplexTypeRecoverableError(
4127                                 "ct-props-correct.3: Recursive type definition");
4128                        }
4129                        fBaseTypeNameStack.push(fullBaseName);
4130                        baseTypeSymbol = traverseComplexTypeDecl( baseTypeNode, true );
4131                    fBaseTypeNameStack.pop();
4132                        baseComplexTypeInfo = (ComplexTypeInfo)
4133                          fComplexTypeRegistry.get(fStringPool.toString(baseTypeSymbol));
4134                        //REVISIT: should it be fullBaseName;
4135
}
4136                    else {
4137                        baseTypeNode = getTopLevelComponentByName(
4138                                   SchemaSymbols.ELT_SIMPLETYPE, localpart);
4139                        if (baseTypeNode != null) {
4140                            baseTypeSymbol = traverseSimpleTypeDecl( baseTypeNode );
4141                            baseDTValidator = getDatatypeValidator(typeURI, localpart);
4142                        }
4143                    }
4144                }
4145            }
4146        } // end else (type must be from same schema)
4147

4148        //
4149
//Schema Spec: Complex Type Definition Representation OK : 2
4150
//
4151
if (baseComplexTypeInfo == null && baseDTValidator == null) {
4152            throw new ComplexTypeRecoverableError(
4153             "src-ct.2: Cannot find type definition for '" + base +"'");
4154        }
4155
4156        typeInfo.baseComplexTypeInfo = baseComplexTypeInfo;
4157        typeInfo.baseDataTypeValidator = baseDTValidator;
4158    } // end processBaseTypeInfo
4159

4160    /**
4161     * Process content which is complex
4162     *
4163     * (group | all | choice | sequence) ? ,
4164     * ((attribute | attributeGroup)* , anyAttribute?))
4165     *
4166     * @param typeNameIndex
4167     * @param complexContentChild
4168     * @param typeInfo
4169     * @return
4170     */

4171
4172    private void processComplexContent(int typeNameIndex,
4173               Element JavaDoc complexContentChild, ComplexTypeInfo typeInfo, QName baseName,
4174               boolean isMixed) throws Exception JavaDoc {
4175
4176       Element JavaDoc attrNode = null;
4177       int index=-2;
4178       String JavaDoc typeName = fStringPool.toString(typeNameIndex);
4179
4180       if (complexContentChild != null) {
4181           // -------------------------------------------------------------
4182
// GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
4183
// Note that it's possible that only attributes are specified.
4184
// -------------------------------------------------------------
4185

4186
4187          String JavaDoc childName = complexContentChild.getLocalName();
4188
4189          if (childName.equals(SchemaSymbols.ELT_GROUP)) {
4190               GroupInfo grpInfo = traverseGroupDecl(complexContentChild);
4191               int groupIndex = (grpInfo != null) ? grpInfo.contentSpecIndex:-2;
4192
4193               index = handleOccurrences(groupIndex,
4194                                complexContentChild,
4195                                hasAllContent(groupIndex) ? GROUP_REF_WITH_ALL :
4196                                                            NOT_ALL_CONTEXT);
4197               attrNode = XUtil.getNextSiblingElement(complexContentChild);
4198           }
4199           else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
4200               index = handleOccurrences(traverseSequence(complexContentChild),
4201                                         complexContentChild);
4202               attrNode = XUtil.getNextSiblingElement(complexContentChild);
4203           }
4204           else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
4205               index = handleOccurrences(traverseChoice(complexContentChild),
4206                                          complexContentChild);
4207               attrNode = XUtil.getNextSiblingElement(complexContentChild);
4208           }
4209           else if (childName.equals(SchemaSymbols.ELT_ALL)) {
4210               index = handleOccurrences(traverseAll(complexContentChild),
4211                                         complexContentChild,
4212                                         PROCESSING_ALL_GP);
4213               attrNode = XUtil.getNextSiblingElement(complexContentChild);
4214           }
4215           else if (isAttrOrAttrGroup(complexContentChild)) {
4216               // reset the contentType
4217
typeInfo.contentType = XMLElementDecl.TYPE_ANY;
4218               attrNode = complexContentChild;
4219           }
4220           else {
4221               throw new ComplexTypeRecoverableError(
4222                "Invalid child '"+ childName +"' in the complex type");
4223           }
4224       }
4225
4226       typeInfo.contentSpecHandle = index;
4227
4228       // -----------------------------------------------------------------------
4229
// Merge in information from base, if it exists
4230
// -----------------------------------------------------------------------
4231
if (typeInfo.baseComplexTypeInfo != null) {
4232           int baseContentSpecHandle = typeInfo.baseComplexTypeInfo.contentSpecHandle;
4233
4234           //-------------------------------------------------------------
4235
// RESTRICTION
4236
//-------------------------------------------------------------
4237
if (typeInfo.derivedBy == SchemaSymbols.RESTRICTION) {
4238              // check to see if the baseType permits derivation by restriction
4239
if((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.RESTRICTION) != 0)
4240                    throw new ComplexTypeRecoverableError("Derivation by restriction is forbidden by either the base type " + fStringPool.toString(baseName.localpart) + " or the schema");
4241
4242              // if the content is EMPTY, check that the base is correct
4243
// according to derivation-ok-restriction 5.2
4244
if (typeInfo.contentSpecHandle==-2) {
4245                 if (!(typeInfo.baseComplexTypeInfo.contentType==XMLElementDecl.TYPE_EMPTY ||
4246                     particleEmptiable(baseContentSpecHandle))) {
4247                    throw new ComplexTypeRecoverableError("derivation-ok-restrictoin.5.2 Content type of complexType is EMPTY but base is not EMPTY or does not have a particle which is emptiable");
4248                 }
4249              }
4250
4251              //
4252
// Delay derivation by restriction particle constraint checking until
4253
// the whole schema has been processed. We need to do this because:
4254
// - top-level element declarations are not processed until traversed
4255
// thru the main traverseSchema walk.
4256
//
4257
//
4258

4259           }
4260           //-------------------------------------------------------------
4261
// EXTENSION
4262
//-------------------------------------------------------------
4263
else {
4264               // check to see if the baseType permits derivation by extension
4265
if((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.EXTENSION) != 0)
4266                    throw new ComplexTypeRecoverableError("cos-ct-extends.1.1: Derivation by extension is forbidden by either the base type " + fStringPool.toString(baseName.localpart) + " or the schema");
4267
4268               //
4269
// Check if the contentType of the base is consistent with the new type
4270
// cos-ct-extends.1.4.2.2
4271
if (typeInfo.baseComplexTypeInfo.contentType != XMLElementDecl.TYPE_EMPTY) {
4272                  if (((typeInfo.baseComplexTypeInfo.contentType == XMLElementDecl.TYPE_CHILDREN) &&
4273                       isMixed) ||
4274                      ((typeInfo.baseComplexTypeInfo.contentType == XMLElementDecl.TYPE_MIXED_COMPLEX) &&
4275                      !isMixed)) {
4276                    throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.2.2.2.1: The content type of the base type " +
4277                    fStringPool.toString(baseName.localpart) + " and derived type " +
4278                    typeName + " must both be mixed or element-only");
4279                  }
4280
4281               }
4282
4283               //
4284
// Compose the final content model by concatenating the base and the
4285
// current in sequence
4286
//
4287
if (baseFromAnotherSchema(baseName)) {
4288                   String JavaDoc baseSchemaURI = fStringPool.toString(baseName.uri);
4289                   SchemaGrammar aGrammar= (SchemaGrammar) fGrammarResolver.getGrammar(
4290                                    baseSchemaURI);
4291                   baseContentSpecHandle = importContentSpec(aGrammar, baseContentSpecHandle);
4292               }
4293               if (typeInfo.contentSpecHandle == -2) {
4294                   typeInfo.contentSpecHandle = baseContentSpecHandle;
4295               }
4296               else if (baseContentSpecHandle > -1) {
4297                   if (typeInfo.contentSpecHandle > -1 &&
4298                       (hasAllContent(typeInfo.contentSpecHandle) ||
4299                        hasAllContent(baseContentSpecHandle))) {
4300                       throw new ComplexTypeRecoverableError("cos-all-limited.1.2: An \"all\" model group that is part of a complex type definition must constitute the entire {content type} of the definition.");
4301                   }
4302
4303                   typeInfo.contentSpecHandle =
4304                   fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
4305                                                     baseContentSpecHandle,
4306                                                     typeInfo.contentSpecHandle,
4307                                                     false);
4308               }
4309
4310               //
4311
// Check that there is a particle in the final content
4312
// cos-ct-extends.1.4.2.1
4313
// LM - commented out until I get a clarification from HT
4314
//
4315
//if (typeInfo.contentSpecHandle <0) {
4316
// throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.2.1: The content of a type derived by EXTENSION must contain a particle");
4317
//}
4318
}
4319       }
4320       else {
4321           typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
4322       }
4323
4324       // -------------------------------------------------------------
4325
// Set the content type
4326
// -------------------------------------------------------------
4327
if (isMixed) {
4328
4329           // if there are no children, detect an error
4330
// See the definition of content type in Structures 3.4.1
4331
// This is commented out for now, until I get a clarification from schema WG
4332
// LM.
4333

4334           if (typeInfo.contentSpecHandle == -2) {
4335             //throw new ComplexTypeRecoverableError("Type '" + typeName + "': The content of a mixed complexType must not be empty");
4336

4337             // for "mixed" complex type with empty content
4338
// we add an optional leaf node to the content model
4339
// with empty namespace and -1 name (which won't match any element)
4340
// so that the result content model is emptible and only match
4341
// with cdata
4342
int emptyIndex = fSchemaGrammar.addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF,
4343                                                                -1,
4344                                                                StringPool.EMPTY_STRING,
4345                                                                false);
4346             if (fSchemaGrammar.getDeferContentSpecExpansion()) {
4347                 fSchemaGrammar.setContentSpecMinOccurs(emptyIndex, 0);
4348                 fSchemaGrammar.setContentSpecMaxOccurs(emptyIndex, 1);
4349                 typeInfo.contentSpecHandle = emptyIndex;
4350             } else {
4351                 typeInfo.contentSpecHandle = fSchemaGrammar.expandContentModel(emptyIndex,0,1);
4352             }
4353
4354             typeInfo.contentType = XMLElementDecl.TYPE_MIXED_SIMPLE;
4355           }
4356
4357           else
4358             typeInfo.contentType = XMLElementDecl.TYPE_MIXED_COMPLEX;
4359       }
4360       else if (typeInfo.contentSpecHandle == -2)
4361           typeInfo.contentType = XMLElementDecl.TYPE_EMPTY;
4362       else
4363           typeInfo.contentType = XMLElementDecl.TYPE_CHILDREN;
4364
4365
4366       // -------------------------------------------------------------
4367
// add a template element to the grammar element decl pool.
4368
// -------------------------------------------------------------
4369
int templateElementNameIndex = fStringPool.addSymbol("$"+typeName);
4370
4371       typeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
4372            new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
4373            (fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : fCurrentScope, typeInfo.scopeDefined,
4374            typeInfo.contentType,
4375            typeInfo.contentSpecHandle, -1, typeInfo.datatypeValidator);
4376       typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(
4377                               typeInfo.templateElementIndex);
4378
4379       // -------------------------------------------------------------
4380
// Now, check attributes and handle
4381
// -------------------------------------------------------------
4382
if (attrNode !=null) {
4383           if (!isAttrOrAttrGroup(attrNode)) {
4384              throw new ComplexTypeRecoverableError(
4385                  "Invalid child "+ attrNode.getLocalName() + " in the complexType or complexContent");
4386           }
4387           else
4388              processAttributes(attrNode,baseName,typeInfo);
4389       }
4390       else if (typeInfo.baseComplexTypeInfo != null)
4391           processAttributes(null,baseName,typeInfo);
4392
4393
4394    } // end processComplexContent
4395

4396    /**
4397     * Process attributes of a complex type
4398     *
4399     * @param attrNode
4400     * @param typeInfo
4401     * @return
4402     */

4403
4404    private void processAttributes(Element JavaDoc attrNode, QName baseName,
4405               ComplexTypeInfo typeInfo) throws Exception JavaDoc {
4406
4407
4408        XMLAttributeDecl attWildcard = null;
4409        Vector JavaDoc anyAttDecls = new Vector JavaDoc();
4410
4411        Element JavaDoc child;
4412        for (child = attrNode;
4413             child != null;
4414             child = XUtil.getNextSiblingElement(child)) {
4415
4416            String JavaDoc childName = child.getLocalName();
4417
4418            if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
4419                traverseAttributeDecl(child, typeInfo, false);
4420            }
4421            else if ( childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ) {
4422                traverseAttributeGroupDecl(child,typeInfo,anyAttDecls);
4423
4424            }
4425            else if ( childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE) ) {
4426                attWildcard = traverseAnyAttribute(child);
4427            }
4428            else {
4429                throw new ComplexTypeRecoverableError( "Invalid child among the children of the complexType definition");
4430            }
4431        }
4432
4433        if (attWildcard != null) {
4434            XMLAttributeDecl fromGroup = null;
4435            final int count = anyAttDecls.size();
4436            if ( count > 0) {
4437                fromGroup = (XMLAttributeDecl) anyAttDecls.elementAt(0);
4438                for (int i=1; i<count; i++) {
4439                    fromGroup = AWildCardIntersection(
4440                                fromGroup,(XMLAttributeDecl)anyAttDecls.elementAt(i));
4441                }
4442            }
4443            if (fromGroup != null) {
4444                int saveProcessContents = attWildcard.defaultType;
4445                attWildcard = AWildCardIntersection(attWildcard, fromGroup);
4446                attWildcard.defaultType = saveProcessContents;
4447            }
4448        }
4449        else {
4450            //REVISIT: unclear in the Scheme Structures 4.3.3 what to do in this case
4451
if (anyAttDecls.size()>0) {
4452                attWildcard = (XMLAttributeDecl)anyAttDecls.elementAt(0);
4453            }
4454        }
4455        //
4456
// merge in base type's attribute decls
4457
//
4458
XMLAttributeDecl baseAttWildcard = null;
4459        ComplexTypeInfo baseTypeInfo = typeInfo.baseComplexTypeInfo;
4460
4461        SchemaGrammar aGrammar=null;
4462        if (baseTypeInfo != null && baseTypeInfo.attlistHead > -1 ) {
4463            int attDefIndex = baseTypeInfo.attlistHead;
4464            aGrammar = fSchemaGrammar;
4465            String JavaDoc baseTypeSchemaURI = baseFromAnotherSchema(baseName)?
4466                           fStringPool.toString(baseName.uri):null;
4467            if (baseTypeSchemaURI != null) {
4468                aGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(baseTypeSchemaURI);
4469            }
4470            if (aGrammar == null) {
4471                //reportGenericSchemaError("In complexType "+typeName+", can NOT find the grammar "+
4472
// "with targetNamespace" + baseTypeSchemaURI+
4473
// "for the base type");
4474
}
4475            else
4476            while ( attDefIndex > -1 ) {
4477                fTempAttributeDecl.clear();
4478                aGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
4479                if (fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_ANY
4480                    ||fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
4481                    ||fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER ) {
4482                    if (attWildcard == null) {
4483                        baseAttWildcard = fTempAttributeDecl;
4484                    }
4485                    attDefIndex = aGrammar.getNextAttributeDeclIndex(attDefIndex);
4486                    continue;
4487                }
4488                // if found a duplicate, if it is derived by restriction,
4489
// then skip the one from the base type
4490

4491                int temp = fSchemaGrammar.getAttributeDeclIndex(typeInfo.templateElementIndex, fTempAttributeDecl.name);
4492                if ( temp > -1) {
4493                  if (typeInfo.derivedBy==SchemaSymbols.EXTENSION) {
4494                    throw new ComplexTypeRecoverableError("Attribute " + fStringPool.toString(fTempAttributeDecl.name.localpart) + " that appeared in the base should not appear in a derivation by extension");
4495
4496
4497                  }
4498                  else {
4499                    attDefIndex = fSchemaGrammar.getNextAttributeDeclIndex(attDefIndex);
4500                    continue;
4501                  }
4502                }
4503
4504                fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
4505                                          fTempAttributeDecl.name, fTempAttributeDecl.type,
4506                                          fTempAttributeDecl.enumeration, fTempAttributeDecl.defaultType,
4507                                          fTempAttributeDecl.defaultValue,
4508                                          fTempAttributeDecl.datatypeValidator,
4509                                          fTempAttributeDecl.list);
4510                attDefIndex = aGrammar.getNextAttributeDeclIndex(attDefIndex);
4511            }
4512        }
4513
4514        // att wildcard will inserted after all attributes were processed
4515
if (attWildcard != null) {
4516            if (attWildcard.type != -1) {
4517                fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
4518                                          attWildcard.name, attWildcard.type,
4519                                          attWildcard.enumeration, attWildcard.defaultType,
4520                                          attWildcard.defaultValue,
4521                                          attWildcard.datatypeValidator,
4522                                          attWildcard.list);
4523            }
4524            else {
4525                //REVISIT: unclear in Schema spec if should report error here.
4526
reportGenericSchemaError("The intensional intersection for {attribute wildcard}s must be expressible");
4527            }
4528        }
4529        else if (baseAttWildcard != null) {
4530            fSchemaGrammar.addAttDef( typeInfo.templateElementIndex,
4531                                      baseAttWildcard.name, baseAttWildcard.type,
4532                                      baseAttWildcard.enumeration, baseAttWildcard.defaultType,
4533                                      baseAttWildcard.defaultValue,
4534                                      baseAttWildcard.datatypeValidator,
4535                                      baseAttWildcard.list);
4536        }
4537
4538        typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex
4539                                              (typeInfo.templateElementIndex);
4540
4541        // For derivation by restriction, ensure that the resulting attribute list
4542
// satisfies the constraints in derivation-ok-restriction 2,3,4
4543
if ((typeInfo.derivedBy==SchemaSymbols.RESTRICTION) &&
4544            (typeInfo.attlistHead>-1 && baseTypeInfo != null)) {
4545           checkAttributesDerivationOKRestriction(typeInfo.attlistHead,fSchemaGrammar,
4546               attWildcard,baseTypeInfo.attlistHead,aGrammar,baseAttWildcard);
4547        }
4548
4549    } // end processAttributes
4550

4551    // Check that the attributes of a type derived by restriction satisfy the
4552
// constraints of derivation-ok-restriction
4553

4554    private void checkAttributesDerivationOKRestriction(int dAttListHead, SchemaGrammar dGrammar, XMLAttributeDecl dAttWildCard, int bAttListHead, SchemaGrammar bGrammar, XMLAttributeDecl bAttWildCard) throws ComplexTypeRecoverableError {
4555
4556       int attDefIndex = dAttListHead;
4557
4558       if (bAttListHead < 0) {
4559          throw new ComplexTypeRecoverableError("derivation-ok-restriction.2: Base type definition does not have any attributes");
4560       }
4561
4562       // Loop thru the attributes
4563
while ( attDefIndex > -1 ) {
4564          fTempAttributeDecl.clear();
4565          dGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
4566          if (isAWildCard(fTempAttributeDecl)) {
4567             attDefIndex = dGrammar.getNextAttributeDeclIndex(attDefIndex);
4568             continue;
4569          }
4570          int bAttDefIndex = bGrammar.findAttributeDecl(bAttListHead, fTempAttributeDecl.name);
4571          if (bAttDefIndex > -1) {
4572             fTemp2AttributeDecl.clear();
4573             bGrammar.getAttributeDecl(bAttDefIndex, fTemp2AttributeDecl);
4574
4575             // derivation-ok-restriction. Constraint 2.1.1
4576
if ((fTemp2AttributeDecl.defaultType &
4577                   XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) > 0 &&
4578                (fTempAttributeDecl.defaultType &
4579                   XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) <= 0) {
4580               throw new ComplexTypeRecoverableError("derivation-ok-restriction.2.1.1: Attribute '" + fStringPool.toString(fTempAttributeDecl.name.localpart) + "' in derivation has an inconsistent REQUIRED setting to that of attribute in base");
4581             }
4582
4583             //
4584
// derivation-ok-restriction. Constraint 2.1.2
4585
//
4586
if (!(checkSimpleTypeDerivationOK(
4587                  fTempAttributeDecl.datatypeValidator,
4588                  fTemp2AttributeDecl.datatypeValidator))) {
4589               throw new ComplexTypeRecoverableError("derivation-ok-restriction.2.1.2: Type of attribute '" + fStringPool.toString(fTempAttributeDecl.name.localpart) + "' in derivation must be a restriction of type of attribute in base");
4590             }
4591
4592             //
4593
// derivation-ok-restriction. Constraint 2.1.3
4594
//
4595
if ((fTemp2AttributeDecl.defaultType &
4596                   XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0) {
4597
4598               if (!((fTempAttributeDecl.defaultType &
4599                   XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0) ||
4600                   !fTempAttributeDecl.defaultValue.equals(fTemp2AttributeDecl.defaultValue)) {
4601
4602                  throw new ComplexTypeRecoverableError("derivation-ok-restriction.2.1.3: Attribute '" + fStringPool.toString(fTempAttributeDecl.name.localpart) + "' is either not fixed, or is not fixed with the same value as the attribute in the base");
4603               }
4604             }
4605
4606          }
4607         else {
4608             //
4609
// derivation-ok-restriction. Constraint 2.2
4610
//
4611
if ((bAttWildCard==null) ||
4612              !AWildCardAllowsNameSpace(bAttWildCard, dGrammar.getTargetNamespaceURI())) {
4613                throw new ComplexTypeRecoverableError("derivation-ok-restriction.2.2: Attribute '" + fStringPool.toString(fTempAttributeDecl.name.localpart) + "' has a target namespace which is not valid with respect to a base type definition's wildcard or, the base does not contain a wildcard");
4614
4615             }
4616         }
4617         attDefIndex = dGrammar.getNextAttributeDeclIndex(attDefIndex);
4618
4619       }
4620
4621       // derivation-ok-restriction. Constraint 4
4622
if (dAttWildCard!=null) {
4623          if (bAttWildCard==null) {
4624            throw new ComplexTypeRecoverableError("derivation-ok-restriction.4.1: An attribute wildcard is present in the derived type, but not the base");
4625          }
4626
4627          if (!AWildCardSubset(dAttWildCard,bAttWildCard)) {
4628            throw new ComplexTypeRecoverableError("derivation-ok-restriction.4.2: The attribute wildcard in the derived type is not a valid subset of that in the base");
4629
4630          }
4631       }
4632    }
4633
4634    private boolean isAttrOrAttrGroup(Element JavaDoc e)
4635    {
4636        String JavaDoc elementName = e.getLocalName();
4637
4638        if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE) ||
4639            elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ||
4640            elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE))
4641          return true;
4642        else
4643          return false;
4644    }
4645
4646    private void checkRecursingComplexType() throws Exception JavaDoc {
4647        if ( fCurrentTypeNameStack.empty() ) {
4648            if (! fElementRecurseComplex.isEmpty() ) {
4649
4650               int count= fElementRecurseComplex.size();
4651
4652               for (int i = 0; i<count; i++) {
4653
4654                 ElementInfo eobj = (ElementInfo)fElementRecurseComplex.elementAt(i);
4655                 int elementIndex = eobj.elementIndex;
4656                 String JavaDoc typeName = eobj.typeName;
4657
4658
4659                 ComplexTypeInfo typeInfo =
4660                     (ComplexTypeInfo) fComplexTypeRegistry.get(fTargetNSURIString+","+typeName);
4661                 if (typeInfo==null) {
4662                    throw new Exception JavaDoc ( "Internal Error in void checkRecursingComplexType(). " );
4663                 }
4664                 else {
4665                   // update the element decl with info from the type
4666

4667                   fSchemaGrammar.getElementDecl(elementIndex, fTempElementDecl);
4668                   fTempElementDecl.type = typeInfo.contentType;
4669                   fTempElementDecl.contentSpecIndex = typeInfo.contentSpecHandle;
4670                   fTempElementDecl.datatypeValidator = typeInfo.datatypeValidator;
4671                   fSchemaGrammar.setElementDecl(elementIndex, fTempElementDecl);
4672
4673                   fSchemaGrammar.setFirstAttributeDeclIndex(elementIndex,
4674                        typeInfo.attlistHead);
4675                   fSchemaGrammar.setElementComplexTypeInfo(elementIndex,typeInfo);
4676                   fSchemaGrammar.setElementDefinedScope(elementIndex,typeInfo.scopeDefined);
4677                 }
4678               }
4679               fElementRecurseComplex.removeAllElements();
4680            }
4681        }
4682    }
4683
4684    // Check that the particle defined by the derived ct tree is a valid restriction of
4685
// that specified by baseContentSpecIndex. derivedScope and baseScope are the
4686
// scopes of the particles, respectively. bInfo is supplied when the base particle
4687
// is from a base type definition, and may be null - it helps determine other scopes
4688
// that elements should be looked up in.
4689

4690    private void checkParticleDerivationOK(int derivedContentSpecIndex, int derivedScope, int baseContentSpecIndex, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
4691
4692
4693       // Only do this if full checking is enabled
4694
if (!fFullConstraintChecking)
4695           return;
4696
4697       // Check for pointless occurrences of all, choice, sequence. The result is the
4698
// contentspec which is not pointless. If the result is a non-pointless
4699
// group, Vector is filled in with the children of interest
4700
int csIndex1 = derivedContentSpecIndex;
4701       fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
4702       int csIndex2 = baseContentSpecIndex;
4703       fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
4704
4705       Vector JavaDoc tempVector1 = new Vector JavaDoc();
4706       Vector JavaDoc tempVector2 = new Vector JavaDoc();
4707
4708       if (tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_SEQ ||
4709           tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
4710           tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_ALL) {
4711         csIndex1 = checkForPointlessOccurrences(csIndex1,tempVector1);
4712       }
4713       if (tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_SEQ ||
4714           tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
4715           tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_ALL) {
4716         csIndex2 = checkForPointlessOccurrences(csIndex2,tempVector2);
4717       }
4718
4719       fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
4720       fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
4721
4722       switch (tempContentSpec1.type & 0x0f) {
4723         case XMLContentSpec.CONTENTSPECNODE_LEAF:
4724         {
4725            switch (tempContentSpec2.type & 0x0f) {
4726
4727              // Elt:Elt NameAndTypeOK
4728
case XMLContentSpec.CONTENTSPECNODE_LEAF:
4729              {
4730                 checkNameAndTypeOK(csIndex1, derivedScope, csIndex2, baseScope, bInfo);
4731                 return;
4732              }
4733
4734              // Elt:Any NSCompat
4735
case XMLContentSpec.CONTENTSPECNODE_ANY:
4736              case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4737              case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4738              {
4739                 checkNSCompat(csIndex1, derivedScope, csIndex2);
4740                 return;
4741              }
4742
4743              // Elt:All RecurseAsIfGroup
4744
case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4745              case XMLContentSpec.CONTENTSPECNODE_SEQ:
4746              case XMLContentSpec.CONTENTSPECNODE_ALL:
4747              {
4748                 checkRecurseAsIfGroup(csIndex1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4749                 return;
4750              }
4751
4752              default:
4753              {
4754            throw new ParticleRecoverableError("internal Xerces error");
4755              }
4756            }
4757         }
4758
4759         case XMLContentSpec.CONTENTSPECNODE_ANY:
4760         case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4761         case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4762         {
4763            switch (tempContentSpec2.type & 0x0f) {
4764
4765              // Any:Any NSSubset
4766
case XMLContentSpec.CONTENTSPECNODE_ANY:
4767              case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4768              case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4769              {
4770                 checkNSSubset(csIndex1, csIndex2);
4771                 return;
4772              }
4773
4774              case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4775              case XMLContentSpec.CONTENTSPECNODE_SEQ:
4776              case XMLContentSpec.CONTENTSPECNODE_ALL:
4777              case XMLContentSpec.CONTENTSPECNODE_LEAF:
4778              {
4779                 throw new ParticleRecoverableError("cos-particle-restrict: Forbidden restriction: Any: Choice,Seq,All,Elt");
4780              }
4781
4782              default:
4783              {
4784            throw new ParticleRecoverableError("internal Xerces error");
4785              }
4786            }
4787         }
4788
4789         case XMLContentSpec.CONTENTSPECNODE_ALL:
4790         {
4791            switch (tempContentSpec2.type & 0x0f) {
4792
4793              // All:Any NSRecurseCheckCardinality
4794
case XMLContentSpec.CONTENTSPECNODE_ANY:
4795              case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4796              case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4797              {
4798                 checkNSRecurseCheckCardinality(csIndex1, tempVector1, derivedScope, csIndex2);
4799                 return;
4800              }
4801
4802              case XMLContentSpec.CONTENTSPECNODE_ALL:
4803              {
4804                 checkRecurse(csIndex1, tempVector1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4805                 return;
4806              }
4807
4808              case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4809              case XMLContentSpec.CONTENTSPECNODE_SEQ:
4810              case XMLContentSpec.CONTENTSPECNODE_LEAF:
4811              {
4812                 throw new ParticleRecoverableError("cos-particle-restrict: Forbidden restriction: All:Choice,Seq,Elt");
4813              }
4814
4815              default:
4816              {
4817            throw new ParticleRecoverableError("internal Xerces error");
4818              }
4819            }
4820         }
4821
4822         case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4823         {
4824            switch (tempContentSpec2.type & 0x0f) {
4825
4826              // Choice:Any NSRecurseCheckCardinality
4827
case XMLContentSpec.CONTENTSPECNODE_ANY:
4828              case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4829              case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4830              {
4831                 checkNSRecurseCheckCardinality(csIndex1, tempVector1, derivedScope, csIndex2);
4832                 return;
4833              }
4834
4835              case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4836              {
4837                 checkRecurseLax(csIndex1, tempVector1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4838                 return;
4839              }
4840
4841              case XMLContentSpec.CONTENTSPECNODE_ALL:
4842              case XMLContentSpec.CONTENTSPECNODE_SEQ:
4843              case XMLContentSpec.CONTENTSPECNODE_LEAF:
4844              {
4845                 throw new ParticleRecoverableError("cos-particle-restrict: Forbidden restriction: Choice:All,Seq,Leaf");
4846              }
4847
4848              default:
4849              {
4850            throw new ParticleRecoverableError("internal Xerces error");
4851              }
4852            }
4853         }
4854
4855
4856         case XMLContentSpec.CONTENTSPECNODE_SEQ:
4857         {
4858            switch (tempContentSpec2.type & 0x0f) {
4859
4860              // Choice:Any NSRecurseCheckCardinality
4861
case XMLContentSpec.CONTENTSPECNODE_ANY:
4862              case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
4863              case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
4864              {
4865                 checkNSRecurseCheckCardinality(csIndex1, tempVector1, derivedScope, csIndex2);
4866                 return;
4867              }
4868
4869              case XMLContentSpec.CONTENTSPECNODE_ALL:
4870              {
4871                 checkRecurseUnordered(csIndex1, tempVector1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4872                 return;
4873              }
4874
4875              case XMLContentSpec.CONTENTSPECNODE_SEQ:
4876              {
4877                 checkRecurse(csIndex1, tempVector1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4878                 return;
4879              }
4880
4881              case XMLContentSpec.CONTENTSPECNODE_CHOICE:
4882              {
4883                 checkMapAndSum(csIndex1, tempVector1, derivedScope, csIndex2, tempVector2, baseScope, bInfo);
4884                 return;
4885              }
4886
4887              case XMLContentSpec.CONTENTSPECNODE_LEAF:
4888              {
4889                throw new ParticleRecoverableError("cos-particle-restrict: Forbidden restriction: Seq:Elt");
4890              }
4891
4892              default:
4893              {
4894            throw new ParticleRecoverableError("internal Xerces error");
4895              }
4896            }
4897         }
4898
4899       }
4900
4901    }
4902
4903    private int checkForPointlessOccurrences(int csIndex, Vector JavaDoc tempVector) {
4904
4905       // Note: instead of using a Vector, we should use a growable array of int.
4906
// To be cleaned up in release 1.4.1. (LM)
4907

4908       fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
4909
4910       if (tempContentSpec1.otherValue == -2) {
4911         gatherChildren(tempContentSpec1.type,tempContentSpec1.value,tempVector);
4912         if (tempVector.size() == 1) {
4913           Integer JavaDoc returnVal = (Integer JavaDoc)(tempVector.elementAt(0));
4914           return returnVal.intValue();
4915         }
4916         return csIndex;
4917       }
4918
4919       int type = tempContentSpec1.type;
4920       int value = tempContentSpec1.value;
4921       int otherValue = tempContentSpec1.otherValue;
4922
4923       gatherChildren(type,value, tempVector);
4924       gatherChildren(type,otherValue, tempVector);
4925
4926
4927       return csIndex;
4928    }
4929
4930
4931    private void gatherChildren(int parentType, int csIndex, Vector JavaDoc tempVector) {
4932
4933       fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
4934       int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
4935       int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
4936       int left = tempContentSpec1.value;
4937       int right = tempContentSpec1.otherValue;
4938       int type = tempContentSpec1.type;
4939
4940       if (type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
4941           (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
4942           (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS ||
4943           (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ) {
4944          tempVector.addElement(new Integer JavaDoc(csIndex));
4945       }
4946       else if (! (min==1 && max==1)) {
4947          tempVector.addElement(new Integer JavaDoc(csIndex));
4948       }
4949       else if (right == -2) {
4950          gatherChildren(type,left,tempVector);
4951       }
4952       else if (parentType == type) {
4953          gatherChildren(type,left,tempVector);
4954          gatherChildren(type,right,tempVector);
4955       }
4956       else {
4957          tempVector.addElement(new Integer JavaDoc(csIndex));
4958       }
4959
4960    }
4961
4962
4963    private void checkNameAndTypeOK(int csIndex1, int derivedScope, int csIndex2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
4964
4965      fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
4966      fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
4967
4968
4969      int localpart1 = tempContentSpec1.value;
4970      int uri1 = tempContentSpec1.otherValue;
4971      int localpart2 = tempContentSpec2.value;
4972      int uri2 = tempContentSpec2.otherValue;
4973
4974      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
4975      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
4976      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
4977      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
4978
4979      //start the checking...
4980
if (!(localpart1==localpart2 && uri1==uri2)) {
4981
4982        // we have non-matching names. Check substitution groups.
4983
if (fSComp == null)
4984           fSComp = new SubstitutionGroupComparator(fGrammarResolver,fStringPool,fErrorReporter);
4985        if (!checkSubstitutionGroups(localpart1,uri1,localpart2,uri2))
4986          throw new ParticleRecoverableError("rcase-nameAndTypeOK.1: Element name/uri in restriction does not match that of corresponding base element");
4987      }
4988
4989      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
4990        throw new ParticleRecoverableError("rcase-nameAndTypeOK.3: Element occurrence range not a restriction of base element's range: element is " + fStringPool.toString(localpart1));
4991      }
4992
4993      SchemaGrammar aGrammar = fSchemaGrammar;
4994
4995      // get the element decl indices for the remainder...
4996
String JavaDoc schemaURI = fStringPool.toString(uri1);
4997      if ( !schemaURI.equals(fTargetNSURIString)
4998            && schemaURI.length() != 0 )
4999         aGrammar= (SchemaGrammar) fGrammarResolver.getGrammar(schemaURI);
5000
5001      int eltndx1 = findElement(derivedScope, uri1, localpart1, aGrammar, null);
5002      if (eltndx1 < 0)
5003         return;
5004
5005      int eltndx2 = findElement(baseScope, uri2, localpart2, aGrammar, bInfo);
5006      if (eltndx2 < 0)
5007         return;
5008
5009      int miscFlags1 = ((SchemaGrammar) aGrammar).getElementDeclMiscFlags(eltndx1);
5010      int miscFlags2 = ((SchemaGrammar) aGrammar).getElementDeclMiscFlags(eltndx2);
5011      boolean element1IsNillable = (miscFlags1 & SchemaSymbols.NILLABLE) !=0;
5012      boolean element2IsNillable = (miscFlags2 & SchemaSymbols.NILLABLE) !=0;
5013      boolean element2IsFixed = (miscFlags2 & SchemaSymbols.FIXED) !=0;
5014      boolean element1IsFixed = (miscFlags1 & SchemaSymbols.FIXED) !=0;
5015      String JavaDoc element1Value = aGrammar.getElementDefaultValue(eltndx1);
5016      String JavaDoc element2Value = aGrammar.getElementDefaultValue(eltndx2);
5017
5018      if (! (element2IsNillable || !element1IsNillable)) {
5019        throw new ParticleRecoverableError("rcase-nameAndTypeOK.2: Element " +fStringPool.toString(localpart1) + " is nillable in the restriction but not the base");
5020      }
5021
5022      if (! (element2Value == null || !element2IsFixed ||
5023             (element1IsFixed && element1Value.equals(element2Value)))) {
5024        throw new ParticleRecoverableError("rcase-nameAndTypeOK.4: Element " +fStringPool.toString(localpart1) + " is either not fixed, or is not fixed with the same value as in the base");
5025      }
5026
5027      // check disallowed substitutions
5028
int blockSet1 = ((SchemaGrammar) aGrammar).getElementDeclBlockSet(eltndx1);
5029      int blockSet2 = ((SchemaGrammar) aGrammar).getElementDeclBlockSet(eltndx2);
5030      if (((blockSet1 & blockSet2)!=blockSet2) ||
5031            (blockSet1==0 && blockSet2!=0))
5032        throw new ParticleRecoverableError("rcase-nameAndTypeOK.6: Element " +fStringPool.toString(localpart1) + "'s disallowed subsitutions are not a superset of those of the base element's");
5033
5034
5035      // Need element decls for the remainder of the checks
5036
aGrammar.getElementDecl(eltndx1, fTempElementDecl);
5037      aGrammar.getElementDecl(eltndx2, fTempElementDecl2);
5038
5039      // check identity constraints
5040
checkIDConstraintRestriction(fTempElementDecl, fTempElementDecl2, aGrammar, localpart1, localpart2);
5041
5042      // check that the derived element's type is derived from the base's. - TO BE DONE
5043
checkTypesOK(fTempElementDecl,fTempElementDecl2,eltndx1,eltndx2,aGrammar,fStringPool.toString(localpart1));
5044
5045    }
5046
5047    private void checkTypesOK(XMLElementDecl derived, XMLElementDecl base, int dndx, int bndx, SchemaGrammar aGrammar, String JavaDoc elementName) throws Exception JavaDoc {
5048
5049      ComplexTypeInfo tempType=((SchemaGrammar)aGrammar).getElementComplexTypeInfo(dndx);
5050      ComplexTypeInfo bType=((SchemaGrammar)aGrammar).getElementComplexTypeInfo(bndx);
5051      if (derived.type == XMLElementDecl.TYPE_SIMPLE ) {
5052
5053        if (base.type != XMLElementDecl.TYPE_SIMPLE &&
5054            base.type != XMLElementDecl.TYPE_ANY)
5055            throw new ParticleRecoverableError("rcase-nameAndTypeOK.6: Derived element " + elementName + " has a type that does not derive from that of the base");
5056
5057        if (tempType == null) {
5058         if (!(checkSimpleTypeDerivationOK(derived.datatypeValidator,
5059               base.datatypeValidator)) &&
5060             !(bType == null && base.datatypeValidator == null))
5061              throw new ParticleRecoverableError("rcase-nameAndTypeOK.6: Derived element " + elementName + " has a type that does not derive from that of the base");
5062         return;
5063        }
5064      }
5065
5066      for(; tempType != null; tempType = tempType.baseComplexTypeInfo) {
5067        if (bType != null && tempType.typeName.equals(bType.typeName))
5068          break;
5069        if (tempType.derivedBy != SchemaSymbols.RESTRICTION) {
5070          throw new ParticleRecoverableError("rcase-nameAndTypeOK.6: Derived element " + elementName + " has a type that does not derive from that of the base");
5071        }
5072      }
5073
5074      if(tempType == null && !(bType == null && base.datatypeValidator == null)) {
5075        throw new ParticleRecoverableError("rcase-nameAndTypeOK.6: Derived element " + elementName + " has a type that does not derive from that of the base");
5076      }
5077    }
5078
5079    private void checkIDConstraintRestriction(XMLElementDecl derivedElemDecl, XMLElementDecl baseElemDecl,
5080                SchemaGrammar grammar, int derivedElemName, int baseElemName) throws Exception JavaDoc {
5081        // this method throws no errors if the ID constraints on
5082
// the derived element are a logical subset of those on the
5083
// base element--that is, those that are present are
5084
// identical to ones in the base element.
5085
Vector JavaDoc derivedUnique = derivedElemDecl.unique;
5086        Vector JavaDoc baseUnique = baseElemDecl.unique;
5087        if(derivedUnique.size() > baseUnique.size()) {
5088            throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5089                    fStringPool.toString(derivedElemName) +
5090                    " has fewer <unique> Identity Constraints than the base element"+
5091                    fStringPool.toString(baseElemName));
5092        } else {
5093            boolean found = true;
5094            for(int i=0; i<derivedUnique.size() && found; i++) {
5095                Unique id = (Unique)derivedUnique.elementAt(i);
5096                found = false;
5097                for(int j=0; j<baseUnique.size(); j++) {
5098                    if(id.equals((Unique)baseUnique.elementAt(j))) {
5099                        found = true;
5100                        break;
5101                    }
5102                }
5103            }
5104            if(!found) {
5105                throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5106                    fStringPool.toString(derivedElemName) +
5107                    " has a <unique> Identity Constraint that does not appear on the base element"+
5108                    fStringPool.toString(baseElemName));
5109            }
5110        }
5111
5112        Vector JavaDoc derivedKey = derivedElemDecl.key;
5113        Vector JavaDoc baseKey = baseElemDecl.key;
5114        if(derivedKey.size() > baseKey.size()) {
5115            throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5116                    fStringPool.toString(derivedElemName) +
5117                    " has fewer <key> Identity Constraints than the base element"+
5118                    fStringPool.toString(baseElemName));
5119        } else {
5120            boolean found = true;
5121            for(int i=0; i<derivedKey.size() && found; i++) {
5122                Key id = (Key)derivedKey.elementAt(i);
5123                found = false;
5124                for(int j=0; j<baseKey.size(); j++) {
5125                    if(id.equals((Key)baseKey.elementAt(j))) {
5126                        found = true;
5127                        break;
5128                    }
5129                }
5130            }
5131            if(!found) {
5132                throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5133                    fStringPool.toString(derivedElemName) +
5134                    " has a <key> Identity Constraint that does not appear on the base element"+
5135                    fStringPool.toString(baseElemName));
5136            }
5137        }
5138
5139        Vector JavaDoc derivedKeyRef = derivedElemDecl.keyRef;
5140        Vector JavaDoc baseKeyRef = baseElemDecl.keyRef;
5141        if(derivedKeyRef.size() > baseKeyRef.size()) {
5142            throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5143                    fStringPool.toString(derivedElemName) +
5144                    " has fewer <keyref> Identity Constraints than the base element"+
5145                    fStringPool.toString(baseElemName));
5146        } else {
5147            boolean found = true;
5148            for(int i=0; i<derivedKeyRef.size() && found; i++) {
5149                KeyRef id = (KeyRef)derivedKeyRef.elementAt(i);
5150                found = false;
5151                for(int j=0; j<baseKeyRef.size(); j++) {
5152                    if(id.equals((KeyRef)baseKeyRef.elementAt(j))) {
5153                        found = true;
5154                        break;
5155                    }
5156                }
5157            }
5158            if(!found) {
5159                throw new ParticleRecoverableError("rcase-nameAndTypeOK.5: derived element " +
5160                    fStringPool.toString(derivedElemName) +
5161                    " has a <keyref> Identity Constraint that does not appear on the base element"+
5162                    fStringPool.toString(baseElemName));
5163            }
5164        }
5165    } // checkIDConstraintRestriction
5166

5167    private boolean checkSubstitutionGroups(int local1, int uri1, int local2, int uri2)
5168throws Exception JavaDoc {
5169
5170       // check if either name is in the other's substitution group
5171
QName name1 = new QName(-1,local1,local1,uri1);
5172       QName name2 = new QName(-1,local2,local2,uri2);
5173
5174       if (fSComp.isEquivalentTo(name1,name2) ||
5175           fSComp.isEquivalentTo(name2,name1))
5176         return true;
5177       else
5178         return false;
5179
5180    }
5181    private boolean checkOccurrenceRange(int min1, int max1, int min2, int max2) {
5182
5183      if ((min1 >= min2) &&
5184          ((max2==SchemaSymbols.OCCURRENCE_UNBOUNDED) || (max1!=SchemaSymbols.OCCURRENCE_UNBOUNDED && max1<=max2)))
5185        return true;
5186      else
5187        return false;
5188    }
5189
5190    private int findElement(int scope, int uriIndex, int nameIndex, SchemaGrammar gr, ComplexTypeInfo bInfo) {
5191
5192      // check for element at given scope first
5193
int elementDeclIndex = gr.getElementDeclIndex(uriIndex,nameIndex,scope);
5194
5195      // if not found, check at global scope
5196
if (elementDeclIndex == -1) {
5197         elementDeclIndex = gr.getElementDeclIndex(nameIndex, -1);
5198
5199         // if still not found, and base is specified, look it up there
5200
if (elementDeclIndex == -1 && bInfo != null) {
5201            ComplexTypeInfo baseInfo = bInfo;
5202            while (baseInfo != null) {
5203                elementDeclIndex = gr.getElementDeclIndex(nameIndex,baseInfo.scopeDefined);
5204                if (elementDeclIndex > -1)
5205                   break;
5206                baseInfo = baseInfo.baseComplexTypeInfo;
5207            }
5208         }
5209
5210      }
5211      return elementDeclIndex;
5212    }
5213
5214    private void checkNSCompat(int csIndex1, int derivedScope, int csIndex2) throws Exception JavaDoc {
5215
5216      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
5217      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5218      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5219      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5220
5221      // check Occurrence ranges
5222
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5223        throw new ParticleRecoverableError("rcase-NSCompat.2: Element occurrence range not a restriction of base any element's range");
5224      }
5225
5226
5227      fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
5228      int uri = tempContentSpec1.otherValue;
5229
5230      // check wildcard subset
5231
if (!wildcardEltAllowsNamespace(csIndex2, uri))
5232        throw new ParticleRecoverableError("rcase-NSCompat.1: Element's namespace not allowed by wildcard in base");
5233
5234    }
5235
5236    private boolean wildcardEltAllowsNamespace(int wildcardNode, int uriIndex) {
5237
5238      fSchemaGrammar.getContentSpec(wildcardNode, tempContentSpec1);
5239      if ((tempContentSpec1.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY)
5240        return true;
5241
5242      if ((tempContentSpec1.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
5243        if (uriIndex == tempContentSpec1.otherValue)
5244           return true;
5245      }
5246      else { // must be ANY_OTHER
5247
if (uriIndex != tempContentSpec1.otherValue && uriIndex != StringPool.EMPTY_STRING)
5248            return true;
5249      }
5250
5251      return false;
5252    }
5253
5254
5255    private void checkNSSubset(int csIndex1, int csIndex2) throws Exception JavaDoc {
5256      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
5257      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5258      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5259      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5260
5261      // check Occurrence ranges
5262
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5263        throw new ParticleRecoverableError("rcase-NSSubset.2: Wildcard's occurrence range not a restriction of base wildcard's range");
5264      }
5265
5266      if (!wildcardEltSubset(csIndex1, csIndex2))
5267         throw new ParticleRecoverableError("rcase-NSSubset.1: Wildcard is not a subset of corresponding wildcard in base");
5268
5269
5270    }
5271
5272    private boolean wildcardEltSubset(int wildcardNode, int wildcardBaseNode) {
5273
5274      fSchemaGrammar.getContentSpec(wildcardNode, tempContentSpec1);
5275      fSchemaGrammar.getContentSpec(wildcardBaseNode, tempContentSpec2);
5276
5277      if ((tempContentSpec2.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY)
5278        return true;
5279
5280      if ((tempContentSpec1.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
5281        if ((tempContentSpec2.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_OTHER &&
5282            tempContentSpec1.otherValue == tempContentSpec2.otherValue)
5283           return true;
5284      }
5285
5286      if ((tempContentSpec1.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
5287        if ((tempContentSpec2.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_NS &&
5288            tempContentSpec1.otherValue == tempContentSpec2.otherValue)
5289           return true;
5290
5291        if ((tempContentSpec2.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ANY_OTHER &&
5292            tempContentSpec1.otherValue != tempContentSpec2.otherValue)
5293           return true;
5294
5295      }
5296
5297      return false;
5298    }
5299
5300    private void checkRecurseAsIfGroup(int csIndex1, int derivedScope, int csIndex2, Vector JavaDoc tempVector2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
5301
5302      fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
5303
5304       // Treat the element as if it were in a group of the same type as csindex2
5305
int indexOfGrp=fSchemaGrammar.addContentSpecNode(tempContentSpec2.type,
5306                             csIndex1,-2, false);
5307      Vector JavaDoc tmpVector = new Vector JavaDoc();
5308      tmpVector.addElement(new Integer JavaDoc(csIndex1));
5309
5310
5311      if (tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_ALL ||
5312          tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_SEQ)
5313         checkRecurse(indexOfGrp, tmpVector, derivedScope, csIndex2,
5314                      tempVector2, baseScope, bInfo);
5315      else
5316         checkRecurseLax(indexOfGrp, tmpVector, derivedScope, csIndex2,
5317                         tempVector2, baseScope, bInfo);
5318
5319      tmpVector = null;
5320    }
5321
5322    private void checkNSRecurseCheckCardinality(int csIndex1, Vector JavaDoc tempVector1, int derivedScope, int csIndex2) throws Exception JavaDoc {
5323
5324      // Implement total range check
5325
int min1 = minEffectiveTotalRange(csIndex1);
5326      int max1 = maxEffectiveTotalRange(csIndex1);
5327
5328      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5329      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5330
5331      // check Occurrence ranges
5332
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5333        throw new ParticleRecoverableError("rcase-NSSubset.2: Wildcard's occurrence range not a restriction of base wildcard's range");
5334      }
5335
5336      if (!wildcardEltSubset(csIndex1, csIndex2))
5337         throw new ParticleRecoverableError("rcase-NSSubset.1: Wildcard is not a subset of corresponding wildcard in base");
5338      // Check that each member of the group is a valid restriction of the wildcard
5339
int count = tempVector1.size();
5340      for (int i = 0; i < count; i++) {
5341         Integer JavaDoc particle1 = (Integer JavaDoc)tempVector1.elementAt(i);
5342         checkParticleDerivationOK(particle1.intValue(),derivedScope,csIndex2,-1,null);
5343      }
5344
5345    }
5346
5347    private void checkRecurse(int csIndex1, Vector JavaDoc tempVector1, int derivedScope, int csIndex2, Vector JavaDoc tempVector2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
5348
5349      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
5350      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5351      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5352      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5353
5354      // check Occurrence ranges
5355
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5356        throw new ParticleRecoverableError("rcase-Recurse.1: Occurrence range of group is not a valid restriction of occurence range of base group");
5357      }
5358
5359      int count1= tempVector1.size();
5360      int count2= tempVector2.size();
5361
5362      int current = 0;
5363      label: for (int i = 0; i<count1; i++) {
5364
5365        Integer JavaDoc particle1 = (Integer JavaDoc)tempVector1.elementAt(i);
5366        for (int j = current; j<count2; j++) {
5367           Integer JavaDoc particle2 = (Integer JavaDoc)tempVector2.elementAt(j);
5368           current +=1;
5369           try {
5370             checkParticleDerivationOK(particle1.intValue(),derivedScope,
5371                particle2.intValue(), baseScope, bInfo);
5372             continue label;
5373           }
5374           catch (ParticleRecoverableError e) {
5375             if (!particleEmptiable(particle2.intValue()))
5376                throw new ParticleRecoverableError("rcase-Recurse.2: There is not a complete functional mapping between the particles");
5377           }
5378        }
5379        throw new ParticleRecoverableError("rcase-Recurse.2: There is not a complete functional mapping between the particles");
5380      }
5381
5382      // Now, see if there are some elements in the base we didn't match up
5383
for (int j=current; j < count2; j++) {
5384        Integer JavaDoc particle2 = (Integer JavaDoc)tempVector2.elementAt(j);
5385        if (!particleEmptiable(particle2.intValue())) {
5386          throw new ParticleRecoverableError("rcase-Recurse.2: There is not a complete functional mapping between the particles");
5387        }
5388      }
5389
5390    }
5391
5392    private void checkRecurseUnordered(int csIndex1, Vector JavaDoc tempVector1, int derivedScope, int csIndex2, Vector JavaDoc tempVector2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
5393      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
5394      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5395      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5396      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5397
5398      // check Occurrence ranges
5399
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5400        throw new ParticleRecoverableError("rcase-RecurseUnordered.1: Occurrence range of group is not a valid restriction of occurence range of base group");
5401      }
5402
5403      int count1= tempVector1.size();
5404      int count2 = tempVector2.size();
5405
5406      boolean foundIt[] = new boolean[count2];
5407
5408      label: for (int i = 0; i<count1; i++) {
5409
5410        Integer JavaDoc particle1 = (Integer JavaDoc)tempVector1.elementAt(i);
5411        for (int j = 0; j<count2; j++) {
5412           Integer JavaDoc particle2 = (Integer JavaDoc)tempVector2.elementAt(j);
5413           try {
5414             checkParticleDerivationOK(particle1.intValue(),derivedScope,
5415                particle2.intValue(), baseScope, bInfo);
5416             if (foundIt[j])
5417            throw new ParticleRecoverableError("rcase-RecurseUnordered.2: There is not a complete functional mapping between the particles");
5418             else
5419                foundIt[j]=true;
5420
5421             continue label;
5422           }
5423           catch (ParticleRecoverableError e) {
5424           }
5425        }
5426        // didn't find a match. Detect an error
5427
throw new ParticleRecoverableError("rcase-RecurseUnordered.2: There is not a complete functional mapping between the particles");
5428      }
5429
5430    }
5431
5432    private void checkRecurseLax(int csIndex1, Vector JavaDoc tempVector1, int derivedScope, int csIndex2, Vector JavaDoc tempVector2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
5433
5434      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
5435      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5436      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5437      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5438
5439      // check Occurrence ranges
5440
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5441        throw new ParticleRecoverableError("rcase-RecurseLax.1: Occurrence range of group is not a valid restriction of occurence range of base group");
5442      }
5443
5444      int count1= tempVector1.size();
5445      int count2 = tempVector2.size();
5446
5447      int current = 0;
5448      label: for (int i = 0; i<count1; i++) {
5449
5450        Integer JavaDoc particle1 = (Integer JavaDoc)tempVector1.elementAt(i);
5451        for (int j = current; j<count2; j++) {
5452           Integer JavaDoc particle2 = (Integer JavaDoc)tempVector2.elementAt(j);
5453           current +=1;
5454           try {
5455             checkParticleDerivationOK(particle1.intValue(),derivedScope,
5456                particle2.intValue(), baseScope, bInfo);
5457             continue label;
5458           }
5459           catch (ParticleRecoverableError e) {
5460           }
5461        }
5462        // didn't find a match. Detect an error
5463
throw new ParticleRecoverableError("rcase-Recurse.2: There is not a complete functional mapping between the particles");
5464
5465      }
5466
5467    }
5468
5469    private void checkMapAndSum(int csIndex1, Vector JavaDoc tempVector1, int derivedScope, int csIndex2, Vector JavaDoc tempVector2, int baseScope, ComplexTypeInfo bInfo) throws Exception JavaDoc {
5470
5471      // See if the sequence group is a valid restriction of the choice
5472

5473      // Here is an example of a valid restriction:
5474
// <choice minOccurs="2">
5475
// <a/>
5476
// <b/>
5477
// <c/>
5478
// </choice>
5479
//
5480
// <sequence>
5481
// <b/>
5482
// <a/>
5483
// </sequence>
5484

5485      // check the occurrence ranges
5486
// Occurrence range for the sequence:
5487
// min1 = (length of particles) * min of sequence
5488
// max1 = (length of particles) * max of sequence (or unbounded)
5489
// min2 = minOccurs of choice
5490
// max2 = maxOccurs of choice
5491

5492      int count1 = tempVector1.size();
5493      int count2 = tempVector2.size();
5494      int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1) * count1;
5495      int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
5496      if (max1!=SchemaSymbols.OCCURRENCE_UNBOUNDED)
5497        max1 = max1 * count1;
5498      int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
5499      int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
5500
5501      // check Occurrence ranges
5502
if (!checkOccurrenceRange(min1,max1,min2,max2)) {
5503        throw new ParticleRecoverableError("rcase-MapAndSum.2: Occurrence range of group is not a valid restriction of occurence range of base group");
5504      }
5505
5506      label: for (int i = 0; i<count1; i++) {
5507
5508        Integer JavaDoc particle1 = (Integer JavaDoc)tempVector1.elementAt(i);
5509        for (int j = 0; j<count2; j++) {
5510           Integer JavaDoc particle2 = (Integer JavaDoc)tempVector2.elementAt(j);
5511           try {
5512             checkParticleDerivationOK(particle1.intValue(),derivedScope,
5513                particle2.intValue(), baseScope, bInfo);
5514
5515             continue label;
5516           }
5517           catch (ParticleRecoverableError e) {
5518           }
5519        }
5520        // didn't find a match. Detect an error
5521
throw new ParticleRecoverableError("rcase-MapAndSum.1: There is not a complete functional mapping between the particles");
5522      }
5523    }
5524
5525    private int importContentSpec(SchemaGrammar aGrammar, int contentSpecHead ) throws Exception JavaDoc {
5526        XMLContentSpec ctsp = new XMLContentSpec();
5527        aGrammar.getContentSpec(contentSpecHead, ctsp);
5528        int left = -1;
5529        int right = -1;
5530        if ( ctsp.type == XMLContentSpec.CONTENTSPECNODE_LEAF
5531             || (ctsp.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY
5532             || (ctsp.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS
5533             || (ctsp.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ) {
5534            left = fSchemaGrammar.addContentSpecNode(ctsp.type, ctsp.value, ctsp.otherValue, false);
5535        }
5536        else if (ctsp.type == -1)
5537            // case where type being extended has no content
5538
return -2;
5539        else {
5540            if ( ctsp.value == -1 ) {
5541                left = -1;
5542            }
5543            else {
5544                left = importContentSpec(aGrammar, ctsp.value);
5545            }
5546
5547            if ( ctsp.otherValue == -1 ) {
5548                right = -1;
5549            }
5550            else {
5551                right = importContentSpec(aGrammar, ctsp.otherValue);
5552            }
5553            left = fSchemaGrammar.addContentSpecNode(ctsp.type, left, right, false);
5554        }
5555
5556        if (fFullConstraintChecking) {
5557            fSchemaGrammar.setContentSpecMaxOccurs(left, aGrammar.getContentSpecMaxOccurs(contentSpecHead));
5558            fSchemaGrammar.setContentSpecMinOccurs(left, aGrammar.getContentSpecMinOccurs(contentSpecHead));
5559        }
5560        return left;
5561    }
5562
5563    private int handleOccurrences(int index,
5564                                  Element JavaDoc particle) throws Exception JavaDoc {
5565        // Pass through, indicating we're not processing an <all>
5566
return handleOccurrences(index, particle, NOT_ALL_CONTEXT);
5567    }
5568
5569    // Checks constraints for minOccurs, maxOccurs and expands content model
5570
// accordingly
5571
private int handleOccurrences(int index, Element JavaDoc particle,
5572                                  int allContextFlags) throws Exception JavaDoc {
5573
5574        // if index is invalid, return
5575
if (index < 0)
5576          return index;
5577
5578        String JavaDoc minOccurs =
5579                    particle.getAttribute(SchemaSymbols.ATT_MINOCCURS).trim();
5580        String JavaDoc maxOccurs =
5581                    particle.getAttribute(SchemaSymbols.ATT_MAXOCCURS).trim();
5582        boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
5583        boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
5584        boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
5585        boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
5586
5587        // Neither minOccurs nor maxOccurs may be specified
5588
// for the child of a model group definition.
5589
if (isGroupChild &&
5590            (minOccurs.length() != 0 || maxOccurs.length() != 0)) {
5591            Element JavaDoc group = (Element JavaDoc)particle.getParentNode();
5592            Object JavaDoc[] args = new Object JavaDoc[]{group.getAttribute(SchemaSymbols.ATT_NAME),
5593                                         particle.getNodeName()};
5594            reportSchemaError(SchemaMessageProvider.MinMaxOnGroupChild, args);
5595            minOccurs = (maxOccurs = "1");
5596        }
5597
5598        // If minOccurs=maxOccurs=0, no component is specified
5599
if(minOccurs.equals("0") && maxOccurs.equals("0")){
5600            return -2;
5601        }
5602
5603        int min=1, max=1;
5604
5605        if (minOccurs.length() == 0) {
5606            minOccurs = "1";
5607        }
5608        if (maxOccurs.length() == 0) {
5609            maxOccurs = "1";
5610        }
5611
5612        // For the elements referenced in an <all>, minOccurs attribute
5613
// must be zero or one, and maxOccurs attribute must be one.
5614
// For a complex type definition that contains an <all> or a
5615
// reference a <group> whose model group is an all model group,
5616
// minOccurs and maxOccurs must be one.
5617
if (processingAllEl || groupRefWithAll || processingAllGP) {
5618            if ((processingAllGP||groupRefWithAll||!minOccurs.equals("0")) &&
5619                 !minOccurs.equals("1")) {
5620                int minMsg;
5621
5622                if (processingAllEl) {
5623                    minMsg = SchemaMessageProvider.BadMinMaxForAllElem;
5624                }
5625                else if (processingAllGP) {
5626                    minMsg = SchemaMessageProvider.BadMinMaxForAllGp;
5627                }
5628                else {
5629                    minMsg = SchemaMessageProvider.BadMinMaxForGroupWithAll;
5630                }
5631
5632                reportSchemaError(minMsg, new Object JavaDoc [] { "minOccurs",
5633                                                          minOccurs });
5634                minOccurs = "1";
5635            }
5636
5637            if (!maxOccurs.equals("1")) {
5638                int maxMsg;
5639
5640                if (processingAllEl) {
5641                    maxMsg = SchemaMessageProvider.BadMinMaxForAllElem;
5642                }
5643                else if (processingAllGP) {
5644                    maxMsg = SchemaMessageProvider.BadMinMaxForAllGp;
5645                }
5646                else {
5647                    maxMsg = SchemaMessageProvider.BadMinMaxForGroupWithAll;
5648                }
5649
5650                reportSchemaError(maxMsg, new Object JavaDoc [] { "maxOccurs",
5651                                                          maxOccurs });
5652                maxOccurs = "1";
5653            }
5654        }
5655
5656        try {
5657            min = Integer.parseInt(minOccurs);
5658        }
5659        catch (Exception JavaDoc e){
5660            reportSchemaError(SchemaMessageProvider.GenericError,
5661                              new Object JavaDoc [] { "illegal value for minOccurs or maxOccurs : '" +e.getMessage()+ "' "});
5662        }
5663
5664        if (maxOccurs.equals("unbounded")) {
5665           max = SchemaSymbols.OCCURRENCE_UNBOUNDED;
5666        }
5667        else {
5668           try {
5669               max = Integer.parseInt(maxOccurs);
5670           }
5671           catch (Exception JavaDoc e){
5672               reportSchemaError(SchemaMessageProvider.GenericError,
5673                                new Object JavaDoc [] { "illegal value for minOccurs or maxOccurs : '" +e.getMessage()+ "' "});
5674           }
5675
5676           // Check that minOccurs isn't greater than maxOccurs.
5677
// p-props-correct 2.1
5678
if (min > max) {
5679               reportGenericSchemaError("p-props-correct:2.1 Value of minOccurs '" + minOccurs + "' must not be greater than value of maxOccurs '" + maxOccurs +"'");
5680           }
5681
5682           if (max < 1) {
5683               reportGenericSchemaError("p-props-correct:2.2 Value of maxOccurs " + maxOccurs + " is invalid. It must be greater than or equal to 1");
5684           }
5685        }
5686
5687        if (fSchemaGrammar.getDeferContentSpecExpansion()) {
5688          fSchemaGrammar.setContentSpecMinOccurs(index,min);
5689          fSchemaGrammar.setContentSpecMaxOccurs(index,max);
5690          return index;
5691        }
5692        else {
5693          return fSchemaGrammar.expandContentModel(index,min,max);
5694        }
5695
5696    }
5697
5698
5699    /**
5700     * Traverses Schema attribute declaration.
5701     *
5702     * <attribute
5703     * default = string
5704     * fixed = string
5705     * form = (qualified | unqualified)
5706     * id = ID
5707     * name = NCName
5708     * ref = QName
5709     * type = QName
5710     * use = (optional | prohibited | required) : optional
5711     * {any attributes with non-schema namespace ...}>
5712     * Content: (annotation? , simpleType?)
5713     * <attribute/>
5714     *
5715     * @param attributeDecl: the declaration of the attribute under consideration
5716     * @param typeInfo: Contains the index of the element to which the attribute declaration is attached.
5717     * @param referredTo: true iff traverseAttributeDecl was called because
5718     * of encountering a ``ref''property (used
5719     * to suppress error-reporting).
5720     * @return 0 if the attribute schema is validated successfully, otherwise -1
5721     * @exception Exception
5722     */

5723    private int traverseAttributeDecl( Element JavaDoc attrDecl, ComplexTypeInfo typeInfo, boolean referredTo ) throws Exception JavaDoc {
5724
5725        // General Attribute Checking
5726
int scope = isTopLevel(attrDecl)?
5727                    GeneralAttrCheck.ELE_CONTEXT_GLOBAL:
5728                    GeneralAttrCheck.ELE_CONTEXT_LOCAL;
5729        Hashtable JavaDoc attrValues = generalCheck(attrDecl, scope);
5730
5731        ////// Get declared fields of the attribute
5732
String JavaDoc defaultStr = attrDecl.getAttribute(SchemaSymbols.ATT_DEFAULT);
5733        String JavaDoc fixedStr = attrDecl.getAttribute(SchemaSymbols.ATT_FIXED);
5734        String JavaDoc formStr = attrDecl.getAttribute(SchemaSymbols.ATT_FORM);//form attribute
5735
String JavaDoc attNameStr = attrDecl.getAttribute(SchemaSymbols.ATT_NAME);
5736        String JavaDoc refStr = attrDecl.getAttribute(SchemaSymbols.ATT_REF);
5737        String JavaDoc datatypeStr = attrDecl.getAttribute(SchemaSymbols.ATT_TYPE);
5738        String JavaDoc useStr = attrDecl.getAttribute(SchemaSymbols.ATT_USE);
5739        Element JavaDoc simpleTypeChild = findAttributeSimpleType(attrDecl);
5740
5741        Attr JavaDoc defaultAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_DEFAULT);
5742        Attr JavaDoc fixedAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_FIXED);
5743        Attr JavaDoc formAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_FORM);
5744        Attr JavaDoc attNameAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_NAME);
5745        Attr JavaDoc refAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_REF);
5746