1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xerces.internal.impl.xs; 23 24import com.sun.org.apache.xerces.internal.impl.Constants; 25import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl; 26import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMap4Types; 27import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMapImpl; 28import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 29import com.sun.org.apache.xerces.internal.util.SymbolHash; 30import com.sun.org.apache.xerces.internal.util.XMLSymbols; 31import com.sun.org.apache.xerces.internal.xs.StringList; 32import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration; 33import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition; 34import com.sun.org.apache.xerces.internal.xs.XSConstants; 35import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration; 36import com.sun.org.apache.xerces.internal.xs.XSIDCDefinition; 37import com.sun.org.apache.xerces.internal.xs.XSModel; 38import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition; 39import com.sun.org.apache.xerces.internal.xs.XSNamedMap; 40import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; 41import com.sun.org.apache.xerces.internal.xs.XSNamespaceItemList; 42import com.sun.org.apache.xerces.internal.xs.XSNotationDeclaration; 43import com.sun.org.apache.xerces.internal.xs.XSObject; 44import com.sun.org.apache.xerces.internal.xs.XSObjectList; 45import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 46import java.lang.reflect.Array; 47import java.util.AbstractList; 48import java.util.Iterator; 49import java.util.ListIterator; 50import java.util.NoSuchElementException; 51import java.util.Vector; 52 53/** 54 * Implements XSModel: a read-only interface that represents an XML Schema, 55 * which could be components from different namespaces. 56 * 57 * @xerces.internal 58 * 59 * @author Sandy Gao, IBM 60 * 61 */ 62public 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 true, // 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 case XSConstants.IDENTITY_CONSTRAINT: 331 tables[i] = fGrammarList[i].fGlobalIDConstraintDecls; 332 break; 333 } 334 } 335 // for complex/simple types, create a special implementation, 336 // which take specific types out of the hash table 337 if (objectType == XSTypeDefinition.COMPLEX_TYPE || 338 objectType == XSTypeDefinition.SIMPLE_TYPE) { 339 fGlobalComponents[objectType] = new XSNamedMap4Types(fNamespaces, tables, fGrammarCount, objectType); 340 } 341 else { 342 fGlobalComponents[objectType] = new XSNamedMapImpl(fNamespaces, tables, fGrammarCount); 343 } 344 } 345 346 return fGlobalComponents[objectType]; 347 } 348 349 /** 350 * Convenience method. Returns a list of top-level component declarations 351 * that are defined within the specified namespace, i.e. element 352 * declarations, attribute declarations, etc. 353 * @param objectType The type of the declaration, i.e. 354 * <code>ELEMENT_DECLARATION</code>. 355 * @param namespace The namespace to which the declaration belongs or 356 * <code>null</code> (for components with no target namespace). 357 * @return A list of top-level definitions of the specified type in 358 * <code>objectType</code> and defined in the specified 359 * <code>namespace</code> or an empty <code>XSNamedMap</code>. 360 */ 361 public synchronized XSNamedMap getComponentsByNamespace(short objectType, 362 String namespace) { 363 if (objectType <= 0 || objectType > MAX_COMP_IDX || 364 !GLOBAL_COMP[objectType]) { 365 return XSNamedMapImpl.EMPTY_MAP; 366 } 367 368 // try to find the grammar 369 int i = 0; 370 if (namespace != null) { 371 for (; i < fGrammarCount; ++i) { 372 if (namespace.equals(fNamespaces[i])) { 373 break; 374 } 375 } 376 } 377 else { 378 for (; i < fGrammarCount; ++i) { 379 if (fNamespaces[i] == null) { 380 break; 381 } 382 } 383 } 384 if (i == fGrammarCount) { 385 return XSNamedMapImpl.EMPTY_MAP; 386 } 387 388 // get the hashtable for this type of components 389 if (fNSComponents[i][objectType] == null) { 390 SymbolHash table = null; 391 switch (objectType) { 392 case XSConstants.TYPE_DEFINITION: 393 case XSTypeDefinition.COMPLEX_TYPE: 394 case XSTypeDefinition.SIMPLE_TYPE: 395 table = fGrammarList[i].fGlobalTypeDecls; 396 break; 397 case XSConstants.ATTRIBUTE_DECLARATION: 398 table = fGrammarList[i].fGlobalAttrDecls; 399 break; 400 case XSConstants.ELEMENT_DECLARATION: 401 table = fGrammarList[i].fGlobalElemDecls; 402 break; 403 case XSConstants.ATTRIBUTE_GROUP: 404 table = fGrammarList[i].fGlobalAttrGrpDecls; 405 break; 406 case XSConstants.MODEL_GROUP_DEFINITION: 407 table = fGrammarList[i].fGlobalGroupDecls; 408 break; 409 case XSConstants.NOTATION_DECLARATION: 410 table = fGrammarList[i].fGlobalNotationDecls; 411 break; 412 case XSConstants.IDENTITY_CONSTRAINT: 413 table = fGrammarList[i].fGlobalIDConstraintDecls; 414 break; 415 } 416 417 // for complex/simple types, create a special implementation, 418 // which take specific types out of the hash table 419 if (objectType == XSTypeDefinition.COMPLEX_TYPE || 420 objectType == XSTypeDefinition.SIMPLE_TYPE) { 421 fNSComponents[i][objectType] = new XSNamedMap4Types(namespace, table, objectType); 422 } 423 else { 424 fNSComponents[i][objectType] = new XSNamedMapImpl(namespace, table); 425 } 426 } 427 428 return fNSComponents[i][objectType]; 429 } 430 431 /** 432 * Convenience method. Returns a top-level simple or complex type 433 * definition. 434 * @param name The name of the definition. 435 * @param namespace The namespace of the definition, otherwise null. 436 * @return An <code>XSTypeDefinition</code> or null if such definition 437 * does not exist. 438 */ 439 public XSTypeDefinition getTypeDefinition(String name, 440 String namespace) { 441 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 442 if (sg == null) { 443 return null; 444 } 445 return (XSTypeDefinition)sg.fGlobalTypeDecls.get(name); 446 } 447 448 /** 449 * Convenience method. Returns a top-level simple or complex type 450 * definition. 451 * @param name The name of the definition. 452 * @param namespace The namespace of the definition, otherwise null. 453 * @param loc The schema location where the component was defined 454 * @return An <code>XSTypeDefinition</code> or null if such definition 455 * does not exist. 456 */ 457 public XSTypeDefinition getTypeDefinition(String name, 458 String namespace, 459 String loc) { 460 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 461 if (sg == null) { 462 return null; 463 } 464 return sg.getGlobalTypeDecl(name, loc); 465 } 466 467 /** 468 * Convenience method. Returns a top-level attribute declaration. 469 * @param name The name of the declaration. 470 * @param namespace The namespace of the definition, otherwise null. 471 * @return A top-level attribute declaration or null if such declaration 472 * does not exist. 473 */ 474 public XSAttributeDeclaration getAttributeDeclaration(String name, 475 String namespace) { 476 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 477 if (sg == null) { 478 return null; 479 } 480 return (XSAttributeDeclaration)sg.fGlobalAttrDecls.get(name); 481 } 482 483 /** 484 * Convenience method. Returns a top-level attribute declaration. 485 * @param name The name of the declaration. 486 * @param namespace The namespace of the definition, otherwise null. 487 * @param loc The schema location where the component was defined 488 * @return A top-level attribute declaration or null if such declaration 489 * does not exist. 490 */ 491 public XSAttributeDeclaration getAttributeDeclaration(String name, 492 String namespace, 493 String loc) { 494 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 495 if (sg == null) { 496 return null; 497 } 498 return sg.getGlobalAttributeDecl(name, loc); 499 } 500 501 /** 502 * Convenience method. Returns a top-level element declaration. 503 * @param name The name of the declaration. 504 * @param namespace The namespace of the definition, otherwise null. 505 * @return A top-level element declaration or null if such declaration 506 * does not exist. 507 */ 508 public XSElementDeclaration getElementDeclaration(String name, 509 String namespace) { 510 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 511 if (sg == null) { 512 return null; 513 } 514 return (XSElementDeclaration)sg.fGlobalElemDecls.get(name); 515 } 516 517 /** 518 * Convenience method. Returns a top-level element declaration. 519 * @param name The name of the declaration. 520 * @param namespace The namespace of the definition, otherwise null. 521 * @param loc The schema location where the component was defined 522 * @return A top-level element declaration or null if such declaration 523 * does not exist. 524 */ 525 public XSElementDeclaration getElementDeclaration(String name, 526 String namespace, 527 String loc) { 528 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 529 if (sg == null) { 530 return null; 531 } 532 return sg.getGlobalElementDecl(name, loc); 533 } 534 535 /** 536 * Convenience method. Returns a top-level attribute group definition. 537 * @param name The name of the definition. 538 * @param namespace The namespace of the definition, otherwise null. 539 * @return A top-level attribute group definition or null if such 540 * definition does not exist. 541 */ 542 public XSAttributeGroupDefinition getAttributeGroup(String name, 543 String namespace) { 544 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 545 if (sg == null) { 546 return null; 547 } 548 return (XSAttributeGroupDefinition)sg.fGlobalAttrGrpDecls.get(name); 549 } 550 551 /** 552 * Convenience method. Returns a top-level attribute group definition. 553 * @param name The name of the definition. 554 * @param namespace The namespace of the definition, otherwise null. 555 * @param loc The schema location where the component was defined 556 * @return A top-level attribute group definition or null if such 557 * definition does not exist. 558 */ 559 public XSAttributeGroupDefinition getAttributeGroup(String name, 560 String namespace, 561 String loc) { 562 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 563 if (sg == null) { 564 return null; 565 } 566 return sg.getGlobalAttributeGroupDecl(name, loc); 567 } 568 569 /** 570 * Convenience method. Returns a top-level model group definition. 571 * 572 * @param name The name of the definition. 573 * @param namespace The namespace of the definition, otherwise null. 574 * @return A top-level model group definition definition or null if such 575 * definition does not exist. 576 */ 577 public XSModelGroupDefinition getModelGroupDefinition(String name, 578 String namespace) { 579 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 580 if (sg == null) { 581 return null; 582 } 583 return (XSModelGroupDefinition)sg.fGlobalGroupDecls.get(name); 584 } 585 586 /** 587 * Convenience method. Returns a top-level model group definition. 588 * 589 * @param name The name of the definition. 590 * @param namespace The namespace of the definition, otherwise null. 591 * @param loc The schema location where the component was defined 592 * @return A top-level model group definition definition or null if such 593 * definition does not exist. 594 */ 595 public XSModelGroupDefinition getModelGroupDefinition(String name, 596 String namespace, 597 String loc) { 598 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 599 if (sg == null) { 600 return null; 601 } 602 return sg.getGlobalGroupDecl(name, loc); 603 } 604 605 /** 606 * Convenience method. Returns a top-level model group definition. 607 * 608 * @param name The name of the definition. 609 * @param namespace The namespace of the definition, otherwise null. 610 * @return A top-level model group definition definition or null if such 611 * definition does not exist. 612 */ 613 public XSIDCDefinition getIDCDefinition(String name, String namespace) { 614 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 615 if (sg == null) { 616 return null; 617 } 618 return (XSIDCDefinition)sg.fGlobalIDConstraintDecls.get(name); 619 } 620 621 /** 622 * Convenience method. Returns a top-level model group definition. 623 * 624 * @param name The name of the definition. 625 * @param namespace The namespace of the definition, otherwise null. 626 * @param loc The schema location where the component was defined 627 * @return A top-level model group definition definition or null if such 628 * definition does not exist. 629 */ 630 public XSIDCDefinition getIDCDefinition(String name, String namespace, 631 String loc) { 632 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 633 if (sg == null) { 634 return null; 635 } 636 return sg.getIDConstraintDecl(name, loc); 637 } 638 639 640 /** 641 * @see org.apache.xerces.xs.XSModel#getNotationDeclaration(String, String) 642 */ 643 public XSNotationDeclaration getNotationDeclaration(String name, 644 String namespace) { 645 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 646 if (sg == null) { 647 return null; 648 } 649 return (XSNotationDeclaration)sg.fGlobalNotationDecls.get(name); 650 } 651 652 public XSNotationDeclaration getNotationDeclaration(String name, 653 String namespace, 654 String loc) { 655 SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace)); 656 if (sg == null) { 657 return null; 658 } 659 return sg.getGlobalNotationDecl(name, loc); 660 } 661 662 /** 663 * [annotations]: a set of annotations if it exists, otherwise an empty 664 * <code>XSObjectList</code>. 665 */ 666 public synchronized XSObjectList getAnnotations() { 667 if (fAnnotations != null) { 668 return fAnnotations; 669 } 670 671 // do this in two passes to avoid inaccurate array size 672 int totalAnnotations = 0; 673 for (int i = 0; i < fGrammarCount; i++) { 674 totalAnnotations += fGrammarList[i].fNumAnnotations; 675 } 676 if (totalAnnotations == 0) { 677 fAnnotations = XSObjectListImpl.EMPTY_LIST; 678 return fAnnotations; 679 } 680 XSAnnotationImpl [] annotations = new XSAnnotationImpl [totalAnnotations]; 681 int currPos = 0; 682 for (int i = 0; i < fGrammarCount; i++) { 683 SchemaGrammar currGrammar = fGrammarList[i]; 684 if (currGrammar.fNumAnnotations > 0) { 685 System.arraycopy(currGrammar.fAnnotations, 0, annotations, currPos, currGrammar.fNumAnnotations); 686 currPos += currGrammar.fNumAnnotations; 687 } 688 } 689 fAnnotations = new XSObjectListImpl(annotations, annotations.length); 690 return fAnnotations; 691 } 692 693 private static final String null2EmptyString(String str) { 694 return str == null ? XMLSymbols.EMPTY_STRING : str; 695 } 696 697 /** 698 * REVISIT: to expose identity constraints from XSModel. 699 * For now, we only expose whether there are any IDCs. 700 * We also need to add these methods to the public 701 * XSModel interface. 702 */ 703 public boolean hasIDConstraints() { 704 return fHasIDC; 705 } 706 707 /** 708 * Convenience method. Returns a list containing the members of the 709 * substitution group for the given <code>XSElementDeclaration</code> 710 * or an empty <code>XSObjectList</code> if the substitution group 711 * contains no members. 712 * @param head The substitution group head. 713 * @return A list containing the members of the substitution group 714 * for the given <code>XSElementDeclaration</code> or an empty 715 * <code>XSObjectList</code> if the substitution group contains 716 * no members. 717 */ 718 public XSObjectList getSubstitutionGroup(XSElementDeclaration head) { 719 return (XSObjectList)fSubGroupMap.get(head); 720 } 721 722 // 723 // XSNamespaceItemList methods 724 // 725 726 /** 727 * The number of <code>XSNamespaceItem</code>s in the list. The range of 728 * valid child object indices is 0 to <code>length-1</code> inclusive. 729 */ 730 public int getLength() { 731 return fGrammarCount; 732 } 733 734 /** 735 * Returns the <code>index</code>th item in the collection or 736 * <code>null</code> if <code>index</code> is greater than or equal to 737 * the number of objects in the list. The index starts at 0. 738 * @param index index into the collection. 739 * @return The <code>XSNamespaceItem</code> at the <code>index</code>th 740 * position in the <code>XSNamespaceItemList</code>, or 741 * <code>null</code> if the index specified is not valid. 742 */ 743 public XSNamespaceItem item(int index) { 744 if (index < 0 || index >= fGrammarCount) { 745 return null; 746 } 747 return fGrammarList[index]; 748 } 749 750 // 751 // java.util.List methods 752 // 753 754 public Object get(int index) { 755 if (index >= 0 && index < fGrammarCount) { 756 return fGrammarList[index]; 757 } 758 throw new IndexOutOfBoundsException("Index: " + index); 759 } 760 761 public int size() { 762 return getLength(); 763 } 764 765 public Iterator iterator() { 766 return listIterator0(0); 767 } 768 769 public ListIterator listIterator() { 770 return listIterator0(0); 771 } 772 773 public ListIterator listIterator(int index) { 774 if (index >= 0 && index < fGrammarCount) { 775 return listIterator0(index); 776 } 777 throw new IndexOutOfBoundsException("Index: " + index); 778 } 779 780 private ListIterator listIterator0(int index) { 781 return new XSNamespaceItemListIterator(index); 782 } 783 784 public Object[] toArray() { 785 Object[] a = new Object[fGrammarCount]; 786 toArray0(a); 787 return a; 788 } 789 790 public Object[] toArray(Object[] a) { 791 if (a.length < fGrammarCount) { 792 Class arrayClass = a.getClass(); 793 Class componentType = arrayClass.getComponentType(); 794 a = (Object[]) Array.newInstance(componentType, fGrammarCount); 795 } 796 toArray0(a); 797 if (a.length > fGrammarCount) { 798 a[fGrammarCount] = null; 799 } 800 return a; 801 } 802 803 private void toArray0(Object[] a) { 804 if (fGrammarCount > 0) { 805 System.arraycopy(fGrammarList, 0, a, 0, fGrammarCount); 806 } 807 } 808 809 private final class XSNamespaceItemListIterator implements ListIterator { 810 private int index; 811 public XSNamespaceItemListIterator(int index) { 812 this.index = index; 813 } 814 public boolean hasNext() { 815 return (index < fGrammarCount); 816 } 817 public Object next() { 818 if (index < fGrammarCount) { 819 return fGrammarList[index++]; 820 } 821 throw new NoSuchElementException(); 822 } 823 public boolean hasPrevious() { 824 return (index > 0); 825 } 826 public Object previous() { 827 if (index > 0) { 828 return fGrammarList[--index]; 829 } 830 throw new NoSuchElementException(); 831 } 832 public int nextIndex() { 833 return index; 834 } 835 public int previousIndex() { 836 return index - 1; 837 } 838 public void remove() { 839 throw new UnsupportedOperationException(); 840 } 841 public void set(Object o) { 842 throw new UnsupportedOperationException(); 843 } 844 public void add(Object o) { 845 throw new UnsupportedOperationException(); 846 } 847 } 848 849} // class XSModelImpl 850