1 /* 2 * Copyright (c) 2000, 2013, 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 */ 79 public abstract class SAXParser { 80 81 /** 82 * <p>Protected constructor to prevent instantiation. 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 encapsulated by the 397 * implementation of this class. 398 * 399 * @return The SAX parser that is encapsulated 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 * <p> 445 * All implementations that implement JAXP 1.5 or newer are required to 446 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and 447 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. 448 * </p> 449 * <ul> 450 * <li> 451 * <p> 452 * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property 453 * restricts the access to external DTDs, external Entity References to 454 * the protocols specified by the property. If access is denied during parsing 455 * due to the restriction of this property, {@link org.xml.sax.SAXException} 456 * will be thrown by the parse methods defined by {@link javax.xml.parsers.SAXParser}. 457 * </p> 458 * <p> 459 * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property 460 * restricts the access to external Schema set by the schemaLocation attribute to 461 * the protocols specified by the property. If access is denied during parsing 462 * due to the restriction of this property, {@link org.xml.sax.SAXException} 463 * will be thrown by the parse methods defined by the {@link javax.xml.parsers.SAXParser}. 464 * </p> 465 * </li> 466 * </ul> 467 * 468 * @param name The name of the property to be set. 469 * @param value The value of the property to be set. 470 * 471 * @throws SAXNotRecognizedException When the underlying XMLReader does 472 * not recognize the property name. 473 * @throws SAXNotSupportedException When the underlying XMLReader 474 * recognizes the property name but doesn't support the property. 475 * 476 * @see org.xml.sax.XMLReader#setProperty 477 */ 478 public abstract void setProperty(String name, Object value) 479 throws SAXNotRecognizedException, SAXNotSupportedException; 480 481 /** 482 * <p>Returns the particular property requested for in the underlying 483 * implementation of {@link org.xml.sax.XMLReader}.</p> 484 * 485 * @param name The name of the property to be retrieved. 486 * @return Value of the requested property. 487 * 488 * @throws SAXNotRecognizedException When the underlying XMLReader does 489 * not recognize the property name. 490 * @throws SAXNotSupportedException When the underlying XMLReader 491 * recognizes the property name but doesn't support the property. 492 * 493 * @see org.xml.sax.XMLReader#getProperty 494 */ 495 public abstract Object getProperty(String name) 496 throws SAXNotRecognizedException, SAXNotSupportedException; 497 498 /** <p>Get current state of canonicalization.</p> 499 * 500 * @return current state canonicalization control 501 */ 502 /* 503 public boolean getCanonicalization() { 504 return canonicalState; 505 } 506 */ 507 508 /** <p>Get a reference to the the {@link Schema} being used by 509 * the XML processor.</p> 510 * 511 * <p>If no schema is being used, <code>null</code> is returned.</p> 512 * 513 * @return {@link Schema} being used or <code>null</code> 514 * if none in use 515 * 516 * @throws UnsupportedOperationException When implementation does not 517 * override this method 518 * 519 * @since 1.5 520 */ 521 public Schema getSchema() { 522 throw new UnsupportedOperationException( 523 "This parser does not support specification \"" 524 + this.getClass().getPackage().getSpecificationTitle() 525 + "\" version \"" 526 + this.getClass().getPackage().getSpecificationVersion() 527 + "\"" 528 ); 529 } 530 531 /** 532 * <p>Get the XInclude processing mode for this parser.</p> 533 * 534 * @return 535 * the return value of 536 * the {@link SAXParserFactory#isXIncludeAware()} 537 * when this parser was created from factory. 538 * 539 * @throws UnsupportedOperationException When implementation does not 540 * override this method 541 * 542 * @since 1.5 543 * 544 * @see SAXParserFactory#setXIncludeAware(boolean) 545 */ 546 public boolean isXIncludeAware() { 547 throw new UnsupportedOperationException( 548 "This parser does not support specification \"" 549 + this.getClass().getPackage().getSpecificationTitle() 550 + "\" version \"" 551 + this.getClass().getPackage().getSpecificationVersion() 552 + "\"" 553 ); 554 } 555 }