1 /*
   2  * Copyright (c) 2015, 2016, 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.HashMap;
  41 import java.util.Iterator;
  42 import java.util.Map;
  43 import java.util.StringTokenizer;
  44 import java.util.Vector;
  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  * @version $Id: XSAttributeChecker.java,v 1.12 2010-11-01 04:40:02 joehw Exp $
  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 fEleAttrsMapG = new HashMap(29);
 149     // for 39 local elememnts
 150     private static final Map 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
 464         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
 465         // fixed = string
 466         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
 467         // id = ID
 468         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 469         // name = NCName
 470         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 471         // type = QName
 472         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
 473         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTE, attrList);
 474 
 475         // for element "attribute" - local name
 476         attrList = Container.getContainer(7);
 477         // default = string
 478         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
 479         // fixed = string
 480         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
 481         // form = (qualified | unqualified)
 482         attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
 483         // id = ID
 484         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 485         // name = NCName
 486         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 487         // type = QName
 488         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
 489         // use = (optional | prohibited | required) : optional
 490         attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
 491         fEleAttrsMapL.put(ATTRIBUTE_N, attrList);
 492 
 493         // for element "attribute" - local ref
 494         attrList = Container.getContainer(5);
 495         // default = string
 496         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
 497         // fixed = string
 498         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
 499         // id = ID
 500         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 501         // ref = QName
 502         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
 503         // use = (optional | prohibited | required) : optional
 504         attrList.put(SchemaSymbols.ATT_USE, allAttrs[ATT_USE_D]);
 505         fEleAttrsMapL.put(ATTRIBUTE_R, attrList);
 506 
 507         // for element "element" - global
 508         attrList = Container.getContainer(10);
 509         // abstract = boolean : false
 510         attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
 511         // block = (#all | List of (extension | restriction | substitution))
 512         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
 513         // default = string
 514         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
 515         // final = (#all | List of (extension | restriction))
 516         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
 517         // fixed = string
 518         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
 519         // id = ID
 520         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 521         // name = NCName
 522         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 523         // nillable = boolean : false
 524         attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
 525         // substitutionGroup = QName
 526         attrList.put(SchemaSymbols.ATT_SUBSTITUTIONGROUP, allAttrs[ATT_SUBSTITUTION_G_N]);
 527         // type = QName
 528         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
 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))
 534         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
 535         // default = string
 536         attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
 537         // fixed = string
 538         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_N]);
 539         // form = (qualified | unqualified)
 540         attrList.put(SchemaSymbols.ATT_FORM, allAttrs[ATT_FORM_N]);
 541         // id = ID
 542         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 543         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
 544         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
 545         // minOccurs = nonNegativeInteger : 1
 546         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
 547         // name = NCName
 548         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 549         // nillable = boolean : false
 550         attrList.put(SchemaSymbols.ATT_NILLABLE, allAttrs[ATT_NILLABLE_D]);
 551         // type = QName
 552         attrList.put(SchemaSymbols.ATT_TYPE, allAttrs[ATT_TYPE_N]);
 553         fEleAttrsMapL.put(ELEMENT_N, attrList);
 554 
 555         // for element "element" - local ref
 556         attrList = Container.getContainer(4);
 557         // id = ID
 558         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 559         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
 560         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
 561         // minOccurs = nonNegativeInteger : 1
 562         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
 563         // ref = QName
 564         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
 565         fEleAttrsMapL.put(ELEMENT_R, attrList);
 566 
 567         // for element "complexType" - global
 568         attrList = Container.getContainer(6);
 569         // abstract = boolean : false
 570         attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
 571         // block = (#all | List of (extension | restriction))
 572         attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK1_N]);
 573         // final = (#all | List of (extension | restriction))
 574         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL_N]);
 575         // id = ID
 576         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 577         // mixed = boolean : false
 578         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
 579         // name = NCName
 580         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 581         fEleAttrsMapG.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList);
 582 
 583         // for element "notation" - global
 584         attrList = Container.getContainer(4);
 585         // id = ID
 586         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 587         // name = NCName
 588         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 589         // public = A public identifier, per ISO 8879
 590         attrList.put(SchemaSymbols.ATT_PUBLIC, allAttrs[ATT_PUBLIC_R]);
 591         // system = anyURI
 592         attrList.put(SchemaSymbols.ATT_SYSTEM, allAttrs[ATT_SYSTEM_N]);
 593         fEleAttrsMapG.put(SchemaSymbols.ELT_NOTATION, attrList);
 594 
 595 
 596         // for element "complexType" - local
 597         attrList = Container.getContainer(2);
 598         // id = ID
 599         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 600         // mixed = boolean : false
 601         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_D]);
 602         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXTYPE, attrList);
 603 
 604         // for element "simpleContent" - local
 605         attrList = Container.getContainer(1);
 606         // id = ID
 607         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 608         fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLECONTENT, attrList);
 609 
 610         // for element "restriction" - local
 611         attrList = Container.getContainer(2);
 612         // base = QName
 613         attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_N]);
 614         // id = ID
 615         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 616         fEleAttrsMapL.put(SchemaSymbols.ELT_RESTRICTION, attrList);
 617 
 618         // for element "extension" - local
 619         attrList = Container.getContainer(2);
 620         // base = QName
 621         attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_R]);
 622         // id = ID
 623         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 624         fEleAttrsMapL.put(SchemaSymbols.ELT_EXTENSION, attrList);
 625 
 626         // for element "attributeGroup" - local ref
 627         attrList = Container.getContainer(2);
 628         // id = ID
 629         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 630         // ref = QName
 631         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
 632         fEleAttrsMapL.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList);
 633 
 634         // for element "anyAttribute" - local
 635         attrList = Container.getContainer(3);
 636         // id = ID
 637         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 638         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
 639         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
 640         // processContents = (lax | skip | strict) : strict
 641         attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
 642         fEleAttrsMapL.put(SchemaSymbols.ELT_ANYATTRIBUTE, attrList);
 643 
 644         // for element "complexContent" - local
 645         attrList = Container.getContainer(2);
 646         // id = ID
 647         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 648         // mixed = boolean
 649         attrList.put(SchemaSymbols.ATT_MIXED, allAttrs[ATT_MIXED_N]);
 650         fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXCONTENT, attrList);
 651 
 652         // for element "attributeGroup" - global
 653         attrList = Container.getContainer(2);
 654         // id = ID
 655         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 656         // name = NCName
 657         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 658         fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, attrList);
 659 
 660         // for element "group" - global
 661         attrList = Container.getContainer(2);
 662         // id = ID
 663         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 664         // name = NCName
 665         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 666         fEleAttrsMapG.put(SchemaSymbols.ELT_GROUP, attrList);
 667 
 668         // for element "group" - local ref
 669         attrList = Container.getContainer(4);
 670         // id = ID
 671         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 672         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
 673         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
 674         // minOccurs = nonNegativeInteger : 1
 675         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
 676         // ref = QName
 677         attrList.put(SchemaSymbols.ATT_REF, allAttrs[ATT_REF_R]);
 678         fEleAttrsMapL.put(SchemaSymbols.ELT_GROUP, attrList);
 679 
 680         // for element "all" - local
 681         attrList = Container.getContainer(3);
 682         // id = ID
 683         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 684         // maxOccurs = 1 : 1
 685         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS1_D]);
 686         // minOccurs = (0 | 1) : 1
 687         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS1_D]);
 688         fEleAttrsMapL.put(SchemaSymbols.ELT_ALL, attrList);
 689 
 690         // for element "choice" - local
 691         attrList = Container.getContainer(3);
 692         // id = ID
 693         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 694         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
 695         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
 696         // minOccurs = nonNegativeInteger : 1
 697         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
 698         fEleAttrsMapL.put(SchemaSymbols.ELT_CHOICE, attrList);
 699         // for element "sequence" - local
 700         fEleAttrsMapL.put(SchemaSymbols.ELT_SEQUENCE, attrList);
 701 
 702         // for element "any" - local
 703         attrList = Container.getContainer(5);
 704         // id = ID
 705         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 706         // maxOccurs = (nonNegativeInteger | unbounded)  : 1
 707         attrList.put(SchemaSymbols.ATT_MAXOCCURS, allAttrs[ATT_MAXOCCURS_D]);
 708         // minOccurs = nonNegativeInteger : 1
 709         attrList.put(SchemaSymbols.ATT_MINOCCURS, allAttrs[ATT_MINOCCURS_D]);
 710         // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
 711         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_D]);
 712         // processContents = (lax | skip | strict) : strict
 713         attrList.put(SchemaSymbols.ATT_PROCESSCONTENTS, allAttrs[ATT_PROCESS_C_D]);
 714         fEleAttrsMapL.put(SchemaSymbols.ELT_ANY, attrList);
 715 
 716         // for element "unique" - local
 717         attrList = Container.getContainer(2);
 718         // id = ID
 719         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 720         // name = NCName
 721         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 722         fEleAttrsMapL.put(SchemaSymbols.ELT_UNIQUE, attrList);
 723         // for element "key" - local
 724         fEleAttrsMapL.put(SchemaSymbols.ELT_KEY, attrList);
 725 
 726         // for element "keyref" - local
 727         attrList = Container.getContainer(3);
 728         // id = ID
 729         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 730         // name = NCName
 731         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 732         // refer = QName
 733         attrList.put(SchemaSymbols.ATT_REFER, allAttrs[ATT_REFER_R]);
 734         fEleAttrsMapL.put(SchemaSymbols.ELT_KEYREF, attrList);
 735 
 736         // for element "selector" - local
 737         attrList = Container.getContainer(2);
 738         // id = ID
 739         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 740         // xpath = a subset of XPath expression
 741         attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH_R]);
 742         fEleAttrsMapL.put(SchemaSymbols.ELT_SELECTOR, attrList);
 743 
 744         // for element "field" - local
 745         attrList = Container.getContainer(2);
 746         // id = ID
 747         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 748         // xpath = a subset of XPath expression
 749         attrList.put(SchemaSymbols.ATT_XPATH, allAttrs[ATT_XPATH1_R]);
 750         fEleAttrsMapL.put(SchemaSymbols.ELT_FIELD, attrList);
 751 
 752         // for element "annotation" - global
 753         attrList = Container.getContainer(1);
 754         // id = ID
 755         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 756         fEleAttrsMapG.put(SchemaSymbols.ELT_ANNOTATION, attrList);
 757         // for element "annotation" - local
 758         fEleAttrsMapL.put(SchemaSymbols.ELT_ANNOTATION, attrList);
 759 
 760         // for element "appinfo" - local
 761         attrList = Container.getContainer(1);
 762         // source = anyURI
 763         attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
 764         fEleAttrsMapG.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
 770         attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
 771         // xml:lang = language
 772         attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG]);
 773         fEleAttrsMapG.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))
 779         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
 780         // id = ID
 781         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 782         // name = NCName
 783         attrList.put(SchemaSymbols.ATT_NAME, allAttrs[ATT_NAME_R]);
 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))
 789         attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
 790         // id = ID
 791         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 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
 800         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 801         // itemType = QName
 802         attrList.put(SchemaSymbols.ATT_ITEMTYPE, allAttrs[ATT_ITEMTYPE_N]);
 803         fEleAttrsMapL.put(SchemaSymbols.ELT_LIST, attrList);
 804 
 805         // for element "union" - local
 806         attrList = Container.getContainer(2);
 807         // id = ID
 808         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 809         // memberTypes = List of QName
 810         attrList.put(SchemaSymbols.ATT_MEMBERTYPES, allAttrs[ATT_MEMBER_T_N]);
 811         fEleAttrsMapL.put(SchemaSymbols.ELT_UNION, attrList);
 812 
 813         // for element "schema" - global
 814         attrList = Container.getContainer(8);
 815         // attributeFormDefault = (qualified | unqualified) : unqualified
 816         attrList.put(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT, allAttrs[ATT_ATTRIBUTE_FD_D]);
 817         // blockDefault = (#all | List of (extension | restriction | substitution))  : ''
 818         attrList.put(SchemaSymbols.ATT_BLOCKDEFAULT, allAttrs[ATT_BLOCK_D_D]);
 819         // elementFormDefault = (qualified | unqualified) : unqualified
 820         attrList.put(SchemaSymbols.ATT_ELEMENTFORMDEFAULT, allAttrs[ATT_ELEMENT_FD_D]);
 821         // finalDefault = (#all | List of (extension | restriction | list | union))  : ''
 822         attrList.put(SchemaSymbols.ATT_FINALDEFAULT, allAttrs[ATT_FINAL_D_D]);
 823         // id = ID
 824         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 825         // targetNamespace = anyURI
 826         attrList.put(SchemaSymbols.ATT_TARGETNAMESPACE, allAttrs[ATT_TARGET_N_N]);
 827         // version = token
 828         attrList.put(SchemaSymbols.ATT_VERSION, allAttrs[ATT_VERSION_N]);
 829         // xml:lang = language
 830         attrList.put(SchemaSymbols.ATT_XML_LANG, allAttrs[ATT_XML_LANG]);
 831         fEleAttrsMapG.put(SchemaSymbols.ELT_SCHEMA, attrList);
 832 
 833         // for element "include" - global
 834         attrList = Container.getContainer(2);
 835         // id = ID
 836         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 837         // schemaLocation = anyURI
 838         attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_R]);
 839         fEleAttrsMapG.put(SchemaSymbols.ELT_INCLUDE, attrList);
 840         // for element "redefine" - global
 841         fEleAttrsMapG.put(SchemaSymbols.ELT_REDEFINE, attrList);
 842 
 843         // for element "import" - global
 844         attrList = Container.getContainer(3);
 845         // id = ID
 846         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 847         // namespace = anyURI
 848         attrList.put(SchemaSymbols.ATT_NAMESPACE, allAttrs[ATT_NAMESPACE_N]);
 849         // schemaLocation = anyURI
 850         attrList.put(SchemaSymbols.ATT_SCHEMALOCATION, allAttrs[ATT_SCHEMA_L_N]);
 851         fEleAttrsMapG.put(SchemaSymbols.ELT_IMPORT, attrList);
 852 
 853         // for element "length" - local
 854         attrList = Container.getContainer(3);
 855         // id = ID
 856         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 857         // value = nonNegativeInteger
 858         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_NNI_N]);
 859         // fixed = boolean : false
 860         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
 861         fEleAttrsMapL.put(SchemaSymbols.ELT_LENGTH, attrList);
 862         // for element "minLength" - local
 863         fEleAttrsMapL.put(SchemaSymbols.ELT_MINLENGTH, attrList);
 864         // for element "maxLength" - local
 865         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXLENGTH, attrList);
 866         // for element "fractionDigits" - local
 867         fEleAttrsMapL.put(SchemaSymbols.ELT_FRACTIONDIGITS, attrList);
 868 
 869         // for element "totalDigits" - local
 870         attrList = Container.getContainer(3);
 871         // id = ID
 872         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 873         // value = positiveInteger
 874         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_PI_N]);
 875         // fixed = boolean : false
 876         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
 877         fEleAttrsMapL.put(SchemaSymbols.ELT_TOTALDIGITS, attrList);
 878 
 879         // for element "pattern" - local
 880         attrList = Container.getContainer(2);
 881         // id = ID
 882         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 883         // value = string
 884         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
 885         fEleAttrsMapL.put(SchemaSymbols.ELT_PATTERN, attrList);
 886 
 887         // for element "enumeration" - local
 888         attrList = Container.getContainer(2);
 889         // id = ID
 890         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 891         // value = anySimpleType
 892         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
 893         fEleAttrsMapL.put(SchemaSymbols.ELT_ENUMERATION, attrList);
 894 
 895         // for element "whiteSpace" - local
 896         attrList = Container.getContainer(3);
 897         // id = ID
 898         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 899         // value = preserve | replace | collapse
 900         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_WS_N]);
 901         // fixed = boolean : false
 902         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
 903         fEleAttrsMapL.put(SchemaSymbols.ELT_WHITESPACE, attrList);
 904 
 905         // for element "maxInclusive" - local
 906         attrList = Container.getContainer(3);
 907         // id = ID
 908         attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
 909         // value = anySimpleType
 910         attrList.put(SchemaSymbols.ATT_VALUE, allAttrs[ATT_VALUE_STR_N]);
 911         // fixed = boolean : false
 912         attrList.put(SchemaSymbols.ATT_FIXED, allAttrs[ATT_FIXED_D]);
 913         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXINCLUSIVE, attrList);
 914         // for element "maxExclusive" - local
 915         fEleAttrsMapL.put(SchemaSymbols.ELT_MAXEXCLUSIVE, attrList);
 916         // for element "minInclusive" - local
 917         fEleAttrsMapL.put(SchemaSymbols.ELT_MININCLUSIVE, attrList);
 918         // for element "minExclusive" - local
 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 fNonSchemaAttrs = new HashMap();
 930 
 931     // temprory vector, used to hold the namespace list
 932     protected Vector fNamespaceList = new Vector();
 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
 939     public XSAttributeChecker(XSDHandler schemaHandler) {
 940         fSchemaHandler = schemaHandler;
 941     }
 942 
 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      */
 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     public Object[] checkAttributes(Element element, boolean isGlobal,
 978                                     XSDocumentInfo schemaDoc, boolean enumAsQName) {
 979         if (element == null)
 980             return null;
 981 
 982         // get all attributes
 983         Attr[] attrs = DOMUtil.getAttrs(element);
 984 
 985         // update NamespaceSupport
 986         resolveNamespace(element, attrs, schemaDoc.fNamespaceSupport);
 987 
 988         String uri = DOMUtil.getNamespaceURI(element);
 989         String elName = DOMUtil.getLocalName(element);
 990 
 991         if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(uri)) {
 992             reportSchemaError("s4s-elt-schema-ns", new Object[] {elName}, element);
 993         }
 994 
 995         Map eleAttrsMap = fEleAttrsMapG;
 996         String lookupName = elName;
 997 
 998         // REVISIT: only local element and attribute are different from others.
 999         //          it's possible to have either name or ref. all the others
1000         //          are only allowed to have one of name or ref, or neither of them.
1001         //          we'd better move such checking to the traverser.
1002         if (!isGlobal) {
1003             eleAttrsMap = fEleAttrsMapL;
1004             if (elName.equals(SchemaSymbols.ELT_ELEMENT)) {
1005                 if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1006                     lookupName = ELEMENT_R;
1007                 else
1008                     lookupName = ELEMENT_N;
1009             } else if (elName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1010                 if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
1011                     lookupName = ATTRIBUTE_R;
1012                 else
1013                     lookupName = ATTRIBUTE_N;
1014             }
1015         }
1016 
1017         // get desired attribute list of this element
1018         Container attrList = (Container)eleAttrsMap.get(lookupName);
1019         if (attrList == null) {
1020             // should never gets here.
1021             // when this method is called, the call already knows that
1022             // the element can appear.
1023             reportSchemaError ("s4s-elt-invalid", new Object[] {elName}, element);
1024             return null;
1025         }
1026 
1027         Object[] attrValues = getAvailableArray();
1028         long fromDefault = 0;
1029 
1030         // clear the "seen" flag.
1031         System.arraycopy(fSeenTemp, 0, fSeen, 0, ATTIDX_COUNT);
1032 
1033         // traverse all attributes
1034         int length = attrs.length;
1035         Attr sattr = null;
1036         for (int i = 0; i < length; i++) {
1037             sattr = attrs[i];
1038             // get the attribute name/value
1039             //String attrName = DOMUtil.getLocalName(sattr);
1040             String attrName = sattr.getName();
1041             String attrURI = DOMUtil.getNamespaceURI(sattr);
1042             String attrVal = DOMUtil.getValue(sattr);
1043 
1044             if (attrName.startsWith("xml")) {
1045                 String attrPrefix = DOMUtil.getPrefix(sattr);
1046                 // we don't want to add namespace declarations to the non-schema attributes
1047                 if ("xmlns".equals(attrPrefix) || "xmlns".equals(attrName)) {
1048                     continue;
1049                 }
1050                 // Both <schema> and <documentation> may have an xml:lang attribute.
1051                 // Set the URI for this attribute to null so that we process it
1052                 // like any other schema attribute.
1053                 else if (SchemaSymbols.ATT_XML_LANG.equals(attrName) &&
1054                         (SchemaSymbols.ELT_SCHEMA.equals(elName) ||
1055                                 SchemaSymbols.ELT_DOCUMENTATION.equals(elName))) {
1056                     attrURI = null;
1057                 }
1058             }
1059 
1060             // for attributes with namespace prefix
1061             //
1062             if (attrURI != null && attrURI.length() != 0) {
1063                 // attributes with schema namespace are not allowed
1064                 // and not allowed on "document" and "appInfo"
1065                 if (attrURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
1066                     reportSchemaError ("s4s-att-not-allowed", new Object[] {elName, attrName}, element);
1067                 }
1068                 else {
1069                     if(attrValues[ATTIDX_NONSCHEMA] == null) {
1070                         // these are usually small
1071                         attrValues[ATTIDX_NONSCHEMA] = new Vector(4,2);
1072                     }
1073                     ((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrName);
1074                     ((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrVal);
1075                     // for attributes from other namespace
1076                     // store them in a list, and TRY to validate them after
1077                     // schema traversal (because it's "lax")
1078                     //otherValues.put(attrName, attrVal);
1079                     // REVISIT:  actually use this some day...
1080                     // String attrRName = attrURI + "," + attrName;
1081                     // Vector values = (Vector)fNonSchemaAttrs.get(attrRName);
1082                     // if (values == null) {
1083                         // values = new Vector();
1084                         // values.addElement(attrName);
1085                         // values.addElement(elName);
1086                         // values.addElement(attrVal);
1087                         // fNonSchemaAttrs.put(attrRName, values);
1088                     // }
1089                     // else {
1090                         // values.addElement(elName);
1091                         // values.addElement(attrVal);
1092                     // }
1093                 }
1094                 continue;
1095             }
1096 
1097             // check whether this attribute is allowed
1098             OneAttr oneAttr = attrList.get(attrName);
1099             if (oneAttr == null) {
1100                 reportSchemaError ("s4s-att-not-allowed",
1101                                    new Object[] {elName, attrName},
1102                                    element);
1103                 continue;
1104             }
1105 
1106             // we've seen this attribute
1107             fSeen[oneAttr.valueIndex] = true;
1108 
1109             // check the value against the datatype
1110             try {
1111                 // no checking on string needs to be done here.
1112                 // no checking on xpath needs to be done here.
1113                 // xpath values are validated in xpath parser
1114                 if (oneAttr.dvIndex >= 0) {
1115                     if (oneAttr.dvIndex != DT_STRING &&
1116                         oneAttr.dvIndex != DT_XPATH &&
1117                         oneAttr.dvIndex != DT_XPATH1) {
1118                         XSSimpleType dv = fExtraDVs[oneAttr.dvIndex];
1119                         Object avalue = dv.validate(attrVal, schemaDoc.fValidationContext, null);
1120                         // kludge to handle chameleon includes/redefines...
1121                         if (oneAttr.dvIndex == DT_QNAME) {
1122                             QName qname = (QName)avalue;
1123                             if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1124                                 qname.uri = schemaDoc.fTargetNamespace;
1125                         }
1126                         attrValues[oneAttr.valueIndex] = avalue;
1127                     } else {
1128                         attrValues[oneAttr.valueIndex] = attrVal;
1129                     }
1130                 }
1131                 else {
1132                     attrValues[oneAttr.valueIndex] = validate(attrValues, attrName, attrVal, oneAttr.dvIndex, schemaDoc);
1133                 }
1134             } catch (InvalidDatatypeValueException ide) {
1135                 reportSchemaError ("s4s-att-invalid-value",
1136                                    new Object[] {elName, attrName, ide.getMessage()},
1137                                    element);
1138                 if (oneAttr.dfltValue != null)
1139                     //attrValues.put(attrName, oneAttr.dfltValue);
1140                     attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1141             }
1142 
1143             // For "enumeration", and type is possible to be a QName, we need
1144             // to return namespace context for later QName resolution.
1145             if (elName.equals(SchemaSymbols.ELT_ENUMERATION) && enumAsQName) {
1146                 attrValues[ATTIDX_ENUMNSDECLS] = new SchemaNamespaceSupport(schemaDoc.fNamespaceSupport);
1147             }
1148         }
1149 
1150         // apply default values
1151         OneAttr[] reqAttrs = attrList.values;
1152         for (int i = 0; i < reqAttrs.length; i++) {
1153             OneAttr oneAttr = reqAttrs[i];
1154 
1155             // if the attribute didn't apprear, and
1156             // if the attribute is optional with default value, apply it
1157             if (oneAttr.dfltValue != null && !fSeen[oneAttr.valueIndex]) {
1158                 //attrValues.put(oneAttr.name, oneAttr.dfltValue);
1159                 attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
1160                 fromDefault |= (1<<oneAttr.valueIndex);
1161             }
1162         }
1163 
1164         attrValues[ATTIDX_FROMDEFAULT] = new Long(fromDefault);
1165         //attrValues[ATTIDX_OTHERVALUES] = otherValues;
1166 
1167         // Check that minOccurs isn't greater than maxOccurs.
1168         // p-props-correct 2.1
1169         if (attrValues[ATTIDX_MAXOCCURS] != null) {
1170             int min = ((XInt)attrValues[ATTIDX_MINOCCURS]).intValue();
1171             int max = ((XInt)attrValues[ATTIDX_MAXOCCURS]).intValue();
1172             if (max != SchemaSymbols.OCCURRENCE_UNBOUNDED) {
1173 
1174                 // maxOccurLimit is only check in secure mode
1175                 if (fSchemaHandler.fSecurityManager != null) {
1176                     String localName = element.getLocalName();
1177 
1178                 // The maxOccurs restriction no longer applies to elements
1179                     // and wildcards in a sequence in which they are the only
1180                     // particle. These are now validated using a constant
1181                     // space algorithm. The restriction still applies to all
1182                     // other cases.
1183 
1184                     // Determine if constant-space algorithm can be applied
1185                     final boolean optimize =
1186                             (localName.equals("element") || localName.equals("any")) &&
1187                             (element.getNextSibling() == null) &&
1188                             (element.getPreviousSibling() == null) &&
1189                             (element.getParentNode().getLocalName().equals("sequence"));
1190 
1191                     if (!optimize) {
1192                     //Revisit :: IMO this is not right place to check
1193                     // maxOccurNodeLimit.
1194                     int maxOccurNodeLimit = fSchemaHandler.fSecurityManager.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT);
1195                     if (max > maxOccurNodeLimit && !fSchemaHandler.fSecurityManager.isNoLimit(maxOccurNodeLimit)) {
1196                         reportSchemaFatalError("MaxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element);
1197 
1198                         // reset max values in case processing continues on error
1199                         attrValues[ATTIDX_MAXOCCURS] = fXIntPool.getXInt(maxOccurNodeLimit);
1200                                                 //new Integer(maxOccurNodeLimit);
1201                         max = maxOccurNodeLimit;
1202                     }
1203                 }
1204                 }
1205 
1206                 if (min > max) {
1207                     reportSchemaError ("p-props-correct.2.1",
1208                                        new Object[] {elName, attrValues[ATTIDX_MINOCCURS], attrValues[ATTIDX_MAXOCCURS]},
1209                                        element);
1210                     attrValues[ATTIDX_MINOCCURS] = attrValues[ATTIDX_MAXOCCURS];
1211                 }
1212             }
1213         }
1214 
1215         return attrValues;
1216     }
1217 
1218     private Object validate(Object[] attrValues, String attr, String ivalue, int dvIndex,
1219                             XSDocumentInfo schemaDoc) throws InvalidDatatypeValueException {
1220         if (ivalue == null)
1221             return null;
1222 
1223         // To validate these types, we don't actually need to normalize the
1224         // strings. We only need to remove the whitespace from both ends.
1225         // In some special cases (list types), StringTokenizer can correctly
1226         // process the un-normalized whitespace.
1227 
1228         String value = XMLChar.trim(ivalue);
1229         Object retValue = null;
1230         Vector memberType;
1231         int choice;
1232 
1233         switch (dvIndex) {
1234         case DT_BOOLEAN:
1235             if (value.equals(SchemaSymbols.ATTVAL_FALSE) ||
1236                 value.equals(SchemaSymbols.ATTVAL_FALSE_0)) {
1237                 retValue = Boolean.FALSE;
1238             } else if (value.equals(SchemaSymbols.ATTVAL_TRUE) ||
1239                        value.equals(SchemaSymbols.ATTVAL_TRUE_1)) {
1240                 retValue = Boolean.TRUE;
1241             } else {
1242                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "boolean"});
1243             }
1244             break;
1245         case DT_NONNEGINT:
1246             try {
1247                 if (value.length() > 0 && value.charAt(0) == '+')
1248                     value = value.substring(1);
1249                 retValue = fXIntPool.getXInt(Integer.parseInt(value));
1250             } catch (NumberFormatException e) {
1251                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
1252             }
1253             if (((XInt)retValue).intValue() < 0)
1254                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
1255             break;
1256         case DT_POSINT:
1257             try {
1258                 if (value.length() > 0 && value.charAt(0) == '+')
1259                     value = value.substring(1);
1260                 retValue = fXIntPool.getXInt(Integer.parseInt(value));
1261             } catch (NumberFormatException e) {
1262                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
1263             }
1264             if (((XInt)retValue).intValue() <= 0)
1265                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
1266             break;
1267         case DT_BLOCK:
1268             // block = (#all | List of (extension | restriction | substitution))
1269             choice = 0;
1270             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1271                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1272                          XSConstants.DERIVATION_RESTRICTION;
1273             }
1274             else {
1275                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1276                 while (t.hasMoreTokens()) {
1277                     String token = t.nextToken ();
1278 
1279                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1280                         choice |= XSConstants.DERIVATION_EXTENSION;
1281                     }
1282                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1283                         choice |= XSConstants.DERIVATION_RESTRICTION;
1284                     }
1285                     else if (token.equals (SchemaSymbols.ATTVAL_SUBSTITUTION)) {
1286                         choice |= XSConstants.DERIVATION_SUBSTITUTION;
1287                     }
1288                     else {
1289                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction | substitution))"});
1290                     }
1291                 }
1292             }
1293             retValue = fXIntPool.getXInt(choice);
1294             break;
1295         case DT_BLOCK1:
1296         case DT_FINAL:
1297             // block = (#all | List of (extension | restriction))
1298             // final = (#all | List of (extension | restriction))
1299             choice = 0;
1300             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1301                 //choice = SchemaSymbols.EXTENSION|SchemaSymbols.RESTRICTION;
1302                 // REVISIT: if #all, then make the result the combination of
1303                 //          everything: substitution/externsion/restriction/list/union.
1304                 //          would this be a problem?
1305                 // the reason doing so is that when final/blockFinal on <schema>
1306                 // is #all, it's not always the same as the conbination of those
1307                 // values allowed by final/blockFinal.
1308                 // for example, finalDefault="#all" is not always the same as
1309                 // finalDefault="extension restriction".
1310                 // if finalDefault="#all", final on any simple type would be
1311                 // "extension restriction list union".
1312                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1313                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1314                          XSConstants.DERIVATION_UNION;
1315             }
1316             else {
1317                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1318                 while (t.hasMoreTokens()) {
1319                     String token = t.nextToken ();
1320 
1321                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1322                         choice |= XSConstants.DERIVATION_EXTENSION;
1323                     }
1324                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1325                         choice |= XSConstants.DERIVATION_RESTRICTION;
1326                     }
1327                     else {
1328                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction))"});
1329                     }
1330                 }
1331             }
1332             retValue = fXIntPool.getXInt(choice);
1333             break;
1334         case DT_FINAL1:
1335             // final = (#all | List of (list | union | restriction))
1336             choice = 0;
1337             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1338                 //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1339                 //         SchemaSymbols.UNION;
1340                 // REVISIT: if #all, then make the result the combination of
1341                 //          everything: substitution/externsion/restriction/list/union.
1342                 //          would this be a problem?
1343                 // same reason as above DT_BLOCK1/DT_FINAL
1344                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1345                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1346                          XSConstants.DERIVATION_UNION;
1347             }
1348             else {
1349                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1350                 while (t.hasMoreTokens()) {
1351                     String token = t.nextToken ();
1352 
1353                     if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1354                         choice |= XSConstants.DERIVATION_LIST;
1355                     }
1356                     else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1357                         choice |= XSConstants.DERIVATION_UNION;
1358                     }
1359                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1360                         choice |= XSConstants.DERIVATION_RESTRICTION;
1361                     }
1362                     else {
1363                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (list | union | restriction))"});
1364                     }
1365                 }
1366             }
1367             retValue = fXIntPool.getXInt(choice);
1368             break;
1369         case DT_FINAL2:
1370             // finalDefault = (#all | List of (extension | restriction | list | union))
1371             choice = 0;
1372             if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
1373                 //choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
1374                 //         SchemaSymbols.UNION;
1375                 // REVISIT: if #all, then make the result the combination of
1376                 //          everything: substitution/externsion/restriction/list/union.
1377                 //          would this be a problem?
1378                 // same reason as above DT_BLOCK1/DT_FINAL
1379                 choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
1380                          XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
1381                          XSConstants.DERIVATION_UNION;
1382             }
1383             else {
1384                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1385                 while (t.hasMoreTokens()) {
1386                     String token = t.nextToken ();
1387 
1388                     if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
1389                         choice |= XSConstants.DERIVATION_EXTENSION;
1390                     }
1391                     else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
1392                         choice |= XSConstants.DERIVATION_RESTRICTION;
1393                     }
1394                     else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
1395                         choice |= XSConstants.DERIVATION_LIST;
1396                     }
1397                     else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
1398                         choice |= XSConstants.DERIVATION_UNION;
1399                     }
1400                     else {
1401                         throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction | list | union))"});
1402                     }
1403                 }
1404             }
1405             retValue = fXIntPool.getXInt(choice);
1406             break;
1407         case DT_FORM:
1408             // form = (qualified | unqualified)
1409             if (value.equals (SchemaSymbols.ATTVAL_QUALIFIED))
1410                 retValue = INT_QUALIFIED;
1411             else if (value.equals (SchemaSymbols.ATTVAL_UNQUALIFIED))
1412                 retValue = INT_UNQUALIFIED;
1413             else
1414                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1415                                                         new Object[]{value, "(qualified | unqualified)"});
1416             break;
1417         case DT_MAXOCCURS:
1418             // maxOccurs = (nonNegativeInteger | unbounded)
1419             if (value.equals(SchemaSymbols.ATTVAL_UNBOUNDED)) {
1420                 retValue = INT_UNBOUNDED;
1421             } else {
1422                 try {
1423                     retValue = validate(attrValues, attr, value, DT_NONNEGINT, schemaDoc);
1424                 } catch (NumberFormatException e) {
1425                     throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(nonNegativeInteger | unbounded)"});
1426                 }
1427             }
1428             break;
1429         case DT_MAXOCCURS1:
1430             // maxOccurs = 1
1431             if (value.equals("1"))
1432                 retValue = fXIntPool.getXInt(1);
1433             else
1434                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1435                                                         new Object[]{value, "(1)"});
1436             break;
1437         case DT_MEMBERTYPES:
1438             // memberTypes = List of QName
1439             memberType = new Vector();
1440             try {
1441                 StringTokenizer t = new StringTokenizer(value, " \n\t\r");
1442                 while (t.hasMoreTokens()) {
1443                     String token = t.nextToken ();
1444                     QName qname = (QName)fExtraDVs[DT_QNAME].validate(token, schemaDoc.fValidationContext, null);
1445                     // kludge to handle chameleon includes/redefines...
1446                     if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
1447                         qname.uri = schemaDoc.fTargetNamespace;
1448                     memberType.addElement(qname);
1449                 }
1450                 retValue = memberType;
1451             }
1452             catch (InvalidDatatypeValueException ide) {
1453                 throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.2", new Object[]{value, "(List of QName)"});
1454             }
1455             break;
1456         case DT_MINOCCURS1:
1457             // minOccurs = (0 | 1)
1458             if (value.equals("0"))
1459                 retValue = fXIntPool.getXInt(0);
1460             else if (value.equals("1"))
1461                 retValue = fXIntPool.getXInt(1);
1462             else
1463                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1464                                                         new Object[]{value, "(0 | 1)"});
1465             break;
1466         case DT_NAMESPACE:
1467             // namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )
1468             if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY)) {
1469                 // ##any
1470                 retValue = INT_ANY_ANY;
1471             } else if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
1472                 // ##other
1473                 retValue = INT_ANY_NOT;
1474                 String[] list = new String[2];
1475                 list[0] = schemaDoc.fTargetNamespace;
1476                 list[1] = null;
1477                 attrValues[ATTIDX_NAMESPACE_LIST] = list;
1478             } else {
1479                 // list
1480                 retValue = INT_ANY_LIST;
1481 
1482                 fNamespaceList.removeAllElements();
1483 
1484                 // tokenize
1485                 StringTokenizer tokens = new StringTokenizer(value, " \n\t\r");
1486                 String token;
1487                 String tempNamespace;
1488                 try {
1489                     while (tokens.hasMoreTokens()) {
1490                         token = tokens.nextToken();
1491                         if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
1492                             tempNamespace = null;
1493                         } else if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS)) {
1494                             tempNamespace = schemaDoc.fTargetNamespace;
1495                         } else {
1496                             // we have found namespace URI here
1497                             // need to add it to the symbol table
1498                             fExtraDVs[DT_ANYURI].validate(token, schemaDoc.fValidationContext, null);
1499                             tempNamespace = fSymbolTable.addSymbol(token);
1500                         }
1501 
1502                         //check for duplicate namespaces in the list
1503                         if (!fNamespaceList.contains(tempNamespace)) {
1504                             fNamespaceList.addElement(tempNamespace);
1505                         }
1506                     }
1507                 } catch (InvalidDatatypeValueException ide) {
1508                     throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )"});
1509                 }
1510 
1511                 // convert the vector to an array
1512                 int num = fNamespaceList.size();
1513                 String[] list = new String[num];
1514                 fNamespaceList.copyInto(list);
1515                 attrValues[ATTIDX_NAMESPACE_LIST] = list;
1516             }
1517             break;
1518         case DT_PROCESSCONTENTS:
1519             // processContents = (lax | skip | strict)
1520             if (value.equals (SchemaSymbols.ATTVAL_STRICT))
1521                 retValue = INT_ANY_STRICT;
1522             else if (value.equals (SchemaSymbols.ATTVAL_LAX))
1523                 retValue = INT_ANY_LAX;
1524             else if (value.equals (SchemaSymbols.ATTVAL_SKIP))
1525                 retValue = INT_ANY_SKIP;
1526             else
1527                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1528                                                         new Object[]{value, "(lax | skip | strict)"});
1529             break;
1530         case DT_USE:
1531             // use = (optional | prohibited | required)
1532             if (value.equals (SchemaSymbols.ATTVAL_OPTIONAL))
1533                 retValue = INT_USE_OPTIONAL;
1534             else if (value.equals (SchemaSymbols.ATTVAL_REQUIRED))
1535                 retValue = INT_USE_REQUIRED;
1536             else if (value.equals (SchemaSymbols.ATTVAL_PROHIBITED))
1537                 retValue = INT_USE_PROHIBITED;
1538             else
1539                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1540                                                         new Object[]{value, "(optional | prohibited | required)"});
1541             break;
1542         case DT_WHITESPACE:
1543             // value = preserve | replace | collapse
1544             if (value.equals (SchemaSymbols.ATTVAL_PRESERVE))
1545                 retValue = INT_WS_PRESERVE;
1546             else if (value.equals (SchemaSymbols.ATTVAL_REPLACE))
1547                 retValue = INT_WS_REPLACE;
1548             else if (value.equals (SchemaSymbols.ATTVAL_COLLAPSE))
1549                 retValue = INT_WS_COLLAPSE;
1550             else
1551                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1552                                                         new Object[]{value, "(preserve | replace | collapse)"});
1553             break;
1554         }
1555 
1556         return retValue;
1557     }
1558 
1559     void reportSchemaFatalError (String key, Object[] args, Element ele) {
1560         fSchemaHandler.reportSchemaFatalError(key, args, ele);
1561     }
1562 
1563     void reportSchemaError (String key, Object[] args, Element ele) {
1564         fSchemaHandler.reportSchemaError(key, args, ele);
1565     }
1566 
1567     // validate attriubtes from non-schema namespaces
1568     // REVISIT: why we store the attributes in this way? why not just a list
1569     //          of structure {element node, attr name/qname, attr value)?
1570     // REVISIT: pass the proper element node to reportSchemaError
1571     public void checkNonSchemaAttributes(XSGrammarBucket grammarBucket) {
1572         // for all attributes
1573         Iterator entries = fNonSchemaAttrs.entrySet().iterator();
1574         XSAttributeDecl attrDecl;
1575         while (entries.hasNext()) {
1576             Map.Entry entry = (Map.Entry) entries.next();
1577             // get name, uri, localpart
1578             String attrRName = (String) entry.getKey();
1579             String attrURI = attrRName.substring(0,attrRName.indexOf(','));
1580             String attrLocal = attrRName.substring(attrRName.indexOf(',')+1);
1581             // find associated grammar
1582             SchemaGrammar sGrammar = grammarBucket.getGrammar(attrURI);
1583             if (sGrammar == null) {
1584                 continue;
1585             }
1586             // and get the datatype validator, if there is one
1587             attrDecl = sGrammar.getGlobalAttributeDecl(attrLocal);
1588             if (attrDecl == null) {
1589                 continue;
1590             }
1591             XSSimpleType dv = (XSSimpleType)attrDecl.getTypeDefinition();
1592             if (dv == null) {
1593                 continue;
1594             }
1595 
1596             // get all values appeared with this attribute name
1597             Vector values = (Vector) entry.getValue();
1598             String elName;
1599             String attrName = (String)values.elementAt(0);
1600             // for each of the values
1601             int count = values.size();
1602             for (int i = 1; i < count; i += 2) {
1603                 elName = (String)values.elementAt(i);
1604                 try {
1605                     // and validate it using the XSSimpleType
1606                     // REVISIT: what would be the proper validation context?
1607                     //          guess we need to save that in the vectors too.
1608                     dv.validate((String)values.elementAt(i+1), null, null);
1609                 } catch(InvalidDatatypeValueException ide) {
1610                     reportSchemaError ("s4s-att-invalid-value",
1611                                        new Object[] {elName, attrName, ide.getMessage()},
1612                                        null);
1613                 }
1614             }
1615         }
1616     }
1617 
1618     // normalize the string according to the whiteSpace facet
1619     public static String normalize(String content, short ws) {
1620         int len = content == null ? 0 : content.length();
1621         if (len == 0 || ws == XSSimpleType.WS_PRESERVE)
1622             return content;
1623 
1624         StringBuffer sb = new StringBuffer();
1625         if (ws == XSSimpleType.WS_REPLACE) {
1626             char ch;
1627             // when it's replace, just replace #x9, #xa, #xd by #x20
1628             for (int i = 0; i < len; i++) {
1629                 ch = content.charAt(i);
1630                 if (ch != 0x9 && ch != 0xa && ch != 0xd)
1631                     sb.append(ch);
1632                 else
1633                     sb.append((char)0x20);
1634             }
1635         } else {
1636             char ch;
1637             int i;
1638             boolean isLeading = true;
1639             // when it's collapse
1640             for (i = 0; i < len; i++) {
1641                 ch = content.charAt(i);
1642                 // append real characters, so we passed leading ws
1643                 if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
1644                     sb.append(ch);
1645                     isLeading = false;
1646                 }
1647                 else {
1648                     // for whitespaces, we skip all following ws
1649                     for (; i < len-1; i++) {
1650                         ch = content.charAt(i+1);
1651                         if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
1652                             break;
1653                     }
1654                     // if it's not a leading or tailing ws, then append a space
1655                     if (i < len - 1 && !isLeading)
1656                         sb.append((char)0x20);
1657                 }
1658             }
1659         }
1660 
1661         return sb.toString();
1662     }
1663 
1664     // the following part implements an attribute-value-array pool.
1665     // when checkAttribute is called, it calls getAvailableArray to get
1666     // an array from the pool; when the caller is done with the array,
1667     // it calls returnAttrArray to return that array to the pool.
1668 
1669     // initial size of the array pool. 10 is big enough
1670     static final int INIT_POOL_SIZE = 10;
1671     // the incremental size of the array pool
1672     static final int INC_POOL_SIZE  = 10;
1673     // the array pool
1674     Object[][] fArrayPool = new Object[INIT_POOL_SIZE][ATTIDX_COUNT];
1675     // used to clear the returned array
1676     // I think System.arrayCopy is more efficient than setting 35 fields to null
1677     private static Object[] fTempArray = new Object[ATTIDX_COUNT];
1678     // current position of the array pool (# of arrays not returned)
1679     int fPoolPos = 0;
1680 
1681     // get the next available array
1682     protected Object[] getAvailableArray() {
1683         // if no array left in the pool, increase the pool size
1684         if (fArrayPool.length == fPoolPos) {
1685             // increase size
1686             fArrayPool = new Object[fPoolPos+INC_POOL_SIZE][];
1687             // initialize each *new* array
1688             for (int i = fPoolPos; i < fArrayPool.length; i++)
1689                 fArrayPool[i] = new Object[ATTIDX_COUNT];
1690         }
1691         // get the next available one
1692         Object[] retArray = fArrayPool[fPoolPos];
1693         // clear it from the pool. this is for GC: if a caller forget to
1694         // return the array, we want that array to be GCed.
1695         fArrayPool[fPoolPos++] = null;
1696         // to make sure that one array is not returned twice, we use
1697         // the last entry to indicate whether an array is already returned
1698         // now set it to false.
1699         System.arraycopy(fTempArray, 0, retArray, 0, ATTIDX_COUNT-1);
1700         retArray[ATTIDX_ISRETURNED] = Boolean.FALSE;
1701 
1702         return retArray;
1703     }
1704 
1705     // return an array back to the pool
1706     public void returnAttrArray(Object[] attrArray, XSDocumentInfo schemaDoc) {
1707         // pop the namespace context
1708         if (schemaDoc != null)
1709             schemaDoc.fNamespaceSupport.popContext();
1710 
1711         // if 1. the pool is full; 2. the array is null;
1712         // 3. the array is of wrong size; 4. the array is already returned
1713         // then we can't accept this array to be returned
1714         if (fPoolPos == 0 ||
1715             attrArray == null ||
1716             attrArray.length != ATTIDX_COUNT ||
1717             ((Boolean)attrArray[ATTIDX_ISRETURNED]).booleanValue()) {
1718             return;
1719         }
1720 
1721         // mark this array as returned
1722         attrArray[ATTIDX_ISRETURNED] = Boolean.TRUE;
1723         // better clear nonschema vector
1724         if(attrArray[ATTIDX_NONSCHEMA] != null)
1725             ((Vector)attrArray[ATTIDX_NONSCHEMA]).clear();
1726         // and put it into the pool
1727         fArrayPool[--fPoolPos] = attrArray;
1728     }
1729 
1730     public void resolveNamespace(Element element, Attr[] attrs,
1731                                  SchemaNamespaceSupport nsSupport) {
1732         // push the namespace context
1733         nsSupport.pushContext();
1734 
1735         // search for new namespace bindings
1736         int length = attrs.length;
1737         Attr sattr = null;
1738         String rawname, prefix, uri;
1739         for (int i = 0; i < length; i++) {
1740             sattr = attrs[i];
1741             rawname = DOMUtil.getName(sattr);
1742             prefix = null;
1743             if (rawname.equals(XMLSymbols.PREFIX_XMLNS))
1744                 prefix = XMLSymbols.EMPTY_STRING;
1745             else if (rawname.startsWith("xmlns:"))
1746                 prefix = fSymbolTable.addSymbol(DOMUtil.getLocalName(sattr));
1747             if (prefix != null) {
1748                 uri = fSymbolTable.addSymbol(DOMUtil.getValue(sattr));
1749                 nsSupport.declarePrefix(prefix, uri.length()!=0 ? uri : null);
1750             }
1751         }
1752     }
1753 }
1754 
1755 class OneAttr {
1756     // name of the attribute
1757     public String name;
1758     // index of the datatype validator
1759     public int dvIndex;
1760     // whether it's optional, and has default value
1761     public int valueIndex;
1762     // the default value of this attribute
1763     public Object dfltValue;
1764 
1765     public OneAttr(String name, int dvIndex, int valueIndex, Object dfltValue) {
1766         this.name = name;
1767         this.dvIndex = dvIndex;
1768         this.valueIndex = valueIndex;
1769         this.dfltValue = dfltValue;
1770     }
1771 }
1772 
1773 abstract class Container {
1774     static final int THRESHOLD = 5;
1775     static Container getContainer(int size) {
1776         if (size > THRESHOLD)
1777             return new LargeContainer(size);
1778         else
1779             return new SmallContainer(size);
1780     }
1781     abstract void put(String key, OneAttr value);
1782     abstract OneAttr get(String key);
1783 
1784     OneAttr[] values;
1785     int pos = 0;
1786 }
1787 
1788 class SmallContainer extends Container {
1789     String[] keys;
1790     SmallContainer(int size) {
1791         keys = new String[size];
1792         values = new OneAttr[size];
1793     }
1794     void put(String key, OneAttr value) {
1795         keys[pos] = key;
1796         values[pos++] = value;
1797     }
1798     OneAttr get(String key) {
1799         for (int i = 0; i < pos; i++) {
1800             if (keys[i].equals(key)) {
1801                 return values[i];
1802             }
1803         }
1804         return null;
1805     }
1806 }
1807 
1808 class LargeContainer extends Container {
1809     Map items;
1810     LargeContainer(int size) {
1811         items = new HashMap(size*2+1);
1812         values = new OneAttr[size];
1813     }
1814     void put(String key, OneAttr value) {
1815         items.put(key, value);
1816         values[pos++] = value;
1817     }
1818     OneAttr get(String key) {
1819         OneAttr ret = (OneAttr)items.get(key);
1820         return ret;
1821     }
1822 }