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