| /* 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.inst2xsd.util; |
| |
| import org.apache.xmlbeans.XmlCursor; |
| import org.apache.xmlbeans.XmlQName; |
| import org.apache.xmlbeans.impl.values.XmlQNameImpl; |
| |
| import javax.xml.namespace.QName; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004 |
| */ |
| public class Type { |
| private QName _name; |
| |
| private int _kind = SIMPLE_TYPE_SIMPLE_CONTENT; |
| // _kind value space |
| public static final int SIMPLE_TYPE_SIMPLE_CONTENT = 1; // ie no atts, no elems, just text |
| public static final int COMPLEX_TYPE_SIMPLE_CONTENT = 2; // ie atts*, no elems, text* - simple type extension |
| public static final int COMPLEX_TYPE_COMPLEX_CONTENT = 3; // ie atts*, elems, no text |
| public static final int COMPLEX_TYPE_MIXED_CONTENT = 4; // ie atts*, elems, text |
| public static final int COMPLEX_TYPE_EMPTY_CONTENT = 5; // no elems, no text, just atts |
| |
| private int _topParticleForComplexOrMixedContent = PARTICLE_SEQUENCE; |
| // _topParticleForComplexOrMixedContent |
| public static final int PARTICLE_SEQUENCE = 1; |
| public static final int PARTICLE_CHOICE_UNBOUNDED = 2; |
| |
| private List<Element> _elements; // size>0 COMPLEX |
| private List<Attribute> _attributes; // size>0 COMPLEX |
| |
| private Type _extensionType; |
| private boolean _isGlobal = false; |
| |
| private List<String> _enumerationValues; |
| private boolean _acceptsEnumerationValue = true; |
| private List<QName> _enumerationQNames; // This is a special case where the lexical representation |
| // is not enough for a value, the QNames need to be remembered |
| // in case the _extensionType is QName |
| |
| protected Type() { |
| } |
| |
| public static Type createNamedType(QName name, int contentType) { |
| assert name != null; |
| Type type = new Type(); |
| type.setName(name); |
| type.setContentType(contentType); |
| return type; |
| } |
| |
| public static Type createUnnamedType(int contentType) { |
| assert contentType == SIMPLE_TYPE_SIMPLE_CONTENT || |
| contentType == COMPLEX_TYPE_SIMPLE_CONTENT || |
| contentType == COMPLEX_TYPE_COMPLEX_CONTENT || |
| contentType == COMPLEX_TYPE_MIXED_CONTENT || |
| contentType == COMPLEX_TYPE_EMPTY_CONTENT : "Unknown contentType: " + contentType; |
| Type type = new Type(); |
| type.setContentType(contentType); |
| return type; |
| } |
| |
| |
| public QName getName() { |
| return _name; |
| } |
| |
| public void setName(QName name) { |
| this._name = name; |
| } |
| |
| /** |
| * @return SIMPLE_TYPE_SIMPLE_CONTENT // ie no atts, no elems, just text |
| * COMPLEX_TYPE_SIMPLE_CONTENT // ie atts*, no elems, text* - simple type extension |
| * COMPLEX_TYPE_COMPLEX_CONTENT // ie atts*, elems, no text |
| * COMPLEX_TYPE_MIXED_CONTENT // ie atts*, elems, text |
| * COMPLEX_TYPE_EMPTY_CONTENT // no elems, no text, just atts |
| */ |
| public int getContentType() { |
| return _kind; |
| } |
| |
| /** |
| * @param kind 4 kinds: |
| * SIMPLE_TYPE_SIMPLE_CONTENT // ie no atts, no elems, just text |
| * COMPLEX_TYPE_SIMPLE_CONTENT // ie atts*, no elems, text* - simple type extension |
| * COMPLEX_TYPE_COMPLEX_CONTENT // ie atts*, elems, no text |
| * COMPLEX_TYPE_MIXED_CONTENT // ie atts*, elems, text |
| * COMPLEX_TYPE_EMPTY_CONTENT // no elems, no text, just atts |
| */ |
| public void setContentType(int kind) { |
| this._kind = kind; |
| } |
| |
| public List<Element> getElements() { |
| ensureElements(); |
| return _elements; |
| } |
| |
| public void addElement(Element element) { |
| ensureElements(); |
| _elements.add(element); |
| } |
| |
| public void setElements(List<Element> elements) { |
| ensureElements(); |
| _elements.clear(); |
| _elements.addAll(elements); |
| } |
| |
| private void ensureElements() { |
| if (_elements == null) { |
| _elements = new ArrayList<>(); |
| } |
| } |
| |
| public List<Attribute> getAttributes() { |
| ensureAttributes(); |
| return _attributes; |
| } |
| |
| public void addAttribute(Attribute attribute) { |
| ensureAttributes(); |
| _attributes.add(attribute); |
| } |
| |
| public Attribute getAttribute(QName name) { |
| for (Attribute value : _attributes) { |
| if (value.getName().equals(name)) { |
| return value; |
| } |
| } |
| return null; |
| } |
| |
| private void ensureAttributes() { |
| if (_attributes == null) { |
| _attributes = new ArrayList<>(); |
| } |
| } |
| |
| public boolean isComplexType() { |
| return (_kind == COMPLEX_TYPE_COMPLEX_CONTENT || |
| _kind == COMPLEX_TYPE_MIXED_CONTENT || |
| _kind == COMPLEX_TYPE_SIMPLE_CONTENT); |
| } |
| |
| public boolean hasSimpleContent() { |
| return (_kind == SIMPLE_TYPE_SIMPLE_CONTENT || |
| _kind == COMPLEX_TYPE_SIMPLE_CONTENT); |
| } |
| |
| /** |
| * @return PARTICLE_SEQUENCE or PARTICLE_CHOICE_UNBOUNDED |
| */ |
| public int getTopParticleForComplexOrMixedContent() { |
| return _topParticleForComplexOrMixedContent; |
| } |
| |
| /** |
| * @param topParticleForComplexOrMixedContent PARTICLE_SEQUENCE or PARTICLE_CHOICE_UNBOUNDED |
| */ |
| public void setTopParticleForComplexOrMixedContent(int topParticleForComplexOrMixedContent) { |
| this._topParticleForComplexOrMixedContent = topParticleForComplexOrMixedContent; |
| } |
| |
| public boolean isGlobal() { |
| return _isGlobal; |
| } |
| |
| public void setGlobal(boolean isGlobal) { |
| assert isGlobal && getName() != null; |
| _isGlobal = isGlobal; |
| } |
| |
| public Type getExtensionType() { |
| return _extensionType; |
| } |
| |
| public void setExtensionType(Type extendedType) { |
| assert _kind == COMPLEX_TYPE_SIMPLE_CONTENT : "Extension used only for type which are COMPLEX_TYPE_SIMPLE_CONTENT"; |
| assert extendedType != null && extendedType.getName() != null : "Extended type must be a named type."; |
| _extensionType = extendedType; |
| } |
| |
| public List<String> getEnumerationValues() { |
| ensureEnumerationValues(); |
| return _enumerationValues; |
| } |
| |
| public List<QName> getEnumerationQNames() { |
| ensureEnumerationValues(); |
| return _enumerationQNames; |
| } |
| |
| public void addEnumerationValue(String enumerationValue, final XmlCursor xc) { |
| assert _kind == SIMPLE_TYPE_SIMPLE_CONTENT || _kind == COMPLEX_TYPE_SIMPLE_CONTENT : "Enumerations possible only on simple content"; |
| ensureEnumerationValues(); |
| if (_acceptsEnumerationValue && !_enumerationValues.contains(enumerationValue)) { |
| _enumerationValues.add(enumerationValue); |
| if (_name.equals(XmlQName.type.getName())) { |
| // check for QName |
| QName qname = XmlQNameImpl.validateLexical(enumerationValue, null, xc::namespaceForPrefix); |
| |
| assert qname != null : "The check for QName should allready have happened."; |
| _enumerationQNames.add(qname); |
| } |
| } |
| } |
| |
| private void ensureEnumerationValues() { |
| if (_enumerationValues == null) { |
| _enumerationValues = new ArrayList<>(); |
| _enumerationQNames = new ArrayList<>(); |
| } |
| } |
| |
| public boolean isEnumeration() { |
| return _acceptsEnumerationValue && _enumerationValues != null && _enumerationValues.size() > 1; |
| } |
| |
| public boolean isQNameEnumeration() { |
| return isEnumeration() && _name.equals(XmlQName.type.getName()) && _enumerationQNames != null && _enumerationQNames.size() > 1; |
| } |
| |
| public void closeEnumeration() { |
| _acceptsEnumerationValue = false; |
| } |
| |
| public String toString() { |
| return "Type{" + |
| "_name = " + _name + |
| ", _extensionType = " + _extensionType + |
| ", _kind = " + _kind + |
| ", _elements = " + _elements + |
| ", _attributes = " + _attributes + |
| "}"; |
| } |
| |
| public void addAllEnumerationsFrom(Type from) { |
| assert _kind == SIMPLE_TYPE_SIMPLE_CONTENT || _kind == COMPLEX_TYPE_SIMPLE_CONTENT : "Enumerations possible only on simple content"; |
| ensureEnumerationValues(); |
| |
| if (_name.equals(XmlQName.type.getName()) && from._name.equals(XmlQName.type.getName())) { |
| for (int i = 0; i < from.getEnumerationValues().size(); i++) { |
| String enumValue = from.getEnumerationValues().get(i); |
| QName enumQNameValue = from.getEnumerationQNames().get(i); |
| if (_acceptsEnumerationValue && !_enumerationQNames.contains(enumQNameValue)) { |
| _enumerationValues.add(enumValue); |
| _enumerationQNames.add(enumQNameValue); |
| } |
| } |
| } else { |
| for (int i = 0; i < from.getEnumerationValues().size(); i++) { |
| String enumValue = from.getEnumerationValues().get(i); |
| if (_acceptsEnumerationValue && !_enumerationValues.contains(enumValue)) { |
| _enumerationValues.add(enumValue); |
| } |
| } |
| } |
| } |
| } |