KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.xquark.schema.*;
26
27 public class ElementTreeContentIterator extends ContentIterator {
28     private static final String JavaDoc RCSRevision = "$Revision: 1.2 $";
29     private static final String JavaDoc RCSName = "$Name: $";
30     private java.util.LinkedList JavaDoc iterators = new java.util.LinkedList JavaDoc();
31     private ContentIterator iterator;
32     private ElementDeclaration matchedDecl = null;
33     private SchemaManager manager;
34
35     public ElementTreeContentIterator(SchemaManager manager) {
36         this(manager, false);
37     }
38
39     public ElementTreeContentIterator(SchemaManager manager, boolean strict) {
40         this.manager = manager;
41         this.iterator = new DefaultContentIterator(manager, strict ? STRICT : LAX);
42     }
43
44     public ElementTreeContentIterator(ComplexType type) {
45         this.manager = type.getManager();
46         DefaultContentIterator dummy = new DefaultContentIterator(manager);
47         dummy.setType(type);
48         iterators.addFirst(dummy);
49         this.iterator = type.childIterator();
50     }
51
52     public ElementDeclaration getMatchedDeclaration() {
53         return matchedDecl;
54     }
55
56     public ElementDeclaration getModelDeclaration() {
57         if (iterator != null)
58             return iterator.getModelDeclaration();
59         else
60             return null;
61     }
62
63     public int getProcessContents() {
64         return iterator.getProcessContents();
65     }
66
67     public void startElement(String JavaDoc namespace, String JavaDoc localName, Type localType, boolean localTypePresent)
68         throws SchemaException {
69         if (done)
70             illegalState("Iterator terminated for element {" + namespace + "}" + localName);
71
72         if (endRequired) {
73             if (currentType.isSimpleType())
74                 invalidElement("cvc-type.3.1.2", currentType);
75             else if (currentType.getContentType() == EMPTY)
76                 invalidElement("cvc-complex-type.2.1", currentType);
77             else if (currentType.getContentType() == TEXT_ONLY)
78                 invalidElement("cvc-complex-type.2.2", currentType);
79             else
80                 invalidElement("cvc-complex-type.2.4", currentType);
81             endRequired = false;
82             iterators.addFirst(iterator);
83             iterator = new DefaultContentIterator(manager);
84         }
85         Type parentType = null;
86         currentType = null;
87         switch (iterator.nextElement(namespace, localName)) {
88             case MATCHED :
89                 matchedDecl = iterator.getMatchedDeclaration();
90                 currentType = checkDeclarationAndType(localType, localTypePresent);
91                 if (currentType != null) {
92                     // This is used to retrieve the parent type when an iterator must be replaced by a default one
93
iterator.setType(currentType);
94                     ContentIterator nextIterator = currentType.childIterator();
95                     if (nextIterator != null) {
96                         endRequired = false;
97                         iterators.addFirst(iterator);
98                         iterator = nextIterator;
99                     } else {
100                         endRequired = true;
101                     }
102                     checkPendingExceptions();
103                     return;
104                 } else {
105                     endRequired = false;
106                     iterators.addFirst(iterator);
107                     iterator = new DefaultContentIterator(manager);
108                     checkPendingExceptions();
109                     return;
110                 }
111             case UNKNOWN :
112                 // used in default and wildcard iterator when no declaration is found
113
matchedDecl = null;
114                 currentType = checkDeclarationAndType(localType, localTypePresent);
115                 if (currentType != null) {
116                     // This is used to retrieve the parent type when an iterator must be replaced by a default one
117
iterator.setType(currentType);
118                     ContentIterator nextIterator = currentType.childIterator();
119                     if (nextIterator != null) {
120                         endRequired = false;
121                         iterators.addFirst(iterator);
122                         iterator = nextIterator;
123                     } else {
124                         endRequired = true;
125                     }
126                     checkPendingExceptions();
127                     return;
128                 } else {
129                     endRequired = false;
130                     iterators.addFirst(iterator);
131                     iterator = new DefaultContentIterator(manager, iterator.getProcessContents());
132                     checkPendingExceptions();
133                     return;
134                 }
135             case INVALID :
136             case TOO_MANY :
137                 if (!iterators.isEmpty())
138                     parentType = ((ContentIterator) iterators.getFirst()).getType();
139                 invalidElement("cvc-complex-type.2.4", parentType, iterator.getExceptions());
140                 break;
141             case DONE :
142                 if (!iterators.isEmpty())
143                     parentType = ((ContentIterator) iterators.getFirst()).getType();
144                 invalidElement(
145                     "cvc-complex-type.2.4",
146                     parentType,
147                     SchemaException.computeException(iterator.getParticle()));
148                 break;
149         }
150
151         if (parentType == null && iterator != null && iterator instanceof DefaultContentIterator)
152             // it's an error, a dead loop
153
invalidElement("cvc-complex-type.2.4", matchedDecl);
154         else {
155             // Replace invalid iterator by default one
156
if (parentType != null)
157                 iterator = new DefaultContentIterator((ComplexType) parentType);
158             else
159                 iterator = new DefaultContentIterator(manager);
160             endRequired = false;
161             // Try again
162
startElement(namespace, localName, localType, localTypePresent);
163         }
164     }
165
166     private void checkPendingExceptions() throws SchemaException {
167         if (!isValid()) {
168             SchemaException exception = new SchemaException(getExceptions());
169             resetExceptions();
170             throw exception;
171         }
172     }
173
174     public void endElement(String JavaDoc namespace, String JavaDoc localName) throws SchemaException {
175         if (done)
176             illegalState("Iterator terminated for element {" + namespace + "}" + localName);
177         else if (!endRequired) {
178             if (iterator.stopProcessing() == INVALID) {
179                 Type parentType = null;
180                 if (!iterators.isEmpty())
181                     parentType = ((ContentIterator) iterators.getFirst()).getType();
182                 invalidElement("cvc-complex-type.2.4", parentType, iterator.getExceptions());
183             }
184             if (iterators.isEmpty()) {
185                 illegalState("Too many endElement statements before element {" + namespace + "}" + localName);
186             } else {
187                 iterator = (ContentIterator) iterators.removeFirst();
188                 if (!iterators.isEmpty()) {
189                     ContentIterator prev = (ContentIterator) iterators.getFirst();
190                     currentType = prev.getType();
191                     matchedDecl = prev.getMatchedDeclaration();
192                 }
193             }
194         }
195         endRequired = false;
196         checkPendingExceptions();
197     }
198
199     public int getMinOccurs() {
200         return iterator.getMinOccurs();
201     }
202
203     public int getMaxOccurs() {
204         return iterator.getMaxOccurs();
205     }
206
207     public Particle getParticle() {
208         return iterator.getParticle();
209     }
210
211     protected int nextElement(String JavaDoc namespace, String JavaDoc localName) {
212         return INVALID;
213     }
214
215     public int stopProcessing() {
216         return INVALID;
217     }
218
219     protected boolean nextValidElements(java.util.List JavaDoc elements) {
220         return iterator.nextValidElements(elements);
221     }
222
223 }
224
Popular Tags