KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > dtd > models > SimpleContentModel


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2002 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 com.sun.org.apache.xerces.internal.impl.dtd.models;
59
60 import com.sun.org.apache.xerces.internal.xni.QName;
61
62 import com.sun.org.apache.xerces.internal.impl.dtd.XMLContentSpec;
63
64 /**
65  * @version $Id: SimpleContentModel.java,v 1.4 2002/05/29 17:59:37 neilg Exp $
66  *
67  * SimpleContentModel is a derivative of the abstract content model base
68  * class that handles a small set of simple content models that are just
69  * way overkill to give the DFA treatment.
70  * <p>
71  * This class handles the following scenarios:
72  * <ul>
73  * <li> a
74  * <li> a?
75  * <li> a*
76  * <li> a+
77  * <li> a,b
78  * <li> a|b
79  * </ul>
80  * <p>
81  * These all involve a unary operation with one element type, or a binary
82  * operation with two elements. These are very simple and can be checked
83  * in a simple way without a DFA and without the overhead of setting up a
84  * DFA for such a simple check.
85  *
86  */

87 public class SimpleContentModel
88     implements ContentModelValidator {
89
90     //
91
// Constants
92
//
93

94     /** CHOICE */
95     public static final short CHOICE = -1;
96
97     /** SEQUENCE */
98     public static final short SEQUENCE = -1;
99
100     //
101
// Data
102
//
103

104
105     /**
106      * The element decl pool indices of the first (and optional second)
107      * child node. The operation code tells us whether the second child
108      * is used or not.
109      */

110     private QName fFirstChild = new QName();
111
112     /**
113      * The element decl pool indices of the first (and optional second)
114      * child node. The operation code tells us whether the second child
115      * is used or not.
116      */

117     private QName fSecondChild = new QName();
118
119     /**
120      * The operation that this object represents. Since this class only
121      * does simple contents, there is only ever a single operation
122      * involved (i.e. the children of the operation are always one or
123      * two leafs.) This is one of the XMLDTDParams.CONTENTSPECNODE_XXX values.
124      */

125     private int fOperator;
126
127     /* this is the EquivClassComparator object */
128     //private EquivClassComparator comparator = null;
129

130
131     //
132
// Constructors
133
//
134

135     /**
136      * Constructs a simple content model.
137      *
138      * @param operator The content model operator.
139      * @param firstChild The first child index.
140      * @param secondChild The second child index.
141      * @param dtd if it is for a DTDGrammar.
142      *
143      */

144     public SimpleContentModel(short operator, QName firstChild, QName secondChild) {
145         //
146
// Store away the children and operation. This is all we need to
147
// do the content model check.
148
//
149
// The operation is one of the ContentSpecNode.NODE_XXX values!
150
//
151
fFirstChild.setValues(firstChild);
152         if (secondChild != null) {
153             fSecondChild.setValues(secondChild);
154         }
155         else {
156             fSecondChild.clear();
157         }
158         fOperator = operator;
159     }
160
161     //
162
// ContentModelValidator methods
163
//
164

165     /**
166      * Check that the specified content is valid according to this
167      * content model. This method can also be called to do 'what if'
168      * testing of content models just to see if they would be valid.
169      * <p>
170      * A value of -1 in the children array indicates a PCDATA node. All other
171      * indexes will be positive and represent child elements. The count can be
172      * zero, since some elements have the EMPTY content model and that must be
173      * confirmed.
174      *
175      * @param children The children of this element. Each integer is an index within
176      * the <code>StringPool</code> of the child element name. An index
177      * of -1 is used to indicate an occurrence of non-whitespace character
178      * data.
179      * @param offset Offset into the array where the children starts.
180      * @param length The number of entries in the <code>children</code> array.
181      *
182      * @return The value -1 if fully valid, else the 0 based index of the child
183      * that first failed. If the value returned is equal to the number
184      * of children, then the specified children are valid but additional
185      * content is required to reach a valid ending state.
186      *
187      */

188     public int validate(QName[] children, int offset, int length) {
189
190         //
191
// According to the type of operation, we do the correct type of
192
// content check.
193
//
194
switch(fOperator)
195         {
196             case XMLContentSpec.CONTENTSPECNODE_LEAF :
197                 // If there is not a child, then report an error at index 0
198
if (length == 0)
199                     return 0;
200
201                 // If the 0th child is not the right kind, report an error at 0
202
if (children[offset].rawname != fFirstChild.rawname) {
203                     return 0;
204                 }
205
206                 // If more than one child, report an error at index 1
207
if (length > 1)
208                     return 1;
209                 break;
210
211             case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE :
212                 //
213
// If there is one child, make sure its the right type. If not,
214
// then its an error at index 0.
215
//
216
if (length == 1) {
217                     if (children[offset].rawname != fFirstChild.rawname) {
218                         return 0;
219                     }
220                 }
221
222                 //
223
// If the child count is greater than one, then obviously
224
// bad, so report an error at index 1.
225
//
226
if (length > 1)
227                     return 1;
228                 break;
229
230             case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE :
231                 //
232
// If the child count is zero, that's fine. If its more than
233
// zero, then make sure that all children are of the element
234
// type that we stored. If not, report the index of the first
235
// failed one.
236
//
237
if (length > 0)
238                 {
239                     for (int index = 0; index < length; index++) {
240                         if (children[offset + index].rawname != fFirstChild.rawname) {
241                             return index;
242                         }
243                     }
244                 }
245                 break;
246
247             case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE :
248                 //
249
// If the child count is zero, that's an error so report
250
// an error at index 0.
251
//
252
if (length == 0)
253                     return 0;
254
255                 //
256
// Otherwise we have to check them all to make sure that they
257
// are of the correct child type. If not, then report the index
258
// of the first one that is not.
259
//
260
for (int index = 0; index < length; index++) {
261                     if (children[offset + index].rawname != fFirstChild.rawname) {
262                         return index;
263                     }
264                 }
265                 break;
266
267             case XMLContentSpec.CONTENTSPECNODE_CHOICE :
268                 //
269
// There must be one and only one child, so if the element count
270
// is zero, return an error at index 0.
271
//
272
if (length == 0)
273                     return 0;
274
275                 // If the zeroth element isn't one of our choices, error at 0
276
if ((children[offset].rawname != fFirstChild.rawname) &&
277                     (children[offset].rawname != fSecondChild.rawname)) {
278                     return 0;
279                 }
280
281                 // If there is more than one element, then an error at 1
282
if (length > 1)
283                     return 1;
284                 break;
285
286             case XMLContentSpec.CONTENTSPECNODE_SEQ :
287                 //
288
// There must be two children and they must be the two values
289
// we stored, in the stored order.
290
//
291
if (length == 2) {
292                     if (children[offset].rawname != fFirstChild.rawname) {
293                         return 0;
294                     }
295                     if (children[offset + 1].rawname != fSecondChild.rawname) {
296                         return 1;
297                     }
298                 }
299                 else {
300                     if (length > 2) {
301                         return 2;
302                     }
303
304                     return length;
305                 }
306
307                 break;
308
309             default :
310                 throw new RuntimeException JavaDoc("ImplementationMessages.VAL_CST");
311         }
312
313         // We survived, so return success status
314
return -1;
315     } // validate
316

317 } // class SimpleContentModel
318
Popular Tags