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