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