1 /*
2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3  */
4 /*
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * The ASF licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  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 import com.sun.org.apache.xerces.internal.xs.XSValue;
38 
39 /**
40  * The XML representation for an element declaration
41  * schema component is an <element> element information item
42  *
43  * @xerces.internal
44  *
45  * @author Elena Litani, IBM
46  * @author Sandy Gao, IBM
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
setConstraintType(short constraintType)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     }
setIsNillable()96     public void setIsNillable() {
97         fMiscFlags |= NILLABLE;
98     }
setIsAbstract()99     public void setIsAbstract() {
100         fMiscFlags |= ABSTRACT;
101     }
setIsGlobal()102     public void setIsGlobal() {
103         fScope = SCOPE_GLOBAL;
104     }
setIsLocal(XSComplexTypeDecl enclosingCT)105     public void setIsLocal(XSComplexTypeDecl enclosingCT) {
106         fScope = SCOPE_LOCAL;
107         fEnclosingCT = enclosingCT;
108     }
109 
addIDConstraint(IdentityConstraint idc)110     public void addIDConstraint(IdentityConstraint idc) {
111         if (fIDCPos == fIDConstraints.length) {
112             fIDConstraints = resize(fIDConstraints, fIDCPos*2);
113         }
114         fIDConstraints[fIDCPos++] = idc;
115     }
116 
getIDConstraints()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 
resize(IdentityConstraint[] oldArray, int newSize)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;
toString()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      */
hashCode()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      */
equals(Object o)170     public boolean equals(Object o) {
171         return o == this;
172     }
173 
174     /**
175       * Reset current element declaration
176       */
reset()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      */
getType()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      */
getName()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      */
getNamespace()217     public String getNamespace() {
218         return fTargetNamespace;
219     }
220 
221     /**
222      * Either a simple type definition or a complex type definition.
223      */
getTypeDefinition()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      */
getScope()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      */
getEnclosingCTDefinition()244     public XSComplexTypeDefinition getEnclosingCTDefinition() {
245         return fEnclosingCT;
246     }
247 
248     /**
249      * A value constraint: one of default, fixed.
250      */
getConstraintType()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     @Deprecated
getConstraintValue()260     public String getConstraintValue() {
261         // REVISIT: SCAPI: what's the proper representation
262         return getConstraintType() == XSConstants.VC_NONE ?
263                null :
264                fDefault.stringValue();
265     }
266 
267     /**
268      * If {nillable} is true, then an element may also be valid if it carries
269      * the namespace qualified attribute with [local name] nil from
270      * namespace http://www.w3.org/2001/XMLSchema-instance and value true
271      * (see xsi:nil (2.6.2)) even if it has no text or element content
272      * despite a {content type} which would otherwise require content.
273      */
getNillable()274     public boolean getNillable() {
275         return ((fMiscFlags & NILLABLE) != 0);
276     }
277 
278     /**
279      * {identity-constraint definitions} A set of constraint definitions.
280      */
getIdentityConstraints()281     public XSNamedMap getIdentityConstraints() {
282         return new XSNamedMapImpl(fIDConstraints, fIDCPos);
283     }
284 
285     /**
286      * {substitution group affiliation} Optional. A top-level element
287      * definition.
288      */
getSubstitutionGroupAffiliation()289     public XSElementDeclaration getSubstitutionGroupAffiliation() {
290         return fSubGroup;
291     }
292 
293     /**
294      * Convenience method. Check if <code>exclusion</code> is a substitution
295      * group exclusion for this element declaration.
296      * @param exclusion Extension, restriction or none. Represents final
297      *   set for the element.
298      * @return True if <code>exclusion</code> is a part of the substitution
299      *   group exclusion subset.
300      */
isSubstitutionGroupExclusion(short exclusion)301     public boolean isSubstitutionGroupExclusion(short exclusion) {
302         return (fFinal & exclusion) != 0;
303     }
304 
305     /**
306      * Specifies if this declaration can be nominated as
307      * the {substitution group affiliation} of other
308      * element declarations having the same {type definition}
309      * or types derived therefrom.
310      *
311      * @return A bit flag representing {extension, restriction} or NONE.
312      */
getSubstitutionGroupExclusions()313     public short getSubstitutionGroupExclusions() {
314         return fFinal;
315     }
316 
317     /**
318      * Convenience method. Check if <code>disallowed</code> is a disallowed
319      * substitution for this element declaration.
320      * @param disallowed Substitution, extension, restriction or none.
321      *   Represents a block set for the element.
322      * @return True if <code>disallowed</code> is a part of the substitution
323      *   group exclusion subset.
324      */
isDisallowedSubstitution(short disallowed)325     public boolean isDisallowedSubstitution(short disallowed) {
326         return (fBlock & disallowed) != 0;
327     }
328 
329     /**
330      * The supplied values for {disallowed substitutions}
331      *
332      * @return A bit flag representing {substitution, extension, restriction} or NONE.
333      */
getDisallowedSubstitutions()334     public short getDisallowedSubstitutions() {
335         return fBlock;
336     }
337 
338     /**
339      * {abstract} A boolean.
340      */
getAbstract()341     public boolean getAbstract() {
342         return ((fMiscFlags & ABSTRACT) != 0);
343     }
344 
345     /**
346      * Optional. Annotation.
347      */
getAnnotation()348     public XSAnnotation getAnnotation() {
349         return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null;
350     }
351 
352     /**
353      * Optional. Annotations.
354      */
getAnnotations()355     public XSObjectList getAnnotations() {
356         return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
357     }
358 
359 
360     /**
361      * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
362      */
getNamespaceItem()363     public XSNamespaceItem getNamespaceItem() {
364         return fNamespaceItem;
365     }
366 
setNamespaceItem(XSNamespaceItem namespaceItem)367     void setNamespaceItem(XSNamespaceItem namespaceItem) {
368         fNamespaceItem = namespaceItem;
369     }
370 
371     @Deprecated
getActualVC()372     public Object getActualVC() {
373         return getConstraintType() == XSConstants.VC_NONE ?
374                null :
375                fDefault.actualValue;
376     }
377 
378     @Deprecated
getActualVCType()379     public short getActualVCType() {
380         return getConstraintType() == XSConstants.VC_NONE ?
381                XSConstants.UNAVAILABLE_DT :
382                fDefault.actualValueType;
383     }
384 
385     @Deprecated
getItemValueTypes()386     public ShortList getItemValueTypes() {
387         return getConstraintType() == XSConstants.VC_NONE ?
388                null :
389                fDefault.itemValueTypes;
390     }
391 
getValueConstraintValue()392     public XSValue getValueConstraintValue() {
393         return fDefault;
394     }
395 
396 } // class XSElementDecl
397