1 /*
2  * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3  */
4 /*
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * The ASF licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22 
23 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
24 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
25 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
26 import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
27 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
28 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeDecl;
29 import com.sun.org.apache.xerces.internal.impl.xs.XSGrammarBucket;
30 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
31 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
32 import com.sun.org.apache.xerces.internal.impl.xs.util.XIntPool;
33 import com.sun.org.apache.xerces.internal.util.DOMUtil;
34 import com.sun.org.apache.xerces.internal.util.SymbolTable;
35 import com.sun.org.apache.xerces.internal.util.XMLChar;
36 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
37 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
38 import com.sun.org.apache.xerces.internal.xni.QName;
39 import com.sun.org.apache.xerces.internal.xs.XSConstants;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.StringTokenizer;
45 import org.w3c.dom.Attr;
46 import org.w3c.dom.Element;
47 
48 /**
49  * Class <code>XSAttributeCheck</code> is used to check the validity of attributes
50  * appearing in the schema document. It
51  * - reports an error for invalid element (invalid namespace, invalid name)
52  * - reports an error for invalid attribute (invalid namespace, invalid name)
53  * - reports an error for invalid attribute value
54  * - return compiled values for attriute values
55  * - provide default value for missing optional attributes
56  * - provide default value for incorrect attribute values
57  *
58  * But it's the caller's responsibility to check whether a required attribute
59  * is present.
60  *
61  * Things need revisiting:
62  * - Whether to return non-schema attributes/values
63  * - Do we need to update NamespaceScope and ErrorReporter when reset()?
64  * - Should have the datatype validators return compiled value
65  * - use symbol table instead of many maps
66  *
67  * @xerces.internal
68  *
69  * @author Sandy Gao, IBM
70  * @LastModified: Nov 2017
71  */
72 
73 public class XSAttributeChecker {
74 
75     // REVISIT: only local element and attribute are different from others.
76     //          it's possible to have either name or ref. all the others
77     //          are only allowed to have one of name or ref, or neither of them.
78     //          we'd better move such checking to the traverser.
79     private static final String ELEMENT_N = "element_n";
80     private static final String ELEMENT_R = "element_r";
81     private static final String ATTRIBUTE_N = "attribute_n";
82     private static final String ATTRIBUTE_R = "attribute_r";
83 
84     private static       int ATTIDX_COUNT           = 0;
85     public static final int ATTIDX_ABSTRACT        = ATTIDX_COUNT++;
86     public static final int ATTIDX_AFORMDEFAULT    = ATTIDX_COUNT++;
87     public static final int ATTIDX_BASE            = ATTIDX_COUNT++;
88     public static final int ATTIDX_BLOCK           = ATTIDX_COUNT++;
89     public static final int ATTIDX_BLOCKDEFAULT    = ATTIDX_COUNT++;
90     public static final int ATTIDX_DEFAULT         = ATTIDX_COUNT++;
91     public static final int ATTIDX_EFORMDEFAULT    = ATTIDX_COUNT++;
92     public static final int ATTIDX_FINAL           = ATTIDX_COUNT++;
93     public static final int ATTIDX_FINALDEFAULT    = ATTIDX_COUNT++;
94     public static final int ATTIDX_FIXED           = ATTIDX_COUNT++;
95     public static final int ATTIDX_FORM            = ATTIDX_COUNT++;
96     public static final int ATTIDX_ID              = ATTIDX_COUNT++;
97     public static final int ATTIDX_ITEMTYPE        = ATTIDX_COUNT++;
98     public static final int ATTIDX_MAXOCCURS       = ATTIDX_COUNT++;
99     public static final int ATTIDX_MEMBERTYPES     = ATTIDX_COUNT++;
100     public static final int ATTIDX_MINOCCURS       = ATTIDX_COUNT++;
101     public static final int ATTIDX_MIXED           = ATTIDX_COUNT++;
102     public static final int ATTIDX_NAME            = ATTIDX_COUNT++;
103     public static final int ATTIDX_NAMESPACE       = ATTIDX_COUNT++;
104     public static final int ATTIDX_NAMESPACE_LIST  = ATTIDX_COUNT++;
105     public static final int ATTIDX_NILLABLE        = ATTIDX_COUNT++;
106     public static final int ATTIDX_NONSCHEMA       = ATTIDX_COUNT++;
107     public static final int ATTIDX_PROCESSCONTENTS = ATTIDX_COUNT++;
108     public static final int ATTIDX_PUBLIC          = ATTIDX_COUNT++;
109     public static final int ATTIDX_REF             = ATTIDX_COUNT++;
110     public static final int ATTIDX_REFER           = ATTIDX_COUNT++;
111     public static final int ATTIDX_SCHEMALOCATION  = ATTIDX_COUNT++;
112     public static final int ATTIDX_SOURCE          = ATTIDX_COUNT++;
113     public static final int ATTIDX_SUBSGROUP       = ATTIDX_COUNT++;
114     public static final int ATTIDX_SYSTEM          = ATTIDX_COUNT++;
115     public static final int ATTIDX_TARGETNAMESPACE = ATTIDX_COUNT++;
116     public static final int ATTIDX_TYPE            = ATTIDX_COUNT++;
117     public static final int ATTIDX_USE             = ATTIDX_COUNT++;
118     public static final int ATTIDX_VALUE           = ATTIDX_COUNT++;
119     public static final int ATTIDX_ENUMNSDECLS     = ATTIDX_COUNT++;
120     public static final int ATTIDX_VERSION         = ATTIDX_COUNT++;
121     public static final int ATTIDX_XML_LANG        = ATTIDX_COUNT++;
122     public static final int ATTIDX_XPATH           = ATTIDX_COUNT++;
123     public static final int ATTIDX_FROMDEFAULT     = ATTIDX_COUNT++;
124     //public static final int ATTIDX_OTHERVALUES     = ATTIDX_COUNT++;
125     public static final int ATTIDX_ISRETURNED      = ATTIDX_COUNT++;
126 
127     private static final XIntPool fXIntPool = new XIntPool();
128     // constants to return
129     private static final XInt INT_QUALIFIED      = fXIntPool.getXInt(SchemaSymbols.FORM_QUALIFIED);
130     private static final XInt INT_UNQUALIFIED    = fXIntPool.getXInt(SchemaSymbols.FORM_UNQUALIFIED);
131     private static final XInt INT_EMPTY_SET      = fXIntPool.getXInt(XSConstants.DERIVATION_NONE);
132     private static final XInt INT_ANY_STRICT     = fXIntPool.getXInt(XSWildcardDecl.PC_STRICT);
133     private static final XInt INT_ANY_LAX        = fXIntPool.getXInt(XSWildcardDecl.PC_LAX);
134     private static final XInt INT_ANY_SKIP       = fXIntPool.getXInt(XSWildcardDecl.PC_SKIP);
135     private static final XInt INT_ANY_ANY        = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_ANY);
136     private static final XInt INT_ANY_LIST       = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_LIST);
137     private static final XInt INT_ANY_NOT        = fXIntPool.getXInt(XSWildcardDecl.NSCONSTRAINT_NOT);
138     private static final XInt INT_USE_OPTIONAL   = fXIntPool.getXInt(SchemaSymbols.USE_OPTIONAL);
139     private static final XInt INT_USE_REQUIRED   = fXIntPool.getXInt(SchemaSymbols.USE_REQUIRED);
140     private static final XInt INT_USE_PROHIBITED = fXIntPool.getXInt(SchemaSymbols.USE_PROHIBITED);
141     private static final XInt INT_WS_PRESERVE    = fXIntPool.getXInt(XSSimpleType.WS_PRESERVE);
142     private static final XInt INT_WS_REPLACE     = fXIntPool.getXInt(XSSimpleType.WS_REPLACE);
143     private static final XInt INT_WS_COLLAPSE    = fXIntPool.getXInt(XSSimpleType.WS_COLLAPSE);
144     private static final XInt INT_UNBOUNDED      = fXIntPool.getXInt(SchemaSymbols.OCCURRENCE_UNBOUNDED);
145 
146     // used to store the map from element name to attribute list
147     // for 14 global elements
148     private static final Map<String, Container> fEleAttrsMapG = new HashMap<>(29);
149     // for 39 local elememnts
150     private static final Map<String, Container> fEleAttrsMapL = new HashMap<>(79);
151 
152     // used to initialize fEleAttrsMap
153     // step 1: all possible data types
154     // DT_??? >= 0 : validate using a validator, which is initialized staticly
155     // DT_??? <  0 : validate directly, which is done in "validate()"
156 
157     protected static final int DT_ANYURI           = 0;
158     protected static final int DT_ID               = 1;
159     protected static final int DT_QNAME            = 2;
160     protected static final int DT_STRING           = 3;
161     protected static final int DT_TOKEN            = 4;
162     protected static final int DT_NCNAME           = 5;
163     protected static final int DT_XPATH            = 6;
164     protected static final int DT_XPATH1           = 7;
165     protected static final int DT_LANGUAGE         = 8;
166 
167     // used to store extra datatype validators
168     protected static final int DT_COUNT            = DT_LANGUAGE + 1;
169     private static final XSSimpleType[] fExtraDVs = new XSSimpleType[DT_COUNT];
170     static {
171         // step 5: register all datatype validators for new types
172         SchemaGrammar grammar = SchemaGrammar.SG_SchemaNS;
173         // anyURI
174         fExtraDVs[DT_ANYURI] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_ANYURI);
175         // ID
176         fExtraDVs[DT_ID] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_ID);
177         // QName
178         fExtraDVs[DT_QNAME] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
179         // string
180         fExtraDVs[DT_STRING] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_STRING);
181         // token
182         fExtraDVs[DT_TOKEN] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_TOKEN);
183         // NCName
184         fExtraDVs[DT_NCNAME] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_NCNAME);
185         // xpath = a subset of XPath expression
186         fExtraDVs[DT_XPATH] = fExtraDVs[DT_STRING];
187         // xpath = a subset of XPath expression
188         fExtraDVs[DT_XPATH] = fExtraDVs[DT_STRING];
189         // language
190         fExtraDVs[DT_LANGUAGE] = (XSSimpleType)grammar.getGlobalTypeDecl(SchemaSymbols.ATTVAL_LANGUAGE);
191     }
192 
193     protected static final int DT_BLOCK            = -1;
194     protected static final int DT_BLOCK1           = -2;
195     protected static final int DT_FINAL            = -3;
196     protected static final int DT_FINAL1           = -4;
197     protected static final int DT_FINAL2           = -5;
198     protected static final int DT_FORM             = -6;
199     protected static final int DT_MAXOCCURS        = -7;
200     protected static final int DT_MAXOCCURS1       = -8;
201     protected static final int DT_MEMBERTYPES      = -9;
202     protected static final int DT_MINOCCURS1       = -10;
203     protected static final int DT_NAMESPACE        = -11;
204     protected static final int DT_PROCESSCONTENTS  = -12;
205     protected static final int DT_USE              = -13;
206     protected static final int DT_WHITESPACE       = -14;
207     protected static final int DT_BOOLEAN          = -15;
208     protected static final int DT_NONNEGINT        = -16;
209     protected static final int DT_POSINT           = -17;
210 
211     static {
212         // step 2: all possible attributes for all elements
213         int attCount = 0;
214         int ATT_ABSTRACT_D          = attCount++;
215         int ATT_ATTRIBUTE_FD_D      = attCount++;
216         int ATT_BASE_R              = attCount++;
217         int ATT_BASE_N              = attCount++;
218         int ATT_BLOCK_N             = attCount++;
219         int ATT_BLOCK1_N            = attCount++;
220         int ATT_BLOCK_D_D           = attCount++;
221         int ATT_DEFAULT_N           = attCount++;
222         int ATT_ELEMENT_FD_D        = attCount++;
223         int ATT_FINAL_N             = attCount++;
224         int ATT_FINAL1_N            = attCount++;
225         int ATT_FINAL_D_D           = attCount++;
226         int ATT_FIXED_N             = attCount++;
227         int ATT_FIXED_D             = attCount++;
228         int ATT_FORM_N              = attCount++;
229         int ATT_ID_N                = attCount++;
230         int ATT_ITEMTYPE_N          = attCount++;
231         int ATT_MAXOCCURS_D         = attCount++;
232         int ATT_MAXOCCURS1_D        = attCount++;
233         int ATT_MEMBER_T_N          = attCount++;
234         int ATT_MINOCCURS_D         = attCount++;
235         int ATT_MINOCCURS1_D        = attCount++;
236         int ATT_MIXED_D             = attCount++;
237         int ATT_MIXED_N             = attCount++;
238         int ATT_NAME_R              = attCount++;
239         int ATT_NAMESPACE_D         = attCount++;
240         int ATT_NAMESPACE_N         = attCount++;
241         int ATT_NILLABLE_D          = attCount++;
242         int ATT_PROCESS_C_D         = attCount++;
243         int ATT_PUBLIC_R            = attCount++;
244         int ATT_REF_R               = attCount++;
245         int ATT_REFER_R             = attCount++;
246         int ATT_SCHEMA_L_R          = attCount++;
247         int ATT_SCHEMA_L_N          = attCount++;
248         int ATT_SOURCE_N            = attCount++;
249         int ATT_SUBSTITUTION_G_N    = attCount++;
250         int ATT_SYSTEM_N            = attCount++;
251         int ATT_TARGET_N_N          = attCount++;
252         int ATT_TYPE_N              = attCount++;
253         int ATT_USE_D               = attCount++;
254         int ATT_VALUE_NNI_N         = attCount++;
255         int ATT_VALUE_PI_N          = attCount++;
256         int ATT_VALUE_STR_N         = attCount++;
257         int ATT_VALUE_WS_N          = attCount++;
258         int ATT_VERSION_N           = attCount++;
259         int ATT_XML_LANG            = attCount++;
260         int ATT_XPATH_R             = attCount++;
261         int ATT_XPATH1_R            = attCount++;
262 
263         // step 3: store all these attributes in an array
264         OneAttr[] allAttrs = new OneAttr[attCount];
265         allAttrs[ATT_ABSTRACT_D]        =   new OneAttr(SchemaSymbols.ATT_ABSTRACT,
266                                                         DT_BOOLEAN,
267                                                         ATTIDX_ABSTRACT,
268                                                         Boolean.FALSE);
269         allAttrs[ATT_ATTRIBUTE_FD_D]    =   new OneAttr(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT,
270                                                         DT_FORM,
271                                                         ATTIDX_AFORMDEFAULT,
272                                                         INT_UNQUALIFIED);
273         allAttrs[ATT_BASE_R]            =   new OneAttr(SchemaSymbols.ATT_BASE,
274                                                         DT_QNAME,
275                                                         ATTIDX_BASE,
276                                                         null);
277         allAttrs[ATT_BASE_N]            =   new OneAttr(SchemaSymbols.ATT_BASE,
278                                                         DT_QNAME,
279                                                         ATTIDX_BASE,
280                                                         null);
281         allAttrs[ATT_BLOCK_N]           =   new OneAttr(SchemaSymbols.ATT_BLOCK,
282                                                         DT_BLOCK,
283                                                         ATTIDX_BLOCK,
284                                                         null);
285         allAttrs[ATT_BLOCK1_N]          =   new OneAttr(SchemaSymbols.ATT_BLOCK,
286                                                         DT_BLOCK1,
287                                                         ATTIDX_BLOCK,
288                                                         null);
289         allAttrs[ATT_BLOCK_D_D]         =   new OneAttr(SchemaSymbols.ATT_BLOCKDEFAULT,
290                                                         DT_BLOCK,
291                                                         ATTIDX_BLOCKDEFAULT,
292                                                         INT_EMPTY_SET);
293         allAttrs[ATT_DEFAULT_N]         =   new OneAttr(SchemaSymbols.ATT_DEFAULT,
294                                                         DT_STRING,
295                                                         ATTIDX_DEFAULT,
296                                                         null);
297         allAttrs[ATT_ELEMENT_FD_D]      =   new OneAttr(SchemaSymbols.ATT_ELEMENTFORMDEFAULT,
298                                                         DT_FORM,
299                                                         ATTIDX_EFORMDEFAULT,
300                                                         INT_UNQUALIFIED);
301         allAttrs[ATT_FINAL_N]           =   new OneAttr(SchemaSymbols.ATT_FINAL,
302                                                         DT_FINAL,
303                                                         ATTIDX_FINAL,
304                                                         null);
305         allAttrs[ATT_FINAL1_N]          =   new OneAttr(SchemaSymbols.ATT_FINAL,
306                                                         DT_FINAL1,
307                                                         ATTIDX_FINAL,
308                                                         null);
309         allAttrs[ATT_FINAL_D_D]         =   new OneAttr(SchemaSymbols.ATT_FINALDEFAULT,
310                                                         DT_FINAL2,
311                                                         ATTIDX_FINALDEFAULT,
312                                                         INT_EMPTY_SET);
313         allAttrs[ATT_FIXED_N]           =   new OneAttr(SchemaSymbols.ATT_FIXED,
314                                                         DT_STRING,
315                                                         ATTIDX_FIXED,
316                                                         null);
317         allAttrs[ATT_FIXED_D]           =   new OneAttr(SchemaSymbols.ATT_FIXED,
318                                                         DT_BOOLEAN,
319                                                         ATTIDX_FIXED,
320                                                         Boolean.FALSE);
321         allAttrs[ATT_FORM_N]            =   new OneAttr(SchemaSymbols.ATT_FORM,
322                                                         DT_FORM,
323                                                         ATTIDX_FORM,
324                                                         null);
325         allAttrs[ATT_ID_N]              =   new OneAttr(SchemaSymbols.ATT_ID,
326                                                         DT_ID,
327                                                         ATTIDX_ID,
328                                                         null);
329         allAttrs[ATT_ITEMTYPE_N]        =   new OneAttr(SchemaSymbols.ATT_ITEMTYPE,
330                                                         DT_QNAME,
331                                                         ATTIDX_ITEMTYPE,
332                                                         null);
333         allAttrs[ATT_MAXOCCURS_D]       =   new OneAttr(SchemaSymbols.ATT_MAXOCCURS,
334                                                         DT_MAXOCCURS,
335                                                         ATTIDX_MAXOCCURS,
336                                                         fXIntPool.getXInt(1));
337         allAttrs[ATT_MAXOCCURS1_D]      =   new OneAttr(SchemaSymbols.ATT_MAXOCCURS,
338                                                         DT_MAXOCCURS1,
339                                                         ATTIDX_MAXOCCURS,
340                                                         fXIntPool.getXInt(1));
341         allAttrs[ATT_MEMBER_T_N]        =   new OneAttr(SchemaSymbols.ATT_MEMBERTYPES,
342                                                         DT_MEMBERTYPES,
343                                                         ATTIDX_MEMBERTYPES,
344                                                         null);
345         allAttrs[ATT_MINOCCURS_D]       =   new OneAttr(SchemaSymbols.ATT_MINOCCURS,
346                                                         DT_NONNEGINT,
347                                                         ATTIDX_MINOCCURS,
348                                                         fXIntPool.getXInt(1));
349         allAttrs[ATT_MINOCCURS1_D]      =   new OneAttr(SchemaSymbols.ATT_MINOCCURS,
350                                                         DT_MINOCCURS1,
351                                                         ATTIDX_MINOCCURS,
352                                                         fXIntPool.getXInt(1));
353         allAttrs[ATT_MIXED_D]           =   new OneAttr(SchemaSymbols.ATT_MIXED,
354                                                         DT_BOOLEAN,
355                                                         ATTIDX_MIXED,
356                                                         Boolean.FALSE);
357         allAttrs[ATT_MIXED_N]           =   new OneAttr(SchemaSymbols.ATT_MIXED,
358                                                         DT_BOOLEAN,
359                                                         ATTIDX_MIXED,
360                                                         null);
361         allAttrs[ATT_NAME_R]            =   new OneAttr(SchemaSymbols.ATT_NAME,
362                                                         DT_NCNAME,
363                                                         ATTIDX_NAME,
364                                                         null);
365         allAttrs[ATT_NAMESPACE_D]       =   new OneAttr(SchemaSymbols.ATT_NAMESPACE,
366                                                         DT_NAMESPACE,
367                                                         ATTIDX_NAMESPACE,
368                                                         INT_ANY_ANY);
369         allAttrs[ATT_NAMESPACE_N]       =   new OneAttr(SchemaSymbols.ATT_NAMESPACE,
370                                                         DT_ANYURI,
371                                                         ATTIDX_NAMESPACE,
372                                                         null);
373         allAttrs[ATT_NILLABLE_D]        =   new OneAttr(SchemaSymbols.ATT_NILLABLE,
374                                                         DT_BOOLEAN,
375                                                         ATTIDX_NILLABLE,
376                                                         Boolean.FALSE);
377         allAttrs[ATT_PROCESS_C_D]       =   new OneAttr(SchemaSymbols.ATT_PROCESSCONTENTS,
378                                                         DT_PROCESSCONTENTS,
379                                                         ATTIDX_PROCESSCONTENTS,
380                                                         INT_ANY_STRICT);
381         allAttrs[ATT_PUBLIC_R]          =   new OneAttr(SchemaSymbols.ATT_PUBLIC,
382                                                         DT_TOKEN,
383                                                         ATTIDX_PUBLIC,
384                                                         null);
385         allAttrs[ATT_REF_R]             =   new OneAttr(SchemaSymbols.ATT_REF,
386                                                         DT_QNAME,
387                                                         ATTIDX_REF,
388                                                         null);
389         allAttrs[ATT_REFER_R]           =   new OneAttr(SchemaSymbols.ATT_REFER,
390                                                         DT_QNAME,
391                                                         ATTIDX_REFER,
392                                                         null);
393         allAttrs[ATT_SCHEMA_L_R]        =   new OneAttr(SchemaSymbols.ATT_SCHEMALOCATION,
394                                                         DT_ANYURI,
395                                                         ATTIDX_SCHEMALOCATION,
396                                                         null);
397         allAttrs[ATT_SCHEMA_L_N]        =   new OneAttr(SchemaSymbols.ATT_SCHEMALOCATION,
398                                                         DT_ANYURI,
399                                                         ATTIDX_SCHEMALOCATION,
400                                                         null);
401         allAttrs[ATT_SOURCE_N]          =   new OneAttr(SchemaSymbols.ATT_SOURCE,
402                                                         DT_ANYURI,
403                                                         ATTIDX_SOURCE,
404                                                         null);
405         allAttrs[ATT_SUBSTITUTION_G_N]  =   new OneAttr(SchemaSymbols.ATT_SUBSTITUTIONGROUP,
406                                                         DT_QNAME,
407                                                         ATTIDX_SUBSGROUP,
408                                                         null);
409         allAttrs[ATT_SYSTEM_N]          =   new OneAttr(SchemaSymbols.ATT_SYSTEM,
410                                                         DT_ANYURI,
411                                                         ATTIDX_SYSTEM,
412                                                         null);
413         allAttrs[ATT_TARGET_N_N]        =   new OneAttr(SchemaSymbols.ATT_TARGETNAMESPACE,
414                                                         DT_ANYURI,
415                                                         ATTIDX_TARGETNAMESPACE,
416                                                         null);
417         allAttrs[ATT_TYPE_N]            =   new OneAttr(SchemaSymbols.ATT_TYPE,
418                                                         DT_QNAME,
419                                                         ATTIDX_TYPE,
420                                                         null);
421         allAttrs[ATT_USE_D]             =   new OneAttr(SchemaSymbols.ATT_USE,
422                                                         DT_USE,
423                                                         ATTIDX_USE,
424                                                         INT_USE_OPTIONAL);
425         allAttrs[ATT_VALUE_NNI_N]       =   new OneAttr(SchemaSymbols.ATT_VALUE,
426                                                         DT_NONNEGINT,
427                                                         ATTIDX_VALUE,
428                                                         null);
429         allAttrs[ATT_VALUE_PI_N]        =   new OneAttr(SchemaSymbols.ATT_VALUE,
430                                                         DT_POSINT,
431                                                         ATTIDX_VALUE,
432                                                         null);
433         allAttrs[ATT_VALUE_STR_N]       =   new OneAttr(SchemaSymbols.ATT_VALUE,
434                                                         DT_STRING,
435                                                         ATTIDX_VALUE,
436                                                         null);
437         allAttrs[ATT_VALUE_WS_N]        =   new OneAttr(SchemaSymbols.ATT_VALUE,
438                                                         DT_WHITESPACE,
439                                                         ATTIDX_VALUE,
440                                                         null);
441         allAttrs[ATT_VERSION_N]         =   new OneAttr(SchemaSymbols.ATT_VERSION,
442                                                         DT_TOKEN,
443                                                         ATTIDX_VERSION,
444                                                         null);
445         allAttrs[ATT_XML_LANG]          =   new OneAttr(SchemaSymbols.ATT_XML_LANG,
446                                                         DT_LANGUAGE,
447                                                         ATTIDX_XML_LANG,
448                                                         null);
449         allAttrs[ATT_XPATH_R]           =   new OneAttr(SchemaSymbols.ATT_XPATH,
450                                                         DT_XPATH,
451                                                         ATTIDX_XPATH,
452                                                         null);
453         allAttrs[ATT_XPATH1_R]          =   new OneAttr(SchemaSymbols.ATT_XPATH,
454                                                         DT_XPATH1,
455                                                         ATTIDX_XPATH,
456                                                         null);
457 
458         // step 4: for each element, make a list of possible attributes
459         Container attrList;
460 
461         // for element "attribute" - global
462         attrList = Container.getContainer(5);
463         // default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N])464         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
465         // fixed = string
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N])466         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
467         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])468         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
469         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])470         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
471         // type = QName
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N])472         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTE, attrList)473         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTE, attrList);
474 
475         // for element "attribute" - local name
476         attrList = Container.getContainer(7);
477         // default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N])478         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
479         // fixed = string
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N])480         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
481         // form = (qualified | unqualified)
attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N])482         attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
483         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])484         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
485         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])486         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
487         // type = QName
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N])488         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
489         // use = (optional | prohibited | required) : optional
attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D])490         attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
fEleAttrsMapL.put(ATTRIBUTE_N, attrList)491         fEleAttrsMapL.put(ATTRIBUTE_N, attrList);
492 
493         // for element "attribute" - local ref
494         attrList = Container.getContainer(5);
495         // default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N])496         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
497         // fixed = string
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N])498         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
499         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])500         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
501         // ref = QName
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R])502         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
503         // use = (optional | prohibited | required) : optional
attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D])504         attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
fEleAttrsMapL.put(ATTRIBUTE_R, attrList)505         fEleAttrsMapL.put(ATTRIBUTE_R, attrList);
506 
507         // for element "element" - global
508         attrList = Container.getContainer(10);
509         // abstract = boolean : false
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D])510         attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
511         // block = (#all | List of (extension | restriction | substitution))
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N])512         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
513         // default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N])514         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
515         // final = (#all | List of (extension | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N])516         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
517         // fixed = string
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N])518         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
519         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])520         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
521         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])522         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
523         // nillable = boolean : false
attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D])524         attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
525         // substitutionGroup = QName
attrList.put(SchemaSymbols.ATT_SUBSTITUTIONGROUP, allAttrs[ATT_SUBSTITUTION_G_N])526         attrList.put(SchemaSymbols.ATT_SUBSTITUTIONGROUP, allAttrs[ATT_SUBSTITUTION_G_N]);
527         // type = QName
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N])528         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_ELEMENT, attrList)529         fEleAttrsMapG.put(SchemaSymbols.ELT_ELEMENT, attrList);
530 
531         // for element "element" - local name
532         attrList = Container.getContainer(10);
533         // block = (#all | List of (extension | restriction | substitution))
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N])534         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
535         // default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N])536         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
537         // fixed = string
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N])538         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
539         // form = (qualified | unqualified)
attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N])540         attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
541         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])542         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
543         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D])544         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
545         // minOccurs = nonNegativeInteger : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D])546         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
547         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])548         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
549         // nillable = boolean : false
attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D])550         attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
551         // type = QName
attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N])552         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
fEleAttrsMapL.put(ELEMENT_N, attrList)553         fEleAttrsMapL.put(ELEMENT_N, attrList);
554 
555         // for element "element" - local ref
556         attrList = Container.getContainer(4);
557         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])558         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
559         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D])560         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
561         // minOccurs = nonNegativeInteger : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D])562         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
563         // ref = QName
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R])564         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
fEleAttrsMapL.put(ELEMENT_R, attrList)565         fEleAttrsMapL.put(ELEMENT_R, attrList);
566 
567         // for element "complexType" - global
568         attrList = Container.getContainer(6);
569         // abstract = boolean : false
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D])570         attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
571         // block = (#all | List of (extension | restriction))
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK1_N])572         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK1_N]);
573         // final = (#all | List of (extension | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N])574         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
575         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])576         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
577         // mixed = boolean : false
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D])578         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
579         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])580         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
fEleAttrsMapG.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList)581         fEleAttrsMapG.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList);
582 
583         // for element "notation" - global
584         attrList = Container.getContainer(4);
585         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])586         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
587         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])588         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
589         // public = A public identifier, per ISO 8879
attrList.put(SchemaSymbols.ATT_PUBLIC, allAttrs[ATT_PUBLIC_R])590         attrList.put(SchemaSymbols.ATT_PUBLIC, allAttrs[ATT_PUBLIC_R]);
591         // system = anyURI
attrList.put(SchemaSymbols.ATT_SYSTEM, allAttrs[ATT_SYSTEM_N])592         attrList.put(SchemaSymbols.ATT_SYSTEM, allAttrs[ATT_SYSTEM_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_NOTATION, attrList)593         fEleAttrsMapG.put(SchemaSymbols.ELT_NOTATION, attrList);
594 
595 
596         // for element "complexType" - local
597         attrList = Container.getContainer(2);
598         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])599         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
600         // mixed = boolean : false
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D])601         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList)602         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList);
603 
604         // for element "simpleContent" - local
605         attrList = Container.getContainer(1);
606         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])607         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLECONTENT, attrList)608         fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLECONTENT, attrList);
609 
610         // for element "restriction" - local
611         attrList = Container.getContainer(2);
612         // base = QName
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_N])613         attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_N]);
614         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])615         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_RESTRICTION, attrList)616         fEleAttrsMapL.put(SchemaSymbols.ELT_RESTRICTION, attrList);
617 
618         // for element "extension" - local
619         attrList = Container.getContainer(2);
620         // base = QName
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_R])621         attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_R]);
622         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])623         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_EXTENSION, attrList)624         fEleAttrsMapL.put(SchemaSymbols.ELT_EXTENSION, attrList);
625 
626         // for element "attributeGroup" - local ref
627         attrList = Container.getContainer(2);
628         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])629         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
630         // ref = QName
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R])631         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList)632         fEleAttrsMapL.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList);
633 
634         // for element "anyAttribute" - local
635         attrList = Container.getContainer(3);
636         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])637         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
638         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D])639         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
640         // processContents = (lax | skip | strict) : strict
attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D])641         attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_ANYATTRIBUTE, attrList)642         fEleAttrsMapL.put(SchemaSymbols.ELT_ANYATTRIBUTE, attrList);
643 
644         // for element "complexContent" - local
645         attrList = Container.getContainer(2);
646         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])647         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
648         // mixed = boolean
attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_N])649         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXCONTENT, attrList)650         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXCONTENT, attrList);
651 
652         // for element "attributeGroup" - global
653         attrList = Container.getContainer(2);
654         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])655         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
656         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])657         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList)658         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList);
659 
660         // for element "group" - global
661         attrList = Container.getContainer(2);
662         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])663         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
664         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])665         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
fEleAttrsMapG.put(SchemaSymbols.ELT_GROUP, attrList)666         fEleAttrsMapG.put(SchemaSymbols.ELT_GROUP, attrList);
667 
668         // for element "group" - local ref
669         attrList = Container.getContainer(4);
670         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])671         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
672         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D])673         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
674         // minOccurs = nonNegativeInteger : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D])675         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
676         // ref = QName
attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R])677         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_GROUP, attrList)678         fEleAttrsMapL.put(SchemaSymbols.ELT_GROUP, attrList);
679 
680         // for element "all" - local
681         attrList = Container.getContainer(3);
682         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])683         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
684         // maxOccurs = 1 : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS1_D])685         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS1_D]);
686         // minOccurs = (0 | 1) : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS1_D])687         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS1_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_ALL, attrList)688         fEleAttrsMapL.put(SchemaSymbols.ELT_ALL, attrList);
689 
690         // for element "choice" - local
691         attrList = Container.getContainer(3);
692         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])693         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
694         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D])695         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
696         // minOccurs = nonNegativeInteger : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D])697         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_CHOICE, attrList)698         fEleAttrsMapL.put(SchemaSymbols.ELT_CHOICE, attrList);
699         // for element "sequence" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_SEQUENCE, attrList)700         fEleAttrsMapL.put(SchemaSymbols.ELT_SEQUENCE, attrList);
701 
702         // for element "any" - local
703         attrList = Container.getContainer(5);
704         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])705         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
706         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D])707         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
708         // minOccurs = nonNegativeInteger : 1
attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D])709         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
710         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D])711         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
712         // processContents = (lax | skip | strict) : strict
attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D])713         attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_ANY, attrList)714         fEleAttrsMapL.put(SchemaSymbols.ELT_ANY, attrList);
715 
716         // for element "unique" - local
717         attrList = Container.getContainer(2);
718         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])719         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
720         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])721         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_UNIQUE, attrList)722         fEleAttrsMapL.put(SchemaSymbols.ELT_UNIQUE, attrList);
723         // for element "key" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_KEY, attrList)724         fEleAttrsMapL.put(SchemaSymbols.ELT_KEY, attrList);
725 
726         // for element "keyref" - local
727         attrList = Container.getContainer(3);
728         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])729         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
730         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])731         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
732         // refer = QName
attrList.put(SchemaSymbols.ATT_REFER, allAttrs[ATT_REFER_R])733         attrList.put(SchemaSymbols.ATT_REFER, allAttrs[ATT_REFER_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_KEYREF, attrList)734         fEleAttrsMapL.put(SchemaSymbols.ELT_KEYREF, attrList);
735 
736         // for element "selector" - local
737         attrList = Container.getContainer(2);
738         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])739         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
740         // xpath = a subset of XPath expression
attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH_R])741         attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_SELECTOR, attrList)742         fEleAttrsMapL.put(SchemaSymbols.ELT_SELECTOR, attrList);
743 
744         // for element "field" - local
745         attrList = Container.getContainer(2);
746         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])747         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
748         // xpath = a subset of XPath expression
attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH1_R])749         attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH1_R]);
fEleAttrsMapL.put(SchemaSymbols.ELT_FIELD, attrList)750         fEleAttrsMapL.put(SchemaSymbols.ELT_FIELD, attrList);
751 
752         // for element "annotation" - global
753         attrList = Container.getContainer(1);
754         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])755         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_ANNOTATION, attrList)756         fEleAttrsMapG.put(SchemaSymbols.ELT_ANNOTATION, attrList);
757         // for element "annotation" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_ANNOTATION, attrList)758         fEleAttrsMapL.put(SchemaSymbols.ELT_ANNOTATION, attrList);
759 
760         // for element "appinfo" - local
761         attrList = Container.getContainer(1);
762         // source = anyURI
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N])763         attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_APPINFO, attrList)764         fEleAttrsMapG.put(SchemaSymbols.ELT_APPINFO, attrList);
fEleAttrsMapL.put(SchemaSymbols.ELT_APPINFO, attrList)765         fEleAttrsMapL.put(SchemaSymbols.ELT_APPINFO, attrList);
766 
767         // for element "documentation" - local
768         attrList = Container.getContainer(2);
769         // source = anyURI
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N])770         attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
771         // xml:lang = language
attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG])772         attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG]);
fEleAttrsMapG.put(SchemaSymbols.ELT_DOCUMENTATION, attrList)773         fEleAttrsMapG.put(SchemaSymbols.ELT_DOCUMENTATION, attrList);
fEleAttrsMapL.put(SchemaSymbols.ELT_DOCUMENTATION, attrList)774         fEleAttrsMapL.put(SchemaSymbols.ELT_DOCUMENTATION, attrList);
775 
776         // for element "simpleType" - global
777         attrList = Container.getContainer(3);
778         // final = (#all | List of (list | union | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N])779         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
780         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])781         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
782         // name = NCName
attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R])783         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
fEleAttrsMapG.put(SchemaSymbols.ELT_SIMPLETYPE, attrList)784         fEleAttrsMapG.put(SchemaSymbols.ELT_SIMPLETYPE, attrList);
785 
786         // for element "simpleType" - local
787         attrList = Container.getContainer(2);
788         // final = (#all | List of (list | union | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N])789         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
790         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])791         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLETYPE, attrList)792         fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLETYPE, attrList);
793 
794         // for element "restriction" - local
795         // already registered for complexType
796 
797         // for element "list" - local
798         attrList = Container.getContainer(2);
799         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])800         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
801         // itemType = QName
attrList.put(SchemaSymbols.ATT_ITEMTYPE, allAttrs[ATT_ITEMTYPE_N])802         attrList.put(SchemaSymbols.ATT_ITEMTYPE, allAttrs[ATT_ITEMTYPE_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_LIST, attrList)803         fEleAttrsMapL.put(SchemaSymbols.ELT_LIST, attrList);
804 
805         // for element "union" - local
806         attrList = Container.getContainer(2);
807         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])808         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
809         // memberTypes = List of QName
attrList.put(SchemaSymbols.ATT_MEMBERTYPES, allAttrs[ATT_MEMBER_T_N])810         attrList.put(SchemaSymbols.ATT_MEMBERTYPES, allAttrs[ATT_MEMBER_T_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_UNION, attrList)811         fEleAttrsMapL.put(SchemaSymbols.ELT_UNION, attrList);
812 
813         // for element "schema" - global
814         attrList = Container.getContainer(8);
815         // attributeFormDefault = (qualified | unqualified) : unqualified
attrList.put(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT, allAttrs[ATT_ATTRIBUTE_FD_D])816         attrList.put(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT, allAttrs[ATT_ATTRIBUTE_FD_D]);
817         // blockDefault = (#all | List of (extension | restriction | substitution))  : ''
attrList.put(SchemaSymbols.ATT_BLOCKDEFAULT, allAttrs[ATT_BLOCK_D_D])818         attrList.put(SchemaSymbols.ATT_BLOCKDEFAULT, allAttrs[ATT_BLOCK_D_D]);
819         // elementFormDefault = (qualified | unqualified) : unqualified
attrList.put(SchemaSymbols.ATT_ELEMENTFORMDEFAULT, allAttrs[ATT_ELEMENT_FD_D])820         attrList.put(SchemaSymbols.ATT_ELEMENTFORMDEFAULT, allAttrs[ATT_ELEMENT_FD_D]);
821         // finalDefault = (#all | List of (extension | restriction | list | union))  : ''
attrList.put(SchemaSymbols.ATT_FINALDEFAULT, allAttrs[ATT_FINAL_D_D])822         attrList.put(SchemaSymbols.ATT_FINALDEFAULT, allAttrs[ATT_FINAL_D_D]);
823         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])824         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
825         // targetNamespace = anyURI
attrList.put(SchemaSymbols.ATT_TARGETNAMESPACE, allAttrs[ATT_TARGET_N_N])826         attrList.put(SchemaSymbols.ATT_TARGETNAMESPACE, allAttrs[ATT_TARGET_N_N]);
827         // version = token
attrList.put(SchemaSymbols.ATT_VERSION, allAttrs[ATT_VERSION_N])828         attrList.put(SchemaSymbols.ATT_VERSION, allAttrs[ATT_VERSION_N]);
829         // xml:lang = language
attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG])830         attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG]);
fEleAttrsMapG.put(SchemaSymbols.ELT_SCHEMA, attrList)831         fEleAttrsMapG.put(SchemaSymbols.ELT_SCHEMA, attrList);
832 
833         // for element "include" - global
834         attrList = Container.getContainer(2);
835         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])836         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
837         // schemaLocation = anyURI
attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_R])838         attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_R]);
fEleAttrsMapG.put(SchemaSymbols.ELT_INCLUDE, attrList)839         fEleAttrsMapG.put(SchemaSymbols.ELT_INCLUDE, attrList);
840         // for element "redefine" - global
fEleAttrsMapG.put(SchemaSymbols.ELT_REDEFINE, attrList)841         fEleAttrsMapG.put(SchemaSymbols.ELT_REDEFINE, attrList);
842 
843         // for element "import" - global
844         attrList = Container.getContainer(3);
845         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])846         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
847         // namespace = anyURI
attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_N])848         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_N]);
849         // schemaLocation = anyURI
attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_N])850         attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_N]);
fEleAttrsMapG.put(SchemaSymbols.ELT_IMPORT, attrList)851         fEleAttrsMapG.put(SchemaSymbols.ELT_IMPORT, attrList);
852 
853         // for element "length" - local
854         attrList = Container.getContainer(3);
855         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])856         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
857         // value = nonNegativeInteger
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_NNI_N])858         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_NNI_N]);
859         // fixed = boolean : false
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D])860         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_LENGTH, attrList)861         fEleAttrsMapL.put(SchemaSymbols.ELT_LENGTH, attrList);
862         // for element "minLength" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_MINLENGTH, attrList)863         fEleAttrsMapL.put(SchemaSymbols.ELT_MINLENGTH, attrList);
864         // for element "maxLength" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_MAXLENGTH, attrList)865         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXLENGTH, attrList);
866         // for element "fractionDigits" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_FRACTIONDIGITS, attrList)867         fEleAttrsMapL.put(SchemaSymbols.ELT_FRACTIONDIGITS, attrList);
868 
869         // for element "totalDigits" - local
870         attrList = Container.getContainer(3);
871         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])872         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
873         // value = positiveInteger
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_PI_N])874         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_PI_N]);
875         // fixed = boolean : false
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D])876         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_TOTALDIGITS, attrList)877         fEleAttrsMapL.put(SchemaSymbols.ELT_TOTALDIGITS, attrList);
878 
879         // for element "pattern" - local
880         attrList = Container.getContainer(2);
881         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])882         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
883         // value = string
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N])884         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_PATTERN, attrList)885         fEleAttrsMapL.put(SchemaSymbols.ELT_PATTERN, attrList);
886 
887         // for element "enumeration" - local
888         attrList = Container.getContainer(2);
889         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])890         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
891         // value = anySimpleType
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N])892         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
fEleAttrsMapL.put(SchemaSymbols.ELT_ENUMERATION, attrList)893         fEleAttrsMapL.put(SchemaSymbols.ELT_ENUMERATION, attrList);
894 
895         // for element "whiteSpace" - local
896         attrList = Container.getContainer(3);
897         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])898         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
899         // value = preserve | replace | collapse
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_WS_N])900         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_WS_N]);
901         // fixed = boolean : false
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D])902         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_WHITESPACE, attrList)903         fEleAttrsMapL.put(SchemaSymbols.ELT_WHITESPACE, attrList);
904 
905         // for element "maxInclusive" - local
906         attrList = Container.getContainer(3);
907         // id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N])908         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
909         // value = anySimpleType
attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N])910         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
911         // fixed = boolean : false
attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D])912         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
fEleAttrsMapL.put(SchemaSymbols.ELT_MAXINCLUSIVE, attrList)913         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXINCLUSIVE, attrList);
914         // for element "maxExclusive" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_MAXEXCLUSIVE, attrList)915         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXEXCLUSIVE, attrList);
916         // for element "minInclusive" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_MININCLUSIVE, attrList)917         fEleAttrsMapL.put(SchemaSymbols.ELT_MININCLUSIVE, attrList);
918         // for element "minExclusive" - local
fEleAttrsMapL.put(SchemaSymbols.ELT_MINEXCLUSIVE, attrList)919         fEleAttrsMapL.put(SchemaSymbols.ELT_MINEXCLUSIVE, attrList);
920     }
921 
922     // used to resolver namespace prefixes
923     protected XSDHandler fSchemaHandler = null;
924 
925     // used to store symbols.
926     protected SymbolTable fSymbolTable = null;
927 
928     // used to store the mapping from processed element to attributes
929     protected Map<String, List<String>> fNonSchemaAttrs = new HashMap<>();
930 
931     // temprory vector, used to hold the namespace list
932     protected List<String> fNamespaceList = new ArrayList<>();
933 
934     // whether this attribute appeared in the current element
935     protected boolean[] fSeen = new boolean[ATTIDX_COUNT];
936     private static boolean[] fSeenTemp = new boolean[ATTIDX_COUNT];
937 
938     // constructor. Sets fErrorReproter and get datatype validators
XSAttributeChecker(XSDHandler schemaHandler)939     public XSAttributeChecker(XSDHandler schemaHandler) {
940         fSchemaHandler = schemaHandler;
941     }
942 
reset(SymbolTable symbolTable)943     public void reset(SymbolTable symbolTable) {
944         fSymbolTable = symbolTable;
945         fNonSchemaAttrs.clear();
946     }
947 
948     /**
949      * Check whether the specified element conforms to the attributes restriction
950      * an array of attribute values is returned. the caller must call
951      * <code>returnAttrArray</code> to return that array.
952      *
953      * @param element    which element to check
954      * @param isGlobal   whether a child of &lt;schema&gt; or &lt;redefine&gt;
955      * @param schemaDoc  the document where the element lives in
956      * @return           an array containing attribute values
957      */
checkAttributes(Element element, boolean isGlobal, XSDocumentInfo schemaDoc)958     public Object[] checkAttributes(Element element, boolean isGlobal,
959                                     XSDocumentInfo schemaDoc) {
960         return checkAttributes(element, isGlobal, schemaDoc, false);
961     }
962 
963     /**
964      * Check whether the specified element conforms to the attributes restriction
965      * an array of attribute values is returned. the caller must call
966      * <code>returnAttrArray</code> to return that array. This method also takes
967      * an extra parameter: if the element is "enumeration", whether to make a
968      * copy of the namespace context, so that the value can be resolved as a
969      * QName later.
970      *
971      * @param element      which element to check
972      * @param isGlobal     whether a child of &lt;schema&gt; or &lt;redefine&gt;
973      * @param schemaDoc    the document where the element lives in
974      * @param enumAsQName  whether to tread enumeration value as QName
975      * @return             an array containing attribute values
976      */
977     @SuppressWarnings("unchecked")
checkAttributes(Element element, boolean isGlobal, XSDocumentInfo schemaDoc, boolean enumAsQName)978     public Object[] checkAttributes(Element element, boolean isGlobal,
979                                     XSDocumentInfo schemaDoc, boolean enumAsQName) {
980         if (element == null)
981             return null;
982 
983         // get all attributes
984         Attr[] attrs = DOMUtil.getAttrs(element);
985 
986         // update NamespaceSupport
987         resolveNamespace(element, attrs, schemaDoc.fNamespaceSupport);
988 
989         String uri = DOMUtil.getNamespaceURI(element);
990         String elName = DOMUtil.getLocalName(element);
991 
992         if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(uri)) {
993             reportSchemaError("s4s-elt-schema-ns", new Object[] {elName}, element);
994         }
995 
996         Map<String, Container> eleAttrsMap = fEleAttrsMapG;
997         String lookupName = elName;
998 
999         // REVISIT: only local element and attribute are different from others.
1000         //          it's possible to have either name or ref. all the others
1001         //          are only allowed to have one of name or ref, or neither of them.
1002         //          we'd better move such checking to the traverser.
1003         if (!isGlobal) {
1004             eleAttrsMap = fEleAttrsMapL;
1005             if (elName.equals(SchemaSymbols.ELT_ELEMENT)) {
1006                 if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1007                     lookupName = ELEMENT_R;
1008                 else
1009                     lookupName = ELEMENT_N;
1010             } else if (elName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1011                 if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1012                     lookupName = ATTRIBUTE_R;
1013                 else
1014                     lookupName = ATTRIBUTE_N;
1015             }
1016         }
1017 
1018         // get desired attribute list of this element
1019         Container attrList = eleAttrsMap.get(lookupName);
1020         if (attrList == null) {
1021             // should never gets here.
1022             // when this method is called, the call already knows that
1023             // the element can appear.
1024             reportSchemaError ("s4s-elt-invalid", new Object[] {elName}, element);
1025             return null;
1026         }
1027 
1028         Object[] attrValues = getAvailableArray();
1029         long fromDefault = 0;
1030 
1031         // clear the "seen" flag.
1032         System.arraycopy(fSeenTemp, 0, fSeen, 0, ATTIDX_COUNT);
1033 
1034         // traverse all attributes
1035         int length = attrs.length;
1036         Attr sattr = null;
1037         for (int i = 0; i < length; i++) {
1038             sattr = attrs[i];
1039             // get the attribute name/value
1040             //String attrName = DOMUtil.getLocalName(sattr);
1041             String attrName = sattr.getName();
1042             String attrURI = DOMUtil.getNamespaceURI(sattr);
1043             String attrVal = DOMUtil.getValue(sattr);
1044 
1045             if (attrName.startsWith("xml")) {
1046                 String attrPrefix = DOMUtil.getPrefix(sattr);
1047                 // we don't want to add namespace declarations to the non-schema attributes
1048                 if ("xmlns".equals(attrPrefix) || "xmlns".equals(attrName)) {
1049                     continue;
1050                 }
1051                 // Both <schema> and <documentation> may have an xml:lang attribute.
1052                 // Set the URI for this attribute to null so that we process it
1053                 // like any other schema attribute.
1054                 else if (SchemaSymbols.ATT_XML_LANG.equals(attrName) &&
1055                         (SchemaSymbols.ELT_SCHEMA.equals(elName) ||
1056                                 SchemaSymbols.ELT_DOCUMENTATION.equals(elName))) {
1057                     attrURI = null;
1058                 }
1059             }
1060 
1061             // for attributes with namespace prefix
1062             //
1063             if (attrURI != null && attrURI.length() != 0) {
1064                 // attributes with schema namespace are not allowed
1065                 // and not allowed on "document" and "appInfo"
1066                 if (attrURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
1067                     reportSchemaError ("s4s-att-not-allowed", new Object[] {elName, attrName}, element);
1068                 }
1069                 else {
1070                     List<String> temp;
1071                     if(attrValues[ATTIDX_NONSCHEMA] == null) {
1072                         // these are usually small
1073                         temp = new ArrayList<>(4);
1074                     } else {
1075                         temp = (List<String>)attrValues[ATTIDX_NONSCHEMA];
1076                     }
1077                     temp.add(attrName);
1078                     temp.add(attrVal);
1079                     attrValues[ATTIDX_NONSCHEMA] = temp;
1080                     // for attributes from other namespace
1081                     // store them in a list, and TRY to validate them after
1082                     // schema traversal (because it's "lax")
1083                     //otherValues.put(attrName, attrVal);
1084                     // REVISIT:  actually use this some day...
1085                     // String attrRName = attrURI + "," + attrName;
1086                     // List<String> values = (ArrayList<String>)fNonSchemaAttrs.get(attrRName);
1087                     // if (values == null) {
1088                         // values = new ArrayList<>();
1089                         // values.add(attrName);
1090                         // values.add(elName);
1091                         // values.add(attrVal);
1092                         // fNonSchemaAttrs.put(attrRName, values);
1093                     // }
1094                     // else {
1095                         // values.add(elName);
1096                         // values.add(attrVal);
1097                     // }
1098                 }
1099                 continue;
1100             }
1101 
1102             // check whether this attribute is allowed
1103             OneAttr oneAttr = attrList.get(attrName);
1104             if (oneAttr == null) {
1105                 reportSchemaError ("s4s-att-not-allowed",
1106                                    new Object[] {elName, attrName},
1107                                    element);
1108                 continue;
1109             }
1110 
1111             // we've seen this attribute
1112             fSeen[oneAttr.valueIndex] = true;
1113 
1114             // check the value against the datatype
1115             try {
1116                 // no checking on string needs to be done here.
1117                 // no checking on xpath needs to be done here.
1118                 // xpath values are validated in xpath parser
1119                 if (oneAttr.dvIndex >= 0) {
1120                     if (oneAttr.dvIndex != DT_STRING &&
1121                         oneAttr.dvIndex != DT_XPATH &&
1122                         oneAttr.dvIndex != DT_XPATH1) {
1123                         XSSimpleType dv = fExtraDVs[oneAttr.dvIndex];
1124                         Object avalue = dv.validate(attrVal, schemaDoc.fValidationContext, null);
1125                         // kludge to handle chameleon includes/redefines...
1126                         if (oneAttr.dvIndex == DT_QNAME) {
1127                             QName qname = (QName)avalue;
1128                             if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1129                                 qname.uri = schemaDoc.fTargetNamespace;
1130                         }
1131                         attrValues[oneAttr.valueIndex] = avalue;
1132                     } else {
1133                         attrValues[oneAttr.valueIndex] = attrVal;
1134                     }
1135                 }
1136                 else {
1137                     attrValues[oneAttr.valueIndex] = validate(attrValues, attrName, attrVal, oneAttr.dvIndex, schemaDoc);
1138                 }
1139             } catch (InvalidDatatypeValueException ide) {
1140                 reportSchemaError ("s4s-att-invalid-value",
1141                                    new Object[] {elName, attrName, ide.getMessage()},
1142                                    element);
1143                 if (oneAttr.dfltValue != null)
1144                     //attrValues.put(attrName, oneAttr.dfltValue);
1145                     attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1146             }
1147 
1148             // For "enumeration", and type is possible to be a QName, we need
1149             // to return namespace context for later QName resolution.
1150             if (elName.equals(SchemaSymbols.ELT_ENUMERATION) && enumAsQName) {
1151                 attrValues[ATTIDX_ENUMNSDECLS] = new SchemaNamespaceSupport(schemaDoc.fNamespaceSupport);
1152             }
1153         }
1154 
1155         // apply default values
1156         OneAttr[] reqAttrs = attrList.values;
1157         for (int i = 0; i < reqAttrs.length; i++) {
1158             OneAttr oneAttr = reqAttrs[i];
1159 
1160             // if the attribute didn't apprear, and
1161             // if the attribute is optional with default value, apply it
1162             if (oneAttr.dfltValue != null && !fSeen[oneAttr.valueIndex]) {
1163                 //attrValues.put(oneAttr.name, oneAttr.dfltValue);
1164                 attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1165                 fromDefault |= (1<<oneAttr.valueIndex);
1166             }
1167         }
1168 
1169         attrValues[ATTIDX_FROMDEFAULT] = fromDefault;
1170         //attrValues[ATTIDX_OTHERVALUES] = otherValues;
1171 
1172         // Check that minOccurs isn't greater than maxOccurs.
1173         // p-props-correct 2.1
1174         if (attrValues[ATTIDX_MAXOCCURS] != null) {
1175             int min = ((XInt)attrValues[ATTIDX_MINOCCURS]).intValue();
1176             int max = ((XInt)attrValues[ATTIDX_MAXOCCURS]).intValue();
1177             if (max != SchemaSymbols.OCCURRENCE_UNBOUNDED) {
1178 
1179                 // maxOccurLimit is only check in secure mode
1180                 if (fSchemaHandler.fSecurityManager != null) {
1181                     String localName = element.getLocalName();
1182 
1183                 // The maxOccurs restriction no longer applies to elements
1184                     // and wildcards in a sequence in which they are the only
1185                     // particle. These are now validated using a constant
1186                     // space algorithm. The restriction still applies to all
1187                     // other cases.
1188 
1189                     // Determine if constant-space algorithm can be applied
1190                     final boolean optimize =
1191                             (localName.equals("element") || localName.equals("any")) &&
1192                             (element.getNextSibling() == null) &&
1193                             (element.getPreviousSibling() == null) &&
1194                             (element.getParentNode().getLocalName().equals("sequence"));
1195 
1196                     if (!optimize) {
1197                     //Revisit :: IMO this is not right place to check
1198                     // maxOccurNodeLimit.
1199                     int maxOccurNodeLimit = fSchemaHandler.fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT);
1200                     if (max > maxOccurNodeLimit && !fSchemaHandler.fSecurityManager.isNoLimit(maxOccurNodeLimit)) {
1201                         reportSchemaFatalError("MaxOccurLimit", new Object[] {maxOccurNodeLimit}, element);
1202 
1203                         // reset max values in case processing continues on error
1204                         attrValues[ATTIDX_MAXOCCURS] = fXIntPool.getXInt(maxOccurNodeLimit);
1205                                                 //new Integer(maxOccurNodeLimit);
1206                         max = maxOccurNodeLimit;
1207                     }
1208                 }
1209                 }
1210 
1211                 if (min > max) {
1212                     reportSchemaError ("p-props-correct.2.1",
1213                                        new Object[] {elName, attrValues[ATTIDX_MINOCCURS], attrValues[ATTIDX_MAXOCCURS]},
1214                                        element);
1215                     attrValues[ATTIDX_MINOCCURS] = attrValues[ATTIDX_MAXOCCURS];
1216                 }
1217             }
1218         }
1219 
1220         return attrValues;
1221     }
1222 
validate(Object[] attrValues, String attr, String ivalue, int dvIndex, XSDocumentInfo schemaDoc)1223     private Object validate(Object[] attrValues, String attr, String ivalue, int dvIndex,
1224                             XSDocumentInfo schemaDoc) throws InvalidDatatypeValueException {
1225         if (ivalue == null)
1226             return null;
1227 
1228         // To validate these types, we don't actually need to normalize the
1229         // strings. We only need to remove the whitespace from both ends.
1230         // In some special cases (list types), StringTokenizer can correctly
1231         // process the un-normalized whitespace.
1232 
1233         String value = XMLChar.trim(ivalue);
1234         Object retValue = null;
1235         List<QName> memberType;
1236         int choice;
1237 
1238         switch (dvIndex) {
1239         case DT_BOOLEAN:
1240             if (value.equals(SchemaSymbols.ATTVAL_FALSE) ||
1241                 value.equals(SchemaSymbols.ATTVAL_FALSE_0)) {
1242                 retValue = Boolean.FALSE;
1243             } else if (value.equals(SchemaSymbols.ATTVAL_TRUE) ||
1244                        value.equals(SchemaSymbols.ATTVAL_TRUE_1)) {
1245                 retValue = Boolean.TRUE;
1246             } else {
1247                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "boolean"});
1248             }
1249             break;
1250         case DT_NONNEGINT:
1251             try {
1252                 if (value.length() > 0 && value.charAt(0) == '+')
1253                     value = value.substring(1);
1254                 retValue = fXIntPool.getXInt(Integer.parseInt(value));
1255             } catch (NumberFormatException e) {
1256                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
1257             }
1258             if (((XInt)retValue).intValue() < 0)
1259                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
1260             break;
1261         case DT_POSINT:
1262             try {
1263                 if (value.length() > 0 && value.charAt(0) == '+')
1264                     value = value.substring(1);
1265                 retValue = fXIntPool.getXInt(Integer.parseInt(value));
1266             } catch (NumberFormatException e) {
1267                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
1268             }
1269             if (((XInt)retValue).intValue() <= 0)
1270                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
1271             break;
1272         case DT_BLOCK:
1273             // block = (#all | List of (extension | restriction | substitution))
1274             choice = 0;
1275             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1276                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1277                          XSConstants.DERIVATION_RESTRICTION;
1278             }
1279             else {
1280                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1281                 while (t.hasMoreTokens()) {
1282                     String token = t.nextToken ();
1283 
1284                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1285                         choice |= XSConstants.DERIVATION_EXTENSION;
1286                     }
1287                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1288                         choice |= XSConstants.DERIVATION_RESTRICTION;
1289                     }
1290                     else if (token.equals (SchemaSymbols.ATTVAL_SUBSTITUTION)) {
1291                         choice |= XSConstants.DERIVATION_SUBSTITUTION;
1292                     }
1293                     else {
1294                         throw new InvalidDatatypeValueException(
1295                                 "cvc-datatype-valid.1.2.3", new Object[]{value,
1296                                     "(#all | List of (extension | restriction | substitution))"});
1297                     }
1298                 }
1299             }
1300             retValue = fXIntPool.getXInt(choice);
1301             break;
1302         case DT_BLOCK1:
1303         case DT_FINAL:
1304             // block = (#all | List of (extension | restriction))
1305             // final = (#all | List of (extension | restriction))
1306             choice = 0;
1307             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1308                 //choice = SchemaSymbols.EXTENSION|SchemaSymbols.RESTRICTION;
1309                 // REVISIT: if #all, then make the result the combination of
1310                 //          everything: substitution/externsion/restriction/list/union.
1311                 //          would this be a problem?
1312                 // the reason doing so is that when final/blockFinal on <schema>
1313                 // is #all, it's not always the same as the conbination of those
1314                 // values allowed by final/blockFinal.
1315                 // for example, finalDefault="#all" is not always the same as
1316                 // finalDefault="extension restriction".
1317                 // if finalDefault="#all", final on any simple type would be
1318                 // "extension restriction list union".
1319                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1320                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1321                          XSConstants.DERIVATION_UNION;
1322             }
1323             else {
1324                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1325                 while (t.hasMoreTokens()) {
1326                     String token = t.nextToken ();
1327 
1328                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1329                         choice |= XSConstants.DERIVATION_EXTENSION;
1330                     }
1331                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1332                         choice |= XSConstants.DERIVATION_RESTRICTION;
1333                     }
1334                     else {
1335                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction))"});
1336                     }
1337                 }
1338             }
1339             retValue = fXIntPool.getXInt(choice);
1340             break;
1341         case DT_FINAL1:
1342             // final = (#all | List of (list | union | restriction))
1343             choice = 0;
1344             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1345                 //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1346                 //         SchemaSymbols.UNION;
1347                 // REVISIT: if #all, then make the result the combination of
1348                 //          everything: substitution/externsion/restriction/list/union.
1349                 //          would this be a problem?
1350                 // same reason as above DT_BLOCK1/DT_FINAL
1351                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1352                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1353                          XSConstants.DERIVATION_UNION;
1354             }
1355             else {
1356                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1357                 while (t.hasMoreTokens()) {
1358                     String token = t.nextToken ();
1359 
1360                     if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1361                         choice |= XSConstants.DERIVATION_LIST;
1362                     }
1363                     else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1364                         choice |= XSConstants.DERIVATION_UNION;
1365                     }
1366                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1367                         choice |= XSConstants.DERIVATION_RESTRICTION;
1368                     }
1369                     else {
1370                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (list | union | restriction))"});
1371                     }
1372                 }
1373             }
1374             retValue = fXIntPool.getXInt(choice);
1375             break;
1376         case DT_FINAL2:
1377             // finalDefault = (#all | List of (extension | restriction | list | union))
1378             choice = 0;
1379             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1380                 //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1381                 //         SchemaSymbols.UNION;
1382                 // REVISIT: if #all, then make the result the combination of
1383                 //          everything: substitution/externsion/restriction/list/union.
1384                 //          would this be a problem?
1385                 // same reason as above DT_BLOCK1/DT_FINAL
1386                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1387                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1388                          XSConstants.DERIVATION_UNION;
1389             }
1390             else {
1391                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1392                 while (t.hasMoreTokens()) {
1393                     String token = t.nextToken ();
1394 
1395                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1396                         choice |= XSConstants.DERIVATION_EXTENSION;
1397                     }
1398                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1399                         choice |= XSConstants.DERIVATION_RESTRICTION;
1400                     }
1401                     else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1402                         choice |= XSConstants.DERIVATION_LIST;
1403                     }
1404                     else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1405                         choice |= XSConstants.DERIVATION_UNION;
1406                     }
1407                     else {
1408                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction | list | union))"});
1409                     }
1410                 }
1411             }
1412             retValue = fXIntPool.getXInt(choice);
1413             break;
1414         case DT_FORM:
1415             // form = (qualified | unqualified)
1416             if (value.equals (SchemaSymbols.ATTVAL_QUALIFIED))
1417                 retValue = INT_QUALIFIED;
1418             else if (value.equals (SchemaSymbols.ATTVAL_UNQUALIFIED))
1419                 retValue = INT_UNQUALIFIED;
1420             else
1421                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1422                                                         new Object[]{value, "(qualified | unqualified)"});
1423             break;
1424         case DT_MAXOCCURS:
1425             // maxOccurs = (nonNegativeInteger | unbounded)
1426             if (value.equals(SchemaSymbols.ATTVAL_UNBOUNDED)) {
1427                 retValue = INT_UNBOUNDED;
1428             } else {
1429                 try {
1430                     retValue = validate(attrValues, attr, value, DT_NONNEGINT, schemaDoc);
1431                 } catch (NumberFormatException e) {
1432                     throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(nonNegativeInteger | unbounded)"});
1433                 }
1434             }
1435             break;
1436         case DT_MAXOCCURS1:
1437             // maxOccurs = 1
1438             if (value.equals("1"))
1439                 retValue = fXIntPool.getXInt(1);
1440             else
1441                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1442                                                         new Object[]{value, "(1)"});
1443             break;
1444         case DT_MEMBERTYPES:
1445             // memberTypes = List of QName
1446             memberType = new ArrayList<>();
1447             try {
1448                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1449                 while (t.hasMoreTokens()) {
1450                     String token = t.nextToken ();
1451                     QName qname = (QName)fExtraDVs[DT_QNAME].validate(token, schemaDoc.fValidationContext, null);
1452                     // kludge to handle chameleon includes/redefines...
1453                     if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1454                         qname.uri = schemaDoc.fTargetNamespace;
1455                     memberType.add(qname);
1456                 }
1457                 retValue = memberType;
1458             }
1459             catch (InvalidDatatypeValueException ide) {
1460                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.2", new Object[]{value, "(List of QName)"});
1461             }
1462             break;
1463         case DT_MINOCCURS1:
1464             // minOccurs = (0 | 1)
1465             if (value.equals("0"))
1466                 retValue = fXIntPool.getXInt(0);
1467             else if (value.equals("1"))
1468                 retValue = fXIntPool.getXInt(1);
1469             else
1470                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1471                                                         new Object[]{value, "(0 | 1)"});
1472             break;
1473         case DT_NAMESPACE:
1474             // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )
1475             if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY)) {
1476                 // ##any
1477                 retValue = INT_ANY_ANY;
1478             } else if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
1479                 // ##other
1480                 retValue = INT_ANY_NOT;
1481                 String[] list = new String[2];
1482                 list[0] = schemaDoc.fTargetNamespace;
1483                 list[1] = null;
1484                 attrValues[ATTIDX_NAMESPACE_LIST] = list;
1485             } else {
1486                 // list
1487                 retValue = INT_ANY_LIST;
1488 
1489                 fNamespaceList.clear();
1490 
1491                 // tokenize
1492                 StringTokenizer tokens = new StringTokenizer(value, " \n\t\r");
1493                 String token;
1494                 String tempNamespace;
1495                 try {
1496                     while (tokens.hasMoreTokens()) {
1497                         token = tokens.nextToken();
1498                         if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
1499                             tempNamespace = null;
1500                         } else if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS)) {
1501                             tempNamespace = schemaDoc.fTargetNamespace;
1502                         } else {
1503                             // we have found namespace URI here
1504                             // need to add it to the symbol table
1505                             fExtraDVs[DT_ANYURI].validate(token, schemaDoc.fValidationContext, null);
1506                             tempNamespace = fSymbolTable.addSymbol(token);
1507                         }
1508 
1509                         //check for duplicate namespaces in the list
1510                         if (!fNamespaceList.contains(tempNamespace)) {
1511                             fNamespaceList.add(tempNamespace);
1512                         }
1513                     }
1514                 } catch (InvalidDatatypeValueException ide) {
1515                     throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
1516                             new Object[]{value,
1517                                 "((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )"});
1518                 }
1519 
1520                 // convert the vector to an array
1521                 int num = fNamespaceList.size();
1522                 String[] list = new String[num];
1523                 list = fNamespaceList.toArray(list);
1524                 attrValues[ATTIDX_NAMESPACE_LIST] = list;
1525             }
1526             break;
1527         case DT_PROCESSCONTENTS:
1528             // processContents = (lax | skip | strict)
1529             if (value.equals (SchemaSymbols.ATTVAL_STRICT))
1530                 retValue = INT_ANY_STRICT;
1531             else if (value.equals (SchemaSymbols.ATTVAL_LAX))
1532                 retValue = INT_ANY_LAX;
1533             else if (value.equals (SchemaSymbols.ATTVAL_SKIP))
1534                 retValue = INT_ANY_SKIP;
1535             else
1536                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1537                                                         new Object[]{value, "(lax | skip | strict)"});
1538             break;
1539         case DT_USE:
1540             // use = (optional | prohibited | required)
1541             if (value.equals (SchemaSymbols.ATTVAL_OPTIONAL))
1542                 retValue = INT_USE_OPTIONAL;
1543             else if (value.equals (SchemaSymbols.ATTVAL_REQUIRED))
1544                 retValue = INT_USE_REQUIRED;
1545             else if (value.equals (SchemaSymbols.ATTVAL_PROHIBITED))
1546                 retValue = INT_USE_PROHIBITED;
1547             else
1548                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1549                                                         new Object[]{value, "(optional | prohibited | required)"});
1550             break;
1551         case DT_WHITESPACE:
1552             // value = preserve | replace | collapse
1553             if (value.equals (SchemaSymbols.ATTVAL_PRESERVE))
1554                 retValue = INT_WS_PRESERVE;
1555             else if (value.equals (SchemaSymbols.ATTVAL_REPLACE))
1556                 retValue = INT_WS_REPLACE;
1557             else if (value.equals (SchemaSymbols.ATTVAL_COLLAPSE))
1558                 retValue = INT_WS_COLLAPSE;
1559             else
1560                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1561                                                         new Object[]{value, "(preserve | replace | collapse)"});
1562             break;
1563         }
1564 
1565         return retValue;
1566     }
1567 
reportSchemaFatalError(String key, Object[] args, Element ele)1568     void reportSchemaFatalError (String key, Object[] args, Element ele) {
1569         fSchemaHandler.reportSchemaFatalError(key, args, ele);
1570     }
1571 
reportSchemaError(String key, Object[] args, Element ele)1572     void reportSchemaError (String key, Object[] args, Element ele) {
1573         fSchemaHandler.reportSchemaError(key, args, ele);
1574     }
1575 
1576     // validate attriubtes from non-schema namespaces
1577     // REVISIT: why we store the attributes in this way? why not just a list
1578     //          of structure {element node, attr name/qname, attr value)?
1579     // REVISIT: pass the proper element node to reportSchemaError
checkNonSchemaAttributes(XSGrammarBucket grammarBucket)1580     public void checkNonSchemaAttributes(XSGrammarBucket grammarBucket) {
1581         // for all attributes
1582         XSAttributeDecl attrDecl;
1583         for (Map.Entry<String, List<String>> entry : fNonSchemaAttrs.entrySet()) {
1584             // get name, uri, localpart
1585             String attrRName = entry.getKey();
1586             String attrURI = attrRName.substring(0,attrRName.indexOf(','));
1587             String attrLocal = attrRName.substring(attrRName.indexOf(',')+1);
1588             // find associated grammar
1589             SchemaGrammar sGrammar = grammarBucket.getGrammar(attrURI);
1590             if (sGrammar == null) {
1591                 continue;
1592             }
1593             // and get the datatype validator, if there is one
1594             attrDecl = sGrammar.getGlobalAttributeDecl(attrLocal);
1595             if (attrDecl == null) {
1596                 continue;
1597             }
1598             XSSimpleType dv = (XSSimpleType)attrDecl.getTypeDefinition();
1599             if (dv == null) {
1600                 continue;
1601             }
1602 
1603             // get all values appeared with this attribute name
1604             List<String> values = entry.getValue();
1605             String elName;
1606             String attrName = values.get(0);
1607             // for each of the values
1608             int count = values.size();
1609             for (int i = 1; i < count; i += 2) {
1610                 elName = values.get(i);
1611                 try {
1612                     // and validate it using the XSSimpleType
1613                     // REVISIT: what would be the proper validation context?
1614                     //          guess we need to save that in the vectors too.
1615                     dv.validate(values.get(i+1), null, null);
1616                 } catch(InvalidDatatypeValueException ide) {
1617                     reportSchemaError ("s4s-att-invalid-value",
1618                                        new Object[] {elName, attrName, ide.getMessage()},
1619                                        null);
1620                 }
1621             }
1622         }
1623     }
1624 
1625     // normalize the string according to the whiteSpace facet
normalize(String content, short ws)1626     public static String normalize(String content, short ws) {
1627         int len = content == null ? 0 : content.length();
1628         if (len == 0 || ws == XSSimpleType.WS_PRESERVE)
1629             return content;
1630 
1631         StringBuilder sb = new StringBuilder();
1632         if (ws == XSSimpleType.WS_REPLACE) {
1633             char ch;
1634             // when it's replace, just replace #x9, #xa, #xd by #x20
1635             for (int i = 0; i < len; i++) {
1636                 ch = content.charAt(i);
1637                 if (ch != 0x9 && ch != 0xa && ch != 0xd)
1638                     sb.append(ch);
1639                 else
1640                     sb.append((char)0x20);
1641             }
1642         } else {
1643             char ch;
1644             int i;
1645             boolean isLeading = true;
1646             // when it's collapse
1647             for (i = 0; i < len; i++) {
1648                 ch = content.charAt(i);
1649                 // append real characters, so we passed leading ws
1650                 if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
1651                     sb.append(ch);
1652                     isLeading = false;
1653                 }
1654                 else {
1655                     // for whitespaces, we skip all following ws
1656                     for (; i < len-1; i++) {
1657                         ch = content.charAt(i+1);
1658                         if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
1659                             break;
1660                     }
1661                     // if it's not a leading or tailing ws, then append a space
1662                     if (i < len - 1 && !isLeading)
1663                         sb.append((char)0x20);
1664                 }
1665             }
1666         }
1667 
1668         return sb.toString();
1669     }
1670 
1671     // the following part implements an attribute-value-array pool.
1672     // when checkAttribute is called, it calls getAvailableArray to get
1673     // an array from the pool; when the caller is done with the array,
1674     // it calls returnAttrArray to return that array to the pool.
1675 
1676     // initial size of the array pool. 10 is big enough
1677     static final int INIT_POOL_SIZE = 10;
1678     // the incremental size of the array pool
1679     static final int INC_POOL_SIZE  = 10;
1680     // the array pool
1681     Object[][] fArrayPool = new Object[INIT_POOL_SIZE][ATTIDX_COUNT];
1682     // used to clear the returned array
1683     // I think System.arrayCopy is more efficient than setting 35 fields to null
1684     private static Object[] fTempArray = new Object[ATTIDX_COUNT];
1685     // current position of the array pool (# of arrays not returned)
1686     int fPoolPos = 0;
1687 
1688     // get the next available array
getAvailableArray()1689     protected Object[] getAvailableArray() {
1690         // if no array left in the pool, increase the pool size
1691         if (fArrayPool.length == fPoolPos) {
1692             // increase size
1693             fArrayPool = new Object[fPoolPos+INC_POOL_SIZE][];
1694             // initialize each *new* array
1695             for (int i = fPoolPos; i < fArrayPool.length; i++)
1696                 fArrayPool[i] = new Object[ATTIDX_COUNT];
1697         }
1698         // get the next available one
1699         Object[] retArray = fArrayPool[fPoolPos];
1700         // clear it from the pool. this is for GC: if a caller forget to
1701         // return the array, we want that array to be GCed.
1702         fArrayPool[fPoolPos++] = null;
1703         // to make sure that one array is not returned twice, we use
1704         // the last entry to indicate whether an array is already returned
1705         // now set it to false.
1706         System.arraycopy(fTempArray, 0, retArray, 0, ATTIDX_COUNT-1);
1707         retArray[ATTIDX_ISRETURNED] = Boolean.FALSE;
1708 
1709         return retArray;
1710     }
1711 
1712     // return an array back to the pool
1713     @SuppressWarnings("unchecked")
returnAttrArray(Object[] attrArray, XSDocumentInfo schemaDoc)1714     public void returnAttrArray(Object[] attrArray, XSDocumentInfo schemaDoc) {
1715         // pop the namespace context
1716         if (schemaDoc != null)
1717             schemaDoc.fNamespaceSupport.popContext();
1718 
1719         // if 1. the pool is full; 2. the array is null;
1720         // 3. the array is of wrong size; 4. the array is already returned
1721         // then we can't accept this array to be returned
1722         if (fPoolPos == 0 ||
1723             attrArray == null ||
1724             attrArray.length != ATTIDX_COUNT ||
1725                 ((Boolean)attrArray[ATTIDX_ISRETURNED])) {
1726             return;
1727         }
1728 
1729         // mark this array as returned
1730         attrArray[ATTIDX_ISRETURNED] = Boolean.TRUE;
1731         // better clear nonschema vector
1732         if(attrArray[ATTIDX_NONSCHEMA] != null)
1733             ((List<String>)attrArray[ATTIDX_NONSCHEMA]).clear();
1734         // and put it into the pool
1735         fArrayPool[--fPoolPos] = attrArray;
1736     }
1737 
resolveNamespace(Element element, Attr[] attrs, SchemaNamespaceSupport nsSupport)1738     public void resolveNamespace(Element element, Attr[] attrs,
1739                                  SchemaNamespaceSupport nsSupport) {
1740         // push the namespace context
1741         nsSupport.pushContext();
1742 
1743         // search for new namespace bindings
1744         int length = attrs.length;
1745         Attr sattr = null;
1746         String rawname, prefix, uri;
1747         for (int i = 0; i < length; i++) {
1748             sattr = attrs[i];
1749             rawname = DOMUtil.getName(sattr);
1750             prefix = null;
1751             if (rawname.equals(XMLSymbols.PREFIX_XMLNS))
1752                 prefix = XMLSymbols.EMPTY_STRING;
1753             else if (rawname.startsWith("xmlns:"))
1754                 prefix = fSymbolTable.addSymbol(DOMUtil.getLocalName(sattr));
1755             if (prefix != null) {
1756                 uri = fSymbolTable.addSymbol(DOMUtil.getValue(sattr));
1757                 nsSupport.declarePrefix(prefix, uri.length()!=0 ? uri : null);
1758             }
1759         }
1760     }
1761 }
1762 
1763 class OneAttr {
1764     // name of the attribute
1765     public String name;
1766     // index of the datatype validator
1767     public int dvIndex;
1768     // whether it's optional, and has default value
1769     public int valueIndex;
1770     // the default value of this attribute
1771     public Object dfltValue;
1772 
OneAttr(String name, int dvIndex, int valueIndex, Object dfltValue)1773     public OneAttr(String name, int dvIndex, int valueIndex, Object dfltValue) {
1774         this.name = name;
1775         this.dvIndex = dvIndex;
1776         this.valueIndex = valueIndex;
1777         this.dfltValue = dfltValue;
1778     }
1779 }
1780 
1781 abstract class Container {
1782     static final int THRESHOLD = 5;
getContainer(int size)1783     static Container getContainer(int size) {
1784         if (size > THRESHOLD)
1785             return new LargeContainer(size);
1786         else
1787             return new SmallContainer(size);
1788     }
put(String key, OneAttr value)1789     abstract void put(String key, OneAttr value);
get(String key)1790     abstract OneAttr get(String key);
1791 
1792     OneAttr[] values;
1793     int pos = 0;
1794 }
1795 
1796 class SmallContainer extends Container {
1797     String[] keys;
SmallContainer(int size)1798     SmallContainer(int size) {
1799         keys = new String[size];
1800         values = new OneAttr[size];
1801     }
put(String key, OneAttr value)1802     void put(String key, OneAttr value) {
1803         keys[pos] = key;
1804         values[pos++] = value;
1805     }
get(String key)1806     OneAttr get(String key) {
1807         for (int i = 0; i < pos; i++) {
1808             if (keys[i].equals(key)) {
1809                 return values[i];
1810             }
1811         }
1812         return null;
1813     }
1814 }
1815 
1816 class LargeContainer extends Container {
1817     Map<String, OneAttr> items;
LargeContainer(int size)1818     LargeContainer(int size) {
1819         items = new HashMap<>(size*2+1);
1820         values = new OneAttr[size];
1821     }
put(String key, OneAttr value)1822     void put(String key, OneAttr value) {
1823         items.put(key, value);
1824         values[pos++] = value;
1825     }
get(String key)1826     OneAttr get(String key) {
1827         OneAttr ret = items.get(key);
1828         return ret;
1829     }
1830 }
1831