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