View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package com.sun.org.apache.xerces.internal.impl.xs;
22  
23  import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
24  import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
25  import com.sun.org.apache.xerces.internal.impl.xs.util.XSNamedMapImpl;
26  import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
27  import com.sun.org.apache.xerces.internal.xni.QName;
28  import com.sun.org.apache.xerces.internal.xs.ShortList;
29  import com.sun.org.apache.xerces.internal.xs.XSAnnotation;
30  import com.sun.org.apache.xerces.internal.xs.XSComplexTypeDefinition;
31  import com.sun.org.apache.xerces.internal.xs.XSConstants;
32  import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration;
33  import com.sun.org.apache.xerces.internal.xs.XSNamedMap;
34  import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
35  import com.sun.org.apache.xerces.internal.xs.XSObjectList;
36  import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
37  
38  /**
39   * The XML representation for an element declaration
40   * schema component is an <element> element information item
41   *
42   * @xerces.internal
43   *
44   * @author Elena Litani, IBM
45   * @author Sandy Gao, IBM
46   * @version $Id: XSElementDecl.java,v 1.7 2010-11-01 04:39:55 joehw Exp $
47   */
48  public class XSElementDecl implements XSElementDeclaration {
49  
50      // scopes
51      public final static short     SCOPE_ABSENT        = 0;
52      public final static short     SCOPE_GLOBAL        = 1;
53      public final static short     SCOPE_LOCAL         = 2;
54  
55      // name of the element
56      public String fName = null;
57      // target namespace of the element
58      public String fTargetNamespace = null;
59      // type of the element
60      public XSTypeDefinition fType = null;
61      public QName fUnresolvedTypeName = null;
62      // misc flag of the element: nillable/abstract/fixed
63      short fMiscFlags = 0;
64      public short fScope = XSConstants.SCOPE_ABSENT;
65      // enclosing complex type, when the scope is local
66      XSComplexTypeDecl fEnclosingCT = null;
67      // block set (disallowed substitutions) of the element
68      public short fBlock = XSConstants.DERIVATION_NONE;
69      // final set (substitution group exclusions) of the element
70      public short fFinal = XSConstants.DERIVATION_NONE;
71      // optional annotation
72      public XSObjectList fAnnotations = null;
73      // value constraint value
74      public ValidatedInfo fDefault = null;
75      // the substitution group affiliation of the element
76      public XSElementDecl fSubGroup = null;
77      // identity constraints
78      static final int INITIAL_SIZE = 2;
79      int fIDCPos = 0;
80      IdentityConstraint[] fIDConstraints = new IdentityConstraint[INITIAL_SIZE];
81      // The namespace schema information item corresponding to the target namespace
82      // of the element declaration, if it is globally declared; or null otherwise.
83      private XSNamespaceItem fNamespaceItem = null;
84  
85      private static final short CONSTRAINT_MASK = 3;
86      private static final short NILLABLE        = 4;
87      private static final short ABSTRACT        = 8;
88  
89      // methods to get/set misc flag
90      public void setConstraintType(short constraintType) {
91          // first clear the bits
92          fMiscFlags ^= (fMiscFlags & CONSTRAINT_MASK);
93          // then set the proper one
94          fMiscFlags |= (constraintType & CONSTRAINT_MASK);
95      }
96      public void setIsNillable() {
97          fMiscFlags |= NILLABLE;
98      }
99      public void setIsAbstract() {
100         fMiscFlags |= ABSTRACT;
101     }
102     public void setIsGlobal() {
103         fScope = SCOPE_GLOBAL;
104     }
105     public void setIsLocal(XSComplexTypeDecl enclosingCT) {
106         fScope = SCOPE_LOCAL;
107         fEnclosingCT = enclosingCT;
108     }
109 
110     public void addIDConstraint(IdentityConstraint idc) {
111         if (fIDCPos == fIDConstraints.length) {
112             fIDConstraints = resize(fIDConstraints, fIDCPos*2);
113         }
114         fIDConstraints[fIDCPos++] = idc;
115     }
116 
117     public IdentityConstraint[] getIDConstraints() {
118         if (fIDCPos == 0) {
119             return null;
120         }
121         if (fIDCPos < fIDConstraints.length) {
122             fIDConstraints = resize(fIDConstraints, fIDCPos);
123         }
124         return fIDConstraints;
125     }
126 
127     static final IdentityConstraint[] resize(IdentityConstraint[] oldArray, int newSize) {
128         IdentityConstraint[] newArray = new IdentityConstraint[newSize];
129         System.arraycopy(oldArray, 0, newArray, 0, Math.min(oldArray.length, newSize));
130         return newArray;
131     }
132 
133     /**
134      * get the string description of this element
135      */
136     private String fDescription = null;
137     public String toString() {
138         if (fDescription == null) {
139             if (fTargetNamespace != null) {
140                 StringBuffer buffer = new StringBuffer(
141                     fTargetNamespace.length() +
142                     ((fName != null) ? fName.length() : 4) + 3);
143                 buffer.append('"');
144                 buffer.append(fTargetNamespace);
145                 buffer.append('"');
146                 buffer.append(':');
147                 buffer.append(fName);
148                 fDescription = buffer.toString();
149             }
150             else {
151                 fDescription = fName;
152             }
153         }
154         return fDescription;
155     }
156 
157     /**
158      * get the hash code
159      */
160     public int hashCode() {
161         int code = fName.hashCode();
162         if (fTargetNamespace != null)
163             code = (code<<16)+fTargetNamespace.hashCode();
164         return code;
165     }
166 
167     /**
168      * whether two decls are the same
169      */
170     public boolean equals(Object o) {
171         return o == this;
172     }
173 
174     /**
175       * Reset current element declaration
176       */
177     public void reset(){
178         fScope = XSConstants.SCOPE_ABSENT;
179         fName = null;
180         fTargetNamespace = null;
181         fType = null;
182         fUnresolvedTypeName = null;
183         fMiscFlags = 0;
184         fBlock = XSConstants.DERIVATION_NONE;
185         fFinal = XSConstants.DERIVATION_NONE;
186         fDefault = null;
187         fAnnotations = null;
188         fSubGroup = null;
189         // reset identity constraints
190         for (int i=0;i<fIDCPos;i++) {
191             fIDConstraints[i] = null;
192         }
193 
194         fIDCPos = 0;
195     }
196 
197     /**
198      * Get the type of the object, i.e ELEMENT_DECLARATION.
199      */
200     public short getType() {
201         return XSConstants.ELEMENT_DECLARATION;
202     }
203 
204     /**
205      * The <code>name</code> of this <code>XSObject</code> depending on the
206      * <code>XSObject</code> type.
207      */
208     public String getName() {
209         return fName;
210     }
211 
212     /**
213      * The namespace URI of this node, or <code>null</code> if it is
214      * unspecified.  defines how a namespace URI is attached to schema
215      * components.
216      */
217     public String getNamespace() {
218         return fTargetNamespace;
219     }
220 
221     /**
222      * Either a simple type definition or a complex type definition.
223      */
224     public XSTypeDefinition getTypeDefinition() {
225         return fType;
226     }
227 
228     /**
229      * Optional. Either global or a complex type definition (
230      * <code>ctDefinition</code>). This property is absent in the case of
231      * declarations within named model groups: their scope will be
232      * determined when they are used in the construction of complex type
233      * definitions.
234      */
235     public short getScope() {
236         return fScope;
237     }
238 
239     /**
240      * Locally scoped declarations are available for use only within the
241      * complex type definition identified by the <code>scope</code>
242      * property.
243      */
244     public XSComplexTypeDefinition getEnclosingCTDefinition() {
245         return fEnclosingCT;
246     }
247 
248     /**
249      * A value constraint: one of default, fixed.
250      */
251     public short getConstraintType() {
252         return (short)(fMiscFlags & CONSTRAINT_MASK);
253     }
254 
255     /**
256      * A value constraint: The actual value (with respect to the {type
257      * definition})
258      */
259     public String getConstraintValue() {
260         // REVISIT: SCAPI: what's the proper representation
261         return getConstraintType() == XSConstants.VC_NONE ?
262                null :
263                fDefault.stringValue();
264     }
265 
266     /**
267      * If {nillable} is true, then an element may also be valid if it carries
268      * the namespace qualified attribute with [local name] nil from
269      * namespace http://www.w3.org/2001/XMLSchema-instance and value true
270      * (see xsi:nil (2.6.2)) even if it has no text or element content
271      * despite a {content type} which would otherwise require content.
272      */
273     public boolean getNillable() {
274         return ((fMiscFlags & NILLABLE) != 0);
275     }
276 
277     /**
278      * {identity-constraint definitions} A set of constraint definitions.
279      */
280     public XSNamedMap getIdentityConstraints() {
281         return new XSNamedMapImpl(fIDConstraints, fIDCPos);
282     }
283 
284     /**
285      * {substitution group affiliation} Optional. A top-level element
286      * definition.
287      */
288     public XSElementDeclaration getSubstitutionGroupAffiliation() {
289         return fSubGroup;
290     }
291 
292     /**
293      * Convenience method. Check if <code>exclusion</code> is a substitution
294      * group exclusion for this element declaration.
295      * @param exclusion Extension, restriction or none. Represents final
296      *   set for the element.
297      * @return True if <code>exclusion</code> is a part of the substitution
298      *   group exclusion subset.
299      */
300     public boolean isSubstitutionGroupExclusion(short exclusion) {
301         return (fFinal & exclusion) != 0;
302     }
303 
304     /**
305      * Specifies if this declaration can be nominated as
306      * the {substitution group affiliation} of other
307      * element declarations having the same {type definition}
308      * or types derived therefrom.
309      *
310      * @return A bit flag representing {extension, restriction} or NONE.
311      */
312     public short getSubstitutionGroupExclusions() {
313         return fFinal;
314     }
315 
316     /**
317      * Convenience method. Check if <code>disallowed</code> is a disallowed
318      * substitution for this element declaration.
319      * @param disallowed Substitution, extension, restriction or none.
320      *   Represents a block set for the element.
321      * @return True if <code>disallowed</code> is a part of the substitution
322      *   group exclusion subset.
323      */
324     public boolean isDisallowedSubstitution(short disallowed) {
325         return (fBlock & disallowed) != 0;
326     }
327 
328     /**
329      * The supplied values for {disallowed substitutions}
330      *
331      * @return A bit flag representing {substitution, extension, restriction} or NONE.
332      */
333     public short getDisallowedSubstitutions() {
334         return fBlock;
335     }
336 
337     /**
338      * {abstract} A boolean.
339      */
340     public boolean getAbstract() {
341         return ((fMiscFlags & ABSTRACT) != 0);
342     }
343 
344     /**
345      * Optional. Annotation.
346      */
347     public XSAnnotation getAnnotation() {
348         return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null;
349     }
350 
351     /**
352      * Optional. Annotations.
353      */
354     public XSObjectList getAnnotations() {
355         return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
356     }
357 
358 
359     /**
360      * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
361      */
362     public XSNamespaceItem getNamespaceItem() {
363         return fNamespaceItem;
364     }
365 
366     void setNamespaceItem(XSNamespaceItem namespaceItem) {
367         fNamespaceItem = namespaceItem;
368     }
369 
370     public Object getActualVC() {
371         return getConstraintType() == XSConstants.VC_NONE ?
372                null :
373                fDefault.actualValue;
374     }
375 
376     public short getActualVCType() {
377         return getConstraintType() == XSConstants.VC_NONE ?
378                XSConstants.UNAVAILABLE_DT :
379                fDefault.actualValueType;
380     }
381 
382     public ShortList getItemValueTypes() {
383         return getConstraintType() == XSConstants.VC_NONE ?
384                null :
385                fDefault.itemValueTypes;
386     }
387 
388 } // class XSElementDecl