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