KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > xs > traversers > XSDSimpleTypeTraverser


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
59
60 import java.util.Vector JavaDoc;
61
62 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
63 import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
64 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
65 import com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl;
66 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
67 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
68 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
69 import com.sun.org.apache.xerces.internal.xs.XSConstants;
70 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
71 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
72 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
73 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
74 import com.sun.org.apache.xerces.internal.util.DOMUtil;
75 import com.sun.org.apache.xerces.internal.xni.QName;
76 import org.w3c.dom.Element JavaDoc;
77
78 /**
79  * The simple type definition schema component traverser.
80  *
81  * <simpleType
82  * final = (#all | (list | union | restriction))
83  * id = ID
84  * name = NCName
85  * {any attributes with non-schema namespace . . .}>
86  * Content: (annotation?, (restriction | list | union))
87  * </simpleType>
88  *
89  * <restriction
90  * base = QName
91  * id = ID
92  * {any attributes with non-schema namespace . . .}>
93  * Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))
94  * </restriction>
95  *
96  * <list
97  * id = ID
98  * itemType = QName
99  * {any attributes with non-schema namespace . . .}>
100  * Content: (annotation?, (simpleType?))
101  * </list>
102  *
103  * <union
104  * id = ID
105  * memberTypes = List of QName
106  * {any attributes with non-schema namespace . . .}>
107  * Content: (annotation?, (simpleType*))
108  * </union>
109  *
110  * @author Elena Litani, IBM
111  * @author Neeraj Bajaj, Sun Microsystems, Inc.
112  * @author Sandy Gao, IBM
113  *
114  * @version $Id: XSDSimpleTypeTraverser.java,v 1.26 2003/11/11 20:15:00 sandygao Exp $
115  */

116 class XSDSimpleTypeTraverser extends XSDAbstractTraverser {
117
118     // the factory used to query/create simple types
119
private final SchemaDVFactory schemaFactory = SchemaDVFactory.getInstance();
120
121     // whether the type being parsed is a S4S built-in type.
122
private boolean fIsBuiltIn = false;
123
124     XSDSimpleTypeTraverser (XSDHandler handler,
125                             XSAttributeChecker gAttrCheck) {
126         super(handler, gAttrCheck);
127         if (schemaFactory instanceof SchemaDVFactoryImpl) {
128             ((SchemaDVFactoryImpl)schemaFactory).setDeclPool(handler.fDeclPool);
129         }
130     }
131
132     //return qualified name of simpleType or empty string if error occured
133
XSSimpleType traverseGlobal(Element JavaDoc elmNode,
134                                 XSDocumentInfo schemaDoc,
135                                 SchemaGrammar grammar) {
136
137         // General Attribute Checking
138
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(elmNode, true, schemaDoc);
139         String JavaDoc nameAtt = (String JavaDoc)attrValues[XSAttributeChecker.ATTIDX_NAME];
140         XSSimpleType type = traverseSimpleTypeDecl(elmNode, attrValues, schemaDoc, grammar);
141         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
142
143         // if it's a global type without a name, return null
144
if (nameAtt == null) {
145             reportSchemaError("s4s-att-must-appear", new Object JavaDoc[]{SchemaSymbols.ELT_SIMPLETYPE, SchemaSymbols.ATT_NAME}, elmNode);
146             type = null;
147         }
148
149         // don't add global components without name to the grammar
150
if (type != null) {
151             grammar.addGlobalTypeDecl(type);
152         }
153
154         return type;
155     }
156
157     XSSimpleType traverseLocal(Element JavaDoc elmNode,
158                                XSDocumentInfo schemaDoc,
159                                SchemaGrammar grammar) {
160
161         // General Attribute Checking
162
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(elmNode, false, schemaDoc);
163         XSSimpleType type = traverseSimpleTypeDecl (elmNode, attrValues, schemaDoc, grammar);
164         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
165
166         return type;
167     }
168
169     private XSSimpleType traverseSimpleTypeDecl(Element JavaDoc simpleTypeDecl,
170                                                 Object JavaDoc[] attrValues,
171                                                 XSDocumentInfo schemaDoc,
172                                                 SchemaGrammar grammar) {
173
174         // get name and final values
175
String JavaDoc name = (String JavaDoc)attrValues[XSAttributeChecker.ATTIDX_NAME];
176         XInt finalAttr = (XInt)attrValues[XSAttributeChecker.ATTIDX_FINAL];
177         int finalProperty = finalAttr == null ? schemaDoc.fFinalDefault : finalAttr.intValue();
178
179         // annotation?,(list|restriction|union)
180
Element JavaDoc child = DOMUtil.getFirstChildElement(simpleTypeDecl);
181         XSAnnotationImpl [] annotations = null;
182         if (child != null) {
183             // traverse annotation if any
184
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
185                 XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
186                 if (annotation != null)
187                     annotations = new XSAnnotationImpl [] {annotation};
188                 child = DOMUtil.getNextSiblingElement(child);
189             }
190         }
191
192         // (list|restriction|union)
193
if (child == null) {
194             reportSchemaError("s4s-elt-must-match.2", new Object JavaDoc[]{SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))"}, simpleTypeDecl);
195             return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
196         }
197
198         // derivation type: restriction/list/union
199
String JavaDoc varietyProperty = DOMUtil.getLocalName(child);
200         short refType = XSConstants.DERIVATION_RESTRICTION;
201         boolean restriction = false, list = false, union = false;
202         if (varietyProperty.equals(SchemaSymbols.ELT_RESTRICTION)) {
203             refType = XSConstants.DERIVATION_RESTRICTION;
204             restriction = true;
205         }
206         else if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) {
207             refType = XSConstants.DERIVATION_LIST;
208             list = true;
209         }
210         else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) {
211             refType = XSConstants.DERIVATION_UNION;
212             union = true;
213         }
214         else {
215             reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))", varietyProperty}, simpleTypeDecl);
216             return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
217         }
218
219         // nothing should follow this element
220
Element JavaDoc nextChild = DOMUtil.getNextSiblingElement(child);
221         if (nextChild != null) {
222             reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))", DOMUtil.getLocalName(nextChild)}, nextChild);
223         }
224         
225         // General Attribute Checking: get base/item/member types
226
Object JavaDoc[] contentAttrs = fAttrChecker.checkAttributes(child, false, schemaDoc);
227         QName baseTypeName = (QName)contentAttrs[restriction ?
228                                                  XSAttributeChecker.ATTIDX_BASE :
229                                                  XSAttributeChecker.ATTIDX_ITEMTYPE];
230         Vector JavaDoc memberTypes = (Vector JavaDoc)contentAttrs[XSAttributeChecker.ATTIDX_MEMBERTYPES];
231
232         //content = {annotation?,simpleType?...}
233
Element JavaDoc content = DOMUtil.getFirstChildElement(child);
234
235         //check content (annotation?, ...)
236
if (content != null) {
237             // traverse annotation if any
238
if (DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_ANNOTATION)) {
239                 XSAnnotationImpl annotation = traverseAnnotationDecl(content, contentAttrs, false, schemaDoc);
240                 if(annotation != null ) {
241                     if(annotations == null)
242                         annotations = new XSAnnotationImpl [] {annotation};
243                     else {
244                         XSAnnotationImpl [] tempArray = new XSAnnotationImpl[2];
245                         tempArray[0] = annotations[0];
246                         annotations = tempArray;
247                         annotations[1] = annotation;
248                     }
249                 }
250                 content = DOMUtil.getNextSiblingElement(content);
251             }
252         }
253
254         // get base type from "base" attribute
255
XSSimpleType baseValidator = null;
256         if ((restriction || list) && baseTypeName != null) {
257             baseValidator = findDTValidator(child, name, baseTypeName, refType, schemaDoc);
258             // if its the built-in type, return null from here
259
if (baseValidator == null && fIsBuiltIn) {
260                 fIsBuiltIn = false;
261                 return null;
262             }
263         }
264
265         // get types from "memberTypes" attribute
266
Vector JavaDoc dTValidators = null;
267         XSSimpleType dv = null;
268         XSObjectList dvs;
269         if (union && memberTypes != null && memberTypes.size() > 0) {
270             int size = memberTypes.size();
271             dTValidators = new Vector JavaDoc(size, 2);
272             // for each qname in the list
273
for (int i = 0; i < size; i++) {
274                 // get the type decl
275
dv = findDTValidator(child, name, (QName)memberTypes.elementAt(i),
276                                      XSConstants.DERIVATION_UNION, schemaDoc);
277                 if (dv != null) {
278                     // if it's a union, expand it
279
if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
280                         dvs = dv.getMemberTypes();
281                         for (int j = 0; j < dvs.getLength(); j++)
282                             dTValidators.addElement(dvs.item(j));
283                     } else {
284                         dTValidators.addElement(dv);
285                     }
286                 }
287             }
288         }
289
290         // when there is an error finding the base type of a restriction
291
// we use anySimpleType as the base, then we should skip the facets,
292
// because anySimpleType doesn't recognize any facet.
293
boolean skipFacets = false;
294         
295         // check if there is a child "simpleType"
296
if (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE)) {
297             if (restriction || list) {
298                 // it's an error for both "base" and "simpleType" to appear
299
if (baseTypeName != null) {
300                     reportSchemaError(list ? "src-simple-type.3.a" : "src-simple-type.2.a", null, content);
301                 }
302                 else {
303                     // traver this child to get the base type
304
baseValidator = traverseLocal(content, schemaDoc, grammar);
305                 }
306                 // get the next element
307
content = DOMUtil.getNextSiblingElement(content);
308             }
309             else if (union) {
310                 if (dTValidators == null) {
311                     dTValidators = new Vector JavaDoc(2, 2);
312                 }
313                 do {
314                     // traver this child to get the member type
315
dv = traverseLocal(content, schemaDoc, grammar);
316                     if (dv != null) {
317                         // if it's a union, expand it
318
if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
319                             dvs = dv.getMemberTypes();
320                             for (int j = 0; j < dvs.getLength(); j++)
321                                 dTValidators.addElement(dvs.item(j));
322                         } else {
323                             dTValidators.addElement(dv);
324                         }
325                     }
326                     // get the next element
327
content = DOMUtil.getNextSiblingElement(content);
328                 } while (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE));
329             }
330         }
331         else if ((restriction || list) && baseTypeName == null) {
332             // it's an error if neither "base" nor "simpleType" appears
333
reportSchemaError(list ? "src-simple-type.3.b" : "src-simple-type.2.b", null, child);
334             // base can't be found, skip the facets.
335
skipFacets = true;
336             baseValidator = SchemaGrammar.fAnySimpleType;
337         }
338         else if (union && (memberTypes == null || memberTypes.size() == 0)) {
339             // it's an error if "memberTypes" is empty and no "simpleType" appears
340
reportSchemaError("src-union-memberTypes-or-simpleTypes", null, child);
341             dTValidators = new Vector JavaDoc(1);
342             dTValidators.addElement(SchemaGrammar.fAnySimpleType);
343         }
344
345         // error finding "base" or error traversing "simpleType".
346
// don't need to report an error, since some error has been reported.
347
if ((restriction || list) && baseValidator == null) {
348             baseValidator = SchemaGrammar.fAnySimpleType;
349         }
350         // error finding "memberTypes" or error traversing "simpleType".
351
// don't need to report an error, since some error has been reported.
352
if (union && (dTValidators == null || dTValidators.size() == 0)) {
353             dTValidators = new Vector JavaDoc(1);
354             dTValidators.addElement(SchemaGrammar.fAnySimpleType);
355         }
356
357         // item type of list types can't have list content
358
if (list && isListDatatype(baseValidator)) {
359             reportSchemaError("cos-st-restricts.2.1", new Object JavaDoc[]{name, baseValidator.getName()}, child);
360         }
361         
362         // create the simple type based on the "base" type
363
XSSimpleType newDecl = null;
364         if (restriction) {
365             newDecl = schemaFactory.createTypeRestriction(name, schemaDoc.fTargetNamespace, (short)finalProperty, baseValidator,
366                 annotations == null? null : new XSObjectListImpl(annotations, annotations.length));
367         }
368         else if (list) {
369             newDecl = schemaFactory.createTypeList(name, schemaDoc.fTargetNamespace, (short)finalProperty, baseValidator,
370                 annotations == null? null : new XSObjectListImpl(annotations, annotations.length));
371         }
372         else if (union) {
373             XSSimpleType[] memberDecls = new XSSimpleType[dTValidators.size()];
374             for (int i = 0; i < dTValidators.size(); i++)
375                 memberDecls[i] = (XSSimpleType)dTValidators.elementAt(i);
376             newDecl = schemaFactory.createTypeUnion(name, schemaDoc.fTargetNamespace, (short)finalProperty, memberDecls,
377                 annotations == null? null : new XSObjectListImpl(annotations, annotations.length));
378         }
379
380         // now traverse facets, if it's derived by restriction
381
if (restriction && content != null) {
382             FacetInfo fi = traverseFacets(content, baseValidator, schemaDoc);
383             content = fi.nodeAfterFacets;
384
385             if (!skipFacets) {
386                 try {
387                     fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
388                     newDecl.applyFacets(fi.facetdata, fi.fPresentFacets, fi.fFixedFacets, fValidationState);
389                 } catch (InvalidDatatypeFacetException ex) {
390                     reportSchemaError(ex.getKey(), ex.getArgs(), child);
391                 }
392             }
393         }
394
395         // now element should appear after this point
396
if (content != null) {
397             if (restriction) {
398                 reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{SchemaSymbols.ELT_RESTRICTION, "(annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))", DOMUtil.getLocalName(content)}, content);
399             }
400             else if (list) {
401                 reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{SchemaSymbols.ELT_LIST, "(annotation?, (simpleType?))", DOMUtil.getLocalName(content)}, content);
402             }
403             else if (union) {
404                 reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{SchemaSymbols.ELT_UNION, "(annotation?, (simpleType*))", DOMUtil.getLocalName(content)}, content);
405             }
406         }
407         
408         fAttrChecker.returnAttrArray(contentAttrs, schemaDoc);
409
410         // return the new type
411
return newDecl;
412     }
413
414     //@param: elm - top element
415
//@param: baseTypeStr - type (base/itemType/memberTypes)
416
//@param: baseRefContext: whether the caller is using this type as a base for restriction, union or list
417
//return XSSimpleType available for the baseTypeStr, null if not found or disallowed.
418
// also throws an error if the base type won't allow itself to be used in this context.
419
// REVISIT: can this code be re-used?
420
private XSSimpleType findDTValidator(Element JavaDoc elm, String JavaDoc refName,
421                                          QName baseTypeStr, short baseRefContext,
422                                          XSDocumentInfo schemaDoc) {
423         if (baseTypeStr == null)
424             return null;
425
426         XSTypeDefinition baseType = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, baseTypeStr, elm);
427         if (baseType != null) {
428             // if it's a complex type, or if its restriction of anySimpleType
429
if (baseType.getTypeCategory() != XSTypeDefinition.SIMPLE_TYPE ||
430                 (baseType == SchemaGrammar.fAnySimpleType &&
431                 baseRefContext == XSConstants.DERIVATION_RESTRICTION)) {
432                 // if the base type is anySimpleType and the current type is
433
// a S4S built-in type, return null. (not an error).
434
if (baseType == SchemaGrammar.fAnySimpleType &&
435                     checkBuiltIn(refName, schemaDoc.fTargetNamespace)) {
436                     return null;
437                 }
438                 reportSchemaError("cos-st-restricts.1.1", new Object JavaDoc[]{baseTypeStr.rawname, refName}, elm);
439                 return SchemaGrammar.fAnySimpleType;
440             }
441             if ((baseType.getFinal() & baseRefContext) != 0) {
442                 if (baseRefContext == XSConstants.DERIVATION_RESTRICTION) {
443                     reportSchemaError("st-props-correct.3", new Object JavaDoc[]{refName, baseTypeStr.rawname}, elm);
444                 }
445                 else if (baseRefContext == XSConstants.DERIVATION_LIST) {
446                     reportSchemaError("cos-st-restricts.2.3.1.1", new Object JavaDoc[]{baseTypeStr.rawname, refName}, elm);
447                 }
448                 else if (baseRefContext == XSConstants.DERIVATION_UNION) {
449                     reportSchemaError("cos-st-restricts.3.3.1.1", new Object JavaDoc[]{baseTypeStr.rawname, refName}, elm);
450                 }
451             }
452         }
453
454         return (XSSimpleType)baseType;
455     }
456
457     // check whethe the type denoted by the name and namespace is a S4S
458
// built-in type. update fIsBuiltIn at the same time.
459
private final boolean checkBuiltIn(String JavaDoc name, String JavaDoc namespace) {
460         if (namespace != SchemaSymbols.URI_SCHEMAFORSCHEMA)
461             return false;
462         if (SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(name) != null)
463             fIsBuiltIn = true;
464         return fIsBuiltIn;
465     }
466
467     // find if a datatype validator is a list or has list datatype member.
468
private boolean isListDatatype(XSSimpleType validator) {
469         if (validator.getVariety() == XSSimpleType.VARIETY_LIST)
470             return true;
471
472         if (validator.getVariety() == XSSimpleType.VARIETY_UNION) {
473             XSObjectList temp = validator.getMemberTypes();
474             for (int i = 0; i < temp.getLength(); i++) {
475                 if (((XSSimpleType)temp.item(i)).getVariety() == XSSimpleType.VARIETY_LIST) {
476                     return true;
477                 }
478             }
479         }
480
481         return false;
482     }//isListDatatype(XSSimpleTypeDecl):boolean
483

484     private XSSimpleType errorType(String JavaDoc name, String JavaDoc namespace, short refType) {
485         switch (refType) {
486         case XSConstants.DERIVATION_RESTRICTION:
487             return schemaFactory.createTypeRestriction(name, namespace, (short)0,
488                                                        SchemaGrammar.fAnySimpleType, null);
489         case XSConstants.DERIVATION_LIST:
490             return schemaFactory.createTypeList(name, namespace, (short)0,
491                                                 SchemaGrammar.fAnySimpleType, null);
492         case XSConstants.DERIVATION_UNION:
493             return schemaFactory.createTypeUnion(name, namespace, (short)0,
494                                                  new XSSimpleType[]{SchemaGrammar.fAnySimpleType}, null);
495         }
496         
497         return null;
498     }
499     
500 }//class XSDSimpleTypeTraverser
501
Popular Tags