001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.impl.xs.traversers;
019:
020: import org.apache.xerces.impl.xs.SchemaGrammar;
021: import org.apache.xerces.impl.xs.SchemaSymbols;
022: import org.apache.xerces.impl.xs.XSAnnotationImpl;
023: import org.apache.xerces.impl.xs.XSGroupDecl;
024: import org.apache.xerces.impl.xs.XSModelGroupImpl;
025: import org.apache.xerces.impl.xs.XSParticleDecl;
026: import org.apache.xerces.impl.xs.util.XInt;
027: import org.apache.xerces.impl.xs.util.XSObjectListImpl;
028: import org.apache.xerces.util.DOMUtil;
029: import org.apache.xerces.util.XMLSymbols;
030: import org.apache.xerces.xni.QName;
031: import org.apache.xerces.xs.XSObjectList;
032: import org.w3c.dom.Element;
033:
034: /**
035: * The model group schema component traverser.
036: *
037: * <group
038: * name = NCName>
039: * Content: (annotation?, (all | choice | sequence))
040: * </group>
041: *
042: * @xerces.internal
043: *
044: * @author Rahul Srivastava, Sun Microsystems Inc.
045: * @author Elena Litani, IBM
046: * @author Lisa Martin, IBM
047: * @version $Id: XSDGroupTraverser.java 518305 2007-03-14 20:23:24Z mrglavas $
048: */
049: class XSDGroupTraverser extends XSDAbstractParticleTraverser {
050:
051: XSDGroupTraverser(XSDHandler handler, XSAttributeChecker gAttrCheck) {
052:
053: super (handler, gAttrCheck);
054: }
055:
056: XSParticleDecl traverseLocal(Element elmNode,
057: XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
058:
059: // General Attribute Checking for elmNode declared locally
060: Object[] attrValues = fAttrChecker.checkAttributes(elmNode,
061: false, schemaDoc);
062: QName refAttr = (QName) attrValues[XSAttributeChecker.ATTIDX_REF];
063: XInt minAttr = (XInt) attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
064: XInt maxAttr = (XInt) attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
065:
066: XSGroupDecl group = null;
067:
068: // ref should be here.
069: if (refAttr == null) {
070: reportSchemaError("s4s-att-must-appear", new Object[] {
071: "group (local)", "ref" }, elmNode);
072: } else {
073: // get global decl
074: // index is a particle index.
075: group = (XSGroupDecl) fSchemaHandler.getGlobalDecl(
076: schemaDoc, XSDHandler.GROUP_TYPE, refAttr, elmNode);
077: }
078:
079: XSAnnotationImpl annotation = null;
080: // no children other than "annotation?" are allowed
081: Element child = DOMUtil.getFirstChildElement(elmNode);
082: if (child != null
083: && DOMUtil.getLocalName(child).equals(
084: SchemaSymbols.ELT_ANNOTATION)) {
085: annotation = traverseAnnotationDecl(child, attrValues,
086: false, schemaDoc);
087: child = DOMUtil.getNextSiblingElement(child);
088: } else {
089: String text = DOMUtil.getSyntheticAnnotation(elmNode);
090: if (text != null) {
091: annotation = traverseSyntheticAnnotation(elmNode, text,
092: attrValues, false, schemaDoc);
093: }
094: }
095:
096: if (child != null) {
097: reportSchemaError("s4s-elt-must-match.1", new Object[] {
098: "group (local)", "(annotation?)",
099: DOMUtil.getLocalName(elmNode) }, elmNode);
100: }
101:
102: int minOccurs = minAttr.intValue();
103: int maxOccurs = maxAttr.intValue();
104:
105: XSParticleDecl particle = null;
106:
107: // not empty group, not empty particle
108: if (group != null && group.fModelGroup != null
109: && !(minOccurs == 0 && maxOccurs == 0)) {
110: // create a particle to contain this model group
111: if (fSchemaHandler.fDeclPool != null) {
112: particle = fSchemaHandler.fDeclPool.getParticleDecl();
113: } else {
114: particle = new XSParticleDecl();
115: }
116: particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
117: particle.fValue = group.fModelGroup;
118: particle.fMinOccurs = minOccurs;
119: particle.fMaxOccurs = maxOccurs;
120: if (group.fModelGroup.fCompositor == XSModelGroupImpl.MODELGROUP_ALL) {
121: Long defaultVals = (Long) attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
122: particle = checkOccurrences(particle,
123: SchemaSymbols.ELT_GROUP, (Element) elmNode
124: .getParentNode(), GROUP_REF_WITH_ALL,
125: defaultVals.longValue());
126: }
127: if (refAttr != null) {
128: XSObjectList annotations;
129: if (annotation != null) {
130: annotations = new XSObjectListImpl();
131: ((XSObjectListImpl) annotations).add(annotation);
132: } else {
133: annotations = XSObjectListImpl.EMPTY_LIST;
134: }
135: particle.fAnnotations = annotations;
136: } else {
137: particle.fAnnotations = group.fAnnotations;
138: }
139: }
140:
141: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
142:
143: return particle;
144:
145: } // traverseLocal
146:
147: XSGroupDecl traverseGlobal(Element elmNode,
148: XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
149:
150: // General Attribute Checking for elmNode declared globally
151: Object[] attrValues = fAttrChecker.checkAttributes(elmNode,
152: true, schemaDoc);
153: String strNameAttr = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
154:
155: // must have a name
156: if (strNameAttr == null) {
157: reportSchemaError("s4s-att-must-appear", new Object[] {
158: "group (global)", "name" }, elmNode);
159: }
160:
161: XSGroupDecl group = null;
162: XSParticleDecl particle = null;
163:
164: // must have at least one child
165: Element l_elmChild = DOMUtil.getFirstChildElement(elmNode);
166: XSAnnotationImpl annotation = null;
167: if (l_elmChild == null) {
168: reportSchemaError("s4s-elt-must-match.2", new Object[] {
169: "group (global)",
170: "(annotation?, (all | choice | sequence))" },
171: elmNode);
172: } else {
173: // Create the group defi up-front, so it can be passed
174: // to the traversal methods
175: group = new XSGroupDecl();
176:
177: String childName = l_elmChild.getLocalName();
178: if (childName.equals(SchemaSymbols.ELT_ANNOTATION)) {
179: annotation = traverseAnnotationDecl(l_elmChild,
180: attrValues, true, schemaDoc);
181: l_elmChild = DOMUtil.getNextSiblingElement(l_elmChild);
182: if (l_elmChild != null)
183: childName = l_elmChild.getLocalName();
184: } else {
185: String text = DOMUtil.getSyntheticAnnotation(elmNode);
186: if (text != null) {
187: annotation = traverseSyntheticAnnotation(elmNode,
188: text, attrValues, false, schemaDoc);
189: }
190: }
191:
192: if (l_elmChild == null) {
193: reportSchemaError("s4s-elt-must-match.2", new Object[] {
194: "group (global)",
195: "(annotation?, (all | choice | sequence))" },
196: elmNode);
197: } else if (childName.equals(SchemaSymbols.ELT_ALL)) {
198: particle = traverseAll(l_elmChild, schemaDoc, grammar,
199: CHILD_OF_GROUP, group);
200: } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
201: particle = traverseChoice(l_elmChild, schemaDoc,
202: grammar, CHILD_OF_GROUP, group);
203: } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
204: particle = traverseSequence(l_elmChild, schemaDoc,
205: grammar, CHILD_OF_GROUP, group);
206: } else {
207: reportSchemaError("s4s-elt-must-match.1", new Object[] {
208: "group (global)",
209: "(annotation?, (all | choice | sequence))",
210: DOMUtil.getLocalName(l_elmChild) }, l_elmChild);
211: }
212:
213: if (l_elmChild != null
214: && DOMUtil.getNextSiblingElement(l_elmChild) != null) {
215: reportSchemaError("s4s-elt-must-match.1", new Object[] {
216: "group (global)",
217: "(annotation?, (all | choice | sequence))",
218: DOMUtil.getLocalName(DOMUtil
219: .getNextSiblingElement(l_elmChild)) },
220: DOMUtil.getNextSiblingElement(l_elmChild));
221: }
222:
223: // add global group declaration to the grammar
224: if (strNameAttr != null) {
225: group.fName = strNameAttr;
226: group.fTargetNamespace = schemaDoc.fTargetNamespace;
227: if (particle != null)
228: group.fModelGroup = (XSModelGroupImpl) particle.fValue;
229: XSObjectList annotations;
230: if (annotation != null) {
231: annotations = new XSObjectListImpl();
232: ((XSObjectListImpl) annotations).add(annotation);
233: } else {
234: annotations = XSObjectListImpl.EMPTY_LIST;
235: }
236: group.fAnnotations = annotations;
237: grammar.addGlobalGroupDecl(group);
238: } else {
239: // name attribute is not there, don't return this group.
240: group = null;
241: }
242: }
243: if (group != null) {
244: // store groups redefined by restriction in the grammar so
245: // that we can get at them at full-schema-checking time.
246: Object redefinedGrp = fSchemaHandler
247: .getGrpOrAttrGrpRedefinedByRestriction(
248: XSDHandler.GROUP_TYPE, new QName(
249: XMLSymbols.EMPTY_STRING,
250: strNameAttr, strNameAttr,
251: schemaDoc.fTargetNamespace),
252: schemaDoc, elmNode);
253: if (redefinedGrp != null) {
254: // store in grammar
255: grammar.addRedefinedGroupDecl(group,
256: (XSGroupDecl) redefinedGrp, fSchemaHandler
257: .element2Locator(elmNode));
258: }
259: }
260:
261: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
262:
263: return group;
264:
265: } // traverseGlobal
266: }
|