FileDocCategorySizeDatePackage
XSModelImpl.javaAPI DocApache Xerces 3.0.120597Fri Sep 14 20:33:56 BST 2007org.apache.xerces.impl.xs

XSModelImpl

public class XSModelImpl extends Object implements org.apache.xerces.xs.XSModel
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 446734 2006-09-15 20:51:23Z mrglavas $

Fields Summary
private static final short
MAX_COMP_IDX
private static final boolean[]
GLOBAL_COMP
private int
fGrammarCount
private String[]
fNamespaces
private SchemaGrammar[]
fGrammarList
private org.apache.xerces.util.SymbolHash
fGrammarMap
private org.apache.xerces.util.SymbolHash
fSubGroupMap
private org.apache.xerces.xs.XSNamedMap[]
fGlobalComponents
private org.apache.xerces.xs.XSNamedMap[]
fNSComponents
private org.apache.xerces.impl.xs.util.XSObjectListImpl
fAnnotations
private boolean
fHasIDC
Constructors Summary
public XSModelImpl(SchemaGrammar[] grammars)
Construct an XSModelImpl, by storing some grammars and grammars imported by them to this object.

param
grammars the array of schema grammars

    
                                
       
        // copy namespaces/grammars from the array to our arrays
        int len = grammars.length;
        fNamespaces = new String[Math.max(len+1, 5)];
        fGrammarList = new SchemaGrammar[Math.max(len+1, 5)];
        boolean hasS4S = false;
        for (int i = 0; i < len; i++) {
            fNamespaces[i] = grammars[i].getTargetNamespace();
            fGrammarList[i] = grammars[i];
            if (fNamespaces[i] == SchemaSymbols.URI_SCHEMAFORSCHEMA)
                hasS4S = true;
        }
        // If a schema for the schema namespace isn't included, include it here.
        if (!hasS4S) {
            fNamespaces[len] = SchemaSymbols.URI_SCHEMAFORSCHEMA;
            fGrammarList[len++] = SchemaGrammar.SG_SchemaNS;
        }

        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 = fGrammarList[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 == fGrammarList[k])
                        break;
                }
                // if it's not, add it to the list
                if (k == len) {
                    // ensure the capacity of the arrays
                    if (len == fGrammarList.length) {
                        String[] newSA = new String[len*2];
                        System.arraycopy(fNamespaces, 0, newSA, 0, len);
                        fNamespaces = newSA;
                        SchemaGrammar[] newGA = new SchemaGrammar[len*2];
                        System.arraycopy(fGrammarList, 0, newGA, 0, len);
                        fGrammarList = newGA;
                    }
                    fNamespaces[len] = sg2.getTargetNamespace();
                    fGrammarList[len] = sg2;
                    len++;
                }
            }
        }

        // 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())
                fHasIDC = true;
        }
        
        fGrammarCount = len;
        fGlobalComponents = new XSNamedMap[MAX_COMP_IDX+1];
        fNSComponents = new XSNamedMap[len][MAX_COMP_IDX+1];
        
        // build substitution groups
        buildSubGroups();
    
Methods Summary
private voidbuildSubGroups()

        SubstitutionGroupHandler sgHandler = new SubstitutionGroupHandler(null);
        for (int i = 0 ; i < fGrammarCount; i++) {
            sgHandler.addSubstitutionGroup(fGrammarList[i].getSubstitutionGroups());
        }

        XSNamedMap elements = getComponents(XSConstants.ELEMENT_DECLARATION);
        int len = elements.getLength();
        fSubGroupMap = new SymbolHash(len*2);
        XSElementDecl head;
        XSElementDeclaration[] subGroup;
        for (int i = 0; i < len; i++) {
            head = (XSElementDecl)elements.item(i);
            subGroup = sgHandler.getSubstitutionGroup(head);
            fSubGroupMap.put(head, subGroup.length > 0 ? 
                    new XSObjectListImpl(subGroup, subGroup.length) : XSObjectListImpl.EMPTY_LIST);
        }
    
public synchronized org.apache.xerces.xs.XSObjectListgetAnnotations()
{annotations} A set of annotations.

        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;
        }
        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;
    
public org.apache.xerces.xs.XSAttributeDeclarationgetAttributeDeclaration(java.lang.String name, java.lang.String namespace)
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.

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSAttributeDeclaration)sg.fGlobalAttrDecls.get(name);
    
public org.apache.xerces.xs.XSAttributeGroupDefinitiongetAttributeGroup(java.lang.String name, java.lang.String namespace)
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.

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSAttributeGroupDefinition)sg.fGlobalAttrGrpDecls.get(name);
    
public synchronized org.apache.xerces.xs.XSNamedMapgetComponents(short objectType)
Returns a list of top-level components, i.e. element declarations, attribute declarations, etc.

param
objectType The type of the declaration, i.e. ELEMENT_DECLARATION. Note that XSTypeDefinition.SIMPLE_TYPE and XSTypeDefinition.COMPLEX_TYPE can also be used as the objectType to retrieve only complex types or simple types, instead of all types.
return
A list of top-level definitions of the specified type in objectType or an empty XSNamedMap if no such definitions exist.

        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];
    
public synchronized org.apache.xerces.xs.XSNamedMapgetComponentsByNamespace(short objectType, java.lang.String namespace)
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. ELEMENT_DECLARATION.
param
namespace The namespace to which the declaration belongs or null (for components with no target namespace).
return
A list of top-level definitions of the specified type in objectType and defined in the specified namespace or an empty XSNamedMap.

        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];
    
public org.apache.xerces.xs.XSElementDeclarationgetElementDeclaration(java.lang.String name, java.lang.String namespace)
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.

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSElementDeclaration)sg.fGlobalElemDecls.get(name);
    
public org.apache.xerces.xs.XSModelGroupDefinitiongetModelGroupDefinition(java.lang.String name, java.lang.String namespace)
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.

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSModelGroupDefinition)sg.fGlobalGroupDecls.get(name);
    
public org.apache.xerces.xs.XSNamespaceItemListgetNamespaceItems()


        // REVISIT: should the type of fGrammarList be NSItemListImpl?
        return new NSItemListImpl(fGrammarList, fGrammarCount);
    
public org.apache.xerces.xs.StringListgetNamespaces()
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 null if all components don't have a targetNamespace.

        // REVISIT: should the type of fNamespace be StringListImpl?
        return new StringListImpl(fNamespaces, fGrammarCount);
    
public org.apache.xerces.xs.XSNotationDeclarationgetNotationDeclaration(java.lang.String name, java.lang.String namespace)

see
org.apache.xerces.xs.XSModel#getNotationDeclaration(String, String)

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSNotationDeclaration)sg.fGlobalNotationDecls.get(name);
    
public org.apache.xerces.xs.XSObjectListgetSubstitutionGroup(org.apache.xerces.xs.XSElementDeclaration head)

        return (XSObjectList)fSubGroupMap.get(head);
    
public org.apache.xerces.xs.XSTypeDefinitiongetTypeDefinition(java.lang.String name, java.lang.String namespace)
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 XSTypeDefinition or null if such definition does not exist.

        SchemaGrammar sg = (SchemaGrammar)fGrammarMap.get(null2EmptyString(namespace));
        if (sg == null)
            return null;
        return (XSTypeDefinition)sg.fGlobalTypeDecls.get(name);
    
public booleanhasIDConstraints()
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.

        return fHasIDC;
    
private static final java.lang.Stringnull2EmptyString(java.lang.String str)

        return str == null ? XMLSymbols.EMPTY_STRING : str;