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.AttributeGroup;
43 import org.exolab.castor.xml.schema.ComplexType;
44 import org.exolab.castor.xml.schema.SchemaContext;
45 import org.exolab.castor.xml.schema.Group;
46 import org.exolab.castor.xml.schema.Schema;
47 import org.exolab.castor.xml.schema.SchemaException;
48 import org.exolab.castor.xml.schema.SchemaNames;
49 import org.exolab.castor.xml.schema.Wildcard;
50
51 import java.util.StringTokenizer;
52
53
54
55
56
57
58
59 public class WildcardUnmarshaller extends ComponentReader {
60
61
62
63
64
65 private static final String MAX_OCCURS_WILDCARD = "unbounded";
66
67
68
69
70
71
72
73
74
75 private ComponentReader unmarshaller;
76
77
78
79
80 private int depth = 0;
81
82
83
84
85 private Wildcard _wildcard = null;
86
87
88
89 private Schema _schema = null;
90
91
92
93
94 private String _element = SchemaNames.ANY;
95
96
97
98
99
100 public WildcardUnmarshaller(final SchemaContext schemaContext, final ComplexType complexType,
101 final Schema schema, final String element, final AttributeSet atts) {
102 this(schemaContext, schema, element, atts, new Wildcard(complexType));
103 }
104
105 public WildcardUnmarshaller(final SchemaContext schemaContext, final Group group,
106 final Schema schema, final String element, final AttributeSet atts) {
107 this(schemaContext, schema, element, atts, new Wildcard(group));
108 }
109
110 public WildcardUnmarshaller(final SchemaContext schemaContext, final AttributeGroup attGroup,
111 final Schema schema, final String element, final AttributeSet atts) {
112 this(schemaContext, schema, element, atts, new Wildcard(attGroup));
113 }
114
115
116
117
118
119
120
121
122
123
124 private WildcardUnmarshaller(final SchemaContext schemaContext, final Schema schema,
125 final String element, final AttributeSet atts, final Wildcard wildcard) {
126 super(schemaContext);
127 _wildcard = wildcard;
128 this._schema = schema;
129 this._element = element;
130
131
132 String attValue = null;
133
134 if (SchemaNames.ANY_ATTRIBUTE.equals(element))
135 _wildcard.setAttributeWildcard();
136 _element = element;
137
138
139 attValue = atts.getValue(SchemaNames.NAMESPACE);
140
141 if (attValue != null) {
142
143 StringTokenizer tokenizer = new StringTokenizer(attValue);
144 while (tokenizer.hasMoreTokens()) {
145
146 String temp = tokenizer.nextToken();
147
148
149
150 if (tokenizer.countTokens() > 1)
151 if ((SchemaNames.NAMESPACE_ANY.equals(temp))
152 || (SchemaNames.NAMESPACE_OTHER.equals(temp)))
153 throw new IllegalArgumentException(
154 temp + " is not valid when multiple namespaces are listed.");
155
156
157
158
159
160
161 if (SchemaNames.isNamespaceName(temp))
162 _wildcard.addNamespace(temp);
163 else {
164 String err = "Invalid 'namespace' value: " + temp;
165 throw new IllegalArgumentException(err);
166 }
167 }
168 }
169 else
170 _wildcard.addNamespace(SchemaNames.NAMESPACE_ANY);
171
172
173
174
175
176 attValue = atts.getValue(SchemaNames.MAX_OCCURS_ATTR);
177 if (attValue != null) {
178 if (_wildcard.isAttributeWildcard())
179 throw new IllegalStateException("'maxOccurs' is prohibited on a <anyAttribute> element.");
180 if (MAX_OCCURS_WILDCARD.equals(attValue))
181 attValue = "-1";
182 int maxOccurs = toInt(attValue);
183 _wildcard.setMaxOccurs(maxOccurs);
184 }
185
186 attValue = atts.getValue("minOccurs");
187 if (attValue != null) {
188 if (_wildcard.isAttributeWildcard())
189 throw new IllegalStateException("'minOccurs' is prohibited on a <anyAttribute> element.");
190 _wildcard.setMinOccurs(toInt(attValue));
191 }
192
193 attValue = atts.getValue("processContents");
194
195 if (attValue != null) {
196 try {
197 _wildcard.setProcessContents(attValue);
198 } catch (SchemaException e) {
199 throw new IllegalArgumentException(e.getMessage());
200 }
201 }
202
203
204
205 _wildcard.setId(atts.getValue("id"));
206
207 }
208
209
210
211
212
213
214
215
216
217
218 public String elementName() {
219 return _element;
220 }
221
222
223
224
225
226
227
228 public Wildcard getWildcard() {
229 return _wildcard;
230 }
231
232
233
234
235
236
237 public Object getObject() {
238 return getWildcard();
239 }
240
241
242
243
244
245
246
247
248
249
250
251 public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
252 throws XMLException {
253
254 if (unmarshaller != null) {
255 unmarshaller.startElement(name, namespace, atts, nsDecls);
256 ++depth;
257 return;
258 }
259
260 if (SchemaNames.ANNOTATION.equals(name)) {
261 unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
262 }
263
264 else {
265 String err = new StringBuffer("illegal element <").append(name).append("> found in <")
266 .append(_element).append('>').toString();
267 throw new SchemaException(err);
268 }
269
270 }
271
272
273
274
275
276
277
278
279 public void endElement(String name, String namespace) throws XMLException {
280
281
282 if ((unmarshaller != null) && (depth > 0)) {
283 unmarshaller.endElement(name, namespace);
284 --depth;
285 return;
286 }
287
288
289 if (unmarshaller != null) {
290 if (!name.equals(unmarshaller.elementName())) {
291 String err = "missing end element for ";
292 err += unmarshaller.elementName();
293 throw new SchemaException(err);
294 }
295 }
296
297
298 unmarshaller.finish();
299
300
301 if (name == SchemaNames.ANNOTATION) {
302 _schema.addAnnotation((Annotation) unmarshaller.getObject());
303 }
304 unmarshaller = null;
305 }
306
307 public void characters(char[] ch, int start, int length) throws XMLException {
308
309 if (unmarshaller != null) {
310 unmarshaller.characters(ch, start, length);
311 }
312 }
313
314 }