KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > schema > SchemaGrammar


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

58
59  /*
60  * @author Eric Ye
61  *
62  * @see
63  * @version $Id: SchemaGrammar.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
64  */

65 package org.enhydra.apache.xerces.validators.schema;
66
67 import java.util.Hashtable JavaDoc;
68 import java.util.Vector JavaDoc;
69
70 import org.enhydra.apache.xerces.framework.XMLContentSpec;
71 import org.enhydra.apache.xerces.utils.NamespacesScope;
72 import org.enhydra.apache.xerces.utils.QName;
73 import org.enhydra.apache.xerces.utils.StringPool;
74 import org.enhydra.apache.xerces.validators.common.Grammar;
75 import org.enhydra.apache.xerces.validators.common.GrammarResolver;
76 import org.enhydra.apache.xerces.validators.common.XMLAttributeDecl;
77 import org.enhydra.apache.xerces.validators.common.XMLContentModel;
78 import org.enhydra.apache.xerces.validators.common.XMLElementDecl;
79 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidator;
80 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
81
82 public class SchemaGrammar extends Grammar{
83
84     // Constants
85
//
86

87     private static final int CHUNK_SHIFT = 8; // 2^8 = 256
88
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
89     private static final int CHUNK_MASK = CHUNK_SIZE - 1;
90     private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
91

92     //Temp objects for decls structs.
93
private XMLContentSpec fTempContentSpecNode = new XMLContentSpec();
94     private XMLElementDecl fTempElementDecl = new XMLElementDecl();
95     private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
96
97     //
98
// Data
99
//
100

101     // basic information
102

103     // private int fTargetNamespace;
104

105     // private Element fGrammarDocument;
106

107     // element decl tables that used only by Schemas
108
// these arrays are indexed by elementdeclindex.
109

110     private int fScopeDefinedByElement[][] = new int[INITIAL_CHUNK_COUNT][];
111     private String JavaDoc fFromAnotherSchemaURI[][] = new String JavaDoc[INITIAL_CHUNK_COUNT][];
112     private TraverseSchema.ComplexTypeInfo fComplexTypeInfo[][] =
113         new TraverseSchema.ComplexTypeInfo[INITIAL_CHUNK_COUNT][];
114     private int fElementDeclDefaultType[][] = new int[INITIAL_CHUNK_COUNT][];
115     private String JavaDoc fElementDeclDefaultValue[][] = new String JavaDoc[INITIAL_CHUNK_COUNT][];
116     private String JavaDoc fElementDeclSubGroupAffFullName[][] = new String JavaDoc[INITIAL_CHUNK_COUNT][];
117     private Vector JavaDoc fElementDeclSubGroupQNames[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
118     private Vector JavaDoc fElementDeclAllSubGroupQNamesBlock[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
119     private Vector JavaDoc fElementDeclAllSubGroupQNames[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
120     private int fElementDeclBlockSet[][] = new int[INITIAL_CHUNK_COUNT][];
121     private int fElementDeclFinalSet[][] = new int[INITIAL_CHUNK_COUNT][];
122     private int fElementDeclMiscFlags[][] = new int[INITIAL_CHUNK_COUNT][];
123
124     // additional content spec tables
125
// used if deferContentSpecExansion is enabled
126
private int fContentSpecMinOccurs[][] = new int[INITIAL_CHUNK_COUNT][];
127     private int fContentSpecMaxOccurs[][] = new int[INITIAL_CHUNK_COUNT][];
128
129     //ComplexType and SimpleTypeRegistries
130
private Hashtable JavaDoc fComplexTypeRegistry = null;
131     private Hashtable JavaDoc fAttributeDeclRegistry = null;
132     private DatatypeValidatorFactoryImpl fDatatypeRegistry = null;
133
134     Hashtable JavaDoc topLevelGroupDecls = new Hashtable JavaDoc();
135     Hashtable JavaDoc topLevelNotationDecls = new Hashtable JavaDoc();
136     Hashtable JavaDoc topLevelAttrDecls = new Hashtable JavaDoc();
137     Hashtable JavaDoc topLevelAttrGrpDecls = new Hashtable JavaDoc();
138     Hashtable JavaDoc topLevelElemDecls = new Hashtable JavaDoc();
139     Hashtable JavaDoc topLevelTypeDecls = new Hashtable JavaDoc();
140
141     private NamespacesScope fNamespacesScope = null;
142     private String JavaDoc fTargetNamespaceURI = "";
143
144     // Set if we defer min/max expansion for content trees. This is required if we
145
// are doing particle derivation checking for schema.
146
private boolean deferContentSpecExpansion = false;
147
148     // Set if we check Unique Particle Attribution
149
// This one onle takes effect when deferContentSpecExpansion is set
150
private boolean checkUniqueParticleAttribution = false;
151     private boolean checkingUPA = false;
152     // store the original uri
153
private int fContentSpecOrgUri[][] = new int[INITIAL_CHUNK_COUNT][];
154
155     //
156
// Public methods
157
//
158

159     public NamespacesScope getNamespacesScope(){
160         return fNamespacesScope;
161     }
162
163     public boolean getDeferContentSpecExpansion() {
164         return deferContentSpecExpansion;
165     }
166
167     public boolean getCheckUniqueParticleAttribution() {
168         return checkUniqueParticleAttribution;
169     }
170
171     public String JavaDoc getTargetNamespaceURI(){
172         return fTargetNamespaceURI;
173     }
174
175     public Hashtable JavaDoc getAttributeDeclRegistry() {
176         return fAttributeDeclRegistry;
177     }
178
179     public Hashtable JavaDoc getComplexTypeRegistry(){
180         return fComplexTypeRegistry;
181     }
182
183     public DatatypeValidatorFactoryImpl getDatatypeRegistry(){
184         return fDatatypeRegistry;
185     }
186
187     public int getElementDefinedScope(int elementDeclIndex) {
188
189         if (elementDeclIndex < -1) {
190             return -1;
191         }
192         int chunk = elementDeclIndex >> CHUNK_SHIFT;
193         int index = elementDeclIndex & CHUNK_MASK;
194         return fScopeDefinedByElement[chunk][index];
195
196     }
197
198     public int getElementDefaultTYpe(int elementDeclIndex) {
199
200         if (elementDeclIndex < -1) {
201             return -1;
202         }
203         int chunk = elementDeclIndex >> CHUNK_SHIFT;
204         int index = elementDeclIndex & CHUNK_MASK;
205         return fElementDeclDefaultType[chunk][index];
206
207     }
208
209     public int getElementDeclBlockSet(int elementDeclIndex) {
210
211         if (elementDeclIndex < -1) {
212             return -1;
213         }
214         int chunk = elementDeclIndex >> CHUNK_SHIFT;
215         int index = elementDeclIndex & CHUNK_MASK;
216         return fElementDeclBlockSet[chunk][index];
217     }
218
219     public int getElementDeclFinalSet(int elementDeclIndex) {
220
221         if (elementDeclIndex < -1) {
222             return -1;
223         }
224         int chunk = elementDeclIndex >> CHUNK_SHIFT;
225         int index = elementDeclIndex & CHUNK_MASK;
226         return fElementDeclFinalSet[chunk][index];
227     }
228
229     public int getElementDeclMiscFlags(int elementDeclIndex) {
230
231         if (elementDeclIndex < -1) {
232             return -1;
233         }
234         int chunk = elementDeclIndex >> CHUNK_SHIFT;
235         int index = elementDeclIndex & CHUNK_MASK;
236         return fElementDeclMiscFlags[chunk][index];
237     }
238
239     public String JavaDoc getElementFromAnotherSchemaURI(int elementDeclIndex) {
240
241         if (elementDeclIndex < 0 ) {
242             return null;
243         }
244         int chunk = elementDeclIndex >> CHUNK_SHIFT;
245         int index = elementDeclIndex & CHUNK_MASK;
246         return fFromAnotherSchemaURI[chunk][index];
247
248     }
249
250     public String JavaDoc getElementDefaultValue(int elementDeclIndex) {
251
252         if (elementDeclIndex < 0 ) {
253             return null;
254         }
255         int chunk = elementDeclIndex >> CHUNK_SHIFT;
256         int index = elementDeclIndex & CHUNK_MASK;
257         return fElementDeclDefaultValue[chunk][index];
258
259     }
260     public String JavaDoc getElementDeclSubstitutionGroupAffFullName( int elementDeclIndex){
261
262         if (elementDeclIndex < 0 ) {
263             return null;
264         }
265         int chunk = elementDeclIndex >> CHUNK_SHIFT;
266         int index = elementDeclIndex & CHUNK_MASK;
267         return fElementDeclSubGroupAffFullName[chunk][index];
268
269     }
270
271     // get a list of element qnames that substitute the current element directly
272
private Vector JavaDoc getElementDeclSubstitutionGroupQNames( int elementDeclIndex){
273
274         if (elementDeclIndex < 0 ) {
275             return null;
276         }
277         int chunk = elementDeclIndex >> CHUNK_SHIFT;
278         int index = elementDeclIndex & CHUNK_MASK;
279         return fElementDeclSubGroupQNames[chunk][index];
280
281     }
282
283     // get a list of element qnames that substitute the current element directly
284
// or indirectly
285
// and get the derivation methods / block set along the derivation chain
286
// but we haven't checked "blockset" yet, because it's possible that
287
// A substitute B, B substitute C, with types (AT, BT, CT)
288
// but the derivation method from AT to BT is block by B's blockset
289
// then A can't substitute B, but it's still possible that A substitute C.
290
private Vector JavaDoc getElementDeclAllSubstitutionGroupQNamesBlock( int elementDeclIndex, GrammarResolver grammarResolver, StringPool stringPool) {
291         if (elementDeclIndex < 0 ) {
292             return null;
293         }
294         int chunk = elementDeclIndex >> CHUNK_SHIFT;
295         int index = elementDeclIndex & CHUNK_MASK;
296         if (fElementDeclAllSubGroupQNamesBlock[chunk][index] != null)
297             return fElementDeclAllSubGroupQNamesBlock[chunk][index];
298
299         Vector JavaDoc groups = new Vector JavaDoc();
300         fElementDeclAllSubGroupQNamesBlock[chunk][index] = groups;
301
302         // get the type info for the current element
303
TraverseSchema.ComplexTypeInfo typeInfo = getElementComplexTypeInfo(elementDeclIndex);
304
305         // for all elements that can substitute directly
306
Vector JavaDoc substitutionGroupQNames = getElementDeclSubstitutionGroupQNames(elementDeclIndex);
307         int size = substitutionGroupQNames == null ? 0 : substitutionGroupQNames.size();
308         for (int i = 0; i < size; i++) {
309             OneSubGroup oneGroup = (OneSubGroup)substitutionGroupQNames.elementAt(i);
310             SchemaGrammar sGrammar = oneGroup.grammar;
311             int subElementIndex = oneGroup.eleIndex;
312
313             // derivation method
314
// and prohibited derivation method
315
int devMethod = 0, pDevMethod = 0;
316
317             TraverseSchema.ComplexTypeInfo subTypeInfo = sGrammar.getElementComplexTypeInfo(subElementIndex);
318             if (subTypeInfo == null) {
319                 // for simple type, we compare the datatypeValidators
320
XMLElementDecl tmpElementDecl = new XMLElementDecl();
321                 sGrammar.getElementDecl(subElementIndex, tmpElementDecl);
322                 DatatypeValidator subElementDV = tmpElementDecl.datatypeValidator;
323                 getElementDecl(elementDeclIndex, tmpElementDecl);
324                 DatatypeValidator elementDV = tmpElementDecl.datatypeValidator;
325                 if (subElementDV != null && subElementDV != elementDV)
326                     devMethod = SchemaSymbols.RESTRICTION;
327             } else {
328                 // store the devMethod of the deriving type,
329
// and pDevMethod of the derived type
330
if (subTypeInfo != typeInfo) {
331                     devMethod = subTypeInfo.derivedBy;
332                     if (typeInfo != null)
333                         pDevMethod = typeInfo.blockSet;
334                     subTypeInfo = subTypeInfo.baseComplexTypeInfo;
335                 }
336                 for (; subTypeInfo != null && subTypeInfo != typeInfo;
337                      subTypeInfo = subTypeInfo.baseComplexTypeInfo) {
338                      devMethod |= subTypeInfo.derivedBy;
339                      pDevMethod |= subTypeInfo.blockSet;
340                 }
341             }
342
343             // put this element into the list
344
SubGroupBlockQName oneName = new SubGroupBlockQName();
345             oneName.name = oneGroup;
346             oneName.method = devMethod;
347             oneName.pmethod = pDevMethod;
348             groups.addElement(oneName);
349
350             // recursively get all elements that can substitute this element
351
Vector JavaDoc subSubGroup = sGrammar.getElementDeclAllSubstitutionGroupQNamesBlock(subElementIndex, grammarResolver, stringPool);
352             int bsize = subSubGroup == null ? 0 : subSubGroup.size();
353             for (int j = 0; j < bsize; j++) {
354                 // and add them to the list too
355
SubGroupBlockQName name = (SubGroupBlockQName)subSubGroup.elementAt(j);
356                 oneName = new SubGroupBlockQName();
357                 oneName.name = name.name;
358                 // note that we need to append the dev/pdev method
359
oneName.method = name.method|devMethod;
360                 oneName.pmethod = name.pmethod|pDevMethod;
361                 groups.addElement(oneName);
362             }
363         }
364
365         return groups;
366     }
367
368     // all elements that can substitute the given one
369
// returns a list (Vector) of SchemaGrammar.OneSubGroup: qname+grammar+elementIndex
370
// be sure to call this method ONLY AFTER (not during) schema traversal!!!
371
public Vector JavaDoc getElementDeclAllSubstitutionGroupQNames( int elementDeclIndex, GrammarResolver grammarResolver, StringPool stringPool) {
372
373         if (elementDeclIndex < 0 ) {
374             return null;
375         }
376         int chunk = elementDeclIndex >> CHUNK_SHIFT;
377         int index = elementDeclIndex & CHUNK_MASK;
378         if (fElementDeclAllSubGroupQNames[chunk][index] != null)
379             return fElementDeclAllSubGroupQNames[chunk][index];
380
381         Vector JavaDoc groups = new Vector JavaDoc();
382         fElementDeclAllSubGroupQNames[chunk][index] = groups;
383
384         // get the blockset of the current element
385
int blockSet = getElementDeclBlockSet(elementDeclIndex);
386         // 1 The blocking constraint does not contain substitution.
387
if((blockSet & SchemaSymbols.SUBSTITUTION) != 0)
388             return groups;
389
390         // 2 There is a chain of {substitution group affiliation}s from D to C, that is, either D's {substitution group affiliation} is C, or D's {substitution group affiliation}'s {substitution group affiliation} is C, or . . .
391
// get all substitution candidates without checking blockset
392
Vector JavaDoc substitutionGroupQNamesBlock = getElementDeclAllSubstitutionGroupQNamesBlock(elementDeclIndex, grammarResolver, stringPool);
393         // now check it
394
// 3 The set of all {derivation method}s involved in the derivation of D's {type definition} from C's {type definition} does not intersect with the union of the blocking constraint, C's {prohibited substitutions} (if C is complex, otherwise the empty set) and the {prohibited substitutions} (respectively the empty set) of any intermediate {type definition}s in the derivation of D's {type definition} from C's {type definition}.
395
for (int i = 0; i < substitutionGroupQNamesBlock.size(); i++) {
396             SubGroupBlockQName oneName = (SubGroupBlockQName)substitutionGroupQNamesBlock.elementAt(i);
397             if (((blockSet | oneName.pmethod) & oneName.method) == 0)
398                 groups.addElement(oneName.name);
399         }
400
401         return groups;
402     }
403
404     public TraverseSchema.ComplexTypeInfo getElementComplexTypeInfo(int elementDeclIndex){
405
406         if (elementDeclIndex <- 1) {
407             return null;
408         }
409         int chunk = elementDeclIndex >> CHUNK_SHIFT;
410         int index = elementDeclIndex & CHUNK_MASK;
411         return fComplexTypeInfo[chunk][index];
412     }
413
414     // Protected methods
415
//
416

417     protected int convertContentSpecTree(int contentSpecIndex) {
418
419         // We may want to consider trying to combine this with buildSyntaxTree at some
420
// point (if possible)
421

422         if ((!deferContentSpecExpansion) || (contentSpecIndex<0)) {
423            return contentSpecIndex;
424         }
425
426         getContentSpec( contentSpecIndex, fTempContentSpecNode);
427
428         int minOccurs = getContentSpecMinOccurs(contentSpecIndex);
429         int maxOccurs = getContentSpecMaxOccurs(contentSpecIndex);
430
431
432         if (((fTempContentSpecNode.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) ||
433             ((fTempContentSpecNode.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) ||
434             ((fTempContentSpecNode.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS) ||
435             (fTempContentSpecNode.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
436
437           // When checking Unique Particle Attribution, rename leaf elements
438
if (checkingUPA) {
439             contentSpecIndex = addContentSpecNode(fTempContentSpecNode.type,
440                                                   fTempContentSpecNode.value,
441                                                   fTempContentSpecNode.otherValue,
442                                                   false);
443             setContentSpecOrgUri(contentSpecIndex, fTempContentSpecNode.otherValue);
444             getContentSpec(contentSpecIndex, fTempContentSpecNode);
445             fTempContentSpecNode.otherValue = contentSpecIndex;
446             setContentSpec(contentSpecIndex, fTempContentSpecNode);
447           }
448
449           return expandContentModel(contentSpecIndex,minOccurs,maxOccurs);
450         }
451         else if (fTempContentSpecNode.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
452                  fTempContentSpecNode.type == XMLContentSpec.CONTENTSPECNODE_ALL ||
453                  fTempContentSpecNode.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
454
455           int left = fTempContentSpecNode.value;
456           int right = fTempContentSpecNode.otherValue;
457           int type = fTempContentSpecNode.type;
458
459           left = convertContentSpecTree(left);
460
461           if (right == -2)
462              return expandContentModel(left, minOccurs, maxOccurs);
463
464           right = convertContentSpecTree(right);
465
466           // When checking Unique Particle Attribution, we always create new
467
// new node to store different name for different groups
468
if (checkingUPA) {
469               contentSpecIndex = addContentSpecNode (type, left, right, false);
470           } else {
471           fTempContentSpecNode.type = type;
472           fTempContentSpecNode.value = left;
473           fTempContentSpecNode.otherValue = right;
474           setContentSpec(contentSpecIndex, fTempContentSpecNode);
475           }
476
477           return expandContentModel(contentSpecIndex, minOccurs, maxOccurs);
478         }
479         else {
480           // When checking Unique Particle Attribution, we have to rename
481
// uri even on zero_or_one, zero_or_more and one_or_more
482
if (checkingUPA) {
483               return addContentSpecNode (fTempContentSpecNode.type,
484                                          convertContentSpecTree(fTempContentSpecNode.value),
485                                          convertContentSpecTree(fTempContentSpecNode.otherValue),
486                                          false);
487           } else {
488               return contentSpecIndex;
489           }
490         }
491     }
492
493     // Unique Particle Attribution
494
// overrides same method from Grammar, to do UPA checking
495
public XMLContentModel getContentModel(int contentSpecIndex, int contentType, SubstitutionGroupComparator comparator) throws Exception JavaDoc {
496         // if the content model is already there, no UPA checking is necessary
497
if (existContentModel(contentSpecIndex))
498             return super.getContentModel(contentSpecIndex, contentType, comparator);
499
500         // if it's not there, we create a new one, do UPA checking,
501
// then throw it away. because UPA checking might result in NFA,
502
// but we need DFA for further checking
503
if (checkUniqueParticleAttribution) {
504             checkingUPA = true;
505             XMLContentModel contentModel = super.getContentModel(contentSpecIndex, contentType, comparator);
506             checkingUPA = false;
507
508             if (contentModel != null) {
509                 contentModel.checkUniqueParticleAttribution(this);
510                 clearContentModel(contentSpecIndex);
511             }
512         }
513
514         return super.getContentModel(contentSpecIndex, contentType, comparator);
515     }
516
517     // Unique Particle Attribution
518
// set/get the original uri for a specific index
519
public void setContentSpecOrgUri(int contentSpecIndex, int orgUri) {
520         if (contentSpecIndex > -1 ) {
521             int chunk = contentSpecIndex >> CHUNK_SHIFT;
522             int index = contentSpecIndex & CHUNK_MASK;
523             ensureContentSpecCapacity(chunk);
524             fContentSpecOrgUri[chunk][index] = orgUri;
525         }
526     }
527     public int getContentSpecOrgUri(int contentSpecIndex) {
528         if (contentSpecIndex > -1 ) {
529             int chunk = contentSpecIndex >> CHUNK_SHIFT;
530             int index = contentSpecIndex & CHUNK_MASK;
531             return fContentSpecOrgUri[chunk][index];
532         } else {
533             return -1;
534         }
535     }
536
537     public void setDeferContentSpecExpansion() {
538         deferContentSpecExpansion = true;
539     }
540
541     public void setCheckUniqueParticleAttribution() {
542         deferContentSpecExpansion = true;
543         checkUniqueParticleAttribution = true;
544     }
545
546     protected void setAttributeDeclRegistry(Hashtable JavaDoc attrReg){
547         fAttributeDeclRegistry = attrReg;
548     }
549
550     protected void setComplexTypeRegistry(Hashtable JavaDoc cTypeReg){
551         fComplexTypeRegistry = cTypeReg;
552     }
553
554     protected void setDatatypeRegistry(DatatypeValidatorFactoryImpl dTypeReg){
555         fDatatypeRegistry = dTypeReg;
556     }
557
558     protected void setNamespacesScope(NamespacesScope nsScope) {
559         fNamespacesScope = nsScope;
560     }
561
562     protected void setTargetNamespaceURI(String JavaDoc targetNSUri) {
563         fTargetNamespaceURI = targetNSUri;
564     }
565
566
567     protected int createElementDecl() {
568         return super.createElementDecl();
569     }
570
571     protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
572         super.setElementDecl(elementDeclIndex,elementDecl);
573     }
574
575     //public int addAttributeDeclByHead(int attributeDeclIndex, int attributeListHead) {
576
// return super.addAttributeDeclByHead(attributeDeclIndex, attributeListHead);
577
//}
578

579
580     protected int createContentSpec() {
581         return super.createContentSpec();
582     }
583
584     protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
585         super.setContentSpec(contentSpecIndex, contentSpec);
586     }
587
588     protected int createAttributeDecl() {
589         return super.createAttributeDecl();
590     }
591
592     protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
593         super.setAttributeDecl(elementDeclIndex, attributeDeclIndex, attributeDecl);
594     }
595
596     protected void setElementDefinedScope(int elementDeclIndex, int scopeDefined) {
597         int chunk = elementDeclIndex >> CHUNK_SHIFT;
598         int index = elementDeclIndex & CHUNK_MASK;
599         ensureElementDeclCapacity(chunk);
600         if (elementDeclIndex > -1 ) {
601             fScopeDefinedByElement[chunk][index] = scopeDefined;
602         }
603     }
604
605     protected void setElementFromAnotherSchemaURI(int elementDeclIndex, String JavaDoc anotherSchemaURI) {
606         int chunk = elementDeclIndex >> CHUNK_SHIFT;
607         int index = elementDeclIndex & CHUNK_MASK;
608         ensureElementDeclCapacity(chunk);
609         if (elementDeclIndex > -1 ) {
610             fFromAnotherSchemaURI[chunk][index] = anotherSchemaURI;
611         }
612     }
613
614     protected void setElementComplexTypeInfo(int elementDeclIndex, TraverseSchema.ComplexTypeInfo typeInfo){
615         int chunk = elementDeclIndex >> CHUNK_SHIFT;
616         int index = elementDeclIndex & CHUNK_MASK;
617         ensureElementDeclCapacity(chunk);
618         if (elementDeclIndex > -1 ) {
619             fComplexTypeInfo[chunk][index] = typeInfo;
620         }
621     }
622
623     protected void setElementDefault(int elementDeclIndex, String JavaDoc defaultValue) {
624         int chunk = elementDeclIndex >> CHUNK_SHIFT;
625         int index = elementDeclIndex & CHUNK_MASK;
626         ensureElementDeclCapacity(chunk);
627         if (elementDeclIndex > -1 ) {
628             fElementDeclDefaultValue[chunk][index] = defaultValue;
629         }
630     }
631
632     protected void setElementDeclBlockSet(int elementDeclIndex, int blockSet) {
633         int chunk = elementDeclIndex >> CHUNK_SHIFT;
634         int index = elementDeclIndex & CHUNK_MASK;
635         ensureElementDeclCapacity(chunk);
636         if (elementDeclIndex > -1 ) {
637             fElementDeclBlockSet[chunk][index] = blockSet;
638         }
639     }
640
641     protected void setElementDeclFinalSet(int elementDeclIndex, int finalSet) {
642         int chunk = elementDeclIndex >> CHUNK_SHIFT;
643         int index = elementDeclIndex & CHUNK_MASK;
644         ensureElementDeclCapacity(chunk);
645         if (elementDeclIndex > -1 ) {
646             fElementDeclFinalSet[chunk][index] = finalSet;
647         }
648     }
649
650     protected void setElementDeclMiscFlags(int elementDeclIndex, int miscFlags) {
651         int chunk = elementDeclIndex >> CHUNK_SHIFT;
652         int index = elementDeclIndex & CHUNK_MASK;
653         ensureElementDeclCapacity(chunk);
654         if (elementDeclIndex > -1 ) {
655             fElementDeclMiscFlags[chunk][index] = miscFlags;
656         }
657     }
658
659     protected void setElementDeclSubstitutionGroupAffFullName( int elementDeclIndex, String JavaDoc substitutionGroupFullName){
660         int chunk = elementDeclIndex >> CHUNK_SHIFT;
661         int index = elementDeclIndex & CHUNK_MASK;
662         ensureElementDeclCapacity(chunk);
663         if (elementDeclIndex > -1 ) {
664             fElementDeclSubGroupAffFullName[chunk][index] = substitutionGroupFullName;
665         }
666     }
667
668     protected void addElementDeclOneSubstitutionGroupQName( int elementDeclIndex, QName name, SchemaGrammar grammar, int eleIndex){
669         int chunk = elementDeclIndex >> CHUNK_SHIFT;
670         int index = elementDeclIndex & CHUNK_MASK;
671         ensureElementDeclCapacity(chunk);
672         if (elementDeclIndex > -1 ) {
673             if (fElementDeclSubGroupQNames[chunk][index] == null)
674                 fElementDeclSubGroupQNames[chunk][index] = new Vector JavaDoc();
675             OneSubGroup oneGroup = new OneSubGroup();
676             oneGroup.name = name;
677             oneGroup.grammar = grammar;
678             oneGroup.eleIndex = eleIndex;
679             fElementDeclSubGroupQNames[chunk][index].addElement(oneGroup);
680         }
681     }
682
683     protected void setContentSpecMinOccurs(int contentSpecIndex, int minOccurs) {
684         if (contentSpecIndex > -1 ) {
685         int chunk = contentSpecIndex >> CHUNK_SHIFT;
686         int index = contentSpecIndex & CHUNK_MASK;
687         ensureContentSpecCapacity(chunk);
688             fContentSpecMinOccurs[chunk][index] = minOccurs;
689         }
690     }
691
692     protected int getContentSpecMinOccurs(int contentSpecIndex) {
693         if (contentSpecIndex > -1 ) {
694         int chunk = contentSpecIndex >> CHUNK_SHIFT;
695         int index = contentSpecIndex & CHUNK_MASK;
696         return fContentSpecMinOccurs[chunk][index];
697         } else {
698             return -1;
699         }
700     }
701
702     protected int getContentSpecMaxOccurs(int contentSpecIndex) {
703         if (contentSpecIndex > -1 ) {
704         int chunk = contentSpecIndex >> CHUNK_SHIFT;
705         int index = contentSpecIndex & CHUNK_MASK;
706         return fContentSpecMaxOccurs[chunk][index];
707         } else {
708             return -1;
709         }
710     }
711
712     protected void setContentSpecMaxOccurs(int contentSpecIndex, int maxOccurs) {
713         if (contentSpecIndex > -1 ) {
714         int chunk = contentSpecIndex >> CHUNK_SHIFT;
715         int index = contentSpecIndex & CHUNK_MASK;
716         ensureContentSpecCapacity(chunk);
717             fContentSpecMaxOccurs[chunk][index] = maxOccurs;
718         }
719     }
720
721     //add methods for TraverseSchema
722
/**
723      *@return elementDecl Index,
724      */

725
726     protected int addElementDecl(QName eltQName, int enclosingScope, int scopeDefined,
727                                  int contentSpecType, int contentSpecIndex,
728                                  int attrListHead, DatatypeValidator dv){
729         int elementDeclIndex = getElementDeclIndex(eltQName, enclosingScope);
730         if (elementDeclIndex == -1) {
731             if (enclosingScope<-1 || scopeDefined < -1 ) {
732                 //TO DO: report error here;
733
}
734             fTempElementDecl.name.setValues(eltQName);
735             fTempElementDecl.enclosingScope = enclosingScope;
736             fTempElementDecl.type = contentSpecType;
737             fTempElementDecl.contentSpecIndex = contentSpecIndex;
738             fTempElementDecl.datatypeValidator = dv;
739             //fTempElementDecl.firstAttributeDeclIndex = attrListHead;
740
elementDeclIndex = createElementDecl();
741             setElementDecl(elementDeclIndex,fTempElementDecl);
742             setFirstAttributeDeclIndex(elementDeclIndex, attrListHead);
743             //note, this is the scope defined by the element, not its enclosing scope
744
setElementDefinedScope(elementDeclIndex, scopeDefined);
745         }
746
747     //debugging
748
/*****
749              XMLElementDecl fTempElementDecl = new XMLElementDecl();
750              getElementDecl(elementDeclIndex, fTempElementDecl);
751              System.out.println("elementDeclIndex in addElementDecl : " + elementDeclIndex
752                                 + " \n and itsName : '"
753                                 + (fTempElementDecl.name.localpart)
754                                 +"' \n its ContentType:" + (fTempElementDecl.type)
755                                 +"\n its ContentSpecIndex : " + fTempElementDecl.contentSpecIndex +"\n");
756     /*****/

757         return elementDeclIndex;
758
759     }
760
761     // Create a new elementdecl at a new scope, based on an existing decl
762
protected int cloneElementDecl(int eltNdx, int enclosingScope, int scopeDefined) {
763
764         getElementDecl(eltNdx,fTempElementDecl);
765         TraverseSchema.ComplexTypeInfo typeInfo = getElementComplexTypeInfo(eltNdx);
766         int blockSet = getElementDeclBlockSet(eltNdx);
767         int finalSet = getElementDeclFinalSet(eltNdx);
768         int elementMiscFlags = getElementDeclMiscFlags(eltNdx);
769         String JavaDoc defaultStr = getElementDefaultValue(eltNdx);
770         String JavaDoc subGroupName = getElementDeclSubstitutionGroupAffFullName(eltNdx);
771         int attrListHead = getFirstAttributeDeclIndex(eltNdx);
772         String JavaDoc anotherSchema = getElementFromAnotherSchemaURI(eltNdx);
773
774         fTempElementDecl.enclosingScope = enclosingScope;
775         int newElt= addElementDecl(fTempElementDecl.name,enclosingScope,scopeDefined,
776                  fTempElementDecl.type,fTempElementDecl.contentSpecIndex,
777                  attrListHead,fTempElementDecl.datatypeValidator);
778
779         setElementComplexTypeInfo(newElt, typeInfo);
780         setElementDeclBlockSet(newElt, blockSet);
781         setElementDeclFinalSet(newElt, finalSet);
782         setElementDeclMiscFlags(newElt, elementMiscFlags);
783         setElementDefault(newElt, defaultStr);
784         setElementFromAnotherSchemaURI(newElt, anotherSchema);
785         return newElt;
786
787     }
788     /**
789      *@return the new attribute List Head
790      */

791     protected void addAttDef( int templateElementIndex,
792                       QName attQName, int attType,
793                       int enumeration, int attDefaultType,
794                       String JavaDoc attDefaultValue, DatatypeValidator dv, boolean isList){
795         int attrDeclIndex = createAttributeDecl();
796         fTempAttributeDecl.name.setValues(attQName);
797         fTempAttributeDecl.datatypeValidator = dv;
798         fTempAttributeDecl.type = attType;
799         fTempAttributeDecl.defaultType = attDefaultType;
800         fTempAttributeDecl.defaultValue = attDefaultValue;
801         fTempAttributeDecl.list = isList;
802         fTempAttributeDecl.enumeration = enumeration;
803
804         super.setAttributeDecl(templateElementIndex, attrDeclIndex, fTempAttributeDecl);
805     }
806
807     public int getAttributeDeclIndex(int elementIndex, QName attribute) {
808         if (elementIndex == -1) {
809             return -1;
810         }
811         int attDefIndex = getFirstAttributeDeclIndex(elementIndex);
812         return findAttributeDecl(attDefIndex, attribute);
813
814     } // getAttributeDeclIndex (int,QName)
815

816     public int findAttributeDecl(int attListHead, QName attribute) {
817
818         int attDefIndex = attListHead;
819         while (attDefIndex != -1) {
820             getAttributeDecl(attDefIndex, fTempAttributeDecl);
821             if (fTempAttributeDecl.name.localpart == attribute.localpart &&
822                 fTempAttributeDecl.name.uri == attribute.uri ) {
823                 return attDefIndex;
824             }
825             attDefIndex = getNextAttributeDeclIndex(attDefIndex);
826         }
827         return -1;
828      }
829
830     /**
831       set the attribute decl index
832      */

833     protected void setFirstAttributeDeclIndex(int eltNdx, int attListHead) {
834       super.setFirstAttributeDeclIndex(eltNdx, attListHead);
835     }
836
837     /**
838      *@return the new contentSpec Index
839      */

840     protected int addContentSpecNode(int contentSpecType, int value, int otherValue, boolean mustBeUnique) {
841         fTempContentSpecNode.type = contentSpecType;
842         fTempContentSpecNode.value = value;
843         fTempContentSpecNode.otherValue = otherValue;
844
845         int contentSpecIndex = createContentSpec();
846         setContentSpec(contentSpecIndex, fTempContentSpecNode);
847         setContentSpecMinOccurs(contentSpecIndex, 1);
848         setContentSpecMaxOccurs(contentSpecIndex, 1);
849         return contentSpecIndex;
850     }
851
852     protected int expandContentModel(int index, int minOccurs, int maxOccurs) {
853
854         int leafIndex = index;
855
856         if (minOccurs==1 && maxOccurs==1) {
857
858         }
859         else if (minOccurs==0 && maxOccurs==1) {
860             //zero or one
861
index = addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
862                                                    index,
863                                                    -1,
864                                                    false);
865         }
866         else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
867             //zero or more
868
index = addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
869                                                    index,
870                                                    -1,
871                                                    false);
872         }
873         else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
874             //one or more
875
index = addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
876                                                    index,
877                                                    -1,
878                                                    false);
879         }
880         else if (maxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) {
881             if (minOccurs<2) {
882                 //REVISIT
883
}
884
885             // => a,a,..,a+
886
index = addContentSpecNode( XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
887                    index,
888                    -1,
889                    false);
890
891             for (int i=0; i < (minOccurs-1); i++) {
892                 index = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
893                                                       leafIndex,
894                                                       index,
895                                                       false);
896             }
897
898         }
899         else {
900             // {n,m} => a,a,a,...(a),(a),...
901

902
903             if (minOccurs==0) {
904                 int optional = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
905                                                                  leafIndex,
906                                                                  -1,
907                                                                  false);
908                 index = optional;
909                 for (int i=0; i < (maxOccurs-minOccurs-1); i++) {
910                     index = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
911                                                               index,
912                                                               optional,
913                                                               false);
914                 }
915             }
916             else {
917                 for (int i=0; i<(minOccurs-1); i++) {
918                     index = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
919                                                           index,
920                                                           leafIndex,
921                                                           false);
922                 }
923
924                 int optional = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
925                                                                  leafIndex,
926                                                                  -1,
927                                                                  false);
928                 for (int i=0; i < (maxOccurs-minOccurs); i++) {
929                     index = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_SEQ,
930                                                               index,
931                                                               optional,
932                                                               false);
933                 }
934             }
935         }
936
937         return index;
938     }
939
940
941     //
942
// Private methods
943
//
944

945     // ensure capacity
946

947     private boolean ensureContentSpecCapacity(int chunk) {
948         try {
949             return fContentSpecMinOccurs[chunk][0] == 0;
950         } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
951             fContentSpecMinOccurs = resize(fContentSpecMinOccurs, fContentSpecMinOccurs.length * 2);
952             fContentSpecMaxOccurs = resize(fContentSpecMaxOccurs, fContentSpecMaxOccurs.length * 2);
953             fContentSpecOrgUri = resize(fContentSpecOrgUri, fContentSpecOrgUri.length * 2);
954         } catch (NullPointerException JavaDoc ex) {
955             // ignore
956
}
957         fContentSpecMinOccurs[chunk] = new int[CHUNK_SIZE];
958         fContentSpecMaxOccurs[chunk] = new int[CHUNK_SIZE];
959         fContentSpecOrgUri[chunk] = new int[CHUNK_SIZE];
960         return true;
961     }
962
963     private boolean ensureElementDeclCapacity(int chunk) {
964         try {
965             return fScopeDefinedByElement[chunk][0] == -2;
966         }
967         catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
968              fScopeDefinedByElement= resize(fScopeDefinedByElement, fScopeDefinedByElement.length * 2);
969              fFromAnotherSchemaURI = resize(fFromAnotherSchemaURI, fFromAnotherSchemaURI.length *2);
970              fComplexTypeInfo = resize(fComplexTypeInfo, fComplexTypeInfo.length *2);
971              fElementDeclDefaultType = resize(fElementDeclDefaultType,fElementDeclDefaultType.length*2);
972              fElementDeclDefaultValue = resize(fElementDeclDefaultValue,fElementDeclDefaultValue.length*2);
973              fElementDeclBlockSet = resize(fElementDeclBlockSet,fElementDeclBlockSet.length*2);
974              fElementDeclFinalSet = resize(fElementDeclFinalSet,fElementDeclFinalSet.length*2);
975              fElementDeclMiscFlags = resize(fElementDeclMiscFlags,fElementDeclMiscFlags.length*2);
976              fElementDeclSubGroupAffFullName = resize(fElementDeclSubGroupAffFullName,fElementDeclSubGroupAffFullName.length*2);
977              fElementDeclSubGroupQNames = resize(fElementDeclSubGroupQNames,fElementDeclSubGroupQNames.length*2);
978              fElementDeclAllSubGroupQNames = resize(fElementDeclAllSubGroupQNames,fElementDeclAllSubGroupQNames.length*2);
979              fElementDeclAllSubGroupQNamesBlock = resize(fElementDeclAllSubGroupQNamesBlock,fElementDeclAllSubGroupQNamesBlock.length*2);
980         }
981         catch (NullPointerException JavaDoc ex) {
982             // ignore
983
}
984         fScopeDefinedByElement[chunk] = new int[CHUNK_SIZE];
985         for (int i=0; i<CHUNK_SIZE; i++) {
986             fScopeDefinedByElement[chunk][i] = -2; //-1, 0 are all valid scope value.
987
}
988         fFromAnotherSchemaURI[chunk] = new String JavaDoc[CHUNK_SIZE];
989         fComplexTypeInfo[chunk] = new TraverseSchema.ComplexTypeInfo[CHUNK_SIZE];
990         fElementDeclDefaultType[chunk] = new int[CHUNK_SIZE];
991         fElementDeclDefaultValue[chunk] = new String JavaDoc[CHUNK_SIZE];
992         fElementDeclSubGroupAffFullName[chunk] = new String JavaDoc[CHUNK_SIZE];
993         fElementDeclSubGroupQNames[chunk] = new Vector JavaDoc[CHUNK_SIZE];
994         fElementDeclAllSubGroupQNames[chunk] = new Vector JavaDoc[CHUNK_SIZE];
995         fElementDeclAllSubGroupQNamesBlock[chunk] = new Vector JavaDoc[CHUNK_SIZE];
996         fElementDeclBlockSet[chunk] = new int[CHUNK_SIZE]; // initialized to 0
997
fElementDeclFinalSet[chunk] = new int[CHUNK_SIZE]; // initialized to 0
998
fElementDeclMiscFlags[chunk] = new int[CHUNK_SIZE]; // initialized to 0
999
return true;
1000    }
1001
1002
1003    // resize initial chunk
1004

1005    private int[][] resize(int array[][], int newsize) {
1006        int newarray[][] = new int[newsize][];
1007        System.arraycopy(array, 0, newarray, 0, array.length);
1008        return newarray;
1009    }
1010
1011    private String JavaDoc[][] resize(String JavaDoc array[][], int newsize) {
1012        String JavaDoc newarray[][] = new String JavaDoc[newsize][];
1013        System.arraycopy(array, 0, newarray, 0, array.length);
1014        return newarray;
1015    }
1016    private TraverseSchema.ComplexTypeInfo[][] resize(TraverseSchema.ComplexTypeInfo array[][], int newsize) {
1017        TraverseSchema.ComplexTypeInfo newarray[][] = new TraverseSchema.ComplexTypeInfo[newsize][];
1018        System.arraycopy(array, 0, newarray, 0, array.length);
1019        return newarray;
1020    }
1021
1022    private Vector JavaDoc[][] resize(Vector JavaDoc array[][], int newsize) {
1023        Vector JavaDoc newarray[][] = new Vector JavaDoc[newsize][];
1024        System.arraycopy(array, 0, newarray, 0, array.length);
1025        return newarray;
1026    }
1027
1028    // make it public, so that other classes can access both qname and
1029
// grammar+index pair
1030
public class OneSubGroup {
1031        public QName name;
1032        SchemaGrammar grammar;
1033        int eleIndex;
1034    }
1035
1036    // OneSubGroup + derivation/prohibited derivation method
1037
private class SubGroupBlockQName {
1038        public OneSubGroup name;
1039        public int method;
1040        public int pmethod;
1041    } // class IgnoreWhitespaceParser
1042
} // class SchemaGrammar
1043
Popular Tags