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 22package com.sun.org.apache.xerces.internal.impl.xs.traversers; 23 24import com.sun.org.apache.xerces.internal.impl.xpath.XPathException; 25import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; 26import com.sun.org.apache.xerces.internal.impl.xs.identity.Field; 27import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint; 28import com.sun.org.apache.xerces.internal.impl.xs.identity.Selector; 29import com.sun.org.apache.xerces.internal.util.DOMUtil; 30import com.sun.org.apache.xerces.internal.util.XMLChar; 31import org.w3c.dom.Element; 32 33/** 34 * This class contains code that all three IdentityConstraint 35 * traversers (the XSDUniqueTraverser, XSDKeyTraverser and 36 * XSDKeyrefTraverser) rely upon. 37 * 38 * @xerces.internal 39 * 40 */ 41class XSDAbstractIDConstraintTraverser extends XSDAbstractTraverser { 42 43 public XSDAbstractIDConstraintTraverser (XSDHandler handler, 44 XSAttributeChecker gAttrCheck) { 45 super(handler, gAttrCheck); 46 } 47 48 boolean traverseIdentityConstraint(IdentityConstraint ic, 49 Element icElem, XSDocumentInfo schemaDoc, Object [] icElemAttrs) { 50 51 // General Attribute Checking will have been done on icElem by caller 52 53 // check for <annotation> and get selector 54 Element sElem = DOMUtil.getFirstChildElement(icElem); 55 if(sElem == null) { 56 reportSchemaError("s4s-elt-must-match.2", 57 new Object[]{"identity constraint", "(annotation?, selector, field+)"}, 58 icElem); 59 return false; 60 } 61 62 // General Attribute Checking on sElem 63 // first child could be an annotation 64 if (DOMUtil.getLocalName(sElem).equals(SchemaSymbols.ELT_ANNOTATION)) { 65 ic.addAnnotation(traverseAnnotationDecl(sElem, icElemAttrs, false, schemaDoc)); 66 sElem = DOMUtil.getNextSiblingElement(sElem); 67 // if no more children report an error 68 if(sElem == null) { 69 reportSchemaError("s4s-elt-must-match.2", new Object[]{"identity constraint", "(annotation?, selector, field+)"}, icElem); 70 return false; 71 } 72 } 73 else { 74 String text = DOMUtil.getSyntheticAnnotation(icElem); 75 if (text != null) { 76 ic.addAnnotation(traverseSyntheticAnnotation(icElem, text, icElemAttrs, false, schemaDoc)); 77 } 78 } 79 80 // must be <selector> 81 if(!DOMUtil.getLocalName(sElem).equals(SchemaSymbols.ELT_SELECTOR)) { 82 reportSchemaError("s4s-elt-must-match.1", new Object[]{"identity constraint", "(annotation?, selector, field+)", SchemaSymbols.ELT_SELECTOR}, sElem); 83 return false; 84 } 85 Object [] attrValues = fAttrChecker.checkAttributes(sElem, false, schemaDoc); 86 87 // make sure <selector>'s content is fine: 88 Element selChild = DOMUtil.getFirstChildElement(sElem); 89 90 if (selChild !=null) { 91 // traverse annotation if any 92 if (DOMUtil.getLocalName(selChild).equals(SchemaSymbols.ELT_ANNOTATION)) { 93 ic.addAnnotation(traverseAnnotationDecl(selChild, attrValues, false, schemaDoc)); 94 selChild = DOMUtil.getNextSiblingElement(selChild); 95 } 96 else { 97 reportSchemaError("s4s-elt-must-match.1", new Object[]{SchemaSymbols.ELT_SELECTOR, "(annotation?)", DOMUtil.getLocalName(selChild)}, selChild); 98 } 99 if (selChild != null) { 100 reportSchemaError("s4s-elt-must-match.1", new Object [] {SchemaSymbols.ELT_SELECTOR, "(annotation?)", DOMUtil.getLocalName(selChild)}, selChild); 101 } 102 } 103 else { 104 String text = DOMUtil.getSyntheticAnnotation(sElem); 105 if (text != null) { 106 ic.addAnnotation(traverseSyntheticAnnotation(icElem, text, attrValues, false, schemaDoc)); 107 } 108 } 109 110 String sText = ((String)attrValues[XSAttributeChecker.ATTIDX_XPATH]); 111 if(sText == null) { 112 reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_SELECTOR, SchemaSymbols.ATT_XPATH}, sElem); 113 return false; 114 } 115 sText = XMLChar.trim(sText); 116 117 Selector.XPath sXpath = null; 118 try { 119 sXpath = new Selector.XPath(sText, fSymbolTable, 120 schemaDoc.fNamespaceSupport); 121 Selector selector = new Selector(sXpath, ic); 122 ic.setSelector(selector); 123 } 124 catch (XPathException e) { 125 reportSchemaError(e.getKey(), new Object[]{sText}, sElem); 126 // put back attr values... 127 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 128 return false; 129 } 130 131 // put back attr values... 132 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 133 134 // get fields 135 Element fElem = DOMUtil.getNextSiblingElement(sElem); 136 if(fElem == null) { 137 reportSchemaError("s4s-elt-must-match.2", new Object[]{"identity constraint", "(annotation?, selector, field+)"}, sElem); 138 return false; 139 } 140 while (fElem != null) { 141 if(!DOMUtil.getLocalName(fElem).equals(SchemaSymbols.ELT_FIELD)) { 142 reportSchemaError("s4s-elt-must-match.1", new Object[]{"identity constraint", "(annotation?, selector, field+)", SchemaSymbols.ELT_FIELD}, fElem); 143 fElem = DOMUtil.getNextSiblingElement(fElem); 144 continue; 145 } 146 147 // General Attribute Checking 148 attrValues = fAttrChecker.checkAttributes(fElem, false, schemaDoc); 149 150 // and make sure <field>'s content is fine: 151 Element fieldChild = DOMUtil.getFirstChildElement(fElem); 152 if (fieldChild != null) { 153 // traverse annotation 154 if (DOMUtil.getLocalName(fieldChild).equals(SchemaSymbols.ELT_ANNOTATION)) { 155 ic.addAnnotation(traverseAnnotationDecl(fieldChild, attrValues, false, schemaDoc)); 156 fieldChild = DOMUtil.getNextSiblingElement(fieldChild); 157 } 158 } 159 if (fieldChild != null) { 160 reportSchemaError("s4s-elt-must-match.1", new Object [] {SchemaSymbols.ELT_FIELD, "(annotation?)", DOMUtil.getLocalName(fieldChild)}, fieldChild); 161 } 162 else { 163 String text = DOMUtil.getSyntheticAnnotation(fElem); 164 if (text != null) { 165 ic.addAnnotation(traverseSyntheticAnnotation(icElem, text, attrValues, false, schemaDoc)); 166 } 167 } 168 String fText = ((String)attrValues[XSAttributeChecker.ATTIDX_XPATH]); 169 if (fText == null) { 170 reportSchemaError("s4s-att-must-appear", new Object [] {SchemaSymbols.ELT_FIELD, SchemaSymbols.ATT_XPATH}, fElem); 171 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 172 return false; 173 } 174 fText = XMLChar.trim(fText); 175 try { 176 Field.XPath fXpath = new Field.XPath(fText, fSymbolTable, 177 schemaDoc.fNamespaceSupport); 178 Field field = new Field(fXpath, ic); 179 ic.addField(field); 180 } 181 catch (XPathException e) { 182 reportSchemaError(e.getKey(), new Object[]{fText}, fElem); 183 // put back attr values... 184 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 185 return false; 186 } 187 fElem = DOMUtil.getNextSiblingElement(fElem); 188 // put back attr values... 189 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 190 } 191 192 return ic.getFieldCount() > 0; 193 } // traverseIdentityConstraint(IdentityConstraint,Element, XSDocumentInfo) 194} // XSDAbstractIDConstraintTraverser 195