001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.xsom.impl;
027:
028: import com.sun.xml.internal.xsom.XSElementDecl;
029: import com.sun.xml.internal.xsom.XSIdentityConstraint;
030: import com.sun.xml.internal.xsom.XSModelGroup;
031: import com.sun.xml.internal.xsom.XSModelGroupDecl;
032: import com.sun.xml.internal.xsom.XSTerm;
033: import com.sun.xml.internal.xsom.XSType;
034: import com.sun.xml.internal.xsom.XSWildcard;
035: import com.sun.xml.internal.xsom.XmlString;
036: import com.sun.xml.internal.xsom.impl.parser.PatcherManager;
037: import com.sun.xml.internal.xsom.impl.parser.SchemaDocumentImpl;
038: import com.sun.xml.internal.xsom.visitor.XSFunction;
039: import com.sun.xml.internal.xsom.visitor.XSTermFunction;
040: import com.sun.xml.internal.xsom.visitor.XSTermFunctionWithParam;
041: import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
042: import com.sun.xml.internal.xsom.visitor.XSVisitor;
043: import org.xml.sax.Locator;
044:
045: import java.util.Collections;
046: import java.util.HashSet;
047: import java.util.List;
048: import java.util.Set;
049:
050: public class ElementDecl extends DeclarationImpl implements
051: XSElementDecl, Ref.Term {
052: public ElementDecl(PatcherManager reader, SchemaDocumentImpl owner,
053: AnnotationImpl _annon, Locator _loc,
054: ForeignAttributesImpl fa, String _tns, String _name,
055: boolean _anonymous,
056:
057: XmlString _defv, XmlString _fixedv, boolean _nillable,
058: boolean _abstract, Ref.Type _type, Ref.Element _substHead,
059: int _substDisallowed, int _substExcluded,
060: List<IdentityConstraintImpl> idConstraints) {
061:
062: super (owner, _annon, _loc, fa, _tns, _name, _anonymous);
063:
064: this .defaultValue = _defv;
065: this .fixedValue = _fixedv;
066: this .nillable = _nillable;
067: this ._abstract = _abstract;
068: this .type = _type;
069: this .substHead = _substHead;
070: this .substDisallowed = _substDisallowed;
071: this .substExcluded = _substExcluded;
072: this .idConstraints = Collections
073: .unmodifiableList((List<? extends XSIdentityConstraint>) idConstraints);
074:
075: for (IdentityConstraintImpl idc : idConstraints)
076: idc.setParent(this );
077:
078: if (type == null)
079: throw new IllegalArgumentException();
080: }
081:
082: private XmlString defaultValue;
083:
084: public XmlString getDefaultValue() {
085: return defaultValue;
086: }
087:
088: private XmlString fixedValue;
089:
090: public XmlString getFixedValue() {
091: return fixedValue;
092: }
093:
094: private boolean nillable;
095:
096: public boolean isNillable() {
097: return nillable;
098: }
099:
100: private boolean _abstract;
101:
102: public boolean isAbstract() {
103: return _abstract;
104: }
105:
106: private Ref.Type type;
107:
108: public XSType getType() {
109: return type.getType();
110: }
111:
112: private Ref.Element substHead;
113:
114: public XSElementDecl getSubstAffiliation() {
115: if (substHead == null)
116: return null;
117: return substHead.get();
118: }
119:
120: private int substDisallowed;
121:
122: public boolean isSubstitutionDisallowed(int method) {
123: return (substDisallowed & method) != 0;
124: }
125:
126: private int substExcluded;
127:
128: public boolean isSubstitutionExcluded(int method) {
129: return (substExcluded & method) != 0;
130: }
131:
132: private final List<XSIdentityConstraint> idConstraints;
133:
134: public List<XSIdentityConstraint> getIdentityConstraints() {
135: return idConstraints;
136: }
137:
138: /**
139: * @deprecated
140: */
141: public XSElementDecl[] listSubstitutables() {
142: Set<? extends XSElementDecl> s = getSubstitutables();
143: return s.toArray(new XSElementDecl[s.size()]);
144: }
145:
146: /** Set that represents element decls that can substitute this element. */
147: private Set<XSElementDecl> substitutables = null;
148:
149: /** Unmodifieable view of {@link #substitutables}. */
150: private Set<XSElementDecl> substitutablesView = null;
151:
152: public Set<? extends XSElementDecl> getSubstitutables() {
153: if (substitutables == null) {
154: // if the field is null by the time this method
155: // is called, it means this element is substitutable by itself only.
156: substitutables = substitutablesView = Collections
157: .singleton((XSElementDecl) this );
158: }
159: return substitutablesView;
160: }
161:
162: protected void addSubstitutable(ElementDecl decl) {
163: if (substitutables == null) {
164: substitutables = new HashSet<XSElementDecl>();
165: substitutables.add(this );
166: substitutablesView = Collections
167: .unmodifiableSet(substitutables);
168: }
169: substitutables.add(decl);
170: }
171:
172: public void updateSubstitutabilityMap() {
173: ElementDecl parent = this ;
174: XSType type = this .getType();
175:
176: boolean rused = false;
177: boolean eused = false;
178:
179: while ((parent = (ElementDecl) parent.getSubstAffiliation()) != null) {
180:
181: if (parent.isSubstitutionDisallowed(XSType.SUBSTITUTION))
182: continue;
183:
184: boolean rd = parent
185: .isSubstitutionDisallowed(XSType.RESTRICTION);
186: boolean ed = parent
187: .isSubstitutionDisallowed(XSType.EXTENSION);
188:
189: if ((rd && rused) || (ed && eused))
190: continue;
191:
192: XSType parentType = parent.getType();
193: while (type != parentType) {
194: if (type.getDerivationMethod() == XSType.RESTRICTION)
195: rused = true;
196: else
197: eused = true;
198:
199: type = type.getBaseType();
200: if (type == null) // parentType and type doesn't share the common base type. a bug in the schema.
201: break;
202:
203: if (type.isComplexType()) {
204: rd |= type.asComplexType()
205: .isSubstitutionProhibited(
206: XSType.RESTRICTION);
207: ed |= type.asComplexType()
208: .isSubstitutionProhibited(XSType.EXTENSION);
209: }
210: }
211:
212: if ((rd && rused) || (ed && eused))
213: continue;
214:
215: // this element can substitute "parent"
216: parent.addSubstitutable(this );
217: }
218: }
219:
220: public boolean canBeSubstitutedBy(XSElementDecl e) {
221: return getSubstitutables().contains(e);
222: }
223:
224: public boolean isWildcard() {
225: return false;
226: }
227:
228: public boolean isModelGroupDecl() {
229: return false;
230: }
231:
232: public boolean isModelGroup() {
233: return false;
234: }
235:
236: public boolean isElementDecl() {
237: return true;
238: }
239:
240: public XSWildcard asWildcard() {
241: return null;
242: }
243:
244: public XSModelGroupDecl asModelGroupDecl() {
245: return null;
246: }
247:
248: public XSModelGroup asModelGroup() {
249: return null;
250: }
251:
252: public XSElementDecl asElementDecl() {
253: return this ;
254: }
255:
256: public void visit(XSVisitor visitor) {
257: visitor.elementDecl(this );
258: }
259:
260: public void visit(XSTermVisitor visitor) {
261: visitor.elementDecl(this );
262: }
263:
264: public Object apply(XSTermFunction function) {
265: return function.elementDecl(this );
266: }
267:
268: public <T, P> T apply(XSTermFunctionWithParam<T, P> function,
269: P param) {
270: return function.elementDecl(this , param);
271: }
272:
273: public Object apply(XSFunction function) {
274: return function.elementDecl(this );
275: }
276:
277: // Ref.Term implementation
278: public XSTerm getTerm() {
279: return this;
280: }
281: }
|