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