View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2002,2003-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.xs.util.XSObjectListImpl;
24  import com.sun.org.apache.xerces.internal.xs.XSAnnotation;
25  import com.sun.org.apache.xerces.internal.xs.XSConstants;
26  import com.sun.org.apache.xerces.internal.xs.XSModelGroup;
27  import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
28  import com.sun.org.apache.xerces.internal.xs.XSObjectList;
29  
30  /**
31   * Store schema model group declaration.
32   *
33   * @xerces.internal
34   *
35   * @author Sandy Gao, IBM
36   *
37   * @version $Id: XSModelGroupImpl.java,v 1.7 2010-11-01 04:39:55 joehw Exp $
38   */
39  public class XSModelGroupImpl implements XSModelGroup {
40  
41      // types of model groups
42      // REVISIT: can't use same constants as those for particles, because
43      // there are place where the constants are used together. For example,
44      // to check whether the content is an element or a sequence.
45      public static final short MODELGROUP_CHOICE       = 101;
46      public static final short MODELGROUP_SEQUENCE     = 102;
47      public static final short MODELGROUP_ALL          = 103;
48  
49      // compositor of the model group
50      public short fCompositor;
51  
52      // particles
53      public XSParticleDecl[] fParticles = null;
54      public int fParticleCount = 0;
55  
56      // this particle's optional annotations
57      public XSObjectList fAnnotations = null;
58  
59      // whether this model group contains nothing
60      public boolean isEmpty() {
61          for (int i = 0; i < fParticleCount; i++) {
62              if (!fParticles[i].isEmpty())
63                  return false;
64          }
65          return true;
66      }
67  
68      /**
69       * 3.8.6 Effective Total Range (all and sequence) and
70       *       Effective Total Range (choice)
71       * The following methods are used to return min/max range for a particle.
72       * They are not exactly the same as it's described in the spec, but all the
73       * values from the spec are retrievable by these methods.
74       */
75      public int minEffectiveTotalRange() {
76          if (fCompositor == MODELGROUP_CHOICE)
77              return minEffectiveTotalRangeChoice();
78          else
79              return minEffectiveTotalRangeAllSeq();
80      }
81  
82      // return the sum of all min values of the particles
83      private int minEffectiveTotalRangeAllSeq() {
84          int total = 0;
85          for (int i = 0; i < fParticleCount; i++)
86              total += fParticles[i].minEffectiveTotalRange();
87          return total;
88      }
89  
90      // return the min of all min values of the particles
91      private int minEffectiveTotalRangeChoice() {
92          int min = 0, one;
93          if (fParticleCount > 0)
94              min = fParticles[0].minEffectiveTotalRange();
95  
96          for (int i = 1; i < fParticleCount; i++) {
97              one = fParticles[i].minEffectiveTotalRange();
98              if (one < min)
99                  min = one;
100         }
101 
102         return min;
103     }
104 
105     public int maxEffectiveTotalRange() {
106         if (fCompositor == MODELGROUP_CHOICE)
107             return maxEffectiveTotalRangeChoice();
108         else
109             return maxEffectiveTotalRangeAllSeq();
110     }
111 
112     // if one of the max value of the particles is unbounded, return unbounded;
113     // otherwise return the sum of all max values
114     private int maxEffectiveTotalRangeAllSeq() {
115         int total = 0, one;
116         for (int i = 0; i < fParticleCount; i++) {
117             one = fParticles[i].maxEffectiveTotalRange();
118             if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED)
119                 return SchemaSymbols.OCCURRENCE_UNBOUNDED;
120             total += one;
121         }
122         return total;
123     }
124 
125     // if one of the max value of the particles is unbounded, return unbounded;
126     // otherwise return the max of all max values
127     private int maxEffectiveTotalRangeChoice() {
128         int max = 0, one;
129         if (fParticleCount > 0) {
130             max = fParticles[0].maxEffectiveTotalRange();
131             if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
132                 return SchemaSymbols.OCCURRENCE_UNBOUNDED;
133         }
134 
135         for (int i = 1; i < fParticleCount; i++) {
136             one = fParticles[i].maxEffectiveTotalRange();
137             if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED)
138                 return SchemaSymbols.OCCURRENCE_UNBOUNDED;
139             if (one > max)
140                 max = one;
141         }
142         return max;
143     }
144 
145     /**
146      * get the string description of this particle
147      */
148     private String fDescription = null;
149     public String toString() {
150         // REVISIT: Commented code may help to eliminate redundant parentheses (test first before committing)
151         if (fDescription == null) {
152             StringBuffer buffer = new StringBuffer();
153             if (fCompositor == MODELGROUP_ALL)
154                 buffer.append("all(");
155             else  //if (fMinOccurs != 1 || fMaxOccurs != 1)
156                 buffer.append('(');
157             if (fParticleCount > 0)
158                 buffer.append(fParticles[0].toString());
159             for (int i = 1; i < fParticleCount; i++) {
160                 if (fCompositor == MODELGROUP_CHOICE)
161                     buffer.append('|');
162                 else
163                     buffer.append(',');
164                 buffer.append(fParticles[i].toString());
165             }
166             //if (fCompositor == MODELGROUP_ALL || fMinOccurs != 1 || fMaxOccurs != 1)
167                   buffer.append(')');
168             fDescription = buffer.toString();
169         }
170         return fDescription;
171     }
172 
173     public void reset(){
174         fCompositor = MODELGROUP_SEQUENCE;
175         fParticles = null;
176         fParticleCount = 0;
177         fDescription = null;
178         fAnnotations = null;
179     }
180 
181     /**
182      * Get the type of the object, i.e ELEMENT_DECLARATION.
183      */
184     public short getType() {
185         return XSConstants.MODEL_GROUP;
186     }
187 
188     /**
189      * The <code>name</code> of this <code>XSObject</code> depending on the
190      * <code>XSObject</code> type.
191      */
192     public String getName() {
193         return null;
194     }
195 
196     /**
197      * The namespace URI of this node, or <code>null</code> if it is
198      * unspecified.  defines how a namespace URI is attached to schema
199      * components.
200      */
201     public String getNamespace() {
202         return null;
203     }
204 
205     /**
206      * {compositor} One of all, choice or sequence. The valid constants values
207      * are: ALL, CHOICE, SEQUENCE.
208      */
209     public short getCompositor() {
210         if (fCompositor == MODELGROUP_CHOICE)
211             return XSModelGroup.COMPOSITOR_CHOICE;
212         else if (fCompositor == MODELGROUP_SEQUENCE)
213             return XSModelGroup.COMPOSITOR_SEQUENCE;
214         else
215             return XSModelGroup.COMPOSITOR_ALL;
216     }
217 
218     /**
219      * {particles} A list of particles
220      */
221     public XSObjectList getParticles() {
222         return new XSObjectListImpl(fParticles, fParticleCount);
223     }
224 
225     /**
226      * Optional. Annotation.
227      */
228     public XSAnnotation getAnnotation() {
229         return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null;
230     }
231 
232     /**
233      * Optional. Annotations.
234      */
235     public XSObjectList getAnnotations() {
236         return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
237     }
238 
239     /**
240      * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
241      */
242     public XSNamespaceItem getNamespaceItem() {
243         return null;
244     }
245 
246 } // class XSModelGroupImpl