KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > xs > traversers > XSDAbstractParticleTraverser


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.xs.traversers;
18
19 import org.apache.xerces.impl.xs.SchemaGrammar;
20 import org.apache.xerces.impl.xs.SchemaSymbols;
21 import org.apache.xerces.impl.xs.XSAnnotationImpl;
22 import org.apache.xerces.impl.xs.XSModelGroupImpl;
23 import org.apache.xerces.impl.xs.XSParticleDecl;
24 import org.apache.xerces.impl.xs.util.XInt;
25 import org.apache.xerces.util.DOMUtil;
26 import org.apache.xerces.xs.XSObject;
27 import org.w3c.dom.Element JavaDoc;
28
29 /**
30  * @xerces.internal
31  *
32  * @author Elena Litani, IBM
33  * @author Sandy Gao, IBM
34  * @version $Id: XSDAbstractParticleTraverser.java,v 1.20 2004/12/20 05:43:36 mrglavas Exp $
35  */

36 abstract class XSDAbstractParticleTraverser extends XSDAbstractTraverser {
37     
38     XSDAbstractParticleTraverser (XSDHandler handler,
39             XSAttributeChecker gAttrCheck) {
40         super(handler, gAttrCheck);
41     }
42     
43     /**
44      *
45      * Traverse the "All" declaration
46      *
47      * <all
48      * id = ID
49      * maxOccurs = 1 : 1
50      * minOccurs = (0 | 1) : 1>
51      * Content: (annotation? , element*)
52      * </all>
53      **/

54     XSParticleDecl traverseAll(Element JavaDoc allDecl,
55             XSDocumentInfo schemaDoc,
56             SchemaGrammar grammar,
57             int allContextFlags,
58             XSObject parent) {
59         
60         // General Attribute Checking
61

62         Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(allDecl, false, schemaDoc);
63         
64         Element JavaDoc child = DOMUtil.getFirstChildElement(allDecl);
65         
66         XSAnnotationImpl annotation = null;
67         if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
68             annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
69             child = DOMUtil.getNextSiblingElement(child);
70         }
71         else {
72             String JavaDoc text = DOMUtil.getSyntheticAnnotation(allDecl);
73             if (text != null) {
74                 annotation = traverseSyntheticAnnotation(allDecl, text, attrValues, false, schemaDoc);
75             }
76         }
77         String JavaDoc childName = null;
78         XSParticleDecl particle;
79         fPArray.pushContext();
80         
81         for (; child != null; child = DOMUtil.getNextSiblingElement(child)) {
82             
83             particle = null;
84             childName = DOMUtil.getLocalName(child);
85             
86             // Only elements are allowed in <all>
87
if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
88                 particle = fSchemaHandler.fElementTraverser.traverseLocal(child, schemaDoc, grammar, PROCESSING_ALL_EL, parent);
89             }
90             else {
91                 Object JavaDoc[] args = {"all", "(annotation?, element*)", DOMUtil.getLocalName(child)};
92                 reportSchemaError("s4s-elt-must-match.1", args, child);
93             }
94             
95             if (particle != null)
96                 fPArray.addParticle(particle);
97         }
98         
99         particle = null;
100         XInt minAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
101         XInt maxAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
102         Long JavaDoc defaultVals = (Long JavaDoc)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
103         
104         XSModelGroupImpl group = new XSModelGroupImpl();
105         group.fCompositor = XSModelGroupImpl.MODELGROUP_ALL;
106         group.fParticleCount = fPArray.getParticleCount();
107         group.fParticles = fPArray.popContext();
108         group.fAnnotation = annotation;
109         particle = new XSParticleDecl();
110         particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
111         particle.fMinOccurs = minAtt.intValue();
112         particle.fMaxOccurs = maxAtt.intValue();
113         particle.fValue = group;
114         
115         particle = checkOccurrences(particle,
116                 SchemaSymbols.ELT_ALL,
117                 (Element JavaDoc)allDecl.getParentNode(),
118                 allContextFlags,
119                 defaultVals.longValue());
120         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
121         
122         return particle;
123     }
124     
125     /**
126      * Traverse the Sequence declaration
127      *
128      * <sequence
129      * id = ID
130      * maxOccurs = string
131      * minOccurs = nonNegativeInteger>
132      * Content: (annotation? , (element | group | choice | sequence | any)*)
133      * </sequence>
134      *
135      * @param seqDecl
136      * @param schemaDoc
137      * @param grammar
138      * @return
139      */

140     XSParticleDecl traverseSequence(Element JavaDoc seqDecl,
141             XSDocumentInfo schemaDoc,
142             SchemaGrammar grammar,
143             int allContextFlags,
144             XSObject parent) {
145         
146         return traverseSeqChoice(seqDecl, schemaDoc, grammar, allContextFlags, false, parent);
147     }
148     
149     /**
150      * Traverse the Choice declaration
151      *
152      * <choice
153      * id = ID
154      * maxOccurs = string
155      * minOccurs = nonNegativeInteger>
156      * Content: (annotation? , (element | group | choice | sequence | any)*)
157      * </choice>
158      *
159      * @param choiceDecl
160      * @param schemaDoc
161      * @param grammar
162      * @return
163      */

164     XSParticleDecl traverseChoice(Element JavaDoc choiceDecl,
165             XSDocumentInfo schemaDoc,
166             SchemaGrammar grammar,
167             int allContextFlags,
168             XSObject parent) {
169         
170         return traverseSeqChoice (choiceDecl, schemaDoc, grammar, allContextFlags, true, parent);
171     }
172     
173     /**
174      * Common traversal for <choice> and <sequence>
175      *
176      * @param decl
177      * @param schemaDoc
178      * @param grammar
179      * @param choice If traversing <choice> this parameter is true.
180      * @return
181      */

182     private XSParticleDecl traverseSeqChoice(Element JavaDoc decl,
183             XSDocumentInfo schemaDoc,
184             SchemaGrammar grammar,
185             int allContextFlags,
186             boolean choice,
187             XSObject parent) {
188         
189         // General Attribute Checking
190
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(decl, false, schemaDoc);
191         
192         Element JavaDoc child = DOMUtil.getFirstChildElement(decl);
193         XSAnnotationImpl annotation = null;
194         if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
195             annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
196             child = DOMUtil.getNextSiblingElement(child);
197         }
198         else {
199             String JavaDoc text = DOMUtil.getSyntheticAnnotation(decl);
200             if (text != null) {
201                 annotation = traverseSyntheticAnnotation(decl, text, attrValues, false, schemaDoc);
202             }
203         }
204         
205         boolean hadContent = false;
206         String JavaDoc childName = null;
207         XSParticleDecl particle;
208         fPArray.pushContext();
209         
210         for (;child != null;child = DOMUtil.getNextSiblingElement(child)) {
211             
212             particle = null;
213             
214             childName = DOMUtil.getLocalName(child);
215             if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
216                 particle = fSchemaHandler.fElementTraverser.traverseLocal(child, schemaDoc, grammar, NOT_ALL_CONTEXT, parent);
217             }
218             else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
219                 particle = fSchemaHandler.fGroupTraverser.traverseLocal(child, schemaDoc, grammar);
220                 
221                 // A content type of all can only appear
222
// as the content type of a complex type definition.
223
if (hasAllContent(particle)) {
224                     // don't insert the "all" particle, otherwise we won't be
225
// able to create DFA from this content model
226
particle = null;
227                     reportSchemaError("cos-all-limited.1.2", null, child);
228                 }
229                 
230             }
231             else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
232                 particle = traverseChoice(child, schemaDoc, grammar, NOT_ALL_CONTEXT, parent);
233             }
234             else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
235                 particle = traverseSequence(child, schemaDoc, grammar, NOT_ALL_CONTEXT, parent);
236             }
237             else if (childName.equals(SchemaSymbols.ELT_ANY)) {
238                 particle = fSchemaHandler.fWildCardTraverser.traverseAny(child, schemaDoc, grammar);
239             }
240             else {
241                 Object JavaDoc [] args;
242                 if (choice) {
243                     args = new Object JavaDoc[]{"choice", "(annotation?, (element | group | choice | sequence | any)*)", DOMUtil.getLocalName(child)};
244                 }
245                 else {
246                     args = new Object JavaDoc[]{"sequence", "(annotation?, (element | group | choice | sequence | any)*)", DOMUtil.getLocalName(child)};
247                 }
248                 reportSchemaError("s4s-elt-must-match.1", args, child);
249             }
250             
251             if (particle != null)
252                 fPArray.addParticle(particle);
253         }
254         
255         particle = null;
256         
257         XInt minAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
258         XInt maxAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
259         Long JavaDoc defaultVals = (Long JavaDoc)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
260         
261         XSModelGroupImpl group = new XSModelGroupImpl();
262         group.fCompositor = choice ? XSModelGroupImpl.MODELGROUP_CHOICE : XSModelGroupImpl.MODELGROUP_SEQUENCE;
263         group.fParticleCount = fPArray.getParticleCount();
264         group.fParticles = fPArray.popContext();
265         group.fAnnotation = annotation;
266         particle = new XSParticleDecl();
267         particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
268         particle.fMinOccurs = minAtt.intValue();
269         particle.fMaxOccurs = maxAtt.intValue();
270         particle.fValue = group;
271         
272         particle = checkOccurrences(particle,
273                 choice ? SchemaSymbols.ELT_CHOICE : SchemaSymbols.ELT_SEQUENCE,
274                         (Element JavaDoc)decl.getParentNode(),
275                         allContextFlags,
276                         defaultVals.longValue());
277         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
278         
279         return particle;
280     }
281     
282     // Determines whether a content spec tree represents an "all" content model
283
protected boolean hasAllContent(XSParticleDecl particle) {
284         // If the content is not empty, is the top node ALL?
285
if (particle != null && particle.fType == XSParticleDecl.PARTICLE_MODELGROUP) {
286             return ((XSModelGroupImpl)particle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL;
287         }
288         
289         return false;
290     }
291     
292     // the inner class: used to store particles for model groups
293
// to avoid creating a new Vector in each model group, or when traversing
294
// each model group, we use this one big array to store all particles
295
// for model groups. when the traversal finishes, this class returns an
296
// XSParticleDecl[] containing all particles for the current model group.
297
// it's possible that we need to traverse another model group while
298
// traversing one (one inside another one; referring to a global group,
299
// etc.), so we have push/pos context methods to save the same of the
300
// current traversal before starting the traversal of another model group.
301
protected static class ParticleArray {
302         // big array to contain all particles
303
XSParticleDecl[] fParticles = new XSParticleDecl[10];
304         // the ending position of particles in the array for each context
305
// index 0 is reserved, with value 0. index 1 is used for the fist
306
// context. so that the number of particles for context 'i' can be
307
// computed simply by fPos[i] - fPos[i-1].
308
int[] fPos = new int[5];
309         // number of contexts
310
int fContextCount = 0;
311         
312         // start a new context (start traversing a new model group)
313
void pushContext() {
314             fContextCount++;
315             // resize position array if necessary
316
if (fContextCount == fPos.length) {
317                 int newSize = fContextCount * 2;
318                 int[] newArray = new int[newSize];
319                 System.arraycopy(fPos, 0, newArray, 0, fContextCount);
320                 fPos = newArray;
321             }
322             // the initial ending position of the current context is the
323
// ending position of the previsous context. which means there is
324
// no particle for the current context yet.
325
fPos[fContextCount] = fPos[fContextCount-1];
326         }
327         
328         // get the number of particles of this context (model group)
329
int getParticleCount() {
330             return fPos[fContextCount] - fPos[fContextCount-1];
331         }
332         
333         // add a particle to the current context
334
void addParticle(XSParticleDecl particle) {
335             // resize the particle array if necessary
336
if (fPos[fContextCount] == fParticles.length) {
337                 int newSize = fPos[fContextCount] * 2;
338                 XSParticleDecl[] newArray = new XSParticleDecl[newSize];
339                 System.arraycopy(fParticles, 0, newArray, 0, fPos[fContextCount]);
340                 fParticles = newArray;
341             }
342             fParticles[fPos[fContextCount]++] = particle;
343         }
344         
345         // end the current context, and return an array of particles
346
XSParticleDecl[] popContext() {
347             int count = fPos[fContextCount] - fPos[fContextCount-1];
348             XSParticleDecl[] array = null;
349             if (count != 0) {
350                 array = new XSParticleDecl[count];
351                 System.arraycopy(fParticles, fPos[fContextCount-1], array, 0, count);
352                 // clear the particle array, to release memory
353
for (int i = fPos[fContextCount-1]; i < fPos[fContextCount]; i++)
354                     fParticles[i] = null;
355             }
356             fContextCount--;
357             return array;
358         }
359         
360     }
361     
362     // the big particle array to hold all particles in model groups
363
ParticleArray fPArray = new ParticleArray();
364 }
365
Popular Tags