KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > common > Grammar


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2000 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) 1999, 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 org.enhydra.apache.xerces.validators.common;
59
60 import java.util.Vector JavaDoc;
61
62 import org.enhydra.apache.xerces.framework.XMLContentSpec;
63 import org.enhydra.apache.xerces.utils.Hash2intTable;
64 import org.enhydra.apache.xerces.utils.ImplementationMessages;
65 import org.enhydra.apache.xerces.utils.QName;
66 import org.enhydra.apache.xerces.utils.StringPool;
67 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidator;
68 import org.enhydra.apache.xerces.validators.schema.SubstitutionGroupComparator;
69 import org.w3c.dom.Document JavaDoc;
70
71
72 /**
73  * @version $Id: Grammar.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
74  */

75 public class Grammar
76 implements XMLContentSpec.Provider {
77
78     //
79
// Constants
80
//
81

82     /** Signifies top level scope (-1). */
83     public static final int TOP_LEVEL_SCOPE = -1;
84
85     private static final int CHUNK_SHIFT = 8; // 2^8 = 256
86
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
87     private static final int CHUNK_MASK = CHUNK_SIZE - 1;
88     private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
89

90     private static final int LIST_FLAG = 0x8000;
91     private static final int LIST_MASK = ~LIST_FLAG;
92
93     //
94
// Data
95
//
96

97     // basic information
98

99     private int fTargetNamespace;
100
101     private Document JavaDoc fGrammarDocument;
102
103     // element decl tables
104

105     private int fElementDeclCount = 0;
106     private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
107     private int fElementDeclType[][] = new int[INITIAL_CHUNK_COUNT][];
108     private DatatypeValidator fElementDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
109     private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
110     private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
111     private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
112     private Vector JavaDoc fElementDeclUnique[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
113     private Vector JavaDoc fElementDeclKey[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
114     private Vector JavaDoc fElementDeclKeyRef[][] = new Vector JavaDoc[INITIAL_CHUNK_COUNT][];
115
116     // content spec tables
117

118     private int fContentSpecCount = 0 ;
119     private int fContentSpecType[][] = new int[INITIAL_CHUNK_COUNT][];
120     private int fContentSpecValue[][] = new int[INITIAL_CHUNK_COUNT][];
121     private int fContentSpecOtherValue[][] = new int[INITIAL_CHUNK_COUNT][];
122     private XMLContentModel fContentSpecValidator[][] = new XMLContentModel[INITIAL_CHUNK_COUNT][];
123
124     // attribute decl tables
125

126     private int fAttributeDeclCount = 0 ;
127     private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
128     private int fAttributeDeclType[][] = new int[INITIAL_CHUNK_COUNT][];
129     private int fAttributeDeclEnumeration[][] = new int[INITIAL_CHUNK_COUNT][];
130     private int fAttributeDeclDefaultType[][] = new int[INITIAL_CHUNK_COUNT][];
131     private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
132     private String JavaDoc fAttributeDeclDefaultValue[][] = new String JavaDoc[INITIAL_CHUNK_COUNT][];
133     private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
134
135     // scope mapping tables
136

137     private Hash2intTable fElementNameAndScopeToElementDeclIndexMapping = new Hash2intTable();
138
139     // temp vars
140

141     private QName fQName1 = new QName();
142     private QName fQName2 = new QName();
143
144     //
145
// Public methods
146
//
147

148     public Document JavaDoc getGrammarDocument() {
149         return fGrammarDocument;
150     }
151
152     public int getElementDeclIndex(int localpartIndex, int scopeIndex) {
153         if ( localpartIndex > -1 && scopeIndex >-2 ) {
154             return fElementNameAndScopeToElementDeclIndexMapping.get(StringPool.EMPTY_STRING, localpartIndex, scopeIndex);
155         }
156         return -1;
157     }
158
159     public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) {
160         if ( localpartIndex > -1 && scopeIndex >-2 ) {
161             return fElementNameAndScopeToElementDeclIndexMapping.get(uriIndex, localpartIndex, scopeIndex);
162         }
163         return -1;
164     }
165
166     public int getElementDeclIndex(QName element, int scopeIndex) {
167         if ( element.localpart > -1 && scopeIndex >-2 ) {
168             return fElementNameAndScopeToElementDeclIndexMapping.get(element.uri, element.localpart, scopeIndex);
169         }
170         return -1;
171     }
172
173     public boolean getElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
174         if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
175             return false;
176         }
177
178         int chunk = elementDeclIndex >> CHUNK_SHIFT;
179         int index = elementDeclIndex & CHUNK_MASK;
180
181         elementDecl.name.setValues(fElementDeclName[chunk][index]);
182         if (fElementDeclType[chunk][index] == -1) {
183             elementDecl.type = -1;
184             elementDecl.list = false;
185         }
186         else {
187             elementDecl.type = fElementDeclType[chunk][index] & LIST_MASK;
188             elementDecl.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
189         }
190         elementDecl.datatypeValidator = fElementDeclDatatypeValidator[chunk][index];
191         elementDecl.contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
192
193         // copy identity constraints
194
elementDecl.unique.removeAllElements();
195         int ucount = fElementDeclUnique[chunk][index] != null
196                    ? fElementDeclUnique[chunk][index].size() : 0;
197         for (int i = 0; i < ucount; i++) {
198             elementDecl.unique.addElement(fElementDeclUnique[chunk][index].elementAt(i));
199         }
200         elementDecl.key.removeAllElements();
201         int kcount = fElementDeclKey[chunk][index] != null
202                    ? fElementDeclKey[chunk][index].size() : 0;
203         for (int i = 0; i < kcount; i++) {
204             elementDecl.key.addElement(fElementDeclKey[chunk][index].elementAt(i));
205         }
206         elementDecl.keyRef.removeAllElements();
207         int krcount = fElementDeclKeyRef[chunk][index] != null
208                     ? fElementDeclKeyRef[chunk][index].size() : 0;
209         for (int i = 0; i < krcount; i++) {
210             elementDecl.keyRef.addElement(fElementDeclKeyRef[chunk][index].elementAt(i));
211         }
212
213         return true;
214     }
215
216     public int getFirstAttributeDeclIndex(int elementDeclIndex) {
217         int chunk = elementDeclIndex >> CHUNK_SHIFT;
218         int index = elementDeclIndex & CHUNK_MASK;
219
220         return fElementDeclFirstAttributeDeclIndex[chunk][index];
221     }
222
223     public int getNextAttributeDeclIndex(int attributeDeclIndex) {
224         int chunk = attributeDeclIndex >> CHUNK_SHIFT;
225         int index = attributeDeclIndex & CHUNK_MASK;
226
227         return fAttributeDeclNextAttributeDeclIndex[chunk][index];
228     }
229
230     public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
231         if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount )
232             return false;
233
234         int chunk = contentSpecIndex >> CHUNK_SHIFT;
235         int index = contentSpecIndex & CHUNK_MASK;
236
237         contentSpec.type = fContentSpecType[chunk][index];
238         contentSpec.value = fContentSpecValue[chunk][index];
239         contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
240         return true;
241     }
242
243     protected void clearContentModel(int contentSpecIndex) {
244         if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount)
245             return;
246
247         int chunk = contentSpecIndex >> CHUNK_SHIFT;
248         int index = contentSpecIndex & CHUNK_MASK;
249
250         fContentSpecValidator[chunk][index] = null;
251     }
252
253     protected boolean existContentModel(int contentSpecIndex) {
254         if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount)
255             return false;
256
257         int chunk = contentSpecIndex >> CHUNK_SHIFT;
258         int index = contentSpecIndex & CHUNK_MASK;
259
260         return (fContentSpecValidator[chunk][index] != null);
261     }
262
263     public XMLContentModel getElementContentModel(int elementDeclIndex, SubstitutionGroupComparator comparator) throws Exception JavaDoc {
264
265         if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount)
266             return null;
267
268         int chunk = elementDeclIndex >> CHUNK_SHIFT;
269         int index = elementDeclIndex & CHUNK_MASK;
270
271         int contentType = fElementDeclType[chunk][index];
272
273         return getContentModel(fElementDeclContentSpecIndex[chunk][index],
274                                contentType, comparator);
275     }
276
277     public XMLContentModel getContentModel(int contentSpecIndex, int contentType, SubstitutionGroupComparator comparator) throws Exception JavaDoc {
278         if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount)
279             return null;
280
281         int chunk = contentSpecIndex >> CHUNK_SHIFT;
282         int index = contentSpecIndex & CHUNK_MASK;
283
284         XMLContentModel contentModel = fContentSpecValidator[chunk][index];
285
286         // If we have one, just return that. Otherwise, gotta create one
287
if (contentModel != null)
288             return contentModel;
289
290         if (contentType == XMLElementDecl.TYPE_SIMPLE) {
291             return null;
292         }
293
294         // Get the type of content this element has
295
int expendedIndex = convertContentSpecTree(contentSpecIndex);
296
297         XMLContentSpec contentSpec = new XMLContentSpec();
298         getContentSpec( expendedIndex, contentSpec );
299
300         // And create the content model according to the spec type
301

302         if ( contentType == XMLElementDecl.TYPE_MIXED_SIMPLE ) {
303               //
304
// just create a mixed content model object. This type of
305
// content model is optimized for simple mixed content validation.
306
//
307

308               Vector JavaDoc vQName = new Vector JavaDoc();
309               ChildrenList children = new ChildrenList();
310               contentSpecTree(expendedIndex, contentSpec, children);
311               contentModel = new MixedContentModel(children.qname,
312                                                    children.type,
313                                                    0, children.length, false, isDTD());
314         }
315         else if (contentType == XMLElementDecl.TYPE_MIXED_COMPLEX) {
316               //
317
// For Schema, we need a more complex model. Create a child model as
318
// per the element-only case, unless there are actually no children in
319
// the model. If that's the case, we can use the Mixed Content Model for
320
// DTDs.
321
contentModel = createChildModel(expendedIndex, true);
322         }
323
324
325         else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
326             // This method will create an optimal model for the complexity
327
// of the element's defined model. If it's simple, it will create
328
// a SimpleContentModel object. If it's a simple list, it will
329
// create a SimpleListContentModel object. If it's complex, it
330
// will create a DFAContentModel object.
331
//
332
contentModel = createChildModel(expendedIndex, false);
333         } else {
334             throw new CMException(ImplementationMessages.VAL_CST);
335         }
336
337         // Add the new model to the content model for this element
338

339         fContentSpecValidator[chunk][index] = contentModel;
340
341         //build it ..... in XMLValidator
342
if (contentModel != null)
343             contentModel.setSubstitutionGroupComparator(comparator);
344
345         return contentModel;
346     }
347
348     public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
349         if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
350             return false;
351         }
352         int chunk = attributeDeclIndex >> CHUNK_SHIFT;
353         int index = attributeDeclIndex & CHUNK_MASK;
354
355         attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
356
357         if (fAttributeDeclType[chunk][index] == -1) {
358
359             attributeDecl.type = -1;
360             attributeDecl.list = false;
361         }
362         else {
363             attributeDecl.type = fAttributeDeclType[chunk][index] & LIST_MASK;
364             attributeDecl.list = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
365         }
366         attributeDecl.datatypeValidator = fAttributeDeclDatatypeValidator[chunk][index];
367         attributeDecl.enumeration = fAttributeDeclEnumeration[chunk][index];
368         attributeDecl.defaultType = fAttributeDeclDefaultType[chunk][index];
369         attributeDecl.defaultValue = fAttributeDeclDefaultValue[chunk][index];
370         return true;
371     }
372
373     //
374
// Protected methods
375
//
376

377     protected void setGrammarDocument(Document JavaDoc grammarDocument) {
378         fGrammarDocument = grammarDocument;
379     }
380
381     // SchemaGrammar overrides this and does a conversion
382
protected int convertContentSpecTree(int index) {
383         return index;
384     }
385
386     protected int createElementDecl() {
387
388         int chunk = fElementDeclCount >> CHUNK_SHIFT;
389         int index = fElementDeclCount & CHUNK_MASK;
390         ensureElementDeclCapacity(chunk);
391         fElementDeclName[chunk][index] = new QName();
392         fElementDeclType[chunk][index] = -1;
393         fElementDeclDatatypeValidator[chunk][index] = null;
394         fElementDeclContentSpecIndex[chunk][index] = -1;
395         fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
396         fElementDeclLastAttributeDeclIndex[chunk][index] = -1;
397         return fElementDeclCount++;
398     }
399
400     protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
401
402         if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
403             return;
404         }
405         int chunk = elementDeclIndex >> CHUNK_SHIFT;
406         int index = elementDeclIndex & CHUNK_MASK;
407
408         fElementDeclName[chunk][index].setValues(elementDecl.name);
409         fElementDeclType[chunk][index] = elementDecl.type;
410         if (elementDecl.list) {
411             fElementDeclType[chunk][index] |= LIST_FLAG;
412         }
413         fElementDeclDatatypeValidator[chunk][index] = elementDecl.datatypeValidator;
414         fElementDeclContentSpecIndex[chunk][index] = elementDecl.contentSpecIndex;
415
416         // copy identity constraints
417
int ucount = elementDecl.unique.size();
418         if (ucount > 0) {
419             if (fElementDeclUnique[chunk][index] == null) {
420                 fElementDeclUnique[chunk][index] = (Vector JavaDoc)elementDecl.unique.clone();
421             }
422             else {
423                 fElementDeclUnique[chunk][index].removeAllElements();
424                 for (int i = 0; i < ucount; i++) {
425                     fElementDeclUnique[chunk][index].addElement(elementDecl.unique.elementAt(i));
426                 }
427             }
428         }
429         int kcount = elementDecl.key.size();
430         if (kcount > 0) {
431             if (fElementDeclKey[chunk][index] == null) {
432                 fElementDeclKey[chunk][index] = (Vector JavaDoc)elementDecl.key.clone();
433             }
434             else {
435                 fElementDeclKey[chunk][index].removeAllElements();
436                 for (int i = 0; i < kcount; i++) {
437                     fElementDeclKey[chunk][index].addElement(elementDecl.key.elementAt(i));
438                 }
439             }
440         }
441         int krcount = elementDecl.keyRef.size();
442         if (krcount > 0) {
443             if (fElementDeclKeyRef[chunk][index] == null) {
444                 fElementDeclKeyRef[chunk][index] = (Vector JavaDoc)elementDecl.keyRef.clone();
445             }
446             else {
447                 fElementDeclKeyRef[chunk][index].removeAllElements();
448                 for (int i = 0; i < krcount; i++) {
449                     fElementDeclKeyRef[chunk][index].addElement(elementDecl.keyRef.elementAt(i));
450                 }
451             }
452         }
453
454         // add the mapping information to the
455
putElementNameMapping(elementDecl.name,
456                               elementDecl.enclosingScope,
457                               elementDeclIndex);
458     }
459
460     protected void putElementNameMapping(QName name, int scope,
461                                          int elementDeclIndex) {
462         fElementNameAndScopeToElementDeclIndexMapping.put(name.uri,
463                                                           name.localpart,
464                                                           scope,
465                                                           elementDeclIndex);
466     }
467
468     protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){
469
470         if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
471             return;
472         }
473
474         int chunk = elementDeclIndex >> CHUNK_SHIFT;
475         int index = elementDeclIndex & CHUNK_MASK;
476
477         fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
478         if (fElementDeclLastAttributeDeclIndex[chunk][index] == -1)
479             fElementDeclLastAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
480     }
481
482
483     protected int createContentSpec() {
484         int chunk = fContentSpecCount >> CHUNK_SHIFT;
485         int index = fContentSpecCount & CHUNK_MASK;
486
487         ensureContentSpecCapacity(chunk);
488         fContentSpecType[chunk][index] = -1;
489         fContentSpecValue[chunk][index] = -1;
490         fContentSpecOtherValue[chunk][index] = -1;
491         fContentSpecValidator[chunk][index] = null;
492
493         return fContentSpecCount++;
494     }
495
496     protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
497         int chunk = contentSpecIndex >> CHUNK_SHIFT;
498         int index = contentSpecIndex & CHUNK_MASK;
499
500         fContentSpecType[chunk][index] = contentSpec.type;
501         fContentSpecValue[chunk][index] = contentSpec.value;
502         fContentSpecOtherValue[chunk][index] = contentSpec.otherValue;
503     }
504
505     protected int createAttributeDecl() {
506         int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
507         int index = fAttributeDeclCount & CHUNK_MASK;
508
509         ensureAttributeDeclCapacity(chunk);
510         fAttributeDeclName[chunk][index] = new QName();
511         fAttributeDeclType[chunk][index] = -1;
512         fAttributeDeclDatatypeValidator[chunk][index] = null;
513         fAttributeDeclEnumeration[chunk][index] = -1;
514         fAttributeDeclDefaultType[chunk][index] = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
515         fAttributeDeclDefaultValue[chunk][index] = null;
516         fAttributeDeclNextAttributeDeclIndex[chunk][index] = -1;
517         return fAttributeDeclCount++;
518     }
519
520
521     protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
522
523         int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
524         int attrIndex = attributeDeclIndex & CHUNK_MASK;
525
526         fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name);
527
528         fAttributeDeclType[attrChunk][attrIndex] = attributeDecl.type;
529         if (attributeDecl.list) {
530             fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
531         }
532         fAttributeDeclEnumeration[attrChunk][attrIndex] = attributeDecl.enumeration;
533         fAttributeDeclDefaultType[attrChunk][attrIndex] = attributeDecl.defaultType;
534         fAttributeDeclDatatypeValidator[attrChunk][attrIndex] = attributeDecl.datatypeValidator;
535         fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.defaultValue;
536
537         int elemChunk = elementDeclIndex >> CHUNK_SHIFT;
538         int elemIndex = elementDeclIndex & CHUNK_MASK;
539         int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
540         while (index != -1) {
541             if (index == attributeDeclIndex) {
542                 break;
543             }
544             attrChunk = index >> CHUNK_SHIFT;
545             attrIndex = index & CHUNK_MASK;
546             index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
547         }
548         if (index == -1) {
549             if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
550                 fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
551             }
552             else {
553                 index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
554                 attrChunk = index >> CHUNK_SHIFT;
555                 attrIndex = index & CHUNK_MASK;
556                 fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
557             }
558             fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
559         }
560
561     }
562
563     protected boolean isDTD() {
564         return false;
565     }
566
567     // debugging
568

569     public void printElements(org.enhydra.apache.xerces.utils.StringPool pool) {
570         int elementDeclIndex = 0;
571         XMLElementDecl elementDecl = new XMLElementDecl();
572         while (getElementDecl(elementDeclIndex++, elementDecl)) {
573             System.out.println("element decl: "+elementDecl.name+
574                                ", "+pool.toString(elementDecl.name.rawname)+
575                                ", "+XMLContentSpec.toString(this, pool, elementDecl.contentSpecIndex));
576         }
577     }
578
579     public void printAttributes(int elementDeclIndex) {
580         int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
581         System.out.print(elementDeclIndex);
582         System.out.print(" [");
583         while (attributeDeclIndex != -1) {
584             System.out.print(' ');
585             System.out.print(attributeDeclIndex);
586             printAttribute(attributeDeclIndex);
587             attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
588             if (attributeDeclIndex != -1) {
589                 System.out.print(",");
590             }
591         }
592         System.out.println(" ]");
593     }
594
595     //
596
// Private methods
597
//
598

599     // debugging
600

601     private void printAttribute(int attributeDeclIndex) {
602         XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
603         if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
604             System.out.print(" { ");
605             System.out.print(attributeDecl.name.localpart);
606             System.out.print(" }");
607         }
608     }
609
610     // content models
611

612     //
613
// When the element has a 'CHILDREN' model, this method is called to
614
// create the content model object. It looks for some special case simple
615
// models and creates SimpleContentModel objects for those. For the rest
616
// it creates the standard DFA style model.
617
//
618
private final XMLContentModel createChildModel(int contentSpecIndex, boolean isMixed) throws CMException
619     {
620         //
621
// Get the content spec node for the element we are working on.
622
// This will tell us what kind of node it is, which tells us what
623
// kind of model we will try to create.
624
//
625
XMLContentSpec contentSpec = new XMLContentSpec();
626
627
628         getContentSpec(contentSpecIndex, contentSpec);
629
630         if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY ||
631             (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
632             (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
633             // let fall through to build a DFAContentModel
634
}
635         else if (isMixed) {
636             if ((contentSpec.type & 0x0f)==XMLContentSpec.CONTENTSPECNODE_ALL) {
637                 // All the nodes under an ALL must be additional ALL nodes and
638
// ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
639
// We collapse the ELEMENTs into a single vector.
640
AllContentModel allContent = new AllContentModel(false, true);
641                 gatherAllLeaves(contentSpecIndex, contentSpec, allContent);
642
643                 return allContent;
644             }
645             else if ((contentSpec.type & 0x0f) ==
646                      XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
647                 int zeroOrOneChildIndex = contentSpec.value;
648                 getContentSpec(zeroOrOneChildIndex, contentSpec);
649
650                 // An ALL node can appear under a ZERO_OR_ONE node.
651
if ((contentSpec.type & 0x0f) ==
652                     XMLContentSpec.CONTENTSPECNODE_ALL) {
653                     AllContentModel allContent = new AllContentModel(true,true);
654                     gatherAllLeaves(zeroOrOneChildIndex, contentSpec,
655                                     allContent);
656
657                     return new AllContentModel(true);
658                 }
659             }
660             // otherwise, let fall through to build a DFAContentModel
661
}
662
663         else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
664             //
665
// Check that the left value is not -1, since any content model
666
// with PCDATA should be MIXED, so we should not have gotten here.
667
//
668
if (contentSpec.value == -1 && contentSpec.otherValue == -1)
669                 throw new CMException(ImplementationMessages.VAL_NPCD);
670
671             //
672
// It's a single leaf, so it's an 'a' type of content model, i.e.
673
// just one instance of one element. That one is definitely a
674
// simple content model.
675
//
676

677             fQName1.setValues(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
678             return new SimpleContentModel(fQName1, null, contentSpec.type, isDTD());
679         }
680         else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
681                    || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
682             //
683
// Lets see if both of the children are leafs. If so, then
684
// it has to be a simple content model
685
//
686
XMLContentSpec contentSpecLeft = new XMLContentSpec();
687             XMLContentSpec contentSpecRight = new XMLContentSpec();
688
689             getContentSpec(contentSpec.value, contentSpecLeft);
690             getContentSpec(contentSpec.otherValue, contentSpecRight);
691
692             if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
693                 && (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
694                 //
695
// It's a simple choice or sequence, so we can do a simple
696
// content model for it.
697
//
698
fQName1.setValues(-1, contentSpecLeft.value, contentSpecLeft.value, contentSpecLeft.otherValue);
699                 fQName2.setValues(-1, contentSpecRight.value, contentSpecRight.value, contentSpecRight.otherValue);
700                 return new SimpleContentModel(fQName1, fQName2, contentSpec.type, isDTD());
701             }
702         }
703         else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
704                    || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
705                    || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
706             //
707
// It's a repetition, so see if its one child is a leaf. If so
708
// it's a repetition of a single element, so we can do a simple
709
// content model for that.
710
//
711
XMLContentSpec contentSpecLeft = new XMLContentSpec();
712             getContentSpec(contentSpec.value, contentSpecLeft);
713
714             if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
715                 //
716
// It is, so we can create a simple content model here that
717
// will check for this repetition. We pass -1 for the unused
718
// right node.
719
//
720
fQName1.setValues(-1, contentSpecLeft.value, contentSpecLeft.value, contentSpecLeft.otherValue);
721                 return new SimpleContentModel(fQName1, null, contentSpec.type, isDTD());
722             }
723             else if (contentSpecLeft.type==XMLContentSpec.CONTENTSPECNODE_ALL) {
724                 // An ALL can be optional. We must use the special
725
// AllContentModel for such an animal. Indicate the
726
// entire content is optional on the constructor.
727
AllContentModel allContent = new AllContentModel(true);
728
729                 // All of the nodes under an ALL must be additional ALL nodes
730
// and ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
731
// We collapse the ELEMENTs into a single vector.
732
gatherAllLeaves(contentSpec.value, contentSpecLeft, allContent);
733
734                 return allContent;
735             }
736         }
737         else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ALL) {
738             // All of the nodes under an ALL must be additional ALL nodes and
739
// ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
740
// We collapse the ELEMENTs into a single vector.
741
AllContentModel allContent = new AllContentModel(false);
742             gatherAllLeaves(contentSpecIndex, contentSpec, allContent);
743
744             return allContent;
745         }
746         else {
747             throw new CMException(ImplementationMessages.VAL_CST);
748         }
749
750         //
751
// It's not a simple content model, so here we have to create a DFA
752
// for this element. So we create a DFAContentModel object. He
753
// encapsulates all of the work to create the DFA.
754
//
755

756         //int leafCount = countLeaves(contentSpecIndex);
757
fLeafCount = 0;
758         CMNode cmn = buildSyntaxTree(contentSpecIndex, contentSpec);
759
760         // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
761
return new DFAContentModel( cmn, fLeafCount, isDTD(), isMixed);
762     }
763
764     private void printSyntaxTree(CMNode cmn){
765         System.out.println("CMNode : " + cmn.type());
766
767         if (cmn.type() == XMLContentSpec.CONTENTSPECNODE_LEAF) {
768             System.out.println( " Leaf: " + ((CMLeaf)cmn).getElement());
769             return;
770         }
771         if (cmn instanceof CMBinOp) {
772             printSyntaxTree( ((CMBinOp)cmn).getLeft());
773             printSyntaxTree( ((CMBinOp)cmn).getRight());
774         }
775         if (cmn instanceof CMUniOp) {
776             printSyntaxTree( ((CMUniOp)cmn).getChild());
777         }
778
779     }
780
781
782     private int countLeaves(int contentSpecIndex) {
783         return countLeaves(contentSpecIndex, new XMLContentSpec());
784     }
785
786     private int countLeaves(int contentSpecIndex, XMLContentSpec contentSpec) {
787
788         if (contentSpecIndex == -1) {
789             return 0;
790         }
791         /****
792         int chunk = contentSpecIndex >> CHUNK_SHIFT;
793         int index = contentSpecIndex & CHUNK_MASK;
794         int type = fContentSpecType[chunk][index];
795         if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
796             return 1;
797         }
798         int value = fContentSpecValue[chunk][index];
799         int otherValue = fContentSpecOtherValue[chunk][index];
800         return countLeaves(value) + countLeaves(otherValue);
801         /***/

802         getContentSpec(contentSpecIndex, contentSpec);
803         if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
804             return 1;
805         }
806         int value = contentSpec.value;
807         int otherValue = contentSpec.otherValue;
808         return countLeaves(value, contentSpec) + countLeaves(otherValue, contentSpec);
809         /***/
810     }
811
812     private int fLeafCount = 0;
813     private int fEpsilonIndex = -1;
814     private final CMNode buildSyntaxTree(int startNode, XMLContentSpec contentSpec) throws CMException
815     {
816         // We will build a node at this level for the new tree
817
CMNode nodeRet = null;
818         getContentSpec(startNode, contentSpec);
819         if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
820             (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
821             (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
822             nodeRet = new CMAny(contentSpec.type, contentSpec.otherValue, fLeafCount++);
823         }
824         //
825
// If this node is a leaf, then it's an easy one. We just add it
826
// to the tree.
827
//
828
else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
829             //
830
// Create a new leaf node, and pass it the current leaf count,
831
// which is its DFA state position. Bump the leaf count after
832
// storing it. This makes the positions zero based since we
833
// store first and then increment.
834
//
835
fQName1.setValues(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
836             nodeRet = new CMLeaf(fQName1, fLeafCount++);
837         }
838         else {
839             //
840
// It's not a leaf, so we have to recurse its left and maybe right
841
// nodes. Save both values before we recurse and trash the node.
842
//
843
final int leftNode = contentSpec.value;
844             final int rightNode = contentSpec.otherValue;
845
846             if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
847                 || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
848                 //
849
// Recurse on both children, and return a binary op node
850
// with the two created sub nodes as its children. The node
851
// type is the same type as the source.
852
//
853

854                 nodeRet = new CMBinOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec)
855                                        , buildSyntaxTree(rightNode, contentSpec));
856
857         /* MODIFIED (Jan, 2001) */
858
859         } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
860                || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
861                || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
862         nodeRet = new CMUniOp(contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
863         }
864
865         /* MODIFIED (Jan, 2001) */
866
867         else {
868         throw new CMException(ImplementationMessages.VAL_CST);
869             }
870         }
871         // And return our new node for this level
872
return nodeRet;
873     }
874
875     /**
876      * Recursively build an AllContentModel based on a content spec tree
877      * rooted at an ALL node.
878      *
879      * @param contentSpecIndex
880      * A content spec tree containing only ALL, LEAF and
881      * ZERO_OR_ONE nodes. Any ZERO_OR_ONE nodes must be parents
882      * of LEAF nodes.
883      * @param contentSpec
884      * A temporary XMLContentSpec object used to record info.
885      * about the current node in the tree. Used as a scratch
886      * pad by each recursive invocation of this method.
887      * @param allContent
888      * The AllContentModel that's being built for this tree
889      * @exception CMException
890      */

891     private final void gatherAllLeaves(int contentSpecIndex,
892                                        XMLContentSpec contentSpec,
893                                        AllContentModel allContent)
894                          throws CMException {
895
896       if (contentSpecIndex <= -1) return;
897
898       getContentSpec(contentSpecIndex, contentSpec);
899
900       int value = contentSpec.value;
901       int otherValue = contentSpec.otherValue;
902       int type = contentSpec.type;
903
904       if (type == XMLContentSpec.CONTENTSPECNODE_ALL) {
905           // At an all node, visit left and right subtrees
906
gatherAllLeaves(value, contentSpec, allContent);
907           gatherAllLeaves(otherValue, contentSpec, allContent);
908       }
909       else if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
910           // At leaf, add the element to list of elements permitted in the all
911
allContent.addElement(new QName(-1, value, value, otherValue), false);
912       }
913       else if (type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
914           // At ZERO_OR_ONE node, subtree must be an element
915
// that was specified with minOccurs=0, maxOccurs=1
916
getContentSpec(value, contentSpec);
917
918           value = contentSpec.value;
919           otherValue = contentSpec.otherValue;
920           type = contentSpec.type;
921
922           if (type != XMLContentSpec.CONTENTSPECNODE_LEAF)
923               throw new CMException(ImplementationMessages.VAL_CST);
924
925           // Add the optional element to list of elements permitted in the all
926
allContent.addElement(new QName(-1, value, value, otherValue), true);
927       }
928       else {
929           throw new CMException(ImplementationMessages.VAL_CST);
930       }
931     }
932
933     /**
934      * Build a vector of valid QNames from Content Spec
935      * table.
936      *
937      * @param contentSpecIndex
938      * Content Spec index
939      * @param vectorQName
940      * Array of QName
941      * @exception CMException
942      */

943     private void contentSpecTree(int contentSpecIndex,
944                                 XMLContentSpec contentSpec,
945                                 ChildrenList children) throws CMException {
946
947         // Handle any and leaf nodes
948
getContentSpec( contentSpecIndex, contentSpec);
949         if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
950             (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
951             (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS ||
952             (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
953
954             // resize arrays, if needed
955
if (children.length == children.qname.length) {
956                 QName[] newQName = new QName[children.length * 2];
957                 System.arraycopy(children.qname, 0, newQName, 0, children.length);
958                 children.qname = newQName;
959                 int[] newType = new int[children.length * 2];
960                 System.arraycopy(children.type, 0, newType, 0, children.length);
961                 children.type = newType;
962             }
963
964             // save values and return length
965
children.qname[children.length] = new QName(-1, contentSpec.value, contentSpec.value, contentSpec.otherValue);
966             children.type[children.length] = contentSpec.type;
967             children.length++;
968             return;
969         }
970
971         //
972
// It's not a leaf, so we have to recurse its left and maybe right
973
// nodes. Save both values before we recurse and trash the node.
974
//
975
final int leftNode = contentSpec.value;
976         final int rightNode = contentSpec.otherValue;
977
978         if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
979             contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
980             contentSpecTree(leftNode, contentSpec, children);
981             contentSpecTree(rightNode, contentSpec, children);
982             return;
983         }
984
985         if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ||
986             contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
987             contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
988             contentSpecTree(leftNode, contentSpec, children);
989             return;
990         }
991
992         // error
993
throw new CMException(ImplementationMessages.VAL_CST);
994     }
995
996
997
998     // ensure capacity
999

1000    private void ensureElementDeclCapacity(int chunk) {
1001        if (chunk >= fElementDeclName.length) {
1002            fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
1003            fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
1004            fElementDeclDatatypeValidator = resize(fElementDeclDatatypeValidator, fElementDeclDatatypeValidator.length * 2);
1005            fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex, fElementDeclContentSpecIndex.length * 2);
1006            fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
1007            fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
1008            fElementDeclUnique = resize(fElementDeclUnique, fElementDeclUnique.length * 2);
1009            fElementDeclKey = resize(fElementDeclKey, fElementDeclKey.length * 2);
1010            fElementDeclKeyRef = resize(fElementDeclKeyRef, fElementDeclKeyRef.length * 2);
1011        } else if (fElementDeclName[chunk] != null) {
1012            return;
1013        }
1014        fElementDeclName[chunk] = new QName[CHUNK_SIZE];
1015        fElementDeclType[chunk] = new int[CHUNK_SIZE];
1016        fElementDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
1017        fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
1018        fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
1019        fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
1020        fElementDeclUnique[chunk] = new Vector JavaDoc[CHUNK_SIZE];
1021        fElementDeclKey[chunk] = new Vector JavaDoc[CHUNK_SIZE];
1022        fElementDeclKeyRef[chunk] = new Vector JavaDoc[CHUNK_SIZE];
1023    }
1024
1025    private void ensureContentSpecCapacity(int chunk) {
1026        if (chunk >= fContentSpecType.length) {
1027            fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
1028            fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
1029            fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
1030            fContentSpecValidator = resize(fContentSpecValidator, fContentSpecValidator.length * 2);
1031        } else if (fContentSpecType[chunk] != null) {
1032            return;
1033        }
1034        fContentSpecType[chunk] = new int[CHUNK_SIZE];
1035        fContentSpecValue[chunk] = new int[CHUNK_SIZE];
1036        fContentSpecOtherValue[chunk] = new int[CHUNK_SIZE];
1037        fContentSpecValidator[chunk] = new XMLContentModel[CHUNK_SIZE];
1038    }
1039
1040    private void ensureAttributeDeclCapacity(int chunk) {
1041        if (chunk >= fAttributeDeclName.length) {
1042            fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
1043            fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
1044            fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
1045            fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
1046            fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2);
1047            fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
1048            fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
1049        } else if (fAttributeDeclName[chunk] != null) {
1050            return;
1051        }
1052        fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
1053        fAttributeDeclType[chunk] = new int[CHUNK_SIZE];
1054        fAttributeDeclEnumeration[chunk] = new int[CHUNK_SIZE];
1055        fAttributeDeclDefaultType[chunk] = new int[CHUNK_SIZE];
1056        fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
1057        fAttributeDeclDefaultValue[chunk] = new String JavaDoc[CHUNK_SIZE];
1058        fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
1059    }
1060
1061    // resize initial chunk
1062

1063    private int[][] resize(int array[][], int newsize) {
1064        int newarray[][] = new int[newsize][];
1065        System.arraycopy(array, 0, newarray, 0, array.length);
1066        return newarray;
1067    }
1068
1069    private DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
1070        DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
1071        System.arraycopy(array, 0, newarray, 0, array.length);
1072        return newarray;
1073    }
1074
1075    private XMLContentModel[][] resize(XMLContentModel array[][], int newsize) {
1076        XMLContentModel newarray[][] = new XMLContentModel[newsize][];
1077        System.arraycopy(array, 0, newarray, 0, array.length);
1078        return newarray;
1079    }
1080
1081    private QName[][] resize(QName array[][], int newsize) {
1082        QName newarray[][] = new QName[newsize][];
1083        System.arraycopy(array, 0, newarray, 0, array.length);
1084        return newarray;
1085    }
1086
1087    private String JavaDoc[][] resize(String JavaDoc array[][], int newsize) {
1088        String JavaDoc newarray[][] = new String JavaDoc[newsize][];
1089        System.arraycopy(array, 0, newarray, 0, array.length);
1090        return newarray;
1091    }
1092
1093    private Vector JavaDoc[][] resize(Vector JavaDoc array[][], int newsize) {
1094        Vector JavaDoc newarray[][] = new Vector JavaDoc[newsize][];
1095        System.arraycopy(array, 0, newarray, 0, array.length);
1096        return newarray;
1097    }
1098
1099    //
1100
// Classes
1101
//
1102

1103    /**
1104     * Children list for <code>contentSpecTree</code> method.
1105     */

1106    static class ChildrenList {
1107        public int length = 0;
1108        public QName[] qname = new QName[2];
1109        public int[] type = new int[2];
1110    }
1111
1112} // class Grammar
1113
Popular Tags