1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2002-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * 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; 22 23 import java.lang.reflect.Array; 24 import java.util.AbstractList; 25 import java.util.Iterator; 26 import java.util.ListIterator; 27 import java.util.NoSuchElementException; 28 import java.util.Vector; 29 30 import com.sun.org.apache.xerces.internal.impl.Constants; 31 import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; 32 import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMap4Types; 33 import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMapImpl; 34 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 35 import com.sun.org.apache.xerces.internal.util.SymbolHash; 36 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 37 import com.sun.org.apache.xerces.internal.xs.StringList; 38 import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration; 39 import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition; 40 import com.sun.org.apache.xerces.internal.xs.XSConstants; 41 import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; 42 import com.sun.org.apache.xerces.internal.xs.XSModel; 43 import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition; 44 import com.sun.org.apache.xerces.internal.xs.XSNamedMap; 45 import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; 46 import com.sun.org.apache.xerces.internal.xs.XSNamespaceItemList; 47 import com.sun.org.apache.xerces.internal.xs.XSNotationDeclaration; 48 import com.sun.org.apache.xerces.internal.xs.XSObject; 49 import com.sun.org.apache.xerces.internal.xs.XSObjectList; 50 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 51 52 /** 53 * Implements XSModel: a read-only interface that represents an XML Schema, 54 * which could be components from different namespaces. 55 * 56 * @xerces.internal 57 * 58 * @author Sandy Gao, IBM 59 * 60 * @version $Id: XSModelImpl.java,v 1.7 2010-11-01 04:39:55 joehw Exp $ 61 */ 62 public final class XSModelImpl extends AbstractList implements XSModel, XSNamespaceItemList { 63 64 // the max index / the max value of XSObject type 65 private static final short MAX_COMP_IDX = XSTypeDefinition.SIMPLE_TYPE; 66 private static final boolean[] GLOBAL_COMP = {false, // null 67 true, // attribute 68 true, // element 69 true, // type 70 false, // attribute use 71 true, // attribute group 72 true, // group 73 false, // model group 74 false, // particle 75 false, // wildcard 76 false, // idc 77 true, // notation 78 false, // annotation 79 false, // facet 80 false, // multi value facet 81 true, // complex type 82 true // simple type 83 }; 84 85 // number of grammars/namespaces stored here 86 private final int fGrammarCount; 87 // all target namespaces 88 private final String[] fNamespaces; 89 // all schema grammar objects (for each namespace) 90 private final SchemaGrammar[] fGrammarList; 91 // a map from namespace to schema grammar 92 private final SymbolHash fGrammarMap; 93 // a map from element declaration to its substitution group 94 private final SymbolHash fSubGroupMap; 95 96 // store a certain kind of components from all namespaces 97 private final XSNamedMap[] fGlobalComponents; 98 // store a certain kind of components from one namespace 99 private final XSNamedMap[][] fNSComponents; 100 101 // a string list of all the target namespaces. 102 private final StringList fNamespacesList; 103 // store all annotations 104 private XSObjectList fAnnotations = null; 105 106 // whether there is any IDC in this XSModel 107 private final boolean fHasIDC; 108 109 /** 110 * Construct an XSModelImpl, by storing some grammars and grammars imported 111 * by them to this object. 112 * 113 * @param grammars the array of schema grammars 114 */ 115 public XSModelImpl(SchemaGrammar[] grammars) { 116 this(grammars, Constants.SCHEMA_VERSION_1_0); 117 } 118 119 public XSModelImpl(SchemaGrammar[] grammars, short s4sVersion) { 120 // copy namespaces/grammars from the array to our arrays 121 int len = grammars.length; 122 final int initialSize = Math.max(len+1, 5); 123 String[] namespaces = new String[initialSize]; 124 SchemaGrammar[] grammarList = new SchemaGrammar[initialSize]; 125 boolean hasS4S = false; 126 for (int i = 0; i < len; i++) { 127 final SchemaGrammar sg = grammars[i]; 128 final String tns = sg.getTargetNamespace(); 129 namespaces[i] = tns; 130 grammarList[i] = sg; 131 if (tns == SchemaSymbols.URI_SCHEMAFORSCHEMA) { 132 hasS4S = true; 133 } 134 } 135 // If a schema for the schema namespace isn't included, include it here. 136 if (!hasS4S) { 137 namespaces[len] = SchemaSymbols.URI_SCHEMAFORSCHEMA; 138 grammarList[len++] = SchemaGrammar.getS4SGrammar(s4sVersion); 139 } 140 141 SchemaGrammar sg1, sg2; 142 Vector gs; 143 int i, j, k; 144 // and recursively get all imported grammars, add them to our arrays 145 for (i = 0; i < len; i++) { 146 // get the grammar 147 sg1 = grammarList[i]; 148 gs = sg1.getImportedGrammars(); 149 // for each imported grammar 150 for (j = gs == null ? -1 : gs.size() - 1; j >= 0; j--) { 151 sg2 = (SchemaGrammar)gs.elementAt(j); 152 // check whether this grammar is already in the list 153 for (k = 0; k < len; k++) { 154 if (sg2 == grammarList[k]) { 155 break; 156 } 157 } 158 // if it's not, add it to the list 159 if (k == len) { 160 // ensure the capacity of the arrays 161 if (len == grammarList.length) { 162 String[] newSA = new String[len*2]; 163 System.arraycopy(namespaces, 0, newSA, 0, len); 164 namespaces = newSA; 165 SchemaGrammar[] newGA = new SchemaGrammar[len*2]; 166 System.arraycopy(grammarList, 0, newGA, 0, len); 167 grammarList = newGA; 168 } 169 namespaces[len] = sg2.getTargetNamespace(); 170 grammarList[len] = sg2; 171 len++; 172 } 173 } 174 } 175 176 fNamespaces = namespaces; 177 fGrammarList = grammarList; 178 179 boolean hasIDC = false; 180 // establish the mapping from namespace to grammars 181 fGrammarMap = new SymbolHash(len*2); 182 for (i = 0; i < len; i++) { 183 fGrammarMap.put(null2EmptyString(fNamespaces[i]), fGrammarList[i]); 184 // update the idc field 185 if (fGrammarList[i].hasIDConstraints()) { 186 hasIDC = true; 187 } 188 } 189 190 fHasIDC = hasIDC; 191 fGrammarCount = len; 192 fGlobalComponents = new XSNamedMap[MAX_COMP_IDX+1]; 193 fNSComponents = new XSNamedMap[len][MAX_COMP_IDX+1]; 194 fNamespacesList = new StringListImpl(fNamespaces, fGrammarCount); 195 196 // build substitution groups 197 fSubGroupMap = buildSubGroups(); 198 } 199 200 private SymbolHash buildSubGroups_Org() { 201 SubstitutionGroupHandler sgHandler = new SubstitutionGroupHandler(null); 202 for (int i = 0 ; i < fGrammarCount; i++) { 203 sgHandler.addSubstitutionGroup(fGrammarList[i].getSubstitutionGroups()); 204 } 205 206 final XSNamedMap elements = getComponents(XSConstants.ELEMENT_DECLARATION); 207 final int len = elements.getLength(); 208 final SymbolHash subGroupMap = new SymbolHash(len*2); 209 XSElementDecl head; 210 XSElementDeclaration[] subGroup; 211 for (int i = 0; i < len; i++) { 212 head = (XSElementDecl)elements.item(i); 213 subGroup = sgHandler.getSubstitutionGroup(head); 214 subGroupMap.put(head, subGroup.length > 0 ? 215 new XSObjectListImpl(subGroup, subGroup.length) : XSObjectListImpl.EMPTY_LIST); 216 } 217 return subGroupMap; 218 } 219 220 private SymbolHash buildSubGroups() { 221 SubstitutionGroupHandler sgHandler = new SubstitutionGroupHandler(null); 222 for (int i = 0 ; i < fGrammarCount; i++) { 223 sgHandler.addSubstitutionGroup(fGrammarList[i].getSubstitutionGroups()); 224 } 225 226 final XSObjectListImpl elements = getGlobalElements(); 227 final int len = elements.getLength(); 228 final SymbolHash subGroupMap = new SymbolHash(len*2); 229 XSElementDecl head; 230 XSElementDeclaration[] subGroup; 231 for (int i = 0; i < len; i++) { 232 head = (XSElementDecl)elements.item(i); 233 subGroup = sgHandler.getSubstitutionGroup(head); 234 subGroupMap.put(head, subGroup.length > 0 ? 235 new XSObjectListImpl(subGroup, subGroup.length) : XSObjectListImpl.EMPTY_LIST); 236 } 237 return subGroupMap; 238 } 239 240 private XSObjectListImpl getGlobalElements() { 241 final SymbolHash[] tables = new SymbolHash[fGrammarCount]; 242 int length = 0; 243 244 for (int i = 0; i < fGrammarCount; i++) { 245 tables[i] = fGrammarList[i].fAllGlobalElemDecls; 246 length += tables[i].getLength(); 247 } 248 249 if (length == 0) { 250 return XSObjectListImpl.EMPTY_LIST; 251 } 252 253 final XSObject[] components = new XSObject[length]; 254 255 int start = 0; 256 for (int i = 0; i < fGrammarCount; i++) { 257 tables[i].getValues(components, start); 258 start += tables[i].getLength(); 259 } 260 261 return new XSObjectListImpl(components, length); 262 } 263 264 /** 265 * Convenience method. Returns a list of all namespaces that belong to 266 * this schema. 267 * @return A list of all namespaces that belong to this schema or 268 * <code>null</code> if all components don't have a targetNamespace. 269 */ 270 public StringList getNamespaces() { 271 return fNamespacesList; 272 } 273 274 /** 275 * A set of namespace schema information information items (of type 276 * <code>XSNamespaceItem</code>), one for each namespace name which 277 * appears as the target namespace of any schema component in the schema 278 * used for that assessment, and one for absent if any schema component 279 * in the schema had no target namespace. For more information see 280 * schema information. 281 */ 282 public XSNamespaceItemList getNamespaceItems() { 283 return this; 284 } 285 286 /** 287 * Returns a list of top-level components, i.e. element declarations, 288 * attribute declarations, etc. 289 * @param objectType The type of the declaration, i.e. 290 * <code>ELEMENT_DECLARATION</code>. Note that 291 * <code>XSTypeDefinition.SIMPLE_TYPE</code> and 292 * <code>XSTypeDefinition.COMPLEX_TYPE</code> can also be used as the 293 * <code>objectType</code> to retrieve only complex types or simple 294 * types, instead of all types. 295 * @return A list of top-level definitions of the specified type in 296 * <code>objectType</code> or an empty <code>XSNamedMap</code> if no 297 * such definitions exist. 298 */ 299 public synchronized XSNamedMap getComponents(short objectType) { 300 if (objectType <= 0 || objectType > MAX_COMP_IDX || 301 !GLOBAL_COMP[objectType]) { 302 return XSNamedMapImpl.EMPTY_MAP; 303 } 304 305 SymbolHash[] tables = new SymbolHash[fGrammarCount]; 306 // get all hashtables from all namespaces for this type of components 307 if (fGlobalComponents[objectType] == null) { 308 for (int i = 0; i < fGrammarCount; i++) { 309 switch (objectType) { 310 case XSConstants.TYPE_DEFINITION: 311 case XSTypeDefinition.COMPLEX_TYPE: 312 case XSTypeDefinition.SIMPLE_TYPE: 313 tables[i] = fGrammarList[i].fGlobalTypeDecls; 314 break; 315 case XSConstants.ATTRIBUTE_DECLARATION: 316 tables[i] = fGrammarList[i].fGlobalAttrDecls; 317 break; 318 case XSConstants.ELEMENT_DECLARATION: 319 tables[i] = fGrammarList[i].fGlobalElemDecls; 320 break; 321 case XSConstants.ATTRIBUTE_GROUP: 322 tables[i] = fGrammarList[i].fGlobalAttrGrpDecls; 323 break; 324 case XSConstants.MODEL_GROUP_DEFINITION: 325 tables[i] = fGrammarList[i].fGlobalGroupDecls; 326 break; 327 case XSConstants.NOTATION_DECLARATION: 328 tables[i] = fGrammarList[i].fGlobalNotationDecls; 329 break; 330 } 331 } 332 // for complex/simple types, create a special implementation, 333 // which take specific types out of the hash table 334 if (objectType == XSTypeDefinition.COMPLEX_TYPE || 335 objectType == XSTypeDefinition.SIMPLE_TYPE) { 336 fGlobalComponents[objectType] = new XSNamedMap4Types(fNamespaces, tables, fGrammarCount, objectType); 337 } 338 else { 339 fGlobalComponents[objectType] = new XSNamedMapImpl(fNamespaces, tables, fGrammarCount); 340 } 341 } 342 343 return fGlobalComponents[objectType]; 344 } 345 346 /** 347 * Convenience method. Returns a list of top-level component declarations 348 * that are defined within the specified namespace, i.e. element 349 * declarations, attribute declarations, etc. 350 * @param objectType The type of the declaration, i.e. 351 * <code>ELEMENT_DECLARATION</code>. 352 * @param namespace The namespace to which the declaration belongs or 353 * <code>null</code> (for components with no target namespace). 354 * @return A list of top-level definitions of the specified type in 355 * <code>objectType</code> and defined in the specified 356 * <code>namespace</code> or an empty <code>XSNamedMap</code>. 357 */ 358 public synchronized XSNamedMap getComponentsByNamespace(short objectType, 359 String namespace) { 360 if (objectType <= 0 || objectType > MAX_COMP_IDX || 361 !GLOBAL_COMP[objectType]) { 362 return XSNamedMapImpl.EMPTY_MAP; 363 } 364 365 // try to find the grammar 366 int i = 0; 367 if (namespace != null) { 368 for (; i < fGrammarCount; ++i) { 369 if (namespace.equals(fNamespaces[i])) { 370 break; 371 } 372 } 373 } 374 else { 375 for (; i < fGrammarCount; ++i) { 376 if (fNamespaces[i] == null) { 377 break; 378 } 379 } 380 } 381 if (i == fGrammarCount) { 382 return XSNamedMapImpl.EMPTY_MAP; 383 } 384 385 // get the hashtable for this type of components 386 if (fNSComponents[i][objectType] == null) { 387 SymbolHash table = null; 388 switch (objectType) { 389 case XSConstants.TYPE_DEFINITION: 390 case XSTypeDefinition.COMPLEX_TYPE: 391 case XSTypeDefinition.SIMPLE_TYPE: 392 table = fGrammarList[i].fGlobalTypeDecls; 393 break; 394 case XSConstants.ATTRIBUTE_DECLARATION: 395 table = fGrammarList[i].fGlobalAttrDecls; 396 break; 397 case XSConstants.ELEMENT_DECLARATION: 398 table = fGrammarList[i].fGlobalElemDecls; 399 break; 400 case XSConstants.ATTRIBUTE_GROUP: 401 table = fGrammarList[i].fGlobalAttrGrpDecls; 402 break; 403 case XSConstants.MODEL_GROUP_DEFINITION: 404 table = fGrammarList[i].fGlobalGroupDecls; 405 break; 406 case XSConstants.NOTATION_DECLARATION: 407 table = fGrammarList[i].fGlobalNotationDecls; 408 break; 409 } 410 411 // for complex/simple types, create a special implementation, 412 // which take specific types out of the hash table 413 if (objectType == XSTypeDefinition.COMPLEX_TYPE || 414 objectType == XSTypeDefinition.SIMPLE_TYPE) { 415 fNSComponents[i][objectType] = new XSNamedMap4Types(namespace, table, objectType); 416 } 417 else { 418 fNSComponents[i][objectType] = new XSNamedMapImpl(namespace, table); 419 } 420 } 421 422 return fNSComponents[i][objectType]; 423 } 424 425 /** 426 * Convenience method. Returns a top-level simple or complex type 427 * definition. 428 * @param name The name of the definition. 429 * @param namespace The namespace of the definition, otherwise null. 430 * @return An <code>XSTypeDefinition</code> or null if such definition 431 * does not exist. 432 */ 433 public XSTypeDefinition getTypeDefinition(String name, 434 String namespace) { 435 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 436 if (sg == null) { 437 return null; 438 } 439 return (XSTypeDefinition)sg.fGlobalTypeDecls.get(name); 440 } 441 442 /** 443 * Convenience method. Returns a top-level simple or complex type 444 * definition. 445 * @param name The name of the definition. 446 * @param namespace The namespace of the definition, otherwise null. 447 * @param loc The schema location where the component was defined 448 * @return An <code>XSTypeDefinition</code> or null if such definition 449 * does not exist. 450 */ 451 public XSTypeDefinition getTypeDefinition(String name, 452 String namespace, 453 String loc) { 454 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 455 if (sg == null) { 456 return null; 457 } 458 return sg.getGlobalTypeDecl(name, loc); 459 } 460 461 /** 462 * Convenience method. Returns a top-level attribute declaration. 463 * @param name The name of the declaration. 464 * @param namespace The namespace of the definition, otherwise null. 465 * @return A top-level attribute declaration or null if such declaration 466 * does not exist. 467 */ 468 public XSAttributeDeclaration getAttributeDeclaration(String name, 469 String namespace) { 470 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 471 if (sg == null) { 472 return null; 473 } 474 return (XSAttributeDeclaration)sg.fGlobalAttrDecls.get(name); 475 } 476 477 /** 478 * Convenience method. Returns a top-level attribute declaration. 479 * @param name The name of the declaration. 480 * @param namespace The namespace of the definition, otherwise null. 481 * @param loc The schema location where the component was defined 482 * @return A top-level attribute declaration or null if such declaration 483 * does not exist. 484 */ 485 public XSAttributeDeclaration getAttributeDeclaration(String name, 486 String namespace, 487 String loc) { 488 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 489 if (sg == null) { 490 return null; 491 } 492 return sg.getGlobalAttributeDecl(name, loc); 493 } 494 495 /** 496 * Convenience method. Returns a top-level element declaration. 497 * @param name The name of the declaration. 498 * @param namespace The namespace of the definition, otherwise null. 499 * @return A top-level element declaration or null if such declaration 500 * does not exist. 501 */ 502 public XSElementDeclaration getElementDeclaration(String name, 503 String namespace) { 504 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 505 if (sg == null) { 506 return null; 507 } 508 return (XSElementDeclaration)sg.fGlobalElemDecls.get(name); 509 } 510 511 /** 512 * Convenience method. Returns a top-level element declaration. 513 * @param name The name of the declaration. 514 * @param namespace The namespace of the definition, otherwise null. 515 * @param loc The schema location where the component was defined 516 * @return A top-level element declaration or null if such declaration 517 * does not exist. 518 */ 519 public XSElementDeclaration getElementDeclaration(String name, 520 String namespace, 521 String loc) { 522 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 523 if (sg == null) { 524 return null; 525 } 526 return sg.getGlobalElementDecl(name, loc); 527 } 528 529 /** 530 * Convenience method. Returns a top-level attribute group definition. 531 * @param name The name of the definition. 532 * @param namespace The namespace of the definition, otherwise null. 533 * @return A top-level attribute group definition or null if such 534 * definition does not exist. 535 */ 536 public XSAttributeGroupDefinition getAttributeGroup(String name, 537 String namespace) { 538 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 539 if (sg == null) { 540 return null; 541 } 542 return (XSAttributeGroupDefinition)sg.fGlobalAttrGrpDecls.get(name); 543 } 544 545 /** 546 * Convenience method. Returns a top-level attribute group definition. 547 * @param name The name of the definition. 548 * @param namespace The namespace of the definition, otherwise null. 549 * @param loc The schema location where the component was defined 550 * @return A top-level attribute group definition or null if such 551 * definition does not exist. 552 */ 553 public XSAttributeGroupDefinition getAttributeGroup(String name, 554 String namespace, 555 String loc) { 556 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 557 if (sg == null) { 558 return null; 559 } 560 return sg.getGlobalAttributeGroupDecl(name, loc); 561 } 562 563 /** 564 * Convenience method. Returns a top-level model group definition. 565 * 566 * @param name The name of the definition. 567 * @param namespace The namespace of the definition, otherwise null. 568 * @return A top-level model group definition definition or null if such 569 * definition does not exist. 570 */ 571 public XSModelGroupDefinition getModelGroupDefinition(String name, 572 String namespace) { 573 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 574 if (sg == null) { 575 return null; 576 } 577 return (XSModelGroupDefinition)sg.fGlobalGroupDecls.get(name); 578 } 579 580 /** 581 * Convenience method. Returns a top-level model group definition. 582 * 583 * @param name The name of the definition. 584 * @param namespace The namespace of the definition, otherwise null. 585 * @param loc The schema location where the component was defined 586 * @return A top-level model group definition definition or null if such 587 * definition does not exist. 588 */ 589 public XSModelGroupDefinition getModelGroupDefinition(String name, 590 String namespace, 591 String loc) { 592 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 593 if (sg == null) { 594 return null; 595 } 596 return sg.getGlobalGroupDecl(name, loc); 597 } 598 599 600 /** 601 * @see org.apache.xerces.xs.XSModel#getNotationDeclaration(String, String) 602 */ 603 public XSNotationDeclaration getNotationDeclaration(String name, 604 String namespace) { 605 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 606 if (sg == null) { 607 return null; 608 } 609 return (XSNotationDeclaration)sg.fGlobalNotationDecls.get(name); 610 } 611 612 public XSNotationDeclaration getNotationDeclaration(String name, 613 String namespace, 614 String loc) { 615 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 616 if (sg == null) { 617 return null; 618 } 619 return sg.getGlobalNotationDecl(name, loc); 620 } 621 622 /** 623 * [annotations]: a set of annotations if it exists, otherwise an empty 624 * <code>XSObjectList</code>. 625 */ 626 public synchronized XSObjectList getAnnotations() { 627 if (fAnnotations != null) { 628 return fAnnotations; 629 } 630 631 // do this in two passes to avoid inaccurate array size 632 int totalAnnotations = 0; 633 for (int i = 0; i < fGrammarCount; i++) { 634 totalAnnotations += fGrammarList[i].fNumAnnotations; 635 } 636 if (totalAnnotations == 0) { 637 fAnnotations = XSObjectListImpl.EMPTY_LIST; 638 return fAnnotations; 639 } 640 XSAnnotationImpl [] annotations = new XSAnnotationImpl [totalAnnotations]; 641 int currPos = 0; 642 for (int i = 0; i < fGrammarCount; i++) { 643 SchemaGrammar currGrammar = fGrammarList[i]; 644 if (currGrammar.fNumAnnotations > 0) { 645 System.arraycopy(currGrammar.fAnnotations, 0, annotations, currPos, currGrammar.fNumAnnotations); 646 currPos += currGrammar.fNumAnnotations; 647 } 648 } 649 fAnnotations = new XSObjectListImpl(annotations, annotations.length); 650 return fAnnotations; 651 } 652 653 private static final String null2EmptyString(String str) { 654 return str == null ? XMLSymbols.EMPTY_STRING : str; 655 } 656 657 /** 658 * REVISIT: to expose identity constraints from XSModel. 659 * For now, we only expose whether there are any IDCs. 660 * We also need to add these methods to the public 661 * XSModel interface. 662 */ 663 public boolean hasIDConstraints() { 664 return fHasIDC; 665 } 666 667 /** 668 * Convenience method. Returns a list containing the members of the 669 * substitution group for the given <code>XSElementDeclaration</code> 670 * or an empty <code>XSObjectList</code> if the substitution group 671 * contains no members. 672 * @param head The substitution group head. 673 * @return A list containing the members of the substitution group 674 * for the given <code>XSElementDeclaration</code> or an empty 675 * <code>XSObjectList</code> if the substitution group contains 676 * no members. 677 */ 678 public XSObjectList getSubstitutionGroup(XSElementDeclaration head) { 679 return (XSObjectList)fSubGroupMap.get(head); 680 } 681 682 // 683 // XSNamespaceItemList methods 684 // 685 686 /** 687 * The number of <code>XSNamespaceItem</code>s in the list. The range of 688 * valid child object indices is 0 to <code>length-1</code> inclusive. 689 */ 690 public int getLength() { 691 return fGrammarCount; 692 } 693 694 /** 695 * Returns the <code>index</code>th item in the collection or 696 * <code>null</code> if <code>index</code> is greater than or equal to 697 * the number of objects in the list. The index starts at 0. 698 * @param index index into the collection. 699 * @return The <code>XSNamespaceItem</code> at the <code>index</code>th 700 * position in the <code>XSNamespaceItemList</code>, or 701 * <code>null</code> if the index specified is not valid. 702 */ 703 public XSNamespaceItem item(int index) { 704 if (index < 0 || index >= fGrammarCount) { 705 return null; 706 } 707 return fGrammarList[index]; 708 } 709 710 // 711 // java.util.List methods 712 // 713 714 public Object get(int index) { 715 if (index >= 0 && index < fGrammarCount) { 716 return fGrammarList[index]; 717 } 718 throw new IndexOutOfBoundsException("Index: " + index); 719 } 720 721 public int size() { 722 return getLength(); 723 } 724 725 public Iterator iterator() { 726 return listIterator0(0); 727 } 728 729 public ListIterator listIterator() { 730 return listIterator0(0); 731 } 732 733 public ListIterator listIterator(int index) { 734 if (index >= 0 && index < fGrammarCount) { 735 return listIterator0(index); 736 } 737 throw new IndexOutOfBoundsException("Index: " + index); 738 } 739 740 private ListIterator listIterator0(int index) { 741 return new XSNamespaceItemListIterator(index); 742 } 743 744 public Object[] toArray() { 745 Object[] a = new Object[fGrammarCount]; 746 toArray0(a); 747 return a; 748 } 749 750 public Object[] toArray(Object[] a) { 751 if (a.length < fGrammarCount) { 752 Class arrayClass = a.getClass(); 753 Class componentType = arrayClass.getComponentType(); 754 a = (Object[]) Array.newInstance(componentType, fGrammarCount); 755 } 756 toArray0(a); 757 if (a.length > fGrammarCount) { 758 a[fGrammarCount] = null; 759 } 760 return a; 761 } 762 763 private void toArray0(Object[] a) { 764 if (fGrammarCount > 0) { 765 System.arraycopy(fGrammarList, 0, a, 0, fGrammarCount); 766 } 767 } 768 769 private final class XSNamespaceItemListIterator implements ListIterator { 770 private int index; 771 public XSNamespaceItemListIterator(int index) { 772 this.index = index; 773 } 774 public boolean hasNext() { 775 return (index < fGrammarCount); 776 } 777 public Object next() { 778 if (index < fGrammarCount) { 779 return fGrammarList[index++]; 780 } 781 throw new NoSuchElementException(); 782 } 783 public boolean hasPrevious() { 784 return (index > 0); 785 } 786 public Object previous() { 787 if (index > 0) { 788 return fGrammarList[--index]; 789 } 790 throw new NoSuchElementException(); 791 } 792 public int nextIndex() { 793 return index; 794 } 795 public int previousIndex() { 796 return index - 1; 797 } 798 public void remove() { 799 throw new UnsupportedOperationException(); 800 } 801 public void set(Object o) { 802 throw new UnsupportedOperationException(); 803 } 804 public void add(Object o) { 805 throw new UnsupportedOperationException(); 806 } 807 } 808 809 } // class XSModelImpl