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.net.URIException;
50 import org.exolab.castor.net.URILocation;
51 import org.exolab.castor.net.URIResolver;
52 import org.exolab.castor.xml.AttributeSet;
53 import org.exolab.castor.xml.Namespaces;
54 import org.exolab.castor.xml.XMLException;
55 import org.exolab.castor.xml.schema.Annotation;
56 import org.exolab.castor.xml.schema.AttributeGroup;
57 import org.exolab.castor.xml.schema.AttributeGroupDecl;
58 import org.exolab.castor.xml.schema.ComplexType;
59 import org.exolab.castor.xml.schema.Group;
60 import org.exolab.castor.xml.schema.ModelGroup;
61 import org.exolab.castor.xml.schema.RedefineSchema;
62 import org.exolab.castor.xml.schema.Schema;
63 import org.exolab.castor.xml.schema.SchemaContext;
64 import org.exolab.castor.xml.schema.SchemaException;
65 import org.exolab.castor.xml.schema.SchemaNames;
66 import org.exolab.castor.xml.schema.SimpleType;
67 import org.exolab.castor.xml.schema.XMLType;
68 import org.xml.sax.InputSource;
69 import org.xml.sax.Locator;
70 import org.xml.sax.Parser;
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public class RedefineUnmarshaller extends ComponentReader
85 {
86
87
88
89
90 private ComponentReader _unmarshaller;
91
92
93
94
95 private int _depth = 0;
96
97
98
99
100 private Schema _schema;
101
102
103
104
105 private Schema _importedSchema;
106
107 private RedefineSchema _redefineSchema;
108
109
110
111
112
113 public RedefineUnmarshaller(
114 final SchemaContext schemaContext,
115 final Schema schema,
116 final AttributeSet atts,
117 final URIResolver uriResolver,
118 final Locator locator,
119 final SchemaUnmarshallerState state)
120 throws XMLException {
121 super(schemaContext);
122 if (schema == null) {
123 String err = SchemaNames.REDEFINE + " must be used with an existing parent XML Schema.";
124 throw new SchemaException(err);
125 }
126 setURIResolver(uriResolver);
127
128 URILocation uri = null;
129
130 String schemaLocation = atts.getValue(SchemaNames.SCHEMALOCATION_ATTR);
131 _schema = schema;
132
133 if (schemaLocation == null) {
134
135 _redefineSchema = new RedefineSchema(schema);
136 _schema.addRedefineSchema(_redefineSchema);
137 return;
138 }
139
140
141 if (schemaLocation.indexOf("\\") != -1) {
142 String err = "'" + schemaLocation +
143 "' is not a valid URI as defined by IETF RFC 2396.";
144 err += "The URI mustn't contain '\\'.";
145 error(err);
146 }
147
148 try {
149 String documentBase = locator.getSystemId();
150 if (documentBase != null) {
151 if (!documentBase.endsWith("/"))
152 documentBase = documentBase.substring(0, documentBase.lastIndexOf('/') +1 );
153 }
154 uri = getURIResolver().resolve(schemaLocation, documentBase);
155 if (uri != null) {
156 schemaLocation = uri.getAbsoluteURI();
157 }
158 }
159 catch (URIException urix) {
160 throw new XMLException(urix);
161 }
162
163
164 boolean addSchema = false;
165 _redefineSchema = schema.getRedefineSchema(schemaLocation);
166 Schema importedSchema = null;
167
168 boolean alreadyLoaded = false;
169
170
171 if (_redefineSchema == null) {
172 if (uri instanceof SchemaLocation) {
173 importedSchema = ((SchemaLocation)uri).getSchema();
174
175
176
177
178
179 _redefineSchema = new RedefineSchema(schema, importedSchema);
180 schema.addRedefineSchema(_redefineSchema);
181 alreadyLoaded = true;
182 }
183 else {
184 importedSchema = new Schema();
185 addSchema = true;
186 }
187 }
188 else {
189
190 String tmpLocation = _redefineSchema.getOriginalSchema().getSchemaLocation();
191 alreadyLoaded = schemaLocation.equals(tmpLocation);
192 }
193
194 state.markAsProcessed(schemaLocation, importedSchema);
195
196 if (alreadyLoaded) return;
197
198
199 Parser parser = null;
200 try {
201 parser = getSchemaContext().getParser();
202 }
203 catch(RuntimeException rte) {}
204 if (parser == null) {
205 throw new SchemaException("Error failed to create parser for import");
206 }
207
208 SchemaUnmarshaller schemaUnmarshaller = new SchemaUnmarshaller(getSchemaContext(), state);
209 schemaUnmarshaller.setURIResolver(getURIResolver());
210 schemaUnmarshaller.setSchema(importedSchema);
211 Sax2ComponentReader handler = new Sax2ComponentReader(schemaUnmarshaller);
212 parser.setDocumentHandler(handler);
213 parser.setErrorHandler(handler);
214
215 try {
216 InputSource source = new InputSource(uri.getReader());
217 source.setSystemId(uri.getAbsoluteURI());
218 parser.parse(source);
219 }
220 catch(java.io.IOException ioe) {
221 throw new SchemaException("Error reading import file '"+schemaLocation+"': "+ ioe);
222 }
223 catch(org.xml.sax.SAXException sx) {
224 throw new SchemaException(sx);
225 }
226
227
228 String namespace = importedSchema.getTargetNamespace();
229 if ( namespace != null ) {
230
231
232
233 if (!namespace.equals(schema.getTargetNamespace()) ) {
234 String err = "The 'namespace' attribute in the <redefine> element must be the same of the targetNamespace of the global schema.\n"
235 +namespace+" is different from:"+schema.getTargetNamespace();
236 error (err);
237 }
238 } else {
239 importedSchema.setTargetNamespace(schema.getTargetNamespace());
240 }
241
242
243
244
245
246
247 _importedSchema = importedSchema;
248 _redefineSchema = new RedefineSchema(schema, _importedSchema);
249
250 if (addSchema)
251 {
252 importedSchema.setSchemaLocation(schemaLocation);
253 _schema.addRedefineSchema(_redefineSchema);
254 }
255 }
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270 public void startElement(String name, String namespace, AttributeSet atts,
271 Namespaces nsDecls)
272 throws XMLException
273 {
274
275
276
277
278
279
280
281
282 if (_unmarshaller != null) {
283 try {
284 _unmarshaller.startElement(name, namespace, atts, nsDecls);
285 _depth ++;
286 return;
287 } catch(RuntimeException rtx) {
288 error(rtx);
289 }
290 }
291
292
293 if (name.equals(SchemaNames.ANNOTATION)) {
294 _unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
295 }
296
297 else if (name.equals(SchemaNames.ATTRIBUTE_GROUP)) {
298 _unmarshaller = new AttributeGroupUnmarshaller(getSchemaContext(), _schema, atts);
299 }
300
301 else if (name.equals(SchemaNames.COMPLEX_TYPE)) {
302 _unmarshaller
303 = new ComplexTypeUnmarshaller(getSchemaContext(), _schema, atts);
304 }
305
306 else if (name.equals(SchemaNames.SIMPLE_TYPE)) {
307 _unmarshaller = new SimpleTypeUnmarshaller(getSchemaContext(), _schema, atts);
308 }
309
310 else if (name.equals(SchemaNames.GROUP)) {
311 _unmarshaller = new ModelGroupUnmarshaller(getSchemaContext(), _schema, atts);
312 }
313 else {
314
315 String err = "<" + name +"> elements cannot be used in a redefine.";
316 error(err);
317 }
318
319 _unmarshaller.setDocumentLocator(getDocumentLocator());
320
321 }
322
323
324
325
326
327
328
329
330 public void endElement(String name, String namespace)
331 throws XMLException
332 {
333
334
335
336
337
338
339 if ((_unmarshaller != null) && (_depth > 0)) {
340 _unmarshaller.endElement(name, namespace);
341 --_depth;
342 return;
343 }
344
345
346
347 name = name.intern();
348
349
350
351 if ((_unmarshaller != null)) {
352 if (!name.equals(_unmarshaller.elementName())) {
353 String err = "error: missing end element for ";
354 err += _unmarshaller.elementName();
355 error(err);
356 }
357 }
358 else {
359 String err = "error: missing start element for " + name;
360 throw new SchemaException(err);
361 }
362
363
364 _unmarshaller.finish();
365
366
367 if (name.equals(SchemaNames.ANNOTATION)) {
368 _redefineSchema.addAnnotation((Annotation)_unmarshaller.getObject());
369 }
370
371 else if (name.equals(SchemaNames.ATTRIBUTE_GROUP)) {
372 if (_redefineSchema.getSchemaLocation() == "") {
373 String err = "In a <redefine>, only annotations can be defined when no -schemaLocation- is specified.";
374 error(err);
375 }
376
377 AttributeGroupDecl group = null;
378 group = (AttributeGroupDecl)(((AttributeGroupUnmarshaller)_unmarshaller).getAttributeGroup());
379
380 String structureName = group.getName();
381 if (structureName == null) {
382 String err = "When redefining an AttributeGroup, the group must have a name.\n";
383 error(err);
384 }
385
386
387 AttributeGroup original = _importedSchema.getAttributeGroup(structureName);
388 if (original == null) {
389 String err = "When redefining an AttributeGroup, the AttributeGroup must be present in the imported XML schema.\n"
390 +"AttributeGroup: "+structureName+" is not defined in XML Schema:" + _importedSchema.getSchemaLocation();
391 error(err);
392 }
393
394
395 group.setRedefined();
396 _redefineSchema.addAttributeGroup(group);
397
398 }
399
400 else if (name.equals(SchemaNames.COMPLEX_TYPE)) {
401 if (_redefineSchema.getSchemaLocation() == "") {
402 String err = "In a <redefine>, only annotations can be defined when no -schemaLocation- is specified.";
403 error(err);
404 }
405 ComplexType complexType = null;
406 complexType = ((ComplexTypeUnmarshaller)_unmarshaller).getComplexType();
407
408 String structureName = complexType.getName();
409 if (structureName == null) {
410 String err = "When redefining a complexType, the complexType must have a name.\n";
411 error(err);
412 }
413
414
415 ComplexType original = _importedSchema.getComplexType(structureName);
416 if (original == null) {
417 String err = "When redefining a complexType, the complexType must be present in the imported XML schema.\n"
418 +"ComplexType: "+structureName+" is not defined in XML Schema:" + _importedSchema.getSchemaLocation();
419 error(err);
420 }
421
422
423 XMLType baseType = complexType.getBaseType();
424
425 if (baseType == null || !baseType.getName().equals(structureName)) {
426 String err = "When redefining a complexType, the complexType must use itself as the base type definition.\n"
427 +"ComplexType: "+structureName+" uses:" + baseType+ " as its base type.";
428 error(err);
429 }
430
431 complexType.setRedefined();
432 _redefineSchema.addComplexType(complexType);
433 getResolver().addResolvable(complexType.getReferenceId(), complexType);
434 }
435
436 else if (name.equals(SchemaNames.SIMPLE_TYPE)) {
437 if (_redefineSchema.getSchemaLocation() == "") {
438 String err = "In a <redefine>, only annotations can be defined when no -schemaLocation- is specified.";
439 error(err);
440 }
441
442 SimpleType simpleType = null;
443 simpleType = ((SimpleTypeUnmarshaller)_unmarshaller).getSimpleType();
444
445 String structureName = simpleType.getName();
446 if (structureName == null) {
447 String err = "When redefining a simpleType, the simpleType must have a name.\n";
448 error(err);
449 }
450
451
452 SimpleType original = _importedSchema.getSimpleType(structureName,_schema.getTargetNamespace() );
453 if (original == null) {
454 String err = "When redefining a simpleType, the simpleType must be present in the imported XML schema.\n"
455 +"SimpleType: "+structureName+" is not defined in XML Schema:" + _importedSchema.getSchemaLocation();
456 error(err);
457 }
458
459
460 XMLType baseType = simpleType.getBaseType();
461
462 if (!baseType.getName().equals(structureName)) {
463 String err = "When redefining a simpleType, the simpleType must use itself as the base type definition.\n"
464 +"SimpleType: "+structureName+" uses:" + baseType.getName() + " as its base type.";
465 error(err);
466 }
467
468 simpleType.setRedefined();
469 _redefineSchema.addSimpleType(simpleType);
470 getResolver().addResolvable(simpleType.getReferenceId(), simpleType);
471 }
472
473 else if (name.equals(SchemaNames.GROUP)) {
474 if (_redefineSchema.getSchemaLocation() == "") {
475 String err = "In a <redefine>, only annotations can be defined when no -schemaLocation- is specified.";
476 error(err);
477 }
478
479 ModelGroup group = null;
480 group = (((ModelGroupUnmarshaller)_unmarshaller).getGroup());
481
482 String structureName = group.getName();
483 if (structureName == null) {
484 String err = "When redefining a group, the group must have a name.\n";
485 error(err);
486 }
487
488
489 Group original = _importedSchema.getModelGroup(structureName);
490 if (original == null) {
491 String err = "When redefining a group, the group must be present in the imported XML schema.\n"
492 +"Group: "+structureName+" is not defined in XML Schema:" + _importedSchema.getSchemaLocation();
493 error(err);
494 }
495
496
497
498
499 group.setRedefined();
500 _redefineSchema.addGroup(group);
501 } else {
502 String err = "In a <redefine>, only complexTypes|simpleTypes|groups or attributeGroups can be redefined.";
503 error(err);
504 }
505
506 _unmarshaller = null;
507 }
508
509 public void characters(char[] ch, int start, int length)
510 throws XMLException
511 {
512
513 if (_unmarshaller != null) {
514 _unmarshaller.characters(ch, start, length);
515 }
516 }
517
518
519
520
521
522 public String elementName() {
523 return SchemaNames.REDEFINE;
524 }
525
526
527
528
529
530 public Object getObject() {
531 return _redefineSchema;
532 }
533
534 }