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