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 */ 39 class XSDKeyrefTraverser extends XSDAbstractIDConstraintTraverser { 40 41 public XSDKeyrefTraverser (XSDHandler handler, 42 XSAttributeChecker gAttrCheck) { 43 super(handler, gAttrCheck); 44 } 45 46 void traverse(Element krElem, XSElementDecl element, 47 XSDocumentInfo schemaDoc, SchemaGrammar grammar) { 48 49 // General Attribute Checking 50 Object[] attrValues = fAttrChecker.checkAttributes(krElem, false, schemaDoc); 51 52 // create identity constraint 53 String krName = (String)attrValues[XSAttributeChecker.ATTIDX_NAME]; 54 if(krName == null){ 55 reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_KEYREF , SchemaSymbols.ATT_NAME }, krElem); 56 //return this array back to pool 57 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 58 return; 59 } 60 QName kName = (QName)attrValues[XSAttributeChecker.ATTIDX_REFER]; 61 if(kName == null){ 62 reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_KEYREF , SchemaSymbols.ATT_REFER }, krElem); 63 //return this array back to pool 64 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 65 return; 66 } 67 68 UniqueOrKey key = null; 69 IdentityConstraint ret = (IdentityConstraint)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.IDENTITYCONSTRAINT_TYPE, kName, krElem); 70 // if ret == null, we've already reported an error in getGlobalDecl 71 // we report an error only when ret != null, and the return type keyref 72 if (ret != null) { 73 if (ret.getCategory() == IdentityConstraint.IC_KEY || 74 ret.getCategory() == IdentityConstraint.IC_UNIQUE) { 75 key = (UniqueOrKey)ret; 76 } else { 77 reportSchemaError("src-resolve", new Object[]{kName.rawname, "identity constraint key/unique"}, krElem); 78 } 79 } 80 81 if(key == null) { 82 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 83 return; 84 } 85 86 KeyRef keyRef = new KeyRef(schemaDoc.fTargetNamespace, krName, element.fName, key); 87 88 // If errors occurred in traversing the identity constraint, then don't 89 // add it to the schema, to avoid errors when processing the instance. 90 if (traverseIdentityConstraint(keyRef, krElem, schemaDoc, attrValues)) { 91 //Schema Component Constraint: Identity-constraint Definition Properties Correct 92 //2 If the {identity-constraint category} is keyref, the cardinality of the {fields} must equal that of the {fields} of the {referenced key}. 93 if(key.getFieldCount() != keyRef.getFieldCount()) { 94 reportSchemaError("c-props-correct.2" , new Object [] {krName,key.getIdentityConstraintName()}, krElem); 95 } else { 96 // add key reference to element decl 97 // and stuff this in the grammar 98 if (grammar.getIDConstraintDecl(keyRef.getIdentityConstraintName()) == null) { 99 grammar.addIDConstraintDecl(element, keyRef); 100 } 101 102 // also add it to extended map 103 final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc); 104 final IdentityConstraint idc = grammar.getIDConstraintDecl(keyRef.getIdentityConstraintName(), loc); 105 if (idc == null) { 106 grammar.addIDConstraintDecl(element, keyRef, loc); 107 } 108 109 // handle duplicates 110 if (fSchemaHandler.fTolerateDuplicates) { 111 if (idc != null) { 112 if (idc instanceof KeyRef) { 113 keyRef = (KeyRef) idc; 114 } 115 } 116 fSchemaHandler.addIDConstraintDecl(keyRef); 117 } 118 } 119 } 120 121 // and put back attributes 122 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 123 } // traverse(Element,int,XSDocumentInfo, SchemaGrammar) 124 } // XSDKeyrefTraverser