001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: package com.sun.xml.xsom.impl;
021:
022: import com.sun.xml.xsom.XSElementDecl;
023: import com.sun.xml.xsom.XSIdentityConstraint;
024: import com.sun.xml.xsom.XSModelGroup;
025: import com.sun.xml.xsom.XSModelGroupDecl;
026: import com.sun.xml.xsom.XSTerm;
027: import com.sun.xml.xsom.XSType;
028: import com.sun.xml.xsom.XSWildcard;
029: import com.sun.xml.xsom.XmlString;
030: import com.sun.xml.xsom.impl.parser.PatcherManager;
031: import com.sun.xml.xsom.impl.parser.SchemaDocumentImpl;
032: import com.sun.xml.xsom.visitor.XSFunction;
033: import com.sun.xml.xsom.visitor.XSTermFunction;
034: import com.sun.xml.xsom.visitor.XSTermFunctionWithParam;
035: import com.sun.xml.xsom.visitor.XSTermVisitor;
036: import com.sun.xml.xsom.visitor.XSVisitor;
037: import org.xml.sax.Locator;
038:
039: import java.util.Collections;
040: import java.util.HashSet;
041: import java.util.List;
042: import java.util.Set;
043:
044: public class ElementDecl extends DeclarationImpl implements
045: XSElementDecl, Ref.Term {
046: public ElementDecl(PatcherManager reader, SchemaDocumentImpl owner,
047: AnnotationImpl _annon, Locator _loc,
048: ForeignAttributesImpl fa, String _tns, String _name,
049: boolean _anonymous,
050:
051: XmlString _defv, XmlString _fixedv, boolean _nillable,
052: boolean _abstract, Ref.Type _type, Ref.Element _substHead,
053: int _substDisallowed, int _substExcluded,
054: List<IdentityConstraintImpl> idConstraints) {
055:
056: super (owner, _annon, _loc, fa, _tns, _name, _anonymous);
057:
058: this .defaultValue = _defv;
059: this .fixedValue = _fixedv;
060: this .nillable = _nillable;
061: this ._abstract = _abstract;
062: this .type = _type;
063: this .substHead = _substHead;
064: this .substDisallowed = _substDisallowed;
065: this .substExcluded = _substExcluded;
066: this .idConstraints = Collections
067: .unmodifiableList((List<? extends XSIdentityConstraint>) idConstraints);
068:
069: for (IdentityConstraintImpl idc : idConstraints)
070: idc.setParent(this );
071:
072: if (type == null)
073: throw new IllegalArgumentException();
074: }
075:
076: private XmlString defaultValue;
077:
078: public XmlString getDefaultValue() {
079: return defaultValue;
080: }
081:
082: private XmlString fixedValue;
083:
084: public XmlString getFixedValue() {
085: return fixedValue;
086: }
087:
088: private boolean nillable;
089:
090: public boolean isNillable() {
091: return nillable;
092: }
093:
094: private boolean _abstract;
095:
096: public boolean isAbstract() {
097: return _abstract;
098: }
099:
100: private Ref.Type type;
101:
102: public XSType getType() {
103: return type.getType();
104: }
105:
106: private Ref.Element substHead;
107:
108: public XSElementDecl getSubstAffiliation() {
109: if (substHead == null)
110: return null;
111: return substHead.get();
112: }
113:
114: private int substDisallowed;
115:
116: public boolean isSubstitutionDisallowed(int method) {
117: return (substDisallowed & method) != 0;
118: }
119:
120: private int substExcluded;
121:
122: public boolean isSubstitutionExcluded(int method) {
123: return (substExcluded & method) != 0;
124: }
125:
126: private final List<XSIdentityConstraint> idConstraints;
127:
128: public List<XSIdentityConstraint> getIdentityConstraints() {
129: return idConstraints;
130: }
131:
132: /**
133: * @deprecated
134: */
135: public XSElementDecl[] listSubstitutables() {
136: Set<? extends XSElementDecl> s = getSubstitutables();
137: return s.toArray(new XSElementDecl[s.size()]);
138: }
139:
140: /** Set that represents element decls that can substitute this element. */
141: private Set<XSElementDecl> substitutables = null;
142:
143: /** Unmodifieable view of {@link #substitutables}. */
144: private Set<XSElementDecl> substitutablesView = null;
145:
146: public Set<? extends XSElementDecl> getSubstitutables() {
147: if (substitutables == null) {
148: // if the field is null by the time this method
149: // is called, it means this element is substitutable by itself only.
150: substitutables = substitutablesView = Collections
151: .singleton((XSElementDecl) this );
152: }
153: return substitutablesView;
154: }
155:
156: protected void addSubstitutable(ElementDecl decl) {
157: if (substitutables == null) {
158: substitutables = new HashSet<XSElementDecl>();
159: substitutables.add(this );
160: substitutablesView = Collections
161: .unmodifiableSet(substitutables);
162: }
163: substitutables.add(decl);
164: }
165:
166: public void updateSubstitutabilityMap() {
167: ElementDecl parent = this ;
168: XSType type = this .getType();
169:
170: boolean rused = false;
171: boolean eused = false;
172:
173: while ((parent = (ElementDecl) parent.getSubstAffiliation()) != null) {
174:
175: if (parent.isSubstitutionDisallowed(XSType.SUBSTITUTION))
176: continue;
177:
178: boolean rd = parent
179: .isSubstitutionDisallowed(XSType.RESTRICTION);
180: boolean ed = parent
181: .isSubstitutionDisallowed(XSType.EXTENSION);
182:
183: if ((rd && rused) || (ed && eused))
184: continue;
185:
186: XSType parentType = parent.getType();
187: while (type != parentType) {
188: if (type.getDerivationMethod() == XSType.RESTRICTION)
189: rused = true;
190: else
191: eused = true;
192:
193: type = type.getBaseType();
194: if (type == null) // parentType and type doesn't share the common base type. a bug in the schema.
195: break;
196:
197: if (type.isComplexType()) {
198: rd |= type.asComplexType()
199: .isSubstitutionProhibited(
200: XSType.RESTRICTION);
201: ed |= type.asComplexType()
202: .isSubstitutionProhibited(XSType.EXTENSION);
203: }
204: }
205:
206: if ((rd && rused) || (ed && eused))
207: continue;
208:
209: // this element can substitute "parent"
210: parent.addSubstitutable(this );
211: }
212: }
213:
214: public boolean canBeSubstitutedBy(XSElementDecl e) {
215: return getSubstitutables().contains(e);
216: }
217:
218: public boolean isWildcard() {
219: return false;
220: }
221:
222: public boolean isModelGroupDecl() {
223: return false;
224: }
225:
226: public boolean isModelGroup() {
227: return false;
228: }
229:
230: public boolean isElementDecl() {
231: return true;
232: }
233:
234: public XSWildcard asWildcard() {
235: return null;
236: }
237:
238: public XSModelGroupDecl asModelGroupDecl() {
239: return null;
240: }
241:
242: public XSModelGroup asModelGroup() {
243: return null;
244: }
245:
246: public XSElementDecl asElementDecl() {
247: return this ;
248: }
249:
250: public void visit(XSVisitor visitor) {
251: visitor.elementDecl(this );
252: }
253:
254: public void visit(XSTermVisitor visitor) {
255: visitor.elementDecl(this );
256: }
257:
258: public Object apply(XSTermFunction function) {
259: return function.elementDecl(this );
260: }
261:
262: public <T, P> T apply(XSTermFunctionWithParam<T, P> function,
263: P param) {
264: return function.elementDecl(this , param);
265: }
266:
267: public Object apply(XSFunction function) {
268: return function.elementDecl(this );
269: }
270:
271: // Ref.Term implementation
272: public XSTerm getTerm() {
273: return this;
274: }
275: }
|