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