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