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