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 }