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