1 /* 2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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 underlying 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 * @since 1.4 79 */ 80 @SuppressWarnings("deprecation") 81 public abstract class SAXParser { 82 83 /** 84 * <p>Protected constructor to prevent instantiation. 85 * Use {@link javax.xml.parsers.SAXParserFactory#newSAXParser()}.</p> 86 */ 87 protected SAXParser () { 88 89 } 90 91 /** 92 * <p>Reset this <code>SAXParser</code> to its original configuration.</p> 93 * 94 * <p><code>SAXParser</code> is reset to the same state as when it was created with 95 * {@link SAXParserFactory#newSAXParser()}. 96 * <code>reset()</code> is designed to allow the reuse of existing <code>SAXParser</code>s 97 * thus saving resources associated with the creation of new <code>SAXParser</code>s.</p> 98 * 99 * <p>The reset <code>SAXParser</code> is not guaranteed to have the same {@link Schema} 100 * <code>Object</code>, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal 101 * <code>Schema</code>.</p> 102 * 103 * @throws UnsupportedOperationException When Implementations do not 104 * override this method 105 * 106 * @since 1.5 107 */ 108 public void reset() { 109 110 // implementors should override this method 111 throw new UnsupportedOperationException( 112 "This SAXParser, \"" + this.getClass().getName() + "\", does not support the reset functionality." 113 + " Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\"" 114 + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\"" 115 ); 116 } 117 118 /** 119 * <p>Parse the content of the given {@link java.io.InputStream} 120 * instance as XML using the specified {@link org.xml.sax.HandlerBase}. 121 * <i> Use of the DefaultHandler version of this method is recommended as 122 * the HandlerBase class has been deprecated in SAX 2.0</i>.</p> 123 * 124 * @param is InputStream containing the content to be parsed. 125 * @param hb The SAX HandlerBase to use. 126 * 127 * @throws IllegalArgumentException If the given InputStream is null. 128 * @throws SAXException If parse produces a SAX error. 129 * @throws IOException If an IO error occurs interacting with the 130 * <code>InputStream</code>. 131 * 132 * @see org.xml.sax.DocumentHandler 133 */ 134 public void parse(InputStream is, HandlerBase hb) 135 throws SAXException, IOException { 136 if (is == null) { 137 throw new IllegalArgumentException("InputStream cannot be null"); 138 } 139 140 InputSource input = new InputSource(is); 141 this.parse(input, hb); 142 } 143 144 /** 145 * <p>Parse the content of the given {@link java.io.InputStream} 146 * instance as XML using the specified {@link org.xml.sax.HandlerBase}. 147 * <i> Use of the DefaultHandler version of this method is recommended as 148 * the HandlerBase class has been deprecated in SAX 2.0</i>.</p> 149 * 150 * @param is InputStream containing the content to be parsed. 151 * @param hb The SAX HandlerBase to use. 152 * @param systemId The systemId which is needed for resolving relative URIs. 153 * 154 * @throws IllegalArgumentException If the given <code>InputStream</code> is 155 * <code>null</code>. 156 * @throws IOException If any IO error occurs interacting with the 157 * <code>InputStream</code>. 158 * @throws SAXException If any SAX errors occur during processing. 159 * 160 * @see org.xml.sax.DocumentHandler version of this method instead. 161 */ 162 public void parse( 163 InputStream is, 164 HandlerBase hb, 165 String systemId) 166 throws SAXException, IOException { 167 if (is == null) { 168 throw new IllegalArgumentException("InputStream cannot be null"); 169 } 170 171 InputSource input = new InputSource(is); 172 input.setSystemId(systemId); 173 this.parse(input, hb); 174 } 175 176 /** 177 * Parse the content of the given {@link java.io.InputStream} 178 * instance as XML using the specified 179 * {@link org.xml.sax.helpers.DefaultHandler}. 180 * 181 * @param is InputStream containing the content to be parsed. 182 * @param dh The SAX DefaultHandler to use. 183 * 184 * @throws IllegalArgumentException If the given InputStream is null. 185 * @throws IOException If any IO errors occur. 186 * @throws SAXException If any SAX errors occur during processing. 187 * 188 * @see org.xml.sax.DocumentHandler 189 */ 190 public void parse(InputStream is, DefaultHandler dh) 191 throws SAXException, IOException { 192 if (is == null) { 193 throw new IllegalArgumentException("InputStream cannot be null"); 194 } 195 196 InputSource input = new InputSource(is); 197 this.parse(input, dh); 198 } 199 200 /** 201 * Parse the content of the given {@link java.io.InputStream} 202 * instance as XML using the specified 203 * {@link org.xml.sax.helpers.DefaultHandler}. 204 * 205 * @param is InputStream containing the content to be parsed. 206 * @param dh The SAX DefaultHandler to use. 207 * @param systemId The systemId which is needed for resolving relative URIs. 208 * 209 * @throws IllegalArgumentException If the given InputStream is null. 210 * @throws IOException If any IO errors occur. 211 * @throws SAXException If any SAX errors occur during processing. 212 * 213 * @see org.xml.sax.DocumentHandler version of this method instead. 214 */ 215 public void parse( 216 InputStream is, 217 DefaultHandler dh, 218 String systemId) 219 throws SAXException, IOException { 220 if (is == null) { 221 throw new IllegalArgumentException("InputStream cannot be null"); 222 } 223 224 InputSource input = new InputSource(is); 225 input.setSystemId(systemId); 226 this.parse(input, dh); 227 } 228 229 /** 230 * Parse the content described by the giving Uniform Resource 231 * Identifier (URI) as XML using the specified 232 * {@link org.xml.sax.HandlerBase}. 233 * <i> Use of the DefaultHandler version of this method is recommended as 234 * the <code>HandlerBase</code> class has been deprecated in SAX 2.0</i> 235 * 236 * @param uri The location of the content to be parsed. 237 * @param hb The SAX HandlerBase to use. 238 * 239 * @throws IllegalArgumentException If the uri is null. 240 * @throws IOException If any IO errors occur. 241 * @throws SAXException If any SAX errors occur during processing. 242 * 243 * @see org.xml.sax.DocumentHandler 244 */ 245 public void parse(String uri, HandlerBase hb) 246 throws SAXException, IOException { 247 if (uri == null) { 248 throw new IllegalArgumentException("uri cannot be null"); 249 } 250 251 InputSource input = new InputSource(uri); 252 this.parse(input, hb); 253 } 254 255 /** 256 * Parse the content described by the giving Uniform Resource 257 * Identifier (URI) as XML using the specified 258 * {@link org.xml.sax.helpers.DefaultHandler}. 259 * 260 * @param uri The location of the content to be parsed. 261 * @param dh The SAX DefaultHandler to use. 262 * 263 * @throws IllegalArgumentException If the uri is null. 264 * @throws IOException If any IO errors occur. 265 * @throws SAXException If any SAX errors occur during processing. 266 * 267 * @see org.xml.sax.DocumentHandler 268 */ 269 public void parse(String uri, DefaultHandler dh) 270 throws SAXException, IOException { 271 if (uri == null) { 272 throw new IllegalArgumentException("uri cannot be null"); 273 } 274 275 InputSource input = new InputSource(uri); 276 this.parse(input, dh); 277 } 278 279 /** 280 * Parse the content of the file specified as XML using the 281 * specified {@link org.xml.sax.HandlerBase}. 282 * <i> Use of the DefaultHandler version of this method is recommended as 283 * the HandlerBase class has been deprecated in SAX 2.0</i> 284 * 285 * @param f The file containing the XML to parse 286 * @param hb The SAX HandlerBase to use. 287 * 288 * @throws IllegalArgumentException If the File object is null. 289 * @throws IOException If any IO errors occur. 290 * @throws SAXException If any SAX errors occur during processing. 291 * 292 * @see org.xml.sax.DocumentHandler 293 */ 294 public void parse(File f, HandlerBase hb) 295 throws SAXException, IOException { 296 if (f == null) { 297 throw new IllegalArgumentException("File cannot be null"); 298 } 299 300 //convert file to appropriate URI, f.toURI().toASCIIString() 301 //converts the URI to string as per rule specified in 302 //RFC 2396, 303 InputSource input = new InputSource(f.toURI().toASCIIString()); 304 this.parse(input, hb); 305 } 306 307 /** 308 * Parse the content of the file specified as XML using the 309 * specified {@link org.xml.sax.helpers.DefaultHandler}. 310 * 311 * @param f The file containing the XML to parse 312 * @param dh The SAX DefaultHandler to use. 313 * 314 * @throws IllegalArgumentException If the File object is null. 315 * @throws IOException If any IO errors occur. 316 * @throws SAXException If any SAX errors occur during processing. 317 * 318 * @see org.xml.sax.DocumentHandler 319 */ 320 public void parse(File f, DefaultHandler dh) 321 throws SAXException, IOException { 322 if (f == null) { 323 throw new IllegalArgumentException("File cannot be null"); 324 } 325 326 //convert file to appropriate URI, f.toURI().toASCIIString() 327 //converts the URI to string as per rule specified in 328 //RFC 2396, 329 InputSource input = new InputSource(f.toURI().toASCIIString()); 330 this.parse(input, dh); 331 } 332 333 /** 334 * Parse the content given {@link org.xml.sax.InputSource} 335 * as XML using the specified 336 * {@link org.xml.sax.HandlerBase}. 337 * <i> Use of the DefaultHandler version of this method is recommended as 338 * the HandlerBase class has been deprecated in SAX 2.0</i> 339 * 340 * @param is The InputSource containing the content to be parsed. 341 * @param hb The SAX HandlerBase to use. 342 * 343 * @throws IllegalArgumentException If the <code>InputSource</code> object 344 * is <code>null</code>. 345 * @throws IOException If any IO errors occur. 346 * @throws SAXException If any SAX errors occur during processing. 347 * 348 * @see org.xml.sax.DocumentHandler 349 */ 350 public void parse(InputSource is, HandlerBase hb) 351 throws SAXException, IOException { 352 if (is == null) { 353 throw new IllegalArgumentException("InputSource cannot be null"); 354 } 355 356 Parser parser = this.getParser(); 357 if (hb != null) { 358 parser.setDocumentHandler(hb); 359 parser.setEntityResolver(hb); 360 parser.setErrorHandler(hb); 361 parser.setDTDHandler(hb); 362 } 363 parser.parse(is); 364 } 365 366 /** 367 * Parse the content given {@link org.xml.sax.InputSource} 368 * as XML using the specified 369 * {@link org.xml.sax.helpers.DefaultHandler}. 370 * 371 * @param is The InputSource containing the content to be parsed. 372 * @param dh The SAX DefaultHandler to use. 373 * 374 * @throws IllegalArgumentException If the <code>InputSource</code> object 375 * is <code>null</code>. 376 * @throws IOException If any IO errors occur. 377 * @throws SAXException If any SAX errors occur during processing. 378 * 379 * @see org.xml.sax.DocumentHandler 380 */ 381 public void parse(InputSource is, DefaultHandler dh) 382 throws SAXException, IOException { 383 if (is == null) { 384 throw new IllegalArgumentException("InputSource cannot be null"); 385 } 386 387 XMLReader reader = this.getXMLReader(); 388 if (dh != null) { 389 reader.setContentHandler(dh); 390 reader.setEntityResolver(dh); 391 reader.setErrorHandler(dh); 392 reader.setDTDHandler(dh); 393 } 394 reader.parse(is); 395 } 396 397 /** 398 * Returns the SAX parser that is encapsulated by the 399 * implementation of this class. 400 * 401 * @return The SAX parser that is encapsulated by the 402 * implementation of this class. 403 * 404 * @throws SAXException If any SAX errors occur during processing. 405 */ 406 public abstract org.xml.sax.Parser getParser() throws SAXException; 407 408 /** 409 * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the 410 * implementation of this class. 411 * 412 * @return The XMLReader that is encapsulated by the 413 * implementation of this class. 414 * 415 * @throws SAXException If any SAX errors occur during processing. 416 */ 417 418 public abstract org.xml.sax.XMLReader getXMLReader() throws SAXException; 419 420 /** 421 * Indicates whether or not this parser is configured to 422 * understand namespaces. 423 * 424 * @return true if this parser is configured to 425 * understand namespaces; false otherwise. 426 */ 427 428 public abstract boolean isNamespaceAware(); 429 430 /** 431 * Indicates whether or not this parser is configured to 432 * validate XML documents. 433 * 434 * @return true if this parser is configured to 435 * validate XML documents; false otherwise. 436 */ 437 438 public abstract boolean isValidating(); 439 440 /** 441 * <p>Sets the particular property in the underlying implementation of 442 * {@link org.xml.sax.XMLReader}. 443 * A list of the core features and properties can be found at 444 * <a href="http://sax.sourceforge.net/?selected=get-set"> 445 * http://sax.sourceforge.net/?selected=get-set</a>.</p> 446 * <p> 447 * All implementations that implement JAXP 1.5 or newer are required to 448 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and 449 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. 450 * </p> 451 * <ul> 452 * <li> 453 * <p> 454 * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property 455 * restricts the access to external DTDs, external Entity References to 456 * the protocols specified by the property. If access is denied during parsing 457 * due to the restriction of this property, {@link org.xml.sax.SAXException} 458 * will be thrown by the parse methods defined by {@link javax.xml.parsers.SAXParser}. 459 * </p> 460 * <p> 461 * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property 462 * restricts the access to external Schema set by the schemaLocation attribute to 463 * the protocols specified by the property. If access is denied during parsing 464 * due to the restriction of this property, {@link org.xml.sax.SAXException} 465 * will be thrown by the parse methods defined by the {@link javax.xml.parsers.SAXParser}. 466 * </p> 467 * </li> 468 * </ul> 469 * 470 * @param name The name of the property to be set. 471 * @param value The value of the property to be set. 472 * 473 * @throws SAXNotRecognizedException When the underlying XMLReader does 474 * not recognize the property name. 475 * @throws SAXNotSupportedException When the underlying XMLReader 476 * recognizes the property name but doesn't support the property. 477 * 478 * @see org.xml.sax.XMLReader#setProperty 479 */ 480 public abstract void setProperty(String name, Object value) 481 throws SAXNotRecognizedException, SAXNotSupportedException; 482 483 /** 484 * <p>Returns the particular property requested for in the underlying 485 * implementation of {@link org.xml.sax.XMLReader}.</p> 486 * 487 * @param name The name of the property to be retrieved. 488 * @return Value of the requested property. 489 * 490 * @throws SAXNotRecognizedException When the underlying XMLReader does 491 * not recognize the property name. 492 * @throws SAXNotSupportedException When the underlying XMLReader 493 * recognizes the property name but doesn't support the property. 494 * 495 * @see org.xml.sax.XMLReader#getProperty 496 */ 497 public abstract Object getProperty(String name) 498 throws SAXNotRecognizedException, SAXNotSupportedException; 499 500 /** <p>Get current state of canonicalization.</p> 501 * 502 * @return current state canonicalization control 503 */ 504 /* 505 public boolean getCanonicalization() { 506 return canonicalState; 507 } 508 */ 509 510 /** <p>Get a reference to the the {@link Schema} being used by 511 * the XML processor.</p> 512 * 513 * <p>If no schema is being used, <code>null</code> is returned.</p> 514 * 515 * @return {@link Schema} being used or <code>null</code> 516 * if none in use 517 * 518 * @throws UnsupportedOperationException When implementation does not 519 * override this method 520 * 521 * @since 1.5 522 */ 523 public Schema getSchema() { 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 533 /** 534 * <p>Get the XInclude processing mode for this parser.</p> 535 * 536 * @return 537 * the return value of 538 * the {@link SAXParserFactory#isXIncludeAware()} 539 * when this parser was created from factory. 540 * 541 * @throws UnsupportedOperationException When implementation does not 542 * override this method 543 * 544 * @since 1.5 545 * 546 * @see SAXParserFactory#setXIncludeAware(boolean) 547 */ 548 public boolean isXIncludeAware() { 549 throw new UnsupportedOperationException( 550 "This parser does not support specification \"" 551 + this.getClass().getPackage().getSpecificationTitle() 552 + "\" version \"" 553 + this.getClass().getPackage().getSpecificationVersion() 554 + "\"" 555 ); 556 } 557 }