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