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  package com.sun.org.apache.xerces.internal.impl.xs.traversers;
21  
22  import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
23  import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
24  import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
25  import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
26  import com.sun.org.apache.xerces.internal.impl.xs.XSGroupDecl;
27  import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
28  import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
29  import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
30  import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
31  import com.sun.org.apache.xerces.internal.util.DOMUtil;
32  import com.sun.org.apache.xerces.internal.util.XMLSymbols;
33  import com.sun.org.apache.xerces.internal.xni.QName;
34  import com.sun.org.apache.xerces.internal.xs.XSObjectList;
35  import org.w3c.dom.Element;
36  
37  /**
38   * The model group schema component traverser.
39   *
40   * <group
41   *   name = NCName>
42   *   Content: (annotation?, (all | choice | sequence))
43   * </group>
44   *
45   * @xerces.internal
46   *
47   * @author Rahul Srivastava, Sun Microsystems Inc.
48   * @author Elena Litani, IBM
49   * @author Lisa Martin,  IBM
50   * @version $Id: XSDGroupTraverser.java,v 1.7 2010-11-01 04:40:02 joehw Exp $
51   */
52  class  XSDGroupTraverser extends XSDAbstractParticleTraverser {
53  
54      XSDGroupTraverser (XSDHandler handler,
55              XSAttributeChecker gAttrCheck) {
56  
57          super(handler, gAttrCheck);
58      }
59  
60      XSParticleDecl traverseLocal(Element elmNode,
61              XSDocumentInfo schemaDoc,
62              SchemaGrammar grammar) {
63  
64          // General Attribute Checking for elmNode declared locally
65          Object[] attrValues = fAttrChecker.checkAttributes(elmNode, false,
66                  schemaDoc);
67          QName refAttr = (QName) attrValues[XSAttributeChecker.ATTIDX_REF];
68          XInt  minAttr = (XInt)  attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
69          XInt  maxAttr = (XInt)  attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
70  
71          XSGroupDecl group = null;
72  
73          // ref should be here.
74          if (refAttr == null) {
75              reportSchemaError("s4s-att-must-appear", new Object[]{"group (local)", "ref"}, elmNode);
76          } else {
77              // get global decl
78              // index is a particle index.
79              group = (XSGroupDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.GROUP_TYPE, refAttr, elmNode);
80          }
81  
82          XSAnnotationImpl annotation = null;
83          // no children other than "annotation?" are allowed
84          Element child = DOMUtil.getFirstChildElement(elmNode);
85          if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
86              annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
87              child = DOMUtil.getNextSiblingElement(child);
88          }
89          else {
90              String text = DOMUtil.getSyntheticAnnotation(elmNode);
91              if (text != null) {
92                  annotation = traverseSyntheticAnnotation(elmNode, text, attrValues, false, schemaDoc);
93              }
94          }
95  
96          if (child != null) {
97              reportSchemaError("s4s-elt-must-match.1", new Object[]{"group (local)", "(annotation?)", DOMUtil.getLocalName(elmNode)}, elmNode);
98          }
99  
100         int minOccurs = minAttr.intValue();
101         int maxOccurs = maxAttr.intValue();
102 
103         XSParticleDecl particle = null;
104 
105         // not empty group, not empty particle
106         if (group != null && group.fModelGroup != null &&
107                 !(minOccurs == 0 && maxOccurs == 0)) {
108             // create a particle to contain this model group
109             if (fSchemaHandler.fDeclPool != null) {
110                 particle = fSchemaHandler.fDeclPool.getParticleDecl();
111             } else {
112                 particle = new XSParticleDecl();
113             }
114             particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
115             particle.fValue = group.fModelGroup;
116             particle.fMinOccurs = minOccurs;
117             particle.fMaxOccurs = maxOccurs;
118             if (group.fModelGroup.fCompositor == XSModelGroupImpl.MODELGROUP_ALL) {
119                 Long defaultVals = (Long)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
120                 particle = checkOccurrences(particle, SchemaSymbols.ELT_GROUP,
121                         (Element)elmNode.getParentNode(), GROUP_REF_WITH_ALL,
122                         defaultVals.longValue());
123             }
124             if (refAttr != null) {
125                 XSObjectList annotations;
126                 if (annotation != null) {
127                     annotations = new XSObjectListImpl();
128                     ((XSObjectListImpl) annotations).addXSObject(annotation);
129                 } else {
130                     annotations = XSObjectListImpl.EMPTY_LIST;
131                 }
132                 particle.fAnnotations = annotations;
133             } else {
134                 particle.fAnnotations = group.fAnnotations;
135             }
136         }
137 
138         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
139 
140         return particle;
141 
142     } // traverseLocal
143 
144     XSGroupDecl traverseGlobal(Element elmNode,
145             XSDocumentInfo schemaDoc,
146             SchemaGrammar grammar) {
147 
148         // General Attribute Checking for elmNode declared globally
149         Object[] attrValues = fAttrChecker.checkAttributes(elmNode, true,
150                 schemaDoc);
151         String  strNameAttr = (String)  attrValues[XSAttributeChecker.ATTIDX_NAME];
152 
153         // must have a name
154         if (strNameAttr == null) {
155             reportSchemaError("s4s-att-must-appear", new Object[]{"group (global)", "name"}, elmNode);
156         }
157 
158         // Create the group defi up-front, so it can be passed
159         // to the traversal methods
160         XSGroupDecl group = new XSGroupDecl();
161         XSParticleDecl particle = null;
162 
163         // must have at least one child
164         Element l_elmChild = DOMUtil.getFirstChildElement(elmNode);
165         XSAnnotationImpl annotation = null;
166         if (l_elmChild == null) {
167             reportSchemaError("s4s-elt-must-match.2",
168                     new Object[]{"group (global)", "(annotation?, (all | choice | sequence))"},
169                     elmNode);
170         } else {
171             String childName = l_elmChild.getLocalName();
172             if (childName.equals(SchemaSymbols.ELT_ANNOTATION)) {
173                 annotation = traverseAnnotationDecl(l_elmChild, attrValues, true, schemaDoc);
174                 l_elmChild = DOMUtil.getNextSiblingElement(l_elmChild);
175                 if (l_elmChild != null)
176                     childName = l_elmChild.getLocalName();
177             }
178             else {
179                 String text = DOMUtil.getSyntheticAnnotation(elmNode);
180                 if (text != null) {
181                     annotation = traverseSyntheticAnnotation(elmNode, text, attrValues, false, schemaDoc);
182                 }
183             }
184 
185             if (l_elmChild == null) {
186                 reportSchemaError("s4s-elt-must-match.2",
187                         new Object[]{"group (global)", "(annotation?, (all | choice | sequence))"},
188                         elmNode);
189             } else if (childName.equals(SchemaSymbols.ELT_ALL)) {
190                 particle = traverseAll(l_elmChild, schemaDoc, grammar, CHILD_OF_GROUP, group);
191             } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
192                 particle = traverseChoice(l_elmChild, schemaDoc, grammar, CHILD_OF_GROUP, group);
193             } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
194                 particle = traverseSequence(l_elmChild, schemaDoc, grammar, CHILD_OF_GROUP, group);
195             } else {
196                 reportSchemaError("s4s-elt-must-match.1",
197                         new Object[]{"group (global)", "(annotation?, (all | choice | sequence))", DOMUtil.getLocalName(l_elmChild)},
198                         l_elmChild);
199             }
200 
201             if (l_elmChild != null &&
202                     DOMUtil.getNextSiblingElement(l_elmChild) != null) {
203                 reportSchemaError("s4s-elt-must-match.1",
204                         new Object[]{"group (global)", "(annotation?, (all | choice | sequence))",
205                         DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(l_elmChild))},
206                         DOMUtil.getNextSiblingElement(l_elmChild));
207             }
208         }
209 
210         // add global group declaration to the grammar
211         if (strNameAttr != null) {
212             group.fName = strNameAttr;
213             group.fTargetNamespace = schemaDoc.fTargetNamespace;
214             if (particle == null) {
215                 particle = XSConstraints.getEmptySequence();
216             }
217             group.fModelGroup = (XSModelGroupImpl)particle.fValue;
218             XSObjectList annotations;
219             if (annotation != null) {
220                 annotations = new XSObjectListImpl();
221                 ((XSObjectListImpl) annotations).addXSObject(annotation);
222             } else {
223                 annotations = XSObjectListImpl.EMPTY_LIST;
224             }
225             group.fAnnotations = annotations;
226             // Add group declaration to grammar
227             if (grammar.getGlobalGroupDecl(group.fName) == null) {
228                 grammar.addGlobalGroupDecl(group);
229             }
230 
231             // also add it to extended map
232             final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
233             final XSGroupDecl group2 = grammar.getGlobalGroupDecl(group.fName, loc);
234             if (group2 == null) {
235                 grammar.addGlobalGroupDecl(group, loc);
236             }
237 
238             // handle duplicates
239             if (fSchemaHandler.fTolerateDuplicates) {
240                 if (group2 != null) {
241                     group = group2;
242                 }
243                 fSchemaHandler.addGlobalGroupDecl(group);
244             }
245         }
246         else {
247             // name attribute is not there, don't return this group.
248             group = null;
249         }
250 
251         if (group != null) {
252             // store groups redefined by restriction in the grammar so
253             // that we can get at them at full-schema-checking time.
254             Object redefinedGrp = fSchemaHandler.getGrpOrAttrGrpRedefinedByRestriction(XSDHandler.GROUP_TYPE,
255                     new QName(XMLSymbols.EMPTY_STRING, strNameAttr, strNameAttr, schemaDoc.fTargetNamespace),
256                     schemaDoc, elmNode);
257             if (redefinedGrp != null) {
258                 // store in grammar
259                 grammar.addRedefinedGroupDecl(group, (XSGroupDecl)redefinedGrp,
260                         fSchemaHandler.element2Locator(elmNode));
261             }
262         }
263 
264         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
265 
266         return group;
267 
268     } // traverseGlobal
269 }