1 /*
   2  * Copyright (c) 2000, 2019, 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 com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
  29 import javax.xml.validation.Schema;
  30 
  31 /**
  32  * Defines a factory API that enables applications to obtain a
  33  * parser that produces DOM object trees from XML documents.
  34  *
  35  * @author Jeff Suttor
  36  * @author Neeraj Bajaj
  37  *
  38  * @since 1.4
  39  */
  40 
  41 public abstract class DocumentBuilderFactory {
  42     private static final String DEFAULT_IMPL =
  43             "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
  44     private boolean validating = false;
  45     private boolean namespaceAware = false;
  46     private boolean whitespace = false;
  47     private boolean expandEntityRef = true;
  48     private boolean ignoreComments = false;
  49     private boolean coalescing = false;
  50 
  51     /**
  52      * Protected constructor to prevent instantiation.
  53      * Use {@link #newInstance()}.
  54      */
  55     protected DocumentBuilderFactory () {
  56     }
  57 
  58     /**
  59      * Creates a new NamespaceAware instance of the {@code DocumentBuilderFactory}
  60      * builtin system-default implementation. Parsers produced by the factory
  61      * instance provides support for XML namespaces by default.
  62      *
  63      * @implSpec
  64      * In addition to creating a factory instance using the same process as
  65      * {@link #newDefaultInstance()}, this method must set NamespaceAware to true.
  66      *
  67      * @return a new instance of the {@code DocumentBuilderFactory} builtin
  68      *         system-default implementation.
  69      *
  70      * @since 13
  71      */
  72     public static DocumentBuilderFactory newDefaultNSInstance() {
  73         return makeNSAware(new DocumentBuilderFactoryImpl());
  74     }
  75 
  76     /**
  77      * Creates a new NamespaceAware instance of a {@code DocumentBuilderFactory}.
  78      * Parsers produced by the factory instance provides support for XML namespaces
  79      * by default.
  80      *
  81      * @implSpec
  82      * In addition to creating a factory instance using the same process as
  83      * {@link #newInstance()}, this method must set NamespaceAware to true.
  84      *
  85      * @return a new instance of a {@code DocumentBuilderFactory}
  86      *
  87      * @throws FactoryConfigurationError in case of {@linkplain
  88      *         java.util.ServiceConfigurationError service configuration error}
  89      *         or if the implementation is not available or cannot be instantiated.
  90      *
  91      * @since 13
  92      */
  93     public static DocumentBuilderFactory newNSInstance() {
  94         return makeNSAware(FactoryFinder.find(DocumentBuilderFactory.class, DEFAULT_IMPL));
  95     }
  96 
  97     /**
  98      * Creates a new NamespaceAware instance of a {@code DocumentBuilderFactory}
  99      * from the class name. Parsers produced by the factory instance provides
 100      * support for XML namespaces by default.
 101      *
 102      * @implSpec
 103      * In addition to creating a factory instance using the same process as
 104      * {@link #newInstance(java.lang.String, java.lang.ClassLoader)}, this method
 105      * must set NamespaceAware to true.
 106      *
 107      * @param factoryClassName a fully qualified factory class name that provides
 108      *                         implementation of
 109      *                         {@code javax.xml.parsers.DocumentBuilderFactory}.
 110      *
 111      * @param classLoader the {@code ClassLoader} used to load the factory class.
 112      *                    If it is {@code null}, the current {@code Thread}'s
 113      *                    context classLoader is used to load the factory class.
 114      *
 115      * @return a new instance of a {@code DocumentBuilderFactory}
 116      *
 117      * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or
 118      *                                   the factory class cannot be loaded, instantiated.
 119      *
 120      * @since 13
 121      */
 122     public static DocumentBuilderFactory newNSInstance(String factoryClassName,
 123             ClassLoader classLoader) {
 124             return makeNSAware(FactoryFinder.newInstance(
 125                     DocumentBuilderFactory.class, factoryClassName, classLoader, false));
 126     }
 127 
 128     /**
 129      * Creates a new instance of the {@code DocumentBuilderFactory} builtin
 130      * system-default implementation.
 131      *
 132      * @return A new instance of the {@code DocumentBuilderFactory} builtin
 133      *         system-default implementation.
 134      *
 135      * @since 9
 136      */
 137     public static DocumentBuilderFactory newDefaultInstance() {
 138         return new DocumentBuilderFactoryImpl();
 139     }
 140 
 141     /**
 142      * Obtain a new instance of a
 143      * {@code DocumentBuilderFactory}. This static method creates
 144      * a new factory instance.
 145      * This method uses the following ordered lookup procedure to determine
 146      * the {@code DocumentBuilderFactory} implementation class to
 147      * load:
 148      * <ul>
 149      * <li>
 150      * Use the {@code javax.xml.parsers.DocumentBuilderFactory} system
 151      * property.
 152      * </li>
 153      * <li>
 154      * <p>
 155      * Use the configuration file "jaxp.properties". The file is in standard
 156      * {@link java.util.Properties} format and typically located in the
 157      * {@code conf} directory of the Java installation. It contains the fully qualified
 158      * name of the implementation class with the key being the system property
 159      * defined above.
 160      * <p>
 161      * The jaxp.properties file is read only once by the JAXP implementation
 162      * and its values are then cached for future use.  If the file does not exist
 163      * when the first attempt is made to read from it, no further attempts are
 164      * made to check for its existence.  It is not possible to change the value
 165      * of any property in jaxp.properties after it has been read for the first time.
 166      * </li>
 167      * <li>
 168      * <p>
 169      * Use the service-provider loading facility, defined by the
 170      * {@link java.util.ServiceLoader} class, to attempt to locate and load an
 171      * implementation of the service using the {@linkplain
 172      * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}:
 173      * the service-provider loading facility will use the {@linkplain
 174      * java.lang.Thread#getContextClassLoader() current thread's context class loader}
 175      * to attempt to load the service. If the context class
 176      * loader is null, the {@linkplain
 177      * ClassLoader#getSystemClassLoader() system class loader} will be used.
 178      * </li>
 179      * <li>
 180      * <p>
 181      * Otherwise, the {@linkplain #newDefaultInstance() system-default}
 182      * implementation is returned.
 183      * </li>
 184      * </ul>
 185      *
 186      * <p>
 187      * Once an application has obtained a reference to a
 188      * {@code DocumentBuilderFactory} it can use the factory to
 189      * configure and obtain parser instances.
 190      *
 191      *
 192      * <h4>Tip for Trouble-shooting</h4>
 193      * <p>
 194      * Setting the {@code jaxp.debug} system property will cause
 195      * this method to print a lot of debug messages
 196      * to {@code System.err} about what it is doing and where it is looking at.
 197      *
 198      * <p>
 199      * If you have problems loading {@link DocumentBuilder}s, try:
 200      * <pre>
 201      * java -Djaxp.debug=1 YourProgram ....
 202      * </pre>
 203      *
 204      * @return New instance of a {@code DocumentBuilderFactory}
 205      *
 206      * @throws FactoryConfigurationError in case of {@linkplain
 207      * java.util.ServiceConfigurationError service configuration error} or if
 208      * the implementation is not available or cannot be instantiated.
 209      */
 210     public static DocumentBuilderFactory newInstance() {
 211         return FactoryFinder.find(
 212                 /* The default property name according to the JAXP spec */
 213                 DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
 214                 /* The fallback implementation class name */
 215                 DEFAULT_IMPL);
 216     }
 217 
 218     /**
 219      * Obtain a new instance of a {@code DocumentBuilderFactory} from class name.
 220      * This function is useful when there are multiple providers in the classpath.
 221      * It gives more control to the application as it can specify which provider
 222      * should be loaded.
 223      *
 224      * <p>Once an application has obtained a reference to a {@code DocumentBuilderFactory}
 225      * it can use the factory to configure and obtain parser instances.
 226      *
 227      *
 228      * <h4>Tip for Trouble-shooting</h4>
 229      * <p>Setting the {@code jaxp.debug} system property will cause
 230      * this method to print a lot of debug messages
 231      * to {@code System.err} about what it is doing and where it is looking at.
 232      *
 233      * <p> If you have problems try:
 234      * <pre>
 235      * java -Djaxp.debug=1 YourProgram ....
 236      * </pre>
 237      *
 238      * @param factoryClassName fully qualified factory class name that provides
 239      *        implementation of {@code javax.xml.parsers.DocumentBuilderFactory}.
 240      *
 241      * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null}
 242      *                     current {@code Thread}'s context classLoader is used to load the factory class.
 243      *
 244      * @return New instance of a {@code DocumentBuilderFactory}
 245      *
 246      * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or
 247      *                                   the factory class cannot be loaded, instantiated.
 248      *
 249      * @see #newInstance()
 250      *
 251      * @since 1.6
 252      */
 253     public static DocumentBuilderFactory newInstance(String factoryClassName, ClassLoader classLoader){
 254             //do not fallback if given classloader can't find the class, throw exception
 255             return FactoryFinder.newInstance(DocumentBuilderFactory.class,
 256                         factoryClassName, classLoader, false);
 257     }
 258 
 259     private static DocumentBuilderFactory makeNSAware(DocumentBuilderFactory dbf) {
 260         dbf.setNamespaceAware(true);
 261         return dbf;
 262     }
 263 
 264     /**
 265      * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder}
 266      * using the currently configured parameters.
 267      *
 268      * @return A new instance of a DocumentBuilder.
 269      *
 270      * @throws ParserConfigurationException if a DocumentBuilder
 271      *   cannot be created which satisfies the configuration requested.
 272      */
 273 
 274     public abstract DocumentBuilder newDocumentBuilder()
 275         throws ParserConfigurationException;
 276 
 277 
 278     /**
 279      * Specifies that the parser produced by this code will
 280      * provide support for XML namespaces. By default the value of this is set
 281      * to {@code false}
 282      *
 283      * @param awareness true if the parser produced will provide support
 284      *                  for XML namespaces; false otherwise.
 285      */
 286 
 287     public void setNamespaceAware(boolean awareness) {
 288         this.namespaceAware = awareness;
 289     }
 290 
 291     /**
 292      * Specifies that the parser produced by this code will
 293      * validate documents as they are parsed. By default the value of this
 294      * is set to {@code false}.
 295      *
 296      * <p>
 297      * Note that "the validation" here means
 298      * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating
 299      * parser</a> as defined in the XML recommendation.
 300      * In other words, it essentially just controls the DTD validation.
 301      * (except the legacy two properties defined in JAXP 1.2.)
 302      *
 303      * <p>
 304      * To use modern schema languages such as W3C XML Schema or
 305      * RELAX NG instead of DTD, you can configure your parser to be
 306      * a non-validating parser by leaving the {@link #setValidating(boolean)}
 307      * method {@code false}, then use the {@link #setSchema(Schema)}
 308      * method to associate a schema to a parser.
 309      *
 310      * @param validating true if the parser produced will validate documents
 311      *                   as they are parsed; false otherwise.
 312      */
 313 
 314     public void setValidating(boolean validating) {
 315         this.validating = validating;
 316     }
 317 
 318     /**
 319      * Specifies that the parsers created by this  factory must eliminate
 320      * whitespace in element content (sometimes known loosely as
 321      * 'ignorable whitespace') when parsing XML documents (see XML Rec
 322      * 2.10). Note that only whitespace which is directly contained within
 323      * element content that has an element only content model (see XML
 324      * Rec 3.2.1) will be eliminated. Due to reliance on the content model
 325      * this setting requires the parser to be in validating mode. By default
 326      * the value of this is set to {@code false}.
 327      *
 328      * @param whitespace true if the parser created must eliminate whitespace
 329      *                   in the element content when parsing XML documents;
 330      *                   false otherwise.
 331      */
 332 
 333     public void setIgnoringElementContentWhitespace(boolean whitespace) {
 334         this.whitespace = whitespace;
 335     }
 336 
 337     /**
 338      * Specifies that the parser produced by this code will
 339      * expand entity reference nodes. By default the value of this is set to
 340      * {@code true}
 341      *
 342      * @param expandEntityRef true if the parser produced will expand entity
 343      *                        reference nodes; false otherwise.
 344      */
 345 
 346     public void setExpandEntityReferences(boolean expandEntityRef) {
 347         this.expandEntityRef = expandEntityRef;
 348     }
 349 
 350     /**
 351      * Specifies that the parser produced by this code will
 352      * ignore comments. By default the value of this is set to {@code false}.
 353      *
 354      * @param ignoreComments {@code boolean} value to ignore comments during processing
 355      */
 356 
 357     public void setIgnoringComments(boolean ignoreComments) {
 358         this.ignoreComments = ignoreComments;
 359     }
 360 
 361     /**
 362      * Specifies that the parser produced by this code will
 363      * convert CDATA nodes to Text nodes and append it to the
 364      * adjacent (if any) text node. By default the value of this is set to
 365      * {@code false}
 366      *
 367      * @param coalescing  true if the parser produced will convert CDATA nodes
 368      *                    to Text nodes and append it to the adjacent (if any)
 369      *                    text node; false otherwise.
 370      */
 371 
 372     public void setCoalescing(boolean coalescing) {
 373         this.coalescing = coalescing;
 374     }
 375 
 376     /**
 377      * Indicates whether or not the factory is configured to produce
 378      * parsers which are namespace aware.
 379      *
 380      * @return  true if the factory is configured to produce parsers which
 381      *          are namespace aware; false otherwise.
 382      */
 383 
 384     public boolean isNamespaceAware() {
 385         return namespaceAware;
 386     }
 387 
 388     /**
 389      * Indicates whether or not the factory is configured to produce
 390      * parsers which validate the XML content during parse.
 391      *
 392      * @return  true if the factory is configured to produce parsers
 393      *          which validate the XML content during parse; false otherwise.
 394      */
 395 
 396     public boolean isValidating() {
 397         return validating;
 398     }
 399 
 400     /**
 401      * Indicates whether or not the factory is configured to produce
 402      * parsers which ignore ignorable whitespace in element content.
 403      *
 404      * @return  true if the factory is configured to produce parsers
 405      *          which ignore ignorable whitespace in element content;
 406      *          false otherwise.
 407      */
 408 
 409     public boolean isIgnoringElementContentWhitespace() {
 410         return whitespace;
 411     }
 412 
 413     /**
 414      * Indicates whether or not the factory is configured to produce
 415      * parsers which expand entity reference nodes.
 416      *
 417      * @return  true if the factory is configured to produce parsers
 418      *          which expand entity reference nodes; false otherwise.
 419      */
 420 
 421     public boolean isExpandEntityReferences() {
 422         return expandEntityRef;
 423     }
 424 
 425     /**
 426      * Indicates whether or not the factory is configured to produce
 427      * parsers which ignores comments.
 428      *
 429      * @return  true if the factory is configured to produce parsers
 430      *          which ignores comments; false otherwise.
 431      */
 432 
 433     public boolean isIgnoringComments() {
 434         return ignoreComments;
 435     }
 436 
 437     /**
 438      * Indicates whether or not the factory is configured to produce
 439      * parsers which converts CDATA nodes to Text nodes and appends it to
 440      * the adjacent (if any) Text node.
 441      *
 442      * @return  true if the factory is configured to produce parsers
 443      *          which converts CDATA nodes to Text nodes and appends it to
 444      *          the adjacent (if any) Text node; false otherwise.
 445      */
 446 
 447     public boolean isCoalescing() {
 448         return coalescing;
 449     }
 450 
 451     /**
 452      * Allows the user to set specific attributes on the underlying
 453      * implementation.
 454      * <p>
 455      * All implementations that implement JAXP 1.5 or newer are required to
 456      * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
 457      * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
 458      *
 459      * <ul>
 460      *   <li>
 461      *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
 462      *      restricts the access to external DTDs, external Entity References to the
 463      *      protocols specified by the property.
 464      *      If access is denied during parsing due to the restriction of this property,
 465      *      {@link org.xml.sax.SAXException} will be thrown by the parse methods defined by
 466      *      {@link javax.xml.parsers.DocumentBuilder}.
 467      *   </li>
 468      *   <li>
 469      *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
 470      *      restricts the access to external Schema set by the schemaLocation attribute to
 471      *      the protocols specified by the property.  If access is denied during parsing
 472      *      due to the restriction of this property, {@link org.xml.sax.SAXException}
 473      *      will be thrown by the parse methods defined by
 474      *      {@link javax.xml.parsers.DocumentBuilder}.
 475      *   </li>
 476      * </ul>
 477      *
 478      * @param name The name of the attribute.
 479      * @param value The value of the attribute.
 480      *
 481      * @throws IllegalArgumentException thrown if the underlying
 482      *   implementation doesn't recognize the attribute.
 483      */
 484     public abstract void setAttribute(String name, Object value)
 485                 throws IllegalArgumentException;
 486 
 487     /**
 488      * Allows the user to retrieve specific attributes on the underlying
 489      * implementation.
 490      *
 491      * @param name The name of the attribute.
 492      *
 493      * @return value The value of the attribute.
 494      *
 495      * @throws IllegalArgumentException thrown if the underlying
 496      *   implementation doesn't recognize the attribute.
 497      */
 498     public abstract Object getAttribute(String name)
 499                 throws IllegalArgumentException;
 500 
 501     /**
 502      * Set a feature for this {@code DocumentBuilderFactory}
 503      * and {@code DocumentBuilder}s created by this factory.
 504      *
 505      * <p>
 506      * Feature names are fully qualified {@link java.net.URI}s.
 507      * Implementations may define their own features.
 508      * A {@link ParserConfigurationException} is thrown if this {@code DocumentBuilderFactory} or the
 509      * {@code DocumentBuilder}s it creates cannot support the feature.
 510      * It is possible for a {@code DocumentBuilderFactory} to expose a feature value but be unable to change its state.
 511      *
 512      *
 513      * <p>
 514      * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
 515      * When the feature is:
 516      * <ul>
 517      *   <li>
 518      *     {@code true}: the implementation will limit XML processing to conform to implementation limits.
 519      *     Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources.
 520      *     If XML processing is limited for security reasons, it will be reported via a call to the registered
 521      *    {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}.
 522      *     See {@link  DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}.
 523      *   </li>
 524      *   <li>
 525      *     {@code false}: the implementation will processing XML according to the XML specifications without
 526      *     regard to possible implementation limits.
 527      *   </li>
 528      * </ul>
 529      *
 530      * @param name Feature name.
 531      * @param value Is feature state {@code true} or {@code false}.
 532      *
 533      * @throws ParserConfigurationException if this {@code DocumentBuilderFactory} or the {@code DocumentBuilder}s
 534      *   it creates cannot support this feature.
 535      * @throws NullPointerException If the {@code name} parameter is null.
 536      * @since 1.5
 537      */
 538     public abstract void setFeature(String name, boolean value)
 539             throws ParserConfigurationException;
 540 
 541     /**
 542      * Get the state of the named feature.
 543      *
 544      * <p>
 545      * Feature names are fully qualified {@link java.net.URI}s.
 546      * Implementations may define their own features.
 547      * An {@link ParserConfigurationException} is thrown if this {@code DocumentBuilderFactory} or the
 548      * {@code DocumentBuilder}s it creates cannot support the feature.
 549      * It is possible for an {@code DocumentBuilderFactory} to expose a feature value but be unable to change its state.
 550      *
 551      * @param name Feature name.
 552      *
 553      * @return State of the named feature.
 554      *
 555      * @throws ParserConfigurationException if this {@code DocumentBuilderFactory}
 556      *   or the {@code DocumentBuilder}s it creates cannot support this feature.
 557      * @since 1.5
 558      */
 559     public abstract boolean getFeature(String name)
 560             throws ParserConfigurationException;
 561 
 562 
 563     /**
 564      * Gets the {@link Schema} object specified through
 565      * the {@link #setSchema(Schema schema)} method.
 566      *
 567      * @return
 568      *      the {@link Schema} object that was last set through
 569      *      the {@link #setSchema(Schema)} method, or null
 570      *      if the method was not invoked since a {@link DocumentBuilderFactory}
 571      *      is created.
 572      *
 573      * @throws UnsupportedOperationException When implementation does not
 574      *   override this method.
 575      *
 576      * @since 1.5
 577      */
 578     public Schema getSchema() {
 579         throw new UnsupportedOperationException(
 580             "This parser does not support specification \""
 581             + this.getClass().getPackage().getSpecificationTitle()
 582             + "\" version \""
 583             + this.getClass().getPackage().getSpecificationVersion()
 584             + "\""
 585             );
 586 
 587     }
 588 
 589     /**
 590      * Set the {@link Schema} to be used by parsers created
 591      * from this factory.
 592      *
 593      * <p>
 594      * When a {@link Schema} is non-null, a parser will use a validator
 595      * created from it to validate documents before it passes information
 596      * down to the application.
 597      *
 598      * <p>When errors are found by the validator, the parser is responsible
 599      * to report them to the user-specified {@link org.xml.sax.ErrorHandler}
 600      * (or if the error handler is not set, ignore them or throw them), just
 601      * like any other errors found by the parser itself.
 602      * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
 603      * is set, it must receive those errors, and if not, they must be
 604      * treated according to the implementation specific
 605      * default error handling rules.
 606      *
 607      * <p>
 608      * A validator may modify the outcome of a parse (for example by
 609      * adding default values that were missing in documents), and a parser
 610      * is responsible to make sure that the application will receive
 611      * modified DOM trees.
 612      *
 613      * <p>
 614      * Initially, null is set as the {@link Schema}.
 615      *
 616      * <p>
 617      * This processing will take effect even if
 618      * the {@link #isValidating()} method returns {@code false}.
 619      *
 620      * <p>It is an error to use
 621      * the {@code http://java.sun.com/xml/jaxp/properties/schemaSource}
 622      * property and/or the {@code http://java.sun.com/xml/jaxp/properties/schemaLanguage}
 623      * property in conjunction with a {@link Schema} object.
 624      * Such configuration will cause a {@link ParserConfigurationException}
 625      * exception when the {@link #newDocumentBuilder()} is invoked.
 626      *
 627      *
 628      * <h4>Note for implementors</h4>
 629      *
 630      * <p>
 631      * A parser must be able to work with any {@link Schema}
 632      * implementation. However, parsers and schemas are allowed
 633      * to use implementation-specific custom mechanisms
 634      * as long as they yield the result described in the specification.
 635      *
 636      *
 637      * @param schema {@code Schema} to use or {@code null}
 638      *   to remove a schema.
 639      *
 640      * @throws UnsupportedOperationException When implementation does not
 641      *   override this method.
 642      *
 643      * @since 1.5
 644      */
 645     public void setSchema(Schema schema) {
 646         throw new UnsupportedOperationException(
 647             "This parser does not support specification \""
 648             + this.getClass().getPackage().getSpecificationTitle()
 649             + "\" version \""
 650             + this.getClass().getPackage().getSpecificationVersion()
 651             + "\""
 652             );
 653     }
 654 
 655 
 656 
 657     /**
 658      * Set state of XInclude processing.
 659      *
 660      * <p>If XInclude markup is found in the document instance, should it be
 661      * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
 662      * XML Inclusions (XInclude) Version 1.0</a>.
 663      *
 664      * <p>XInclude processing defaults to {@code false}.
 665      *
 666      * @param state Set XInclude processing to {@code true} or
 667      *   {@code false}
 668      *
 669      * @throws UnsupportedOperationException When implementation does not
 670      *   override this method.
 671      *
 672      * @since 1.5
 673      */
 674     public void setXIncludeAware(final boolean state) {
 675         if (state) {
 676             throw new UnsupportedOperationException(" setXIncludeAware " +
 677                 "is not supported on this JAXP" +
 678                 " implementation or earlier: " + this.getClass());
 679         }
 680     }
 681 
 682     /**
 683      * Get state of XInclude processing.
 684      *
 685      * @return current state of XInclude processing
 686      *
 687      * @throws UnsupportedOperationException When implementation does not
 688      *   override this method.
 689      *
 690      * @since 1.5
 691      */
 692     public boolean isXIncludeAware() {
 693         throw new UnsupportedOperationException(
 694             "This parser does not support specification \""
 695             + this.getClass().getPackage().getSpecificationTitle()
 696             + "\" version \""
 697             + this.getClass().getPackage().getSpecificationVersion()
 698             + "\""
 699             );
 700     }
 701 }