blob: bded2950e0b7b7429173835c2aaf4b023b272f5a [file] [log] [blame]
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2002-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.xs;
import java.lang.reflect.Array;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Vector;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl;
import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMap4Types;
import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMapImpl;
import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
import com.sun.org.apache.xerces.internal.util.SymbolHash;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration;
import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition;
import com.sun.org.apache.xerces.internal.xs.XSConstants;
import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration;
import com.sun.org.apache.xerces.internal.xs.XSModel;
import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition;
import com.sun.org.apache.xerces.internal.xs.XSNamedMap;
import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
import com.sun.org.apache.xerces.internal.xs.XSNamespaceItemList;
import com.sun.org.apache.xerces.internal.xs.XSNotationDeclaration;
import com.sun.org.apache.xerces.internal.xs.XSObject;
import com.sun.org.apache.xerces.internal.xs.XSObjectList;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
/**
* Implements XSModel: a read-only interface that represents an XML Schema,
* which could be components from different namespaces.
*
* @xerces.internal
*
* @author Sandy Gao, IBM
*
* @version $Id: XSModelImpl.java,v 1.7 2010-11-01 04:39:55 joehw Exp $
*/
public final class XSModelImpl extends AbstractList implements XSModel, XSNamespaceItemList {
// the max index / the max value of XSObject type
private static final short MAX_COMP_IDX = XSTypeDefinition.SIMPLE_TYPE;
private static final boolean[] GLOBAL_COMP = {false, // null
true, // attribute
true, // element
true, // type
false, // attribute use
true, // attribute group
true, // group
false, // model group
false, // particle
false, // wildcard
false, // idc
true, // notation
false, // annotation
false, // facet
false, // multi value facet
true, // complex type
true // simple type
};
// number of grammars/namespaces stored here
private final int fGrammarCount;
// all target namespaces
private final String[] fNamespaces;
// all schema grammar objects (for each namespace)
private final SchemaGrammar[] fGrammarList;
// a map from namespace to schema grammar
private final SymbolHash fGrammarMap;
// a map from element declaration to its substitution group
private final SymbolHash fSubGroupMap;
// store a certain kind of components from all namespaces
private final XSNamedMap[] fGlobalComponents;
// store a certain kind of components from one namespace
private final XSNamedMap[][] fNSComponents;
// a string list of all the target namespaces.
private final StringList fNamespacesList;
// store all annotations
private XSObjectList fAnnotations = null;
// whether there is any IDC in this XSModel
private final boolean fHasIDC;
/**
* Construct an XSModelImpl, by storing some grammars and grammars imported
* by them to this object.
*
* @param grammars the array of schema grammars
*/
public XSModelImpl(SchemaGrammar[] grammars) {
this(grammars, Constants.SCHEMA_VERSION_1_0);
}
public XSModelImpl(SchemaGrammar[] grammars, short s4sVersion) {
// copy namespaces/grammars from the array to our arrays
int len = grammars.length;
final int initialSize = Math.max(len+1, 5);
String[] namespaces = new String[initialSize];
SchemaGrammar[] grammarList = new SchemaGrammar[initialSize];
boolean hasS4S = false;
for (int i = 0; i < len; i++) {
final SchemaGrammar sg = grammars[i];
final String tns = sg.getTargetNamespace();
namespaces[i] = tns;
grammarList[i] = sg;
if (tns == SchemaSymbols.URI_SCHEMAFORSCHEMA) {
hasS4S = true;
}
}
// If a schema for the schema namespace isn't included, include it here.
if (!hasS4S) {
namespaces[len] = SchemaSymbols.URI_SCHEMAFORSCHEMA;
grammarList[len++] = SchemaGrammar.getS4SGrammar(s4sVersion);
}
SchemaGrammar sg1, sg2;
Vector gs;
int i, j, k;
// and recursively get all imported grammars, add them to our arrays
for (i = 0; i < len; i++) {
// get the grammar
sg1 = grammarList[i];
gs = sg1.getImportedGrammars();
// for each imported grammar
for (j = gs == null ? -1 : gs.size() - 1; j >= 0; j--) {
sg2 = (SchemaGrammar)gs.elementAt(j);
// check whether this grammar is already in the list
for (k = 0; k < len; k++) {
if (sg2 == grammarList[k]) {
break;
}
}
// if it's not, add it to the list
if (k == len) {
// ensure the capacity of the arrays
if (len == grammarList.length) {
String[] newSA = new String[len*2];
System.arraycopy(namespaces, 0, newSA, 0, len);
namespaces = newSA;
SchemaGrammar[] newGA = new SchemaGrammar[len*2];
System.arraycopy(grammarList, 0, newGA, 0, len);
grammarList = newGA;
}
namespaces[len] = sg2.getTargetNamespace();
grammarList[len] = sg2;
len++;
}
}
}
fNamespaces = namespaces;
fGrammarList = grammarList;
boolean hasIDC = false;
// establish the mapping from namespace to grammars
fGrammarMap = new SymbolHash(len*2);
for (i = 0; i < len; i++) {
fGrammarMap.put(null2EmptyString(fNamespaces[i]), fGrammarList[i]);
// update the idc field
if (fGrammarList[i].hasIDConstraints()) {
hasIDC = true;
}
}
fHasIDC = hasIDC;
fGrammarCount = len;
fGlobalComponents = new XSNamedMap[MAX_COMP_IDX+1];
fNSComponents = new XSNamedMap[len][MAX_COMP_IDX+1];
fNamespacesList = new StringListImpl(fNamespaces, fGrammarCount);
// build substitution groups
fSubGroupMap = buildSubGroups();
}
private SymbolHash buildSubGroups_Org() {
SubstitutionGroupHandler sgHandler = new SubstitutionGroupHandler(null);
for (int i = 0 ; i < fGrammarCount; i++) {
sgHandler.addSubstitutionGroup(fGrammarList[i].getSubstitutionGroups());
}
final XSNamedMap elements = getComponents(XSConstants.ELEMENT_DECLARATION);
final int len = elements.getLength();
final SymbolHash subGroupMap = new SymbolHash(len*2);
XSElementDecl head;
XSElementDeclaration[] subGroup;
for (int i = 0; i < len; i++) {
head = (XSElementDecl)elements.item(i);
subGroup = sgHandler.getSubstitutionGroup(head);
subGroupMap.put(head, subGroup.length > 0 ?
new XSObjectListImpl(subGroup, subGroup.length) : XSObjectListImpl.EMPTY_LIST);
}
return subGroupMap;
}
private SymbolHash buildSubGroups() {
SubstitutionGroupHandler sgHandler = new SubstitutionGroupHandler(null);
for (int i = 0 ; i < fGrammarCount; i++) {
sgHandler.addSubstitutionGroup(fGrammarList[i].getSubstitutionGroups());
}
final XSObjectListImpl elements = getGlobalElements();
final int len = elements.getLength();
final SymbolHash subGroupMap = new SymbolHash(len*2);
XSElementDecl head;
XSElementDeclaration[] subGroup;
for (int i = 0; i < len; i++) {
head = (XSElementDecl)elements.item(i);
subGroup = sgHandler.getSubstitutionGroup(head);
subGroupMap.put(head, subGroup.length > 0 ?
new XSObjectListImpl(subGroup, subGroup.length) : XSObjectListImpl.EMPTY_LIST);
}
return subGroupMap;
}
private XSObjectListImpl getGlobalElements() {
final SymbolHash[] tables = new SymbolHash[fGrammarCount];
int length = 0;
for (int i = 0; i < fGrammarCount; i++) {
tables[i] = fGrammarList[i].fAllGlobalElemDecls;
length += tables[i].getLength();
}
if (length == 0) {
return XSObjectListImpl.EMPTY_LIST;
}
final XSObject[] components = new XSObject[length];
int start = 0;
for (int i = 0; i < fGrammarCount; i++) {
tables[i].getValues(components, start);
start += tables[i].getLength();
}
return new XSObjectListImpl(components, length);
}
/**
* Convenience method. Returns a list of all namespaces that belong to
* this schema.
* @return A list of all namespaces that belong to this schema or
* <code>null</code> if all components don't have a targetNamespace.
*/
public StringList getNamespaces() {
return fNamespacesList;
}
/**
* A set of namespace schema information information items (of type
* <code>XSNamespaceItem</code>), one for each namespace name which
* appears as the target namespace of any schema component in the schema
* used for that assessment, and one for absent if any schema component
* in the schema had no target namespace. For more information see
* schema information.
*/
public XSNamespaceItemList getNamespaceItems() {
return this;
}
/**
* Returns a list of top-level components, i.e. element declarations,
* attribute declarations, etc.
* @param objectType The type of the declaration, i.e.
* <code>ELEMENT_DECLARATION</code>. Note that
* <code>XSTypeDefinition.SIMPLE_TYPE</code> and
* <code>XSTypeDefinition.COMPLEX_TYPE</code> can also be used as the
* <code>objectType</code> to retrieve only complex types or simple
* types, instead of all types.
* @return A list of top-level definitions of the specified type in
* <code>objectType</code> or an empty <code>XSNamedMap</code> if no
* such definitions exist.
*/
public synchronized XSNamedMap getComponents(short objectType) {
if (objectType <= 0 || objectType > MAX_COMP_IDX ||
!GLOBAL_COMP[objectType]) {
return XSNamedMapImpl.EMPTY_MAP;
}
SymbolHash[] tables = new SymbolHash[fGrammarCount];
// get all hashtables from all namespaces for this type of components
if (fGlobalComponents[objectType] == null) {
for (int i = 0; i < fGrammarCount; i++) {
switch (objectType) {
case XSConstants.TYPE_DEFINITION:
case XSTypeDefinition.COMPLEX_TYPE:
case XSTypeDefinition.SIMPLE_TYPE:
tables[i] = fGrammarList[i].fGlobalTypeDecls;
break;
case XSConstants.ATTRIBUTE_DECLARATION:
tables[i] = fGrammarList[i].fGlobalAttrDecls;
break;
case XSConstants.ELEMENT_DECLARATION:
tables[i] = fGrammarList[i].fGlobalElemDecls;
break;
case XSConstants.ATTRIBUTE_GROUP:
tables[i] = fGrammarList[i].fGlobalAttrGrpDecls;
break;
case XSConstants.MODEL_GROUP_DEFINITION:
tables[i] = fGrammarList[i].fGlobalGroupDecls;
break;
case XSConstants.NOTATION_DECLARATION:
tables[i] = fGrammarList[i].fGlobalNotationDecls;
break;
}
}
// for complex/simple types, create a special implementation,
// which take specific types out of the hash table
if (objectType == XSTypeDefinition.COMPLEX_TYPE ||
objectType == XSTypeDefinition.SIMPLE_TYPE) {
fGlobalComponents[objectType] = new XSNamedMap4Types(fNamespaces, tables, fGrammarCount, objectType);
}
else {
fGlobalComponents[objectType] = new XSNamedMapImpl(fNamespaces, tables, fGrammarCount);
}
}
return fGlobalComponents[objectType];
}
/**
* Convenience method. Returns a list of top-level component declarations
* that are defined within the specified namespace, i.e. element
* declarations, attribute declarations, etc.
* @param objectType The type of the declaration, i.e.
* <code>ELEMENT_DECLARATION</code>.
* @param namespace The namespace to which the declaration belongs or
* <code>null</code> (for components with no target namespace).
* @return A list of top-level definitions of the specified type in
* <code>objectType</code> and defined in the specified
* <code>namespace</code> or an empty <code>XSNamedMap</code>.
*/
public synchronized XSNamedMap getComponentsByNamespace(short objectType,
String namespace) {
if (objectType <= 0 || objectType > MAX_COMP_IDX ||
!GLOBAL_COMP[objectType]) {
return XSNamedMapImpl.EMPTY_MAP;
}
// try to find the grammar
int i = 0;
if (namespace != null) {
for (; i < fGrammarCount; ++i) {
if (namespace.equals(fNamespaces[i])) {
break;
}
}
}
else {
for (; i < fGrammarCount; ++i) {
if (fNamespaces[i] == null) {
break;
}
}
}
if (i == fGrammarCount) {
return XSNamedMapImpl.EMPTY_MAP;
}
// get the hashtable for this type of components
if (fNSComponents[i][objectType] == null) {
SymbolHash table = null;
switch (objectType) {
case XSConstants.TYPE_DEFINITION:
case XSTypeDefinition.COMPLEX_TYPE:
case XSTypeDefinition.SIMPLE_TYPE:
table = fGrammarList[i].fGlobalTypeDecls;
break;
case XSConstants.ATTRIBUTE_DECLARATION:
table = fGrammarList[i].fGlobalAttrDecls;
break;
case XSConstants.ELEMENT_DECLARATION:
table = fGrammarList[i].fGlobalElemDecls;
break;
case XSConstants.ATTRIBUTE_GROUP:
table = fGrammarList[i].fGlobalAttrGrpDecls;
break;
case XSConstants.MODEL_GROUP_DEFINITION:
table = fGrammarList[i].fGlobalGroupDecls;
break;
case XSConstants.NOTATION_DECLARATION:
table = fGrammarList[i].fGlobalNotationDecls;
break;
}
// for complex/simple types, create a special implementation,
// which take specific types out of the hash table
if (objectType == XSTypeDefinition.COMPLEX_TYPE ||
objectType == XSTypeDefinition.SIMPLE_TYPE) {
fNSComponents[i][objectType] = new XSNamedMap4Types(namespace, table, objectType);
}
else {
fNSComponents[i][objectType] = new XSNamedMapImpl(namespace, table);
}
}
return fNSComponents[i][objectType];
}
/**
* Convenience method. Returns a top-level simple or complex type
* definition.
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @return An <code>XSTypeDefinition</code> or null if such definition
* does not exist.
*/
public XSTypeDefinition getTypeDefinition(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSTypeDefinition)sg.fGlobalTypeDecls.get(name);
}
/**
* Convenience method. Returns a top-level simple or complex type
* definition.
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @param loc The schema location where the component was defined
* @return An <code>XSTypeDefinition</code> or null if such definition
* does not exist.
*/
public XSTypeDefinition getTypeDefinition(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalTypeDecl(name, loc);
}
/**
* Convenience method. Returns a top-level attribute declaration.
* @param name The name of the declaration.
* @param namespace The namespace of the definition, otherwise null.
* @return A top-level attribute declaration or null if such declaration
* does not exist.
*/
public XSAttributeDeclaration getAttributeDeclaration(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSAttributeDeclaration)sg.fGlobalAttrDecls.get(name);
}
/**
* Convenience method. Returns a top-level attribute declaration.
* @param name The name of the declaration.
* @param namespace The namespace of the definition, otherwise null.
* @param loc The schema location where the component was defined
* @return A top-level attribute declaration or null if such declaration
* does not exist.
*/
public XSAttributeDeclaration getAttributeDeclaration(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalAttributeDecl(name, loc);
}
/**
* Convenience method. Returns a top-level element declaration.
* @param name The name of the declaration.
* @param namespace The namespace of the definition, otherwise null.
* @return A top-level element declaration or null if such declaration
* does not exist.
*/
public XSElementDeclaration getElementDeclaration(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSElementDeclaration)sg.fGlobalElemDecls.get(name);
}
/**
* Convenience method. Returns a top-level element declaration.
* @param name The name of the declaration.
* @param namespace The namespace of the definition, otherwise null.
* @param loc The schema location where the component was defined
* @return A top-level element declaration or null if such declaration
* does not exist.
*/
public XSElementDeclaration getElementDeclaration(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalElementDecl(name, loc);
}
/**
* Convenience method. Returns a top-level attribute group definition.
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @return A top-level attribute group definition or null if such
* definition does not exist.
*/
public XSAttributeGroupDefinition getAttributeGroup(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSAttributeGroupDefinition)sg.fGlobalAttrGrpDecls.get(name);
}
/**
* Convenience method. Returns a top-level attribute group definition.
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @param loc The schema location where the component was defined
* @return A top-level attribute group definition or null if such
* definition does not exist.
*/
public XSAttributeGroupDefinition getAttributeGroup(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalAttributeGroupDecl(name, loc);
}
/**
* Convenience method. Returns a top-level model group definition.
*
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @return A top-level model group definition definition or null if such
* definition does not exist.
*/
public XSModelGroupDefinition getModelGroupDefinition(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSModelGroupDefinition)sg.fGlobalGroupDecls.get(name);
}
/**
* Convenience method. Returns a top-level model group definition.
*
* @param name The name of the definition.
* @param namespace The namespace of the definition, otherwise null.
* @param loc The schema location where the component was defined
* @return A top-level model group definition definition or null if such
* definition does not exist.
*/
public XSModelGroupDefinition getModelGroupDefinition(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalGroupDecl(name, loc);
}
/**
* @see org.apache.xerces.xs.XSModel#getNotationDeclaration(String, String)
*/
public XSNotationDeclaration getNotationDeclaration(String name,
String namespace) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return (XSNotationDeclaration)sg.fGlobalNotationDecls.get(name);
}
public XSNotationDeclaration getNotationDeclaration(String name,
String namespace,
String loc) {
SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
if (sg == null) {
return null;
}
return sg.getGlobalNotationDecl(name, loc);
}
/**
* [annotations]: a set of annotations if it exists, otherwise an empty
* <code>XSObjectList</code>.
*/
public synchronized XSObjectList getAnnotations() {
if (fAnnotations != null) {
return fAnnotations;
}
// do this in two passes to avoid inaccurate array size
int totalAnnotations = 0;
for (int i = 0; i < fGrammarCount; i++) {
totalAnnotations += fGrammarList[i].fNumAnnotations;
}
if (totalAnnotations == 0) {
fAnnotations = XSObjectListImpl.EMPTY_LIST;
return fAnnotations;
}
XSAnnotationImpl [] annotations = new XSAnnotationImpl [totalAnnotations];
int currPos = 0;
for (int i = 0; i < fGrammarCount; i++) {
SchemaGrammar currGrammar = fGrammarList[i];
if (currGrammar.fNumAnnotations > 0) {
System.arraycopy(currGrammar.fAnnotations, 0, annotations, currPos, currGrammar.fNumAnnotations);
currPos += currGrammar.fNumAnnotations;
}
}
fAnnotations = new XSObjectListImpl(annotations, annotations.length);
return fAnnotations;
}
private static final String null2EmptyString(String str) {
return str == null ? XMLSymbols.EMPTY_STRING : str;
}
/**
* REVISIT: to expose identity constraints from XSModel.
* For now, we only expose whether there are any IDCs.
* We also need to add these methods to the public
* XSModel interface.
*/
public boolean hasIDConstraints() {
return fHasIDC;
}
/**
* Convenience method. Returns a list containing the members of the
* substitution group for the given <code>XSElementDeclaration</code>
* or an empty <code>XSObjectList</code> if the substitution group
* contains no members.
* @param head The substitution group head.
* @return A list containing the members of the substitution group
* for the given <code>XSElementDeclaration</code> or an empty
* <code>XSObjectList</code> if the substitution group contains
* no members.
*/
public XSObjectList getSubstitutionGroup(XSElementDeclaration head) {
return (XSObjectList)fSubGroupMap.get(head);
}
//
// XSNamespaceItemList methods
//
/**
* The number of <code>XSNamespaceItem</code>s in the list. The range of
* valid child object indices is 0 to <code>length-1</code> inclusive.
*/
public int getLength() {
return fGrammarCount;
}
/**
* Returns the <code>index</code>th item in the collection or
* <code>null</code> if <code>index</code> is greater than or equal to
* the number of objects in the list. The index starts at 0.
* @param index index into the collection.
* @return The <code>XSNamespaceItem</code> at the <code>index</code>th
* position in the <code>XSNamespaceItemList</code>, or
* <code>null</code> if the index specified is not valid.
*/
public XSNamespaceItem item(int index) {
if (index < 0 || index >= fGrammarCount) {
return null;
}
return fGrammarList[index];
}
//
// java.util.List methods
//
public Object get(int index) {
if (index >= 0 && index < fGrammarCount) {
return fGrammarList[index];
}
throw new IndexOutOfBoundsException("Index: " + index);
}
public int size() {
return getLength();
}
public Iterator iterator() {
return listIterator0(0);
}
public ListIterator listIterator() {
return listIterator0(0);
}
public ListIterator listIterator(int index) {
if (index >= 0 && index < fGrammarCount) {
return listIterator0(index);
}
throw new IndexOutOfBoundsException("Index: " + index);
}
private ListIterator listIterator0(int index) {
return new XSNamespaceItemListIterator(index);
}
public Object[] toArray() {
Object[] a = new Object[fGrammarCount];
toArray0(a);
return a;
}
public Object[] toArray(Object[] a) {
if (a.length < fGrammarCount) {
Class arrayClass = a.getClass();
Class componentType = arrayClass.getComponentType();
a = (Object[]) Array.newInstance(componentType, fGrammarCount);
}
toArray0(a);
if (a.length > fGrammarCount) {
a[fGrammarCount] = null;
}
return a;
}
private void toArray0(Object[] a) {
if (fGrammarCount > 0) {
System.arraycopy(fGrammarList, 0, a, 0, fGrammarCount);
}
}
private final class XSNamespaceItemListIterator implements ListIterator {
private int index;
public XSNamespaceItemListIterator(int index) {
this.index = index;
}
public boolean hasNext() {
return (index < fGrammarCount);
}
public Object next() {
if (index < fGrammarCount) {
return fGrammarList[index++];
}
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return (index > 0);
}
public Object previous() {
if (index > 0) {
return fGrammarList[--index];
}
throw new NoSuchElementException();
}
public int nextIndex() {
return index;
}
public int previousIndex() {
return index - 1;
}
public void remove() {
throw new UnsupportedOperationException();
}
public void set(Object o) {
throw new UnsupportedOperationException();
}
public void add(Object o) {
throw new UnsupportedOperationException();
}
}
} // class XSModelImpl