1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xerces.internal.impl.dtd;
23 
24 /**
25  * ContentSpec really exists to aid the parser classes in implementing
26  * access to the grammar.
27  * <p>
28  * This class is used by the DTD scanner and the validator classes,
29  * allowing them to be used separately or together.  This "struct"
30  * class is used to build content models for validation, where it
31  * is more efficient to fetch all of the information for each of
32  * these content model "fragments" than to fetch each field one at
33  * a time.  Since configurations are allowed to have validators
34  * without a DTD scanner (i.e. a schema validator) and a DTD scanner
35  * without a validator (non-validating processor), this class can be
36  * used by each without requiring the presence of the other.
37  * <p>
38  * When processing element declarations, the DTD scanner will build
39  * up a representation of the content model using the node types that
40  * are defined here.  Since a non-validating processor only needs to
41  * remember the type of content model declared (i.e. ANY, EMPTY, MIXED,
42  * or CHILDREN), it is free to discard the specific details of the
43  * MIXED and CHILDREN content models described using this class.
44  * <p>
45  * In the typical case of a validating processor reading the grammar
46  * of the document from a DTD, the information about the content model
47  * declared will be preserved and later "compiled" into an efficient
48  * form for use during element validation.  Each content spec node
49  * that is saved is assigned a unique index that is used as a handle
50  * for the "value" or "otherValue" fields of other content spec nodes.
51  * A leaf node has a "value" that is either an index in the string
52  * pool of the element type of that leaf, or a value of -1 to indicate
53  * the special "#PCDATA" leaf type used in a mixed content model.
54  * <p>
55  * For a mixed content model, the content spec will be made up of
56  * leaf and choice content spec nodes, with an optional "zero or more"
57  * node.  For example, the mixed content declaration "(#PCDATA)" would
58  * contain a single leaf node with a node value of -1.  A mixed content
59  * declaration of "(#PCDATA|foo)*" would have a content spec consisting
60  * of two leaf nodes, for the "#PCDATA" and "foo" choices, a choice node
61  * with the "value" set to the index of the "#PCDATA" leaf node and the
62  * "otherValue" set to the index of the "foo" leaf node, and a "zero or
63  * more" node with the "value" set to the index of the choice node.  If
64  * the content model has more choices, for example "(#PCDATA|a|b)*", then
65  * there will be more corresponding choice and leaf nodes, the choice
66  * nodes will be chained together through the "value" field with each
67  * leaf node referenced by the "otherValue" field.
68  * <p>
69  * For element content models, there are sequence nodes and also "zero or
70  * one" and "one or more" nodes.  The leaf nodes would always have a valid
71  * string pool index, as the "#PCDATA" leaf is not used in the declarations
72  * for element content models.
73  *
74  * @xerces.internal
75  *
76  */
77 public class XMLContentSpec {
78 
79     //
80     // Constants
81     //
82 
83     /**
84      * Name or #PCDATA. Leaf nodes that represent parsed character
85      * data (#PCDATA) have values of -1.
86      */
87     public static final short CONTENTSPECNODE_LEAF = 0;
88 
89     /** Represents a zero or one occurence count, '?'. */
90     public static final short CONTENTSPECNODE_ZERO_OR_ONE = 1;
91 
92     /** Represents a zero or more occurence count, '*'. */
93     public static final short CONTENTSPECNODE_ZERO_OR_MORE = 2;
94 
95     /** Represents a one or more occurence count, '+'. */
96     public static final short CONTENTSPECNODE_ONE_OR_MORE = 3;
97 
98     /** Represents choice, '|'. */
99     public static final short CONTENTSPECNODE_CHOICE = 4;
100 
101     /** Represents sequence, ','. */
102     public static final short CONTENTSPECNODE_SEQ = 5;
103 
104     /**
105      * Represents any namespace specified namespace. When the element
106      * found in the document must belong to a specific namespace,
107      * <code>otherValue</code> will contain the name of the namespace.
108      * If <code>otherValue</code> is <code>-1</code> then the element
109      * can be from any namespace.
110      * <p>
111      * Lists of valid namespaces are created from choice content spec
112      * nodes that have any content spec nodes as children.
113      */
114     public static final short CONTENTSPECNODE_ANY = 6;
115 
116     /**
117      * Represents any other namespace (XML Schema: ##other).
118      * <p>
119      * When the content spec node type is set to CONTENTSPECNODE_ANY_OTHER,
120      * <code>value</code> will contain the namespace that <em>cannot</em>
121      * occur.
122      */
123     public static final short CONTENTSPECNODE_ANY_OTHER = 7;
124 
125     /** Represents any local element (XML Schema: ##local). */
126     public static final short CONTENTSPECNODE_ANY_LOCAL = 8;
127 
128     /** prcessContent is 'lax' **/
129     public static final short CONTENTSPECNODE_ANY_LAX = 22;
130 
131     public static final short CONTENTSPECNODE_ANY_OTHER_LAX = 23;
132 
133     public static final short CONTENTSPECNODE_ANY_LOCAL_LAX = 24;
134 
135     /** processContent is 'skip' **/
136 
137     public static final short CONTENTSPECNODE_ANY_SKIP = 38;
138 
139     public static final short CONTENTSPECNODE_ANY_OTHER_SKIP = 39;
140 
141     public static final short CONTENTSPECNODE_ANY_LOCAL_SKIP = 40;
142     //
143     // Data
144     //
145 
146     /**
147      * The content spec node type.
148      *
149      * @see #CONTENTSPECNODE_LEAF
150      * @see #CONTENTSPECNODE_ZERO_OR_ONE
151      * @see #CONTENTSPECNODE_ZERO_OR_MORE
152      * @see #CONTENTSPECNODE_ONE_OR_MORE
153      * @see #CONTENTSPECNODE_CHOICE
154      * @see #CONTENTSPECNODE_SEQ
155      */
156     public short type;
157 
158     /**
159      * The "left hand" value object of the content spec node.
160      * leaf name.localpart, single child for unary ops, left child for binary ops.
161      */
162     public Object value;
163 
164     /**
165      * The "right hand" value of the content spec node.
166      *  leaf name.uri, right child for binary ops
167      */
168     public Object otherValue;
169 
170     //
171     // Constructors
172     //
173 
174     /** Default constructor. */
XMLContentSpec()175     public XMLContentSpec() {
176         clear();
177     }
178 
179     /** Constructs a content spec with the specified values. */
XMLContentSpec(short type, Object value, Object otherValue)180     public XMLContentSpec(short type, Object value, Object otherValue) {
181         setValues(type, value, otherValue);
182     }
183 
184     /**
185      * Constructs a content spec from the values in the specified content spec.
186      */
XMLContentSpec(XMLContentSpec contentSpec)187     public XMLContentSpec(XMLContentSpec contentSpec) {
188         setValues(contentSpec);
189     }
190 
191     /**
192      * Constructs a content spec from the values specified by the given
193      * content spec provider and identifier.
194      */
XMLContentSpec(XMLContentSpec.Provider provider, int contentSpecIndex)195     public XMLContentSpec(XMLContentSpec.Provider provider,
196                           int contentSpecIndex) {
197         setValues(provider, contentSpecIndex);
198     }
199 
200     //
201     // Public methods
202     //
203 
204     /** Clears the values. */
clear()205     public void clear() {
206         type = -1;
207         value = null;
208         otherValue = null;
209     }
210 
211     /** Sets the values. */
setValues(short type, Object value, Object otherValue)212     public void setValues(short type, Object value, Object otherValue) {
213         this.type = type;
214         this.value = value;
215         this.otherValue = otherValue;
216     }
217 
218     /** Sets the values of the specified content spec. */
setValues(XMLContentSpec contentSpec)219     public void setValues(XMLContentSpec contentSpec) {
220         type = contentSpec.type;
221         value = contentSpec.value;
222         otherValue = contentSpec.otherValue;
223     }
224 
225     /**
226      * Sets the values from the values specified by the given content spec
227      * provider and identifier. If the specified content spec cannot be
228      * provided, the values of this content spec are cleared.
229      */
setValues(XMLContentSpec.Provider provider, int contentSpecIndex)230     public void setValues(XMLContentSpec.Provider provider,
231                           int contentSpecIndex) {
232         if (!provider.getContentSpec(contentSpecIndex, this)) {
233             clear();
234         }
235     }
236 
237 
238     //
239     // Object methods
240     //
241 
242     /** Returns a hash code for this node. */
hashCode()243     public int hashCode() {
244         return type << 16 |
245                value.hashCode() << 8 |
246                otherValue.hashCode();
247     }
248 
249     /** Returns true if the two objects are equal. */
equals(Object object)250     public boolean equals(Object object) {
251         if (object != null && object instanceof XMLContentSpec) {
252             XMLContentSpec contentSpec = (XMLContentSpec)object;
253             return type == contentSpec.type &&
254                    value == contentSpec.value &&
255                    otherValue == contentSpec.otherValue;
256         }
257         return false;
258     }
259 
260 
261     //
262     // Interfaces
263     //
264 
265     /**
266      * Provides a means for walking the structure built out of
267      * content spec "nodes". The user of this provider interface is
268      * responsible for knowing what the content spec node values
269      * "mean". If those values refer to content spec identifiers,
270      * then the user can call back into the provider to get the
271      * next content spec node in the structure.
272      *
273      * @xerces.internal
274      */
275     public interface Provider {
276 
277         //
278         // XMLContentSpec.Provider methods
279         //
280 
281         /**
282          * Fills in the provided content spec structure with content spec
283          * information for a unique identifier.
284          *
285          * @param contentSpecIndex The content spec identifier. All content
286          *                         spec "nodes" have a unique identifier.
287          * @param contentSpec      The content spec struct to fill in with
288          *                         the information.
289          *
290          * @return Returns true if the contentSpecIndex was found.
291          */
getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec)292         public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec);
293 
294     } // interface Provider
295 
296 } // class XMLContentSpec
297