KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > xs > traversers > XSAttributeChecker


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2004 The Apache Software Foundation. All rights
6  * 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  *1
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) 2001, 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
58 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
59
60 import java.util.Enumeration JavaDoc;
61 import java.util.Hashtable JavaDoc;
62 import java.util.Locale JavaDoc;
63 import java.util.StringTokenizer JavaDoc;
64 import java.util.Vector JavaDoc;
65
66 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
67 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
68 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
69 import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
70 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
71 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeDecl;
72 import com.sun.org.apache.xerces.internal.impl.xs.XSGrammarBucket;
73 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
74 import com.sun.org.apache.xerces.internal.xs.XSConstants;
75 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
76 import com.sun.org.apache.xerces.internal.impl.xs.util.XIntPool;
77 import com.sun.org.apache.xerces.internal.util.DOMUtil;
78 import com.sun.org.apache.xerces.internal.util.SymbolTable;
79 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
80 import com.sun.org.apache.xerces.internal.xni.QName;
81 import org.w3c.dom.Attr JavaDoc;
82 import org.w3c.dom.Element JavaDoc;
83
84 /**
85  * Class <code>XSAttributeCheck</code> is used to check the validity of attributes
86  * appearing in the schema document. It
87  * - reports an error for invalid element (invalid namespace, invalid name)
88  * - reports an error for invalid attribute (invalid namespace, invalid name)
89  * - reports an error for invalid attribute value
90  * - return compiled values for attriute values
91  * - provide default value for missing optional attributes
92  * - provide default value for incorrect attribute values
93  *
94  * But it's the caller's responsibility to check whether a required attribute
95  * is present.
96  *
97  * Things need revisiting:
98  * - Whether to return non-schema attributes/values
99  * - Do we need to update NamespaceScope and ErrorReporter when reset()?
100  * - Should have the datatype validators return compiled value
101  * - use symbol table instead of many hashtables
102  *
103  * @author Sandy Gao, IBM
104  * @version $Id: XSAttributeChecker.java,v 1.30 2004/01/29 20:32:05 sandygao Exp $
105  */

106
107 public class XSAttributeChecker {
108
109     // REVISIT: only local element and attribute are different from others.
110
// it's possible to have either name or ref. all the others
111
// are only allowed to have one of name or ref, or neither of them.
112
// we'd better move such checking to the traverser.
113
private static final String JavaDoc ELEMENT_N = "element_n";
114     private static final String JavaDoc ELEMENT_R = "element_r";
115     private static final String JavaDoc ATTRIBUTE_N = "attribute_n";
116     private static final String JavaDoc ATTRIBUTE_R = "attribute_r";
117
118     private static int ATTIDX_COUNT = 0;
119     public static final int ATTIDX_ABSTRACT = ATTIDX_COUNT++;
120     public static final int ATTIDX_AFORMDEFAULT = ATTIDX_COUNT++;
121     public static final int ATTIDX_BASE = ATTIDX_COUNT++;
122     public static final int ATTIDX_BLOCK = ATTIDX_COUNT++;
123     public static final int ATTIDX_BLOCKDEFAULT = ATTIDX_COUNT++;
124     public static final int ATTIDX_DEFAULT = ATTIDX_COUNT++;
125     public static final int ATTIDX_EFORMDEFAULT = ATTIDX_COUNT++;
126     public static final int ATTIDX_FINAL = ATTIDX_COUNT++;
127     public static final int ATTIDX_FINALDEFAULT = ATTIDX_COUNT++;
128     public static final int ATTIDX_FIXED = ATTIDX_COUNT++;
129     public static final int ATTIDX_FORM = ATTIDX_COUNT++;
130     public static final int ATTIDX_ID = ATTIDX_COUNT++;
131     public static final int ATTIDX_ITEMTYPE = ATTIDX_COUNT++;
132     public static final int ATTIDX_MAXOCCURS = ATTIDX_COUNT++;
133     public static final int ATTIDX_MEMBERTYPES = ATTIDX_COUNT++;
134     public static final int ATTIDX_MINOCCURS = ATTIDX_COUNT++;
135     public static final int ATTIDX_MIXED = ATTIDX_COUNT++;
136     public static final int ATTIDX_NAME = ATTIDX_COUNT++;
137     public static final int ATTIDX_NAMESPACE = ATTIDX_COUNT++;
138     public static final int ATTIDX_NAMESPACE_LIST = ATTIDX_COUNT++;
139     public static final int ATTIDX_NILLABLE = ATTIDX_COUNT++;
140     public static final int ATTIDX_NONSCHEMA = ATTIDX_COUNT++;
141     public static final int ATTIDX_PROCESSCONTENTS = ATTIDX_COUNT++;
142     public static final int ATTIDX_PUBLIC = ATTIDX_COUNT++;
143     public static final int ATTIDX_REF = ATTIDX_COUNT++;
144     public static final int ATTIDX_REFER = ATTIDX_COUNT++;
145     public static final int ATTIDX_SCHEMALOCATION = ATTIDX_COUNT++;
146     public static final int ATTIDX_SOURCE = ATTIDX_COUNT++;
147     public static final int ATTIDX_SUBSGROUP = ATTIDX_COUNT++;
148     public static final int ATTIDX_SYSTEM = ATTIDX_COUNT++;
149     public static final int ATTIDX_TARGETNAMESPACE = ATTIDX_COUNT++;
150     public static final int ATTIDX_TYPE = ATTIDX_COUNT++;
151     public static final int ATTIDX_USE = ATTIDX_COUNT++;
152     public static final int ATTIDX_VALUE = ATTIDX_COUNT++;
153     public static final int ATTIDX_ENUMNSDECLS = ATTIDX_COUNT++;
154     public static final int ATTIDX_VERSION = ATTIDX_COUNT++;
155     public static final int ATTIDX_XPATH = ATTIDX_COUNT++;
156     public static final int ATTIDX_FROMDEFAULT = ATTIDX_COUNT++;
157     //public static final int ATTIDX_OTHERVALUES = ATTIDX_COUNT++;
158
public static final int ATTIDX_ISRETURNED = ATTIDX_COUNT++;
159
160     private static final XIntPool fXIntPool = new XIntPool();
161     // constants to return
162
private static final XInt INT_QUALIFIED = fXIntPool.getXInt(SchemaSymbols.FORM_QUALIFIED);
163     private static final XInt INT_UNQUALIFIED = fXIntPool.getXInt(SchemaSymbols.FORM_UNQUALIFIED);
164     private static final XInt INT_EMPTY_SET = fXIntPool.getXInt(XSConstants.DERIVATION_NONE);
165     private static final XInt INT_ANY_STRICT = fXIntPool.getXInt(XSWildcardDecl.PC_STRICT);
166     private static final XInt INT_ANY_LAX = fXIntPool.getXInt(XSWildcardDecl.PC_LAX);
167     private static final XInt INT_ANY_SKIP = fXIntPool.getXInt(XSWildcardDecl.PC_SKIP);
168     private static final XInt INT_ANY_ANY = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_ANY);
169     private static final XInt INT_ANY_LIST = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_LIST);
170     private static final XInt INT_ANY_NOT = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_NOT);
171     private static final XInt INT_USE_OPTIONAL = fXIntPool.getXInt(SchemaSymbols.USE_OPTIONAL);
172     private static final XInt INT_USE_REQUIRED = fXIntPool.getXInt(SchemaSymbols.USE_REQUIRED);
173     private static final XInt INT_USE_PROHIBITED = fXIntPool.getXInt(SchemaSymbols.USE_PROHIBITED);
174     private static final XInt INT_WS_PRESERVE = fXIntPool.getXInt(XSSimpleType.WS_PRESERVE);
175     private static final XInt INT_WS_REPLACE = fXIntPool.getXInt(XSSimpleType.WS_REPLACE);
176     private static final XInt INT_WS_COLLAPSE = fXIntPool.getXInt(XSSimpleType.WS_COLLAPSE);
177     private static final XInt INT_UNBOUNDED = fXIntPool.getXInt(SchemaSymbols.OCCURRENCE_UNBOUNDED);
178
179     // used to store the map from element name to attribute list
180
// for 14 global elements
181
private static final Hashtable JavaDoc fEleAttrsMapG = new Hashtable JavaDoc(29);
182     // for 39 local elememnts
183
private static final Hashtable JavaDoc fEleAttrsMapL = new Hashtable JavaDoc(79);
184
185     // used to initialize fEleAttrsMap
186
// step 1: all possible data types
187
// DT_??? >= 0 : validate using a validator, which is initialized staticly
188
// DT_??? < 0 : validate directly, which is done in "validate()"
189

190     protected static final int DT_ANYURI = 0;
191     protected static final int DT_ID = 1;
192     protected static final int DT_QNAME = 2;
193     protected static final int DT_STRING = 3;
194     protected static final int DT_TOKEN = 4;
195     protected static final int DT_NCNAME = 5;
196     protected static final int DT_XPATH = 6;
197     protected static final int DT_XPATH1 = 7;
198
199     // used to store extra datatype validators
200
protected static final int DT_COUNT = DT_XPATH1 + 1;
201     private static final XSSimpleType[] fExtraDVs = new XSSimpleType[DT_COUNT];
202     static {
203         // step 5: register all datatype validators for new types
204
SchemaGrammar grammar = SchemaGrammar.SG_SchemaNS;
205         // anyURI
206
fExtraDVs[DT_ANYURI] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_ANYURI);
207         // ID
208
fExtraDVs[DT_ID] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_ID);
209         // QName
210
fExtraDVs[DT_QNAME] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
211         // string
212
fExtraDVs[DT_STRING] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_STRING);
213         // token
214
fExtraDVs[DT_TOKEN] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_TOKEN);
215         // NCName
216
fExtraDVs[DT_NCNAME] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_NCNAME);
217         // xpath = a subset of XPath expression
218
fExtraDVs[DT_XPATH] = fExtraDVs[DT_STRING];
219         // xpath = a subset of XPath expression
220
fExtraDVs[DT_XPATH] = fExtraDVs[DT_STRING];
221     }
222
223     protected static final int DT_BLOCK = -1;
224     protected static final int DT_BLOCK1 = -2;
225     protected static final int DT_FINAL = -3;
226     protected static final int DT_FINAL1 = -4;
227     protected static final int DT_FINAL2 = -5;
228     protected static final int DT_FORM = -6;
229     protected static final int DT_MAXOCCURS = -7;
230     protected static final int DT_MAXOCCURS1 = -8;
231     protected static final int DT_MEMBERTYPES = -9;
232     protected static final int DT_MINOCCURS1 = -10;
233     protected static final int DT_NAMESPACE = -11;
234     protected static final int DT_PROCESSCONTENTS = -12;
235     protected static final int DT_USE = -13;
236     protected static final int DT_WHITESPACE = -14;
237     protected static final int DT_BOOLEAN = -15;
238     protected static final int DT_NONNEGINT = -16;
239     protected static final int DT_POSINT = -17;
240
241     static {
242         // step 2: all possible attributes for all elements
243
int attCount = 0;
244         int ATT_ABSTRACT_D = attCount++;
245         int ATT_ATTRIBUTE_FD_D = attCount++;
246         int ATT_BASE_R = attCount++;
247         int ATT_BASE_N = attCount++;
248         int ATT_BLOCK_N = attCount++;
249         int ATT_BLOCK1_N = attCount++;
250         int ATT_BLOCK_D_D = attCount++;
251         int ATT_DEFAULT_N = attCount++;
252         int ATT_ELEMENT_FD_D = attCount++;
253         int ATT_FINAL_N = attCount++;
254         int ATT_FINAL1_N = attCount++;
255         int ATT_FINAL_D_D = attCount++;
256         int ATT_FIXED_N = attCount++;
257         int ATT_FIXED_D = attCount++;
258         int ATT_FORM_N = attCount++;
259         int ATT_ID_N = attCount++;
260         int ATT_ITEMTYPE_N = attCount++;
261         int ATT_MAXOCCURS_D = attCount++;
262         int ATT_MAXOCCURS1_D = attCount++;
263         int ATT_MEMBER_T_N = attCount++;
264         int ATT_MINOCCURS_D = attCount++;
265         int ATT_MINOCCURS1_D = attCount++;
266         int ATT_MIXED_D = attCount++;
267         int ATT_MIXED_N = attCount++;
268         int ATT_NAME_R = attCount++;
269         int ATT_NAMESPACE_D = attCount++;
270         int ATT_NAMESPACE_N = attCount++;
271         int ATT_NILLABLE_D = attCount++;
272         int ATT_PROCESS_C_D = attCount++;
273         int ATT_PUBLIC_R = attCount++;
274         int ATT_REF_R = attCount++;
275         int ATT_REFER_R = attCount++;
276         int ATT_SCHEMA_L_R = attCount++;
277         int ATT_SCHEMA_L_N = attCount++;
278         int ATT_SOURCE_N = attCount++;
279         int ATT_SUBSTITUTION_G_N = attCount++;
280         int ATT_SYSTEM_N = attCount++;
281         int ATT_TARGET_N_N = attCount++;
282         int ATT_TYPE_N = attCount++;
283         int ATT_USE_D = attCount++;
284         int ATT_VALUE_NNI_N = attCount++;
285         int ATT_VALUE_PI_N = attCount++;
286         int ATT_VALUE_STR_N = attCount++;
287         int ATT_VALUE_WS_N = attCount++;
288         int ATT_VERSION_N = attCount++;
289         int ATT_XPATH_R = attCount++;
290         int ATT_XPATH1_R = attCount++;
291
292         // step 3: store all these attributes in an array
293
OneAttr[] allAttrs = new OneAttr[attCount];
294         allAttrs[ATT_ABSTRACT_D] = new OneAttr(SchemaSymbols.ATT_ABSTRACT,
295                                                         DT_BOOLEAN,
296                                                         ATTIDX_ABSTRACT,
297                                                         Boolean.FALSE);
298         allAttrs[ATT_ATTRIBUTE_FD_D] = new OneAttr(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT,
299                                                         DT_FORM,
300                                                         ATTIDX_AFORMDEFAULT,
301                                                         INT_UNQUALIFIED);
302         allAttrs[ATT_BASE_R] = new OneAttr(SchemaSymbols.ATT_BASE,
303                                                         DT_QNAME,
304                                                         ATTIDX_BASE,
305                                                         null);
306         allAttrs[ATT_BASE_N] = new OneAttr(SchemaSymbols.ATT_BASE,
307                                                         DT_QNAME,
308                                                         ATTIDX_BASE,
309                                                         null);
310         allAttrs[ATT_BLOCK_N] = new OneAttr(SchemaSymbols.ATT_BLOCK,
311                                                         DT_BLOCK,
312                                                         ATTIDX_BLOCK,
313                                                         null);
314         allAttrs[ATT_BLOCK1_N] = new OneAttr(SchemaSymbols.ATT_BLOCK,
315                                                         DT_BLOCK1,
316                                                         ATTIDX_BLOCK,
317                                                         null);
318         allAttrs[ATT_BLOCK_D_D] = new OneAttr(SchemaSymbols.ATT_BLOCKDEFAULT,
319                                                         DT_BLOCK,
320                                                         ATTIDX_BLOCKDEFAULT,
321                                                         INT_EMPTY_SET);
322         allAttrs[ATT_DEFAULT_N] = new OneAttr(SchemaSymbols.ATT_DEFAULT,
323                                                         DT_STRING,
324                                                         ATTIDX_DEFAULT,
325                                                         null);
326         allAttrs[ATT_ELEMENT_FD_D] = new OneAttr(SchemaSymbols.ATT_ELEMENTFORMDEFAULT,
327                                                         DT_FORM,
328                                                         ATTIDX_EFORMDEFAULT,
329                                                         INT_UNQUALIFIED);
330         allAttrs[ATT_FINAL_N] = new OneAttr(SchemaSymbols.ATT_FINAL,
331                                                         DT_FINAL,
332                                                         ATTIDX_FINAL,
333                                                         null);
334         allAttrs[ATT_FINAL1_N] = new OneAttr(SchemaSymbols.ATT_FINAL,
335                                                         DT_FINAL1,
336                                                         ATTIDX_FINAL,
337                                                         null);
338         allAttrs[ATT_FINAL_D_D] = new OneAttr(SchemaSymbols.ATT_FINALDEFAULT,
339                                                         DT_FINAL2,
340                                                         ATTIDX_FINALDEFAULT,
341                                                         INT_EMPTY_SET);
342         allAttrs[ATT_FIXED_N] = new OneAttr(SchemaSymbols.ATT_FIXED,
343                                                         DT_STRING,
344                                                         ATTIDX_FIXED,
345                                                         null);
346         allAttrs[ATT_FIXED_D] = new OneAttr(SchemaSymbols.ATT_FIXED,
347                                                         DT_BOOLEAN,
348                                                         ATTIDX_FIXED,
349                                                         Boolean.FALSE);
350         allAttrs[ATT_FORM_N] = new OneAttr(SchemaSymbols.ATT_FORM,
351                                                         DT_FORM,
352                                                         ATTIDX_FORM,
353                                                         null);
354         allAttrs[ATT_ID_N] = new OneAttr(SchemaSymbols.ATT_ID,
355                                                         DT_ID,
356                                                         ATTIDX_ID,
357                                                         null);
358         allAttrs[ATT_ITEMTYPE_N] = new OneAttr(SchemaSymbols.ATT_ITEMTYPE,
359                                                         DT_QNAME,
360                                                         ATTIDX_ITEMTYPE,
361                                                         null);
362         allAttrs[ATT_MAXOCCURS_D] = new OneAttr(SchemaSymbols.ATT_MAXOCCURS,
363                                                         DT_MAXOCCURS,
364                                                         ATTIDX_MAXOCCURS,
365                                                         fXIntPool.getXInt(1));
366         allAttrs[ATT_MAXOCCURS1_D] = new OneAttr(SchemaSymbols.ATT_MAXOCCURS,
367                                                         DT_MAXOCCURS1,
368                                                         ATTIDX_MAXOCCURS,
369                                                         fXIntPool.getXInt(1));
370         allAttrs[ATT_MEMBER_T_N] = new OneAttr(SchemaSymbols.ATT_MEMBERTYPES,
371                                                         DT_MEMBERTYPES,
372                                                         ATTIDX_MEMBERTYPES,
373                                                         null);
374         allAttrs[ATT_MINOCCURS_D] = new OneAttr(SchemaSymbols.ATT_MINOCCURS,
375                                                         DT_NONNEGINT,
376                                                         ATTIDX_MINOCCURS,
377                                                         fXIntPool.getXInt(1));
378         allAttrs[ATT_MINOCCURS1_D] = new OneAttr(SchemaSymbols.ATT_MINOCCURS,
379                                                         DT_MINOCCURS1,
380                                                         ATTIDX_MINOCCURS,
381                                                         fXIntPool.getXInt(1));
382         allAttrs[ATT_MIXED_D] = new OneAttr(SchemaSymbols.ATT_MIXED,
383                                                         DT_BOOLEAN,
384                                                         ATTIDX_MIXED,
385                                                         Boolean.FALSE);
386         allAttrs[ATT_MIXED_N] = new OneAttr(SchemaSymbols.ATT_MIXED,
387                                                         DT_BOOLEAN,
388                                                         ATTIDX_MIXED,
389                                                         null);
390         allAttrs[ATT_NAME_R] = new OneAttr(SchemaSymbols.ATT_NAME,
391                                                         DT_NCNAME,
392                                                         ATTIDX_NAME,
393                                                         null);
394         allAttrs[ATT_NAMESPACE_D] = new OneAttr(SchemaSymbols.ATT_NAMESPACE,
395                                                         DT_NAMESPACE,
396                                                         ATTIDX_NAMESPACE,
397                                                         INT_ANY_ANY);
398         allAttrs[ATT_NAMESPACE_N] = new OneAttr(SchemaSymbols.ATT_NAMESPACE,
399                                                         DT_ANYURI,
400                                                         ATTIDX_NAMESPACE,
401                                                         null);
402         allAttrs[ATT_NILLABLE_D] = new OneAttr(SchemaSymbols.ATT_NILLABLE,
403                                                         DT_BOOLEAN,
404                                                         ATTIDX_NILLABLE,
405                                                         Boolean.FALSE);
406         allAttrs[ATT_PROCESS_C_D] = new OneAttr(SchemaSymbols.ATT_PROCESSCONTENTS,
407                                                         DT_PROCESSCONTENTS,
408                                                         ATTIDX_PROCESSCONTENTS,
409                                                         INT_ANY_STRICT);
410         allAttrs[ATT_PUBLIC_R] = new OneAttr(SchemaSymbols.ATT_PUBLIC,
411                                                         DT_TOKEN,
412                                                         ATTIDX_PUBLIC,
413                                                         null);
414         allAttrs[ATT_REF_R] = new OneAttr(SchemaSymbols.ATT_REF,
415                                                         DT_QNAME,
416                                                         ATTIDX_REF,
417                                                         null);
418         allAttrs[ATT_REFER_R] = new OneAttr(SchemaSymbols.ATT_REFER,
419                                                         DT_QNAME,
420                                                         ATTIDX_REFER,
421                                                         null);
422         allAttrs[ATT_SCHEMA_L_R] = new OneAttr(SchemaSymbols.ATT_SCHEMALOCATION,
423                                                         DT_ANYURI,
424                                                         ATTIDX_SCHEMALOCATION,
425                                                         null);
426         allAttrs[ATT_SCHEMA_L_N] = new OneAttr(SchemaSymbols.ATT_SCHEMALOCATION,
427                                                         DT_ANYURI,
428                                                         ATTIDX_SCHEMALOCATION,
429                                                         null);
430         allAttrs[ATT_SOURCE_N] = new OneAttr(SchemaSymbols.ATT_SOURCE,
431                                                         DT_ANYURI,
432                                                         ATTIDX_SOURCE,
433                                                         null);
434         allAttrs[ATT_SUBSTITUTION_G_N] = new OneAttr(SchemaSymbols.ATT_SUBSTITUTIONGROUP,
435                                                         DT_QNAME,
436                                                         ATTIDX_SUBSGROUP,
437                                                         null);
438         allAttrs[ATT_SYSTEM_N] = new OneAttr(SchemaSymbols.ATT_SYSTEM,
439                                                         DT_ANYURI,
440                                                         ATTIDX_SYSTEM,
441                                                         null);
442         allAttrs[ATT_TARGET_N_N] = new OneAttr(SchemaSymbols.ATT_TARGETNAMESPACE,
443                                                         DT_ANYURI,
444                                                         ATTIDX_TARGETNAMESPACE,
445                                                         null);
446         allAttrs[ATT_TYPE_N] = new OneAttr(SchemaSymbols.ATT_TYPE,
447                                                         DT_QNAME,
448                                                         ATTIDX_TYPE,
449                                                         null);
450         allAttrs[ATT_USE_D] = new OneAttr(SchemaSymbols.ATT_USE,
451                                                         DT_USE,
452                                                         ATTIDX_USE,
453                                                         INT_USE_OPTIONAL);
454         allAttrs[ATT_VALUE_NNI_N] = new OneAttr(SchemaSymbols.ATT_VALUE,
455                                                         DT_NONNEGINT,
456                                                         ATTIDX_VALUE,
457                                                         null);
458         allAttrs[ATT_VALUE_PI_N] = new OneAttr(SchemaSymbols.ATT_VALUE,
459                                                         DT_POSINT,
460                                                         ATTIDX_VALUE,
461                                                         null);
462         allAttrs[ATT_VALUE_STR_N] = new OneAttr(SchemaSymbols.ATT_VALUE,
463                                                         DT_STRING,
464                                                         ATTIDX_VALUE,
465                                                         null);
466         allAttrs[ATT_VALUE_WS_N] = new OneAttr(SchemaSymbols.ATT_VALUE,
467                                                         DT_WHITESPACE,
468                                                         ATTIDX_VALUE,
469                                                         null);
470         allAttrs[ATT_VERSION_N] = new OneAttr(SchemaSymbols.ATT_VERSION,
471                                                         DT_TOKEN,
472                                                         ATTIDX_VERSION,
473                                                         null);
474         allAttrs[ATT_XPATH_R] = new OneAttr(SchemaSymbols.ATT_XPATH,
475                                                         DT_XPATH,
476                                                         ATTIDX_XPATH,
477                                                         null);
478         allAttrs[ATT_XPATH1_R] = new OneAttr(SchemaSymbols.ATT_XPATH,
479                                                         DT_XPATH1,
480                                                         ATTIDX_XPATH,
481                                                         null);
482
483         // step 4: for each element, make a list of possible attributes
484
Container attrList;
485         OneElement oneEle;
486
487         // for element "attribute" - global
488
attrList = Container.getContainer(5);
489         // default = string
490
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
491         // fixed = string
492
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
493         // id = ID
494
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
495         // name = NCName
496
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
497         // type = QName
498
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
499         oneEle = new OneElement (attrList);
500         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTE, oneEle);
501
502         // for element "attribute" - local name
503
attrList = Container.getContainer(7);
504         // default = string
505
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
506         // fixed = string
507
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
508         // form = (qualified | unqualified)
509
attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
510         // id = ID
511
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
512         // name = NCName
513
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
514         // type = QName
515
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
516         // use = (optional | prohibited | required) : optional
517
attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
518         oneEle = new OneElement (attrList);
519         fEleAttrsMapL.put(ATTRIBUTE_N, oneEle);
520
521         // for element "attribute" - local ref
522
attrList = Container.getContainer(5);
523         // default = string
524
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
525         // fixed = string
526
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
527         // id = ID
528
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
529         // ref = QName
530
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
531         // use = (optional | prohibited | required) : optional
532
attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
533         oneEle = new OneElement (attrList);
534         fEleAttrsMapL.put(ATTRIBUTE_R, oneEle);
535
536         // for element "element" - global
537
attrList = Container.getContainer(10);
538         // abstract = boolean : false
539
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
540         // block = (#all | List of (substitution | extension | restriction | list | union))
541
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
542         // default = string
543
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
544         // final = (#all | List of (extension | restriction))
545
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
546         // fixed = string
547
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
548         // id = ID
549
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
550         // name = NCName
551
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
552         // nillable = boolean : false
553
attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
554         // substitutionGroup = QName
555
attrList.put(SchemaSymbols.ATT_SUBSTITUTIONGROUP, allAttrs[ATT_SUBSTITUTION_G_N]);
556         // type = QName
557
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
558         oneEle = new OneElement (attrList);
559         fEleAttrsMapG.put(SchemaSymbols.ELT_ELEMENT, oneEle);
560
561         // for element "element" - local name
562
attrList = Container.getContainer(10);
563         // block = (#all | List of (substitution | extension | restriction | list | union))
564
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
565         // default = string
566
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
567         // fixed = string
568
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
569         // form = (qualified | unqualified)
570
attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
571         // id = ID
572
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
573         // maxOccurs = (nonNegativeInteger | unbounded) : 1
574
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
575         // minOccurs = nonNegativeInteger : 1
576
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
577         // name = NCName
578
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
579         // nillable = boolean : false
580
attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
581         // type = QName
582
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
583         oneEle = new OneElement (attrList);
584         fEleAttrsMapL.put(ELEMENT_N, oneEle);
585
586         // for element "element" - local ref
587
attrList = Container.getContainer(4);
588         // id = ID
589
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
590         // maxOccurs = (nonNegativeInteger | unbounded) : 1
591
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
592         // minOccurs = nonNegativeInteger : 1
593
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
594         // ref = QName
595
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
596         oneEle = new OneElement (attrList);
597         fEleAttrsMapL.put(ELEMENT_R, oneEle);
598
599         // for element "complexType" - global
600
attrList = Container.getContainer(6);
601         // abstract = boolean : false
602
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
603         // block = (#all | List of (extension | restriction))
604
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK1_N]);
605         // final = (#all | List of (extension | restriction))
606
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
607         // id = ID
608
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
609         // mixed = boolean : false
610
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
611         // name = NCName
612
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
613         oneEle = new OneElement (attrList);
614         fEleAttrsMapG.put(SchemaSymbols.ELT_COMPLEXTYPE, oneEle);
615
616         // for element "notation" - global
617
attrList = Container.getContainer(4);
618         // id = ID
619
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
620         // name = NCName
621
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
622         // public = A public identifier, per ISO 8879
623
attrList.put(SchemaSymbols.ATT_PUBLIC, allAttrs[ATT_PUBLIC_R]);
624         // system = anyURI
625
attrList.put(SchemaSymbols.ATT_SYSTEM, allAttrs[ATT_SYSTEM_N]);
626         oneEle = new OneElement (attrList);
627         fEleAttrsMapG.put(SchemaSymbols.ELT_NOTATION, oneEle);
628
629
630         // for element "complexType" - local
631
attrList = Container.getContainer(2);
632         // id = ID
633
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
634         // mixed = boolean : false
635
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
636         oneEle = new OneElement (attrList);
637         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXTYPE, oneEle);
638
639         // for element "simpleContent" - local
640
attrList = Container.getContainer(1);
641         // id = ID
642
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
643         oneEle = new OneElement (attrList);
644         fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLECONTENT, oneEle);
645
646         // for element "restriction" - local
647
attrList = Container.getContainer(2);
648         // base = QName
649
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_N]);
650         // id = ID
651
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
652         oneEle = new OneElement (attrList);
653         fEleAttrsMapL.put(SchemaSymbols.ELT_RESTRICTION, oneEle);
654
655         // for element "extension" - local
656
attrList = Container.getContainer(2);
657         // base = QName
658
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_R]);
659         // id = ID
660
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
661         oneEle = new OneElement (attrList);
662         fEleAttrsMapL.put(SchemaSymbols.ELT_EXTENSION, oneEle);
663
664         // for element "attributeGroup" - local ref
665
attrList = Container.getContainer(2);
666         // id = ID
667
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
668         // ref = QName
669
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
670         oneEle = new OneElement (attrList);
671         fEleAttrsMapL.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, oneEle);
672
673         // for element "anyAttribute" - local
674
attrList = Container.getContainer(3);
675         // id = ID
676
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
677         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
678
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
679         // processContents = (lax | skip | strict) : strict
680
attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
681         oneEle = new OneElement (attrList);
682         fEleAttrsMapL.put(SchemaSymbols.ELT_ANYATTRIBUTE, oneEle);
683
684         // for element "complexContent" - local
685
attrList = Container.getContainer(2);
686         // id = ID
687
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
688         // mixed = boolean
689
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_N]);
690         oneEle = new OneElement (attrList);
691         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXCONTENT, oneEle);
692
693         // for element "attributeGroup" - global
694
attrList = Container.getContainer(2);
695         // id = ID
696
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
697         // name = NCName
698
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
699         oneEle = new OneElement (attrList);
700         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, oneEle);
701
702         // for element "group" - global
703
attrList = Container.getContainer(2);
704         // id = ID
705
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
706         // name = NCName
707
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
708         oneEle = new OneElement (attrList);
709         fEleAttrsMapG.put(SchemaSymbols.ELT_GROUP, oneEle);
710
711         // for element "group" - local ref
712
attrList = Container.getContainer(4);
713         // id = ID
714
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
715         // maxOccurs = (nonNegativeInteger | unbounded) : 1
716
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
717         // minOccurs = nonNegativeInteger : 1
718
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
719         // ref = QName
720
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
721         oneEle = new OneElement (attrList);
722         fEleAttrsMapL.put(SchemaSymbols.ELT_GROUP, oneEle);
723
724         // for element "all" - local
725
attrList = Container.getContainer(3);
726         // id = ID
727
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
728         // maxOccurs = 1 : 1
729
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS1_D]);
730         // minOccurs = (0 | 1) : 1
731
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS1_D]);
732         oneEle = new OneElement (attrList);
733         fEleAttrsMapL.put(SchemaSymbols.ELT_ALL, oneEle);
734
735         // for element "choice" - local
736
attrList = Container.getContainer(3);
737         // id = ID
738
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
739         // maxOccurs = (nonNegativeInteger | unbounded) : 1
740
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
741         // minOccurs = nonNegativeInteger : 1
742
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
743         oneEle = new OneElement (attrList);
744         fEleAttrsMapL.put(SchemaSymbols.ELT_CHOICE, oneEle);
745         // for element "sequence" - local
746
fEleAttrsMapL.put(SchemaSymbols.ELT_SEQUENCE, oneEle);
747
748         // for element "any" - local
749
attrList = Container.getContainer(5);
750         // id = ID
751
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
752         // maxOccurs = (nonNegativeInteger | unbounded) : 1
753
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
754         // minOccurs = nonNegativeInteger : 1
755
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
756         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
757
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
758         // processContents = (lax | skip | strict) : strict
759
attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
760         oneEle = new OneElement (attrList);
761         fEleAttrsMapL.put(SchemaSymbols.ELT_ANY, oneEle);
762
763         // for element "unique" - local
764
attrList = Container.getContainer(2);
765         // id = ID
766
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
767         // name = NCName
768
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
769         oneEle = new OneElement (attrList);
770         fEleAttrsMapL.put(SchemaSymbols.ELT_UNIQUE, oneEle);
771         // for element "key" - local
772
fEleAttrsMapL.put(SchemaSymbols.ELT_KEY, oneEle);
773
774         // for element "keyref" - local
775
attrList = Container.getContainer(3);
776         // id = ID
777
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
778         // name = NCName
779
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
780         // refer = QName
781
attrList.put(SchemaSymbols.ATT_REFER, allAttrs[ATT_REFER_R]);
782         oneEle = new OneElement (attrList);
783         fEleAttrsMapL.put(SchemaSymbols.ELT_KEYREF, oneEle);
784
785         // for element "selector" - local
786
attrList = Container.getContainer(2);
787         // id = ID
788
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
789         // xpath = a subset of XPath expression
790
attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH_R]);
791         oneEle = new OneElement (attrList);
792         fEleAttrsMapL.put(SchemaSymbols.ELT_SELECTOR, oneEle);
793
794         // for element "field" - local
795
attrList = Container.getContainer(2);
796         // id = ID
797
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
798         // xpath = a subset of XPath expression
799
attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH1_R]);
800         oneEle = new OneElement (attrList);
801         fEleAttrsMapL.put(SchemaSymbols.ELT_FIELD, oneEle);
802
803         // for element "annotation" - global
804
attrList = Container.getContainer(1);
805         // id = ID
806
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
807         oneEle = new OneElement (attrList);
808         fEleAttrsMapG.put(SchemaSymbols.ELT_ANNOTATION, oneEle);
809         // for element "annotation" - local
810
fEleAttrsMapL.put(SchemaSymbols.ELT_ANNOTATION, oneEle);
811
812         // for element "appinfo" - local
813
attrList = Container.getContainer(1);
814         // source = anyURI
815
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
816         oneEle = new OneElement (attrList, false);
817         fEleAttrsMapG.put(SchemaSymbols.ELT_APPINFO, oneEle);
818         fEleAttrsMapL.put(SchemaSymbols.ELT_APPINFO, oneEle);
819
820         // for element "documentation" - local
821
attrList = Container.getContainer(1);
822         // source = anyURI
823
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
824         // xml:lang = language ???
825
oneEle = new OneElement (attrList, false);
826         fEleAttrsMapG.put(SchemaSymbols.ELT_DOCUMENTATION, oneEle);
827         fEleAttrsMapL.put(SchemaSymbols.ELT_DOCUMENTATION, oneEle);
828
829         // for element "simpleType" - global
830
attrList = Container.getContainer(3);
831         // final = (#all | List of (list | union | restriction))
832
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
833         // id = ID
834
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
835         // name = NCName
836
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
837         oneEle = new OneElement (attrList);
838         fEleAttrsMapG.put(SchemaSymbols.ELT_SIMPLETYPE, oneEle);
839
840         // for element "simpleType" - local
841
attrList = Container.getContainer(2);
842         // final = (#all | List of (list | union | restriction))
843
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
844         // id = ID
845
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
846         oneEle = new OneElement (attrList);
847         fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLETYPE, oneEle);
848
849         // for element "restriction" - local
850
// already registered for complexType
851

852         // for element "list" - local
853
attrList = Container.getContainer(2);
854         // id = ID
855
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
856         // itemType = QName
857
attrList.put(SchemaSymbols.ATT_ITEMTYPE, allAttrs[ATT_ITEMTYPE_N]);
858         oneEle = new OneElement (attrList);
859         fEleAttrsMapL.put(SchemaSymbols.ELT_LIST, oneEle);
860
861         // for element "union" - local
862
attrList = Container.getContainer(2);
863         // id = ID
864
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
865         // memberTypes = List of QName
866
attrList.put(SchemaSymbols.ATT_MEMBERTYPES, allAttrs[ATT_MEMBER_T_N]);
867         oneEle = new OneElement (attrList);
868         fEleAttrsMapL.put(SchemaSymbols.ELT_UNION, oneEle);
869
870         // for element "schema" - global
871
attrList = Container.getContainer(7);
872         // attributeFormDefault = (qualified | unqualified) : unqualified
873
attrList.put(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT, allAttrs[ATT_ATTRIBUTE_FD_D]);
874         // blockDefault = (#all | List of (substitution | extension | restriction | list | union)) : ''
875
attrList.put(SchemaSymbols.ATT_BLOCKDEFAULT, allAttrs[ATT_BLOCK_D_D]);
876         // elementFormDefault = (qualified | unqualified) : unqualified
877
attrList.put(SchemaSymbols.ATT_ELEMENTFORMDEFAULT, allAttrs[ATT_ELEMENT_FD_D]);
878         // finalDefault = (#all | List of (extension | restriction | list | union)) : ''
879
attrList.put(SchemaSymbols.ATT_FINALDEFAULT, allAttrs[ATT_FINAL_D_D]);
880         // id = ID
881
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
882         // targetNamespace = anyURI
883
attrList.put(SchemaSymbols.ATT_TARGETNAMESPACE, allAttrs[ATT_TARGET_N_N]);
884         // version = token
885
attrList.put(SchemaSymbols.ATT_VERSION, allAttrs[ATT_VERSION_N]);
886         // xml:lang = language ???
887
oneEle = new OneElement (attrList);
888         fEleAttrsMapG.put(SchemaSymbols.ELT_SCHEMA, oneEle);
889
890         // for element "include" - global
891
attrList = Container.getContainer(2);
892         // id = ID
893
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
894         // schemaLocation = anyURI
895
attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_R]);
896         oneEle = new OneElement (attrList);
897         fEleAttrsMapG.put(SchemaSymbols.ELT_INCLUDE, oneEle);
898         // for element "redefine" - global
899
fEleAttrsMapG.put(SchemaSymbols.ELT_REDEFINE, oneEle);
900
901         // for element "import" - global
902
attrList = Container.getContainer(3);
903         // id = ID
904
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
905         // namespace = anyURI
906
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_N]);
907         // schemaLocation = anyURI
908
attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_N]);
909         oneEle = new OneElement (attrList);
910         fEleAttrsMapG.put(SchemaSymbols.ELT_IMPORT, oneEle);
911
912         // for element "length" - local
913
attrList = Container.getContainer(3);
914         // id = ID
915
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
916         // value = nonNegativeInteger
917
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_NNI_N]);
918         // fixed = boolean : false
919
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
920         oneEle = new OneElement (attrList);
921         fEleAttrsMapL.put(SchemaSymbols.ELT_LENGTH, oneEle);
922         // for element "minLength" - local
923
fEleAttrsMapL.put(SchemaSymbols.ELT_MINLENGTH, oneEle);
924         // for element "maxLength" - local
925
fEleAttrsMapL.put(SchemaSymbols.ELT_MAXLENGTH, oneEle);
926         // for element "fractionDigits" - local
927
fEleAttrsMapL.put(SchemaSymbols.ELT_FRACTIONDIGITS, oneEle);
928
929         // for element "totalDigits" - local
930
attrList = Container.getContainer(3);
931         // id = ID
932
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
933         // value = positiveInteger
934
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_PI_N]);
935         // fixed = boolean : false
936
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
937         oneEle = new OneElement (attrList);
938         fEleAttrsMapL.put(SchemaSymbols.ELT_TOTALDIGITS, oneEle);
939
940         // for element "pattern" - local
941
attrList = Container.getContainer(2);
942         // id = ID
943
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
944         // value = string
945
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
946         oneEle = new OneElement (attrList);
947         fEleAttrsMapL.put(SchemaSymbols.ELT_PATTERN, oneEle);
948
949         // for element "enumeration" - local
950
attrList = Container.getContainer(2);
951         // id = ID
952
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
953         // value = anySimpleType
954
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
955         oneEle = new OneElement (attrList);
956         fEleAttrsMapL.put(SchemaSymbols.ELT_ENUMERATION, oneEle);
957
958         // for element "whiteSpace" - local
959
attrList = Container.getContainer(3);
960         // id = ID
961
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
962         // value = preserve | replace | collapse
963
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_WS_N]);
964         // fixed = boolean : false
965
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
966         oneEle = new OneElement (attrList);
967         fEleAttrsMapL.put(SchemaSymbols.ELT_WHITESPACE, oneEle);
968
969         // for element "maxInclusive" - local
970
attrList = Container.getContainer(3);
971         // id = ID
972
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
973         // value = anySimpleType
974
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
975         // fixed = boolean : false
976
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
977         oneEle = new OneElement (attrList);
978         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXINCLUSIVE, oneEle);
979         // for element "maxExclusive" - local
980
fEleAttrsMapL.put(SchemaSymbols.ELT_MAXEXCLUSIVE, oneEle);
981         // for element "minInclusive" - local
982
fEleAttrsMapL.put(SchemaSymbols.ELT_MININCLUSIVE, oneEle);
983         // for element "minExclusive" - local
984
fEleAttrsMapL.put(SchemaSymbols.ELT_MINEXCLUSIVE, oneEle);
985     }
986
987     // used to resolver namespace prefixes
988
protected XSDHandler fSchemaHandler = null;
989
990     // used to store symbols.
991
protected SymbolTable fSymbolTable = null;
992
993     // used to store the mapping from processed element to attributes
994
protected Hashtable JavaDoc fNonSchemaAttrs = new Hashtable JavaDoc();
995
996     // temprory vector, used to hold the namespace list
997
protected Vector JavaDoc fNamespaceList = new Vector JavaDoc();
998
999     // whether this attribute appeared in the current element
1000
protected boolean[] fSeen = new boolean[ATTIDX_COUNT];
1001    private static boolean[] fSeenTemp = new boolean[ATTIDX_COUNT];
1002
1003    // constructor. Sets fErrorReproter and get datatype validators
1004
public XSAttributeChecker(XSDHandler schemaHandler) {
1005        fSchemaHandler = schemaHandler;
1006    }
1007
1008    public void reset(SymbolTable symbolTable) {
1009        fSymbolTable = symbolTable;
1010        fNonSchemaAttrs.clear();
1011    }
1012
1013    /**
1014     * check whether the specified element conforms to the attributes restriction
1015     * an array of attribute values is returned. the caller must call
1016     * <code>returnAttrArray</code> to return that array.
1017     *
1018     * @param element - which element to check
1019     * @param isGlobal - whether a child of <schema> or <redefine>
1020     * @param schemaDoc - the document where the element lives in
1021     * @return an array containing attribute values
1022     */

1023    public Object JavaDoc[] checkAttributes(Element JavaDoc element, boolean isGlobal,
1024                                    XSDocumentInfo schemaDoc) {
1025        return checkAttributes(element, isGlobal, schemaDoc, false);
1026    }
1027
1028    /**
1029     * check whether the specified element conforms to the attributes restriction
1030     * an array of attribute values is returned. the caller must call
1031     * <code>returnAttrArray</code> to return that array. This method also takes
1032     * an extra parameter: if the element is "enumeration", whether to make a
1033     * copy of the namespace context, so that the value can be resolved as a
1034     * QName later.
1035     *
1036     * @param element - which element to check
1037     * @param isGlobal - whether a child of <schema> or <redefine>
1038     * @param schemaDoc - the document where the element lives in
1039     * @param enumAsQName- whether to tread enumeration value as QName
1040     * @return an array containing attribute values
1041     */

1042    public Object JavaDoc[] checkAttributes(Element JavaDoc element, boolean isGlobal,
1043                                    XSDocumentInfo schemaDoc, boolean enumAsQName) {
1044        if (element == null)
1045            return null;
1046
1047        // get all attributes
1048
Attr JavaDoc[] attrs = DOMUtil.getAttrs(element);
1049
1050        // update NamespaceSupport
1051
resolveNamespace(element, attrs, schemaDoc.fNamespaceSupport);
1052
1053        String JavaDoc uri = DOMUtil.getNamespaceURI(element);
1054        String JavaDoc elName = DOMUtil.getLocalName(element);
1055
1056        if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(uri)) {
1057            reportSchemaError("s4s-elt-schema-ns", new Object JavaDoc[] {elName}, element);
1058        }
1059
1060        Hashtable JavaDoc eleAttrsMap = fEleAttrsMapG;
1061        String JavaDoc lookupName = elName;
1062
1063        // REVISIT: only local element and attribute are different from others.
1064
// it's possible to have either name or ref. all the others
1065
// are only allowed to have one of name or ref, or neither of them.
1066
// we'd better move such checking to the traverser.
1067
if (!isGlobal) {
1068            eleAttrsMap = fEleAttrsMapL;
1069            if (elName.equals(SchemaSymbols.ELT_ELEMENT)) {
1070                if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1071                    lookupName = ELEMENT_R;
1072                else
1073                    lookupName = ELEMENT_N;
1074            } else if (elName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1075                if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1076                    lookupName = ATTRIBUTE_R;
1077                else
1078                    lookupName = ATTRIBUTE_N;
1079            }
1080        }
1081
1082        // get desired attribute list of this element
1083
OneElement oneEle = (OneElement)eleAttrsMap.get(lookupName);
1084        if (oneEle == null) {
1085            // should never gets here.
1086
// when this method is called, the call already knows that
1087
// the element can appear.
1088
reportSchemaError ("s4s-elt-invalid", new Object JavaDoc[] {elName}, element);
1089            return null;
1090        }
1091
1092        //Hashtable attrValues = new Hashtable();
1093
Object JavaDoc[] attrValues = getAvailableArray();
1094        //Hashtable otherValues = new Hashtable();
1095
long fromDefault = 0;
1096        Container attrList = oneEle.attrList;
1097        
1098        // clear the "seen" flag.
1099
System.arraycopy(fSeenTemp, 0, fSeen, 0, ATTIDX_COUNT);
1100
1101        // traverse all attributes
1102
int length = attrs.length;
1103        Attr JavaDoc sattr = null;
1104        for (int i = 0; i < length; i++) {
1105            sattr = attrs[i];
1106            // get the attribute name/value
1107
//String attrName = DOMUtil.getLocalName(sattr);
1108
String JavaDoc attrName = sattr.getName();
1109            String JavaDoc attrVal = DOMUtil.getValue(sattr);
1110
1111            // we don't want to add namespace declarations to the non-schema attributes
1112
if (attrName.startsWith("xmlns")) {
1113                continue;
1114            }
1115            
1116            // skip anything starts with x/X m/M l/L
1117
// add this to the list of "non-schema" attributes
1118
if (attrName.toLowerCase(Locale.ENGLISH).startsWith("xml")) {
1119                if(attrValues[ATTIDX_NONSCHEMA] == null) {
1120                    // these are usually small
1121
attrValues[ATTIDX_NONSCHEMA] = new Vector JavaDoc(4,2);
1122                }
1123                ((Vector JavaDoc)attrValues[ATTIDX_NONSCHEMA]).addElement(attrName);
1124                ((Vector JavaDoc)attrValues[ATTIDX_NONSCHEMA]).addElement(attrVal);
1125                //otherValues.put(attrName, attrVal);
1126
continue;
1127            }
1128
1129            // for attributes with namespace prefix
1130
//
1131
String JavaDoc attrURI = DOMUtil.getNamespaceURI(sattr);
1132            if (attrURI != null && attrURI.length() != 0) {
1133                // attributes with schema namespace are not allowed
1134
// and not allowed on "document" and "appInfo"
1135
if (attrURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ||
1136                    !oneEle.allowNonSchemaAttr) {
1137                    reportSchemaError ("s4s-att-not-allowed", new Object JavaDoc[] {elName, attrName}, element);
1138                }
1139                else {
1140                    if(attrValues[ATTIDX_NONSCHEMA] == null) {
1141                        // these are usually small
1142
attrValues[ATTIDX_NONSCHEMA] = new Vector JavaDoc(4,2);
1143                    }
1144                    ((Vector JavaDoc)attrValues[ATTIDX_NONSCHEMA]).addElement(attrName);
1145                    ((Vector JavaDoc)attrValues[ATTIDX_NONSCHEMA]).addElement(attrVal);
1146                    // for attributes from other namespace
1147
// store them in a list, and TRY to validate them after
1148
// schema traversal (because it's "lax")
1149
//otherValues.put(attrName, attrVal);
1150
// REVISIT: actually use this some day...
1151
// String attrRName = attrURI + "," + attrName;
1152
// Vector values = (Vector)fNonSchemaAttrs.get(attrRName);
1153
// if (values == null) {
1154
// values = new Vector();
1155
// values.addElement(attrName);
1156
// values.addElement(elName);
1157
// values.addElement(attrVal);
1158
// fNonSchemaAttrs.put(attrRName, values);
1159
// }
1160
// else {
1161
// values.addElement(elName);
1162
// values.addElement(attrVal);
1163
// }
1164
}
1165                continue;
1166            }
1167
1168            // check whether this attribute is allowed
1169
OneAttr oneAttr = (OneAttr)attrList.get(attrName);
1170            if (oneAttr == null) {
1171                reportSchemaError ("s4s-att-not-allowed",
1172                                   new Object JavaDoc[] {elName, attrName},
1173                                   element);
1174                continue;
1175            }
1176
1177            // we've seen this attribute
1178
fSeen[oneAttr.valueIndex] = true;
1179
1180            // check the value against the datatype
1181
try {
1182                // no checking on string needs to be done here.
1183
// no checking on xpath needs to be done here.
1184
// xpath values are validated in xpath parser
1185
if (oneAttr.dvIndex >= 0) {
1186                    if (oneAttr.dvIndex != DT_STRING &&
1187                        oneAttr.dvIndex != DT_XPATH &&
1188                        oneAttr.dvIndex != DT_XPATH1) {
1189                        XSSimpleType dv = fExtraDVs[oneAttr.dvIndex];
1190                        Object JavaDoc avalue = dv.validate(attrVal, schemaDoc.fValidationContext, null);
1191                        // kludge to handle chameleon includes/redefines...
1192
if (oneAttr.dvIndex == DT_QNAME) {
1193                            QName qname = (QName)avalue;
1194                            if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1195                                qname.uri = schemaDoc.fTargetNamespace;
1196                        }
1197                        attrValues[oneAttr.valueIndex] = avalue;
1198                    } else {
1199                        attrValues[oneAttr.valueIndex] = attrVal;
1200                    }
1201                }
1202                else {
1203                    attrValues[oneAttr.valueIndex] = validate(attrValues, attrName, attrVal, oneAttr.dvIndex, schemaDoc);
1204                }
1205            } catch (InvalidDatatypeValueException ide) {
1206                reportSchemaError ("s4s-att-invalid-value",
1207                                   new Object JavaDoc[] {elName, attrName, ide.getMessage()},
1208                                   element);
1209                if (oneAttr.dfltValue != null)
1210                    //attrValues.put(attrName, oneAttr.dfltValue);
1211
attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1212            }
1213
1214            // For "enumeration", and type is possible to be a QName, we need
1215
// to return namespace context for later QName resolution.
1216
if (elName.equals(SchemaSymbols.ELT_ENUMERATION) && enumAsQName) {
1217                attrValues[ATTIDX_ENUMNSDECLS] = new SchemaNamespaceSupport(schemaDoc.fNamespaceSupport);
1218            }
1219        }
1220
1221        // apply default values
1222
OneAttr[] reqAttrs = oneEle.attrList.values;
1223        for (int i = 0; i < reqAttrs.length; i++) {
1224            OneAttr oneAttr = reqAttrs[i];
1225
1226            // if the attribute didn't apprear, and
1227
// if the attribute is optional with default value, apply it
1228
if (oneAttr.dfltValue != null && !fSeen[oneAttr.valueIndex]) {
1229                //attrValues.put(oneAttr.name, oneAttr.dfltValue);
1230
attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1231                fromDefault |= (1<<oneAttr.valueIndex);
1232            }
1233        }
1234
1235        attrValues[ATTIDX_FROMDEFAULT] = new Long JavaDoc(fromDefault);
1236        //attrValues[ATTIDX_OTHERVALUES] = otherValues;
1237

1238        // maxOccurs
1239
if (attrValues[ATTIDX_MAXOCCURS] != null) {
1240            int min = ((XInt)attrValues[ATTIDX_MINOCCURS]).intValue();
1241            int max = ((XInt)attrValues[ATTIDX_MAXOCCURS]).intValue();
1242            
1243            if (max != SchemaSymbols.OCCURRENCE_UNBOUNDED) {
1244                // if secure processing in effect, test maxOccurs for maximum
1245
// maxOccurLimit
1246
if (fSchemaHandler.fSecureProcessing != null) {
1247                    //Revisit :: IMO this is not right place to check
1248
// maxOccurNodeLimit.
1249
int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getMaxOccurNodeLimit();
1250                    if (max > maxOccurNodeLimit) {
1251                        reportSchemaError("maxOccurLimit", new Object JavaDoc[] {new Integer JavaDoc(maxOccurNodeLimit)}, element);
1252                    
1253                        // reset max values in case processing continues on error
1254
attrValues[ATTIDX_MAXOCCURS] = fXIntPool.getXInt(maxOccurNodeLimit);
1255                        //new Integer(maxOccurNodeLimit);
1256
max = maxOccurNodeLimit;
1257                    }
1258                }
1259
1260                // Check that minOccurs isn't greater than maxOccurs.
1261
// p-props-correct 2.1
1262
if (min > max) {
1263                    reportSchemaError ("p-props-correct.2.1",
1264                                       new Object JavaDoc[] {elName, attrValues[ATTIDX_MINOCCURS], attrValues[ATTIDX_MAXOCCURS]},
1265                                       element);
1266                    attrValues[ATTIDX_MINOCCURS] = attrValues[ATTIDX_MAXOCCURS];
1267                }
1268            }
1269        }
1270
1271        return attrValues;
1272    }
1273
1274    private Object JavaDoc validate(Object JavaDoc[] attrValues, String JavaDoc attr, String JavaDoc ivalue, int dvIndex,
1275                            XSDocumentInfo schemaDoc) throws InvalidDatatypeValueException {
1276        if (ivalue == null)
1277            return null;
1278
1279        // To validate these types, we don't actually need to normalize the
1280
// strings. We only need to remove the whitespace from both ends.
1281
// In some special cases (list types), StringTokenizer can correctly
1282
// process the un-normalized whitespace.
1283
String JavaDoc value = ivalue.trim();
1284        Object JavaDoc retValue = null;
1285        Vector JavaDoc memberType;
1286        int choice;
1287
1288        switch (dvIndex) {
1289        case DT_BOOLEAN:
1290            if (value.equals(SchemaSymbols.ATTVAL_FALSE) ||
1291                value.equals(SchemaSymbols.ATTVAL_FALSE_0)) {
1292                retValue = Boolean.FALSE;
1293            } else if (value.equals(SchemaSymbols.ATTVAL_TRUE) ||
1294                       value.equals(SchemaSymbols.ATTVAL_TRUE_1)) {
1295                retValue = Boolean.TRUE;
1296            } else {
1297                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{value, "boolean"});
1298            }
1299            break;
1300        case DT_NONNEGINT:
1301            try {
1302                if (value.length() > 0 && value.charAt(0) == '+')
1303                    value = value.substring(1);
1304                retValue = fXIntPool.getXInt(Integer.parseInt(value));
1305            } catch (NumberFormatException JavaDoc e) {
1306                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{value, "nonNegativeInteger"});
1307            }
1308            if (((XInt)retValue).intValue() < 0)
1309                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{value, "nonNegativeInteger"});
1310            break;
1311        case DT_POSINT:
1312            try {
1313                if (value.length() > 0 && value.charAt(0) == '+')
1314                    value = value.substring(1);
1315                retValue = fXIntPool.getXInt(Integer.parseInt(value));
1316            } catch (NumberFormatException JavaDoc e) {
1317                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{value, "positiveInteger"});
1318            }
1319            if (((XInt)retValue).intValue() <= 0)
1320                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{value, "positiveInteger"});
1321            break;
1322        case DT_BLOCK:
1323            // block = (#all | List of (substitution | extension | restriction | list | union))
1324
choice = 0;
1325            if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1326                choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1327                         XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1328                         XSConstants.DERIVATION_UNION;
1329            }
1330            else {
1331                // use the default \t\r\n\f delimiters
1332
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(value);
1333                while (t.hasMoreTokens()) {
1334                    String JavaDoc token = t.nextToken ();
1335
1336                    if (token.equals (SchemaSymbols.ATTVAL_SUBSTITUTION)) {
1337                        choice |= XSConstants.DERIVATION_SUBSTITUTION;
1338                    }
1339                    else if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1340                        choice |= XSConstants.DERIVATION_EXTENSION;
1341                    }
1342                    else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1343                        choice |= XSConstants.DERIVATION_RESTRICTION;
1344                    }
1345                    else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1346                        choice |= XSConstants.DERIVATION_LIST;
1347                    }
1348                    else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1349                        choice |= XSConstants.DERIVATION_RESTRICTION;
1350                    }
1351                    else {
1352                        throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "(#all | List of (substitution | extension | restriction | list | union))"});
1353                    }
1354                }
1355            }
1356            retValue = fXIntPool.getXInt(choice);
1357            break;
1358        case DT_BLOCK1:
1359        case DT_FINAL:
1360            // block = (#all | List of (extension | restriction))
1361
// final = (#all | List of (extension | restriction))
1362
choice = 0;
1363            if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1364                //choice = SchemaSymbols.EXTENSION|SchemaSymbols.RESTRICTION;
1365
// REVISIT: if #all, then make the result the combination of
1366
// everything: substitution/externsion/restriction/list/union.
1367
// would this be a problem?
1368
// the reason doing so is that when final/blockFinal on <schema>
1369
// is #all, it's not always the same as the conbination of those
1370
// values allowed by final/blockFinal.
1371
// for example, finalDefault="#all" is not always the same as
1372
// finalDefault="extension restriction".
1373
// if finalDefault="#all", final on any simple type would be
1374
// "extension restriction list union".
1375
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1376                         XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1377                         XSConstants.DERIVATION_UNION;
1378            }
1379            else {
1380                // use the default \t\r\n\f delimiters
1381
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(value);
1382                while (t.hasMoreTokens()) {
1383                    String JavaDoc token = t.nextToken ();
1384
1385                    if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1386                        choice |= XSConstants.DERIVATION_EXTENSION;
1387                    }
1388                    else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1389                        choice |= XSConstants.DERIVATION_RESTRICTION;
1390                    }
1391                    else {
1392                        throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "(#all | List of (extension | restriction))"});
1393                    }
1394                }
1395            }
1396            retValue = fXIntPool.getXInt(choice);
1397            break;
1398        case DT_FINAL1:
1399            // final = (#all | List of (list | union | restriction))
1400
choice = 0;
1401            if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1402                //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1403
// SchemaSymbols.UNION;
1404
// REVISIT: if #all, then make the result the combination of
1405
// everything: substitution/externsion/restriction/list/union.
1406
// would this be a problem?
1407
// same reason as above DT_BLOCK1/DT_FINAL
1408
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1409                         XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1410                         XSConstants.DERIVATION_UNION;
1411            }
1412            else if (value.equals (SchemaSymbols.ATTVAL_LIST)) {
1413                choice = XSConstants.DERIVATION_LIST;
1414            }
1415            else if (value.equals (SchemaSymbols.ATTVAL_UNION)) {
1416                choice = XSConstants.DERIVATION_UNION;
1417            } else {
1418                // use the default \t\r\n\f delimiters
1419
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(value);
1420                while (t.hasMoreTokens()) {
1421                    String JavaDoc token = t.nextToken ();
1422
1423                    if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1424                        choice |= XSConstants.DERIVATION_LIST;
1425                    }
1426                    else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1427                        choice |= XSConstants.DERIVATION_UNION;
1428                    }
1429                    else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1430                        choice |= XSConstants.DERIVATION_RESTRICTION;
1431                    }
1432                    else {
1433                        throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "(#all | List of (list | union | restriction))"});
1434                    }
1435                }
1436            }
1437            retValue = fXIntPool.getXInt(choice);
1438            break;
1439        case DT_FINAL2:
1440            // finalDefault = (#all | List of (extension | restriction | list | union))
1441
choice = 0;
1442            if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1443                //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1444
// SchemaSymbols.UNION;
1445
// REVISIT: if #all, then make the result the combination of
1446
// everything: substitution/externsion/restriction/list/union.
1447
// would this be a problem?
1448
// same reason as above DT_BLOCK1/DT_FINAL
1449
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1450                         XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1451                         XSConstants.DERIVATION_UNION;
1452            }
1453            else {
1454                // use the default \t\r\n\f delimiters
1455
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(value);
1456                while (t.hasMoreTokens()) {
1457                    String JavaDoc token = t.nextToken ();
1458
1459                    if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1460                        choice |= XSConstants.DERIVATION_EXTENSION;
1461                    }
1462                    else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1463                        choice |= XSConstants.DERIVATION_RESTRICTION;
1464                    }
1465                    else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1466                        choice |= XSConstants.DERIVATION_LIST;
1467                    }
1468                    else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1469                        choice |= XSConstants.DERIVATION_UNION;
1470                    }
1471                    else {
1472                        throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "(#all | List of (extension | restriction | list | union))"});
1473                    }
1474                }
1475            }
1476            retValue = fXIntPool.getXInt(choice);
1477            break;
1478        case DT_FORM:
1479            // form = (qualified | unqualified)
1480
if (value.equals (SchemaSymbols.ATTVAL_QUALIFIED))
1481                retValue = INT_QUALIFIED;
1482            else if (value.equals (SchemaSymbols.ATTVAL_UNQUALIFIED))
1483                retValue = INT_UNQUALIFIED;
1484            else
1485                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1486                                                        new Object JavaDoc[]{value, "(qualified | unqualified)"});
1487            break;
1488        case DT_MAXOCCURS:
1489            // maxOccurs = (nonNegativeInteger | unbounded)
1490
if (value.equals(SchemaSymbols.ATTVAL_UNBOUNDED)) {
1491                retValue = INT_UNBOUNDED;
1492            } else {
1493                try {
1494                    retValue = validate(attrValues, attr, value, DT_NONNEGINT, schemaDoc);
1495                } catch (NumberFormatException JavaDoc e) {
1496                    throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "(nonNegativeInteger | unbounded)"});
1497                }
1498            }
1499            break;
1500        case DT_MAXOCCURS1:
1501            // maxOccurs = 1
1502
if (value.equals("1"))
1503                retValue = fXIntPool.getXInt(1);
1504            else
1505                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1506                                                        new Object JavaDoc[]{value, "(1)"});
1507            break;
1508        case DT_MEMBERTYPES:
1509            // memberTypes = List of QName
1510
memberType = new Vector JavaDoc();
1511            try {
1512                // use the default \t\r\n\f delimiters
1513
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(value);
1514                while (t.hasMoreTokens()) {
1515                    String JavaDoc token = t.nextToken ();
1516                    QName qname = (QName)fExtraDVs[DT_QNAME].validate(token, schemaDoc.fValidationContext, null);
1517                    // kludge to handle chameleon includes/redefines...
1518
if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1519                        qname.uri = schemaDoc.fTargetNamespace;
1520                    memberType.addElement(qname);
1521                }
1522                retValue = memberType;
1523            }
1524            catch (InvalidDatatypeValueException ide) {
1525                throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.2", new Object JavaDoc[]{value, "(List of QName)"});
1526            }
1527            break;
1528        case DT_MINOCCURS1:
1529            // minOccurs = (0 | 1)
1530
if (value.equals("0"))
1531                retValue = fXIntPool.getXInt(0);
1532            else if (value.equals("1"))
1533                retValue = fXIntPool.getXInt(1);
1534            else
1535                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1536                                                        new Object JavaDoc[]{value, "(0 | 1)"});
1537            break;
1538        case DT_NAMESPACE:
1539            // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )
1540
if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY)) {
1541                // ##any
1542
retValue = INT_ANY_ANY;
1543            } else if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
1544                // ##other
1545
retValue = INT_ANY_NOT;
1546                String JavaDoc[] list = new String JavaDoc[2];
1547                list[0] = schemaDoc.fTargetNamespace;
1548                list[1] = null;
1549                attrValues[ATTIDX_NAMESPACE_LIST] = list;
1550            } else {
1551                // list
1552
retValue = INT_ANY_LIST;
1553
1554                fNamespaceList.removeAllElements();
1555                
1556                // tokenize
1557
// use the default \t\r\n\f delimiters
1558
StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(value);
1559                String JavaDoc token;
1560                String JavaDoc tempNamespace;
1561                try {
1562                    while (tokens.hasMoreTokens()) {
1563                        token = tokens.nextToken();
1564                        if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
1565                            tempNamespace = null;
1566                        } else if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS)) {
1567                            tempNamespace = schemaDoc.fTargetNamespace;
1568                        } else {
1569                            // we have found namespace URI here
1570
// need to add it to the symbol table
1571
fExtraDVs[DT_ANYURI].validate(token, schemaDoc.fValidationContext, null);
1572                            tempNamespace = fSymbolTable.addSymbol(token);
1573                        }
1574
1575                        //check for duplicate namespaces in the list
1576
if (!fNamespaceList.contains(tempNamespace)) {
1577                            fNamespaceList.addElement(tempNamespace);
1578                        }
1579                    }
1580                } catch (InvalidDatatypeValueException ide) {
1581                    throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object JavaDoc[]{value, "((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )"});
1582                }
1583
1584                // convert the vector to an array
1585
int num = fNamespaceList.size();
1586                String JavaDoc[] list = new String JavaDoc[num];
1587                fNamespaceList.copyInto(list);
1588                attrValues[ATTIDX_NAMESPACE_LIST] = list;
1589            }
1590            break;
1591        case DT_PROCESSCONTENTS:
1592            // processContents = (lax | skip | strict)
1593
if (value.equals (SchemaSymbols.ATTVAL_STRICT))
1594                retValue = INT_ANY_STRICT;
1595            else if (value.equals (SchemaSymbols.ATTVAL_LAX))
1596                retValue = INT_ANY_LAX;
1597            else if (value.equals (SchemaSymbols.ATTVAL_SKIP))
1598                retValue = INT_ANY_SKIP;
1599            else
1600                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1601                                                        new Object JavaDoc[]{value, "(lax | skip | strict)"});
1602            break;
1603        case DT_USE:
1604            // use = (optional | prohibited | required)
1605
if (value.equals (SchemaSymbols.ATTVAL_OPTIONAL))
1606                retValue = INT_USE_OPTIONAL;
1607            else if (value.equals (SchemaSymbols.ATTVAL_REQUIRED))
1608                retValue = INT_USE_REQUIRED;
1609            else if (value.equals (SchemaSymbols.ATTVAL_PROHIBITED))
1610                retValue = INT_USE_PROHIBITED;
1611            else
1612                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1613                                                        new Object JavaDoc[]{value, "(optional | prohibited | required)"});
1614            break;
1615        case DT_WHITESPACE:
1616            // value = preserve | replace | collapse
1617
if (value.equals (SchemaSymbols.ATTVAL_PRESERVE))
1618                retValue = INT_WS_PRESERVE;
1619            else if (value.equals (SchemaSymbols.ATTVAL_REPLACE))
1620                retValue = INT_WS_REPLACE;
1621            else if (value.equals (SchemaSymbols.ATTVAL_COLLAPSE))
1622                retValue = INT_WS_COLLAPSE;
1623            else
1624                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1625                                                        new Object JavaDoc[]{value, "(preserve | replace | collapse)"});
1626            break;
1627        }
1628
1629        return retValue;
1630    }
1631
1632    void reportSchemaError (String JavaDoc key, Object JavaDoc[] args, Element JavaDoc ele) {
1633        fSchemaHandler.reportSchemaError(key, args, ele);
1634    }
1635
1636    // validate attriubtes from non-schema namespaces
1637
// REVISIT: why we store the attributes in this way? why not just a list
1638
// of structure {element node, attr name/qname, attr value)?
1639
// REVISIT: pass the proper element node to reportSchemaError
1640
public void checkNonSchemaAttributes(XSGrammarBucket grammarBucket) {
1641        // for all attributes
1642
Enumeration JavaDoc keys = fNonSchemaAttrs.keys();
1643        XSAttributeDecl attrDecl;
1644        while (keys.hasMoreElements()) {
1645            // get name, uri, localpart
1646
String JavaDoc attrRName = (String JavaDoc)keys.nextElement();
1647            String JavaDoc attrURI = attrRName.substring(0,attrRName.indexOf(','));
1648            String JavaDoc attrLocal = attrRName.substring(attrRName.indexOf(',')+1);
1649            // find associated grammar
1650
SchemaGrammar sGrammar = grammarBucket.getGrammar(attrURI);
1651            if (sGrammar == null)
1652                continue;
1653            // and get the datatype validator, if there is one
1654
attrDecl = sGrammar.getGlobalAttributeDecl(attrLocal);
1655            if (attrDecl == null)
1656                continue;
1657            XSSimpleType dv = (XSSimpleType)attrDecl.getTypeDefinition();
1658            if (dv == null)
1659                continue;
1660
1661            // get all values appeared with this attribute name
1662
Vector JavaDoc values = (Vector JavaDoc)fNonSchemaAttrs.get(attrRName);
1663            String JavaDoc elName, attrVal;
1664            String JavaDoc attrName = (String JavaDoc)values.elementAt(0);
1665            // for each of the values
1666
int count = values.size();
1667            for (int i = 1; i < count; i += 2) {
1668                elName = (String JavaDoc)values.elementAt(i);
1669                try {
1670                    // and validate it using the XSSimpleType
1671
// REVISIT: what would be the proper validation context?
1672
// guess we need to save that in the vectors too.
1673
dv.validate((String JavaDoc)values.elementAt(i+1), null, null);
1674                } catch(InvalidDatatypeValueException ide) {
1675                    reportSchemaError ("s4s-att-invalid-value",
1676                                       new Object JavaDoc[] {elName, attrName, ide.getMessage()},
1677                                       null);
1678                }
1679            }
1680        }
1681    }
1682
1683    // normalize the string according to the whiteSpace facet
1684
public static String JavaDoc normalize(String JavaDoc content, short ws) {
1685        int len = content == null ? 0 : content.length();
1686        if (len == 0 || ws == XSSimpleType.WS_PRESERVE)
1687            return content;
1688
1689        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1690        if (ws == XSSimpleType.WS_REPLACE) {
1691            char ch;
1692            // when it's replace, just replace #x9, #xa, #xd by #x20
1693
for (int i = 0; i < len; i++) {
1694                ch = content.charAt(i);
1695                if (ch != 0x9 && ch != 0xa && ch != 0xd)
1696                    sb.append(ch);
1697                else
1698                    sb.append((char)0x20);
1699            }
1700        } else {
1701            char ch;
1702            int i;
1703            boolean isLeading = true;
1704            // when it's collapse
1705
for (i = 0; i < len; i++) {
1706                ch = content.charAt(i);
1707                // append real characters, so we passed leading ws
1708
if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
1709                    sb.append(ch);
1710                    isLeading = false;
1711                }
1712                else {
1713                    // for whitespaces, we skip all following ws
1714
for (; i < len-1; i++) {
1715                        ch = content.charAt(i+1);
1716                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
1717                            break;
1718                    }
1719                    // if it's not a leading or tailing ws, then append a space
1720
if (i < len - 1 && !isLeading)
1721                        sb.append((char)0x20);
1722                }
1723            }
1724        }
1725
1726        return sb.toString();
1727    }
1728
1729    // the following part implements an attribute-value-array pool.
1730
// when checkAttribute is called, it calls getAvailableArray to get
1731
// an array from the pool; when the caller is done with the array,
1732
// it calls returnAttrArray to return that array to the pool.
1733

1734    // initial size of the array pool. 10 is big enough
1735
static final int INIT_POOL_SIZE = 10;
1736    // the incremental size of the array pool
1737
static final int INC_POOL_SIZE = 10;
1738    // the array pool
1739
Object JavaDoc[][] fArrayPool = new Object JavaDoc[INIT_POOL_SIZE][ATTIDX_COUNT];
1740    // used to clear the returned array
1741
// I think System.arrayCopy is more efficient than setting 35 fields to null
1742
private static Object JavaDoc[] fTempArray = new Object JavaDoc[ATTIDX_COUNT];
1743    // current position of the array pool (# of arrays not returned)
1744
int fPoolPos = 0;
1745
1746    // get the next available array
1747
protected Object JavaDoc[] getAvailableArray() {
1748        // if no array left in the pool, increase the pool size
1749
if (fArrayPool.length == fPoolPos) {
1750            // increase size
1751
fArrayPool = new Object JavaDoc[fPoolPos+INC_POOL_SIZE][];
1752            // initialize each *new* array
1753
for (int i = fPoolPos; i < fArrayPool.length; i++)
1754                fArrayPool[i] = new Object JavaDoc[ATTIDX_COUNT];
1755        }
1756        // get the next available one
1757
Object JavaDoc[] retArray = fArrayPool[fPoolPos];
1758        // clear it from the pool. this is for GC: if a caller forget to
1759
// return the array, we want that array to be GCed.
1760
fArrayPool[fPoolPos++] = null;
1761        // to make sure that one array is not returned twice, we use
1762
// the last entry to indicate whether an array is already returned
1763
// now set it to false.
1764
System.arraycopy(fTempArray, 0, retArray, 0, ATTIDX_COUNT-1);
1765        retArray[ATTIDX_ISRETURNED] = Boolean.FALSE;
1766
1767        return retArray;
1768    }
1769
1770    // return an array back to the pool
1771
public void returnAttrArray(Object JavaDoc[] attrArray, XSDocumentInfo schemaDoc) {
1772        // pop the namespace context
1773
if (schemaDoc != null)
1774            schemaDoc.fNamespaceSupport.popContext();
1775
1776        // if 1. the pool is full; 2. the array is null;
1777
// 3. the array is of wrong size; 4. the array is already returned
1778
// then we can't accept this array to be returned
1779
if (fPoolPos == 0 ||
1780            attrArray == null ||
1781            attrArray.length != ATTIDX_COUNT ||
1782            ((Boolean JavaDoc)attrArray[ATTIDX_ISRETURNED]).booleanValue()) {
1783            return;
1784        }
1785
1786        // mark this array as returned
1787
attrArray[ATTIDX_ISRETURNED] = Boolean.TRUE;
1788        // better clear nonschema vector
1789
if(attrArray[ATTIDX_NONSCHEMA] != null)
1790            ((Vector JavaDoc)attrArray[ATTIDX_NONSCHEMA]).clear();
1791        // and put it into the pool
1792
fArrayPool[--fPoolPos] = attrArray;
1793    }
1794
1795    public void resolveNamespace(Element JavaDoc element, Attr JavaDoc[] attrs,
1796                                 SchemaNamespaceSupport nsSupport) {
1797        // push the namespace context
1798
nsSupport.pushContext();
1799
1800        // search for new namespace bindings
1801
int length = attrs.length;
1802        Attr JavaDoc sattr = null;
1803        String JavaDoc rawname, prefix, uri;
1804        for (int i = 0; i < length; i++) {
1805            sattr = attrs[i];
1806            rawname = DOMUtil.getName(sattr);
1807            prefix = null;
1808            if (rawname.equals(XMLSymbols.PREFIX_XMLNS))
1809                prefix = XMLSymbols.EMPTY_STRING;
1810            else if (rawname.startsWith("xmlns:"))
1811                prefix = fSymbolTable.addSymbol(DOMUtil.getLocalName(sattr));
1812            if (prefix != null) {
1813                uri = fSymbolTable.addSymbol(DOMUtil.getValue(sattr));
1814                nsSupport.declarePrefix(prefix, uri.length()!=0 ? uri : null);
1815            }
1816        }
1817    }
1818}
1819
1820class OneAttr {
1821    // name of the attribute
1822
public String JavaDoc name;
1823    // index of the datatype validator
1824
public int dvIndex;
1825    // whether it's optional, and has default value
1826
public int valueIndex;
1827    // the default value of this attribute
1828
public Object JavaDoc dfltValue;
1829
1830    public OneAttr(String JavaDoc name, int dvIndex, int valueIndex, Object JavaDoc dfltValue) {
1831        this.name = name;
1832        this.dvIndex = dvIndex;
1833        this.valueIndex = valueIndex;
1834        this.dfltValue = dfltValue;
1835    }
1836}
1837
1838class OneElement {
1839    // the list of attributes that can appear in one element
1840
public Container attrList;
1841    // does this element allow attributes from non-schema namespace
1842
public boolean allowNonSchemaAttr;
1843
1844    public OneElement (Container attrList) {
1845        this(attrList, true);
1846    }
1847
1848    public OneElement (Container attrList, boolean allowNonSchemaAttr) {
1849        this.attrList = attrList;
1850        this.allowNonSchemaAttr = allowNonSchemaAttr;
1851    }
1852}
1853
1854abstract class Container {
1855    static final int THRESHOLD = 5;
1856    static Container getContainer(int size) {
1857        if (size > THRESHOLD)
1858            return new LargeContainer(size);
1859        else
1860            return new SmallContainer(size);
1861    }
1862    abstract void put(String JavaDoc key, OneAttr value);
1863    abstract OneAttr get(String JavaDoc key);
1864
1865    OneAttr[] values;
1866    int pos = 0;
1867}
1868
1869class SmallContainer extends Container {
1870    String JavaDoc[] keys;
1871    SmallContainer(int size) {
1872        keys = new String JavaDoc[size];
1873        values = new OneAttr[size];
1874    }
1875    void put(String JavaDoc key, OneAttr value) {
1876        keys[pos] = key;
1877        values[pos++] = value;
1878    }
1879    OneAttr get(String JavaDoc key) {
1880        for (int i = 0; i < pos; i++) {
1881            if (keys[i].equals(key)) {
1882                return values[i];
1883            }
1884        }
1885        return null;
1886    }
1887}
1888
1889class LargeContainer extends Container {
1890    Hashtable JavaDoc items;
1891    LargeContainer(int size) {
1892        items = new Hashtable JavaDoc(size*2+1);
1893        values = new OneAttr[size];
1894    }
1895    void put(String JavaDoc key, OneAttr value) {
1896        items.put(key, value);
1897        values[pos++] = value;
1898    }
1899    OneAttr get(String JavaDoc key) {
1900        OneAttr ret = (OneAttr)items.get(key);
1901        return ret;
1902    }
1903}
1904
Popular Tags