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