KickJava   Java API By Example, From Geeks To Geeks.

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


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.InvalidDatatypeValueException;
63 import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
64 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
65 import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
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.impl.xs.XSAttributeGroupDecl;
70 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
71 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
72 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
73 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
74 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
75 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
76 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
77 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
78 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
79 import com.sun.org.apache.xerces.internal.util.DOMUtil;
80 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
81 import com.sun.org.apache.xerces.internal.util.SymbolTable;
82 import com.sun.org.apache.xerces.internal.xni.QName;
83 import org.w3c.dom.Element JavaDoc;
84 import org.w3c.dom.Node JavaDoc;
85 import org.w3c.dom.Text JavaDoc;
86
87 /**
88  * Class <code>XSDAbstractTraverser</code> serves as the base class for all
89  * other <code>XSD???Traverser</code>s. It holds the common data and provide
90  * a unified way to initialize these data.
91  *
92  * @author Elena Litani, IBM
93  * @author Rahul Srivastava, Sun Microsystems Inc.
94  * @author Neeraj Bajaj, Sun Microsystems Inc.
95  *
96  * @version $Id: XSDAbstractTraverser.java,v 1.35 2003/11/11 20:15:00 sandygao Exp $
97  */

98 abstract class XSDAbstractTraverser {
99
100     protected static final String JavaDoc NO_NAME = "(no name)";
101
102     // Flags for checkOccurrences to indicate any special
103
// restrictions on minOccurs and maxOccurs relating to "all".
104
// NOT_ALL_CONTEXT - not processing an <all>
105
// PROCESSING_ALL_EL - processing an <element> in an <all>
106
// GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
107
// CHILD_OF_GROUP - processing a child of a model group definition
108
// PROCESSING_ALL_GP - processing an <all> group itself
109

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

291                      if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
292                          enumAnnotations.add(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
293                          child = DOMUtil.getNextSiblingElement(child);
294                      }
295                      if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
296                          reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
297                      }
298                }
299             }
300             else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
301                 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
302                 if (fPattern.length() == 0) {
303                     fPattern.append((String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE]);
304                 } else {
305                     // ---------------------------------------------
306
//datatypes: 5.2.4 pattern: src-multiple-pattern
307
// ---------------------------------------------
308
fPattern.append("|");
309                     fPattern.append((String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE]);
310                 }
311                 Element JavaDoc child = DOMUtil.getFirstChildElement( content );
312                 if (child != null) {
313                          // traverse annotation if any
314
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
315                              if (patternAnnotations == null){
316                                  patternAnnotations = new XSObjectListImpl();
317                              }
318                              patternAnnotations.add(traverseAnnotationDecl(child, attrs, false, schemaDoc));
319                              child = DOMUtil.getNextSiblingElement(child);
320                          }
321                          if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
322                              reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{"pattern", "(annotation?)", DOMUtil.getLocalName(child)}, child);
323                          }
324                 }
325                 
326             }
327             else {
328                 if (facet.equals(SchemaSymbols.ELT_MINLENGTH)) {
329                     currentFacet = XSSimpleType.FACET_MINLENGTH;
330                 }
331                 else if (facet.equals(SchemaSymbols.ELT_MAXLENGTH)) {
332                     currentFacet = XSSimpleType.FACET_MAXLENGTH;
333                 }
334                 else if (facet.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
335                     currentFacet = XSSimpleType.FACET_MAXEXCLUSIVE;
336                 }
337                 else if (facet.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
338                     currentFacet = XSSimpleType.FACET_MAXINCLUSIVE;
339                 }
340                 else if (facet.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
341                     currentFacet = XSSimpleType.FACET_MINEXCLUSIVE;
342                 }
343                 else if (facet.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
344                     currentFacet = XSSimpleType.FACET_MININCLUSIVE;
345                 }
346                 else if (facet.equals(SchemaSymbols.ELT_TOTALDIGITS)) {
347                     currentFacet = XSSimpleType.FACET_TOTALDIGITS;
348                 }
349                 else if (facet.equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
350                     currentFacet = XSSimpleType.FACET_FRACTIONDIGITS;
351                 }
352                 else if (facet.equals(SchemaSymbols.ELT_WHITESPACE)) {
353                     currentFacet = XSSimpleType.FACET_WHITESPACE;
354                 }
355                 else if (facet.equals(SchemaSymbols.ELT_LENGTH)) {
356                     currentFacet = XSSimpleType.FACET_LENGTH;
357                 }
358                 else {
359                     break; // a non-facet
360
}
361
362                 attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
363
364                 // check for duplicate facets
365
if ((facetsPresent & currentFacet) != 0) {
366                     reportSchemaError("src-single-facet-value", new Object JavaDoc[]{facet}, content);
367                 } else if (attrs[XSAttributeChecker.ATTIDX_VALUE] != null) {
368                     facetsPresent |= currentFacet;
369                     // check for fixed facet
370
if (((Boolean JavaDoc)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
371                         facetsFixed |= currentFacet;
372                     }
373                     switch (currentFacet) {
374                         case XSSimpleType.FACET_MINLENGTH:
375                             xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
376                             break;
377                         case XSSimpleType.FACET_MAXLENGTH:
378                             xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
379                             break;
380                         case XSSimpleType.FACET_MAXEXCLUSIVE:
381                             xsFacets.maxExclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
382                             break;
383                         case XSSimpleType.FACET_MAXINCLUSIVE:
384                             xsFacets.maxInclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
385                             break;
386                         case XSSimpleType.FACET_MINEXCLUSIVE:
387                             xsFacets.minExclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
388                             break;
389                         case XSSimpleType.FACET_MININCLUSIVE:
390                             xsFacets.minInclusive = (String JavaDoc)attrs[XSAttributeChecker.ATTIDX_VALUE];
391                             break;
392                         case XSSimpleType.FACET_TOTALDIGITS:
393                             xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
394                             break;
395                         case XSSimpleType.FACET_FRACTIONDIGITS:
396                             xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
397                             break;
398                         case XSSimpleType.FACET_WHITESPACE:
399                             xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
400                             break;
401                         case XSSimpleType.FACET_LENGTH:
402                             xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
403                             break;
404                     }
405                 }
406
407                 Element JavaDoc child = DOMUtil.getFirstChildElement( content );
408                 if (child != null) {
409                     // traverse annotation if any
410
if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
411                         XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
412                         switch (currentFacet) {
413                             case XSSimpleType.FACET_MINLENGTH:
414                                 xsFacets.minLengthAnnotation = annotation;
415                                 break;
416                             case XSSimpleType.FACET_MAXLENGTH:
417                                 xsFacets.maxLengthAnnotation = annotation;
418                                 break;
419                             case XSSimpleType.FACET_MAXEXCLUSIVE:
420                                 xsFacets.maxExclusiveAnnotation = annotation;
421                                 break;
422                             case XSSimpleType.FACET_MAXINCLUSIVE:
423                                 xsFacets.maxInclusiveAnnotation = annotation;
424                                 break;
425                             case XSSimpleType.FACET_MINEXCLUSIVE:
426                                 xsFacets.minExclusiveAnnotation = annotation;
427                                 break;
428                             case XSSimpleType.FACET_MININCLUSIVE:
429                                 xsFacets.minInclusiveAnnotation = annotation;
430                                 break;
431                             case XSSimpleType.FACET_TOTALDIGITS:
432                                 xsFacets.totalDigitsAnnotation = annotation;
433                                 break;
434                             case XSSimpleType.FACET_FRACTIONDIGITS:
435                                 xsFacets.fractionDigitsAnnotation = annotation;
436                                 break;
437                             case XSSimpleType.FACET_WHITESPACE:
438                                 xsFacets.whiteSpaceAnnotation = annotation;
439                                 break;
440                             case XSSimpleType.FACET_LENGTH:
441                                 xsFacets.lengthAnnotation = annotation;
442                                 break;
443                         }
444                         
445                         
446                         child = DOMUtil.getNextSiblingElement(child);
447                     }
448                     if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
449                         reportSchemaError("s4s-elt-must-match.1", new Object JavaDoc[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
450                     }
451                 }
452             }
453             fAttrChecker.returnAttrArray (attrs, schemaDoc);
454             content = DOMUtil.getNextSiblingElement(content);
455         }
456         if (enumData !=null) {
457             facetsPresent |= XSSimpleType.FACET_ENUMERATION;
458             xsFacets.enumeration = enumData;
459             xsFacets.enumNSDecls = enumNSDecls;
460             xsFacets.enumAnnotations = enumAnnotations;
461         }
462         if (fPattern.length() != 0) {
463             facetsPresent |= XSSimpleType.FACET_PATTERN;
464             xsFacets.pattern = fPattern.toString();
465             xsFacets.patternAnnotations = patternAnnotations;
466         }
467
468         fPattern.setLength(0);
469
470         FacetInfo fi = new FacetInfo();
471         fi.facetdata = xsFacets;
472         fi.nodeAfterFacets = content;
473         fi.fPresentFacets = facetsPresent;
474         fi.fFixedFacets = facetsFixed;
475         return fi;
476     }
477
478
479     // return whether QName/NOTATION is part of the given type
480
private boolean containsQName(XSSimpleType type) {
481         if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
482             short primitive = type.getPrimitiveKind();
483             return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
484                     primitive == XSSimpleType.PRIMITIVE_NOTATION);
485         }
486         else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
487             return containsQName((XSSimpleType)type.getItemType());
488         }
489         else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
490             XSObjectList members = type.getMemberTypes();
491             for (int i = 0; i < members.getLength(); i++) {
492                 if (containsQName((XSSimpleType)members.item(i)))
493                     return true;
494             }
495         }
496         return false;
497     }
498
499     //
500
// Traverse a set of attribute and attribute group elements
501
// Needed by complexType and attributeGroup traversal
502
// This method will return the first non-attribute/attrgrp found
503
//
504
Element JavaDoc traverseAttrsAndAttrGrps(Element JavaDoc firstAttr, XSAttributeGroupDecl attrGrp,
505                                      XSDocumentInfo schemaDoc, SchemaGrammar grammar,
506                                      XSComplexTypeDecl enclosingCT) {
507
508         Element JavaDoc child=null;
509         XSAttributeGroupDecl tempAttrGrp = null;
510         XSAttributeUseImpl tempAttrUse = null;
511         String JavaDoc childName;
512
513         for (child=firstAttr; child!=null; child=DOMUtil.getNextSiblingElement(child)) {
514             childName = DOMUtil.getLocalName(child);
515             if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
516                 tempAttrUse = fSchemaHandler.fAttributeTraverser.traverseLocal(child,
517                                                                                schemaDoc,
518                                                                                grammar,
519                                                                                enclosingCT);
520                 if (tempAttrUse == null) break;
521                 if (attrGrp.getAttributeUse(tempAttrUse.fAttrDecl.getNamespace(),
522                                             tempAttrUse.fAttrDecl.getName())==null) {
523                     String JavaDoc idName = attrGrp.addAttributeUse(tempAttrUse);
524                     if (idName != null) {
525                         String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
526                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
527                         reportSchemaError(code, new Object JavaDoc[]{name, tempAttrUse.fAttrDecl.getName(), idName}, child);
528                     }
529                 }
530                 else {
531                     // REVISIT: what if one of the attribute uses is "prohibited"
532
String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
533                     String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
534                     reportSchemaError(code, new Object JavaDoc[]{name, tempAttrUse.fAttrDecl.getName()}, child);
535                 }
536             }
537             else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
538                 //REVISIT: do we need to save some state at this point??
539
tempAttrGrp = fSchemaHandler.fAttributeGroupTraverser.traverseLocal(
540                        child, schemaDoc, grammar);
541                 if(tempAttrGrp == null ) break;
542                 XSObjectList attrUseS = tempAttrGrp.getAttributeUses();
543                 XSAttributeUseImpl existingAttrUse = null, oneAttrUse;
544                 int attrCount = attrUseS.getLength();
545                 for (int i=0; i<attrCount; i++) {
546                     oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
547                     if (existingAttrUse == attrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(),
548                     oneAttrUse.fAttrDecl.getName())) {
549                         String JavaDoc idName = attrGrp.addAttributeUse(oneAttrUse);
550                         if (idName != null) {
551                             String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
552                             String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
553                             reportSchemaError(code, new Object JavaDoc[]{name, oneAttrUse.fAttrDecl.getName(), idName}, child);
554                         }
555                     }
556                     else {
557                         // REVISIT: what if one of the attribute uses is "prohibited"
558
String JavaDoc code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
559                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
560                         reportSchemaError(code, new Object JavaDoc[]{name, oneAttrUse.fAttrDecl.getName()}, child);
561                     }
562                 }
563
564                 if (tempAttrGrp.fAttributeWC != null) {
565                     if (attrGrp.fAttributeWC == null) {
566                         attrGrp.fAttributeWC = tempAttrGrp.fAttributeWC;
567                     }
568                     // perform intersection of attribute wildcard
569
else {
570                         attrGrp.fAttributeWC = attrGrp.fAttributeWC.
571                                                performIntersectionWith(tempAttrGrp.fAttributeWC, attrGrp.fAttributeWC.fProcessContents);
572                         if (attrGrp.fAttributeWC == null) {
573                             String JavaDoc code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
574                             String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
575                             reportSchemaError(code, new Object JavaDoc[]{name}, child);
576                         }
577                     }
578                 }
579             }
580             else
581                 break;
582         } // for
583

584         if (child != null) {
585             childName = DOMUtil.getLocalName(child);
586             if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
587                 XSWildcardDecl tempAttrWC = fSchemaHandler.fWildCardTraverser.
588                                             traverseAnyAttribute(child, schemaDoc, grammar);
589                 if (attrGrp.fAttributeWC == null) {
590                     attrGrp.fAttributeWC = tempAttrWC;
591                 }
592                 // perform intersection of attribute wildcard
593
else {
594                     attrGrp.fAttributeWC = tempAttrWC.
595                                            performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
596                     if (attrGrp.fAttributeWC == null) {
597                         String JavaDoc code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
598                         String JavaDoc name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
599                         reportSchemaError(code, new Object JavaDoc[]{name}, child);
600                     }
601                 }
602                 child = DOMUtil.getNextSiblingElement(child);
603             }
604         }
605
606         // Success
607
return child;
608
609     }
610
611     void reportSchemaError (String JavaDoc key, Object JavaDoc[] args, Element JavaDoc ele) {
612         fSchemaHandler.reportSchemaError(key, args, ele);
613     }
614
615     /**
616      * Element/Attribute traversers call this method to check whether
617      * the type is NOTATION without enumeration facet
618      */

619     void checkNotationType(String JavaDoc refName, XSTypeDefinition typeDecl, Element JavaDoc elem) {
620         if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
621             ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
622             ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
623             if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
624                 reportSchemaError("enumeration-required-notation", new Object JavaDoc[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
625             }
626         }
627     }
628
629     // Checks constraints for minOccurs, maxOccurs
630
protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
631                                               String JavaDoc particleName, Element JavaDoc parent,
632                                               int allContextFlags,
633                                               long defaultVals) {
634
635         int min = particle.fMinOccurs;
636         int max = particle.fMaxOccurs;
637         boolean defaultMin = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MINOCCURS)) != 0;
638         boolean defaultMax = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MAXOCCURS)) != 0;
639
640         boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
641         boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
642         boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
643         boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
644
645         // Neither minOccurs nor maxOccurs may be specified
646
// for the child of a model group definition.
647
if (isGroupChild) {
648             if (!defaultMin) {
649                 Object JavaDoc[] args = new Object JavaDoc[]{particleName, "minOccurs"};
650                 reportSchemaError("s4s-att-not-allowed", args, parent);
651                 min = 1;
652             }
653             if (!defaultMax) {
654                 Object JavaDoc[] args = new Object JavaDoc[]{particleName, "maxOccurs"};
655                 reportSchemaError("s4s-att-not-allowed", args, parent);
656                 max = 1;
657             }
658         }
659
660         // If minOccurs=maxOccurs=0, no component is specified
661
if (min == 0 && max== 0) {
662             particle.fType = XSParticleDecl.PARTICLE_EMPTY;
663             return null;
664         }
665
666         // For the elements referenced in an <all>, minOccurs attribute
667
// must be zero or one, and maxOccurs attribute must be one.
668
// For a complex type definition that contains an <all> or a
669
// reference a <group> whose model group is an all model group,
670
// minOccurs and maxOccurs must be one.
671
if (processingAllEl) {
672             if (max != 1) {
673                 reportSchemaError("cos-all-limited.2", new Object JavaDoc[]{new Integer JavaDoc(max),
674                                   ((XSElementDecl)particle.fValue).getName()}, parent);
675                 max = 1;
676                 if (min > 1)
677                     min = 1;
678             }
679         }
680         else if (processingAllGP || groupRefWithAll) {
681             if (max != 1) {
682                 reportSchemaError("cos-all-limited.1.2", null, parent);
683                 if (min > 1)
684                     min = 1;
685                 max = 1;
686             }
687         }
688
689         particle.fMaxOccurs = min;
690         particle.fMaxOccurs = max;
691
692         return particle;
693     }
694
695     // this is not terribly performant!
696
private static String JavaDoc processAttValue(String JavaDoc original) {
697         // normally, nothing will happen
698
StringBuffer JavaDoc newVal = new StringBuffer JavaDoc(original.length());
699         for(int i=0; i<original.length(); i++) {
700             char currChar = original.charAt(i);
701             if(currChar == '"') {
702                 newVal.append("&quot;");
703             } else if (currChar == '>') {
704                 newVal.append("&gt;");
705             } else if (currChar == '&') {
706                 newVal.append("&amp;");
707             } else {
708                 newVal.append(currChar);
709             }
710         }
711         return newVal.toString();
712     }
713 }
714
Popular Tags