View Javadoc
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