1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Nov 2017
   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.xs.SchemaGrammar;
  25 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  26 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
  27 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
  28 import com.sun.org.apache.xerces.internal.impl.xs.identity.UniqueOrKey;
  29 import com.sun.org.apache.xerces.internal.util.DOMUtil;
  30 import org.w3c.dom.Element;
  31 
  32 /**
  33  * This class contains code that is used to traverse both <key>s and
  34  * <unique>s.
  35  *
  36  * @xerces.internal
  37  *
  38  * @author Neil Graham, IBM
  39  */
  40 class XSDUniqueOrKeyTraverser extends XSDAbstractIDConstraintTraverser {
  41 
  42     public XSDUniqueOrKeyTraverser (XSDHandler handler,
  43                                   XSAttributeChecker gAttrCheck) {
  44         super(handler, gAttrCheck);
  45     }
  46 
  47 
  48     void traverse(Element uElem, XSElementDecl element,
  49             XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
  50 
  51         // General Attribute Checking
  52         Object[] attrValues = fAttrChecker.checkAttributes(uElem, false, schemaDoc);
  53 
  54         // create identity constraint
  55         String uName = (String)attrValues[XSAttributeChecker.ATTIDX_NAME];
  56 
  57         if(uName == null){
  58             reportSchemaError("s4s-att-must-appear", new Object [] {DOMUtil.getLocalName(uElem) , SchemaSymbols.ATT_NAME }, uElem);
  59             //return this array back to pool
  60             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  61             return;
  62         }
  63 
  64         UniqueOrKey uniqueOrKey;
  65         if(DOMUtil.getLocalName(uElem).equals(SchemaSymbols.ELT_UNIQUE)) {
  66             uniqueOrKey = new UniqueOrKey(schemaDoc.fTargetNamespace, uName, element.fName, IdentityConstraint.IC_UNIQUE);
  67         } else {
  68             uniqueOrKey = new UniqueOrKey(schemaDoc.fTargetNamespace, uName, element.fName, IdentityConstraint.IC_KEY);
  69         }
  70         // it's XSDElementTraverser's job to ensure that there's no
  71         // duplication (or if there is that restriction is involved
  72         // and there's identity).
  73 
  74         // If errors occurred in traversing the identity constraint, then don't
  75         // add it to the schema, to avoid errors when processing the instance.
  76         if (traverseIdentityConstraint(uniqueOrKey, uElem, schemaDoc, attrValues)) {
  77             // and stuff this in the grammar
  78             if (grammar.getIDConstraintDecl(uniqueOrKey.getIdentityConstraintName()) == null) {
  79                 grammar.addIDConstraintDecl(element, uniqueOrKey);
  80             }
  81 
  82             final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
  83             final IdentityConstraint idc = grammar.getIDConstraintDecl(uniqueOrKey.getIdentityConstraintName(), loc);
  84             if (idc == null) {
  85                 grammar.addIDConstraintDecl(element, uniqueOrKey, loc);
  86             }
  87 
  88             // handle duplicates
  89             if (fSchemaHandler.fTolerateDuplicates) {
  90                 if (idc != null) {
  91                     if (idc instanceof UniqueOrKey) {
  92                         uniqueOrKey = (UniqueOrKey)idc;
  93                     }
  94                 }
  95                 fSchemaHandler.addIDConstraintDecl(uniqueOrKey);
  96             }
  97         }
  98 
  99         // and fix up attributeChecker
 100         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
 101     } // traverse(Element,XSDElementDecl,XSDocumentInfo, SchemaGrammar)
 102 } // XSDUniqueOrKeyTraverser