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