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