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 21 package com.sun.org.apache.xerces.internal.impl.xs.traversers; 22 23 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException; 24 import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; 25 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; 26 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; 27 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; 28 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl; 29 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeDecl; 30 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl; 31 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl; 32 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt; 33 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 34 import com.sun.org.apache.xerces.internal.util.DOMUtil; 35 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 36 import com.sun.org.apache.xerces.internal.xni.QName; 37 import com.sun.org.apache.xerces.internal.xs.XSConstants; 38 import com.sun.org.apache.xerces.internal.xs.XSObjectList; 39 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 40 import org.w3c.dom.Element; 41 42 /** 43 * The attribute declaration schema component traverser. 44 * 45 * <attribute 46 * default = string 47 * fixed = string 48 * form = (qualified | unqualified) 49 * id = ID 50 * name = NCName 51 * ref = QName 52 * type = QName 53 * use = (optional | prohibited | required) : optional 54 * {any attributes with non-schema namespace . . .}> 55 * Content: (annotation?, (simpleType?)) 56 * </attribute> 57 * 58 * @xerces.internal 59 * 60 * @author Sandy Gao, IBM 61 * @author Neeraj Bajaj, Sun Microsystems, inc. 62 */ 63 class XSDAttributeTraverser extends XSDAbstractTraverser { 64 65 public XSDAttributeTraverser (XSDHandler handler, 66 XSAttributeChecker gAttrCheck) { 67 super(handler, gAttrCheck); 68 } 69 70 protected XSAttributeUseImpl traverseLocal(Element attrDecl, 71 XSDocumentInfo schemaDoc, 72 SchemaGrammar grammar, 73 XSComplexTypeDecl enclosingCT) { 74 75 // General Attribute Checking 76 Object[] attrValues = fAttrChecker.checkAttributes(attrDecl, false, schemaDoc); 77 78 String defaultAtt = (String) attrValues[XSAttributeChecker.ATTIDX_DEFAULT]; 79 String fixedAtt = (String) attrValues[XSAttributeChecker.ATTIDX_FIXED]; 80 String nameAtt = (String) attrValues[XSAttributeChecker.ATTIDX_NAME]; 81 QName refAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_REF]; 82 XInt useAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_USE]; 83 84 // get 'attribute declaration' 85 XSAttributeDecl attribute = null; 86 XSAnnotationImpl annotation = null; 87 if (attrDecl.getAttributeNode(SchemaSymbols.ATT_REF) != null) { 88 if (refAtt != null) { 89 attribute = (XSAttributeDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ATTRIBUTE_TYPE, refAtt, attrDecl); 90 91 Element child = DOMUtil.getFirstChildElement(attrDecl); 92 if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { 93 annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc); 94 child = DOMUtil.getNextSiblingElement(child); 95 } 96 else { 97 String text = DOMUtil.getSyntheticAnnotation(attrDecl); 98 if (text != null) { 99 annotation = traverseSyntheticAnnotation(attrDecl, text, attrValues, false, schemaDoc); 100 } 101 } 102 103 if (child != null) { 104 reportSchemaError("src-attribute.3.2", new Object[]{refAtt.rawname}, child); 105 } 106 // for error reporting 107 nameAtt = refAtt.localpart; 108 } else { 109 attribute = null; 110 } 111 } else { 112 attribute = traverseNamedAttr(attrDecl, attrValues, schemaDoc, grammar, false, enclosingCT); 113 } 114 115 // get 'value constraint' 116 short consType = XSConstants.VC_NONE; 117 if (defaultAtt != null) { 118 consType = XSConstants.VC_DEFAULT; 119 } else if (fixedAtt != null) { 120 consType = XSConstants.VC_FIXED; 121 defaultAtt = fixedAtt; 122 fixedAtt = null; 123 } 124 125 XSAttributeUseImpl attrUse = null; 126 if (attribute != null) { 127 if (fSchemaHandler.fDeclPool !=null) { 128 attrUse = fSchemaHandler.fDeclPool.getAttributeUse(); 129 } else { 130 attrUse = new XSAttributeUseImpl(); 131 } 132 attrUse.fAttrDecl = attribute; 133 attrUse.fUse = useAtt.shortValue(); 134 attrUse.fConstraintType = consType; 135 if (defaultAtt != null) { 136 attrUse.fDefault = new ValidatedInfo(); 137 attrUse.fDefault.normalizedValue = defaultAtt; 138 } 139 // Get the annotation associated witht the local attr decl 140 if (attrDecl.getAttributeNode(SchemaSymbols.ATT_REF) == null) { 141 attrUse.fAnnotations = attribute.getAnnotations(); 142 } else { 143 XSObjectList annotations; 144 if (annotation != null) { 145 annotations = new XSObjectListImpl(); 146 ((XSObjectListImpl) annotations).addXSObject(annotation); 147 } else { 148 annotations = XSObjectListImpl.EMPTY_LIST; 149 } 150 attrUse.fAnnotations = annotations; 151 } 152 } 153 154 //src-attribute 155 156 // 1 default and fixed must not both be present. 157 if (defaultAtt != null && fixedAtt != null) { 158 reportSchemaError("src-attribute.1", new Object[]{nameAtt}, attrDecl); 159 } 160 161 // 2 If default and use are both present, use must have the actual value optional. 162 if (consType == XSConstants.VC_DEFAULT && 163 useAtt != null && useAtt.intValue() != SchemaSymbols.USE_OPTIONAL) { 164 reportSchemaError("src-attribute.2", new Object[]{nameAtt}, attrDecl); 165 // Recover by honouring the default value 166 attrUse.fUse = SchemaSymbols.USE_OPTIONAL; 167 } 168 169 // a-props-correct 170 171 if (defaultAtt != null && attrUse != null) { 172 // 2 if there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in String Valid (3.14.4). 173 fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); 174 try { 175 checkDefaultValid(attrUse); 176 } 177 catch (InvalidDatatypeValueException ide) { 178 reportSchemaError (ide.getKey(), ide.getArgs(), attrDecl); 179 reportSchemaError ("a-props-correct.2", new Object[]{nameAtt, defaultAtt}, attrDecl); 180 // Recover by removing the default value 181 attrUse.fDefault = null; 182 attrUse.fConstraintType = XSConstants.VC_NONE; 183 } 184 185 // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}. 186 if (((XSSimpleType)attribute.getTypeDefinition()).isIDType() ) { 187 reportSchemaError ("a-props-correct.3", new Object[]{nameAtt}, attrDecl); 188 // Recover by removing the default value 189 attrUse.fDefault = null; 190 attrUse.fConstraintType = XSConstants.VC_NONE; 191 } 192 193 // check 3.5.6 constraint 194 // Attribute Use Correct 195 // 2 If the {attribute declaration} has a fixed {value constraint}, then if the attribute use itself has a {value constraint}, it must also be fixed and its value must match that of the {attribute declaration}'s {value constraint}. 196 if (attrUse.fAttrDecl.getConstraintType() == XSConstants.VC_FIXED && 197 attrUse.fConstraintType != XSConstants.VC_NONE) { 198 if (attrUse.fConstraintType != XSConstants.VC_FIXED || 199 !attrUse.fAttrDecl.getValInfo().actualValue.equals(attrUse.fDefault.actualValue)) { 200 reportSchemaError ("au-props-correct.2", new Object[]{nameAtt, attrUse.fAttrDecl.getValInfo().stringValue()}, attrDecl); 201 // Recover by using the decl's {value constraint} 202 attrUse.fDefault = attrUse.fAttrDecl.getValInfo(); 203 attrUse.fConstraintType = XSConstants.VC_FIXED; 204 } 205 } 206 } 207 208 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 209 return attrUse; 210 } 211 212 protected XSAttributeDecl traverseGlobal(Element attrDecl, 213 XSDocumentInfo schemaDoc, 214 SchemaGrammar grammar) { 215 216 // General Attribute Checking 217 Object[] attrValues = fAttrChecker.checkAttributes(attrDecl, true, schemaDoc); 218 XSAttributeDecl attribute = traverseNamedAttr(attrDecl, attrValues, schemaDoc, grammar, true, null); 219 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 220 return attribute; 221 222 } 223 224 /** 225 * Traverse a globally declared attribute. 226 * 227 * @param attrDecl 228 * @param attrValues 229 * @param schemaDoc 230 * @param grammar 231 * @param isGlobal 232 * @return the attribute declaration index 233 */ 234 XSAttributeDecl traverseNamedAttr(Element attrDecl, 235 Object[] attrValues, 236 XSDocumentInfo schemaDoc, 237 SchemaGrammar grammar, 238 boolean isGlobal, 239 XSComplexTypeDecl enclosingCT) { 240 241 String defaultAtt = (String) attrValues[XSAttributeChecker.ATTIDX_DEFAULT]; 242 String fixedAtt = (String) attrValues[XSAttributeChecker.ATTIDX_FIXED]; 243 XInt formAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FORM]; 244 String nameAtt = (String) attrValues[XSAttributeChecker.ATTIDX_NAME]; 245 QName typeAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_TYPE]; 246 247 // Step 1: get declaration information 248 XSAttributeDecl attribute = null; 249 if (fSchemaHandler.fDeclPool !=null) { 250 attribute = fSchemaHandler.fDeclPool.getAttributeDecl(); 251 } else { 252 attribute = new XSAttributeDecl(); 253 } 254 255 // get 'name' 256 if (nameAtt != null) 257 nameAtt = fSymbolTable.addSymbol(nameAtt); 258 259 // get 'target namespace' 260 String tnsAtt = null; 261 XSComplexTypeDecl enclCT = null; 262 short scope = XSAttributeDecl.SCOPE_ABSENT; 263 if (isGlobal) { 264 tnsAtt = schemaDoc.fTargetNamespace; 265 scope = XSAttributeDecl.SCOPE_GLOBAL; 266 } 267 else { 268 if (enclosingCT != null) { 269 enclCT = enclosingCT; 270 scope = XSAttributeDecl.SCOPE_LOCAL; 271 } 272 if (formAtt != null) { 273 if (formAtt.intValue() == SchemaSymbols.FORM_QUALIFIED) 274 tnsAtt = schemaDoc.fTargetNamespace; 275 } else if (schemaDoc.fAreLocalAttributesQualified) { 276 tnsAtt = schemaDoc.fTargetNamespace; 277 } 278 } 279 // get 'value constraint' 280 // for local named attribute, value constraint is absent 281 ValidatedInfo attDefault = null; 282 short constraintType = XSConstants.VC_NONE; 283 if (isGlobal) { 284 if (fixedAtt != null) { 285 attDefault = new ValidatedInfo(); 286 attDefault.normalizedValue = fixedAtt; 287 constraintType = XSConstants.VC_FIXED; 288 } else if (defaultAtt != null) { 289 attDefault = new ValidatedInfo(); 290 attDefault.normalizedValue = defaultAtt; 291 constraintType = XSConstants.VC_DEFAULT; 292 } 293 } 294 295 // get 'annotation' 296 Element child = DOMUtil.getFirstChildElement(attrDecl); 297 XSAnnotationImpl annotation = null; 298 if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { 299 annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc); 300 child = DOMUtil.getNextSiblingElement(child); 301 } 302 else { 303 String text = DOMUtil.getSyntheticAnnotation(attrDecl); 304 if (text != null) { 305 annotation = traverseSyntheticAnnotation(attrDecl, text, attrValues, false, schemaDoc); 306 } 307 } 308 309 // get 'type definition' 310 XSSimpleType attrType = null; 311 boolean haveAnonType = false; 312 313 // Handle Anonymous type if there is one 314 if (child != null) { 315 String childName = DOMUtil.getLocalName(child); 316 317 if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) { 318 attrType = fSchemaHandler.fSimpleTypeTraverser.traverseLocal(child, schemaDoc, grammar); 319 haveAnonType = true; 320 child = DOMUtil.getNextSiblingElement(child); 321 } 322 } 323 324 // Handle type attribute 325 if (attrType == null && typeAtt != null) { 326 XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, typeAtt, attrDecl); 327 if (type != null && type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) { 328 attrType = (XSSimpleType)type; 329 } 330 else { 331 reportSchemaError("src-resolve", new Object[]{typeAtt.rawname, "simpleType definition"}, attrDecl); 332 if (type == null) { 333 attribute.fUnresolvedTypeName = typeAtt; 334 } 335 } 336 } 337 338 if (attrType == null) { 339 attrType = SchemaGrammar.fAnySimpleType; 340 } 341 342 XSObjectList annotations; 343 if (annotation != null) { 344 annotations = new XSObjectListImpl(); 345 ((XSObjectListImpl)annotations).addXSObject(annotation); 346 } else { 347 annotations = XSObjectListImpl.EMPTY_LIST; 348 } 349 attribute.setValues(nameAtt, tnsAtt, attrType, constraintType, scope, 350 attDefault, enclCT, annotations); 351 352 // Step 3: check against schema for schemas 353 354 // required attributes 355 if (nameAtt == null) { 356 if (isGlobal) 357 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_ATTRIBUTE, SchemaSymbols.ATT_NAME}, attrDecl); 358 else 359 reportSchemaError("src-attribute.3.1", null, attrDecl); 360 nameAtt = NO_NAME; 361 } 362 363 // element 364 if (child != null) { 365 reportSchemaError("s4s-elt-must-match.1", new Object[]{nameAtt, "(annotation?, (simpleType?))", DOMUtil.getLocalName(child)}, child); 366 } 367 368 // Step 4: check 3.2.3 constraints 369 370 // src-attribute 371 372 // 1 default and fixed must not both be present. 373 if (defaultAtt != null && fixedAtt != null) { 374 reportSchemaError("src-attribute.1", new Object[]{nameAtt}, attrDecl); 375 } 376 377 // 2 If default and use are both present, use must have the actual value optional. 378 // This is checked in "traverse" method 379 380 // 3 If the item's parent is not <schema>, then all of the following must be true: 381 // 3.1 One of ref or name must be present, but not both. 382 // This is checked in XSAttributeChecker 383 384 // 3.2 If ref is present, then all of <simpleType>, form and type must be absent. 385 // Attributes are checked in XSAttributeChecker, elements are checked in "traverse" method 386 387 // 4 type and <simpleType> must not both be present. 388 if (haveAnonType && (typeAtt != null)) { 389 reportSchemaError( "src-attribute.4", new Object[]{nameAtt}, attrDecl); 390 } 391 392 // Step 5: check 3.2.6 constraints 393 // check for NOTATION type 394 checkNotationType(nameAtt, attrType, attrDecl); 395 396 // a-props-correct 397 398 // 2 if there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in String Valid (3.14.4). 399 if (attDefault != null) { 400 fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); 401 try { 402 checkDefaultValid(attribute); 403 } 404 catch (InvalidDatatypeValueException ide) { 405 reportSchemaError (ide.getKey(), ide.getArgs(), attrDecl); 406 reportSchemaError ("a-props-correct.2", new Object[]{nameAtt, attDefault.normalizedValue}, attrDecl); 407 // Recover by removing the default value 408 attDefault = null; 409 constraintType = XSConstants.VC_NONE; 410 attribute.setValues(nameAtt, tnsAtt, attrType, constraintType, scope, 411 attDefault, enclCT, annotations); 412 } 413 } 414 415 // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}. 416 if (attDefault != null) { 417 if (attrType.isIDType() ) { 418 reportSchemaError ("a-props-correct.3", new Object[]{nameAtt}, attrDecl); 419 // Recover by removing the default value 420 attDefault = null; 421 constraintType = XSConstants.VC_NONE; 422 attribute.setValues(nameAtt, tnsAtt, attrType, constraintType, scope, 423 attDefault, enclCT, annotations); 424 } 425 } 426 427 // no-xmlns 428 429 // The {name} of an attribute declaration must not match xmlns. 430 if (nameAtt != null && nameAtt.equals(XMLSymbols.PREFIX_XMLNS)) { 431 reportSchemaError("no-xmlns", null, attrDecl); 432 return null; 433 } 434 435 // no-xsi 436 437 // The {target namespace} of an attribute declaration, whether local or top-level, must not match http://www.w3.org/2001/XMLSchema-instance (unless it is one of the four built-in declarations given in the next section). 438 if (tnsAtt != null && tnsAtt.equals(SchemaSymbols.URI_XSI)) { 439 reportSchemaError("no-xsi", new Object[]{SchemaSymbols.URI_XSI}, attrDecl); 440 return null; 441 } 442 443 // Attribute without a name. Return null. 444 if (nameAtt.equals(NO_NAME)) 445 return null; 446 447 // Step 2: register attribute decl to the grammar 448 if (isGlobal) { 449 if (grammar.getGlobalAttributeDecl(nameAtt) == null) { 450 grammar.addGlobalAttributeDecl(attribute); 451 } 452 453 // also add it to extended map 454 final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc); 455 final XSAttributeDecl attribute2 = grammar.getGlobalAttributeDecl(nameAtt, loc); 456 if (attribute2 == null) { 457 grammar.addGlobalAttributeDecl(attribute, loc); 458 } 459 460 if (fSchemaHandler.fTolerateDuplicates) { 461 if (attribute2 != null) { 462 attribute = attribute2; 463 } 464 fSchemaHandler.addGlobalAttributeDecl(attribute); 465 } 466 } 467 468 return attribute; 469 } 470 471 // throws an error if the constraint value is invalid for the given type 472 void checkDefaultValid(XSAttributeDecl attribute) throws InvalidDatatypeValueException { 473 // validate the original lexical rep, and set the actual value 474 ((XSSimpleType)attribute.getTypeDefinition()).validate(attribute.getValInfo().normalizedValue, fValidationState, attribute.getValInfo()); 475 // validate the canonical lexical rep 476 ((XSSimpleType)attribute.getTypeDefinition()).validate(attribute.getValInfo().stringValue(), fValidationState, attribute.getValInfo()); 477 } 478 479 // throws an error if the constraint value is invalid for the given type 480 void checkDefaultValid(XSAttributeUseImpl attrUse) throws InvalidDatatypeValueException { 481 // validate the original lexical rep, and set the actual value 482 ((XSSimpleType)attrUse.fAttrDecl.getTypeDefinition()).validate(attrUse.fDefault.normalizedValue, fValidationState, attrUse.fDefault); 483 // validate the canonical lexical rep 484 ((XSSimpleType)attrUse.fAttrDecl.getTypeDefinition()).validate(attrUse.fDefault.stringValue(), fValidationState, attrUse.fDefault); 485 } 486 487 }