KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > schema > validation > SequenceContentIterator


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.schema.validation;
24
25 import java.util.Iterator JavaDoc;
26
27 import org.xquark.schema.*;
28
29 public class SequenceContentIterator extends ContentIterator {
30 private static final String JavaDoc RCSRevision = "$Revision: 1.1 $";
31 private static final String JavaDoc RCSName = "$Name: $";
32
33   private SequenceModelGroup group;
34   private Iterator JavaDoc groupIterator;
35   private Particle currentParticle = null;
36   private int count = 0;
37   private ContentIterator iterator = null;
38   
39   public SequenceContentIterator(Particle particle)
40   {
41     super(particle);
42     group = (SequenceModelGroup)particle.getTerm();
43     groupIterator = group.iterator();
44   }
45
46   public ElementDeclaration getMatchedDeclaration() {
47     if (iterator != null)
48       return iterator.getMatchedDeclaration();
49     else return null;
50   }
51
52   public ElementDeclaration getModelDeclaration() {
53     if (iterator != null)
54       return iterator.getModelDeclaration();
55     else return null;
56   }
57
58   public int getProcessContents() {
59     if (iterator != null)
60       return iterator.getProcessContents();
61     else return LAX;
62   }
63   
64   private ContentIterator selectContentIterator(String JavaDoc namespace, String JavaDoc localName)
65   {
66     // nTested is used in case all particles are optional,
67
// as this could lead to an infinite loop
68
int nTested = 0;
69     while (nTested < group.size()) {
70       if (groupIterator.hasNext()) {
71     Particle particle = (Particle)groupIterator.next();
72     // first, check if local is directly found in particle
73
if (particle.hasNextElement(namespace, localName)) {
74       if (currentParticle == null && count < maxOccurs && reporter != null) {
75         reporter.startGroup(parentParticle, ModelGroup.SEQUENCE, count);
76           }
77       currentParticle = particle;
78           return ContentIteratorFactory.createIterator(currentParticle, reporter);
79     }
80     else if (particle.getMinExtent() > 0) {
81       return null;
82     }
83         
84         // it's necessary to test if the parentParticle has this element
85
// if not, too many particle will be skiped
86
// noted 22, nov 2001
87
else if ( reporter != null && parentParticle.hasNextElement(namespace, localName) ) {
88       reporter.skipped(particle);
89     }
90     nTested++;
91       }
92       else {
93     if (reporter != null)
94       reporter.endGroup(parentParticle, ModelGroup.SEQUENCE);
95     currentParticle = null;
96     count++;
97     groupIterator = group.iterator();
98       }
99     }
100     return null;
101   }
102   
103   protected int nextElement(String JavaDoc namespace, String JavaDoc localName)
104   {
105     // On-going iterator
106
java.util.ArrayList JavaDoc previousExceptions = null;
107     if (iterator != null) {
108       switch (iterator.nextElement(namespace, localName)) {
109       case MATCHED:
110     return MATCHED;
111       case UNKNOWN:
112         return UNKNOWN;
113       case INVALID:
114     if (iterator.getMatchedDeclaration() != null)
115       return invalidElement(iterator.getExceptions());
116     else
117       return invalidElement("cvc-particle.3.3", parentParticle, iterator.getExceptions());
118       case TOO_MANY:
119         previousExceptions = iterator.getExceptions();
120     // try next particle
121
case DONE:
122     // try next particle
123
}
124     }
125
126     iterator = selectContentIterator(namespace, localName);
127     if (iterator == null) {
128       if (previousExceptions != null) {
129     // Previous iterator had too many occurrences, and no new iterator matched
130
// Report previous error
131
return invalidElement("cvc-particle.3.3", parentParticle, previousExceptions);
132       } else if (count == 0 && currentParticle == null && parentParticle.getMinExtent() > 0) {
133     SchemaException se = SchemaException.computeMinExtentException(parentParticle);
134     return invalidElement(se);
135       } else {
136     // Iterator is finished
137
return stopProcessing();
138       }
139     }
140     if (count >= maxOccurs) {
141       if (previousExceptions != null)
142     invalidElement("cvc-particle.3.2", parentParticle, previousExceptions);
143       else
144     invalidElement("cvc-particle.3.2", parentParticle);
145       return TOO_MANY;
146     }
147     switch (iterator.nextElement(namespace, localName)) {
148     case MATCHED:
149       return MATCHED;
150     case UNKNOWN:
151       return UNKNOWN;
152     case INVALID:
153     case TOO_MANY:
154     case DONE:
155     default:
156       if (iterator.getMatchedDeclaration() != null)
157     return invalidElement(iterator.getExceptions());
158       else
159     return invalidElement("cvc-particle.3.3", parentParticle, iterator.getExceptions());
160     }
161   }
162
163   public int stopProcessing() {
164     // Stop current iterator
165
if (iterator != null) {
166       switch (iterator.stopProcessing()) {
167       case INVALID:
168     return invalidElement("cvc-particle.3.3", parentParticle, iterator.getExceptions());
169       case DONE:
170     // Current iterator can be stopped. Continue
171
}
172     }
173     int c;
174     if (currentParticle == null) {
175       // at beginning of sequence
176
c = count;
177     } else {
178       // Can skip the rest of the group (all elements at the end are optional)
179
Iterator JavaDoc it = group.iterator();
180       // Move to current position in the group
181
while (it.hasNext() && it.next() != currentParticle);
182       while (it.hasNext()) {
183     Particle particle = (Particle)it.next();
184     // One particle at least is not optional
185
if (particle.getMinExtent() > 0) {
186       SchemaException se = SchemaException.computeMinExtentException(particle);
187       return invalidElement("cvc-particle.3.3", parentParticle, se);
188     } else if (reporter != null) {
189       reporter.skipped(particle);
190     }
191       }
192       // end of group reached
193
if (reporter != null)
194     reporter.endGroup(parentParticle, ModelGroup.SEQUENCE);
195       // increment the current count
196
c = count+1;
197     }
198     if (c < minOccurs && parentParticle.getMinExtent() != 0) {
199       return invalidElement("cvc-particle.3.1", parentParticle);
200     } else if (reporter != null && c < maxOccurs) {
201       // it's better to skip the parentParticle than the children
202
// noted 22, Nov 2001
203
reporter.skipped(parentParticle);
204     }
205     return DONE;
206   }
207  
208   protected boolean nextValidElements(java.util.List JavaDoc elements) {
209     // Iterator in use
210
if (iterator != null) {
211       boolean canStop = iterator.nextValidElements(elements);
212       // If current iterator cannot be terminated immediately
213
// return false
214
if (!canStop) return false;
215     }
216     int c;
217     if (currentParticle == null) {
218       // at beginning of sequence
219
c = count;
220     } else {
221       // else look for other possible elements in the rest of the group
222
Iterator JavaDoc it = group.iterator();
223       while (it.hasNext() && it.next() != currentParticle);
224       while (it.hasNext()) {
225     Particle particle = (Particle)it.next();
226     if (elements != null) elements.addAll(particle.firstValidElements());
227     // Particle is not optional
228
if (particle.getMinExtent() > 0) return false;
229       }
230       c = count+1;
231     }
232     // If all previous elements are optional and loop is possible,
233
// restart from the beginning of the group
234
if (c < maxOccurs && elements != null) {
235       Iterator JavaDoc it = group.iterator();
236       while (it.hasNext()) {
237     Particle particle = (Particle)it.next();
238     elements.addAll(particle.firstValidElements());
239     if (particle == currentParticle || particle.getMinExtent() > 0)
240       break;
241       }
242     }
243     if (c >= minOccurs || parentParticle.getMinExtent() == 0) return true;
244     else return false;
245   }
246 }
247
Popular Tags