KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.Vector JavaDoc;
20
21 import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
22 import org.apache.xerces.impl.dv.XSFacets;
23 import org.apache.xerces.impl.dv.XSSimpleType;
24 import org.apache.xerces.impl.validation.ValidationState;
25 import org.apache.xerces.impl.xs.SchemaGrammar;
26 import org.apache.xerces.impl.xs.SchemaSymbols;
27 import org.apache.xerces.impl.xs.XSAnnotationImpl;
28 import org.apache.xerces.impl.xs.XSAttributeGroupDecl;
29 import org.apache.xerces.impl.xs.XSAttributeUseImpl;
30 import org.apache.xerces.impl.xs.XSComplexTypeDecl;
31 import org.apache.xerces.impl.xs.XSElementDecl;
32 import org.apache.xerces.impl.xs.XSParticleDecl;
33 import org.apache.xerces.impl.xs.XSWildcardDecl;
34 import org.apache.xerces.xs.XSObjectList;
35 import org.apache.xerces.xs.XSTypeDefinition;
36 import org.apache.xerces.impl.xs.util.XInt;
37 import org.apache.xerces.impl.xs.util.XSObjectListImpl;
38 import org.apache.xerces.util.DOMUtil;
39 import org.apache.xerces.util.NamespaceSupport;
40 import org.apache.xerces.util.SymbolTable;
41 import org.apache.xerces.xni.QName;
42 import org.w3c.dom.Element JavaDoc;
43 import org.w3c.dom.Node JavaDoc;
44 import org.w3c.dom.Text JavaDoc;
45
46 /**
47  * Class <code>XSDAbstractTraverser</code> serves as the base class for all
48  * other <code>XSD???Traverser</code>s. It holds the common data and provide
49  * a unified way to initialize these data.
50  *
51  * @xerces.internal
52  *
53  * @author Elena Litani, IBM
54  * @author Rahul Srivastava, Sun Microsystems Inc.
55  * @author Neeraj Bajaj, Sun Microsystems Inc.
56  *
57  * @version $Id: XSDAbstractTraverser.java,v 1.41 2004/12/20 05:43:36 mrglavas Exp $
58  */

59 abstract class XSDAbstractTraverser {
60     
61     protected static final String JavaDoc NO_NAME = "(no name)";
62     
63     // Flags for checkOccurrences to indicate any special
64
// restrictions on minOccurs and maxOccurs relating to "all".
65
// NOT_ALL_CONTEXT - not processing an <all>
66
// PROCESSING_ALL_EL - processing an <element> in an <all>
67
// GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
68
// CHILD_OF_GROUP - processing a child of a model group definition
69
// PROCESSING_ALL_GP - processing an <all> group itself
70

71     protected static final int NOT_ALL_CONTEXT = 0;
72     protected static final int PROCESSING_ALL_EL = 1;
73     protected static final int GROUP_REF_WITH_ALL = 2;
74     protected static final int CHILD_OF_GROUP = 4;
75     protected static final int PROCESSING_ALL_GP = 8;
76     
77     //Shared data
78
protected XSDHandler fSchemaHandler = null;
79     protected SymbolTable fSymbolTable = null;
80     protected XSAttributeChecker fAttrChecker = null;
81     protected boolean fValidateAnnotations = false;
82     
83     // used to validate default/fixed attribute values
84
ValidationState fValidationState = new ValidationState();
85     
86     XSDAbstractTraverser (XSDHandler handler,
87             XSAttributeChecker attrChecker) {
88         fSchemaHandler = handler;
89         fAttrChecker = attrChecker;
90     }
91     
92     void reset(SymbolTable symbolTable, boolean validateAnnotations) {
93         fSymbolTable = symbolTable;
94         fValidateAnnotations = validateAnnotations;
95         fValidationState.setExtraChecking(false);
96         fValidationState.setSymbolTable(symbolTable);
97     }
98     
99     // traverse the annotation declaration
100
// REVISIT: how to pass the parentAttrs? as DOM attributes?
101
// as name/value pairs (string)? in parsed form?
102
// @return XSAnnotationImpl object
103
XSAnnotationImpl traverseAnnotationDecl(Element JavaDoc annotationDecl, Object JavaDoc[] parentAttrs,
104             boolean isGlobal, XSDocumentInfo schemaDoc) {
105         // General Attribute Checking
106
Object JavaDoc[] attrValues = fAttrChecker.checkAttributes(annotationDecl, isGlobal, schemaDoc);
107         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
108         
109         String JavaDoc contents = null;
110         Element JavaDoc child = DOMUtil.getFirstChildElement(annotationDecl);
111         if (child != null) {
112             do {
113                 String JavaDoc name = DOMUtil.getLocalName(child);
114                 
115                 // the only valid children of "annotation" are
116
// "appinfo" and "documentation"
117
if (!((name.equals(SchemaSymbols.ELT_APPINFO)) ||
118                         (name.equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
119                     reportSchemaError("src-annotation", new Object JavaDoc[]{name}, child);
120                 } else { // the annotation, as we currently know it, is a Text child
121
Node JavaDoc textContent = child.getFirstChild();
122                     if(textContent != null && textContent.getNodeType() == Node.TEXT_NODE) {
123                         contents = ((Text JavaDoc)textContent).getData();
124                     }
125                 }
126                 
127                 // General Attribute Checking
128
// There is no difference between global or local appinfo/documentation,
129
// so we assume it's always global.
130
attrValues = fAttrChecker.checkAttributes(child, true, schemaDoc);
131                 fAttrChecker.returnAttrArray(attrValues, schemaDoc);
132                 
133                 child = DOMUtil.getNextSiblingElement(child);
134             }
135             while (child != null);
136         }
137         // REVISIT: When an annotation has no <documentation> or
138
// <appinfo> children the text child is stored on the first child of its
139
// parent. Only if the annotation is the first child will we find the
140
// text node there. See SchemaDOM. We need to store the string representation
141
// in a consistent place so it can be reliably retrieved, perhaps as
142
// user data. -- mrglavas
143
else {
144             Node JavaDoc textContent = annotationDecl.getFirstChild();
145             if(textContent != null && textContent.getNodeType() == Node.TEXT_NODE) {
146                 contents = ((Text JavaDoc)textContent).getData();
147             }
148         }
149         // if contents was null, must have been some kind of error;
150
// nothing to contribute to PSVI
151
if (contents == null) return null;
152         
153         // find the grammar; fSchemaHandler must be known!
154
SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
155         // fish out local attributes passed from parent
156
Vector JavaDoc annotationLocalAttrs = (Vector JavaDoc)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
157         // optimize for case where there are no local attributes
158
if(annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
159             StringBuffer JavaDoc localStrBuffer = new StringBuffer JavaDoc(64);
160             localStrBuffer.append(" ");
161             // Vector should contain rawname value pairs
162
int i = 0;
163             while (i < annotationLocalAttrs.size()) {
164                 String JavaDoc rawname = (String JavaDoc)annotationLocalAttrs.elementAt(i++);
165                 int colonIndex = rawname.indexOf(':');
166                 String JavaDoc prefix, localpart;
167                 if (colonIndex == -1) {
168                     prefix = "";
169                     localpart = rawname;
170                 }
171                 else {
172                     prefix = rawname.substring(0,colonIndex);
173                     localpart = rawname.substring(colonIndex+1);
174                 }
175                 String JavaDoc uri = schemaDoc.fNamespaceSupport.getURI(prefix.intern());
176                 if (!annotationDecl.getAttributeNS(uri, localpart).equals("")) {
177                     i++; // skip the next value, too
178
continue;
179                 }
180                 localStrBuffer.append(rawname)
181                 .append("=\"");
182                 String JavaDoc value = (String JavaDoc)annotationLocalAttrs.elementAt(i++);
183                 // search for pesky "s and >s within attr value:
184
value = processAttValue(value);
185                 localStrBuffer.append(value)
186                 .append("\" ");
187             }
188             // and now splice it into place; immediately after the annotation token, for simplicity's sake
189
StringBuffer JavaDoc contentBuffer = new StringBuffer JavaDoc(contents.length() + localStrBuffer.length());
190             int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
191             // annotation must occur somewhere or we're in big trouble...
192
if(annotationTokenEnd == -1) return null;
193             annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
194             contentBuffer.append(contents.substring(0,annotationTokenEnd));
195             contentBuffer.append(localStrBuffer.toString());
196             contentBuffer.append(contents.substring(annotationTokenEnd, contents.length()));
197             final String JavaDoc annotation = contentBuffer.toString();
198             if (fValidateAnnotations) {
199                 schemaDoc.addAnnotation(new XSAnnotationInfo(annotation, annotationDecl));
200             }
201             return new XSAnnotationImpl(annotation, grammar);
202         } else {
203             if (fValidateAnnotations) {
204                 schemaDoc.addAnnotation(new XSAnnotationInfo(contents, annotationDecl));
205             }
206             return new XSAnnotationImpl(contents, grammar);
207         }
208         
209     }
210     
211     XSAnnotationImpl traverseSyntheticAnnotation(Element JavaDoc annotationParent, String JavaDoc initialContent,
212             Object JavaDoc[] parentAttrs, boolean isGlobal, XSDocumentInfo schemaDoc) {
213         
214         String JavaDoc contents = initialContent;
215         
216         // find the grammar; fSchemaHandler must be known!
217
SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
218         // fish out local attributes passed from parent
219
Vector JavaDoc annotationLocalAttrs = (Vector JavaDoc)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
220         // optimize for case where there are no local attributes
221
if (annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
222             StringBuffer JavaDoc localStrBuffer = new StringBuffer JavaDoc(64);
223             localStrBuffer.append(" ");
224             // Vector should contain rawname value pairs
225
int i = 0;
226             while (i < annotationLocalAttrs.size()) {
227                 String JavaDoc rawname = (String JavaDoc)annotationLocalAttrs.elementAt(i++);
228                 int colonIndex = rawname.indexOf(':');
229                 String JavaDoc prefix, localpart;
230                 if (colonIndex == -1) {
231                     prefix = "";
232                     localpart = rawname;
233                 }
234                 else {
235                     prefix = rawname.substring(0,colonIndex);
236                     localpart = rawname.substring(colonIndex+1);
237                 }
238                 String JavaDoc uri = schemaDoc.fNamespaceSupport.getURI(prefix.intern());
239                 localStrBuffer.append(rawname)
240                 .append("=\"");
241                 String JavaDoc value = (String JavaDoc)annotationLocalAttrs.elementAt(i++);
242                 // search for pesky "s and >s within attr value:
243
value = processAttValue(value);
244                 localStrBuffer.append(value)
245                 .append("\" ");
246             }
247             // and now splice it into place; immediately after the annotation token, for simplicity's sake
248
StringBuffer JavaDoc contentBuffer = new StringBuffer JavaDoc(contents.length() + localStrBuffer.length());
249             int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
250             // annotation must occur somewhere or we're in big trouble...
251
if(annotationTokenEnd == -1) return null;
252             annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
253             contentBuffer.append(contents.substring(0,annotationTokenEnd));
254             contentBuffer.append(localStrBuffer.toString());
255             contentBuffer.append(contents.substring(annotationTokenEnd, contents.length()));
256             final String JavaDoc annotation = contentBuffer.toString();
257             if (fValidateAnnotations) {
258                 schemaDoc.addAnnotation(new XSAnnotationInfo(annotation, annotationParent));
259             }
260             return new XSAnnotationImpl(annotation, grammar);
261         } else {
262             if (fValidateAnnotations) {
263                 schemaDoc.addAnnotation(new XSAnnotationInfo(contents, annotationParent));
264             }
265             return new XSAnnotationImpl(contents, grammar);
266         }
267     }
268     
269     // the QName simple type used to resolve qnames
270
private static final XSSimpleType fQNameDV = (XSSimpleType)SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
271     // Temp data structures to be re-used in traversing facets
272
private StringBuffer JavaDoc fPattern = new StringBuffer JavaDoc();
273     private final XSFacets xsFacets = new XSFacets();
274     
275     class FacetInfo {
276         XSFacets facetdata;
277         Element JavaDoc nodeAfterFacets;
278         short fPresentFacets;
279         short fFixedFacets;
280     }
281     
282     FacetInfo traverseFacets(Element JavaDoc content,
283             XSSimpleType baseValidator,
284             XSDocumentInfo schemaDoc) {
285         
286         short facetsPresent = 0 ;
287         short facetsFixed = 0; // facets that have fixed="true"
288
String JavaDoc facet;
289         boolean hasQName = containsQName(baseValidator);
290         Vector JavaDoc enumData = null;
291         XSObjectListImpl enumAnnotations = null;
292         XSObjectListImpl patternAnnotations = null;
293         Vector JavaDoc enumNSDecls = hasQName ? new Vector JavaDoc() : null;
294         int currentFacet = 0;
295         xsFacets.reset();
296         while (content != null) {
297             // General Attribute Checking
298
Object JavaDoc[] attrs = null;
299             facet = DOMUtil.getLocalName(content);
300             if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
301                 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName);
302                 String JavaDoc enumVal = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
303                 NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS];
304                 
305                 // for NOTATION types, need to check whether there is a notation
306
// declared with the same name as the enumeration value.
307
if (baseValidator.getVariety() == XSSimpleType.VARIETY_ATOMIC &&
308                         baseValidator.getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
309                     // need to use the namespace context returned from checkAttributes
310
schemaDoc.fValidationContext.setNamespaceSupport(nsDecls);
311                     try{
312                         QName temp = (QName)fQNameDV.validate(enumVal, schemaDoc.fValidationContext, null);
313                         // try to get the notation decl. if failed, getGlobalDecl
314
// reports an error, so we don't need to report one again.
315
fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.NOTATION_TYPE, temp, content);
316                     }catch(InvalidDatatypeValueException ex){
317                         reportSchemaError(ex.getKey(), ex.getArgs(), content);
318                     }
319                     // restore to the normal namespace context
320
schemaDoc.fValidationContext.setNamespaceSupport(schemaDoc.fNamespaceSupport);
321                 }
322                 if (enumData == null){
323                     enumData = new Vector JavaDoc();
324                     enumAnnotations = new XSObjectListImpl();
325                 }
326                 enumData.addElement(enumVal);
327                 enumAnnotations.add(null);
328                 if (hasQName)
329                     enumNSDecls.addElement(nsDecls);
330                 Element JavaDoc child = DOMUtil.getFirstChildElement( content );
331                 
332                 if (child != null) {
333                     // traverse annotation if any
334

335                     if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
336                         enumAnnotations.add(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
337                         child = DOMUtil.getNextSiblingElement(child);
338                     }
339                     else {
340                         String JavaDoc text = DOMUtil.getSyntheticAnnotation(content);
341                         if (text != null) {
342                             enumAnnotations.add(enumAnnotations.getLength()-1, traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
343                         }
344                     }
345                     if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
346                         reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
347                     }
348                 }
349                 else {
350                     String JavaDoc text = DOMUtil.getSyntheticAnnotation(content);
351                     if (text != null) {
352                         enumAnnotations.add(enumAnnotations.getLength() - 1, traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
353                     }
354                 }
355             }
356             else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
357                 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
358                 if (fPattern.length() == 0) {
359                     fPattern.append((String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE]);
360                 } else {
361                     // ---------------------------------------------
362
//datatypes: 5.2.4 pattern: src-multiple-pattern
363
// ---------------------------------------------
364
fPattern.append("|");
365                     fPattern.append((String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE]);
366                 }
367                 Element JavaDoc child = DOMUtil.getFirstChildElement( content );
368                 if (child != null) {
369                     // traverse annotation if any
370
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
371                         if (patternAnnotations == null){
372                             patternAnnotations = new XSObjectListImpl();
373                         }
374                         patternAnnotations.add(traverseAnnotationDecl(child, attrs, false, schemaDoc));
375                         child = DOMUtil.getNextSiblingElement(child);
376                     }
377                     if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
378                         reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{"pattern", "(annotation?)", DOMUtil.getLocalName(child)}, child);
379                     }
380                 }
381                 
382             }
383             else {
384                 if (facet.equals(SchemaSymbols.ELT_MINLENGTH)) {
385                     currentFacet = XSSimpleType.FACET_MINLENGTH;
386                 }
387                 else if (facet.equals(SchemaSymbols.ELT_MAXLENGTH)) {
388                     currentFacet = XSSimpleType.FACET_MAXLENGTH;
389                 }
390                 else if (facet.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
391                     currentFacet = XSSimpleType.FACET_MAXEXCLUSIVE;
392                 }
393                 else if (facet.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
394                     currentFacet = XSSimpleType.FACET_MAXINCLUSIVE;
395                 }
396                 else if (facet.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
397                     currentFacet = XSSimpleType.FACET_MINEXCLUSIVE;
398                 }
399                 else if (facet.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
400                     currentFacet = XSSimpleType.FACET_MININCLUSIVE;
401                 }
402                 else if (facet.equals(SchemaSymbols.ELT_TOTALDIGITS)) {
403                     currentFacet = XSSimpleType.FACET_TOTALDIGITS;
404                 }
405                 else if (facet.equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
406                     currentFacet = XSSimpleType.FACET_FRACTIONDIGITS;
407                 }
408                 else if (facet.equals(SchemaSymbols.ELT_WHITESPACE)) {
409                     currentFacet = XSSimpleType.FACET_WHITESPACE;
410                 }
411                 else if (facet.equals(SchemaSymbols.ELT_LENGTH)) {
412                     currentFacet = XSSimpleType.FACET_LENGTH;
413                 }
414                 else {
415                     break; // a non-facet
416
}
417                 
418                 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
419                 
420                 // check for duplicate facets
421
if ((facetsPresent & currentFacet) != 0) {
422                     reportSchemaError("src-single-facet-value", new Object JavaDoc[]{facet}, content);
423                 } else if (attrs[XSAttributeChecker.ATTIDX_VALUE] != null) {
424                     facetsPresent |= currentFacet;
425                     // check for fixed facet
426
if (((Boolean JavaDoc)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
427                         facetsFixed |= currentFacet;
428                     }
429                     switch (currentFacet) {
430                     case XSSimpleType.FACET_MINLENGTH:
431                         xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
432                     break;
433                     case XSSimpleType.FACET_MAXLENGTH:
434                         xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
435                     break;
436                     case XSSimpleType.FACET_MAXEXCLUSIVE:
437                         xsFacets.maxExclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
438                     break;
439                     case XSSimpleType.FACET_MAXINCLUSIVE:
440                         xsFacets.maxInclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
441                     break;
442                     case XSSimpleType.FACET_MINEXCLUSIVE:
443                         xsFacets.minExclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
444                     break;
445                     case XSSimpleType.FACET_MININCLUSIVE:
446                         xsFacets.minInclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
447                     break;
448                     case XSSimpleType.FACET_TOTALDIGITS:
449                         xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
450                     break;
451                     case XSSimpleType.FACET_FRACTIONDIGITS:
452                         xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
453                     break;
454                     case XSSimpleType.FACET_WHITESPACE:
455                         xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
456                     break;
457                     case XSSimpleType.FACET_LENGTH:
458                         xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
459                     break;
460                     }
461                 }
462                 
463                 Element JavaDoc child = DOMUtil.getFirstChildElement( content );
464                 if (child != null) {
465                     // traverse annotation if any
466
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
467                         XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
468                         switch (currentFacet) {
469                         case XSSimpleType.FACET_MINLENGTH:
470                             xsFacets.minLengthAnnotation = annotation;
471                         break;
472                         case XSSimpleType.FACET_MAXLENGTH:
473                             xsFacets.maxLengthAnnotation = annotation;
474                         break;
475                         case XSSimpleType.FACET_MAXEXCLUSIVE:
476                             xsFacets.maxExclusiveAnnotation = annotation;
477                         break;
478                         case XSSimpleType.FACET_MAXINCLUSIVE:
479                             xsFacets.maxInclusiveAnnotation = annotation;
480                         break;
481                         case XSSimpleType.FACET_MINEXCLUSIVE:
482                             xsFacets.minExclusiveAnnotation = annotation;
483                         break;
484                         case XSSimpleType.FACET_MININCLUSIVE:
485                             xsFacets.minInclusiveAnnotation = annotation;
486                         break;
487                         case XSSimpleType.FACET_TOTALDIGITS:
488                             xsFacets.totalDigitsAnnotation = annotation;
489                         break;
490                         case XSSimpleType.FACET_FRACTIONDIGITS:
491                             xsFacets.fractionDigitsAnnotation = annotation;
492                         break;
493                         case XSSimpleType.FACET_WHITESPACE:
494                             xsFacets.whiteSpaceAnnotation = annotation;
495                         break;
496                         case XSSimpleType.FACET_LENGTH:
497                             xsFacets.lengthAnnotation = annotation;
498                         break;
499                         }
500                         
501                         
502                         child = DOMUtil.getNextSiblingElement(child);
503                     }
504                     else {
505                         String JavaDoc text = DOMUtil.getSyntheticAnnotation(content);
506                         if (text != null) {
507                             XSAnnotationImpl annotation = traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc);
508                             switch (currentFacet) {
509                                 case XSSimpleType.FACET_MINLENGTH:
510                                     xsFacets.minLengthAnnotation = annotation;
511                                     break;
512                                 case XSSimpleType.FACET_MAXLENGTH:
513                                     xsFacets.maxLengthAnnotation = annotation;
514                                     break;
515                                 case XSSimpleType.FACET_MAXEXCLUSIVE:
516                                     xsFacets.maxExclusiveAnnotation = annotation;
517                                     break;
518                                 case XSSimpleType.FACET_MAXINCLUSIVE:
519                                     xsFacets.maxInclusiveAnnotation = annotation;
520                                     break;
521                                 case XSSimpleType.FACET_MINEXCLUSIVE:
522                                     xsFacets.minExclusiveAnnotation = annotation;
523                                     break;
524                                 case XSSimpleType.FACET_MININCLUSIVE:
525                                     xsFacets.minInclusiveAnnotation = annotation;
526                                     break;
527                                 case XSSimpleType.FACET_TOTALDIGITS:
528                                     xsFacets.totalDigitsAnnotation = annotation;
529                                     break;
530                                 case XSSimpleType.FACET_FRACTIONDIGITS:
531                                     xsFacets.fractionDigitsAnnotation = annotation;
532                                     break;
533                                 case XSSimpleType.FACET_WHITESPACE:
534                                     xsFacets.whiteSpaceAnnotation = annotation;
535                                     break;
536                                 case XSSimpleType.FACET_LENGTH:
537                                     xsFacets.lengthAnnotation = annotation;
538                                     break;
539                             }
540                         }
541                     }
542                     if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
543                         reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
544                     }
545                 }
546             }
547             fAttrChecker.returnAttrArray (attrs, schemaDoc);
548             content = DOMUtil.getNextSiblingElement(content);
549         }
550         if (enumData !=null) {
551             facetsPresent |= XSSimpleType.FACET_ENUMERATION;
552             xsFacets.enumeration = enumData;
553             xsFacets.enumNSDecls = enumNSDecls;
554             xsFacets.enumAnnotations = enumAnnotations;
555         }
556         if (fPattern.length() != 0) {
557             facetsPresent |= XSSimpleType.FACET_PATTERN;
558             xsFacets.pattern = fPattern.toString();
559             xsFacets.patternAnnotations = patternAnnotations;
560         }
561         
562         fPattern.setLength(0);
563         
564         FacetInfo fi = new FacetInfo();
565         fi.facetdata = xsFacets;
566         fi.nodeAfterFacets = content;
567         fi.fPresentFacets = facetsPresent;
568         fi.fFixedFacets = facetsFixed;
569         return fi;
570     }
571     
572     
573     // return whether QName/NOTATION is part of the given type
574
private boolean containsQName(XSSimpleType type) {
575         if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
576             short primitive = type.getPrimitiveKind();
577             return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
578                     primitive == XSSimpleType.PRIMITIVE_NOTATION);
579         }
580         else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
581             return containsQName((XSSimpleType)type.getItemType());
582         }
583         else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
584             XSObjectList members = type.getMemberTypes();
585             for (int i = 0; i < members.getLength(); i++) {
586                 if (containsQName((XSSimpleType)members.item(i)))
587                     return true;
588             }
589         }
590         return false;
591     }
592     
593     //
594
// Traverse a set of attribute and attribute group elements
595
// Needed by complexType and attributeGroup traversal
596
// This method will return the first non-attribute/attrgrp found
597
//
598
Element JavaDoc traverseAttrsAndAttrGrps(Element JavaDoc firstAttr, XSAttributeGroupDecl attrGrp,
599             XSDocumentInfo schemaDoc, SchemaGrammar grammar,
600             XSComplexTypeDecl enclosingCT) {
601         
602         Element JavaDoc child=null;
603         XSAttributeGroupDecl tempAttrGrp = null;
604         XSAttributeUseImpl tempAttrUse = null;
605         String JavaDoc childName;
606         
607         for (child=firstAttr; child!=null; child=DOMUtil.getNextSiblingElement(child)) {
608             childName = DOMUtil.getLocalName(child);
609             if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
610                 tempAttrUse = fSchemaHandler.fAttributeTraverser.traverseLocal(child,
611                         schemaDoc,
612                         grammar,
613                         enclosingCT);
614                 if (tempAttrUse == null) break;
615                 if (attrGrp.getAttributeUse(tempAttrUse.fAttrDecl.getNamespace(),
616                         tempAttrUse.fAttrDecl.getName())==null) {
617                     String JavaDoc idName = attrGrp.addAttributeUse(tempAttrUse);
618                     if (idName != null) {
619                         String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
620                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
621                         reportSchemaError(code, new Object JavaDoc[]{name, tempAttrUse.fAttrDecl.getName(), idName}, child);
622                     }
623                 }
624                 else {
625                     // REVISIT: what if one of the attribute uses is "prohibited"
626
String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
627                     String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
628                     reportSchemaError(code, new Object JavaDoc[]{name, tempAttrUse.fAttrDecl.getName()}, child);
629                 }
630             }
631             else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
632                 //REVISIT: do we need to save some state at this point??
633
tempAttrGrp = fSchemaHandler.fAttributeGroupTraverser.traverseLocal(
634                         child, schemaDoc, grammar);
635                 if(tempAttrGrp == null ) break;
636                 XSObjectList attrUseS = tempAttrGrp.getAttributeUses();
637                 XSAttributeUseImpl existingAttrUse = null, oneAttrUse;
638                 int attrCount = attrUseS.getLength();
639                 for (int i=0; i<attrCount; i++) {
640                     oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
641                     if (existingAttrUse == attrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(),
642                             oneAttrUse.fAttrDecl.getName())) {
643                         String JavaDoc idName = attrGrp.addAttributeUse(oneAttrUse);
644                         if (idName != null) {
645                             String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
646                             String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
647                             reportSchemaError(code, new Object JavaDoc[]{name, oneAttrUse.fAttrDecl.getName(), idName}, child);
648                         }
649                     }
650                     else {
651                         // REVISIT: what if one of the attribute uses is "prohibited"
652
String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
653                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
654                         reportSchemaError(code, new Object JavaDoc[]{name, oneAttrUse.fAttrDecl.getName()}, child);
655                     }
656                 }
657                 
658                 if (tempAttrGrp.fAttributeWC != null) {
659                     if (attrGrp.fAttributeWC == null) {
660                         attrGrp.fAttributeWC = tempAttrGrp.fAttributeWC;
661                     }
662                     // perform intersection of attribute wildcard
663
else {
664                         attrGrp.fAttributeWC = attrGrp.fAttributeWC.
665                         performIntersectionWith(tempAttrGrp.fAttributeWC, attrGrp.fAttributeWC.fProcessContents);
666                         if (attrGrp.fAttributeWC == null) {
667                             String JavaDoc code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
668                             String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
669                             reportSchemaError(code, new Object JavaDoc[]{name}, child);
670                         }
671                     }
672                 }
673             }
674             else
675                 break;
676         } // for
677

678         if (child != null) {
679             childName = DOMUtil.getLocalName(child);
680             if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
681                 XSWildcardDecl tempAttrWC = fSchemaHandler.fWildCardTraverser.
682                 traverseAnyAttribute(child, schemaDoc, grammar);
683                 if (attrGrp.fAttributeWC == null) {
684                     attrGrp.fAttributeWC = tempAttrWC;
685                 }
686                 // perform intersection of attribute wildcard
687
else {
688                     attrGrp.fAttributeWC = tempAttrWC.
689                     performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
690                     if (attrGrp.fAttributeWC == null) {
691                         String JavaDoc code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
692                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
693                         reportSchemaError(code, new Object JavaDoc[]{name}, child);
694                     }
695                 }
696                 child = DOMUtil.getNextSiblingElement(child);
697             }
698         }
699         
700         // Success
701
return child;
702         
703     }
704     
705     void reportSchemaError (String JavaDoc key, Object JavaDoc[] args, Element JavaDoc ele) {
706         fSchemaHandler.reportSchemaError(key, args, ele);
707     }
708     
709     /**
710      * Element/Attribute traversers call this method to check whether
711      * the type is NOTATION without enumeration facet
712      */

713     void checkNotationType(String JavaDoc refName, XSTypeDefinition typeDecl, Element JavaDoc elem) {
714         if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
715                 ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
716                 ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
717             if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
718                 reportSchemaError("enumeration-required-notation", new Object JavaDoc[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
719             }
720         }
721     }
722     
723     // Checks constraints for minOccurs, maxOccurs
724
protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
725             String JavaDoc particleName, Element JavaDoc parent,
726             int allContextFlags,
727             long defaultVals) {
728         
729         int min = particle.fMinOccurs;
730         int max = particle.fMaxOccurs;
731         boolean defaultMin = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MINOCCURS)) != 0;
732         boolean defaultMax = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MAXOCCURS)) != 0;
733         
734         boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
735         boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
736         boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
737         boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
738         
739         // Neither minOccurs nor maxOccurs may be specified
740
// for the child of a model group definition.
741
if (isGroupChild) {
742             if (!defaultMin) {
743                 Object JavaDoc[] args = new Object JavaDoc[]{particleName, "minOccurs"};
744                 reportSchemaError("s4s-att-not-allowed", args, parent);
745                 min = 1;
746             }
747             if (!defaultMax) {
748                 Object JavaDoc[] args = new Object JavaDoc[]{particleName, "maxOccurs"};
749                 reportSchemaError("s4s-att-not-allowed", args, parent);
750                 max = 1;
751             }
752         }
753         
754         // If minOccurs=maxOccurs=0, no component is specified
755
if (min == 0 && max== 0) {
756             particle.fType = XSParticleDecl.PARTICLE_EMPTY;
757             return null;
758         }
759         
760         // For the elements referenced in an <all>, minOccurs attribute
761
// must be zero or one, and maxOccurs attribute must be one.
762
// For a complex type definition that contains an <all> or a
763
// reference a <group> whose model group is an all model group,
764
// minOccurs and maxOccurs must be one.
765
if (processingAllEl) {
766             if (max != 1) {
767                 reportSchemaError("cos-all-limited.2", new Object JavaDoc[]{new Integer JavaDoc(max),
768                         ((XSElementDecl)particle.fValue).getName()}, parent);
769                 max = 1;
770                 if (min > 1)
771                     min = 1;
772             }
773         }
774         else if (processingAllGP || groupRefWithAll) {
775             if (max != 1) {
776                 reportSchemaError("cos-all-limited.1.2", null, parent);
777                 if (min > 1)
778                     min = 1;
779                 max = 1;
780             }
781         }
782         
783         particle.fMaxOccurs = min;
784         particle.fMaxOccurs = max;
785         
786         return particle;
787     }
788     
789     // this is not terribly performant!
790
private static String JavaDoc processAttValue(String JavaDoc original) {
791         // normally, nothing will happen
792
StringBuffer JavaDoc newVal = new StringBuffer JavaDoc(original.length());
793         for(int i=0; i<original.length(); i++) {
794             char currChar = original.charAt(i);
795             if(currChar == '"') {
796                 newVal.append("&quot;");
797             } else if (currChar == '>') {
798                 newVal.append("&gt;");
799             } else if (currChar == '&') {
800                 newVal.append("&amp;");
801             } else {
802                 newVal.append(currChar);
803             }
804         }
805         return newVal.toString();
806     }
807 }
808
Popular Tags