1 /* 2 * Copyright (c) 2009, 2016, 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.stream; 27 28 import com.sun.xml.internal.stream.XMLInputFactoryImpl; 29 import javax.xml.stream.util.XMLEventAllocator; 30 import javax.xml.transform.Source; 31 32 /** 33 * Defines an abstract implementation of a factory for getting streams. 34 * 35 * The following table defines the standard properties of this specification. 36 * Each property varies in the level of support required by each implementation. 37 * The level of support required is described in the 'Required' column. 38 * 39 * <table border="2" rules="all" cellpadding="4"> 40 * <thead> 41 * <tr> 42 * <th align="center" colspan="5"> 43 * Configuration parameters 44 * </th> 45 * </tr> 46 * </thead> 47 * <tbody> 48 * <tr> 49 * <th>Property Name</th> 50 * <th>Behavior</th> 51 * <th>Return type</th> 52 * <th>Default Value</th> 53 * <th>Required</th> 54 * </tr> 55 * <tr><td>javax.xml.stream.isValidating</td><td>Turns on/off implementation specific DTD validation</td><td>Boolean</td><td>False</td><td>No</td></tr> 56 * <tr><td>javax.xml.stream.isNamespaceAware</td><td>Turns on/off namespace processing for XML 1.0 support</td><td>Boolean</td><td>True</td><td>True (required) / False (optional)</td></tr> 57 * <tr><td>javax.xml.stream.isCoalescing</td><td>Requires the processor to coalesce adjacent character data</td><td>Boolean</td><td>False</td><td>Yes</td></tr> 58 * <tr><td>javax.xml.stream.isReplacingEntityReferences</td><td>replace internal entity references with their replacement text and report them as characters</td><td>Boolean</td><td>True</td><td>Yes</td></tr> 59 *<tr><td>javax.xml.stream.isSupportingExternalEntities</td><td>Resolve external parsed entities</td><td>Boolean</td><td>Unspecified</td><td>Yes</td></tr> 60 *<tr><td>javax.xml.stream.supportDTD</td><td>Use this property to request processors that do not support DTDs</td><td>Boolean</td><td>True</td><td>Yes</td></tr> 61 *<tr><td>javax.xml.stream.reporter</td><td>sets/gets the impl of the XMLReporter </td><td>javax.xml.stream.XMLReporter</td><td>Null</td><td>Yes</td></tr> 62 *<tr><td>javax.xml.stream.resolver</td><td>sets/gets the impl of the XMLResolver interface</td><td>javax.xml.stream.XMLResolver</td><td>Null</td><td>Yes</td></tr> 63 *<tr><td>javax.xml.stream.allocator</td><td>sets/gets the impl of the XMLEventAllocator interface</td><td>javax.xml.stream.util.XMLEventAllocator</td><td>Null</td><td>Yes</td></tr> 64 * </tbody> 65 * </table> 66 * 67 * 68 * @version 1.2 69 * @author Copyright (c) 2009, 2015 by Oracle Corporation. All Rights Reserved. 70 * @see XMLOutputFactory 71 * @see XMLEventReader 72 * @see XMLStreamReader 73 * @see EventFilter 74 * @see XMLReporter 75 * @see XMLResolver 76 * @see javax.xml.stream.util.XMLEventAllocator 77 * @since 1.6 78 */ 79 80 public abstract class XMLInputFactory { 81 /** 82 * The property used to turn on/off namespace support, 83 * this is to support XML 1.0 documents, 84 * only the true setting must be supported 85 */ 86 public static final String IS_NAMESPACE_AWARE= 87 "javax.xml.stream.isNamespaceAware"; 88 89 /** 90 * The property used to turn on/off implementation specific validation 91 */ 92 public static final String IS_VALIDATING= 93 "javax.xml.stream.isValidating"; 94 95 /** 96 * The property that requires the parser to coalesce adjacent character data sections 97 */ 98 public static final String IS_COALESCING= 99 "javax.xml.stream.isCoalescing"; 100 101 /** 102 * Requires the parser to replace internal 103 * entity references with their replacement 104 * text and report them as characters 105 */ 106 public static final String IS_REPLACING_ENTITY_REFERENCES= 107 "javax.xml.stream.isReplacingEntityReferences"; 108 109 /** 110 * The property that requires the parser to resolve external parsed entities 111 */ 112 public static final String IS_SUPPORTING_EXTERNAL_ENTITIES= 113 "javax.xml.stream.isSupportingExternalEntities"; 114 115 /** 116 * The property that requires the parser to support DTDs 117 */ 118 public static final String SUPPORT_DTD= 119 "javax.xml.stream.supportDTD"; 120 121 /** 122 * The property used to 123 * set/get the implementation of the XMLReporter interface 124 */ 125 public static final String REPORTER= 126 "javax.xml.stream.reporter"; 127 128 /** 129 * The property used to set/get the implementation of the XMLResolver 130 */ 131 public static final String RESOLVER= 132 "javax.xml.stream.resolver"; 133 134 /** 135 * The property used to set/get the implementation of the allocator 136 */ 137 public static final String ALLOCATOR= 138 "javax.xml.stream.allocator"; 139 140 static final String DEFAULIMPL = "com.sun.xml.internal.stream.XMLInputFactoryImpl"; 141 142 protected XMLInputFactory(){} 143 144 /** 145 * Creates a new instance of the {@code XMLInputFactory} builtin 146 * system-default implementation. 147 * 148 * @return A new instance of the {@code XMLInputFactory} builtin 149 * system-default implementation. 150 * 151 * @since 9 152 */ 153 public static XMLInputFactory newDefaultFactory() { 154 return new XMLInputFactoryImpl(); 155 } 156 157 /** 158 * Creates a new instance of the factory in exactly the same manner as the 159 * {@link #newFactory()} method. 160 * @throws FactoryConfigurationError if an instance of this factory cannot be loaded 161 */ 162 public static XMLInputFactory newInstance() 163 throws FactoryConfigurationError 164 { 165 return FactoryFinder.find(XMLInputFactory.class, DEFAULIMPL); 166 } 167 168 /** 169 * Create a new instance of the factory. 170 * <p> 171 * This static method creates a new factory instance. 172 * This method uses the following ordered lookup procedure to determine 173 * the XMLInputFactory implementation class to load: 174 * 175 * <ul> 176 * <li> 177 * <p>Use the javax.xml.stream.XMLInputFactory system property. 178 * </li> 179 * <li> 180 * <p>Use the configuration file "stax.properties". The file is in standard 181 * {@link java.util.Properties} format and typically located in the 182 * {@code conf} directory of the Java installation. It contains the fully qualified 183 * name of the implementation class with the key being the system property 184 * defined above. 185 * 186 * <p>The stax.properties file is read only once by the implementation 187 * and its values are then cached for future use. If the file does not exist 188 * when the first attempt is made to read from it, no further attempts are 189 * made to check for its existence. It is not possible to change the value 190 * of any property in stax.properties after it has been read for the first time. 191 * 192 * <p> 193 * Use the jaxp configuration file "jaxp.properties". The file is in the same 194 * format as stax.properties and will only be read if stax.properties does 195 * not exist. 196 * </li> 197 * <li> 198 * <p>Use the service-provider loading facility, defined by the 199 * {@link java.util.ServiceLoader} class, to attempt to locate and load an 200 * implementation of the service using the {@linkplain 201 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: 202 * the service-provider loading facility will use the {@linkplain 203 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 204 * to attempt to load the service. If the context class 205 * loader is null, the {@linkplain 206 * ClassLoader#getSystemClassLoader() system class loader} will be used. 207 * </li> 208 * <li> 209 * <p>Otherwise, the {@linkplain #newDefaultFactory() system-default} 210 * implementation is returned. 211 * </li> 212 * </ul> 213 * <p> 214 * Once an application has obtained a reference to a XMLInputFactory it 215 * can use the factory to configure and obtain stream instances. 216 * <p> 217 * Note that this is a new method that replaces the deprecated newInstance() method. 218 * No changes in behavior are defined by this replacement method relative to 219 * the deprecated method. 220 * 221 * @throws FactoryConfigurationError in case of {@linkplain 222 * java.util.ServiceConfigurationError service configuration error} or if 223 * the implementation is not available or cannot be instantiated. 224 */ 225 @Deprecated(since="7") 226 public static XMLInputFactory newFactory() 227 throws FactoryConfigurationError 228 { 229 return FactoryFinder.find(XMLInputFactory.class, DEFAULIMPL); 230 } 231 232 /** 233 * Create a new instance of the factory 234 * 235 * @param factoryId Name of the factory to find, same as 236 * a property name 237 * @param classLoader classLoader to use 238 * @return the factory implementation 239 * @throws FactoryConfigurationError if an instance of this factory cannot be loaded 240 * 241 * @deprecated This method has been deprecated to maintain API consistency. 242 * All newInstance methods have been replaced with corresponding 243 * newFactory methods. The replacement {@link 244 * #newFactory(java.lang.String, java.lang.ClassLoader)} method 245 * defines no changes in behavior. 246 */ 247 @Deprecated(since="7") 248 public static XMLInputFactory newInstance(String factoryId, 249 ClassLoader classLoader) 250 throws FactoryConfigurationError { 251 //do not fallback if given classloader can't find the class, throw exception 252 return FactoryFinder.find(XMLInputFactory.class, factoryId, classLoader, null); 253 } 254 255 /** 256 * Create a new instance of the factory. 257 * If the classLoader argument is null, then the ContextClassLoader is used. 258 * <p> 259 * This method uses the following ordered lookup procedure to determine 260 * the XMLInputFactory implementation class to load: 261 * <ul> 262 * <li> 263 * <p> 264 * Use the value of the system property identified by {@code factoryId}. 265 * </li> 266 * <li> 267 * <p> 268 * Use the configuration file "stax.properties". The file is in standard 269 * {@link java.util.Properties} format and typically located in the 270 * {@code conf} directory of the Java installation. It contains the fully qualified 271 * name of the implementation class with the key being the system property 272 * defined above. 273 * 274 * <p> 275 * The stax.properties file is read only once by the implementation 276 * and its values are then cached for future use. If the file does not exist 277 * when the first attempt is made to read from it, no further attempts are 278 * made to check for its existence. It is not possible to change the value 279 * of any property in stax.properties after it has been read for the first time. 280 * 281 * <p> 282 * Use the jaxp configuration file "jaxp.properties". The file is in the same 283 * format as stax.properties and will only be read if stax.properties does 284 * not exist. 285 * </li> 286 * <li> 287 * <p> 288 * If {@code factoryId} is "javax.xml.stream.XMLInputFactory", 289 * use the service-provider loading facility, defined by the 290 * {@link java.util.ServiceLoader} class, to attempt to {@linkplain 291 * java.util.ServiceLoader#load(java.lang.Class, java.lang.ClassLoader) locate and load} 292 * an implementation of the service using the specified {@code ClassLoader}. 293 * If {@code classLoader} is null, the {@linkplain 294 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism} will apply: 295 * That is, the service-provider loading facility will use the {@linkplain 296 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 297 * to attempt to load the service. If the context class 298 * loader is null, the {@linkplain 299 * ClassLoader#getSystemClassLoader() system class loader} will be used. 300 * </li> 301 * <li> 302 * <p> 303 * Otherwise, throws a {@link FactoryConfigurationError}. 304 * </li> 305 * </ul> 306 * 307 * <p> 308 * Note that this is a new method that replaces the deprecated 309 * {@link #newInstance(java.lang.String, java.lang.ClassLoader) 310 * newInstance(String factoryId, ClassLoader classLoader)} method. 311 * No changes in behavior are defined by this replacement method relative 312 * to the deprecated method. 313 * 314 * 315 * @apiNote The parameter factoryId defined here is inconsistent with that 316 * of other JAXP factories where the first parameter is fully qualified 317 * factory class name that provides implementation of the factory. 318 * 319 * @param factoryId Name of the factory to find, same as 320 * a property name 321 * @param classLoader classLoader to use 322 * @return the factory implementation 323 * @throws FactoryConfigurationError in case of {@linkplain 324 * java.util.ServiceConfigurationError service configuration error} or if 325 * the implementation is not available or cannot be instantiated. 326 * @throws FactoryConfigurationError if an instance of this factory cannot be loaded 327 */ 328 public static XMLInputFactory newFactory(String factoryId, 329 ClassLoader classLoader) 330 throws FactoryConfigurationError { 331 //do not fallback if given classloader can't find the class, throw exception 332 return FactoryFinder.find(XMLInputFactory.class, factoryId, classLoader, null); 333 } 334 335 /** 336 * Create a new XMLStreamReader from a reader 337 * @param reader the XML data to read from 338 * @throws XMLStreamException 339 */ 340 public abstract XMLStreamReader createXMLStreamReader(java.io.Reader reader) 341 throws XMLStreamException; 342 343 /** 344 * Create a new XMLStreamReader from a JAXP source. This method is optional. 345 * @param source the source to read from 346 * @throws UnsupportedOperationException if this method is not 347 * supported by this XMLInputFactory 348 * @throws XMLStreamException 349 */ 350 public abstract XMLStreamReader createXMLStreamReader(Source source) 351 throws XMLStreamException; 352 353 /** 354 * Create a new XMLStreamReader from a java.io.InputStream 355 * @param stream the InputStream to read from 356 * @throws XMLStreamException 357 */ 358 public abstract XMLStreamReader createXMLStreamReader(java.io.InputStream stream) 359 throws XMLStreamException; 360 361 /** 362 * Create a new XMLStreamReader from a java.io.InputStream 363 * @param stream the InputStream to read from 364 * @param encoding the character encoding of the stream 365 * @throws XMLStreamException 366 */ 367 public abstract XMLStreamReader createXMLStreamReader(java.io.InputStream stream, String encoding) 368 throws XMLStreamException; 369 370 /** 371 * Create a new XMLStreamReader from a java.io.InputStream 372 * @param systemId the system ID of the stream 373 * @param stream the InputStream to read from 374 */ 375 public abstract XMLStreamReader createXMLStreamReader(String systemId, java.io.InputStream stream) 376 throws XMLStreamException; 377 378 /** 379 * Create a new XMLStreamReader from a java.io.InputStream 380 * @param systemId the system ID of the stream 381 * @param reader the InputStream to read from 382 */ 383 public abstract XMLStreamReader createXMLStreamReader(String systemId, java.io.Reader reader) 384 throws XMLStreamException; 385 386 /** 387 * Create a new XMLEventReader from a reader 388 * @param reader the XML data to read from 389 * @throws XMLStreamException 390 */ 391 public abstract XMLEventReader createXMLEventReader(java.io.Reader reader) 392 throws XMLStreamException; 393 394 /** 395 * Create a new XMLEventReader from a reader 396 * @param systemId the system ID of the input 397 * @param reader the XML data to read from 398 * @throws XMLStreamException 399 */ 400 public abstract XMLEventReader createXMLEventReader(String systemId, java.io.Reader reader) 401 throws XMLStreamException; 402 403 /** 404 * Create a new XMLEventReader from an XMLStreamReader. After being used 405 * to construct the XMLEventReader instance returned from this method 406 * the XMLStreamReader must not be used. 407 * @param reader the XMLStreamReader to read from (may not be modified) 408 * @return a new XMLEventReader 409 * @throws XMLStreamException 410 */ 411 public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) 412 throws XMLStreamException; 413 414 /** 415 * Create a new XMLEventReader from a JAXP source. 416 * Support of this method is optional. 417 * @param source the source to read from 418 * @throws UnsupportedOperationException if this method is not 419 * supported by this XMLInputFactory 420 */ 421 public abstract XMLEventReader createXMLEventReader(Source source) 422 throws XMLStreamException; 423 424 /** 425 * Create a new XMLEventReader from a java.io.InputStream 426 * @param stream the InputStream to read from 427 * @throws XMLStreamException 428 */ 429 public abstract XMLEventReader createXMLEventReader(java.io.InputStream stream) 430 throws XMLStreamException; 431 432 /** 433 * Create a new XMLEventReader from a java.io.InputStream 434 * @param stream the InputStream to read from 435 * @param encoding the character encoding of the stream 436 * @throws XMLStreamException 437 */ 438 public abstract XMLEventReader createXMLEventReader(java.io.InputStream stream, String encoding) 439 throws XMLStreamException; 440 441 /** 442 * Create a new XMLEventReader from a java.io.InputStream 443 * @param systemId the system ID of the stream 444 * @param stream the InputStream to read from 445 * @throws XMLStreamException 446 */ 447 public abstract XMLEventReader createXMLEventReader(String systemId, java.io.InputStream stream) 448 throws XMLStreamException; 449 450 /** 451 * Create a filtered reader that wraps the filter around the reader 452 * @param reader the reader to filter 453 * @param filter the filter to apply to the reader 454 * @throws XMLStreamException 455 */ 456 public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) 457 throws XMLStreamException; 458 459 /** 460 * Create a filtered event reader that wraps the filter around the event reader 461 * @param reader the event reader to wrap 462 * @param filter the filter to apply to the event reader 463 * @throws XMLStreamException 464 */ 465 public abstract XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter) 466 throws XMLStreamException; 467 468 /** 469 * The resolver that will be set on any XMLStreamReader or XMLEventReader created 470 * by this factory instance. 471 */ 472 public abstract XMLResolver getXMLResolver(); 473 474 /** 475 * The resolver that will be set on any XMLStreamReader or XMLEventReader created 476 * by this factory instance. 477 * @param resolver the resolver to use to resolve references 478 */ 479 public abstract void setXMLResolver(XMLResolver resolver); 480 481 /** 482 * The reporter that will be set on any XMLStreamReader or XMLEventReader created 483 * by this factory instance. 484 */ 485 public abstract XMLReporter getXMLReporter(); 486 487 /** 488 * The reporter that will be set on any XMLStreamReader or XMLEventReader created 489 * by this factory instance. 490 * @param reporter the resolver to use to report non fatal errors 491 */ 492 public abstract void setXMLReporter(XMLReporter reporter); 493 494 /** 495 * Allows the user to set specific feature/property on the underlying 496 * implementation. The underlying implementation is not required to support 497 * every setting of every property in the specification and may use 498 * IllegalArgumentException to signal that an unsupported property may not be 499 * set with the specified value. 500 * <p> 501 * All implementations that implement JAXP 1.5 or newer are required to 502 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. 503 * <ul> 504 * <li> 505 * <p> 506 * Access to external DTDs, external Entity References is restricted to the 507 * protocols specified by the property. If access is denied during parsing 508 * due to the restriction of this property, {@link javax.xml.stream.XMLStreamException} 509 * will be thrown by the {@link javax.xml.stream.XMLStreamReader#next()} or 510 * {@link javax.xml.stream.XMLEventReader#nextEvent()} method. 511 * 512 * </li> 513 * </ul> 514 * @param name The name of the property (may not be null) 515 * @param value The value of the property 516 * @throws java.lang.IllegalArgumentException if the property is not supported 517 */ 518 public abstract void setProperty(java.lang.String name, Object value) 519 throws java.lang.IllegalArgumentException; 520 521 /** 522 * Get the value of a feature/property from the underlying implementation 523 * @param name The name of the property (may not be null) 524 * @return The value of the property 525 * @throws IllegalArgumentException if the property is not supported 526 */ 527 public abstract Object getProperty(java.lang.String name) 528 throws java.lang.IllegalArgumentException; 529 530 531 /** 532 * Query the set of properties that this factory supports. 533 * 534 * @param name The name of the property (may not be null) 535 * @return true if the property is supported and false otherwise 536 */ 537 public abstract boolean isPropertySupported(String name); 538 539 /** 540 * Set a user defined event allocator for events 541 * @param allocator the user defined allocator 542 */ 543 public abstract void setEventAllocator(XMLEventAllocator allocator); 544 545 /** 546 * Gets the allocator used by streams created with this factory 547 */ 548 public abstract XMLEventAllocator getEventAllocator(); 549 550 }