1/* 2 * Copyright (c) 2000, 2015, 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 26package javax.xml.parsers; 27 28import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; 29import javax.xml.validation.Schema; 30import org.xml.sax.SAXException; 31import org.xml.sax.SAXNotRecognizedException; 32import org.xml.sax.SAXNotSupportedException; 33 34/** 35 * Defines a factory API that enables applications to configure and 36 * obtain a SAX based parser to parse XML documents. 37 * 38 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> 39 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> 40 * 41 * @since 1.4 42 */ 43public abstract class SAXParserFactory { 44 45 /** 46 * Should Parsers be validating? 47 */ 48 private boolean validating = false; 49 50 /** 51 * Should Parsers be namespace aware? 52 */ 53 private boolean namespaceAware = false; 54 55 /** 56 * Protected constructor to force use of {@link #newInstance()}. 57 */ 58 protected SAXParserFactory () { 59 60 } 61 62 /** 63 * Creates a new instance of the {@code SAXParserFactory} builtin 64 * system-default implementation. 65 * 66 * @return A new instance of the {@code SAXParserFactory} builtin 67 * system-default implementation. 68 * 69 * @since 9 70 */ 71 public static SAXParserFactory newDefaultInstance() { 72 return new SAXParserFactoryImpl(); 73 } 74 75 /** 76 * Obtain a new instance of a {@code SAXParserFactory}. This 77 * static method creates a new factory instance 78 * This method uses the following ordered lookup procedure to determine 79 * the {@code SAXParserFactory} implementation class to 80 * load: 81 * <ul> 82 * <li> 83 * Use the {@code javax.xml.parsers.SAXParserFactory} system 84 * property. 85 * </li> 86 * <li> 87 * <p> 88 * Use the configuration file "jaxp.properties". The file is in standard 89 * {@link java.util.Properties} format and typically located in the 90 * {@code conf} directory of the Java installation. It contains the fully qualified 91 * name of the implementation class with the key being the system property 92 * defined above. 93 * <p> 94 * The jaxp.properties file is read only once by the JAXP implementation 95 * and its values are then cached for future use. If the file does not exist 96 * when the first attempt is made to read from it, no further attempts are 97 * made to check for its existence. It is not possible to change the value 98 * of any property in jaxp.properties after it has been read for the first time. 99 * </li> 100 * <li> 101 * <p> 102 * Use the service-provider loading facility, defined by the 103 * {@link java.util.ServiceLoader} class, to attempt to locate and load an 104 * implementation of the service using the {@linkplain 105 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: 106 * the service-provider loading facility will use the {@linkplain 107 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 108 * to attempt to load the service. If the context class 109 * loader is null, the {@linkplain 110 * ClassLoader#getSystemClassLoader() system class loader} will be used. 111 * </li> 112 * <li> 113 * <p> 114 * Otherwise, the {@linkplain #newDefaultInstance() system-default} 115 * implementation is returned. 116 * </li> 117 * </ul> 118 * 119 * <p> 120 * Once an application has obtained a reference to a 121 * {@code SAXParserFactory} it can use the factory to 122 * configure and obtain parser instances. 123 * 124 * 125 * 126 * <h2>Tip for Trouble-shooting</h2> 127 * <p> 128 * Setting the {@code jaxp.debug} system property will cause 129 * this method to print a lot of debug messages 130 * to {@code System.err} about what it is doing and where it is looking at. 131 * 132 * <p> 133 * If you have problems loading {@link SAXParser}s, try: 134 * <pre> 135 * java -Djaxp.debug=1 YourProgram .... 136 * </pre> 137 * 138 * 139 * @return A new instance of a SAXParserFactory. 140 * 141 * @throws FactoryConfigurationError in case of {@linkplain 142 * java.util.ServiceConfigurationError service configuration error} or if 143 * the implementation is not available or cannot be instantiated. 144 */ 145 146 public static SAXParserFactory newInstance() { 147 return FactoryFinder.find( 148 /* The default property name according to the JAXP spec */ 149 SAXParserFactory.class, 150 /* The fallback implementation class name */ 151 "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); 152 } 153 154 /** 155 * Obtain a new instance of a {@code SAXParserFactory} from class name. 156 * This function is useful when there are multiple providers in the classpath. 157 * It gives more control to the application as it can specify which provider 158 * should be loaded. 159 * 160 * <p>Once an application has obtained a reference to a {@code SAXParserFactory} 161 * it can use the factory to configure and obtain parser instances. 162 * 163 * 164 * <h2>Tip for Trouble-shooting</h2> 165 * <p>Setting the {@code jaxp.debug} system property will cause 166 * this method to print a lot of debug messages 167 * to {@code System.err} about what it is doing and where it is looking at. 168 * 169 * <p> 170 * If you have problems, try: 171 * <pre> 172 * java -Djaxp.debug=1 YourProgram .... 173 * </pre> 174 * 175 * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.parsers.SAXParserFactory}. 176 * 177 * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} 178 * current {@code Thread}'s context classLoader is used to load the factory class. 179 * 180 * @return New instance of a {@code SAXParserFactory} 181 * 182 * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or 183 * the factory class cannot be loaded, instantiated. 184 * 185 * @see #newInstance() 186 * 187 * @since 1.6 188 */ 189 public static SAXParserFactory newInstance(String factoryClassName, ClassLoader classLoader){ 190 //do not fallback if given classloader can't find the class, throw exception 191 return FactoryFinder.newInstance(SAXParserFactory.class, 192 factoryClassName, classLoader, false); 193 } 194 195 /** 196 * Creates a new instance of a SAXParser using the currently 197 * configured factory parameters. 198 * 199 * @return A new instance of a SAXParser. 200 * 201 * @throws ParserConfigurationException if a parser cannot 202 * be created which satisfies the requested configuration. 203 * @throws SAXException for SAX errors. 204 */ 205 206 public abstract SAXParser newSAXParser() 207 throws ParserConfigurationException, SAXException; 208 209 210 /** 211 * Specifies that the parser produced by this code will 212 * provide support for XML namespaces. By default the value of this is set 213 * to {@code false}. 214 * 215 * @param awareness true if the parser produced by this code will 216 * provide support for XML namespaces; false otherwise. 217 */ 218 219 public void setNamespaceAware(boolean awareness) { 220 this.namespaceAware = awareness; 221 } 222 223 /** 224 * Specifies that the parser produced by this code will 225 * validate documents as they are parsed. By default the value of this is 226 * set to {@code false}. 227 * 228 * <p> 229 * Note that "the validation" here means 230 * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating 231 * parser</a> as defined in the XML recommendation. 232 * In other words, it essentially just controls the DTD validation. 233 * (except the legacy two properties defined in JAXP 1.2.) 234 * 235 * <p> 236 * To use modern schema languages such as W3C XML Schema or 237 * RELAX NG instead of DTD, you can configure your parser to be 238 * a non-validating parser by leaving the {@link #setValidating(boolean)} 239 * method {@code false}, then use the {@link #setSchema(Schema)} 240 * method to associate a schema to a parser. 241 * 242 * @param validating true if the parser produced by this code will 243 * validate documents as they are parsed; false otherwise. 244 */ 245 246 public void setValidating(boolean validating) { 247 this.validating = validating; 248 } 249 250 /** 251 * Indicates whether or not the factory is configured to produce 252 * parsers which are namespace aware. 253 * 254 * @return true if the factory is configured to produce 255 * parsers which are namespace aware; false otherwise. 256 */ 257 258 public boolean isNamespaceAware() { 259 return namespaceAware; 260 } 261 262 /** 263 * Indicates whether or not the factory is configured to produce 264 * parsers which validate the XML content during parse. 265 * 266 * @return true if the factory is configured to produce parsers which validate 267 * the XML content during parse; false otherwise. 268 */ 269 270 public boolean isValidating() { 271 return validating; 272 } 273 274 /** 275 * Sets the particular feature in the underlying implementation of 276 * org.xml.sax.XMLReader. 277 * A list of the core features and properties can be found at 278 * <a href="http://www.saxproject.org/">http://www.saxproject.org/</a> 279 * 280 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. 281 * When the feature is 282 * <ul> 283 * <li> 284 * {@code true}: the implementation will limit XML processing to conform to implementation limits. 285 * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. 286 * If XML processing is limited for security reasons, it will be reported via a call to the registered 287 * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. 288 * See {@link SAXParser} {@code parse} methods for handler specification. 289 * </li> 290 * <li> 291 * When the feature is {@code false}, the implementation will processing XML according to the XML specifications without 292 * regard to possible implementation limits. 293 * </li> 294 * </ul> 295 * 296 * @param name The name of the feature to be set. 297 * @param value The value of the feature to be set. 298 * 299 * @throws ParserConfigurationException if a parser cannot 300 * be created which satisfies the requested configuration. 301 * @throws SAXNotRecognizedException When the underlying XMLReader does 302 * not recognize the property name. 303 * @throws SAXNotSupportedException When the underlying XMLReader 304 * recognizes the property name but doesn't support the 305 * property. 306 * @throws NullPointerException If the {@code name} parameter is null. 307 * 308 * @see org.xml.sax.XMLReader#setFeature 309 */ 310 public abstract void setFeature(String name, boolean value) 311 throws ParserConfigurationException, SAXNotRecognizedException, 312 SAXNotSupportedException; 313 314 /** 315 * 316 * Returns the particular property requested for in the underlying 317 * implementation of org.xml.sax.XMLReader. 318 * 319 * @param name The name of the property to be retrieved. 320 * 321 * @return Value of the requested property. 322 * 323 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration. 324 * @throws SAXNotRecognizedException When the underlying XMLReader does not recognize the property name. 325 * @throws SAXNotSupportedException When the underlying XMLReader recognizes the property name but doesn't support the property. 326 * 327 * @see org.xml.sax.XMLReader#getProperty 328 */ 329 public abstract boolean getFeature(String name) 330 throws ParserConfigurationException, SAXNotRecognizedException, 331 SAXNotSupportedException; 332 333 334 /** 335 * Gets the {@link Schema} object specified through 336 * the {@link #setSchema(Schema schema)} method. 337 * 338 * 339 * @throws UnsupportedOperationException When implementation does not 340 * override this method 341 * 342 * @return 343 * the {@link Schema} object that was last set through 344 * the {@link #setSchema(Schema)} method, or null 345 * if the method was not invoked since a {@link SAXParserFactory} 346 * is created. 347 * 348 * @since 1.5 349 */ 350 public Schema getSchema() { 351 throw new UnsupportedOperationException( 352 "This parser does not support specification \"" 353 + this.getClass().getPackage().getSpecificationTitle() 354 + "\" version \"" 355 + this.getClass().getPackage().getSpecificationVersion() 356 + "\"" 357 ); 358 } 359 360 /** 361 * Set the {@link Schema} to be used by parsers created 362 * from this factory. 363 * 364 * <p>When a {@link Schema} is non-null, a parser will use a validator 365 * created from it to validate documents before it passes information 366 * down to the application. 367 * 368 * <p>When warnings/errors/fatal errors are found by the validator, the parser must 369 * handle them as if those errors were found by the parser itself. 370 * In other words, if the user-specified {@link org.xml.sax.ErrorHandler} 371 * is set, it must receive those errors, and if not, they must be 372 * treated according to the implementation specific 373 * default error handling rules. 374 * 375 * <p>A validator may modify the SAX event stream (for example by 376 * adding default values that were missing in documents), and a parser 377 * is responsible to make sure that the application will receive 378 * those modified event stream. 379 * 380 * <p>Initially, {@code null} is set as the {@link Schema}. 381 * 382 * <p>This processing will take effect even if 383 * the {@link #isValidating()} method returns {@code false}. 384 * 385 * <p>It is an error to use 386 * the {@code http://java.sun.com/xml/jaxp/properties/schemaSource} 387 * property and/or the {@code http://java.sun.com/xml/jaxp/properties/schemaLanguage} 388 * property in conjunction with a non-null {@link Schema} object. 389 * Such configuration will cause a {@link SAXException} 390 * exception when those properties are set on a {@link SAXParser}. 391 * 392 * <h3>Note for implementors</h3> 393 * <p> 394 * A parser must be able to work with any {@link Schema} 395 * implementation. However, parsers and schemas are allowed 396 * to use implementation-specific custom mechanisms 397 * as long as they yield the result described in the specification. 398 * 399 * @param schema {@code Schema} to use, {@code null} to remove a schema. 400 * 401 * @throws UnsupportedOperationException When implementation does not 402 * override this method 403 * 404 * @since 1.5 405 */ 406 public void setSchema(Schema schema) { 407 throw new UnsupportedOperationException( 408 "This parser does not support specification \"" 409 + this.getClass().getPackage().getSpecificationTitle() 410 + "\" version \"" 411 + this.getClass().getPackage().getSpecificationVersion() 412 + "\"" 413 ); 414 } 415 416 /** 417 * Set state of XInclude processing. 418 * 419 * <p>If XInclude markup is found in the document instance, should it be 420 * processed as specified in <a href="http://www.w3.org/TR/xinclude/"> 421 * XML Inclusions (XInclude) Version 1.0</a>. 422 * 423 * <p>XInclude processing defaults to {@code false}. 424 * 425 * @param state Set XInclude processing to {@code true} or 426 * {@code false} 427 * 428 * @throws UnsupportedOperationException When implementation does not 429 * override this method 430 * 431 * @since 1.5 432 */ 433 public void setXIncludeAware(final boolean state) { 434 if (state) { 435 throw new UnsupportedOperationException(" setXIncludeAware " + 436 "is not supported on this JAXP" + 437 " implementation or earlier: " + this.getClass()); 438 } 439 } 440 441 /** 442 * Get state of XInclude processing. 443 * 444 * @return current state of XInclude processing 445 * 446 * @throws UnsupportedOperationException When implementation does not 447 * override this method 448 * 449 * @since 1.5 450 */ 451 public boolean isXIncludeAware() { 452 throw new UnsupportedOperationException( 453 "This parser does not support specification \"" 454 + this.getClass().getPackage().getSpecificationTitle() 455 + "\" version \"" 456 + this.getClass().getPackage().getSpecificationVersion() 457 + "\"" 458 ); 459 } 460} 461