| /* Copyright 2004 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 org.apache.xmlbeans.impl.schema; |
| |
| import org.apache.xmlbeans.QNameSet; |
| import org.apache.xmlbeans.QNameSetBuilder; |
| import org.apache.xmlbeans.SchemaAnnotation; |
| import org.apache.xmlbeans.SchemaAttributeModel; |
| import org.apache.xmlbeans.SchemaComponent; |
| import org.apache.xmlbeans.SchemaField; |
| import org.apache.xmlbeans.SchemaGlobalAttribute; |
| import org.apache.xmlbeans.SchemaGlobalElement; |
| import org.apache.xmlbeans.SchemaLocalAttribute; |
| import org.apache.xmlbeans.SchemaLocalElement; |
| import org.apache.xmlbeans.SchemaParticle; |
| import org.apache.xmlbeans.SchemaProperty; |
| import org.apache.xmlbeans.SchemaStringEnumEntry; |
| import org.apache.xmlbeans.SchemaType; |
| import org.apache.xmlbeans.SchemaTypeElementSequencer; |
| import org.apache.xmlbeans.SchemaTypeLoader; |
| import org.apache.xmlbeans.SchemaTypeSystem; |
| import org.apache.xmlbeans.StringEnumAbstractBase; |
| import org.apache.xmlbeans.XmlAnySimpleType; |
| import org.apache.xmlbeans.XmlObject; |
| import org.apache.xmlbeans.InterfaceExtension; |
| import org.apache.xmlbeans.PrePostExtension; |
| import org.apache.xmlbeans.impl.common.QNameHelper; |
| import org.apache.xmlbeans.impl.values.*; |
| |
| import javax.xml.namespace.QName; |
| import java.lang.reflect.Constructor; |
| import java.math.BigInteger; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| public final class SchemaTypeImpl implements SchemaType, TypeStoreUserFactory |
| { |
| // global types have names |
| private QName _name; |
| |
| // annotation on the type |
| private SchemaAnnotation _annotation; |
| |
| // compilation support |
| private int _resolvePhase; |
| private static final int UNRESOLVED = 0; |
| private static final int RESOLVING_SGS = 1; // For document types only |
| private static final int RESOLVED_SGS = 2; // For document types only |
| private static final int RESOLVING = 3; |
| private static final int RESOLVED = 4; |
| private static final int JAVAIZING = 5; |
| private static final int JAVAIZED = 6; |
| |
| // anonymous type support |
| private SchemaType.Ref _outerSchemaTypeRef; |
| private volatile SchemaComponent.Ref _containerFieldRef; |
| private volatile SchemaField _containerField; |
| private volatile int _containerFieldCode; |
| private volatile int _containerFieldIndex; |
| private volatile QName[] _groupReferenceContext; |
| private SchemaType.Ref[] _anonymousTyperefs; |
| private boolean _isDocumentType; |
| private boolean _isAttributeType; |
| // private boolean _skippedAnonymousType; |
| |
| // compiletime java type support |
| private boolean _isCompiled; |
| private String _shortJavaName; |
| private String _fullJavaName; |
| private String _shortJavaImplName; |
| private String _fullJavaImplName; |
| private InterfaceExtension[] _interfaces; |
| private PrePostExtension _prepost; |
| |
| // runtime java type support: volatile because they're cached |
| private volatile Class _javaClass; |
| private volatile Class _javaEnumClass; |
| private volatile Class _javaImplClass; |
| private volatile Constructor _javaImplConstructor; |
| private volatile Constructor _javaImplConstructor2; |
| private volatile boolean _implNotAvailable; |
| private volatile Class _userTypeClass; |
| private volatile Class _userTypeHandlerClass; |
| |
| // user data objects not persisted |
| private volatile Object _userData; |
| |
| private final Object[] _ctrArgs = new Object[] { this }; |
| |
| // reflective support |
| private SchemaContainer _container; |
| private String _filename; |
| |
| // complex content support |
| private SchemaParticle _contentModel; |
| private volatile SchemaLocalElement[] _localElts; // lazily computed |
| private volatile Map _eltToIndexMap; // lazily computed |
| private volatile Map _attrToIndexMap; // lazily computed |
| private Map _propertyModelByElementName; |
| private Map _propertyModelByAttributeName; |
| private boolean _hasAllContent; |
| private boolean _orderSensitive; |
| private QNameSet _typedWildcardElements; |
| private QNameSet _typedWildcardAttributes; |
| private boolean _hasWildcardElements; |
| private boolean _hasWildcardAttributes; |
| // set of valid QNames that can be substituted for a property |
| private Set _validSubstitutions = Collections.EMPTY_SET; |
| |
| // simple content support |
| private int _complexTypeVariety; |
| private SchemaAttributeModel _attributeModel; |
| |
| // simple type support |
| private int _builtinTypeCode; |
| |
| private int _simpleTypeVariety; |
| private boolean _isSimpleType; |
| |
| private SchemaType.Ref _baseTyperef; // via restriction or extension |
| private int _baseDepth; // how many inheritance steps to AnyType |
| private int _derivationType; |
| |
| // user type support |
| private String _userTypeName; |
| private String _userTypeHandler; |
| |
| // for complex types with simple content |
| private SchemaType.Ref _contentBasedOnTyperef; |
| |
| // facets |
| private XmlValueRef[] _facetArray; |
| private boolean[] _fixedFacetArray; |
| |
| // fundamental facets |
| private int _ordered; |
| private boolean _isFinite; |
| private boolean _isBounded; |
| private boolean _isNumeric; |
| |
| private boolean _abs; |
| private boolean _finalExt; |
| private boolean _finalRest; |
| private boolean _finalList; |
| private boolean _finalUnion; |
| private boolean _blockExt; |
| private boolean _blockRest; |
| |
| // whitespace facet |
| private int _whiteSpaceRule; |
| |
| // regex patterns |
| private boolean _hasPatterns; // also takes into account base classes |
| private org.apache.xmlbeans.impl.regex.RegularExpression[] _patterns; |
| |
| // enumerated values |
| private XmlValueRef[] _enumerationValues; |
| private SchemaType.Ref _baseEnumTyperef; |
| private boolean _stringEnumEnsured; |
| private volatile Map _lookupStringEnum; |
| private volatile List _listOfStringEnum; |
| private volatile Map _lookupStringEnumEntry; |
| private SchemaStringEnumEntry[] _stringEnumEntries; |
| |
| // for lists only |
| private SchemaType.Ref _listItemTyperef; |
| |
| // for unions only |
| private boolean _isUnionOfLists; |
| private SchemaType.Ref[] _unionMemberTyperefs; |
| private int _anonymousUnionMemberOrdinal; |
| private volatile SchemaType[] _unionConstituentTypes; |
| private volatile SchemaType[] _unionSubTypes; |
| private volatile SchemaType _unionCommonBaseType; |
| |
| // for atomic types only |
| private SchemaType.Ref _primitiveTypeRef; |
| |
| // for decimal restrictions only |
| private int _decimalSize; |
| |
| // lazy loading support |
| private volatile boolean _unloaded; |
| |
| // for document types only - only valid during compilation |
| private QName _sg; |
| private List _sgMembers = new ArrayList(); |
| |
| public boolean isUnloaded() |
| { |
| return _unloaded; |
| } |
| |
| public void finishLoading() |
| { |
| _unloaded = false; |
| } |
| |
| |
| |
| SchemaTypeImpl(SchemaContainer container) |
| { |
| _container = container; |
| } |
| |
| SchemaTypeImpl(SchemaContainer container, boolean unloaded) |
| { |
| _container = container; |
| _unloaded = unloaded; |
| if (unloaded) |
| finishQuick(); |
| } |
| |
| public boolean isSGResolved() |
| { return _resolvePhase >= RESOLVED_SGS; } |
| |
| public boolean isSGResolving() |
| { return _resolvePhase >= RESOLVING_SGS; } |
| |
| public boolean isResolved() |
| { return _resolvePhase >= RESOLVED; } |
| |
| public boolean isResolving() |
| { return _resolvePhase == RESOLVING; } |
| |
| public boolean isUnjavaized() |
| { return _resolvePhase < JAVAIZED; } |
| |
| public boolean isJavaized() |
| { return _resolvePhase == JAVAIZED; } |
| |
| public void startResolvingSGs() |
| { |
| if (_resolvePhase != UNRESOLVED) |
| throw new IllegalStateException(); |
| _resolvePhase = RESOLVING_SGS; |
| } |
| |
| public void finishResolvingSGs() |
| { |
| if (_resolvePhase != RESOLVING_SGS) |
| throw new IllegalStateException(); |
| _resolvePhase = RESOLVED_SGS; |
| } |
| |
| public void startResolving() |
| { |
| if ( (_isDocumentType && _resolvePhase != RESOLVED_SGS) || |
| (!_isDocumentType && _resolvePhase != UNRESOLVED)) |
| throw new IllegalStateException(); |
| _resolvePhase = RESOLVING; |
| } |
| |
| public void finishResolving() |
| { |
| if (_resolvePhase != RESOLVING) |
| throw new IllegalStateException(); |
| _resolvePhase = RESOLVED; |
| } |
| |
| public void startJavaizing() |
| { |
| if (_resolvePhase != RESOLVED) |
| throw new IllegalStateException(); |
| _resolvePhase = JAVAIZING; |
| } |
| |
| public void finishJavaizing() |
| { |
| if (_resolvePhase != JAVAIZING) |
| throw new IllegalStateException(); |
| _resolvePhase = JAVAIZED; |
| } |
| |
| private void finishQuick() |
| { |
| _resolvePhase = JAVAIZED; |
| } |
| |
| private void assertUnresolved() |
| { |
| if (_resolvePhase != UNRESOLVED && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| private void assertSGResolving() |
| { |
| if (_resolvePhase != RESOLVING_SGS && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| private void assertSGResolved() |
| { |
| if (_resolvePhase != RESOLVED_SGS && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| private void assertResolving() |
| { |
| if (_resolvePhase != RESOLVING && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| private void assertResolved() |
| { |
| if (_resolvePhase != RESOLVED && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| private void assertJavaizing() |
| { |
| if (_resolvePhase != JAVAIZING && !_unloaded) |
| throw new IllegalStateException(); |
| } |
| |
| public QName getName() |
| { return _name; } |
| |
| public void setName(QName name) |
| { assertUnresolved(); _name = name; } |
| |
| public String getSourceName() |
| { |
| if (_filename != null) |
| return _filename; |
| if (getOuterType() != null) |
| return getOuterType().getSourceName(); |
| |
| SchemaField field = getContainerField(); |
| if (field != null) |
| { |
| if (field instanceof SchemaGlobalElement) |
| return ((SchemaGlobalElement)field).getSourceName(); |
| if (field instanceof SchemaGlobalAttribute) |
| return ((SchemaGlobalAttribute)field).getSourceName(); |
| } |
| return null; |
| } |
| |
| public void setFilename(String filename) |
| { assertUnresolved(); _filename = filename; } |
| |
| public int getComponentType() |
| { return SchemaComponent.TYPE; } |
| |
| public boolean isAnonymousType() |
| { return _name == null; } |
| |
| public boolean isDocumentType() |
| { return _isDocumentType; } |
| |
| public boolean isAttributeType() |
| { return _isAttributeType; } |
| |
| public QName getDocumentElementName() |
| { |
| if (_isDocumentType) |
| { |
| SchemaParticle sp = getContentModel(); |
| if (sp != null) |
| return sp.getName(); |
| } |
| |
| return null; |
| } |
| |
| public QName getAttributeTypeAttributeName() |
| { |
| if (_isAttributeType) |
| { |
| SchemaAttributeModel sam = getAttributeModel(); |
| if (sam != null) |
| { |
| SchemaLocalAttribute[] slaArray = sam.getAttributes(); |
| if (slaArray != null && slaArray.length > 0) |
| { |
| SchemaLocalAttribute sla = slaArray[0]; |
| return sla.getName(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public void setAnnotation(SchemaAnnotation ann) |
| { assertUnresolved(); _annotation = ann; } |
| |
| public SchemaAnnotation getAnnotation() |
| { return _annotation; } |
| |
| public void setDocumentType(boolean isDocument) |
| { assertUnresolved(); _isDocumentType = isDocument; } |
| |
| public void setAttributeType(boolean isAttribute) |
| { assertUnresolved(); _isAttributeType = isAttribute; } |
| |
| public int getContentType() |
| { return _complexTypeVariety; } |
| |
| public void setComplexTypeVariety(int complexTypeVariety) |
| { assertResolving(); _complexTypeVariety = complexTypeVariety; } |
| |
| public SchemaTypeElementSequencer getElementSequencer() |
| { |
| if (_complexTypeVariety == NOT_COMPLEX_TYPE) |
| return new SequencerImpl(null); |
| |
| return new SequencerImpl(new SchemaTypeVisitorImpl(_contentModel)); |
| } |
| |
| /** Set the abstract and final flags for a complex type */ |
| void setAbstractFinal( |
| boolean abs, boolean finalExt, boolean finalRest, boolean finalList, boolean finalUnion) |
| { |
| assertResolving(); |
| _abs = abs; |
| _finalExt = finalExt; _finalRest = finalRest; |
| _finalList = finalList; _finalUnion = finalUnion; |
| } |
| |
| /** Set the final flags for a simple type */ |
| void setSimpleFinal(boolean finalRest, boolean finalList, boolean finalUnion) |
| { |
| assertResolving(); _finalRest = finalRest; _finalList = finalList ; _finalUnion = finalUnion; |
| } |
| |
| void setBlock(boolean blockExt, boolean blockRest) |
| { |
| assertResolving(); _blockExt = blockExt ; _blockRest = blockRest; |
| } |
| |
| public boolean blockRestriction() |
| { return _blockRest; } |
| |
| public boolean blockExtension() |
| { return _blockExt; } |
| |
| public boolean isAbstract() |
| { return _abs; } |
| |
| public boolean finalExtension() |
| { return _finalExt; } |
| |
| public boolean finalRestriction() |
| { return _finalRest; } |
| |
| public boolean finalList() |
| { return _finalList; } |
| |
| public boolean finalUnion() |
| { return _finalUnion; } |
| |
| public synchronized SchemaField getContainerField() |
| { |
| if (_containerFieldCode != -1) |
| { |
| SchemaType outer = getOuterType(); |
| if (_containerFieldCode == 0) |
| _containerField = _containerFieldRef == null ? null : (SchemaField)_containerFieldRef.getComponent(); |
| else if (_containerFieldCode == 1) |
| _containerField = outer.getAttributeModel().getAttributes()[_containerFieldIndex]; |
| else |
| _containerField = ((SchemaTypeImpl)outer).getLocalElementByIndex(_containerFieldIndex); |
| _containerFieldCode = -1; |
| } |
| return _containerField; |
| } |
| |
| public void setContainerField(SchemaField field) |
| { |
| assertUnresolved(); |
| _containerField = field; |
| _containerFieldCode = -1; |
| } |
| |
| public void setContainerFieldRef(SchemaComponent.Ref ref) |
| { |
| assertUnresolved(); |
| _containerFieldRef = ref; |
| _containerFieldCode = 0; |
| } |
| |
| public void setContainerFieldIndex(short code, int index) |
| { |
| assertUnresolved(); |
| _containerFieldCode = code; |
| _containerFieldIndex = index; |
| } |
| |
| /* package */ void setGroupReferenceContext(QName[] groupNames) |
| { |
| assertUnresolved(); |
| _groupReferenceContext = groupNames; |
| } |
| |
| /* package */ QName[] getGroupReferenceContext() |
| { return _groupReferenceContext; } |
| |
| public SchemaType getOuterType() |
| { return _outerSchemaTypeRef == null ? null : _outerSchemaTypeRef.get(); } |
| |
| public void setOuterSchemaTypeRef(SchemaType.Ref typeref) |
| { assertUnresolved(); _outerSchemaTypeRef = typeref; } |
| |
| public boolean isCompiled() |
| { return _isCompiled; } |
| |
| public void setCompiled(boolean f) |
| { assertJavaizing(); _isCompiled = f; } |
| |
| public boolean isSkippedAnonymousType() |
| { |
| SchemaType outerType = getOuterType(); |
| return ((outerType == null) ? false : |
| (outerType.getBaseType() == this || |
| outerType.getContentBasedOnType() == this)); |
| } |
| |
| public String getShortJavaName() |
| { return _shortJavaName; } |
| |
| public void setShortJavaName(String name) |
| { |
| assertResolved(); |
| _shortJavaName = name; |
| SchemaType outer = _outerSchemaTypeRef.get(); |
| while (outer.getFullJavaName() == null) |
| outer = outer.getOuterType(); |
| |
| _fullJavaName = outer.getFullJavaName() + "$" + _shortJavaName; |
| } |
| |
| public String getFullJavaName() |
| { return _fullJavaName; } |
| |
| public void setFullJavaName(String name) |
| { |
| assertResolved(); |
| _fullJavaName = name; |
| int index = Math.max(_fullJavaName.lastIndexOf('$'), |
| _fullJavaName.lastIndexOf('.')) + 1; |
| _shortJavaName = _fullJavaName.substring(index); |
| } |
| |
| public void setShortJavaImplName(String name) |
| { |
| assertResolved(); |
| _shortJavaImplName = name; |
| SchemaType outer = _outerSchemaTypeRef.get(); |
| while (outer.getFullJavaImplName() == null) |
| outer = outer.getOuterType(); |
| |
| _fullJavaImplName = outer.getFullJavaImplName() + "$" + _shortJavaImplName; |
| } |
| |
| public void setFullJavaImplName(String name) |
| { |
| assertResolved(); |
| _fullJavaImplName = name; |
| int index = Math.max(_fullJavaImplName.lastIndexOf('$'), |
| _fullJavaImplName.lastIndexOf('.')) + 1; |
| _shortJavaImplName = _fullJavaImplName.substring(index); |
| } |
| |
| public String getFullJavaImplName() { return _fullJavaImplName;} |
| public String getShortJavaImplName() { return _shortJavaImplName;} |
| |
| public String getUserTypeName() |
| { |
| return _userTypeName; |
| } |
| |
| public void setUserTypeName(String userTypeName) |
| { |
| _userTypeName = userTypeName; |
| } |
| |
| public String getUserTypeHandlerName() |
| { |
| return _userTypeHandler; |
| } |
| |
| public void setUserTypeHandlerName(String typeHandler) |
| { |
| _userTypeHandler = typeHandler; |
| } |
| |
| public void setInterfaceExtensions(InterfaceExtension[] interfaces) |
| { |
| assertResolved(); |
| _interfaces = interfaces; |
| } |
| |
| public InterfaceExtension[] getInterfaceExtensions() |
| { |
| return _interfaces; |
| } |
| |
| public void setPrePostExtension(PrePostExtension prepost) |
| { |
| assertResolved(); |
| _prepost = prepost; |
| } |
| |
| public PrePostExtension getPrePostExtension() |
| { |
| return _prepost; |
| } |
| |
| public Object getUserData() |
| { return _userData; } |
| |
| public void setUserData(Object data) |
| { _userData = data; } |
| |
| /* Only used for asserts */ |
| SchemaContainer getContainer() |
| { return _container; } |
| |
| void setContainer(SchemaContainer container) |
| { _container = container; } |
| |
| public SchemaTypeSystem getTypeSystem() |
| { return _container.getTypeSystem(); } |
| |
| public SchemaParticle getContentModel() |
| { return _contentModel; } |
| |
| private static void buildEltList(List eltList, SchemaParticle contentModel) |
| { |
| if (contentModel == null) |
| return; |
| |
| switch (contentModel.getParticleType()) |
| { |
| case SchemaParticle.ELEMENT: |
| eltList.add(contentModel); |
| return; |
| case SchemaParticle.ALL: |
| case SchemaParticle.CHOICE: |
| case SchemaParticle.SEQUENCE: |
| for (int i = 0; i < contentModel.countOfParticleChild(); i++) |
| buildEltList(eltList, contentModel.getParticleChild(i)); |
| return; |
| default: |
| return; |
| } |
| } |
| |
| private void buildLocalElts() |
| { |
| List eltList = new ArrayList(); |
| buildEltList(eltList, _contentModel); |
| _localElts = (SchemaLocalElement[])eltList.toArray(new SchemaLocalElement[eltList.size()]); |
| } |
| |
| public SchemaLocalElement getLocalElementByIndex(int i) |
| { |
| SchemaLocalElement[] elts = _localElts; |
| if (elts == null) |
| { |
| buildLocalElts(); |
| elts = _localElts; |
| } |
| return elts[i]; |
| } |
| |
| public int getIndexForLocalElement(SchemaLocalElement elt) |
| { |
| Map localEltMap = _eltToIndexMap; |
| if (localEltMap == null) |
| { |
| if (_localElts == null) |
| buildLocalElts(); |
| localEltMap = new HashMap(); |
| for (int i = 0; i < _localElts.length; i++) |
| { |
| localEltMap.put(_localElts[i], new Integer(i)); |
| } |
| _eltToIndexMap = localEltMap; |
| } |
| return ((Integer)localEltMap.get(elt)).intValue(); |
| } |
| |
| public int getIndexForLocalAttribute(SchemaLocalAttribute attr) |
| { |
| Map localAttrMap = _attrToIndexMap; |
| if (localAttrMap == null) |
| { |
| localAttrMap = new HashMap(); |
| SchemaLocalAttribute[] attrs = this._attributeModel.getAttributes(); |
| for (int i = 0; i < attrs.length; i++) |
| { |
| localAttrMap.put(attrs[i], new Integer(i)); |
| } |
| _attrToIndexMap = localAttrMap; |
| } |
| return ((Integer)localAttrMap.get(attr)).intValue(); |
| } |
| |
| public SchemaAttributeModel getAttributeModel() |
| { return _attributeModel; } |
| |
| public SchemaProperty[] getProperties() |
| { |
| if (_propertyModelByElementName == null) |
| return getAttributeProperties(); |
| |
| if (_propertyModelByAttributeName == null) |
| return getElementProperties(); |
| |
| List list = new ArrayList(); |
| list.addAll(_propertyModelByElementName.values()); |
| list.addAll(_propertyModelByAttributeName.values()); |
| return (SchemaProperty[])list.toArray(new SchemaProperty[list.size()]); |
| } |
| |
| private static final SchemaProperty[] NO_PROPERTIES = new SchemaProperty[0]; |
| |
| public SchemaProperty[] getDerivedProperties() |
| { |
| SchemaType baseType = getBaseType(); |
| if (baseType == null) |
| return getProperties(); |
| |
| List results = new ArrayList(); |
| |
| if (_propertyModelByElementName != null) |
| results.addAll(_propertyModelByElementName.values()); |
| |
| if (_propertyModelByAttributeName != null) |
| results.addAll(_propertyModelByAttributeName.values()); |
| |
| for (Iterator it = results.iterator() ; it.hasNext() ; ) |
| { |
| SchemaProperty prop = (SchemaProperty)it.next(); |
| SchemaProperty baseProp = prop.isAttribute() ? |
| baseType.getAttributeProperty(prop.getName()) : |
| baseType.getElementProperty(prop.getName()); |
| |
| |
| // Remove the derived property from the results if it is |
| // A) present in the base type and |
| // B) all the details are the same (cardinality, nillability, default) |
| |
| if (baseProp != null) |
| { |
| if ( eq(prop.getMinOccurs(), baseProp.getMinOccurs()) && |
| eq(prop.getMaxOccurs(), baseProp.getMaxOccurs()) && |
| prop.hasNillable() == baseProp.hasNillable() && |
| eq(prop.getDefaultText(), baseProp.getDefaultText())) |
| { |
| it.remove(); |
| } |
| |
| } |
| |
| } |
| |
| return (SchemaProperty[])results.toArray(new SchemaProperty[results.size()]); |
| } |
| |
| private static boolean eq(BigInteger a, BigInteger b) |
| { |
| if (a == null && b == null) |
| return true; |
| if (a== null || b == null) |
| return false; |
| return a.equals(b); |
| } |
| |
| private static boolean eq(String a, String b) |
| { |
| if (a == null && b == null) |
| return true; |
| if (a== null || b == null) |
| return false; |
| return a.equals(b); |
| } |
| |
| public SchemaProperty[] getElementProperties() |
| { |
| if (_propertyModelByElementName == null) |
| return NO_PROPERTIES; |
| |
| return (SchemaProperty[]) |
| _propertyModelByElementName.values().toArray(new SchemaProperty[_propertyModelByElementName.size()]); |
| } |
| |
| public SchemaProperty[] getAttributeProperties() |
| { |
| if (_propertyModelByAttributeName == null) |
| return NO_PROPERTIES; |
| |
| return (SchemaProperty[]) |
| _propertyModelByAttributeName.values().toArray(new SchemaProperty[_propertyModelByAttributeName.size()]); |
| } |
| |
| public SchemaProperty getElementProperty(QName eltName) |
| { return _propertyModelByElementName == null ? null : (SchemaProperty)_propertyModelByElementName.get(eltName); } |
| |
| public SchemaProperty getAttributeProperty(QName attrName) |
| { return _propertyModelByAttributeName == null ? null : (SchemaProperty)_propertyModelByAttributeName.get(attrName); } |
| |
| public boolean hasAllContent() |
| { return _hasAllContent; } |
| |
| public boolean isOrderSensitive() |
| { return _orderSensitive; } |
| |
| public void setOrderSensitive(boolean sensitive) |
| { assertJavaizing(); _orderSensitive = sensitive; } |
| |
| public void setContentModel( |
| SchemaParticle contentModel, |
| SchemaAttributeModel attrModel, |
| Map propertyModelByElementName, |
| Map propertyModelByAttributeName, |
| boolean isAll) |
| { |
| assertResolving(); |
| _contentModel = contentModel; |
| _attributeModel = attrModel; |
| _propertyModelByElementName = propertyModelByElementName; |
| _propertyModelByAttributeName = propertyModelByAttributeName; |
| _hasAllContent = isAll; |
| |
| |
| // Add entries for each element property for substitution group members |
| if (_propertyModelByElementName != null) |
| { |
| _validSubstitutions = new LinkedHashSet(); |
| Collection eltProps = _propertyModelByElementName.values(); |
| for (Iterator it = eltProps.iterator() ; it.hasNext() ; ) |
| { |
| SchemaProperty prop = (SchemaProperty)it.next(); |
| QName[] names = prop.acceptedNames(); |
| for (int i = 0 ; i < names.length ; i++) |
| { |
| if (! _propertyModelByElementName.containsKey(names[i])) |
| _validSubstitutions.add(names[i]); |
| } |
| } |
| } |
| } |
| |
| private boolean containsElements() |
| { |
| return getContentType() == ELEMENT_CONTENT || |
| getContentType() == MIXED_CONTENT; |
| } |
| |
| public boolean hasAttributeWildcards() |
| { |
| return _hasWildcardAttributes; |
| } |
| |
| public boolean hasElementWildcards() |
| { |
| return _hasWildcardElements; |
| } |
| |
| public boolean isValidSubstitution(QName name) |
| { |
| return _validSubstitutions.contains(name); |
| } |
| |
| public SchemaType getElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader) |
| { |
| if (isSimpleType() || !containsElements() || isNoType()) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| |
| SchemaType type = null; |
| SchemaProperty prop = (SchemaProperty)_propertyModelByElementName.get(eltName); |
| if (prop != null) |
| { |
| type = prop.getType(); |
| } |
| else |
| { |
| if (wildcardTypeLoader == null) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| |
| if (_typedWildcardElements.contains(eltName) || |
| _validSubstitutions.contains(eltName)) |
| { |
| SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); |
| if (elt == null) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| // According to http://www.w3.org/TR/xmlschema-1/#key-lva, |
| // the line above should return ST_ANY_TYPE. |
| type = elt.getType(); |
| } |
| else |
| { |
| // Substitution groups |
| // Actually, better not enable this yet |
| /*SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); |
| SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup(); |
| while (sghead != null) |
| { |
| prop = (SchemaProperty)_propertyModelByElementName.get(sghead.getName()); |
| if (prop != null) |
| { |
| type = elt.getType(); |
| break; |
| } |
| sghead = sghead.substitutionGroup(); |
| } |
| */ |
| if (type == null) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| } |
| |
| if (xsiType != null && wildcardTypeLoader != null) |
| { |
| SchemaType itype = wildcardTypeLoader.findType(xsiType); |
| |
| // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the |
| // xsiType was not derived from 'type', but this results in a |
| // ClassCastException. Instead we ignore xsi:type if it's not |
| // found or a derived type. |
| if (itype != null && type.isAssignableFrom(itype)) { |
| return itype; |
| } |
| } |
| |
| return type; |
| } |
| |
| public SchemaType getAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader) |
| { |
| if (isSimpleType() || isNoType()) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| |
| if (isURType()) |
| return BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; |
| |
| SchemaProperty prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName); |
| if (prop != null) |
| return prop.getType(); |
| |
| if (!_typedWildcardAttributes.contains(attrName) || wildcardTypeLoader == null) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| // For symmetry with the element case (as well as with URType), perhaps |
| // the above line should be returning ST_ANY_SIMPLE |
| |
| SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName); |
| if (attr == null) |
| return BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| return attr.getType(); |
| } |
| |
| /* These two methods, createElementType and getElementType have to stay |
| * synchronized, because they create an XmlObject and return the type |
| * for that object, respectively. But since they do slightly different |
| * things, they can't be refactored to share code, so exercise caution |
| */ |
| public XmlObject createElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader) |
| { |
| SchemaType type = null; |
| SchemaProperty prop = null; |
| if (isSimpleType() || !containsElements() || isNoType()) |
| { |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| else |
| { |
| prop = (SchemaProperty)_propertyModelByElementName.get(eltName); |
| if (prop != null) |
| { |
| type = prop.getType(); |
| } |
| else if (_typedWildcardElements.contains(eltName) || |
| _validSubstitutions.contains(eltName)) |
| { |
| SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); |
| if (elt != null) |
| { |
| type = elt.getType(); |
| SchemaType docType = wildcardTypeLoader.findDocumentType(eltName); |
| if (docType != null) |
| prop = docType.getElementProperty(eltName); |
| } |
| else |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| else |
| { |
| // Check if the requested element isn't by any chance part of a |
| // substitution group headed by one of the declared elements |
| // Better not enable this yet |
| /* |
| SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); |
| SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup(); |
| while (sghead != null) |
| { |
| if (_propertyModelByElementName.containsKey(sghead.getName())) |
| { |
| type = elt.getType(); |
| SchemaType docType = wildcardTypeLoader.findDocumentType(elt.getName()); |
| if (docType != null) |
| prop = docType.getElementProperty(elt.getName()); |
| break; |
| } |
| sghead = sghead.substitutionGroup(); |
| } |
| */ |
| if (type == null) |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| |
| if (xsiType != null) |
| { |
| SchemaType itype = wildcardTypeLoader.findType(xsiType); |
| |
| // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the |
| // xsiType was not derived from 'type', but this results in a |
| // ClassCastException. Instead we ignore xsi:type if it's not |
| // found or a derived type. |
| if (itype != null && type.isAssignableFrom(itype)) { |
| type = itype; |
| } |
| } |
| } |
| |
| if (type != null) |
| return ((SchemaTypeImpl)type).createUnattachedNode(prop); |
| return null; |
| } |
| |
| public XmlObject createAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader) |
| { |
| SchemaTypeImpl type = null; |
| SchemaProperty prop = null; |
| if (isSimpleType() || isNoType()) |
| { |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| else if (isURType()) |
| { |
| type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; |
| } |
| else |
| { |
| prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName); |
| if (prop != null) |
| { |
| type = (SchemaTypeImpl)prop.getType(); |
| } |
| else if (!_typedWildcardAttributes.contains(attrName)) |
| { |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| else |
| { |
| SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName); |
| if (attr != null) |
| type = (SchemaTypeImpl)attr.getType(); |
| else |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } |
| } |
| |
| if (type != null) |
| return type.createUnattachedNode(prop); |
| |
| return null; |
| } |
| |
| public void setWildcardSummary(QNameSet elementSet, boolean haswcElt, QNameSet attributeSet, boolean haswcAtt) |
| { |
| assertResolving(); _typedWildcardElements = elementSet; _hasWildcardElements = haswcElt; _typedWildcardAttributes = attributeSet; _hasWildcardAttributes = haswcAtt; |
| } |
| |
| public SchemaType[] getAnonymousTypes() |
| { |
| SchemaType[] result = new SchemaType[_anonymousTyperefs.length]; |
| for (int i = 0; i < result.length; i++) |
| result[i] = _anonymousTyperefs[i].get(); |
| return result; |
| } |
| |
| public void setAnonymousTypeRefs(SchemaType.Ref[] anonymousTyperefs) |
| { |
| _anonymousTyperefs = anonymousTyperefs; |
| } |
| |
| |
| private static SchemaType[] staCopy(SchemaType[] a) |
| { |
| if (a == null) |
| return null; |
| |
| SchemaType[] result = new SchemaType[a.length]; |
| System.arraycopy(a, 0, result, 0, a.length); |
| return result; |
| } |
| |
| private static boolean[] boaCopy(boolean[] a) |
| { |
| if (a == null) |
| return null; |
| |
| boolean[] result = new boolean[a.length]; |
| System.arraycopy(a, 0, result, 0, a.length); |
| return result; |
| } |
| |
| |
| |
| public void setSimpleTypeVariety(int variety) |
| { assertResolving(); _simpleTypeVariety = variety; } |
| |
| public int getSimpleVariety() |
| { return _simpleTypeVariety; } |
| |
| public boolean isURType() |
| { return _builtinTypeCode == BTC_ANY_TYPE || _builtinTypeCode == BTC_ANY_SIMPLE; } |
| |
| public boolean isNoType() |
| { return this == BuiltinSchemaTypeSystem.ST_NO_TYPE; } |
| |
| public boolean isSimpleType() |
| { return _isSimpleType; } |
| |
| public void setSimpleType(boolean f) |
| { assertUnresolved(); _isSimpleType = f; } |
| |
| public boolean isUnionOfLists() |
| { return _isUnionOfLists; } |
| |
| public void setUnionOfLists(boolean f) |
| { assertResolving(); _isUnionOfLists = f; } |
| |
| public SchemaType getPrimitiveType() |
| { return _primitiveTypeRef == null ? null : _primitiveTypeRef.get(); } |
| |
| public void setPrimitiveTypeRef(SchemaType.Ref typeref) |
| { assertResolving(); _primitiveTypeRef = typeref; } |
| |
| public int getDecimalSize() |
| { return _decimalSize; } |
| |
| public void setDecimalSize(int bits) |
| { assertResolving(); _decimalSize = bits; } |
| |
| public SchemaType getBaseType() |
| { return _baseTyperef == null ? null : _baseTyperef.get(); } |
| |
| public void setBaseTypeRef(SchemaType.Ref typeref) |
| { assertResolving(); _baseTyperef = typeref; } |
| |
| public int getBaseDepth() |
| { return _baseDepth; } |
| |
| public void setBaseDepth(int depth) |
| { assertResolving(); _baseDepth = depth; } |
| |
| public SchemaType getContentBasedOnType() |
| { return _contentBasedOnTyperef == null ? null : _contentBasedOnTyperef.get(); } |
| |
| public void setContentBasedOnTypeRef(SchemaType.Ref typeref) |
| { assertResolving(); _contentBasedOnTyperef = typeref; } |
| |
| public int getDerivationType() |
| { return _derivationType; } |
| |
| public void setDerivationType(int type) |
| { assertResolving(); _derivationType = type; } |
| |
| public SchemaType getListItemType() |
| { return _listItemTyperef == null ? null : _listItemTyperef.get(); } |
| |
| public void setListItemTypeRef(SchemaType.Ref typeref) |
| { assertResolving(); _listItemTyperef = typeref; } |
| |
| public SchemaType[] getUnionMemberTypes() |
| { |
| SchemaType[] result = new SchemaType[_unionMemberTyperefs ==null ? 0 : _unionMemberTyperefs.length]; |
| for (int i = 0; i < result.length; i++) |
| result[i] = _unionMemberTyperefs[i].get(); |
| return result; |
| } |
| |
| public void setUnionMemberTypeRefs(SchemaType.Ref[] typerefs) |
| { assertResolving(); _unionMemberTyperefs = typerefs; } |
| |
| public int getAnonymousUnionMemberOrdinal() |
| { return _anonymousUnionMemberOrdinal; } |
| |
| public void setAnonymousUnionMemberOrdinal(int i) |
| { assertUnresolved(); _anonymousUnionMemberOrdinal = i; } |
| |
| public synchronized SchemaType[] getUnionConstituentTypes() |
| { |
| if (_unionCommonBaseType == null) |
| computeFlatUnionModel(); |
| return staCopy(_unionConstituentTypes); |
| } |
| |
| private void setUnionConstituentTypes(SchemaType[] types) |
| { _unionConstituentTypes = types; } |
| |
| public synchronized SchemaType[] getUnionSubTypes() |
| { |
| if (_unionCommonBaseType == null) |
| computeFlatUnionModel(); |
| return staCopy(_unionSubTypes); |
| } |
| |
| private void setUnionSubTypes(SchemaType[] types) |
| { _unionSubTypes = types; } |
| |
| public synchronized SchemaType getUnionCommonBaseType() |
| { |
| if (_unionCommonBaseType == null) |
| computeFlatUnionModel(); |
| return _unionCommonBaseType; |
| } |
| |
| private void setUnionCommonBaseType(SchemaType type) |
| { _unionCommonBaseType = type; } |
| |
| private void computeFlatUnionModel() |
| { |
| if (getSimpleVariety() != SchemaType.UNION) |
| throw new IllegalStateException("Operation is only supported on union types"); |
| Set constituentMemberTypes = new LinkedHashSet(); |
| Set allSubTypes = new LinkedHashSet(); |
| SchemaType commonBaseType = null; |
| |
| allSubTypes.add(this); |
| |
| for (int i = 0; i < _unionMemberTyperefs.length; i++) |
| { |
| SchemaTypeImpl mImpl = (SchemaTypeImpl)_unionMemberTyperefs[i].get(); |
| |
| switch (mImpl.getSimpleVariety()) |
| { |
| case SchemaType.LIST: |
| constituentMemberTypes.add(mImpl); |
| allSubTypes.add(mImpl); |
| commonBaseType = mImpl.getCommonBaseType(commonBaseType); |
| break; |
| case SchemaType.UNION: |
| constituentMemberTypes.addAll(Arrays.asList(mImpl.getUnionConstituentTypes())); |
| allSubTypes.addAll(Arrays.asList(mImpl.getUnionSubTypes())); |
| SchemaType otherCommonBaseType = mImpl.getUnionCommonBaseType(); |
| if (otherCommonBaseType != null) |
| commonBaseType = otherCommonBaseType.getCommonBaseType(commonBaseType); |
| break; |
| case SchemaType.ATOMIC: |
| constituentMemberTypes.add(mImpl); |
| allSubTypes.add(mImpl); |
| commonBaseType = mImpl.getCommonBaseType(commonBaseType); |
| break; |
| default: |
| assert(false); |
| } |
| } |
| |
| setUnionConstituentTypes((SchemaType[]) |
| constituentMemberTypes.toArray(StscState.EMPTY_ST_ARRAY)); |
| setUnionSubTypes((SchemaType[]) |
| allSubTypes.toArray(StscState.EMPTY_ST_ARRAY)); |
| setUnionCommonBaseType(commonBaseType); |
| } |
| |
| public QName getSubstitutionGroup() |
| { return _sg; } |
| |
| public void setSubstitutionGroup(QName sg) |
| { assertSGResolving(); _sg = sg; } |
| |
| public void addSubstitutionGroupMember(QName member) |
| { assertSGResolved(); _sgMembers.add(member); } |
| |
| public QName[] getSubstitutionGroupMembers() |
| { |
| QName[] result = new QName[_sgMembers.size()]; |
| return (QName[])_sgMembers.toArray(result); |
| } |
| |
| public int getWhiteSpaceRule() |
| { return _whiteSpaceRule; } |
| |
| public void setWhiteSpaceRule(int ws) |
| { assertResolving(); _whiteSpaceRule = ws; } |
| |
| public XmlAnySimpleType getFacet(int facetCode) |
| { |
| if (_facetArray == null) |
| return null; |
| XmlValueRef ref = _facetArray[facetCode]; |
| if (ref == null) |
| return null; |
| return ref.get(); |
| } |
| |
| public boolean isFacetFixed(int facetCode) |
| { |
| return _fixedFacetArray[facetCode]; |
| } |
| |
| public XmlAnySimpleType[] getBasicFacets() |
| { |
| XmlAnySimpleType[] result = new XmlAnySimpleType[SchemaType.LAST_FACET + 1]; |
| for (int i = 0; i <= SchemaType.LAST_FACET; i++) |
| { |
| result[i] = getFacet(i); |
| } |
| return result; |
| } |
| |
| public boolean[] getFixedFacets() |
| { |
| return boaCopy(_fixedFacetArray); |
| } |
| |
| public void setBasicFacets(XmlValueRef[] values, boolean[] fixed) |
| { |
| assertResolving(); |
| _facetArray = values; |
| _fixedFacetArray = fixed; |
| } |
| |
| public int ordered() |
| { return _ordered; } |
| |
| public void setOrdered(int ordering) |
| { assertResolving(); _ordered = ordering; } |
| |
| public boolean isBounded() |
| { return _isBounded; } |
| |
| public void setBounded(boolean f) |
| { assertResolving(); _isBounded = f; } |
| |
| public boolean isFinite() |
| { return _isFinite; } |
| |
| public void setFinite(boolean f) |
| { assertResolving(); _isFinite = f; } |
| |
| public boolean isNumeric() |
| { return _isNumeric; } |
| |
| public void setNumeric(boolean f) |
| { assertResolving(); _isNumeric = f; } |
| |
| |
| public boolean hasPatternFacet() |
| { return _hasPatterns; } |
| |
| public void setPatternFacet(boolean hasPatterns) |
| { assertResolving(); _hasPatterns = hasPatterns; } |
| |
| public boolean matchPatternFacet(String s) |
| { |
| if (!_hasPatterns) |
| return true; |
| |
| if (_patterns != null && _patterns.length > 0) |
| { |
| int i; |
| for (i = 0; i < _patterns.length; i++) |
| { |
| if (_patterns[i].matches(s)) |
| break; |
| } |
| if (i >= _patterns.length) |
| return false; |
| } |
| |
| return getBaseType().matchPatternFacet(s); |
| } |
| |
| public String[] getPatterns() |
| { |
| if (_patterns == null) |
| return new String[0]; |
| String[] patterns = new String[_patterns.length]; |
| for (int i=0; i< _patterns.length; i++) |
| patterns[i] = _patterns[i].getPattern(); |
| return patterns; |
| } |
| |
| public org.apache.xmlbeans.impl.regex.RegularExpression[] getPatternExpressions() |
| { |
| if (_patterns == null) |
| return new org.apache.xmlbeans.impl.regex.RegularExpression[0]; |
| org.apache.xmlbeans.impl.regex.RegularExpression[] result = new org.apache.xmlbeans.impl.regex.RegularExpression[_patterns.length]; |
| System.arraycopy(_patterns, 0, result, 0, _patterns.length); |
| return result; |
| } |
| |
| public void setPatterns(org.apache.xmlbeans.impl.regex.RegularExpression[] list) |
| { assertResolving(); _patterns = list; } |
| |
| public XmlAnySimpleType[] getEnumerationValues() |
| { |
| if (_enumerationValues == null) |
| return null; |
| XmlAnySimpleType[] result = new XmlAnySimpleType[_enumerationValues.length]; |
| for (int i = 0; i < result.length; i++) |
| { |
| XmlValueRef ref = _enumerationValues[i]; |
| result[i] = (ref == null ? null : ref.get()); |
| |
| } |
| return result; |
| } |
| |
| public void setEnumerationValues(XmlValueRef[] a) |
| { assertResolving(); _enumerationValues = a; } |
| |
| public StringEnumAbstractBase enumForString(String s) |
| { |
| ensureStringEnumInfo(); |
| if (_lookupStringEnum == null) |
| return null; |
| return (StringEnumAbstractBase)_lookupStringEnum.get(s); |
| } |
| |
| public StringEnumAbstractBase enumForInt(int i) |
| { |
| ensureStringEnumInfo(); |
| if (_listOfStringEnum == null || i < 0 || i >= _listOfStringEnum.size()) |
| return null; |
| return (StringEnumAbstractBase)_listOfStringEnum.get(i); |
| } |
| |
| public SchemaStringEnumEntry enumEntryForString(String s) |
| { |
| ensureStringEnumInfo(); |
| if (_lookupStringEnumEntry == null) |
| return null; |
| return (SchemaStringEnumEntry)_lookupStringEnumEntry.get(s); |
| } |
| |
| public SchemaType getBaseEnumType() |
| { |
| return _baseEnumTyperef == null ? null : _baseEnumTyperef.get(); |
| } |
| |
| public void setBaseEnumTypeRef(SchemaType.Ref baseEnumTyperef) |
| { |
| _baseEnumTyperef = baseEnumTyperef; |
| } |
| |
| public SchemaStringEnumEntry[] getStringEnumEntries() |
| { |
| if (_stringEnumEntries == null) |
| return null; |
| SchemaStringEnumEntry[] result = new SchemaStringEnumEntry[_stringEnumEntries.length]; |
| System.arraycopy(_stringEnumEntries, 0, result, 0, result.length); |
| return result; |
| } |
| |
| public void setStringEnumEntries(SchemaStringEnumEntry sEnums[]) |
| { |
| assertJavaizing(); |
| _stringEnumEntries = sEnums; |
| } |
| |
| private void ensureStringEnumInfo() |
| { |
| if (_stringEnumEnsured) |
| return; |
| |
| SchemaStringEnumEntry[] sEnums = _stringEnumEntries; |
| if (sEnums == null) |
| { |
| _stringEnumEnsured = true; |
| return; |
| } |
| |
| Map lookupStringEnum = new HashMap(sEnums.length); |
| List listOfStringEnum = new ArrayList(sEnums.length + 1); |
| Map lookupStringEnumEntry = new HashMap(sEnums.length); |
| |
| for (int i = 0; i < sEnums.length; i++) |
| { |
| lookupStringEnumEntry.put(sEnums[i].getString(), sEnums[i]); |
| } |
| |
| Class jc = _baseEnumTyperef.get().getEnumJavaClass(); |
| if (jc != null) |
| { |
| try |
| { |
| StringEnumAbstractBase.Table table = (StringEnumAbstractBase.Table)jc.getField("table").get(null); |
| for (int i = 0; i < sEnums.length; i++) |
| { |
| int j = sEnums[i].getIntValue(); |
| StringEnumAbstractBase enumVal = table.forInt(j); |
| lookupStringEnum.put(sEnums[i].getString(), enumVal); |
| while (listOfStringEnum.size() <= j) |
| listOfStringEnum.add(null); |
| listOfStringEnum.set(j, enumVal); |
| } |
| } |
| catch (Exception e) |
| { |
| System.err.println("Something wrong: could not locate enum table for " + jc); |
| jc = null; |
| lookupStringEnum.clear(); |
| listOfStringEnum.clear(); |
| } |
| } |
| |
| if (jc == null) |
| { |
| for (int i = 0; i < sEnums.length; i++) |
| { |
| int j = sEnums[i].getIntValue(); |
| String s = sEnums[i].getString(); |
| StringEnumAbstractBase enumVal = new StringEnumValue(s, j); |
| lookupStringEnum.put(s, enumVal); |
| while (listOfStringEnum.size() <= j) |
| listOfStringEnum.add(null); |
| listOfStringEnum.set(j, enumVal); |
| } |
| } |
| |
| synchronized (this) |
| { |
| if (!_stringEnumEnsured) |
| { |
| _lookupStringEnum = lookupStringEnum; |
| _listOfStringEnum = listOfStringEnum; |
| _lookupStringEnumEntry = lookupStringEnumEntry; |
| } |
| } |
| // HACKHACK: two syncrhonized blocks force a memory barrier: |
| // BUGBUG: this behavior is likely to change in future VMs |
| synchronized (this) |
| { |
| _stringEnumEnsured = true; |
| } |
| } |
| |
| public boolean hasStringEnumValues() |
| { |
| return _stringEnumEntries != null; |
| } |
| |
| public void copyEnumerationValues(SchemaTypeImpl baseImpl) |
| { |
| assertResolving(); |
| _enumerationValues = baseImpl._enumerationValues; |
| _baseEnumTyperef = baseImpl._baseEnumTyperef; |
| } |
| |
| public int getBuiltinTypeCode() |
| { return _builtinTypeCode; } // special: set up pre-init |
| |
| public void setBuiltinTypeCode(int builtinTypeCode) |
| { assertResolving(); _builtinTypeCode = builtinTypeCode; } |
| |
| synchronized void assignJavaElementSetterModel() |
| { |
| // To compute the element setter model, we need to compute the |
| // delimiting elements for each element. |
| |
| SchemaProperty[] eltProps = getElementProperties(); |
| SchemaParticle contentModel = getContentModel(); |
| Map state = new HashMap(); |
| QNameSet allContents = computeAllContainedElements(contentModel, state); |
| |
| for (int i = 0; i < eltProps.length; i++) |
| { |
| SchemaPropertyImpl sImpl = (SchemaPropertyImpl)eltProps[i]; |
| QNameSet nde = computeNondelimitingElements(sImpl.getName(), contentModel, state); |
| QNameSetBuilder builder = new QNameSetBuilder(allContents); |
| builder.removeAll(nde); |
| sImpl.setJavaSetterDelimiter(builder.toQNameSet()); |
| } |
| } |
| |
| /** |
| * Used to compute setter model. |
| * |
| * Returns the QNameSet of all elements that can possibly come before an |
| * element whose name is given by the target in a valid instance of the |
| * contentModel. When appending an element, it comes before the first |
| * one that is not in this set. |
| */ |
| private static QNameSet computeNondelimitingElements(QName target, SchemaParticle contentModel, Map state) |
| { |
| QNameSet allContents = computeAllContainedElements(contentModel, state); |
| if (!allContents.contains(target)) |
| return QNameSet.EMPTY; |
| |
| // If iterated, then all contents are delimiting. |
| if (contentModel.getMaxOccurs() == null || |
| contentModel.getMaxOccurs().compareTo(BigInteger.ONE) > 0) |
| return allContents; |
| |
| QNameSetBuilder builder; |
| |
| switch (contentModel.getParticleType()) |
| { |
| case SchemaParticle.ALL: |
| case SchemaParticle.ELEMENT: |
| default: |
| return allContents; |
| |
| case SchemaParticle.WILDCARD: |
| return QNameSet.singleton(target); |
| |
| case SchemaParticle.CHOICE: |
| builder = new QNameSetBuilder(); |
| for (int i = 0; i < contentModel.countOfParticleChild(); i++) |
| { |
| QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state); |
| if (childContents.contains(target)) |
| builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state)); |
| } |
| return builder.toQNameSet(); |
| |
| case SchemaParticle.SEQUENCE: |
| builder = new QNameSetBuilder(); |
| boolean seenTarget = false; |
| for (int i = contentModel.countOfParticleChild(); i > 0; ) |
| { |
| i--; |
| QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state); |
| if (seenTarget) |
| { |
| builder.addAll(childContents); |
| } |
| else if (childContents.contains(target)) |
| { |
| builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state)); |
| seenTarget = true; |
| } |
| } |
| return builder.toQNameSet(); |
| } |
| } |
| |
| /** |
| * Used to compute the setter model. |
| * |
| * Returns the set of all QNames of elements that could possibly be |
| * contained in the given contentModel. The state variable is used |
| * to record the results, so that if they are needed again later, |
| * they do not need to be recomputed. |
| */ |
| private static QNameSet computeAllContainedElements(SchemaParticle contentModel, Map state) |
| { |
| // Remember previously computed results to avoid complexity explosion |
| QNameSet result = (QNameSet)state.get(contentModel); |
| if (result != null) |
| return result; |
| |
| QNameSetBuilder builder; |
| |
| switch (contentModel.getParticleType()) |
| { |
| case SchemaParticle.ALL: |
| case SchemaParticle.CHOICE: |
| case SchemaParticle.SEQUENCE: |
| default: |
| builder = new QNameSetBuilder(); |
| for (int i = 0; i < contentModel.countOfParticleChild(); i++) |
| { |
| builder.addAll(computeAllContainedElements(contentModel.getParticleChild(i), state)); |
| } |
| result = builder.toQNameSet(); |
| break; |
| |
| case SchemaParticle.WILDCARD: |
| result = contentModel.getWildcardSet(); |
| break; |
| |
| case SchemaParticle.ELEMENT: |
| // Fix for XMLBEANS-228 |
| result = ((SchemaLocalElementImpl) contentModel).acceptedStartNames(); |
| break; |
| } |
| state.put(contentModel, result); |
| return result; |
| } |
| |
| public Class getJavaClass() |
| { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_javaClass == null && getFullJavaName() != null) |
| { |
| try |
| { _javaClass = Class.forName(getFullJavaName(), false, getTypeSystem().getClassLoader()); } |
| catch (ClassNotFoundException e) |
| { |
| // This is a legitimate use, when users get a SchemaTypeSystem without compiling classes |
| // System.err.println("Could not find class name " + getFullJavaName()); |
| // System.err.println("Searched in classloader " + getTypeSystem().getClassLoader()); |
| // e.printStackTrace(System.err); |
| _javaClass = null; |
| } |
| } |
| |
| return _javaClass; |
| } |
| |
| public Class getJavaImplClass() { |
| if (_implNotAvailable) |
| return null; |
| |
| if (_javaImplClass == null) |
| { |
| try { |
| if (getFullJavaImplName() != null) |
| _javaImplClass = Class.forName(getFullJavaImplName(), false, getTypeSystem().getClassLoader()); |
| else |
| _implNotAvailable = true; |
| } |
| catch (ClassNotFoundException e) { |
| _implNotAvailable = true; |
| } |
| } |
| |
| return _javaImplClass; |
| } |
| |
| public Class getUserTypeClass() |
| { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_userTypeClass == null && getUserTypeName() != null) |
| { |
| try |
| { |
| _userTypeClass = Class.forName(_userTypeName, false, |
| getTypeSystem().getClassLoader()); |
| } |
| catch (ClassNotFoundException e) |
| { |
| _userTypeClass = null; |
| } |
| } |
| |
| return _userTypeClass; |
| } |
| |
| public Class getUserTypeHandlerClass() |
| { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_userTypeHandlerClass == null && getUserTypeHandlerName() != null) |
| { |
| try |
| { |
| _userTypeHandlerClass = Class.forName(_userTypeHandler, false, |
| getTypeSystem().getClassLoader()); |
| } |
| catch (ClassNotFoundException e) |
| { |
| _userTypeHandlerClass = null; |
| } |
| } |
| |
| return _userTypeHandlerClass; |
| } |
| |
| public Constructor getJavaImplConstructor() |
| { |
| if (_javaImplConstructor == null && !_implNotAvailable) |
| { |
| final Class impl = getJavaImplClass(); |
| if (impl == null) return null; |
| try |
| { |
| _javaImplConstructor = impl.getConstructor(new Class[] { SchemaType.class }); |
| } |
| catch (NoSuchMethodException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| return _javaImplConstructor; |
| |
| } |
| |
| public Constructor getJavaImplConstructor2() |
| { |
| if (_javaImplConstructor2 == null && !_implNotAvailable) |
| { |
| final Class impl = getJavaImplClass(); |
| if (impl == null) return null; |
| try |
| { |
| _javaImplConstructor2 = impl.getDeclaredConstructor(new Class[] { SchemaType.class, boolean.class }); |
| } |
| catch (NoSuchMethodException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| return _javaImplConstructor2; |
| |
| } |
| |
| public Class getEnumJavaClass() |
| { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_javaEnumClass == null) |
| { |
| if ( getBaseEnumType() != null ) |
| { |
| try |
| { |
| _javaEnumClass = Class.forName(getBaseEnumType().getFullJavaName() + "$Enum", false, getTypeSystem().getClassLoader()); |
| } |
| catch (ClassNotFoundException e) |
| { |
| _javaEnumClass = null; |
| } |
| } |
| } |
| |
| return _javaEnumClass; |
| } |
| |
| public void setJavaClass(Class javaClass) |
| { |
| assertResolved(); |
| _javaClass = javaClass; |
| setFullJavaName(javaClass.getName()); |
| } |
| |
| public boolean isPrimitiveType() |
| { |
| return (getBuiltinTypeCode() >= BTC_FIRST_PRIMITIVE && |
| getBuiltinTypeCode() <= BTC_LAST_PRIMITIVE); |
| } |
| |
| public boolean isBuiltinType() |
| { |
| return getBuiltinTypeCode() != 0; |
| } |
| |
| public XmlObject createUnwrappedNode() |
| { |
| // Todo: attach a new xml store! |
| XmlObject result = createUnattachedNode(null); |
| return result; |
| } |
| |
| /** |
| * TypeStoreUserFactory implementation |
| */ |
| public TypeStoreUser createTypeStoreUser() |
| { |
| return (TypeStoreUser)createUnattachedNode(null); |
| } |
| |
| |
| public XmlAnySimpleType newValidatingValue(Object obj) |
| { |
| return newValue(obj, true); |
| } |
| /** |
| * Creates an immutable simple value. |
| */ |
| public XmlAnySimpleType newValue(Object obj) |
| { |
| return newValue(obj, false); |
| } |
| |
| public XmlAnySimpleType newValue(Object obj, boolean validateOnSet) |
| { |
| if (!isSimpleType() && getContentType() != SchemaType.SIMPLE_CONTENT) |
| throw new XmlValueOutOfRangeException(); // values must be simple |
| |
| XmlObjectBase result = (XmlObjectBase)createUnattachedNode(null); |
| if (validateOnSet) |
| result.setValidateOnSet(); |
| |
| // In the case of tree copy, need to call a specla setter to avoid |
| // set(XmlObject) |
| if (obj instanceof XmlObject) |
| result.set_newValue((XmlObject)obj); |
| else |
| result.objectSet(obj); |
| |
| result.check_dated(); |
| result.setImmutable(); |
| |
| return (XmlAnySimpleType) result; |
| } |
| |
| /** |
| * Creates an instance of this type. |
| */ |
| private XmlObject createUnattachedNode(SchemaProperty prop) |
| { |
| XmlObject result = null; |
| |
| if (!isBuiltinType() && !isNoType()) |
| { |
| // System.out.println("Attempting to load impl class: " + getFullJavaImplName()); |
| Constructor ctr = getJavaImplConstructor(); |
| if (ctr != null) |
| { |
| try |
| { |
| // System.out.println("Succeeded!"); |
| return (XmlObject)ctr.newInstance(_ctrArgs); |
| } |
| catch (Exception e) |
| { |
| System.out.println("Exception trying to instantiate impl class."); |
| e.printStackTrace(); |
| } |
| } |
| } |
| else |
| { |
| result = createBuiltinInstance(); |
| } |
| |
| // if no result, we must be a restriction of some compiled type |
| for (SchemaType sType = this; result == null; sType = sType.getBaseType()) |
| result = ((SchemaTypeImpl)sType).createUnattachedSubclass(this); |
| |
| ((XmlObjectBase)result).init_flags(prop); |
| return result; |
| } |
| |
| private XmlObject createUnattachedSubclass(SchemaType sType) |
| { |
| if (!isBuiltinType() && !isNoType()) |
| { |
| // System.out.println("Attempting to load impl class: " + getFullJavaImplName()); |
| Constructor ctr = getJavaImplConstructor2(); |
| if (ctr != null) |
| { |
| boolean accessible = ctr.isAccessible(); |
| try |
| { |
| ctr.setAccessible(true); |
| // System.out.println("Succeeded!"); |
| try |
| { |
| return (XmlObject)ctr.newInstance(new Object[] { sType, sType.isSimpleType() ? Boolean.FALSE : Boolean.TRUE }); |
| } |
| catch (Exception e) |
| { |
| System.out.println("Exception trying to instantiate impl class."); |
| e.printStackTrace(); |
| } |
| finally |
| { |
| // Make a best-effort try to set the accessibility back to what it was |
| try |
| { ctr.setAccessible(accessible); } |
| catch (SecurityException se) |
| { } |
| } |
| } |
| catch (Exception e) |
| { |
| System.out.println("Exception trying to instantiate impl class."); |
| e.printStackTrace(); |
| } |
| } |
| return null; |
| } |
| else |
| { |
| return createBuiltinSubclass(sType); |
| } |
| } |
| |
| private XmlObject createBuiltinInstance() |
| { |
| switch (getBuiltinTypeCode()) |
| { |
| case BTC_NOT_BUILTIN: |
| return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE); |
| case BTC_ANY_TYPE: |
| return new XmlAnyTypeImpl(); |
| case BTC_ANY_SIMPLE: |
| return new XmlAnySimpleTypeImpl(); |
| case BTC_BOOLEAN: |
| return new XmlBooleanImpl(); |
| case BTC_BASE_64_BINARY: |
| return new XmlBase64BinaryImpl(); |
| case BTC_HEX_BINARY: |
| return new XmlHexBinaryImpl(); |
| case BTC_ANY_URI: |
| return new XmlAnyUriImpl(); |
| case BTC_QNAME: |
| return new XmlQNameImpl(); |
| case BTC_NOTATION: |
| return new XmlNotationImpl(); |
| case BTC_FLOAT: |
| return new XmlFloatImpl(); |
| case BTC_DOUBLE: |
| return new XmlDoubleImpl(); |
| case BTC_DECIMAL: |
| return new XmlDecimalImpl(); |
| case BTC_STRING: |
| return new XmlStringImpl(); |
| case BTC_DURATION: |
| return new XmlDurationImpl(); |
| case BTC_DATE_TIME: |
| return new XmlDateTimeImpl(); |
| case BTC_TIME: |
| return new XmlTimeImpl(); |
| case BTC_DATE: |
| return new XmlDateImpl(); |
| case BTC_G_YEAR_MONTH: |
| return new XmlGYearMonthImpl(); |
| case BTC_G_YEAR: |
| return new XmlGYearImpl(); |
| case BTC_G_MONTH_DAY: |
| return new XmlGMonthDayImpl(); |
| case BTC_G_DAY: |
| return new XmlGDayImpl(); |
| case BTC_G_MONTH: |
| return new XmlGMonthImpl(); |
| case BTC_INTEGER: |
| return new XmlIntegerImpl(); |
| case BTC_LONG: |
| return new XmlLongImpl(); |
| case BTC_INT: |
| return new XmlIntImpl(); |
| case BTC_SHORT: |
| return new XmlShortImpl(); |
| case BTC_BYTE: |
| return new XmlByteImpl(); |
| case BTC_NON_POSITIVE_INTEGER: |
| return new XmlNonPositiveIntegerImpl(); |
| case BTC_NEGATIVE_INTEGER: |
| return new XmlNegativeIntegerImpl(); |
| case BTC_NON_NEGATIVE_INTEGER: |
| return new XmlNonNegativeIntegerImpl(); |
| case BTC_POSITIVE_INTEGER: |
| return new XmlPositiveIntegerImpl(); |
| case BTC_UNSIGNED_LONG: |
| return new XmlUnsignedLongImpl(); |
| case BTC_UNSIGNED_INT: |
| return new XmlUnsignedIntImpl(); |
| case BTC_UNSIGNED_SHORT: |
| return new XmlUnsignedShortImpl(); |
| case BTC_UNSIGNED_BYTE: |
| return new XmlUnsignedByteImpl(); |
| case BTC_NORMALIZED_STRING: |
| return new XmlNormalizedStringImpl(); |
| case BTC_TOKEN: |
| return new XmlTokenImpl(); |
| case BTC_NAME: |
| return new XmlNameImpl(); |
| case BTC_NCNAME: |
| return new XmlNCNameImpl(); |
| case BTC_LANGUAGE: |
| return new XmlLanguageImpl(); |
| case BTC_ID: |
| return new XmlIdImpl(); |
| case BTC_IDREF: |
| return new XmlIdRefImpl(); |
| case BTC_IDREFS: |
| return new XmlIdRefsImpl(); |
| case BTC_ENTITY: |
| return new XmlEntityImpl(); |
| case BTC_ENTITIES: |
| return new XmlEntitiesImpl(); |
| case BTC_NMTOKEN: |
| return new XmlNmTokenImpl(); |
| case BTC_NMTOKENS: |
| return new XmlNmTokensImpl(); |
| default: |
| throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode()); |
| } |
| } |
| |
| private XmlObject createBuiltinSubclass(SchemaType sType) |
| { |
| boolean complex = !sType.isSimpleType(); |
| switch (getBuiltinTypeCode()) |
| { |
| case BTC_NOT_BUILTIN: |
| return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE); |
| case BTC_ANY_TYPE: |
| case BTC_ANY_SIMPLE: |
| switch (sType.getSimpleVariety()) |
| { |
| case NOT_SIMPLE: |
| return new XmlComplexContentImpl(sType); |
| case ATOMIC: |
| return new XmlAnySimpleTypeRestriction(sType, complex); |
| case LIST: |
| return new XmlListImpl(sType, complex); |
| case UNION: |
| return new XmlUnionImpl(sType, complex); |
| default: |
| throw new IllegalStateException(); |
| } |
| case BTC_BOOLEAN: |
| return new XmlBooleanRestriction(sType, complex); |
| case BTC_BASE_64_BINARY: |
| return new XmlBase64BinaryRestriction(sType, complex); |
| case BTC_HEX_BINARY: |
| return new XmlHexBinaryRestriction(sType, complex); |
| case BTC_ANY_URI: |
| return new XmlAnyUriRestriction(sType, complex); |
| case BTC_QNAME: |
| return new XmlQNameRestriction(sType, complex); |
| case BTC_NOTATION: |
| return new XmlNotationRestriction(sType, complex); |
| case BTC_FLOAT: |
| return new XmlFloatRestriction(sType, complex); |
| case BTC_DOUBLE: |
| return new XmlDoubleRestriction(sType, complex); |
| case BTC_DECIMAL: |
| return new XmlDecimalRestriction(sType, complex); |
| case BTC_STRING: |
| if (sType.hasStringEnumValues()) |
| return new XmlStringEnumeration(sType, complex); |
| else |
| return new XmlStringRestriction(sType, complex); |
| case BTC_DURATION: |
| return new XmlDurationImpl(sType, complex); |
| case BTC_DATE_TIME: |
| return new XmlDateTimeImpl(sType, complex); |
| case BTC_TIME: |
| return new XmlTimeImpl(sType, complex); |
| case BTC_DATE: |
| return new XmlDateImpl(sType, complex); |
| case BTC_G_YEAR_MONTH: |
| return new XmlGYearMonthImpl(sType, complex); |
| case BTC_G_YEAR: |
| return new XmlGYearImpl(sType, complex); |
| case BTC_G_MONTH_DAY: |
| return new XmlGMonthDayImpl(sType, complex); |
| case BTC_G_DAY: |
| return new XmlGDayImpl(sType, complex); |
| case BTC_G_MONTH: |
| return new XmlGMonthImpl(sType, complex); |
| case BTC_INTEGER: |
| return new XmlIntegerRestriction(sType, complex); |
| case BTC_LONG: |
| return new XmlLongRestriction(sType, complex); |
| case BTC_INT: |
| return new XmlIntRestriction(sType, complex); |
| case BTC_SHORT: |
| return new XmlShortImpl(sType, complex); |
| case BTC_BYTE: |
| return new XmlByteImpl(sType, complex); |
| case BTC_NON_POSITIVE_INTEGER: |
| return new XmlNonPositiveIntegerImpl(sType, complex); |
| case BTC_NEGATIVE_INTEGER: |
| return new XmlNegativeIntegerImpl(sType, complex); |
| case BTC_NON_NEGATIVE_INTEGER: |
| return new XmlNonNegativeIntegerImpl(sType, complex); |
| case BTC_POSITIVE_INTEGER: |
| return new XmlPositiveIntegerImpl(sType, complex); |
| case BTC_UNSIGNED_LONG: |
| return new XmlUnsignedLongImpl(sType, complex); |
| case BTC_UNSIGNED_INT: |
| return new XmlUnsignedIntImpl(sType, complex); |
| case BTC_UNSIGNED_SHORT: |
| return new XmlUnsignedShortImpl(sType, complex); |
| case BTC_UNSIGNED_BYTE: |
| return new XmlUnsignedByteImpl(sType, complex); |
| case BTC_NORMALIZED_STRING: |
| return new XmlNormalizedStringImpl(sType, complex); |
| case BTC_TOKEN: |
| return new XmlTokenImpl(sType, complex); |
| case BTC_NAME: |
| return new XmlNameImpl(sType, complex); |
| case BTC_NCNAME: |
| return new XmlNCNameImpl(sType, complex); |
| case BTC_LANGUAGE: |
| return new XmlLanguageImpl(sType, complex); |
| case BTC_ID: |
| return new XmlIdImpl(sType, complex); |
| case BTC_IDREF: |
| return new XmlIdRefImpl(sType, complex); |
| case BTC_IDREFS: |
| return new XmlIdRefsImpl(sType, complex); |
| case BTC_ENTITY: |
| return new XmlEntityImpl(sType, complex); |
| case BTC_ENTITIES: |
| return new XmlEntitiesImpl(sType, complex); |
| case BTC_NMTOKEN: |
| return new XmlNmTokenImpl(sType, complex); |
| case BTC_NMTOKENS: |
| return new XmlNmTokensImpl(sType, complex); |
| default: |
| throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode()); |
| } |
| } |
| |
| public SchemaType getCommonBaseType(SchemaType type) |
| { |
| // null type is treated as the no-type |
| if (this == BuiltinSchemaTypeSystem.ST_ANY_TYPE || type == null || type.isNoType()) |
| return this; |
| |
| // any type is the universal base type; noType is the universal derived type |
| if (type == BuiltinSchemaTypeSystem.ST_ANY_TYPE || isNoType()) |
| return type; |
| |
| // the regular case: |
| SchemaTypeImpl sImpl1 = (SchemaTypeImpl)type; |
| while (sImpl1.getBaseDepth() > getBaseDepth()) |
| sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType(); |
| SchemaTypeImpl sImpl2 = this; |
| while (sImpl2.getBaseDepth() > sImpl1.getBaseDepth()) |
| sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType(); |
| for (;;) |
| { |
| if (sImpl1.equals(sImpl2)) |
| break; |
| sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType(); |
| sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType(); |
| assert(sImpl1 != null && sImpl2 != null); // must meet at anyType |
| } |
| return sImpl1; |
| } |
| |
| public boolean isAssignableFrom(SchemaType type) |
| { |
| if (type == null || type.isNoType()) |
| return true; |
| |
| if (isNoType()) |
| return false; |
| |
| if (getSimpleVariety() == UNION) |
| { |
| SchemaType[] members = getUnionMemberTypes(); |
| for (int i = 0; i < members.length; i++) |
| if (members[i].isAssignableFrom(type)) |
| return true; |
| } |
| |
| int depth = ((SchemaTypeImpl)type).getBaseDepth() - getBaseDepth(); |
| if (depth < 0) |
| return false; |
| while (depth > 0) |
| { |
| type = type.getBaseType(); |
| depth -= 1; |
| } |
| return (type != null && type.equals(this)); |
| } |
| |
| |
| public String toString() |
| { |
| if (getName() != null) |
| return "T=" + QNameHelper.pretty(getName()); |
| |
| if (isDocumentType()) |
| return "D=" + QNameHelper.pretty(getDocumentElementName()); |
| |
| if (isAttributeType()) |
| return "R=" + QNameHelper.pretty(getAttributeTypeAttributeName()); |
| |
| String prefix; |
| |
| if (getContainerField() != null) |
| { |
| prefix = (getContainerField().getName().getNamespaceURI().length() > 0 ? |
| (getContainerField().isAttribute() ? "Q=" : "E=") : |
| (getContainerField().isAttribute() ? "A=" : "U=")) |
| + getContainerField().getName().getLocalPart(); |
| if (getOuterType() == null) |
| return prefix + "@" + getContainerField().getName().getNamespaceURI(); |
| } |
| else if (isNoType()) |
| return "N="; |
| else if (getOuterType() == null) |
| return "noouter"; |
| else if (getOuterType().getBaseType() == this) |
| prefix = "B="; |
| else if (getOuterType().getContentBasedOnType() == this) |
| prefix = "S="; |
| else if (getOuterType().getSimpleVariety() == SchemaType.LIST) |
| prefix = "I="; |
| else if (getOuterType().getSimpleVariety() == SchemaType.UNION) |
| prefix = "M=" + getAnonymousUnionMemberOrdinal(); |
| else |
| prefix = "strange="; |
| |
| return prefix + "|" + getOuterType().toString(); |
| } |
| |
| private XmlObject _parseObject; |
| private String _parseTNS; |
| private String _elemFormDefault; |
| private String _attFormDefault; |
| private boolean _chameleon; |
| private boolean _redefinition; |
| |
| public void setParseContext(XmlObject parseObject, String targetNamespace, boolean chameleon, String elemFormDefault, String attFormDefault, boolean redefinition) |
| { |
| _parseObject = parseObject; |
| _parseTNS = targetNamespace; |
| _chameleon = chameleon; |
| _elemFormDefault = elemFormDefault; |
| _attFormDefault = attFormDefault; |
| _redefinition = redefinition; |
| } |
| |
| public XmlObject getParseObject() |
| { return _parseObject; } |
| |
| public String getTargetNamespace() |
| { return _parseTNS; } |
| |
| public boolean isChameleon ( ) |
| { return _chameleon; } |
| |
| public String getElemFormDefault() |
| { return _elemFormDefault; } |
| |
| public String getAttFormDefault() |
| { return _attFormDefault; } |
| |
| public String getChameleonNamespace() |
| { return _chameleon ? _parseTNS : null; } |
| |
| public boolean isRedefinition() |
| { return _redefinition; } |
| |
| private SchemaType.Ref _selfref = new SchemaType.Ref(this); |
| |
| public SchemaType.Ref getRef() |
| { return _selfref; } |
| |
| public SchemaComponent.Ref getComponentRef() |
| { return getRef(); } |
| |
| /** |
| * Gives access to the internals of element validation |
| */ |
| private static class SequencerImpl implements SchemaTypeElementSequencer |
| { |
| private SchemaTypeVisitorImpl _visitor; |
| |
| private SequencerImpl(SchemaTypeVisitorImpl visitor) |
| { |
| _visitor = visitor; |
| } |
| |
| public boolean next(QName elementName) |
| { |
| if (_visitor == null) |
| return false; |
| |
| return _visitor.visit(elementName); |
| } |
| |
| public boolean peek(QName elementName) |
| { |
| if (_visitor == null) |
| return false; |
| |
| return _visitor.testValid(elementName); |
| } |
| } |
| |
| /** |
| * Returns a QNameSet of elements that may exist in wildcard |
| * buchets and are not explicitly defined in this schema type. |
| * Note: In this example: |
| * <xs:complexType name="exampleType"> |
| * <xs:sequence> |
| * <xs:element name="someElement" type='xs:string' /> |
| * <xs:any namespace="##targetNamespace" /> |
| * </xs:sequence> |
| * </xs:complexType> |
| * the returned QNameSet will not contain the qname of 'someElement'. |
| * @return the constructed QNameSet |
| */ |
| public QNameSet qnameSetForWildcardElements() |
| { |
| SchemaParticle model = this.getContentModel(); |
| QNameSetBuilder wildcardSet = new QNameSetBuilder(); |
| computeWildcardSet(model, wildcardSet); |
| |
| QNameSetBuilder qnsb = new QNameSetBuilder( wildcardSet ); |
| SchemaProperty[] props = this.getElementProperties(); |
| |
| for (int i = 0; i < props.length; i++) |
| { |
| SchemaProperty prop = props[i]; |
| qnsb.remove(prop.getName()); |
| } |
| |
| return qnsb.toQNameSet(); |
| } |
| |
| private static void computeWildcardSet(SchemaParticle model, QNameSetBuilder result) |
| { |
| if (model.getParticleType() == SchemaParticle.WILDCARD) |
| { |
| QNameSet cws = model.getWildcardSet(); |
| result.addAll(cws); |
| return; |
| } |
| for (int i = 0; i < model.countOfParticleChild(); i++) |
| { |
| SchemaParticle child = model.getParticleChild(i); |
| computeWildcardSet(child, result); |
| } |
| } |
| |
| /** |
| * Returns a QNameSet of attributes that may exist in wildcard |
| * buchets and are not explicitly defined in this schema type. |
| * Note: In this example: |
| * <xs:complexType name="exampleType"> |
| * ... |
| * <xs:attribute name='someAttribute' type='xs:string' /> |
| * <xs:anyAttribute namespace="##targetNamespace" /> |
| * </xs:complexType> |
| * the returned QNameSet will not contain the qname of 'someAttribute'. |
| * @return the constructed QNameSet |
| */ |
| public QNameSet qnameSetForWildcardAttributes() |
| { |
| SchemaAttributeModel model = this.getAttributeModel(); |
| QNameSet wildcardSet = model.getWildcardSet(); |
| |
| if (wildcardSet==null) |
| return QNameSet.EMPTY; |
| |
| QNameSetBuilder qnsb = new QNameSetBuilder( wildcardSet ); |
| |
| SchemaProperty[] props = this.getAttributeProperties(); |
| |
| for (int i = 0; i < props.length; i++) |
| { |
| SchemaProperty prop = props[i]; |
| qnsb.remove(prop.getName()); |
| } |
| |
| return qnsb.toQNameSet(); |
| } |
| } |