KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2004 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
59
60 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
61 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
62 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
63 import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
64 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
65 import com.sun.org.apache.xerces.internal.util.DOMUtil;
66 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
67 import com.sun.org.apache.xerces.internal.xs.XSObject;
68 import org.w3c.dom.Element JavaDoc;
69
70 /**
71  * @author Elena Litani, IBM
72  * @author Sandy Gao, IBM
73  * @version $Id: XSDAbstractParticleTraverser.java,v 1.16 2004/02/04 18:48:15 mrglavas Exp $
74  */

75 abstract class XSDAbstractParticleTraverser extends XSDAbstractTraverser {
76
77     XSDAbstractParticleTraverser (XSDHandler handler,
78                                   XSAttributeChecker gAttrCheck) {
79         super(handler, gAttrCheck);
80     }
81
82     /**
83      *
84      * Traverse the "All" declaration
85      *
86      * <all
87      * id = ID
88      * maxOccurs = 1 : 1
89      * minOccurs = (0 | 1) : 1>
90      * Content: (annotation? , element*)
91      * </all>
92      **/

93     XSParticleDecl traverseAll(Element JavaDoc allDecl,
94                                XSDocumentInfo schemaDoc,
95                                SchemaGrammar grammar,
96                                int allContextFlags,
97                                XSObject parent) {
98
99         // General Attribute Checking
100

101         Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(allDecl, false, schemaDoc);
102
103         Element JavaDoc child = DOMUtil.getFirstChildElement(allDecl);
104
105         XSAnnotationImpl annotation = null;
106         if (child !=null) {
107             // traverse Annotation
108
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
109                 annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
110                 child = DOMUtil.getNextSiblingElement(child);
111             }
112         }
113         String JavaDoc childName = null;
114         XSParticleDecl particle;
115         fPArray.pushContext();
116
117         for (; child != null; child = DOMUtil.getNextSiblingElement(child)) {
118
119             particle = null;
120             childName = DOMUtil.getLocalName(child);
121
122             // Only elements are allowed in <all>
123
if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
124                 particle = fSchemaHandler.fElementTraverser.traverseLocal(child, schemaDoc, grammar, PROCESSING_ALL_EL, parent);
125             }
126             else {
127                 Object JavaDoc[] args = {"all", "(annotation?, element*)", DOMUtil.getLocalName(child)};
128                 reportSchemaError("s4s-elt-must-match.1", args, child);
129             }
130
131             if (particle != null)
132                 fPArray.addParticle(particle);
133         }
134
135         particle = null;
136         XInt minAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
137         XInt maxAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
138         Long JavaDoc defaultVals = (Long JavaDoc)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
139             
140         XSModelGroupImpl group = new XSModelGroupImpl();
141         group.fCompositor = XSModelGroupImpl.MODELGROUP_ALL;
142         group.fParticleCount = fPArray.getParticleCount();
143         group.fParticles = fPArray.popContext();
144         group.fAnnotation = annotation;
145         particle = new XSParticleDecl();
146         particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
147         particle.fMinOccurs = minAtt.intValue();
148         particle.fMaxOccurs = maxAtt.intValue();
149         particle.fValue = group;
150
151         particle = checkOccurrences(particle,
152                                     SchemaSymbols.ELT_ALL,
153                                     (Element JavaDoc)allDecl.getParentNode(),
154                                     allContextFlags,
155                                     defaultVals.longValue());
156         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
157
158         return particle;
159     }
160
161     /**
162      * Traverse the Sequence declaration
163      *
164      * <sequence
165      * id = ID
166      * maxOccurs = string
167      * minOccurs = nonNegativeInteger>
168      * Content: (annotation? , (element | group | choice | sequence | any)*)
169      * </sequence>
170      *
171      * @param seqDecl
172      * @param schemaDoc
173      * @param grammar
174      * @return
175      */

176     XSParticleDecl traverseSequence(Element JavaDoc seqDecl,
177                                     XSDocumentInfo schemaDoc,
178                                     SchemaGrammar grammar,
179                                     int allContextFlags,
180                                     XSObject parent) {
181
182         return traverseSeqChoice(seqDecl, schemaDoc, grammar, allContextFlags, false, parent);
183     }
184
185     /**
186      * Traverse the Choice declaration
187      *
188      * <choice
189      * id = ID
190      * maxOccurs = string
191      * minOccurs = nonNegativeInteger>
192      * Content: (annotation? , (element | group | choice | sequence | any)*)
193      * </choice>
194      *
195      * @param choiceDecl
196      * @param schemaDoc
197      * @param grammar
198      * @return
199      */

200     XSParticleDecl traverseChoice(Element JavaDoc choiceDecl,
201                                   XSDocumentInfo schemaDoc,
202                                   SchemaGrammar grammar,
203                                   int allContextFlags,
204                                   XSObject parent) {
205
206         return traverseSeqChoice (choiceDecl, schemaDoc, grammar, allContextFlags, true, parent);
207     }
208
209     /**
210      * Common traversal for <choice> and <sequence>
211      *
212      * @param decl
213      * @param schemaDoc
214      * @param grammar
215      * @param choice If traversing <choice> this parameter is true.
216      * @return
217      */

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