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 import java.io.IOException;
49 import java.io.Reader;
50
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53 import org.exolab.castor.net.URIException;
54 import org.exolab.castor.net.URILocation;
55 import org.exolab.castor.net.URIResolver;
56 import org.exolab.castor.util.NestedIOException;
57 import org.exolab.castor.xml.XMLException;
58 import org.exolab.castor.xml.schema.Schema;
59 import org.exolab.castor.xml.schema.SchemaContext;
60 import org.exolab.castor.xml.schema.SchemaContextImpl;
61 import org.xml.sax.EntityResolver;
62 import org.xml.sax.ErrorHandler;
63 import org.xml.sax.InputSource;
64 import org.xml.sax.Parser;
65 import org.xml.sax.SAXException;
66 import org.xml.sax.SAXParseException;
67
68
69
70
71
72
73
74
75 @SuppressWarnings("deprecation")
76 public class SchemaReader {
77
78
79
80
81 private static final Log LOG = LogFactory.getLog(SchemaReader.class);
82
83
84
85
86 private SchemaContext _schemaContext;
87
88
89
90
91 private Parser _parser = null;
92
93
94
95
96 private InputSource _source = null;
97
98
99
100
101 private EntityResolver _resolver = null;
102
103
104
105
106 private ErrorHandler _errorHandler = null;
107
108
109
110
111 private URIResolver _uriResolver;
112
113
114
115
116
117
118
119 private boolean _cacheIncludedSchemas = false;
120
121 private Schema _schema = null;
122
123 private boolean _validate = true;
124
125
126
127
128
129
130
131 private void init() throws IOException {
132
133 _schemaContext = new SchemaContextImpl();
134
135 Parser parser = _schemaContext.getParser();
136
137 if (parser == null) {
138 String message = "fatal error: unable to create SAX parser.";
139 LOG.warn(message);
140 throw new IOException(message);
141 }
142
143 _parser = parser;
144 }
145
146
147
148
149
150
151
152 public SchemaReader(InputSource source) throws IOException {
153 init();
154
155 if (source == null)
156 throw new IllegalArgumentException("InputSource cannot be null");
157
158 _source = source;
159
160 }
161
162
163
164
165
166
167
168
169
170 public SchemaReader(Reader reader, String filename) throws IOException {
171 init();
172
173 if (reader == null) {
174 String err = "The argument 'reader' must not be null.";
175 throw new IllegalArgumentException(err);
176 }
177
178 _source = new InputSource(reader);
179 if (filename == null)
180 filename = reader.toString();
181 _source.setPublicId(filename);
182
183 }
184
185
186
187
188
189
190
191 public SchemaReader(String url) throws IOException {
192 init();
193 if (url == null) {
194 String err = "The argument 'url' must not be null.";
195 throw new IllegalArgumentException(err);
196 }
197 _source = new InputSource(url);
198
199 }
200
201
202
203
204
205 public SchemaReader() {
206 super();
207 }
208
209
210
211
212
213
214
215
216 public void setSchemaContext(final SchemaContext schemaContext) {
217 this._schemaContext = schemaContext;
218
219 Parser p = _schemaContext.getParser();
220 if (p != null) {
221 _parser = p;
222 }
223 }
224
225
226
227
228
229
230
231
232 public void setInputSource(final InputSource inputSource) {
233 if (inputSource == null) {
234 String message = "InputSource must not be null";
235 LOG.warn(message);
236 throw new IllegalArgumentException(message);
237 }
238 _source = inputSource;
239 }
240
241
242
243
244
245
246
247
248
249
250
251 public Schema read() throws IOException {
252 if (_schema != null) {
253 return _schema;
254 }
255 if (_parser == null) {
256 String message = "Required Parser was not specified";
257 LOG.warn(message);
258 throw new IllegalStateException(message);
259 }
260 if (_source == null) {
261 String message = "Required Source was not specified";
262 LOG.warn(message);
263 throw new IllegalStateException(message);
264 }
265 SchemaUnmarshaller schemaUnmarshaller = null;
266
267 try {
268 SchemaUnmarshallerState state = new SchemaUnmarshallerState();
269
270 state.cacheIncludedSchemas = _cacheIncludedSchemas;
271 schemaUnmarshaller = new SchemaUnmarshaller(_schemaContext, state);
272 if (_uriResolver != null)
273 schemaUnmarshaller.setURIResolver(_uriResolver);
274
275
276 String uri = _source.getSystemId();
277 if (uri != null) {
278 URIResolver resolver = schemaUnmarshaller.getURIResolver();
279 try {
280 URILocation location = resolver.resolve(uri, null);
281 if (location != null)
282 uri = location.toString();
283 } catch (URIException except) {
284 throw new NestedIOException(except);
285 }
286 state.markAsProcessed(uri, schemaUnmarshaller.getSchema());
287 }
288
289 Sax2ComponentReader handler = new Sax2ComponentReader(schemaUnmarshaller);
290 _parser.setDocumentHandler(handler);
291
292 if (_errorHandler == null)
293 _parser.setErrorHandler(handler);
294 else
295 _parser.setErrorHandler(_errorHandler);
296
297 if (_resolver != null)
298 _parser.setEntityResolver(_resolver);
299 _parser.parse(_source);
300 } catch (XMLException ex) {
301 handleException(ex);
302 } catch (org.xml.sax.SAXException sx) {
303 handleException(sx);
304 }
305
306 _schema = schemaUnmarshaller.getSchema();
307
308 if (_validate) {
309 try {
310 _schema.validate();
311 } catch (org.exolab.castor.xml.ValidationException vx) {
312 throw new NestedIOException(vx);
313 }
314 }
315
316 return _schema;
317
318 }
319
320
321
322
323
324
325 public void setErrorHandler(ErrorHandler errorHandler) {
326 _errorHandler = errorHandler;
327 }
328
329
330
331
332
333
334
335
336 public void setCacheIncludedSchemas(boolean cache) {
337 _cacheIncludedSchemas = cache;
338 }
339
340
341
342
343
344
345
346
347
348
349 public void setValidation(boolean validate) {
350 _validate = validate;
351 }
352
353
354
355
356
357
358
359
360 public void setEntityResolver(EntityResolver resolver) {
361 _resolver = resolver;
362 }
363
364
365
366
367
368
369
370
371 public void setURIResolver(URIResolver uriresolver) {
372 _uriResolver = uriresolver;
373 }
374
375
376
377
378
379
380
381
382 private void handleException(XMLException xmlException) throws IOException {
383 throw new NestedIOException(xmlException);
384 }
385
386
387
388
389
390
391
392
393 private void handleException(SAXException sx) throws IOException {
394 Exception except = sx.getException();
395 if (except == null) {
396 except = sx;
397 } else if (except instanceof SAXParseException) {
398 SAXParseException spe = (SAXParseException) except;
399 String filename = spe.getSystemId();
400 if (filename == null)
401 filename = spe.getPublicId();
402 if (filename == null)
403 filename = "<filename unavailable>";
404
405 String err = spe.getMessage();
406
407 err += "; " + filename + " [ line: " + spe.getLineNumber();
408 err += ", column: " + spe.getColumnNumber() + ']';
409 throw new NestedIOException(err, except);
410 } else if (except instanceof XMLException) {
411 handleException((XMLException) except);
412 }
413
414 throw new NestedIOException(except);
415
416 }
417 }