| /* 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.*; |
| 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.*; |
| |
| 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<? extends XmlObject> _javaClass; |
| private volatile Class<? extends StringEnumAbstractBase> _javaEnumClass; |
| private volatile Class<? extends XmlObjectBase> _javaImplClass; |
| private volatile Constructor<? extends XmlObjectBase> _javaImplConstructor; |
| private volatile Constructor<? extends XmlObjectBase> _javaImplConstructor2; |
| private volatile boolean _implNotAvailable; |
| |
| // 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<SchemaLocalElement, Integer> _eltToIndexMap; // lazily computed |
| private volatile Map<SchemaLocalAttribute, Integer> _attrToIndexMap; // lazily computed |
| private Map<QName, SchemaProperty> _propertyModelByElementName; |
| private Map<QName, SchemaProperty> _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<QName> _validSubstitutions = Collections.emptySet(); |
| |
| // 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<String, StringEnumAbstractBase> _lookupStringEnum; |
| private volatile List<StringEnumAbstractBase> _listOfStringEnum; |
| private volatile Map<String, SchemaStringEnumEntry> _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 final List<QName> _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) { |
| assert (outer != null); |
| _containerField = outer.getAttributeModel().getAttributes()[_containerFieldIndex]; |
| } else { |
| assert (outer != null); |
| _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 && (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 == null) ? null : interfaces.clone(); |
| } |
| |
| 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<SchemaLocalElement> eltList, SchemaParticle contentModel) { |
| if (contentModel == null) { |
| return; |
| } |
| |
| switch (contentModel.getParticleType()) { |
| case SchemaParticle.ELEMENT: |
| eltList.add((SchemaLocalElement) contentModel); |
| break; |
| case SchemaParticle.ALL: |
| case SchemaParticle.CHOICE: |
| case SchemaParticle.SEQUENCE: |
| for (int i = 0; i < contentModel.countOfParticleChild(); i++) { |
| buildEltList(eltList, contentModel.getParticleChild(i)); |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| private void buildLocalElts() { |
| List<SchemaLocalElement> eltList = new ArrayList<>(); |
| buildEltList(eltList, _contentModel); |
| _localElts = eltList.toArray(new SchemaLocalElement[0]); |
| } |
| |
| public SchemaLocalElement getLocalElementByIndex(int i) { |
| SchemaLocalElement[] elts = _localElts; |
| if (elts == null) { |
| buildLocalElts(); |
| elts = _localElts; |
| } |
| return elts[i]; |
| } |
| |
| public int getIndexForLocalElement(SchemaLocalElement elt) { |
| Map<SchemaLocalElement, Integer> localEltMap = _eltToIndexMap; |
| if (localEltMap == null) { |
| if (_localElts == null) { |
| buildLocalElts(); |
| } |
| localEltMap = new HashMap<>(); |
| for (int i = 0; i < _localElts.length; i++) { |
| localEltMap.put(_localElts[i], i); |
| } |
| _eltToIndexMap = localEltMap; |
| } |
| return localEltMap.get(elt); |
| } |
| |
| public int getIndexForLocalAttribute(SchemaLocalAttribute attr) { |
| Map<SchemaLocalAttribute, Integer> 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], i); |
| } |
| _attrToIndexMap = localAttrMap; |
| } |
| return localAttrMap.get(attr); |
| } |
| |
| public SchemaAttributeModel getAttributeModel() { |
| return _attributeModel; |
| } |
| |
| public SchemaProperty[] getProperties() { |
| if (_propertyModelByElementName == null) { |
| return getAttributeProperties(); |
| } |
| |
| if (_propertyModelByAttributeName == null) { |
| return getElementProperties(); |
| } |
| |
| List<SchemaProperty> list = new ArrayList<>(); |
| list.addAll(_propertyModelByElementName.values()); |
| list.addAll(_propertyModelByAttributeName.values()); |
| return list.toArray(new SchemaProperty[0]); |
| } |
| |
| private static final SchemaProperty[] NO_PROPERTIES = new SchemaProperty[0]; |
| |
| public SchemaProperty[] getDerivedProperties() { |
| SchemaType baseType = getBaseType(); |
| if (baseType == null) { |
| return getProperties(); |
| } |
| |
| List<SchemaProperty> results = new ArrayList<>(); |
| |
| if (_propertyModelByElementName != null) { |
| results.addAll(_propertyModelByElementName.values()); |
| } |
| |
| if (_propertyModelByAttributeName != null) { |
| results.addAll(_propertyModelByAttributeName.values()); |
| } |
| |
| for (Iterator<SchemaProperty> it = results.iterator(); it.hasNext(); ) { |
| SchemaProperty prop = 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 results.toArray(new SchemaProperty[0]); |
| } |
| |
| 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 _propertyModelByElementName.values().toArray(new SchemaProperty[0]); |
| } |
| |
| public SchemaProperty[] getAttributeProperties() { |
| if (_propertyModelByAttributeName == null) { |
| return NO_PROPERTIES; |
| } |
| |
| return _propertyModelByAttributeName.values().toArray(new SchemaProperty[0]); |
| } |
| |
| public SchemaProperty getElementProperty(QName eltName) { |
| return _propertyModelByElementName == null ? null : _propertyModelByElementName.get(eltName); |
| } |
| |
| public SchemaProperty getAttributeProperty(QName attrName) { |
| return _propertyModelByAttributeName == null ? null : _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<QName, SchemaProperty> propertyModelByElementName, |
| Map<QName, SchemaProperty> 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<SchemaProperty> eltProps = _propertyModelByElementName.values(); |
| for (SchemaProperty prop : eltProps) { |
| QName[] names = prop.acceptedNames(); |
| for (QName name : names) { |
| if (!_propertyModelByElementName.containsKey(name)) { |
| _validSubstitutions.add(name); |
| } |
| } |
| } |
| } |
| } |
| |
| 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; |
| SchemaProperty prop = _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(); |
| } |
| */ |
| 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 = _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; |
| SchemaProperty prop = null; |
| if (isSimpleType() || !containsElements() || isNoType()) { |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } else { |
| prop = _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(); |
| } |
| */ |
| 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; |
| SchemaProperty prop = null; |
| if (isSimpleType() || isNoType()) { |
| type = BuiltinSchemaTypeSystem.ST_NO_TYPE; |
| } else if (isURType()) { |
| type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; |
| } else { |
| prop = _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 == null ? null : anonymousTyperefs.clone(); |
| } |
| |
| |
| 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 == null ? null : typerefs.clone(); |
| } |
| |
| 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<SchemaType> constituentMemberTypes = new LinkedHashSet<>(); |
| Set<SchemaType> allSubTypes = new LinkedHashSet<>(); |
| SchemaType commonBaseType = null; |
| |
| allSubTypes.add(this); |
| |
| for (Ref unionMemberTyperef : _unionMemberTyperefs) { |
| SchemaTypeImpl mImpl = (SchemaTypeImpl) unionMemberTyperef.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(constituentMemberTypes.toArray(StscState.EMPTY_ST_ARRAY)); |
| setUnionSubTypes(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() { |
| return _sgMembers.toArray(new QName[0]); |
| } |
| |
| 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 == null ? null : values.clone(); |
| _fixedFacetArray = fixed == null ? null : fixed.clone(); |
| } |
| |
| 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 == null ? null : list.clone(); |
| } |
| |
| 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 == null ? null : a.clone(); |
| } |
| |
| public StringEnumAbstractBase enumForString(String s) { |
| ensureStringEnumInfo(); |
| if (_lookupStringEnum == null) { |
| return null; |
| } |
| return _lookupStringEnum.get(s); |
| } |
| |
| public StringEnumAbstractBase enumForInt(int i) { |
| ensureStringEnumInfo(); |
| if (_listOfStringEnum == null || i < 0 || i >= _listOfStringEnum.size()) { |
| return null; |
| } |
| return _listOfStringEnum.get(i); |
| } |
| |
| public SchemaStringEnumEntry enumEntryForString(String s) { |
| ensureStringEnumInfo(); |
| if (_lookupStringEnumEntry == null) { |
| return null; |
| } |
| return _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 == null ? null : sEnums.clone(); |
| } |
| |
| private void ensureStringEnumInfo() { |
| if (_stringEnumEnsured) { |
| return; |
| } |
| |
| SchemaStringEnumEntry[] sEnums = _stringEnumEntries; |
| if (sEnums == null) { |
| _stringEnumEnsured = true; |
| return; |
| } |
| |
| Map<String, StringEnumAbstractBase> lookupStringEnum = new HashMap<>(sEnums.length); |
| List<StringEnumAbstractBase> listOfStringEnum = new ArrayList<>(sEnums.length + 1); |
| Map<String, SchemaStringEnumEntry> lookupStringEnumEntry = new HashMap<>(sEnums.length); |
| |
| for (SchemaStringEnumEntry sEnum : sEnums) { |
| lookupStringEnumEntry.put(sEnum.getString(), sEnum); |
| } |
| |
| Class<? extends StringEnumAbstractBase> jc = _baseEnumTyperef.get().getEnumJavaClass(); |
| if (jc != null) { |
| try { |
| StringEnumAbstractBase.Table table = (StringEnumAbstractBase.Table) jc.getField("table").get(null); |
| for (SchemaStringEnumEntry sEnum : sEnums) { |
| int j = sEnum.getIntValue(); |
| StringEnumAbstractBase enumVal = table.forInt(j); |
| lookupStringEnum.put(sEnum.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 (SchemaStringEnumEntry sEnum : sEnums) { |
| int j = sEnum.getIntValue(); |
| String s = sEnum.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<SchemaParticle, QNameSet> state = new HashMap<>(); |
| QNameSet allContents = computeAllContainedElements(contentModel, state); |
| |
| for (SchemaProperty eltProp : eltProps) { |
| SchemaPropertyImpl sImpl = (SchemaPropertyImpl) eltProp; |
| QNameSet nde = computeNondelimitingElements(sImpl.getName(), contentModel, state); |
| QNameSetBuilder builder = new QNameSetBuilder(allContents); |
| builder.removeAll(nde); |
| sImpl.setJavaSetterDelimiter(builder.toQNameSet()); |
| } |
| } |
| |
| /** |
| * Used to compute setter model. |
| * <p> |
| * 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<SchemaParticle, QNameSet> 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. |
| * <p> |
| * 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<SchemaParticle, QNameSet> state) { |
| // Remember previously computed results to avoid complexity explosion |
| QNameSet result = 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 = contentModel.acceptedStartNames(); |
| break; |
| } |
| state.put(contentModel, result); |
| return result; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Class<? extends XmlObject> getJavaClass() { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_javaClass == null && getFullJavaName() != null) { |
| try { |
| _javaClass = (Class<? extends XmlObject>) Class.forName(getFullJavaName(), false, getTypeSystem().getClassLoader()); |
| } catch (ClassNotFoundException e) { |
| // This is a legitimate use, when users get a SchemaTypeSystem without compiling classes |
| _javaClass = null; |
| } |
| } |
| |
| return _javaClass; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Class<? extends XmlObjectBase> getJavaImplClass() { |
| if (_implNotAvailable) { |
| return null; |
| } |
| |
| if (_javaImplClass == null) { |
| try { |
| if (getFullJavaImplName() != null) { |
| _javaImplClass = (Class<? extends XmlObjectBase>) Class.forName(getFullJavaImplName(), false, getTypeSystem().getClassLoader()); |
| } else { |
| _implNotAvailable = true; |
| } |
| } catch (ClassNotFoundException e) { |
| _implNotAvailable = true; |
| } |
| } |
| |
| return _javaImplClass; |
| } |
| |
| public Constructor<? extends XmlObjectBase> getJavaImplConstructor() { |
| if (_javaImplConstructor == null && !_implNotAvailable) { |
| final Class<? extends XmlObjectBase> impl = getJavaImplClass(); |
| if (impl == null) { |
| return null; |
| } |
| try { |
| _javaImplConstructor = impl.getConstructor(SchemaType.class); |
| } catch (NoSuchMethodException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| return _javaImplConstructor; |
| |
| } |
| |
| public Constructor<? extends XmlObjectBase> getJavaImplConstructor2() { |
| if (_javaImplConstructor2 == null && !_implNotAvailable) { |
| final Class<? extends XmlObjectBase> impl = getJavaImplClass(); |
| if (impl == null) { |
| return null; |
| } |
| try { |
| _javaImplConstructor2 = impl.getDeclaredConstructor(SchemaType.class, boolean.class); |
| } catch (NoSuchMethodException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| return _javaImplConstructor2; |
| |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public Class<? extends StringEnumAbstractBase> getEnumJavaClass() { |
| // This field is declared volatile and Class is immutable so this is allowed. |
| if (_javaEnumClass == null) { |
| if (getBaseEnumType() != null) { |
| try { |
| _javaEnumClass = (Class<? extends StringEnumAbstractBase>) Class.forName(getBaseEnumType().getFullJavaName() + "$Enum", false, getTypeSystem().getClassLoader()); |
| } catch (ClassNotFoundException e) { |
| _javaEnumClass = null; |
| } |
| } |
| } |
| |
| return _javaEnumClass; |
| } |
| |
| public void setJavaClass(Class<? extends XmlObject> 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! |
| return createUnattachedNode(null); |
| } |
| |
| /** |
| * 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.setObjectValue(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<? extends XmlObjectBase> ctr = getJavaImplConstructor(); |
| if (ctr != null) { |
| try { |
| return 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<? extends XmlObjectBase> ctr = getJavaImplConstructor2(); |
| if (ctr != null) { |
| boolean accessible = ctr.isAccessible(); |
| try { |
| ctr.setAccessible(true); |
| try { |
| return ctr.newInstance(sType, !sType.isSimpleType()); |
| } 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 ignored) { |
| } |
| } |
| } 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(); |
| } |
| while (!sImpl1.equals(sImpl2)) { |
| 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 (SchemaType member : members) { |
| if (member.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 final 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 final 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 (SchemaProperty prop : props) { |
| 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 (SchemaProperty prop : props) { |
| qnsb.remove(prop.getName()); |
| } |
| |
| return qnsb.toQNameSet(); |
| } |
| } |