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.dv.InvalidDatatypeValueException;
021: import org.apache.xerces.impl.dv.ValidatedInfo;
022: import org.apache.xerces.impl.dv.XSSimpleType;
023: import org.apache.xerces.impl.xs.SchemaGrammar;
024: import org.apache.xerces.impl.xs.SchemaSymbols;
025: import org.apache.xerces.impl.xs.XSAnnotationImpl;
026: import org.apache.xerces.impl.xs.XSAttributeDecl;
027: import org.apache.xerces.impl.xs.XSAttributeUseImpl;
028: import org.apache.xerces.impl.xs.XSComplexTypeDecl;
029: import org.apache.xerces.impl.xs.util.XInt;
030: import org.apache.xerces.impl.xs.util.XSObjectListImpl;
031: import org.apache.xerces.util.DOMUtil;
032: import org.apache.xerces.util.XMLSymbols;
033: import org.apache.xerces.xni.QName;
034: import org.apache.xerces.xs.XSConstants;
035: import org.apache.xerces.xs.XSObjectList;
036: import org.apache.xerces.xs.XSTypeDefinition;
037: import org.w3c.dom.Element;
038:
039: /**
040: * The attribute declaration schema component traverser.
041: *
042: * <attribute
043: * default = string
044: * fixed = string
045: * form = (qualified | unqualified)
046: * id = ID
047: * name = NCName
048: * ref = QName
049: * type = QName
050: * use = (optional | prohibited | required) : optional
051: * {any attributes with non-schema namespace . . .}>
052: * Content: (annotation?, (simpleType?))
053: * </attribute>
054: *
055: * @xerces.internal
056: *
057: * @author Sandy Gao, IBM
058: * @author Neeraj Bajaj, Sun Microsystems, inc.
059: * @version $Id: XSDAttributeTraverser.java 449424 2006-09-24 16:22:30Z mrglavas $
060: */
061: class XSDAttributeTraverser extends XSDAbstractTraverser {
062:
063: public XSDAttributeTraverser(XSDHandler handler,
064: XSAttributeChecker gAttrCheck) {
065: super (handler, gAttrCheck);
066: }
067:
068: protected XSAttributeUseImpl traverseLocal(Element attrDecl,
069: XSDocumentInfo schemaDoc, SchemaGrammar grammar,
070: XSComplexTypeDecl enclosingCT) {
071:
072: // General Attribute Checking
073: Object[] attrValues = fAttrChecker.checkAttributes(attrDecl,
074: false, schemaDoc);
075:
076: String defaultAtt = (String) attrValues[XSAttributeChecker.ATTIDX_DEFAULT];
077: String fixedAtt = (String) attrValues[XSAttributeChecker.ATTIDX_FIXED];
078: String nameAtt = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
079: QName refAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_REF];
080: XInt useAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_USE];
081:
082: // get 'attribute declaration'
083: XSAttributeDecl attribute = null;
084: XSAnnotationImpl annotation = null;
085: if (attrDecl.getAttributeNode(SchemaSymbols.ATT_REF) != null) {
086: if (refAtt != null) {
087: attribute = (XSAttributeDecl) fSchemaHandler
088: .getGlobalDecl(schemaDoc,
089: XSDHandler.ATTRIBUTE_TYPE, refAtt,
090: attrDecl);
091:
092: Element child = DOMUtil.getFirstChildElement(attrDecl);
093: if (child != null
094: && DOMUtil.getLocalName(child).equals(
095: SchemaSymbols.ELT_ANNOTATION)) {
096: annotation = traverseAnnotationDecl(child,
097: attrValues, false, schemaDoc);
098: child = DOMUtil.getNextSiblingElement(child);
099: } else {
100: String text = DOMUtil
101: .getSyntheticAnnotation(attrDecl);
102: if (text != null) {
103: annotation = traverseSyntheticAnnotation(
104: attrDecl, text, attrValues, false,
105: schemaDoc);
106: }
107: }
108:
109: if (child != null) {
110: reportSchemaError("src-attribute.3.2",
111: new Object[] { refAtt.rawname }, child);
112: }
113: // for error reporting
114: nameAtt = refAtt.localpart;
115: } else {
116: attribute = null;
117: }
118: } else {
119: attribute = traverseNamedAttr(attrDecl, attrValues,
120: schemaDoc, grammar, false, enclosingCT);
121: }
122:
123: // get 'value constraint'
124: short consType = XSConstants.VC_NONE;
125: if (defaultAtt != null) {
126: consType = XSConstants.VC_DEFAULT;
127: } else if (fixedAtt != null) {
128: consType = XSConstants.VC_FIXED;
129: defaultAtt = fixedAtt;
130: fixedAtt = null;
131: }
132:
133: XSAttributeUseImpl attrUse = null;
134: if (attribute != null) {
135: if (fSchemaHandler.fDeclPool != null) {
136: attrUse = fSchemaHandler.fDeclPool.getAttributeUse();
137: } else {
138: attrUse = new XSAttributeUseImpl();
139: }
140: attrUse.fAttrDecl = attribute;
141: attrUse.fUse = useAtt.shortValue();
142: attrUse.fConstraintType = consType;
143: if (defaultAtt != null) {
144: attrUse.fDefault = new ValidatedInfo();
145: attrUse.fDefault.normalizedValue = defaultAtt;
146: }
147: // Get the annotation associated witht the local attr decl
148: if (attrDecl.getAttributeNode(SchemaSymbols.ATT_REF) == null) {
149: attrUse.fAnnotations = attribute.getAnnotations();
150: } else {
151: XSObjectList annotations;
152: if (annotation != null) {
153: annotations = new XSObjectListImpl();
154: ((XSObjectListImpl) annotations).add(annotation);
155: } else {
156: annotations = XSObjectListImpl.EMPTY_LIST;
157: }
158: attrUse.fAnnotations = annotations;
159: }
160: }
161:
162: //src-attribute
163:
164: // 1 default and fixed must not both be present.
165: if (defaultAtt != null && fixedAtt != null) {
166: reportSchemaError("src-attribute.1",
167: new Object[] { nameAtt }, attrDecl);
168: }
169:
170: // 2 If default and use are both present, use must have the actual value optional.
171: if (consType == XSConstants.VC_DEFAULT && useAtt != null
172: && useAtt.intValue() != SchemaSymbols.USE_OPTIONAL) {
173: reportSchemaError("src-attribute.2",
174: new Object[] { nameAtt }, attrDecl);
175: }
176:
177: // a-props-correct
178:
179: if (defaultAtt != null && attrUse != null) {
180: // 2 if there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in String Valid (3.14.4).
181: fValidationState
182: .setNamespaceSupport(schemaDoc.fNamespaceSupport);
183: try {
184: checkDefaultValid(attrUse);
185: } catch (InvalidDatatypeValueException ide) {
186: reportSchemaError(ide.getKey(), ide.getArgs(), attrDecl);
187: reportSchemaError("a-props-correct.2", new Object[] {
188: nameAtt, defaultAtt }, attrDecl);
189: }
190:
191: // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}.
192: if (((XSSimpleType) attribute.getTypeDefinition())
193: .isIDType()) {
194: reportSchemaError("a-props-correct.3",
195: new Object[] { nameAtt }, attrDecl);
196: }
197:
198: // check 3.5.6 constraint
199: // Attribute Use Correct
200: // 2 If the {attribute declaration} has a fixed {value constraint}, then if the attribute use itself has a {value constraint}, it must also be fixed and its value must match that of the {attribute declaration}'s {value constraint}.
201: if (attrUse.fAttrDecl.getConstraintType() == XSConstants.VC_FIXED
202: && attrUse.fConstraintType != XSConstants.VC_NONE) {
203: if (attrUse.fConstraintType != XSConstants.VC_FIXED
204: || !attrUse.fAttrDecl.getValInfo().actualValue
205: .equals(attrUse.fDefault.actualValue)) {
206: reportSchemaError("au-props-correct.2",
207: new Object[] {
208: nameAtt,
209: attrUse.fAttrDecl.getValInfo()
210: .stringValue() }, attrDecl);
211: }
212: }
213: }
214:
215: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
216: return attrUse;
217: }
218:
219: protected XSAttributeDecl traverseGlobal(Element attrDecl,
220: XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
221:
222: // General Attribute Checking
223: Object[] attrValues = fAttrChecker.checkAttributes(attrDecl,
224: true, schemaDoc);
225: XSAttributeDecl attribute = traverseNamedAttr(attrDecl,
226: attrValues, schemaDoc, grammar, true, null);
227: fAttrChecker.returnAttrArray(attrValues, schemaDoc);
228: return attribute;
229:
230: }
231:
232: /**
233: * Traverse a globally declared attribute.
234: *
235: * @param attrDecl
236: * @param attrValues
237: * @param schemaDoc
238: * @param grammar
239: * @param isGlobal
240: * @return the attribute declaration index
241: */
242: XSAttributeDecl traverseNamedAttr(Element attrDecl,
243: Object[] attrValues, XSDocumentInfo schemaDoc,
244: SchemaGrammar grammar, boolean isGlobal,
245: XSComplexTypeDecl enclosingCT) {
246:
247: String defaultAtt = (String) attrValues[XSAttributeChecker.ATTIDX_DEFAULT];
248: String fixedAtt = (String) attrValues[XSAttributeChecker.ATTIDX_FIXED];
249: XInt formAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FORM];
250: String nameAtt = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
251: QName typeAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_TYPE];
252:
253: // Step 1: get declaration information
254: XSAttributeDecl attribute = null;
255: if (fSchemaHandler.fDeclPool != null) {
256: attribute = fSchemaHandler.fDeclPool.getAttributeDecl();
257: } else {
258: attribute = new XSAttributeDecl();
259: }
260:
261: // get 'name'
262: if (nameAtt != null)
263: nameAtt = fSymbolTable.addSymbol(nameAtt);
264:
265: // get 'target namespace'
266: String tnsAtt = null;
267: XSComplexTypeDecl enclCT = null;
268: short scope = XSAttributeDecl.SCOPE_ABSENT;
269: if (isGlobal) {
270: tnsAtt = schemaDoc.fTargetNamespace;
271: scope = XSAttributeDecl.SCOPE_GLOBAL;
272: } else {
273: if (enclosingCT != null) {
274: enclCT = enclosingCT;
275: scope = XSAttributeDecl.SCOPE_LOCAL;
276: }
277: if (formAtt != null) {
278: if (formAtt.intValue() == SchemaSymbols.FORM_QUALIFIED)
279: tnsAtt = schemaDoc.fTargetNamespace;
280: } else if (schemaDoc.fAreLocalAttributesQualified) {
281: tnsAtt = schemaDoc.fTargetNamespace;
282: }
283: }
284: // get 'value constraint'
285: // for local named attribute, value constraint is absent
286: ValidatedInfo attDefault = null;
287: short constraintType = XSConstants.VC_NONE;
288: if (isGlobal) {
289: if (fixedAtt != null) {
290: attDefault = new ValidatedInfo();
291: attDefault.normalizedValue = fixedAtt;
292: constraintType = XSConstants.VC_FIXED;
293: } else if (defaultAtt != null) {
294: attDefault = new ValidatedInfo();
295: attDefault.normalizedValue = defaultAtt;
296: constraintType = XSConstants.VC_DEFAULT;
297: }
298: }
299:
300: // get 'annotation'
301: Element child = DOMUtil.getFirstChildElement(attrDecl);
302: XSAnnotationImpl annotation = null;
303: if (child != null
304: && DOMUtil.getLocalName(child).equals(
305: SchemaSymbols.ELT_ANNOTATION)) {
306: annotation = traverseAnnotationDecl(child, attrValues,
307: false, schemaDoc);
308: child = DOMUtil.getNextSiblingElement(child);
309: } else {
310: String text = DOMUtil.getSyntheticAnnotation(attrDecl);
311: if (text != null) {
312: annotation = traverseSyntheticAnnotation(attrDecl,
313: text, attrValues, false, schemaDoc);
314: }
315: }
316:
317: // get 'type definition'
318: XSSimpleType attrType = null;
319: boolean haveAnonType = false;
320:
321: // Handle Anonymous type if there is one
322: if (child != null) {
323: String childName = DOMUtil.getLocalName(child);
324:
325: if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
326: attrType = fSchemaHandler.fSimpleTypeTraverser
327: .traverseLocal(child, schemaDoc, grammar);
328: haveAnonType = true;
329: child = DOMUtil.getNextSiblingElement(child);
330: }
331: }
332:
333: // Handler type attribute
334: if (attrType == null && typeAtt != null) {
335: XSTypeDefinition type = (XSTypeDefinition) fSchemaHandler
336: .getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE,
337: typeAtt, attrDecl);
338: if (type != null
339: && type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
340: attrType = (XSSimpleType) type;
341: else
342: reportSchemaError("src-resolve", new Object[] {
343: typeAtt.rawname, "simpleType definition" },
344: attrDecl);
345: }
346:
347: if (attrType == null) {
348: attrType = SchemaGrammar.fAnySimpleType;
349: }
350:
351: XSObjectList annotations;
352: if (annotation != null) {
353: annotations = new XSObjectListImpl();
354: ((XSObjectListImpl) annotations).add(annotation);
355: } else {
356: annotations = XSObjectListImpl.EMPTY_LIST;
357: }
358: attribute.setValues(nameAtt, tnsAtt, attrType, constraintType,
359: scope, attDefault, enclCT, annotations);
360:
361: // Step 2: register attribute decl to the grammar
362: if (isGlobal && nameAtt != null)
363: grammar.addGlobalAttributeDecl(attribute);
364:
365: // Step 3: check against schema for schemas
366:
367: // required attributes
368: if (nameAtt == null) {
369: if (isGlobal)
370: reportSchemaError("s4s-att-must-appear", new Object[] {
371: SchemaSymbols.ELT_ATTRIBUTE,
372: SchemaSymbols.ATT_NAME }, attrDecl);
373: else
374: reportSchemaError("src-attribute.3.1", null, attrDecl);
375: nameAtt = NO_NAME;
376: }
377:
378: // element
379: if (child != null) {
380: reportSchemaError("s4s-elt-must-match.1", new Object[] {
381: nameAtt, "(annotation?, (simpleType?))",
382: DOMUtil.getLocalName(child) }, child);
383: }
384:
385: // Step 4: check 3.2.3 constraints
386:
387: // src-attribute
388:
389: // 1 default and fixed must not both be present.
390: if (defaultAtt != null && fixedAtt != null) {
391: reportSchemaError("src-attribute.1",
392: new Object[] { nameAtt }, attrDecl);
393: }
394:
395: // 2 If default and use are both present, use must have the actual value optional.
396: // This is checked in "traverse" method
397:
398: // 3 If the item's parent is not <schema>, then all of the following must be true:
399: // 3.1 One of ref or name must be present, but not both.
400: // This is checked in XSAttributeChecker
401:
402: // 3.2 If ref is present, then all of <simpleType>, form and type must be absent.
403: // Attributes are checked in XSAttributeChecker, elements are checked in "traverse" method
404:
405: // 4 type and <simpleType> must not both be present.
406: if (haveAnonType && (typeAtt != null)) {
407: reportSchemaError("src-attribute.4",
408: new Object[] { nameAtt }, attrDecl);
409: }
410:
411: // Step 5: check 3.2.6 constraints
412: // check for NOTATION type
413: checkNotationType(nameAtt, attrType, attrDecl);
414:
415: // a-props-correct
416:
417: // 2 if there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in String Valid (3.14.4).
418: if (attDefault != null) {
419: fValidationState
420: .setNamespaceSupport(schemaDoc.fNamespaceSupport);
421: try {
422: checkDefaultValid(attribute);
423: } catch (InvalidDatatypeValueException ide) {
424: reportSchemaError(ide.getKey(), ide.getArgs(), attrDecl);
425: reportSchemaError("a-props-correct.2", new Object[] {
426: nameAtt, attDefault.normalizedValue }, attrDecl);
427: }
428: }
429:
430: // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}.
431: if (attDefault != null) {
432: if (attrType.isIDType()) {
433: reportSchemaError("a-props-correct.3",
434: new Object[] { nameAtt }, attrDecl);
435: }
436: }
437:
438: // no-xmlns
439:
440: // The {name} of an attribute declaration must not match xmlns.
441: if (nameAtt != null && nameAtt.equals(XMLSymbols.PREFIX_XMLNS)) {
442: reportSchemaError("no-xmlns", null, attrDecl);
443: }
444:
445: // no-xsi
446:
447: // The {target namespace} of an attribute declaration, whether local or top-level, must not match http://www.w3.org/2001/XMLSchema-instance (unless it is one of the four built-in declarations given in the next section).
448: if (tnsAtt != null && tnsAtt.equals(SchemaSymbols.URI_XSI)) {
449: reportSchemaError("no-xsi",
450: new Object[] { SchemaSymbols.URI_XSI }, attrDecl);
451: }
452:
453: // Attribute without a name. Return null.
454: if (attribute.getName() == null)
455: return null;
456:
457: return attribute;
458: }
459:
460: // throws an error if the constraint value is invalid for the given type
461: void checkDefaultValid(XSAttributeDecl attribute)
462: throws InvalidDatatypeValueException {
463: // validate the original lexical rep, and set the actual value
464: ((XSSimpleType) attribute.getTypeDefinition()).validate(
465: attribute.getValInfo().normalizedValue,
466: fValidationState, attribute.getValInfo());
467: // validate the canonical lexical rep
468: ((XSSimpleType) attribute.getTypeDefinition()).validate(
469: attribute.getValInfo().stringValue(), fValidationState,
470: attribute.getValInfo());
471: }
472:
473: // throws an error if the constraint value is invalid for the given type
474: void checkDefaultValid(XSAttributeUseImpl attrUse)
475: throws InvalidDatatypeValueException {
476: // validate the original lexical rep, and set the actual value
477: ((XSSimpleType) attrUse.fAttrDecl.getTypeDefinition())
478: .validate(attrUse.fDefault.normalizedValue,
479: fValidationState, attrUse.fDefault);
480: // validate the canonical lexical rep
481: ((XSSimpleType) attrUse.fAttrDecl.getTypeDefinition())
482: .validate(attrUse.fDefault.stringValue(),
483: fValidationState, attrUse.fDefault);
484: }
485:
486: }
|