1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-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.xpath.XPathException; 24 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; 25 import com.sun.org.apache.xerces.internal.impl.xs.identity.Field; 26 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint; 27 import com.sun.org.apache.xerces.internal.impl.xs.identity.Selector; 28 import com.sun.org.apache.xerces.internal.util.DOMUtil; 29 import com.sun.org.apache.xerces.internal.util.XMLChar; 30 import org.w3c.dom.Element; 31 32 /** 33 * This class contains code that all three IdentityConstraint 34 * traversers (the XSDUniqueTraverser, XSDKeyTraverser and 35 * XSDKeyrefTraverser) rely upon. 36 * 37 * @xerces.internal 38 * 39 * @version $Id: XSDAbstractIDConstraintTraverser.java,v 1.7 2010-11-01 04:40:02 joehw Exp $ 40 */ 41 class 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