1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001, 2002,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.xs.SchemaGrammar;
  24 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  25 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
  26 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
  27 import com.sun.org.apache.xerces.internal.impl.xs.identity.KeyRef;
  28 import com.sun.org.apache.xerces.internal.impl.xs.identity.UniqueOrKey;
  29 import com.sun.org.apache.xerces.internal.xni.QName;
  30 import org.w3c.dom.Element;
  31 
  32 /**
  33  * This class contains code that is used to traverse <keyref>s.
  34  *
  35  * @xerces.internal
  36  *
  37  * @author Neil Graham, IBM
  38  * @version $Id: XSDKeyrefTraverser.java,v 1.7 2010-11-01 04:40:02 joehw Exp $
  39  */
  40 class XSDKeyrefTraverser extends XSDAbstractIDConstraintTraverser {
  41 
  42     public XSDKeyrefTraverser (XSDHandler handler,
  43                                   XSAttributeChecker gAttrCheck) {
  44         super(handler, gAttrCheck);
  45     }
  46 
  47     void traverse(Element krElem, XSElementDecl element,
  48             XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
  49 
  50         // General Attribute Checking
  51         Object[] attrValues = fAttrChecker.checkAttributes(krElem, false, schemaDoc);
  52 
  53         // create identity constraint
  54         String krName = (String)attrValues[XSAttributeChecker.ATTIDX_NAME];
  55         if(krName == null){
  56             reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_KEYREF , SchemaSymbols.ATT_NAME }, krElem);
  57             //return this array back to pool
  58             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  59             return;
  60         }
  61         QName kName = (QName)attrValues[XSAttributeChecker.ATTIDX_REFER];
  62         if(kName == null){
  63             reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_KEYREF , SchemaSymbols.ATT_REFER }, krElem);
  64             //return this array back to pool
  65             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  66             return;
  67         }
  68 
  69         UniqueOrKey key = null;
  70         IdentityConstraint ret = (IdentityConstraint)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.IDENTITYCONSTRAINT_TYPE, kName, krElem);
  71         // if ret == null, we've already reported an error in getGlobalDecl
  72         // we report an error only when ret != null, and the return type keyref
  73         if (ret != null) {
  74             if (ret.getCategory() == IdentityConstraint.IC_KEY ||
  75                 ret.getCategory() == IdentityConstraint.IC_UNIQUE) {
  76                 key = (UniqueOrKey)ret;
  77             } else {
  78                 reportSchemaError("src-resolve", new Object[]{kName.rawname, "identity constraint key/unique"}, krElem);
  79             }
  80         }
  81 
  82         if(key == null) {
  83             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  84             return;
  85         }
  86 
  87         KeyRef keyRef = new KeyRef(schemaDoc.fTargetNamespace, krName, element.fName, key);
  88 
  89         // If errors occurred in traversing the identity constraint, then don't
  90         // add it to the schema, to avoid errors when processing the instance.
  91         if (traverseIdentityConstraint(keyRef, krElem, schemaDoc, attrValues)) {
  92             //Schema Component Constraint: Identity-constraint Definition Properties Correct
  93             //2 If the {identity-constraint category} is keyref, the cardinality of the {fields} must equal that of the {fields} of the {referenced key}.
  94             if(key.getFieldCount() != keyRef.getFieldCount()) {
  95                 reportSchemaError("c-props-correct.2" , new Object [] {krName,key.getIdentityConstraintName()}, krElem);
  96             } else {
  97                 // add key reference to element decl
  98                 // and stuff this in the grammar
  99                 if (grammar.getIDConstraintDecl(keyRef.getIdentityConstraintName()) == null) {
 100                     grammar.addIDConstraintDecl(element, keyRef);
 101                 }
 102 
 103                 // also add it to extended map
 104                 final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
 105                 final IdentityConstraint idc = grammar.getIDConstraintDecl(keyRef.getIdentityConstraintName(), loc);
 106                 if (idc  == null) {
 107                     grammar.addIDConstraintDecl(element, keyRef, loc);
 108                 }
 109 
 110                 // handle duplicates
 111                 if (fSchemaHandler.fTolerateDuplicates) {
 112                     if (idc  != null) {
 113                         if (idc instanceof KeyRef) {
 114                             keyRef = (KeyRef) idc;
 115                         }
 116                     }
 117                     fSchemaHandler.addIDConstraintDecl(keyRef);
 118                 }
 119             }
 120         }
 121 
 122         // and put back attributes
 123         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
 124     } // traverse(Element,int,XSDocumentInfo, SchemaGrammar)
 125 } // XSDKeyrefTraverser