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