KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > dtd > models > MixedContentModel


1 /*
2  * Copyright 1999-2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.dtd.models;
18
19 import org.apache.xerces.xni.QName;
20
21 import org.apache.xerces.impl.dtd.XMLContentSpec;
22
23 /**
24  * MixedContentModel is a derivative of the abstract content model base
25  * class that handles the special case of mixed model elements. If an element
26  * is mixed model, it has PCDATA as its first possible content, followed
27  * by an alternation of the possible children. The children cannot have any
28  * numeration or order, so it must look like this:
29  * <pre>
30  * &lt;!ELEMENT Foo ((#PCDATA|a|b|c|)*)&gt;
31  * </pre>
32  * So, all we have to do is to keep an array of the possible children and
33  * validate by just looking up each child being validated by looking it up
34  * in the list.
35  *
36  * @xerces.internal
37  *
38  * @version $Id: MixedContentModel.java,v 1.8 2004/10/04 22:00:42 mrglavas Exp $
39  */

40 public class MixedContentModel
41     implements ContentModelValidator {
42
43     //
44
// Data
45
//
46

47     /** The count of possible children that we have to deal with. */
48     private int fCount;
49
50     /** The list of possible children that we have to accept. */
51     private QName fChildren[];
52
53     /** The type of the children to support ANY. */
54     private int fChildrenType[];
55
56     /* this is the EquivClassComparator object */
57     //private EquivClassComparator comparator = null;
58

59     /**
60      * True if mixed content model is ordered. DTD mixed content models
61      * are <em>always</em> unordered.
62      */

63     private boolean fOrdered;
64
65     //
66
// Constructors
67
//
68

69     /**
70      * Constructs a mixed content model.
71      *
72      * @param children The list of allowed children.
73      * @param type The list of the types of the children.
74      * @param offset The start offset position in the children.
75      * @param length The child count.
76      * @param ordered True if content must be ordered.
77      */

78     public MixedContentModel(QName[] children, int[] type, int offset, int length , boolean ordered) {
79         // Make our own copy now, which is exactly the right size
80
fCount = length;
81         fChildren = new QName[fCount];
82         fChildrenType = new int[fCount];
83         for (int i = 0; i < fCount; i++) {
84             fChildren[i] = new QName(children[offset + i]);
85             fChildrenType[i] = type[offset + i];
86         }
87         fOrdered = ordered;
88
89     }
90
91     //
92
// ContentModelValidator methods
93
//
94

95     
96     /**
97      * Check that the specified content is valid according to this
98      * content model. This method can also be called to do 'what if'
99      * testing of content models just to see if they would be valid.
100      * <p>
101      * A value of -1 in the children array indicates a PCDATA node. All other
102      * indexes will be positive and represent child elements. The count can be
103      * zero, since some elements have the EMPTY content model and that must be
104      * confirmed.
105      *
106      * @param children The children of this element. Each integer is an index within
107      * the <code>StringPool</code> of the child element name. An index
108      * of -1 is used to indicate an occurrence of non-whitespace character
109      * data.
110      * @param offset Offset into the array where the children starts.
111      * @param length The number of entries in the <code>children</code> array.
112      *
113      * @return The value -1 if fully valid, else the 0 based index of the child
114      * that first failed. If the value returned is equal to the number
115      * of children, then the specified children are valid but additional
116      * content is required to reach a valid ending state.
117      *
118      */

119     public int validate(QName[] children, int offset, int length) {
120         
121         // must match order
122
if (fOrdered) {
123             int inIndex = 0;
124             for (int outIndex = 0; outIndex < length; outIndex++) {
125
126                 // ignore mixed text
127
final QName curChild = children[offset + outIndex];
128                 if (curChild.localpart == null) {
129                     continue;
130                 }
131
132                 // element must match
133
int type = fChildrenType[inIndex];
134                 if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
135                     if (fChildren[inIndex].rawname != children[offset + outIndex].rawname) {
136                         return outIndex;
137                     }
138                 }
139                 else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
140                     String JavaDoc uri = fChildren[inIndex].uri;
141                     if (uri != null && uri != children[outIndex].uri) {
142                         return outIndex;
143                     }
144                 }
145                 else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
146                     if (children[outIndex].uri != null) {
147                         return outIndex;
148                     }
149                 }
150                 else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
151                     if (fChildren[inIndex].uri == children[outIndex].uri) {
152                         return outIndex;
153                     }
154                 }
155                 
156                 // advance index
157
inIndex++;
158             }
159         }
160
161         // can appear in any order
162
else {
163             for (int outIndex = 0; outIndex < length; outIndex++)
164             {
165                 // Get the current child out of the source index
166
final QName curChild = children[offset + outIndex];
167     
168                 // If its PCDATA, then we just accept that
169
if (curChild.localpart == null)
170                     continue;
171     
172                 // And try to find it in our list
173
int inIndex = 0;
174                 for (; inIndex < fCount; inIndex++)
175                 {
176                     int type = fChildrenType[inIndex];
177                     if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
178                         if (curChild.rawname == fChildren[inIndex].rawname) {
179                             break;
180                         }
181                     }
182                     else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
183                         String JavaDoc uri = fChildren[inIndex].uri;
184                         if (uri == null || uri == children[outIndex].uri) {
185                             break;
186                         }
187                     }
188                     else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
189                         if (children[outIndex].uri == null) {
190                             break;
191                         }
192                     }
193                     else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
194                         if (fChildren[inIndex].uri != children[outIndex].uri) {
195                             break;
196                         }
197                     }
198                     // REVISIT: What about checking for multiple ANY matches?
199
// The content model ambiguity *could* be checked
200
// by the caller before constructing the mixed
201
// content model.
202
}
203
204                 // We did not find this one, so the validation failed
205
if (inIndex == fCount)
206                     return outIndex;
207             }
208         }
209
210         // Everything seems to be in order, so return success
211
return -1;
212     } // validate
213

214 } // class MixedContentModel
215
Popular Tags