KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > framework > XMLContentSpec


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,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.framework;
59
60 import org.enhydra.apache.xerces.utils.StringPool;
61
62 /**
63  * ContentSpec really exists to aid the parser classes in implementing
64  * access to the grammar.
65  * <p>
66  * This class is used by the DTD scanner and the validator classes,
67  * allowing them to be used separately or together. This "struct"
68  * class is used to build content models for validation, where it
69  * is more efficient to fetch all of the information for each of
70  * these content model "fragments" than to fetch each field one at
71  * a time. Since configurations are allowed to have validators
72  * without a DTD scanner (i.e. a schema validator) and a DTD scanner
73  * without a validator (non-validating processor), this class can be
74  * used by each without requiring the presence of the other.
75  * <p>
76  * When processing element declarations, the DTD scanner will build
77  * up a representation of the content model using the node types that
78  * are defined here. Since a non-validating processor only needs to
79  * remember the type of content model declared (i.e. ANY, EMPTY, MIXED,
80  * or CHILDREN), it is free to discard the specific details of the
81  * MIXED and CHILDREN content models described using this class.
82  * <p>
83  * In the typical case of a validating processor reading the grammar
84  * of the document from a DTD, the information about the content model
85  * declared will be preserved and later "compiled" into an efficient
86  * form for use during element validation. Each content spec node
87  * that is saved is assigned a unique index that is used as a handle
88  * for the "value" or "otherValue" fields of other content spec nodes.
89  * A leaf node has a "value" that is either an index in the string
90  * pool of the element type of that leaf, or a value of -1 to indicate
91  * the special "#PCDATA" leaf type used in a mixed content model.
92  * <p>
93  * For a mixed content model, the content spec will be made up of
94  * leaf and choice content spec nodes, with an optional "zero or more"
95  * node. For example, the mixed content declaration "(#PCDATA)" would
96  * contain a single leaf node with a node value of -1. A mixed content
97  * declaration of "(#PCDATA|foo)*" would have a content spec consisting
98  * of two leaf nodes, for the "#PCDATA" and "foo" choices, a choice node
99  * with the "value" set to the index of the "#PCDATA" leaf node and the
100  * "otherValue" set to the index of the "foo" leaf node, and a "zero or
101  * more" node with the "value" set to the index of the choice node. If
102  * the content model has more choices, for example "(#PCDATA|a|b)*", then
103  * there will be more corresponding choice and leaf nodes, the choice
104  * nodes will be chained together through the "value" field with each
105  * leaf node referenced by the "otherValue" field.
106  * <p>
107  * For element content models, there are sequence nodes and also "zero or
108  * one" and "one or more" nodes. The leaf nodes would always have a valid
109  * string pool index, as the "#PCDATA" leaf is not used in the declarations
110  * for element content models.
111  *
112  * @version $Id: XMLContentSpec.java,v 1.1.1.1 2003/03/10 16:34:32 taweili Exp $
113  */

114 public class XMLContentSpec {
115
116     //
117
// Constants
118
//
119

120     /**
121      * Name or #PCDATA. Leaf nodes that represent parsed character
122      * data (#PCDATA) have values of -1.
123      */

124     public static final int CONTENTSPECNODE_LEAF = 0;
125
126     /** Represents a zero or one occurence count, '?'. */
127     public static final int CONTENTSPECNODE_ZERO_OR_ONE = 1;
128
129     /** Represents a zero or more occurence count, '*'. */
130     public static final int CONTENTSPECNODE_ZERO_OR_MORE = 2;
131     
132     /** Represents a one or more occurence count, '+'. */
133     public static final int CONTENTSPECNODE_ONE_OR_MORE = 3;
134     
135     /** Represents choice, '|'. */
136     public static final int CONTENTSPECNODE_CHOICE = 4;
137     
138     /** Represents sequence, ','. */
139     public static final int CONTENTSPECNODE_SEQ = 5;
140
141     /**
142      * Represents any namespace specified namespace. When the element
143      * found in the document must belong to a specific namespace,
144      * <code>otherValue</code> will contain the name of the namespace.
145      * If <code>otherValue</code> is <code>-1</code> then the element
146      * can be from any namespace.
147      * <p>
148      * Lists of valid namespaces are created from choice content spec
149      * nodes that have any content spec nodes as children.
150      */

151     public static final int CONTENTSPECNODE_ANY = 6;
152
153     /**
154      * Represents any other namespace (XML Schema: ##other).
155      * <p>
156      * When the content spec node type is set to CONTENTSPECNODE_ANY_OTHER,
157      * <code>value</code> will contain the namespace that <em>cannot</em>
158      * occur.
159      */

160     public static final int CONTENTSPECNODE_ANY_OTHER = 7;
161
162     /** Represents any namespace element (including "##local"). */
163     public static final int CONTENTSPECNODE_ANY_NS = 8;
164
165     /** Represents <ALL> */
166     public static final int CONTENTSPECNODE_ALL = 9;
167
168     /** prcessContent is 'lax' **/
169     public static final int CONTENTSPECNODE_ANY_LAX = 22;
170
171     public static final int CONTENTSPECNODE_ANY_OTHER_LAX = 23;
172
173     public static final int CONTENTSPECNODE_ANY_NS_LAX = 24;
174
175     /** processContent is 'skip' **/
176     
177     public static final int CONTENTSPECNODE_ANY_SKIP = 38;
178
179     public static final int CONTENTSPECNODE_ANY_OTHER_SKIP = 39;
180
181     public static final int CONTENTSPECNODE_ANY_NS_SKIP = 40;
182     //
183
// Data
184
//
185

186     /**
187      * The content spec node type.
188      *
189      * @see CONTENTSPECNODE_LEAF
190      * @see CONTENTSPECNODE_ZERO_OR_ONE
191      * @see CONTENTSPECNODE_ZERO_OR_MORE
192      * @see CONTENTSPECNODE_ONE_OR_MORE
193      * @see CONTENTSPECNODE_CHOICE
194      * @see CONTENTSPECNODE_SEQ
195      * @see CONTENTSPECNODE_ALL
196      */

197     public int type;
198
199     /**
200      * The "left hand" value of the content spec node.
201      * // leaf index, single child for unary ops, left child for binary ops.
202      */

203     public int value;
204
205     /**
206      * The "right hand" value of the content spec node.
207      * // right child for binary ops
208      */

209     public int otherValue;
210
211     //
212
// Constructors
213
//
214

215     /** Default constructor. */
216     public XMLContentSpec() {
217         clear();
218     }
219
220     /** Constructs a content spec with the specified values. */
221     public XMLContentSpec(int type, int value, int otherValue) {
222         setValues(type, value, otherValue);
223     }
224
225     /**
226      * Constructs a content spec from the values in the specified content spec.
227      */

228     public XMLContentSpec(XMLContentSpec contentSpec) {
229         setValues(contentSpec);
230     }
231
232     /**
233      * Constructs a content spec from the values specified by the given
234      * content spec provider and identifier.
235      */

236     public XMLContentSpec(XMLContentSpec.Provider provider,
237                           int contentSpecIndex) {
238         setValues(provider, contentSpecIndex);
239     }
240
241     //
242
// Public methods
243
//
244

245     /** Clears the values. */
246     public void clear() {
247         type = -1;
248         value = -1;
249         otherValue = -1;
250     }
251
252     /** Sets the values. */
253     public void setValues(int type, int value, int otherValue) {
254         this.type = type;
255         this.value = value;
256         this.otherValue = otherValue;
257     }
258     
259     /** Sets the values of the specified content spec. */
260     public void setValues(XMLContentSpec contentSpec) {
261         type = contentSpec.type;
262         value = contentSpec.value;
263         otherValue = contentSpec.otherValue;
264     }
265
266     /**
267      * Sets the values from the values specified by the given content spec
268      * provider and identifier. If the specified content spec cannot be
269      * provided, the values of this content spec are cleared.
270      */

271     public void setValues(XMLContentSpec.Provider provider,
272                           int contentSpecIndex) {
273         if (!provider.getContentSpec(contentSpecIndex, this)) {
274             clear();
275         }
276     }
277
278     //
279
// Public static methods
280
//
281

282     /**
283      * Returns a string representation of the specified content spec
284      * identifier in the form of a DTD element content model.
285      * <p>
286      * <strong>Note:</strong> This method is not namespace aware.
287      */

288     public static String JavaDoc toString(XMLContentSpec.Provider provider,
289                                   StringPool stringPool,
290                                   int contentSpecIndex) {
291
292         // lookup content spec node
293
XMLContentSpec contentSpec = new XMLContentSpec();
294        
295         if (provider.getContentSpec(contentSpecIndex, contentSpec)) {
296
297             // build string
298
StringBuffer JavaDoc str = new StringBuffer JavaDoc();
299             int parentContentSpecType = contentSpec.type & 0x0f;
300             int nextContentSpec;
301             switch (parentContentSpecType) {
302                 case XMLContentSpec.CONTENTSPECNODE_LEAF: {
303                     str.append('(');
304                     if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
305                         str.append("#PCDATA");
306                     }
307                     else {
308                         str.append(stringPool.toString(contentSpec.value));
309                     }
310                     str.append(')');
311                     break;
312                 }
313                 case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
314                     provider.getContentSpec(contentSpec.value, contentSpec);
315                     nextContentSpec = contentSpec.type;
316
317                     if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
318                         str.append('(');
319                         str.append(stringPool.toString(contentSpec.value));
320                         str.append(')');
321                     } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
322                             nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
323                             nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
324                         str.append('(' );
325                         appendContentSpec(provider, stringPool, contentSpec, str,
326                                                                  true, parentContentSpecType );
327                         str.append(')');
328
329                     } else {
330                         appendContentSpec(provider, stringPool, contentSpec, str,
331                                                                  true, parentContentSpecType );
332                     }
333                     str.append('?');
334                     break;
335                 }
336                 case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
337                     provider.getContentSpec(contentSpec.value, contentSpec);
338                     nextContentSpec = contentSpec.type;
339
340                     if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
341                         str.append('(');
342                         if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
343                             str.append("#PCDATA");
344                         }
345                         else if (contentSpec.otherValue != -1) {
346                             str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
347                         }
348                         else if (contentSpec.value == -1) {
349                             str.append("##any");
350                         }
351                         else {
352                              appendContentSpec(provider, stringPool, contentSpec, str,
353                                                     true, parentContentSpecType );
354                         }
355                         str.append(')');
356
357                     } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
358                         nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
359                         nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
360                         str.append('(' );
361                         appendContentSpec(provider, stringPool, contentSpec, str,
362                                                             true, parentContentSpecType );
363                         str.append(')');
364                     } else {
365                         appendContentSpec(provider, stringPool, contentSpec, str,
366                                                                 true, parentContentSpecType );
367
368                         //str.append(stringPool.toString(contentSpec.value));
369
}
370                     str.append('*');
371                     break;
372                 }
373                 case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
374                     provider.getContentSpec(contentSpec.value, contentSpec);
375                     nextContentSpec = contentSpec.type;
376
377                     if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
378                         str.append('(');
379                         if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
380                             str.append("#PCDATA");
381                         }
382                         else if (contentSpec.otherValue != -1) {
383                             str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
384                         }
385                         else if (contentSpec.value == -1) {
386                             str.append("##any");
387                         }
388                         else {
389                             str.append(stringPool.toString(contentSpec.value));
390                         }
391                         str.append(')');
392                     } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
393                         nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
394                         nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
395                         str.append('(' );
396                         appendContentSpec(provider, stringPool, contentSpec, str,
397                                                       true, parentContentSpecType );
398                         str.append(')');
399                     } else {
400                         appendContentSpec(provider, stringPool, contentSpec, str,
401                                                             true, parentContentSpecType);
402                     }
403                     str.append('+');
404                     break;
405                 }
406                 case XMLContentSpec.CONTENTSPECNODE_ALL:
407                 case XMLContentSpec.CONTENTSPECNODE_CHOICE:
408                 case XMLContentSpec.CONTENTSPECNODE_SEQ: {
409                     appendContentSpec(provider, stringPool,
410                                       contentSpec, str, true,
411                                       parentContentSpecType );
412                     break;
413                 }
414                 case XMLContentSpec.CONTENTSPECNODE_ANY: {
415                     str.append("##any");
416                     break;
417                 }
418                 case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
419                     str.append("##other:uri=");
420                     str.append(stringPool.toString(contentSpec.otherValue));
421                     break;
422                 }
423                 case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
424                     str.append("namespace:uri=");
425                     str.append(stringPool.toString(contentSpec.otherValue));
426                     break;
427                 }
428                 default: {
429                     str.append("???");
430                 }
431
432             } // switch type
433

434             // return string
435
return str.toString();
436         }
437
438         // not found
439
return null;
440
441     } // toString(XMLContentSpec.Provider):String
442

443     //
444
// Object methods
445
//
446

447     /** Returns a hash code for this node. */
448     public int hashCode() {
449         return type << 16 |
450                value << 8 |
451                otherValue;
452     }
453
454     /** Returns true if the two objects are equal. */
455     public boolean equals(Object JavaDoc object) {
456         if (object != null && object instanceof XMLContentSpec) {
457             XMLContentSpec contentSpec = (XMLContentSpec)object;
458             return type == contentSpec.type &&
459                    value == contentSpec.value &&
460                    otherValue == contentSpec.otherValue;
461         }
462         return false;
463     }
464
465     //
466
// Private static methods
467
//
468

469     /**
470      * Appends more information to the current string buffer.
471      * <p>
472      * <strong>Note:</strong> This method does <em>not</em> preserve the
473      * contents of the content spec node.
474      */

475     private static void appendContentSpec(XMLContentSpec.Provider provider,
476                                           StringPool stringPool,
477                                           XMLContentSpec contentSpec,
478                                           StringBuffer JavaDoc str,
479                                           boolean parens,
480                                           int parentContentSpecType ) {
481
482         int thisContentSpec = contentSpec.type & 0x0f;
483         switch (thisContentSpec) {
484             case XMLContentSpec.CONTENTSPECNODE_LEAF: {
485                 if (contentSpec.value == -1 && contentSpec.otherValue == -1) {
486                     str.append("#PCDATA");
487                 }
488                 else if (contentSpec.value == -1 && contentSpec.otherValue != -1) {
489                     str.append("##any:uri="+stringPool.toString(contentSpec.otherValue));
490                 }
491                 else if (contentSpec.value == -1) {
492                     str.append("##any");
493                 }
494                 else {
495                     str.append(stringPool.toString(contentSpec.value));
496                 }
497                 break;
498             }
499             case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
500                 if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
501                     parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
502                     parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
503                     provider.getContentSpec(contentSpec.value, contentSpec);
504                     str.append('(');
505                     appendContentSpec(provider, stringPool,
506                                       contentSpec, str, true, thisContentSpec );
507                     str.append(')');
508
509                 }
510                 else {
511                     provider.getContentSpec(contentSpec.value, contentSpec);
512                     appendContentSpec(provider, stringPool,
513                                       contentSpec, str, true, thisContentSpec );
514                 }
515                 str.append('?');
516                 break;
517             }
518             case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
519                 if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
520                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
521                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
522                    provider.getContentSpec(contentSpec.value, contentSpec);
523                    str.append('(');
524                    appendContentSpec(provider, stringPool,
525                                       contentSpec, str, true, thisContentSpec);
526                    str.append(')' );
527                 } else{
528                     provider.getContentSpec(contentSpec.value, contentSpec);
529                     appendContentSpec(provider, stringPool,
530                                      contentSpec, str, true, thisContentSpec);
531                 }
532                 str.append('*');
533                 break;
534             }
535             case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
536                 if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
537                     parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
538                     parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
539
540                   str.append('(');
541                   provider.getContentSpec(contentSpec.value, contentSpec);
542                   appendContentSpec(provider, stringPool,
543                                     contentSpec, str, true, thisContentSpec);
544                   str.append(')' );
545                 } else {
546                     provider.getContentSpec(contentSpec.value, contentSpec);
547                     appendContentSpec(provider, stringPool,
548                                    contentSpec, str, true, thisContentSpec);
549                 }
550                 str.append('+');
551                 break;
552             }
553             case XMLContentSpec.CONTENTSPECNODE_CHOICE:
554             case XMLContentSpec.CONTENTSPECNODE_SEQ:
555             case XMLContentSpec.CONTENTSPECNODE_ALL: {
556                 int type = contentSpec.type;
557                 if (parens) {
558                     if (type == XMLContentSpec.CONTENTSPECNODE_ALL)
559                         str.append("all(");
560                     else
561                         str.append('(');
562                 }
563                 int otherValue = contentSpec.otherValue;
564                 provider.getContentSpec(contentSpec.value, contentSpec);
565                 appendContentSpec(provider, stringPool,
566                            contentSpec, str, contentSpec.type != type, thisContentSpec);
567                 if (otherValue != -2) {
568                 if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
569                     str.append('|');
570                 }
571                 else {
572                     str.append(',');
573                 }
574                 /***
575                 // REVISIT: Do we need this? -Ac
576                 if (++index == CHUNK_SIZE) {
577                     chunk++;
578                     index = 0;
579                 }
580                 /***/

581                 provider.getContentSpec(otherValue, contentSpec);
582                 appendContentSpec(provider, stringPool,
583                                   contentSpec, str, true, thisContentSpec);
584                 }
585                 if (parens) {
586                     str.append(')');
587                 }
588                 break;
589             }
590             case XMLContentSpec.CONTENTSPECNODE_ANY: {
591                 str.append("##any");
592                 break;
593             }
594             case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
595                 str.append("##other:uri=");
596                 str.append(stringPool.toString(contentSpec.otherValue));
597                 break;
598             }
599             case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
600                 str.append("namespace:uri=");
601                 str.append(stringPool.toString(contentSpec.otherValue));
602                 break;
603             }
604             default: {
605                 str.append("???");
606                 break;
607             }
608
609         } // switch type
610

611     } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
612

613     //
614
// Interfaces
615
//
616

617     /**
618      * Provides a means for walking the structure built out of
619      * content spec "nodes". The user of this provider interface is
620      * responsible for knowing what the content spec node values
621      * "mean". If those values refer to content spec identifiers,
622      * then the user can call back into the provider to get the
623      * next content spec node in the structure.
624      */

625     public interface Provider {
626
627         //
628
// XMLContentSpec.Provider methods
629
//
630

631         /**
632          * Fills in the provided content spec structure with content spec
633          * information for a unique identifier.
634          *
635          * @param contentSpecIndex The content spec identifier. All content
636          * spec "nodes" have a unique identifier.
637          * @param contentSpec The content spec struct to fill in with
638          * the information.
639          *
640          * @return Returns true if the contentSpecIndex was found.
641          */

642         public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec);
643
644     } // interface Provider
645

646 } // class XMLContentSpec
647
Popular Tags