KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > xs > traversers > XSDAttributeTraverser


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.xs.traversers;
18
19 import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
20 import org.apache.xerces.impl.dv.ValidatedInfo;
21 import org.apache.xerces.impl.dv.XSSimpleType;
22 import org.apache.xerces.impl.xs.SchemaGrammar;
23 import org.apache.xerces.impl.xs.SchemaSymbols;
24 import org.apache.xerces.impl.xs.XSAnnotationImpl;
25 import org.apache.xerces.impl.xs.XSAttributeDecl;
26 import org.apache.xerces.impl.xs.XSAttributeUseImpl;
27 import org.apache.xerces.impl.xs.XSComplexTypeDecl;
28 import org.apache.xerces.impl.xs.util.XInt;
29 import org.apache.xerces.util.DOMUtil;
30 import org.apache.xerces.util.XMLSymbols;
31 import org.apache.xerces.xni.QName;
32 import org.apache.xerces.xs.XSConstants;
33 import org.apache.xerces.xs.XSTypeDefinition;
34 import org.w3c.dom.Element JavaDoc;
35
36 /**
37  * The attribute declaration schema component traverser.
38  *
39  * <attribute
40  * default = string
41  * fixed = string
42  * form = (qualified | unqualified)
43  * id = ID
44  * name = NCName
45  * ref = QName
46  * type = QName
47  * use = (optional | prohibited | required) : optional
48  * {any attributes with non-schema namespace . . .}>
49  * Content: (annotation?, (simpleType?))
50  * </attribute>
51  *
52  * @xerces.internal
53  *
54  * @author Sandy Gao, IBM
55  * @author Neeraj Bajaj, Sun Microsystems, inc.
56  * @version $Id: XSDAttributeTraverser.java,v 1.32 2005/06/10 20:40:05 sandygao Exp $
57  */

58 class XSDAttributeTraverser extends XSDAbstractTraverser {
59     
60     public XSDAttributeTraverser (XSDHandler handler,
61             XSAttributeChecker gAttrCheck) {
62         super(handler, gAttrCheck);
63     }
64     
65     protected XSAttributeUseImpl traverseLocal(Element JavaDoc attrDecl,
66             XSDocumentInfo schemaDoc,
67             SchemaGrammar grammar,
68             XSComplexTypeDecl enclosingCT) {
69         
70         // General Attribute Checking
71
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(attrDecl, false, schemaDoc);
72         
73         String JavaDoc defaultAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_DEFAULT];
74         String JavaDoc fixedAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_FIXED];
75         String JavaDoc nameAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_NAME];
76         QName refAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_REF];
77         XInt useAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_USE];
78         
79         // get 'attribute declaration'
80
XSAttributeDecl attribute = null;
81         if (attrDecl.getAttributeNode(SchemaSymbols.ATT_REF) != null) {
82             if (refAtt != null) {
83                 attribute = (XSAttributeDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ATTRIBUTE_TYPE, refAtt, attrDecl);
84                 
85                 Element JavaDoc child = DOMUtil.getFirstChildElement(attrDecl);
86                 if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
87                     // REVISIT: put this somewhere
88
traverseAnnotationDecl(child, attrValues, false, schemaDoc);
89                     child = DOMUtil.getNextSiblingElement(child);
90                 }
91                 
92                 if (child != null) {
93                     reportSchemaError("src-attribute.3.2", new Object JavaDoc[]{refAtt.rawname}, child);
94                 }
95                 // for error reporting
96
nameAtt = refAtt.localpart;
97             } else {
98                 attribute = null;
99             }
100         } else {
101             attribute = traverseNamedAttr(attrDecl, attrValues, schemaDoc, grammar, false, enclosingCT);
102         }
103         
104         // get 'value constraint'
105
short consType = XSConstants.VC_NONE;
106         if (defaultAtt != null) {
107             consType = XSConstants.VC_DEFAULT;
108         } else if (fixedAtt != null) {
109             consType = XSConstants.VC_FIXED;
110             defaultAtt = fixedAtt;
111             fixedAtt = null;
112         }
113         
114         XSAttributeUseImpl attrUse = null;
115         if (attribute != null) {
116             if (fSchemaHandler.fDeclPool !=null) {
117                 attrUse = fSchemaHandler.fDeclPool.getAttributeUse();
118             } else {
119                 attrUse = new XSAttributeUseImpl();
120             }
121             attrUse.fAttrDecl = attribute;
122             attrUse.fUse = useAtt.shortValue();
123             attrUse.fConstraintType = consType;
124             if (defaultAtt != null) {
125                 attrUse.fDefault = new ValidatedInfo();
126                 attrUse.fDefault.normalizedValue = defaultAtt;
127             }
128         }
129         
130         //src-attribute
131

132         // 1 default and fixed must not both be present.
133
if (defaultAtt != null && fixedAtt != null) {
134             reportSchemaError("src-attribute.1", new Object JavaDoc[]{nameAtt}, attrDecl);
135         }
136         
137         // 2 If default and use are both present, use must have the actual value optional.
138
if (consType == XSConstants.VC_DEFAULT &&
139                 useAtt != null && useAtt.intValue() != SchemaSymbols.USE_OPTIONAL) {
140             reportSchemaError("src-attribute.2", new Object JavaDoc[]{nameAtt}, attrDecl);
141         }
142         
143         // a-props-correct
144

145         if (defaultAtt != null && attrUse != null) {
146             // 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).
147
fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
148             try {
149                 checkDefaultValid(attrUse);
150             }
151             catch (InvalidDatatypeValueException ide) {
152                 reportSchemaError (ide.getKey(), ide.getArgs(), attrDecl);
153                 reportSchemaError ("a-props-correct.2", new Object JavaDoc[]{nameAtt, defaultAtt}, attrDecl);
154             }
155             
156             // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}.
157
if (((XSSimpleType)attribute.getTypeDefinition()).isIDType() ) {
158                 reportSchemaError ("a-props-correct.3", new Object JavaDoc[]{nameAtt}, attrDecl);
159             }
160             
161             // check 3.5.6 constraint
162
// Attribute Use Correct
163
// 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}.
164
if (attrUse.fAttrDecl.getConstraintType() == XSConstants.VC_FIXED &&
165                     attrUse.fConstraintType != XSConstants.VC_NONE) {
166                 if (attrUse.fConstraintType != XSConstants.VC_FIXED ||
167                         !attrUse.fAttrDecl.getValInfo().actualValue.equals(attrUse.fDefault.actualValue)) {
168                     reportSchemaError ("au-props-correct.2", new Object JavaDoc[]{nameAtt, attrUse.fAttrDecl.getValInfo().stringValue()}, attrDecl);
169                 }
170             }
171         }
172         
173         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
174         return attrUse;
175     }
176     
177     protected XSAttributeDecl traverseGlobal(Element JavaDoc attrDecl,
178             XSDocumentInfo schemaDoc,
179             SchemaGrammar grammar) {
180         
181         // General Attribute Checking
182
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(attrDecl, true, schemaDoc);
183         XSAttributeDecl attribute = traverseNamedAttr(attrDecl, attrValues, schemaDoc, grammar, true, null);
184         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
185         return attribute;
186         
187     }
188     
189     /**
190      * Traverse a globally declared attribute.
191      *
192      * @param attrDecl
193      * @param attrValues
194      * @param schemaDoc
195      * @param grammar
196      * @param isGlobal
197      * @return the attribute declaration index
198      */

199     XSAttributeDecl traverseNamedAttr(Element JavaDoc attrDecl,
200             Object JavaDoc[] attrValues,
201             XSDocumentInfo schemaDoc,
202             SchemaGrammar grammar,
203             boolean isGlobal,
204             XSComplexTypeDecl enclosingCT) {
205         
206         String JavaDoc defaultAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_DEFAULT];
207         String JavaDoc fixedAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_FIXED];
208         XInt formAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FORM];
209         String JavaDoc nameAtt = (String JavaDoc) attrValues[XSAttributeChecker.ATTIDX_NAME];
210         QName typeAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_TYPE];
211         
212         // Step 1: get declaration information
213
XSAttributeDecl attribute = null;
214         if (fSchemaHandler.fDeclPool !=null) {
215             attribute = fSchemaHandler.fDeclPool.getAttributeDecl();
216         } else {
217             attribute = new XSAttributeDecl();
218         }
219         
220         // get 'name'
221
if (nameAtt != null)
222             nameAtt = fSymbolTable.addSymbol(nameAtt);
223         
224         // get 'target namespace'
225
String JavaDoc tnsAtt = null;
226         XSComplexTypeDecl enclCT = null;
227         short scope = XSAttributeDecl.SCOPE_ABSENT;
228         if (isGlobal) {
229             tnsAtt = schemaDoc.fTargetNamespace;
230             scope = XSAttributeDecl.SCOPE_GLOBAL;
231         }
232         else {
233             if (enclosingCT != null) {
234                 enclCT = enclosingCT;
235                 scope = XSAttributeDecl.SCOPE_LOCAL;
236             }
237             if (formAtt != null) {
238                 if (formAtt.intValue() == SchemaSymbols.FORM_QUALIFIED)
239                     tnsAtt = schemaDoc.fTargetNamespace;
240             } else if (schemaDoc.fAreLocalAttributesQualified) {
241                 tnsAtt = schemaDoc.fTargetNamespace;
242             }
243         }
244         // get 'value constraint'
245
// for local named attribute, value constraint is absent
246
ValidatedInfo attDefault = null;
247         short constraintType = XSConstants.VC_NONE;
248         if (isGlobal) {
249             if (fixedAtt != null) {
250                 attDefault = new ValidatedInfo();
251                 attDefault.normalizedValue = fixedAtt;
252                 constraintType = XSConstants.VC_FIXED;
253             } else if (defaultAtt != null) {
254                 attDefault = new ValidatedInfo();
255                 attDefault.normalizedValue = defaultAtt;
256                 constraintType = XSConstants.VC_DEFAULT;
257             }
258         }
259         
260         // get 'annotation'
261
Element JavaDoc child = DOMUtil.getFirstChildElement(attrDecl);
262         XSAnnotationImpl annotation = null;
263         if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
264             annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
265             child = DOMUtil.getNextSiblingElement(child);
266         }
267         else {
268             String JavaDoc text = DOMUtil.getSyntheticAnnotation(attrDecl);
269             if (text != null) {
270                 annotation = traverseSyntheticAnnotation(attrDecl, text, attrValues, false, schemaDoc);
271             }
272         }
273         
274         // get 'type definition'
275
XSSimpleType attrType = null;
276         boolean haveAnonType = false;
277         
278         // Handle Anonymous type if there is one
279
if (child != null) {
280             String JavaDoc childName = DOMUtil.getLocalName(child);
281             
282             if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
283                 attrType = fSchemaHandler.fSimpleTypeTraverser.traverseLocal(child, schemaDoc, grammar);
284                 haveAnonType = true;
285                 child = DOMUtil.getNextSiblingElement(child);
286             }
287         }
288         
289         // Handler type attribute
290
if (attrType == null && typeAtt != null) {
291             XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, typeAtt, attrDecl);
292             if (type != null && type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
293                 attrType = (XSSimpleType)type;
294             else
295                 reportSchemaError("src-resolve", new Object JavaDoc[]{typeAtt.rawname, "simpleType definition"}, attrDecl);
296         }
297         
298         if (attrType == null) {
299             attrType = SchemaGrammar.fAnySimpleType;
300         }
301         
302         attribute.setValues(nameAtt, tnsAtt, attrType,
303                 constraintType, scope, attDefault, enclCT, annotation);
304         
305         // Step 2: register attribute decl to the grammar
306
if (isGlobal && nameAtt != null)
307             grammar.addGlobalAttributeDecl(attribute);
308         
309         // Step 3: check against schema for schemas
310

311         // required attributes
312
if (nameAtt == null) {
313             if (isGlobal)
314                 reportSchemaError("s4s-att-must-appear", new Object JavaDoc[]{SchemaSymbols.ELT_ATTRIBUTE, SchemaSymbols.ATT_NAME}, attrDecl);
315             else
316                 reportSchemaError("src-attribute.3.1", null, attrDecl);
317             nameAtt = NO_NAME;
318         }
319         
320         // element
321
if (child != null) {
322             reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{nameAtt, "(annotation?, (simpleType?))", DOMUtil.getLocalName(child)}, child);
323         }
324         
325         // Step 4: check 3.2.3 constraints
326

327         // src-attribute
328

329         // 1 default and fixed must not both be present.
330
if (defaultAtt != null && fixedAtt != null) {
331             reportSchemaError("src-attribute.1", new Object JavaDoc[]{nameAtt}, attrDecl);
332         }
333         
334         // 2 If default and use are both present, use must have the actual value optional.
335
// This is checked in "traverse" method
336

337         // 3 If the item's parent is not <schema>, then all of the following must be true:
338
// 3.1 One of ref or name must be present, but not both.
339
// This is checked in XSAttributeChecker
340

341         // 3.2 If ref is present, then all of <simpleType>, form and type must be absent.
342
// Attributes are checked in XSAttributeChecker, elements are checked in "traverse" method
343

344         // 4 type and <simpleType> must not both be present.
345
if (haveAnonType && (typeAtt != null)) {
346             reportSchemaError( "src-attribute.4", new Object JavaDoc[]{nameAtt}, attrDecl);
347         }
348         
349         // Step 5: check 3.2.6 constraints
350
// check for NOTATION type
351
checkNotationType(nameAtt, attrType, attrDecl);
352         
353         // a-props-correct
354

355         // 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).
356
if (attDefault != null) {
357             fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
358             try {
359                 checkDefaultValid(attribute);
360             }
361             catch (InvalidDatatypeValueException ide) {
362                 reportSchemaError (ide.getKey(), ide.getArgs(), attrDecl);
363                 reportSchemaError ("a-props-correct.2", new Object JavaDoc[]{nameAtt, attDefault.normalizedValue}, attrDecl);
364             }
365         }
366         
367         // 3 If the {type definition} is or is derived from ID then there must not be a {value constraint}.
368
if (attDefault != null) {
369             if (attrType.isIDType() ) {
370                 reportSchemaError ("a-props-correct.3", new Object JavaDoc[]{nameAtt}, attrDecl);
371             }
372         }
373         
374         // no-xmlns
375

376         // The {name} of an attribute declaration must not match xmlns.
377
if (nameAtt != null && nameAtt.equals(XMLSymbols.PREFIX_XMLNS)) {
378             reportSchemaError("no-xmlns", null, attrDecl);
379         }
380         
381         // no-xsi
382

383         // 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).
384
if (tnsAtt != null && tnsAtt.equals(SchemaSymbols.URI_XSI)) {
385             reportSchemaError("no-xsi", new Object JavaDoc[]{SchemaSymbols.URI_XSI}, attrDecl);
386         }
387         
388         // Attribute without a name. Return null.
389
if (attribute.getName() == null)
390             return null;
391         
392         return attribute;
393     }
394     
395     // throws an error if the constraint value is invalid for the given type
396
void checkDefaultValid(XSAttributeDecl attribute) throws InvalidDatatypeValueException {
397         // validate the original lexical rep, and set the actual value
398
((XSSimpleType)attribute.getTypeDefinition()).validate(attribute.getValInfo().normalizedValue, fValidationState, attribute.getValInfo());
399         // validate the canonical lexical rep
400
((XSSimpleType)attribute.getTypeDefinition()).validate(attribute.getValInfo().stringValue(), fValidationState, attribute.getValInfo());
401     }
402     
403     // throws an error if the constraint value is invalid for the given type
404
void checkDefaultValid(XSAttributeUseImpl attrUse) throws InvalidDatatypeValueException {
405         // validate the original lexical rep, and set the actual value
406
((XSSimpleType)attrUse.fAttrDecl.getTypeDefinition()).validate(attrUse.fDefault.normalizedValue, fValidationState, attrUse.fDefault);
407         // validate the canonical lexical rep
408
((XSSimpleType)attrUse.fAttrDecl.getTypeDefinition()).validate(attrUse.fDefault.stringValue(), fValidationState, attrUse.fDefault);
409     }
410     
411 }
412
Popular Tags