1 /*
2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.xml.parsers;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStream;
31
32 import javax.xml.validation.Schema;
33
34 import org.xml.sax.HandlerBase;
35 import org.xml.sax.InputSource;
36 import org.xml.sax.Parser;
37 import org.xml.sax.SAXException;
38 import org.xml.sax.SAXNotRecognizedException;
39 import org.xml.sax.SAXNotSupportedException;
40 import org.xml.sax.XMLReader;
41 import org.xml.sax.helpers.DefaultHandler;
42
43
44 /**
45 * Defines the API that wraps an {@link org.xml.sax.XMLReader}
46 * implementation class. In JAXP 1.0, this class wrapped the
47 * {@link org.xml.sax.Parser} interface, however this interface was
48 * replaced by the {@link org.xml.sax.XMLReader}. For ease
49 * of transition, this class continues to support the same name
50 * and interface as well as supporting new methods.
51 *
52 * An instance of this class can be obtained from the
53 * {@link javax.xml.parsers.SAXParserFactory#newSAXParser()} method.
54 * Once an instance of this class is obtained, XML can be parsed from
55 * a variety of input sources. These input sources are InputStreams,
56 * Files, URLs, and SAX InputSources.<p>
57 *
58 * This static method creates a new factory instance based
59 * on a system property setting or uses the platform default
60 * if no property has been defined.<p>
61 *
62 * The system property that controls which Factory implementation
63 * to create is named <code>"javax.xml.parsers.SAXParserFactory"</code>.
64 * This property names a class that is a concrete subclass of this
65 * abstract class. If no property is defined, a platform default
66 * will be used.</p>
67 *
68 * As the content is parsed by the underlying parser, methods of the
69 * given {@link org.xml.sax.HandlerBase} or the
70 * {@link org.xml.sax.helpers.DefaultHandler} are called.<p>
71 *
72 * Implementors of this class which wrap an underlaying implementation
73 * can consider using the {@link org.xml.sax.helpers.ParserAdapter}
74 * class to initially adapt their SAX1 implementation to work under
75 * this revised class.
76 *
77 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
78 */
79 public abstract class SAXParser {
80
81 /**
82 * <p>Protected constructor to prevent instaniation.
83 * Use {@link javax.xml.parsers.SAXParserFactory#newSAXParser()}.</p>
84 */
85 protected SAXParser () {
86
87 }
88
89 /**
90 * <p>Reset this <code>SAXParser</code> to its original configuration.</p>
91 *
92 * <p><code>SAXParser</code> is reset to the same state as when it was created with
93 * {@link SAXParserFactory#newSAXParser()}.
94 * <code>reset()</code> is designed to allow the reuse of existing <code>SAXParser</code>s
95 * thus saving resources associated with the creation of new <code>SAXParser</code>s.</p>
96 *
97 * <p>The reset <code>SAXParser</code> is not guaranteed to have the same {@link Schema}
98 * <code>Object</code>, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal
99 * <code>Schema</code>.</p>
100 *
101 * @throws UnsupportedOperationException When Implementations do not
102 * override this method
103 *
104 * @since 1.5
105 */
106 public void reset() {
107
108 // implementors should override this method
109 throw new UnsupportedOperationException(
110 "This SAXParser, \"" + this.getClass().getName() + "\", does not support the reset functionality."
111 + " Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\""
112 + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\""
113 );
114 }
115
116 /**
117 * <p>Parse the content of the given {@link java.io.InputStream}
118 * instance as XML using the specified {@link org.xml.sax.HandlerBase}.
119 * <i> Use of the DefaultHandler version of this method is recommended as
120 * the HandlerBase class has been deprecated in SAX 2.0</i>.</p>
121 *
122 * @param is InputStream containing the content to be parsed.
123 * @param hb The SAX HandlerBase to use.
124 *
125 * @throws IllegalArgumentException If the given InputStream is null.
126 * @throws SAXException If parse produces a SAX error.
127 * @throws IOException If an IO error occurs interacting with the
128 * <code>InputStream</code>.
129 *
130 * @see org.xml.sax.DocumentHandler
131 */
132 public void parse(InputStream is, HandlerBase hb)
133 throws SAXException, IOException {
134 if (is == null) {
135 throw new IllegalArgumentException("InputStream cannot be null");
136 }
137
138 InputSource input = new InputSource(is);
139 this.parse(input, hb);
140 }
141
142 /**
143 * <p>Parse the content of the given {@link java.io.InputStream}
144 * instance as XML using the specified {@link org.xml.sax.HandlerBase}.
145 * <i> Use of the DefaultHandler version of this method is recommended as
146 * the HandlerBase class has been deprecated in SAX 2.0</i>.</p>
147 *
148 * @param is InputStream containing the content to be parsed.
149 * @param hb The SAX HandlerBase to use.
150 * @param systemId The systemId which is needed for resolving relative URIs.
151 *
152 * @throws IllegalArgumentException If the given <code>InputStream</code> is
153 * <code>null</code>.
154 * @throws IOException If any IO error occurs interacting with the
155 * <code>InputStream</code>.
156 * @throws SAXException If any SAX errors occur during processing.
157 *
158 * @see org.xml.sax.DocumentHandler version of this method instead.
159 */
160 public void parse(
161 InputStream is,
162 HandlerBase hb,
163 String systemId)
164 throws SAXException, IOException {
165 if (is == null) {
166 throw new IllegalArgumentException("InputStream cannot be null");
167 }
168
169 InputSource input = new InputSource(is);
170 input.setSystemId(systemId);
171 this.parse(input, hb);
172 }
173
174 /**
175 * Parse the content of the given {@link java.io.InputStream}
176 * instance as XML using the specified
177 * {@link org.xml.sax.helpers.DefaultHandler}.
178 *
179 * @param is InputStream containing the content to be parsed.
180 * @param dh The SAX DefaultHandler to use.
181 *
182 * @throws IllegalArgumentException If the given InputStream is null.
183 * @throws IOException If any IO errors occur.
184 * @throws SAXException If any SAX errors occur during processing.
185 *
186 * @see org.xml.sax.DocumentHandler
187 */
188 public void parse(InputStream is, DefaultHandler dh)
189 throws SAXException, IOException {
190 if (is == null) {
191 throw new IllegalArgumentException("InputStream cannot be null");
192 }
193
194 InputSource input = new InputSource(is);
195 this.parse(input, dh);
196 }
197
198 /**
199 * Parse the content of the given {@link java.io.InputStream}
200 * instance as XML using the specified
201 * {@link org.xml.sax.helpers.DefaultHandler}.
202 *
203 * @param is InputStream containing the content to be parsed.
204 * @param dh The SAX DefaultHandler to use.
205 * @param systemId The systemId which is needed for resolving relative URIs.
206 *
207 * @throws IllegalArgumentException If the given InputStream is null.
208 * @throws IOException If any IO errors occur.
209 * @throws SAXException If any SAX errors occur during processing.
210 *
211 * @see org.xml.sax.DocumentHandler version of this method instead.
212 */
213 public void parse(
214 InputStream is,
215 DefaultHandler dh,
216 String systemId)
217 throws SAXException, IOException {
218 if (is == null) {
219 throw new IllegalArgumentException("InputStream cannot be null");
220 }
221
222 InputSource input = new InputSource(is);
223 input.setSystemId(systemId);
224 this.parse(input, dh);
225 }
226
227 /**
228 * Parse the content described by the giving Uniform Resource
229 * Identifier (URI) as XML using the specified
230 * {@link org.xml.sax.HandlerBase}.
231 * <i> Use of the DefaultHandler version of this method is recommended as
232 * the <code>HandlerBase</code> class has been deprecated in SAX 2.0</i>
233 *
234 * @param uri The location of the content to be parsed.
235 * @param hb The SAX HandlerBase to use.
236 *
237 * @throws IllegalArgumentException If the uri is null.
238 * @throws IOException If any IO errors occur.
239 * @throws SAXException If any SAX errors occur during processing.
240 *
241 * @see org.xml.sax.DocumentHandler
242 */
243 public void parse(String uri, HandlerBase hb)
244 throws SAXException, IOException {
245 if (uri == null) {
246 throw new IllegalArgumentException("uri cannot be null");
247 }
248
249 InputSource input = new InputSource(uri);
250 this.parse(input, hb);
251 }
252
253 /**
254 * Parse the content described by the giving Uniform Resource
255 * Identifier (URI) as XML using the specified
256 * {@link org.xml.sax.helpers.DefaultHandler}.
257 *
258 * @param uri The location of the content to be parsed.
259 * @param dh The SAX DefaultHandler to use.
260 *
261 * @throws IllegalArgumentException If the uri is null.
262 * @throws IOException If any IO errors occur.
263 * @throws SAXException If any SAX errors occur during processing.
264 *
265 * @see org.xml.sax.DocumentHandler
266 */
267 public void parse(String uri, DefaultHandler dh)
268 throws SAXException, IOException {
269 if (uri == null) {
270 throw new IllegalArgumentException("uri cannot be null");
271 }
272
273 InputSource input = new InputSource(uri);
274 this.parse(input, dh);
275 }
276
277 /**
278 * Parse the content of the file specified as XML using the
279 * specified {@link org.xml.sax.HandlerBase}.
280 * <i> Use of the DefaultHandler version of this method is recommended as
281 * the HandlerBase class has been deprecated in SAX 2.0</i>
282 *
283 * @param f The file containing the XML to parse
284 * @param hb The SAX HandlerBase to use.
285 *
286 * @throws IllegalArgumentException If the File object is null.
287 * @throws IOException If any IO errors occur.
288 * @throws SAXException If any SAX errors occur during processing.
289 *
290 * @see org.xml.sax.DocumentHandler
291 */
292 public void parse(File f, HandlerBase hb)
293 throws SAXException, IOException {
294 if (f == null) {
295 throw new IllegalArgumentException("File cannot be null");
296 }
297
298 //convert file to appropriate URI, f.toURI().toASCIIString()
299 //converts the URI to string as per rule specified in
300 //RFC 2396,
301 InputSource input = new InputSource(f.toURI().toASCIIString());
302 this.parse(input, hb);
303 }
304
305 /**
306 * Parse the content of the file specified as XML using the
307 * specified {@link org.xml.sax.helpers.DefaultHandler}.
308 *
309 * @param f The file containing the XML to parse
310 * @param dh The SAX DefaultHandler to use.
311 *
312 * @throws IllegalArgumentException If the File object is null.
313 * @throws IOException If any IO errors occur.
314 * @throws SAXException If any SAX errors occur during processing.
315 *
316 * @see org.xml.sax.DocumentHandler
317 */
318 public void parse(File f, DefaultHandler dh)
319 throws SAXException, IOException {
320 if (f == null) {
321 throw new IllegalArgumentException("File cannot be null");
322 }
323
324 //convert file to appropriate URI, f.toURI().toASCIIString()
325 //converts the URI to string as per rule specified in
326 //RFC 2396,
327 InputSource input = new InputSource(f.toURI().toASCIIString());
328 this.parse(input, dh);
329 }
330
331 /**
332 * Parse the content given {@link org.xml.sax.InputSource}
333 * as XML using the specified
334 * {@link org.xml.sax.HandlerBase}.
335 * <i> Use of the DefaultHandler version of this method is recommended as
336 * the HandlerBase class has been deprecated in SAX 2.0</i>
337 *
338 * @param is The InputSource containing the content to be parsed.
339 * @param hb The SAX HandlerBase to use.
340 *
341 * @throws IllegalArgumentException If the <code>InputSource</code> object
342 * is <code>null</code>.
343 * @throws IOException If any IO errors occur.
344 * @throws SAXException If any SAX errors occur during processing.
345 *
346 * @see org.xml.sax.DocumentHandler
347 */
348 public void parse(InputSource is, HandlerBase hb)
349 throws SAXException, IOException {
350 if (is == null) {
351 throw new IllegalArgumentException("InputSource cannot be null");
352 }
353
354 Parser parser = this.getParser();
355 if (hb != null) {
356 parser.setDocumentHandler(hb);
357 parser.setEntityResolver(hb);
358 parser.setErrorHandler(hb);
359 parser.setDTDHandler(hb);
360 }
361 parser.parse(is);
362 }
363
364 /**
365 * Parse the content given {@link org.xml.sax.InputSource}
366 * as XML using the specified
367 * {@link org.xml.sax.helpers.DefaultHandler}.
368 *
369 * @param is The InputSource containing the content to be parsed.
370 * @param dh The SAX DefaultHandler to use.
371 *
372 * @throws IllegalArgumentException If the <code>InputSource</code> object
373 * is <code>null</code>.
374 * @throws IOException If any IO errors occur.
375 * @throws SAXException If any SAX errors occur during processing.
376 *
377 * @see org.xml.sax.DocumentHandler
378 */
379 public void parse(InputSource is, DefaultHandler dh)
380 throws SAXException, IOException {
381 if (is == null) {
382 throw new IllegalArgumentException("InputSource cannot be null");
383 }
384
385 XMLReader reader = this.getXMLReader();
386 if (dh != null) {
387 reader.setContentHandler(dh);
388 reader.setEntityResolver(dh);
389 reader.setErrorHandler(dh);
390 reader.setDTDHandler(dh);
391 }
392 reader.parse(is);
393 }
394
395 /**
396 * Returns the SAX parser that is encapsultated by the
397 * implementation of this class.
398 *
399 * @return The SAX parser that is encapsultated by the
400 * implementation of this class.
401 *
402 * @throws SAXException If any SAX errors occur during processing.
403 */
404 public abstract org.xml.sax.Parser getParser() throws SAXException;
405
406 /**
407 * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the
408 * implementation of this class.
409 *
410 * @return The XMLReader that is encapsulated by the
411 * implementation of this class.
412 *
413 * @throws SAXException If any SAX errors occur during processing.
414 */
415
416 public abstract org.xml.sax.XMLReader getXMLReader() throws SAXException;
417
418 /**
419 * Indicates whether or not this parser is configured to
420 * understand namespaces.
421 *
422 * @return true if this parser is configured to
423 * understand namespaces; false otherwise.
424 */
425
426 public abstract boolean isNamespaceAware();
427
428 /**
429 * Indicates whether or not this parser is configured to
430 * validate XML documents.
431 *
432 * @return true if this parser is configured to
433 * validate XML documents; false otherwise.
434 */
435
436 public abstract boolean isValidating();
437
438 /**
439 * <p>Sets the particular property in the underlying implementation of
440 * {@link org.xml.sax.XMLReader}.
441 * A list of the core features and properties can be found at
442 * <a href="http://sax.sourceforge.net/?selected=get-set">
443 * http://sax.sourceforge.net/?selected=get-set</a>.</p>
444 *
445 * @param name The name of the property to be set.
446 * @param value The value of the property to be set.
447 *
448 * @throws SAXNotRecognizedException When the underlying XMLReader does
449 * not recognize the property name.
450 * @throws SAXNotSupportedException When the underlying XMLReader
451 * recognizes the property name but doesn't support the property.
452 *
453 * @see org.xml.sax.XMLReader#setProperty
454 */
455 public abstract void setProperty(String name, Object value)
456 throws SAXNotRecognizedException, SAXNotSupportedException;
457
458 /**
459 * <p>Returns the particular property requested for in the underlying
460 * implementation of {@link org.xml.sax.XMLReader}.</p>
461 *
462 * @param name The name of the property to be retrieved.
463 * @return Value of the requested property.
464 *
465 * @throws SAXNotRecognizedException When the underlying XMLReader does
466 * not recognize the property name.
467 * @throws SAXNotSupportedException When the underlying XMLReader
468 * recognizes the property name but doesn't support the property.
469 *
470 * @see org.xml.sax.XMLReader#getProperty
471 */
472 public abstract Object getProperty(String name)
473 throws SAXNotRecognizedException, SAXNotSupportedException;
474
475 /** <p>Get current state of canonicalization.</p>
476 *
477 * @return current state canonicalization control
478 */
479 /*
480 public boolean getCanonicalization() {
481 return canonicalState;
482 }
483 */
484
485 /** <p>Get a reference to the the {@link Schema} being used by
486 * the XML processor.</p>
487 *
488 * <p>If no schema is being used, <code>null</code> is returned.</p>
489 *
490 * @return {@link Schema} being used or <code>null</code>
491 * if none in use
492 *
493 * @throws UnsupportedOperationException When implementation does not
494 * override this method
495 *
496 * @since 1.5
497 */
498 public Schema getSchema() {
499 throw new UnsupportedOperationException(
500 "This parser does not support specification \""
501 + this.getClass().getPackage().getSpecificationTitle()
502 + "\" version \""
503 + this.getClass().getPackage().getSpecificationVersion()
504 + "\""
505 );
506 }
507
508 /**
509 * <p>Get the XInclude processing mode for this parser.</p>
510 *
511 * @return
512 * the return value of
513 * the {@link SAXParserFactory#isXIncludeAware()}
514 * when this parser was created from factory.
515 *
516 * @throws UnsupportedOperationException When implementation does not
517 * override this method
518 *
519 * @since 1.5
520 *
521 * @see SAXParserFactory#setXIncludeAware(boolean)
522 */
523 public boolean isXIncludeAware() {
524 throw new UnsupportedOperationException(
525 "This parser does not support specification \""
526 + this.getClass().getPackage().getSpecificationTitle()
527 + "\" version \""
528 + this.getClass().getPackage().getSpecificationVersion()
529 + "\""
530 );
531 }
532 }