1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.exolab.castor.xml.schema.reader;
47
48
49 import org.exolab.castor.xml.AttributeSet;
50 import org.exolab.castor.xml.Namespaces;
51 import org.exolab.castor.xml.XMLException;
52 import org.exolab.castor.xml.schema.Annotation;
53 import org.exolab.castor.xml.schema.ElementDecl;
54 import org.exolab.castor.xml.schema.Group;
55 import org.exolab.castor.xml.schema.ModelGroup;
56 import org.exolab.castor.xml.schema.Order;
57 import org.exolab.castor.xml.schema.Schema;
58 import org.exolab.castor.xml.schema.SchemaContext;
59 import org.exolab.castor.xml.schema.SchemaException;
60 import org.exolab.castor.xml.schema.SchemaNames;
61 import org.exolab.castor.xml.schema.Wildcard;
62
63
64
65
66
67
68 public class GroupUnmarshaller extends ComponentReader {
69
70
71
72
73
74
75
76
77 private static final String MAX_OCCURS_WILDCARD = "unbounded";
78
79
80
81
82
83
84
85
86 private ComponentReader unmarshaller;
87
88
89
90
91 private int depth = 0;
92
93
94
95
96 private Group _group = null;
97
98
99
100
101 private Schema _schema = null;
102
103
104
105
106 private String _element = SchemaNames.SEQUENCE;
107
108 private boolean foundAll = false;
109 private boolean foundElement = false;
110 private boolean foundGroup = false;
111 private boolean foundModelGroup = false;
112 private boolean foundAnnotation = false;
113
114
115
116
117
118
119
120
121
122
123
124
125 public GroupUnmarshaller(
126 final SchemaContext schemaContext,
127 final Schema schema,
128 final String element,
129 final AttributeSet atts) {
130 super(schemaContext);
131
132 this._schema = schema;
133
134 _group = new Group();
135
136 String attValue = null;
137
138
139 if (SchemaNames.SEQUENCE.equals(element)) {
140 _group.setOrder(Order.sequence);
141 }
142 else if (SchemaNames.CHOICE.equals(element)) {
143 _group.setOrder(Order.choice);
144 }
145 else if (SchemaNames.ALL.equals(element)) {
146 foundAll = true;
147 _group.setOrder(Order.all);
148 }
149 else {
150 String err = "Invalid group element name: '" +
151 element + "'";
152 throw new IllegalArgumentException(err);
153 }
154
155
156 _element = element;
157
158
159 attValue = atts.getValue(SchemaNames.NAME_ATTR);
160 if (attValue != null) {
161 _group.setName(attValue);
162 }
163
164
165
166
167
168
169
170 attValue = atts.getValue(SchemaNames.MAX_OCCURS_ATTR);
171
172 if (attValue != null) {
173 if (MAX_OCCURS_WILDCARD.equals(attValue))
174 _group.setMaxOccurs(-1);
175 else
176 _group.setMaxOccurs(toInt(attValue));
177 }
178
179 attValue = atts.getValue("minOccurs");
180 if (attValue != null)
181 _group.setMinOccurs(toInt(attValue));
182
183 if (_group.getOrder() == Order.all) {
184 if (_group.getMaxOccurs() != 1) {
185 String err = "Wrong maxOccurs value for a <all>:"+_group.getMaxOccurs();
186 err += "\n1 is the only possible value.";
187 throw new IllegalArgumentException(err);
188 }
189 if (_group.getMinOccurs() > 1) {
190 String err = "Wrong minOccurs value for a <all>:"+_group.getMinOccurs();
191 err += "\n0 or 1 are the only possible values.";
192 throw new IllegalArgumentException(err);
193 }
194 }
195
196 _group.setId(atts.getValue("id"));
197
198 }
199
200
201
202
203
204
205
206
207
208
209
210 public String elementName() {
211 return _element;
212 }
213
214
215
216
217
218
219
220
221
222 public Group getGroup() {
223 return _group;
224 }
225
226
227
228
229
230 public Object getObject() {
231 return getGroup();
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247 public void startElement(String name, String namespace, AttributeSet atts,
248 Namespaces nsDecls)
249 throws XMLException
250 {
251
252 if (unmarshaller != null) {
253 unmarshaller.startElement(name, namespace, atts, nsDecls);
254 ++depth;
255 return;
256 }
257
258 if (SchemaNames.ANNOTATION.equals(name)) {
259 if (foundElement || foundGroup ||foundModelGroup)
260 error("An annotation may only appear as the first child "+
261 "of an element definition.");
262
263
264 if (foundAnnotation)
265 error("Only one (1) 'annotation' is allowed as a child of "+
266 "element definitions.");
267
268 foundAnnotation = true;
269 unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
270 }
271 else if (SchemaNames.ELEMENT.equals(name)) {
272 foundElement = true;
273 unmarshaller
274 = new ElementUnmarshaller(getSchemaContext(), _schema, atts);
275 }
276
277 else if (name.equals(SchemaNames.GROUP))
278 {
279 foundModelGroup = true;
280 unmarshaller
281 = new ModelGroupUnmarshaller(getSchemaContext(), _schema, atts);
282 }
283
284
285 else if ( (SchemaNames.isGroupName(name)) && (name != SchemaNames.GROUP) )
286 {
287 foundGroup = true;
288 if (SchemaNames.ALL.equals(name))
289 foundAll = true;
290 unmarshaller
291 = new GroupUnmarshaller(getSchemaContext(), _schema, name, atts);
292 }
293
294 else if (SchemaNames.ANY.equals(name)) {
295 if (foundAll)
296 error("<any> can not appear as a child of a <all> element");
297 unmarshaller
298 = new WildcardUnmarshaller(getSchemaContext(), _group, _schema, name, atts);
299 }
300
301 else {
302 StringBuffer err = new StringBuffer("illegal element <");
303 err.append(name);
304 err.append("> found in <group>.");
305 throw new SchemaException(err.toString());
306 }
307
308 }
309
310
311
312
313
314
315
316
317 public void endElement(String name, String namespace)
318 throws XMLException
319 {
320
321
322 if ((unmarshaller != null) && (depth > 0)) {
323 unmarshaller.endElement(name, namespace);
324 --depth;
325 return;
326 }
327
328 if (unmarshaller != null) {
329 if (!name.equals(unmarshaller.elementName())) {
330 String err = "missing end element for ";
331 err += unmarshaller.elementName();
332 throw new SchemaException(err);
333 }
334 }
335
336
337 unmarshaller.finish();
338
339
340 if (SchemaNames.ANY.equals(name)) {
341 Wildcard wildcard =
342 ((WildcardUnmarshaller)unmarshaller).getWildcard();
343 try {
344 _group.addWildcard(wildcard);
345 } catch (SchemaException e) {
346 throw new IllegalArgumentException(e.getMessage());
347 }
348 }
349 if (SchemaNames.ANNOTATION.equals(name)) {
350 Annotation ann = (Annotation)unmarshaller.getObject();
351 _group.addAnnotation(ann);
352 }
353 else if (SchemaNames.ELEMENT.equals(name)) {
354 ElementDecl element = (ElementDecl) unmarshaller.getObject();
355 _group.addElementDecl(element);
356 }
357 else if (name.equals(SchemaNames.GROUP)) {
358 ModelGroup group = (ModelGroup) unmarshaller.getObject();
359 _group.addGroup(group);
360 }
361 else if ( (SchemaNames.isGroupName(name)) && (name != SchemaNames.GROUP) )
362 {
363 Group group = ((GroupUnmarshaller)unmarshaller).getGroup();
364 _group.addGroup(group);
365 }
366
367 unmarshaller = null;
368 }
369
370 public void characters(char[] ch, int start, int length)
371 throws XMLException
372 {
373
374 if (unmarshaller != null) {
375 unmarshaller.characters(ch, start, length);
376 }
377 }
378
379 }