001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.impl.xs.traversers;
019:
020: import org.apache.xerces.impl.xpath.XPathException;
021: import org.apache.xerces.impl.xs.SchemaSymbols;
022: import org.apache.xerces.impl.xs.identity.Field;
023: import org.apache.xerces.impl.xs.identity.IdentityConstraint;
024: import org.apache.xerces.impl.xs.identity.Selector;
025: import org.apache.xerces.util.DOMUtil;
026: import org.apache.xerces.util.XMLChar;
027: import org.w3c.dom.Element;
028:
029: /**
030: * This class contains code that all three IdentityConstraint
031: * traversers (the XSDUniqueTraverser, XSDKeyTraverser and
032: * XSDKeyrefTraverser) rely upon.
033: *
034: * @xerces.internal
035: *
036: * @version $Id: XSDAbstractIDConstraintTraverser.java 469584 2006-10-31 17:57:34Z mrglavas $
037: */
038: class XSDAbstractIDConstraintTraverser extends XSDAbstractTraverser {
039:
040: public XSDAbstractIDConstraintTraverser(XSDHandler handler,
041: XSAttributeChecker gAttrCheck) {
042: super (handler, gAttrCheck);
043: }
044:
045: void traverseIdentityConstraint(IdentityConstraint ic,
046: Element icElem, XSDocumentInfo schemaDoc,
047: Object[] icElemAttrs) {
048:
049: // General Attribute Checking will have been done on icElem by caller
050:
051: // check for <annotation> and get selector
052: Element sElem = DOMUtil.getFirstChildElement(icElem);
053: if (sElem == null) {
054: reportSchemaError("s4s-elt-must-match.2", new Object[] {
055: "identity constraint",
056: "(annotation?, selector, field+)" }, icElem);
057: return;
058: }
059:
060: // General Attribute Checking on sElem
061: // first child could be an annotation
062: if (DOMUtil.getLocalName(sElem).equals(
063: SchemaSymbols.ELT_ANNOTATION)) {
064: ic.addAnnotation(traverseAnnotationDecl(sElem, icElemAttrs,
065: false, schemaDoc));
066: sElem = DOMUtil.getNextSiblingElement(sElem);
067: // if no more children report an error
068: if (sElem == null) {
069: reportSchemaError("s4s-elt-must-match.2", new Object[] {
070: "identity constraint",
071: "(annotation?, selector, field+)" }, icElem);
072: return;
073: }
074: } else {
075: String text = DOMUtil.getSyntheticAnnotation(icElem);
076: if (text != null) {
077: ic.addAnnotation(traverseSyntheticAnnotation(icElem,
078: text, icElemAttrs, false, schemaDoc));
079: }
080: }
081:
082: Object[] attrValues = fAttrChecker.checkAttributes(sElem,
083: false, schemaDoc);
084:
085: // if more than one annotation report an error
086: if (!DOMUtil.getLocalName(sElem).equals(
087: SchemaSymbols.ELT_SELECTOR)) {
088: reportSchemaError("s4s-elt-must-match.1", new Object[] {
089: "identity constraint",
090: "(annotation?, selector, field+)",
091: SchemaSymbols.ELT_SELECTOR }, sElem);
092: }
093: // and make sure <selector>'s content is fine:
094: Element selChild = DOMUtil.getFirstChildElement(sElem);
095:
096: if (selChild != null) {
097: // traverse annotation if any
098: if (DOMUtil.getLocalName(selChild).equals(
099: SchemaSymbols.ELT_ANNOTATION)) {
100: ic.addAnnotation(traverseAnnotationDecl(selChild,
101: attrValues, false, schemaDoc));
102: selChild = DOMUtil.getNextSiblingElement(selChild);
103: } else {
104: reportSchemaError("s4s-elt-must-match.1", new Object[] {
105: SchemaSymbols.ELT_SELECTOR, "(annotation?)",
106: DOMUtil.getLocalName(selChild) }, selChild);
107: }
108: if (selChild != null) {
109: reportSchemaError("s4s-elt-must-match.1", new Object[] {
110: SchemaSymbols.ELT_SELECTOR, "(annotation?)",
111: DOMUtil.getLocalName(selChild) }, selChild);
112: }
113: } else {
114: String text = DOMUtil.getSyntheticAnnotation(sElem);
115: if (text != null) {
116: ic.addAnnotation(traverseSyntheticAnnotation(icElem,
117: text, attrValues, false, schemaDoc));
118: }
119: }
120:
121: String sText = ((String) attrValues[XSAttributeChecker.ATTIDX_XPATH]);
122: if (sText == null) {
123: reportSchemaError("s4s-att-must-appear",
124: new Object[] { SchemaSymbols.ELT_SELECTOR,
125: SchemaSymbols.ATT_XPATH }, sElem);
126: return;
127: }
128: sText = XMLChar.trim(sText);
129:
130: Selector.XPath sXpath = null;
131: try {
132: sXpath = new Selector.XPath(sText, fSymbolTable,
133: schemaDoc.fNamespaceSupport);
134: Selector selector = new Selector(sXpath, ic);
135: ic.setSelector(selector);
136: } catch (XPathException e) {
137: reportSchemaError(e.getKey(), new Object[] { sText }, sElem);
138: // put back attr values...
139: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
140: return;
141: }
142:
143: // put back attr values...
144: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
145:
146: // get fields
147: Element fElem = DOMUtil.getNextSiblingElement(sElem);
148: if (fElem == null) {
149: reportSchemaError("s4s-elt-must-match.2", new Object[] {
150: "identity constraint",
151: "(annotation?, selector, field+)" }, sElem);
152: }
153: while (fElem != null) {
154: // General Attribute Checking
155: attrValues = fAttrChecker.checkAttributes(fElem, false,
156: schemaDoc);
157:
158: if (!DOMUtil.getLocalName(fElem).equals(
159: SchemaSymbols.ELT_FIELD))
160: reportSchemaError("s4s-elt-must-match.1", new Object[] {
161: "identity constraint",
162: "(annotation?, selector, field+)",
163: SchemaSymbols.ELT_FIELD }, fElem);
164:
165: // and make sure <field>'s content is fine:
166: Element fieldChild = DOMUtil.getFirstChildElement(fElem);
167: if (fieldChild != null) {
168: // traverse annotation
169: if (DOMUtil.getLocalName(fieldChild).equals(
170: SchemaSymbols.ELT_ANNOTATION)) {
171: ic.addAnnotation(traverseAnnotationDecl(fieldChild,
172: attrValues, false, schemaDoc));
173: fieldChild = DOMUtil
174: .getNextSiblingElement(fieldChild);
175: }
176: }
177: if (fieldChild != null) {
178: reportSchemaError("s4s-elt-must-match.1", new Object[] {
179: SchemaSymbols.ELT_FIELD, "(annotation?)",
180: DOMUtil.getLocalName(fieldChild) }, fieldChild);
181: } else {
182: String text = DOMUtil.getSyntheticAnnotation(fElem);
183: if (text != null) {
184: ic
185: .addAnnotation(traverseSyntheticAnnotation(
186: icElem, text, attrValues, false,
187: schemaDoc));
188: }
189: }
190: String fText = ((String) attrValues[XSAttributeChecker.ATTIDX_XPATH]);
191: if (fText == null) {
192: reportSchemaError("s4s-att-must-appear", new Object[] {
193: SchemaSymbols.ELT_FIELD,
194: SchemaSymbols.ATT_XPATH }, fElem);
195: return;
196: }
197: fText = fText.trim();
198: try {
199: Field.XPath fXpath = new Field.XPath(fText,
200: fSymbolTable, schemaDoc.fNamespaceSupport);
201: Field field = new Field(fXpath, ic);
202: ic.addField(field);
203: } catch (XPathException e) {
204: reportSchemaError(e.getKey(), new Object[] { fText },
205: fElem);
206: // put back attr values...
207: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
208: return;
209: }
210: fElem = DOMUtil.getNextSiblingElement(fElem);
211: // put back attr values...
212: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
213: }
214:
215: } // traverseIdentityConstraint(IdentityConstraint,Element, XSDocumentInfo)
216: } // XSDAbstractIDConstraintTraverser
|