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 package org.exolab.castor.xml.schema.reader;
37
38 import org.exolab.castor.xml.AttributeSet;
39 import org.exolab.castor.xml.Namespaces;
40 import org.exolab.castor.xml.XMLException;
41 import org.exolab.castor.xml.schema.Annotation;
42 import org.exolab.castor.xml.schema.AttributeDecl;
43 import org.exolab.castor.xml.schema.AttributeGroupReference;
44 import org.exolab.castor.xml.schema.ComplexType;
45 import org.exolab.castor.xml.schema.ContentType;
46 import org.exolab.castor.xml.schema.ElementDecl;
47 import org.exolab.castor.xml.schema.SchemaContext;
48 import org.exolab.castor.xml.schema.Group;
49 import org.exolab.castor.xml.schema.ModelGroup;
50 import org.exolab.castor.xml.schema.Schema;
51 import org.exolab.castor.xml.schema.SchemaException;
52 import org.exolab.castor.xml.schema.SchemaNames;
53 import org.exolab.castor.xml.schema.Wildcard;
54 import org.exolab.castor.xml.schema.XMLType;
55
56
57
58
59
60
61
62 public class ComplexTypeUnmarshaller extends ComponentReader {
63
64
65
66
67 private static final String VALUE_0 = "0";
68
69
70
71
72 private static final String VALUE_1 = "1";
73
74
75
76
77 private static final String VALUE_FALSE = "false";
78
79
80
81
82 private static final String VALUE_TRUE = "true";
83
84
85
86
87 private static final String KEYWORD_RESTRICTIONS = "restrictions";
88
89
90
91
92 private static final String KEYWORD_EXTENSION = "extension";
93
94
95
96
97 private static final String KEYWORD_DERIVED_BY = "derivedBy";
98
99
100
101
102 private ComponentReader unmarshaller;
103
104
105
106
107 private int depth = 0;
108
109
110
111
112 private ComplexType _complexType = null;
113 private boolean allowAnnotation = true;
114 private boolean foundAnnotation = false;
115 private boolean foundAnyAttribute = false;
116 private boolean foundAttributes = false;
117 private boolean foundSimpleContent = false;
118 private boolean foundComplexContent = false;
119 private boolean foundModelGroup = false;
120
121 private Schema _schema = null;
122
123
124
125
126
127
128
129
130
131 public ComplexTypeUnmarshaller(final SchemaContext schemaContext, final Schema schema,
132 final AttributeSet atts) throws XMLException {
133 super(schemaContext);
134
135 this._schema = schema;
136
137 _complexType = schema.createComplexType();
138
139 _complexType.useResolver(getResolver());
140
141
142 String attValue = null;
143
144
145 _complexType.setName(atts.getValue(SchemaNames.NAME_ATTR));
146
147
148 String content = atts.getValue(SchemaNames.MIXED);
149 if (content != null) {
150 if (isTurnedOn(content)) {
151 _complexType.setContentType(ContentType.mixed);
152 }
153 if (isTurnedOff(content)) {
154 _complexType.setContentType(ContentType.elemOnly);
155 }
156 }
157
158
159 String base = atts.getValue(SchemaNames.BASE_ATTR);
160 if ((base != null) && (base.length() > 0)) {
161
162 String derivedBy = atts.getValue(KEYWORD_DERIVED_BY);
163 _complexType.setDerivationMethod(derivedBy);
164 if ((derivedBy == null) || (derivedBy.length() == 0)
165 || (derivedBy.equals(KEYWORD_EXTENSION))) {
166 XMLType baseType = schema.getType(base);
167 if (baseType == null)
168 _complexType.setBase(base);
169 else
170 _complexType.setBaseType(baseType);
171 } else if (derivedBy.equals(KEYWORD_RESTRICTIONS)) {
172 String err = "restrictions not yet supported for <type>.";
173 throw new SchemaException(err);
174 } else {
175 String err = "invalid value for derivedBy attribute of ";
176 err += "<type>: " + derivedBy;
177 throw new SchemaException(err);
178 }
179
180 }
181
182
183 attValue = atts.getValue(SchemaNames.ABSTRACT);
184 if (attValue != null) {
185 Boolean bool = Boolean.valueOf(attValue);
186 _complexType.setAbstract(bool.booleanValue());
187 }
188
189
190 _complexType.setBlock(atts.getValue(SchemaNames.BLOCK_ATTR));
191
192
193 _complexType.setFinal(atts.getValue(SchemaNames.FINAL_ATTR));
194
195
196 _complexType.setId(atts.getValue(SchemaNames.ID_ATTR));
197
198 }
199
200
201
202
203
204
205
206 private boolean isTurnedOff(String content) {
207 return content.equals(VALUE_FALSE) || content.equals(VALUE_0);
208 }
209
210
211
212
213
214
215
216 private boolean isTurnedOn(String property) {
217 return property.equals(VALUE_TRUE) || property.equals(VALUE_1);
218 }
219
220
221
222
223
224
225
226
227
228
229 public String elementName() {
230 return SchemaNames.COMPLEX_TYPE;
231 }
232
233
234
235
236 public ComplexType getComplexType() {
237 return _complexType;
238 }
239
240
241
242
243
244
245 public Object getObject() {
246 return getComplexType();
247 }
248
249
250
251
252
253
254
255
256
257
258
259 public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
260 throws XMLException {
261
262 if (unmarshaller != null) {
263 unmarshaller.startElement(name, namespace, atts, nsDecls);
264 ++depth;
265 return;
266 }
267
268
269 if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
270 if (foundComplexContent)
271 error("an anyAttribute element cannot appear as a child "
272 + "of 'complexType' if 'complexContent' also exists");
273 if (foundSimpleContent)
274 error("an anyAttribute element cannot appear as a child "
275 + "of 'complexType' if 'simpleContent' also exists");
276 foundAnyAttribute = true;
277 allowAnnotation = true;
278 unmarshaller =
279 new WildcardUnmarshaller(getSchemaContext(), _complexType, _schema, name, atts);
280 }
281
282
283 else if (SchemaNames.ATTRIBUTE.equals(name)) {
284 if (foundComplexContent)
285 error("an attribute definition cannot appear as a child "
286 + "of 'complexType' if 'complexContent' also exists");
287 if (foundSimpleContent)
288 error("an 'attribute' definition cannot appear as a child "
289 + "of 'complexType' if 'simpleContent' also exists");
290 if (foundAnyAttribute)
291 error("an attribute definition cannot appear after "
292 + "the definition of an 'anyAttribute' element");
293 foundAttributes = true;
294 allowAnnotation = false;
295 unmarshaller = new AttributeUnmarshaller(getSchemaContext(), _schema, atts);
296 }
297
298 else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
299
300
301
302 if (atts.getValue(SchemaNames.REF_ATTR) == null) {
303 error("A 'complexType' may contain referring " + "attributeGroups, but not defining ones.");
304 }
305 if (foundComplexContent)
306 error("an attributeGroup reference cannot appear as a child "
307 + "of 'complexType' if 'complexContent' also exists");
308 if (foundSimpleContent)
309 error("an attributeGroup reference cannot appear as a child "
310 + "of 'complexType' if 'simpleContent' also exists");
311 if (foundAnyAttribute)
312 error("an 'attributeGroup' reference cannot appear after "
313 + "the definition of an 'anyAttribute' element");
314
315 foundAttributes = true;
316 allowAnnotation = false;
317 unmarshaller = new AttributeGroupUnmarshaller(getSchemaContext(), _schema, atts);
318 }
319
320 else if (SchemaNames.SIMPLE_CONTENT.equals(name)) {
321
322 if (foundAttributes)
323 error("'simpleContent' and attribute definitions cannot both "
324 + "appear as children of 'complexType' at the same time.");
325 if (foundComplexContent)
326 error("'simpleContent' and 'complexContent' cannot both "
327 + "appear as children of 'complexType'.");
328 if (foundSimpleContent)
329 error("Only one (1) 'simpleContent' may appear as a child of " + "'complexType'.");
330 if (foundModelGroup)
331 error("'simpleContent' cannot appear as a child of "
332 + "'complexType' if 'all', 'sequence', 'choice' or " + "'group' also exist");
333
334 foundSimpleContent = true;
335 allowAnnotation = false;
336 _complexType.setSimpleContent(true);
337 unmarshaller = new SimpleContentUnmarshaller(getSchemaContext(), _complexType, atts);
338 }
339
340 else if (SchemaNames.COMPLEX_CONTENT.equals(name)) {
341
342 if (foundAttributes)
343 error("'complexContent' and attribute definitions cannot both "
344 + "appear as children of 'complexType' at the same time.");
345 if (foundSimpleContent)
346 error("'simpleContent' and 'complexContent' cannot both "
347 + "appear as children of 'complexType'.");
348 if (foundComplexContent)
349 error("Only one (1) 'complexContent' may appear as a child of " + "'complexType'.");
350 if (foundModelGroup)
351 error("'complexContent' cannot appear as a child of "
352 + "'complexType' if 'all', 'sequence', 'choice' or " + "'group' also exist");
353
354 foundComplexContent = true;
355 allowAnnotation = false;
356
357 _complexType.setComplexContent(true);
358 unmarshaller = new ComplexContentUnmarshaller(getSchemaContext(), _complexType, atts);
359 }
360
361 else if (name.equals(SchemaNames.GROUP)) {
362 if (foundAttributes)
363 error("'" + name + "' must appear before any attribute "
364 + "definitions when a child of 'complexType'.");
365 if (foundComplexContent)
366 error("'" + name + "' and 'complexContent' cannot both "
367 + "appear as children of 'complexType'.");
368 if (foundSimpleContent)
369 error("'" + name + "' and 'simpleContent' cannot both "
370 + "appear as children of 'complexType'.");
371 if (foundModelGroup)
372 error("'" + name + "' cannot appear as a child of 'complexType' "
373 + "if another 'all', 'sequence', 'choice' or " + "'group' also exists.");
374
375 foundModelGroup = true;
376 allowAnnotation = false;
377 unmarshaller = new ModelGroupUnmarshaller(getSchemaContext(), _schema, atts);
378 }
379
380 else if ((SchemaNames.isGroupName(name)) && (name != SchemaNames.GROUP)) {
381
382 if (foundAttributes)
383 error("'" + name + "' must appear before any attribute "
384 + "definitions when a child of 'complexType'.");
385 if (foundComplexContent)
386 error("'" + name + "' and 'complexContent' cannot both "
387 + "appear as children of 'complexType'.");
388 if (foundSimpleContent)
389 error("'" + name + "' and 'simpleContent' cannot both "
390 + "appear as children of 'complexType'.");
391 if (foundModelGroup)
392 error("'" + name + "' cannot appear as a child of 'complexType' "
393 + "if another 'all', 'sequence', 'choice' or " + "'group' also exists.");
394
395 foundModelGroup = true;
396 allowAnnotation = false;
397 unmarshaller = new GroupUnmarshaller(getSchemaContext(), _schema, name, atts);
398 } else if (name.equals(SchemaNames.ANNOTATION)) {
399 if (allowAnnotation) {
400 unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
401 allowAnnotation = false;
402 foundAnnotation = true;
403 } else {
404 if (foundAnnotation) {
405 error("Only one (1) annotation may appear as a child of " + "'complexType' elements");
406 }
407 error("An annotation must appear as the first child of " + "'complexType' elements.");
408 }
409 } else
410 illegalElement(name);
411
412 }
413
414
415
416
417
418
419
420
421 public void endElement(String name, String namespace) throws XMLException {
422
423
424 if ((unmarshaller != null) && (depth > 0)) {
425 unmarshaller.endElement(name, namespace);
426 --depth;
427 return;
428 }
429
430 unmarshaller.finish();
431
432
433 if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
434 Wildcard wildcard = ((WildcardUnmarshaller) unmarshaller).getWildcard();
435 try {
436 _complexType.setAnyAttribute(wildcard);
437 } catch (SchemaException e) {
438 throw new IllegalArgumentException(e.getMessage());
439 }
440 }
441
442 if (SchemaNames.ATTRIBUTE.equals(name)) {
443 AttributeDecl attrDecl = ((AttributeUnmarshaller) unmarshaller).getAttribute();
444
445 _complexType.addAttributeDecl(attrDecl);
446 }
447
448 else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
449 AttributeGroupReference attrGroupRef = (AttributeGroupReference) unmarshaller.getObject();
450 _complexType.addAttributeGroupReference(attrGroupRef);
451 }
452
453 else if (SchemaNames.ELEMENT.equals(name)) {
454
455 ElementDecl element = ((ElementUnmarshaller) unmarshaller).getElement();
456 _complexType.addElementDecl(element);
457 }
458
459 else if (name.equals(SchemaNames.GROUP)) {
460 ModelGroup group = ((ModelGroupUnmarshaller) unmarshaller).getGroup();
461 _complexType.addGroup(group);
462 }
463
464
465 else if ((SchemaNames.isGroupName(name)) && (name != SchemaNames.GROUP)) {
466 Group group = ((GroupUnmarshaller) unmarshaller).getGroup();
467 _complexType.addGroup(group);
468 }
469
470 else if (SchemaNames.ANNOTATION.equals(name)) {
471 Annotation ann = ((AnnotationUnmarshaller) unmarshaller).getAnnotation();
472 _complexType.addAnnotation(ann);
473 }
474
475 unmarshaller = null;
476 }
477
478 public void characters(char[] ch, int start, int length) throws XMLException {
479
480 if (unmarshaller != null) {
481 unmarshaller.characters(ch, start, length);
482 }
483 }
484
485 }