1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * The Apache Software License, Version 1.1
7  *
8  *
9  * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
10  * reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in
21  *    the documentation and/or other materials provided with the
22  *    distribution.
23  *
24  * 3. The end-user documentation included with the redistribution,
25  *    if any, must include the following acknowledgment:
26  *       "This product includes software developed by the
27  *        Apache Software Foundation (http://www.apache.org/)."
28  *    Alternately, this acknowledgment may appear in the software itself,
29  *    if and wherever such third-party acknowledgments normally appear.
30  *
31  * 4. The names "Xerces" and "Apache Software Foundation" must
32  *    not be used to endorse or promote products derived from this
33  *    software without prior written permission. For written
34  *    permission, please contact apache@apache.org.
35  *
36  * 5. Products derived from this software may not be called "Apache",
37  *    nor may "Apache" appear in their name, without prior written
38  *    permission of the Apache Software Foundation.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Apache Software Foundation and was
56  * originally based on software copyright (c) 1999, International
57  * Business Machines, Inc., http://www.apache.org.  For more
58  * information on the Apache Software Foundation, please see
59  * <http://www.apache.org/>.
60  */
61 
62 package com.sun.org.apache.xerces.internal.impl.dtd;
63 
64 /**
65  * ContentSpec really exists to aid the parser classes in implementing
66  * access to the grammar.
67  * <p>
68  * This class is used by the DTD scanner and the validator classes,
69  * allowing them to be used separately or together.  This "struct"
70  * class is used to build content models for validation, where it
71  * is more efficient to fetch all of the information for each of
72  * these content model "fragments" than to fetch each field one at
73  * a time.  Since configurations are allowed to have validators
74  * without a DTD scanner (i.e. a schema validator) and a DTD scanner
75  * without a validator (non-validating processor), this class can be
76  * used by each without requiring the presence of the other.
77  * <p>
78  * When processing element declarations, the DTD scanner will build
79  * up a representation of the content model using the node types that
80  * are defined here.  Since a non-validating processor only needs to
81  * remember the type of content model declared (i.e. ANY, EMPTY, MIXED,
82  * or CHILDREN), it is free to discard the specific details of the
83  * MIXED and CHILDREN content models described using this class.
84  * <p>
85  * In the typical case of a validating processor reading the grammar
86  * of the document from a DTD, the information about the content model
87  * declared will be preserved and later "compiled" into an efficient
88  * form for use during element validation.  Each content spec node
89  * that is saved is assigned a unique index that is used as a handle
90  * for the "value" or "otherValue" fields of other content spec nodes.
91  * A leaf node has a "value" that is either an index in the string
92  * pool of the element type of that leaf, or a value of -1 to indicate
93  * the special "#PCDATA" leaf type used in a mixed content model.
94  * <p>
95  * For a mixed content model, the content spec will be made up of
96  * leaf and choice content spec nodes, with an optional "zero or more"
97  * node.  For example, the mixed content declaration "(#PCDATA)" would
98  * contain a single leaf node with a node value of -1.  A mixed content
99  * declaration of "(#PCDATA|foo)*" would have a content spec consisting
100  * of two leaf nodes, for the "#PCDATA" and "foo" choices, a choice node
101  * with the "value" set to the index of the "#PCDATA" leaf node and the
102  * "otherValue" set to the index of the "foo" leaf node, and a "zero or
103  * more" node with the "value" set to the index of the choice node.  If
104  * the content model has more choices, for example "(#PCDATA|a|b)*", then
105  * there will be more corresponding choice and leaf nodes, the choice
106  * nodes will be chained together through the "value" field with each
107  * leaf node referenced by the "otherValue" field.
108  * <p>
109  * For element content models, there are sequence nodes and also "zero or
110  * one" and "one or more" nodes.  The leaf nodes would always have a valid
111  * string pool index, as the "#PCDATA" leaf is not used in the declarations
112  * for element content models.
113  *
114  * @xerces.internal
115  *
116  */
117 public class XMLContentSpec {
118 
119     //
120     // Constants
121     //
122 
123     /**
124      * Name or #PCDATA. Leaf nodes that represent parsed character
125      * data (#PCDATA) have values of -1.
126      */
127     public static final short CONTENTSPECNODE_LEAF = 0;
128 
129     /** Represents a zero or one occurence count, '?'. */
130     public static final short CONTENTSPECNODE_ZERO_OR_ONE = 1;
131 
132     /** Represents a zero or more occurence count, '*'. */
133     public static final short CONTENTSPECNODE_ZERO_OR_MORE = 2;
134 
135     /** Represents a one or more occurence count, '+'. */
136     public static final short CONTENTSPECNODE_ONE_OR_MORE = 3;
137 
138     /** Represents choice, '|'. */
139     public static final short CONTENTSPECNODE_CHOICE = 4;
140 
141     /** Represents sequence, ','. */
142     public static final short CONTENTSPECNODE_SEQ = 5;
143 
144     /**
145      * Represents any namespace specified namespace. When the element
146      * found in the document must belong to a specific namespace,
147      * <code>otherValue</code> will contain the name of the namespace.
148      * If <code>otherValue</code> is <code>-1</code> then the element
149      * can be from any namespace.
150      * <p>
151      * Lists of valid namespaces are created from choice content spec
152      * nodes that have any content spec nodes as children.
153      */
154     public static final short CONTENTSPECNODE_ANY = 6;
155 
156     /**
157      * Represents any other namespace (XML Schema: ##other).
158      * <p>
159      * When the content spec node type is set to CONTENTSPECNODE_ANY_OTHER,
160      * <code>value</code> will contain the namespace that <em>cannot</em>
161      * occur.
162      */
163     public static final short CONTENTSPECNODE_ANY_OTHER = 7;
164 
165     /** Represents any local element (XML Schema: ##local). */
166     public static final short CONTENTSPECNODE_ANY_LOCAL = 8;
167 
168     /** prcessContent is 'lax' **/
169     public static final short CONTENTSPECNODE_ANY_LAX = 22;
170 
171     public static final short CONTENTSPECNODE_ANY_OTHER_LAX = 23;
172 
173     public static final short CONTENTSPECNODE_ANY_LOCAL_LAX = 24;
174 
175     /** processContent is 'skip' **/
176 
177     public static final short CONTENTSPECNODE_ANY_SKIP = 38;
178 
179     public static final short CONTENTSPECNODE_ANY_OTHER_SKIP = 39;
180 
181     public static final short CONTENTSPECNODE_ANY_LOCAL_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      */
196     public short type;
197 
198     /**
199      * The "left hand" value object of the content spec node.
200      * leaf name.localpart, single child for unary ops, left child for binary ops.
201      */
202     public Object value;
203 
204     /**
205      * The "right hand" value of the content spec node.
206      *  leaf name.uri, right child for binary ops
207      */
208     public Object otherValue;
209 
210     //
211     // Constructors
212     //
213 
214     /** Default constructor. */
XMLContentSpec()215     public XMLContentSpec() {
216         clear();
217     }
218 
219     /** Constructs a content spec with the specified values. */
XMLContentSpec(short type, Object value, Object otherValue)220     public XMLContentSpec(short type, Object value, Object otherValue) {
221         setValues(type, value, otherValue);
222     }
223 
224     /**
225      * Constructs a content spec from the values in the specified content spec.
226      */
XMLContentSpec(XMLContentSpec contentSpec)227     public XMLContentSpec(XMLContentSpec contentSpec) {
228         setValues(contentSpec);
229     }
230 
231     /**
232      * Constructs a content spec from the values specified by the given
233      * content spec provider and identifier.
234      */
XMLContentSpec(XMLContentSpec.Provider provider, int contentSpecIndex)235     public XMLContentSpec(XMLContentSpec.Provider provider,
236                           int contentSpecIndex) {
237         setValues(provider, contentSpecIndex);
238     }
239 
240     //
241     // Public methods
242     //
243 
244     /** Clears the values. */
clear()245     public void clear() {
246         type = -1;
247         value = null;
248         otherValue = null;
249     }
250 
251     /** Sets the values. */
setValues(short type, Object value, Object otherValue)252     public void setValues(short type, Object value, Object otherValue) {
253         this.type = type;
254         this.value = value;
255         this.otherValue = otherValue;
256     }
257 
258     /** Sets the values of the specified content spec. */
setValues(XMLContentSpec contentSpec)259     public void setValues(XMLContentSpec contentSpec) {
260         type = contentSpec.type;
261         value = contentSpec.value;
262         otherValue = contentSpec.otherValue;
263     }
264 
265     /**
266      * Sets the values from the values specified by the given content spec
267      * provider and identifier. If the specified content spec cannot be
268      * provided, the values of this content spec are cleared.
269      */
setValues(XMLContentSpec.Provider provider, int contentSpecIndex)270     public void setValues(XMLContentSpec.Provider provider,
271                           int contentSpecIndex) {
272         if (!provider.getContentSpec(contentSpecIndex, this)) {
273             clear();
274         }
275     }
276 
277 
278     //
279     // Object methods
280     //
281 
282     /** Returns a hash code for this node. */
hashCode()283     public int hashCode() {
284         return type << 16 |
285                value.hashCode() << 8 |
286                otherValue.hashCode();
287     }
288 
289     /** Returns true if the two objects are equal. */
equals(Object object)290     public boolean equals(Object object) {
291         if (object != null && object instanceof XMLContentSpec) {
292             XMLContentSpec contentSpec = (XMLContentSpec)object;
293             return type == contentSpec.type &&
294                    value == contentSpec.value &&
295                    otherValue == contentSpec.otherValue;
296         }
297         return false;
298     }
299 
300 
301     //
302     // Interfaces
303     //
304 
305     /**
306      * Provides a means for walking the structure built out of
307      * content spec "nodes". The user of this provider interface is
308      * responsible for knowing what the content spec node values
309      * "mean". If those values refer to content spec identifiers,
310      * then the user can call back into the provider to get the
311      * next content spec node in the structure.
312      *
313      * @xerces.internal
314      */
315     public interface Provider {
316 
317         //
318         // XMLContentSpec.Provider methods
319         //
320 
321         /**
322          * Fills in the provided content spec structure with content spec
323          * information for a unique identifier.
324          *
325          * @param contentSpecIndex The content spec identifier. All content
326          *                         spec "nodes" have a unique identifier.
327          * @param contentSpec      The content spec struct to fill in with
328          *                         the information.
329          *
330          * @return Returns true if the contentSpecIndex was found.
331          */
getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec)332         public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec);
333 
334     } // interface Provider
335 
336 } // class XMLContentSpec
337