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.validation; 27 28 import java.io.File; 29 import java.net.URL; 30 import javax.xml.transform.Source; 31 import javax.xml.transform.stream.StreamSource; 32 import org.w3c.dom.ls.LSResourceResolver; 33 import org.xml.sax.ErrorHandler; 34 import org.xml.sax.SAXException; 35 import org.xml.sax.SAXNotRecognizedException; 36 import org.xml.sax.SAXNotSupportedException; 37 import org.xml.sax.SAXParseException; 38 39 /** 40 * Factory that creates {@link Schema} objects. Entry-point to 41 * the validation API. 42 * 43 * <p> 44 * {@link SchemaFactory} is a schema compiler. It reads external 45 * representations of schemas and prepares them for validation. 46 * 47 * <p> 48 * The {@link SchemaFactory} class is not thread-safe. In other words, 49 * it is the application's responsibility to ensure that at most 50 * one thread is using a {@link SchemaFactory} object at any 51 * given moment. Implementations are encouraged to mark methods 52 * as <code>synchronized</code> to protect themselves from broken clients. 53 * 54 * <p> 55 * {@link SchemaFactory} is not re-entrant. While one of the 56 * <code>newSchema</code> methods is being invoked, applications 57 * may not attempt to recursively invoke the <code>newSchema</code> method, 58 * even from the same thread. 59 * 60 * <h2><a name="schemaLanguage"></a>Schema Language</h2> 61 * <p> 62 * This spec uses a namespace URI to designate a schema language. 63 * The following table shows the values defined by this specification. 64 * <p> 65 * To be compliant with the spec, the implementation 66 * is only required to support W3C XML Schema 1.0. However, 67 * if it chooses to support other schema languages listed here, 68 * it must conform to the relevant behaviors described in this spec. 69 * 70 * <p> 71 * Schema languages not listed here are expected to 72 * introduce their own URIs to represent themselves. 73 * The {@link SchemaFactory} class is capable of locating other 74 * implementations for other schema languages at run-time. 75 * 76 * <p> 77 * Note that because the XML DTD is strongly tied to the parsing process 78 * and has a significant effect on the parsing process, it is impossible 79 * to define the DTD validation as a process independent from parsing. 80 * For this reason, this specification does not define the semantics for 81 * the XML DTD. This doesn't prohibit implementors from implementing it 82 * in a way they see fit, but <em>users are warned that any DTD 83 * validation implemented on this interface necessarily deviate from 84 * the XML DTD semantics as defined in the XML 1.0</em>. 85 * 86 * <table border="1" cellpadding="2"> 87 * <thead> 88 * <tr> 89 * <th>value</th> 90 * <th>language</th> 91 * </tr> 92 * </thead> 93 * <tbody> 94 * <tr> 95 * <td>{@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("<code>http://www.w3.org/2001/XMLSchema</code>")</td> 96 * <td><a href="http://www.w3.org/TR/xmlschema-1">W3C XML Schema 1.0</a></td> 97 * </tr> 98 * <tr> 99 * <td>{@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("<code>http://relaxng.org/ns/structure/1.0</code>")</td> 100 * <td><a href="http://www.relaxng.org/">RELAX NG 1.0</a></td> 101 * </tr> 102 * </tbody> 103 * </table> 104 * 105 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> 106 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> 107 * 108 * @since 1.5 109 */ 110 public abstract class SchemaFactory { 111 112 private static SecuritySupport ss = new SecuritySupport(); 113 114 /** 115 * <p>Constructor for derived classes.</p> 116 * 117 * <p>The constructor does nothing.</p> 118 * 119 * <p>Derived classes must create {@link SchemaFactory} objects that have 120 * <code>null</code> {@link ErrorHandler} and 121 * <code>null</code> {@link LSResourceResolver}.</p> 122 */ 123 protected SchemaFactory() { 124 } 125 126 /** 127 * <p>Lookup an implementation of the <code>SchemaFactory</code> that supports the specified 128 * schema language and return it.</p> 129 * 130 * <p>To find a <code>SchemaFactory</code> object for a given schema language, 131 * this method looks the following places in the following order 132 * where "the class loader" refers to the context class loader:</p> 133 * <ol> 134 * <li> 135 * <p> 136 * If the system property 137 * {@code "javax.xml.validation.SchemaFactory:<i>schemaLanguage</i>"} 138 * is present (where <i>schemaLanguage</i> is the parameter 139 * to this method), then its value is read 140 * as a class name. The method will try to 141 * create a new instance of this class by using the class loader, 142 * and returns it if it is successfully created. 143 * </li> 144 * <li> 145 * <p> 146 * Use the configuration file "jaxp.properties". The file is in standard 147 * {@link java.util.Properties} format and typically located in the 148 * conf directory of the Java installation. It contains the fully qualified 149 * name of the implementation class with the key being the system property 150 * defined above. 151 * <p> 152 * The jaxp.properties file is read only once by the JAXP implementation 161 * {@link java.util.ServiceLoader} class, to attempt to locate and load an 162 * implementation of the service using the {@linkplain 163 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: 164 * the service-provider loading facility will use the {@linkplain 165 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 166 * to attempt to load the service. If the context class 167 * loader is null, the {@linkplain 168 * ClassLoader#getSystemClassLoader() system class loader} will be used. 169 * <br> 170 * Each potential service provider is required to implement the method 171 * {@link #isSchemaLanguageSupported(String schemaLanguage)}. 172 * <br> 173 * The first service provider found that supports the specified schema 174 * language is returned. 175 * <br> 176 * In case of {@link java.util.ServiceConfigurationError} a 177 * {@link SchemaFactoryConfigurationError} will be thrown. 178 * </li> 179 * <li> 180 * <p> 181 * Platform default <code>SchemaFactory</code> is located 182 * in a implementation specific way. There must be a platform default 183 * <code>SchemaFactory</code> for W3C XML Schema. 184 * </li> 185 * </ol> 186 * 187 * <p>If everything fails, {@link IllegalArgumentException} will be thrown. 188 * 189 * <p><strong>Tip for Trouble-shooting:</strong> 190 * <p>See {@link java.util.Properties#load(java.io.InputStream)} for 191 * exactly how a property file is parsed. In particular, colons ':' 192 * need to be escaped in a property file, so make sure schema language 193 * URIs are properly escaped in it. For example: 194 * <pre> 195 * http\://www.w3.org/2001/XMLSchema=org.acme.foo.XSSchemaFactory 196 * </pre> 197 * 198 * @param schemaLanguage 199 * Specifies the schema language which the returned 200 * SchemaFactory will understand. See 201 * <a href="#schemaLanguage">the list of available 202 * schema languages</a> for the possible values. 203 * 204 * @return New instance of a <code>SchemaFactory</code> 205 * 206 * @throws IllegalArgumentException 207 * If no implementation of the schema language is available. 208 * @throws NullPointerException 209 * If the <code>schemaLanguage</code> parameter is null. 210 * @throws SchemaFactoryConfigurationError 211 * If a configuration error is encountered. 212 * 213 * @see #newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) 214 */ 215 public static SchemaFactory newInstance(String schemaLanguage) { 216 ClassLoader cl; 217 cl = ss.getContextClassLoader(); 218 219 if (cl == null) { 220 //cl = ClassLoader.getSystemClassLoader(); 221 //use the current class loader 222 cl = SchemaFactory.class.getClassLoader(); 223 } 224 225 SchemaFactory f = new SchemaFactoryFinder(cl).newFactory(schemaLanguage); 226 if (f == null) { 227 throw new IllegalArgumentException( 228 "No SchemaFactory" 229 + " that implements the schema language specified by: " + schemaLanguage 230 + " could be loaded"); 231 } 232 return f; 233 } 234 235 /** 236 * <p>Obtain a new instance of a <code>SchemaFactory</code> from class name. <code>SchemaFactory</code> 237 * is returned if specified factory class name supports the specified schema language. 238 * This function is useful when there are multiple providers in the classpath. 239 * It gives more control to the application as it can specify which provider 240 * should be loaded.</p> 241 * 242 * <h2>Tip for Trouble-shooting</h2> 243 * <p>Setting the <code>jaxp.debug</code> system property will cause 244 * this method to print a lot of debug messages 245 * to <code>System.err</code> about what it is doing and where it is looking at.</p> 246 * 247 * <p> If you have problems try:</p> 248 * <pre> 249 * java -Djaxp.debug=1 YourProgram .... 250 * </pre> 251 * 252 * @param schemaLanguage Specifies the schema language which the returned 253 * <code>SchemaFactory</code> will understand. See 254 * <a href="#schemaLanguage">the list of available 255 * schema languages</a> for the possible values. 256 * 257 * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.validation.SchemaFactory</code>. 258 * 259 * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> 260 * current <code>Thread</code>'s context classLoader is used to load the factory class. 261 * 262 * @return New instance of a <code>SchemaFactory</code> 263 * 264 * @throws IllegalArgumentException 265 * if <code>factoryClassName</code> is <code>null</code>, or 266 * the factory class cannot be loaded, instantiated or doesn't 267 * support the schema language specified in <code>schemLanguage</code> 268 * parameter. 269 * 270 * @throws NullPointerException 271 * If the <code>schemaLanguage</code> parameter is null. 272 * 273 * @see #newInstance(String schemaLanguage) 274 * 275 * @since 1.6 276 */ 277 public static SchemaFactory newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader){ 278 ClassLoader cl = classLoader; 279 280 if (cl == null) { 281 cl = ss.getContextClassLoader(); 282 } 283 284 SchemaFactory f = new SchemaFactoryFinder(cl).createInstance(factoryClassName); 285 if (f == null) { 286 throw new IllegalArgumentException( 287 "Factory " + factoryClassName 288 + " could not be loaded to implement the schema language specified by: " + schemaLanguage); 289 } 290 //if this factory supports the given schemalanguage return this factory else thrown exception 291 if(f.isSchemaLanguageSupported(schemaLanguage)){ 292 return f; 293 }else{ 294 throw new IllegalArgumentException( 295 "Factory " + f.getClass().getName() 296 + " does not implement the schema language specified by: " + schemaLanguage); 297 } 298 299 } 300 301 /** 302 * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p> 303 * 304 * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand. 305 * <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language. 306 * 307 * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>. 308 * 309 * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>. 310 * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code> 311 * or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language. 312 */ 313 public abstract boolean isSchemaLanguageSupported(String schemaLanguage); 314 315 /** 316 * Look up the value of a feature flag. 317 * 318 * <p>The feature name is any fully-qualified URI. It is 319 * possible for a {@link SchemaFactory} to recognize a feature name but 320 * temporarily be unable to return its value. 321 * 322 * <p>Implementors are free (and encouraged) to invent their own features, 323 * using names built on their own URIs.</p> 324 * 325 * @param name The feature name, which is a non-null fully-qualified URI. 326 * 327 * @return The current value of the feature (true or false). 328 * 329 * @throws SAXNotRecognizedException If the feature 330 * value can't be assigned or retrieved. 331 * @throws SAXNotSupportedException When the 332 * {@link SchemaFactory} recognizes the feature name but 333 * cannot determine its value at this time. 334 * @throws NullPointerException If <code>name</code> is <code>null</code>. 335 * 336 * @see #setFeature(String, boolean) 337 */ 338 public boolean getFeature(String name) 339 throws SAXNotRecognizedException, SAXNotSupportedException { 340 341 if (name == null) { 342 throw new NullPointerException("the name parameter is null"); 343 } 344 throw new SAXNotRecognizedException(name); 345 } 346 347 /** 348 * <p>Set a feature for this <code>SchemaFactory</code>, 349 * {@link Schema}s created by this factory, and by extension, 350 * {@link Validator}s and {@link ValidatorHandler}s created by 351 * those {@link Schema}s. 352 * </p> 353 * 354 * <p>Implementors and developers should pay particular attention 355 * to how the special {@link Schema} object returned by {@link 356 * #newSchema()} is processed. In some cases, for example, when the 357 * <code>SchemaFactory</code> and the class actually loading the 358 * schema come from different implementations, it may not be possible 359 * for <code>SchemaFactory</code> features to be inherited automatically. 360 * Developers should 361 * make sure that features, such as secure processing, are explicitly 362 * set in both places.</p> 363 * 364 * <p>The feature name is any fully-qualified URI. It is 365 * possible for a {@link SchemaFactory} to expose a feature value but 366 * to be unable to change the current value.</p> 367 * 368 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. 369 * When the feature is:</p> 370 * <ul> 371 * <li> 372 * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. 373 * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. 374 * If XML processing is limited for security reasons, it will be reported via a call to the registered 375 * {@link ErrorHandler#fatalError(SAXParseException exception)}. 376 * See {@link #setErrorHandler(ErrorHandler errorHandler)}. 377 * </li> 378 * <li> 379 * <code>false</code>: the implementation will processing XML according to the XML specifications without 380 * regard to possible implementation limits. 381 * </li> 382 * </ul> 383 * 384 * @param name The feature name, which is a non-null fully-qualified URI. 385 * @param value The requested value of the feature (true or false). 386 * 387 * @throws SAXNotRecognizedException If the feature 388 * value can't be assigned or retrieved. 389 * @throws SAXNotSupportedException When the 390 * {@link SchemaFactory} recognizes the feature name but 391 * cannot set the requested value. 392 * @throws NullPointerException If <code>name</code> is <code>null</code>. 393 * 394 * @see #getFeature(String) 395 */ 396 public void setFeature(String name, boolean value) 397 throws SAXNotRecognizedException, SAXNotSupportedException { 398 399 if (name == null) { 400 throw new NullPointerException("the name parameter is null"); 401 } 402 throw new SAXNotRecognizedException(name); 403 } 404 405 /** 406 * Set the value of a property. 407 * 408 * <p>The property name is any fully-qualified URI. It is 409 * possible for a {@link SchemaFactory} to recognize a property name but 410 * to be unable to change the current value.</p> 411 * 412 * <p> 413 * All implementations that implement JAXP 1.5 or newer are required to 414 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and 415 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. 416 * </p> 417 * <ul> 418 * <li> 419 * <p>Access to external DTDs in Schema files is restricted to the protocols 420 * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. 421 * If access is denied during the creation of new Schema due to the restriction 422 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 423 * {@link #newSchema(Source)} or {@link #newSchema(File)} 424 * or {@link #newSchema(URL)} or or {@link #newSchema(Source[])} method.</p> 425 * 426 * <p>Access to external DTDs in xml source files is restricted to the protocols 427 * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. 428 * If access is denied during validation due to the restriction 429 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 430 * {@link javax.xml.validation.Validator#validate(Source)} or 431 * {@link javax.xml.validation.Validator#validate(Source, Result)} method.</p> 432 * 433 * <p>Access to external reference set by the schemaLocation attribute is 434 * restricted to the protocols specified by the 435 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. 436 * If access is denied during validation due to the restriction of this property, 437 * {@link org.xml.sax.SAXException} will be thrown by the 438 * {@link javax.xml.validation.Validator#validate(Source)} or 439 * {@link javax.xml.validation.Validator#validate(Source, Result)} method.</p> 440 * 441 * <p>Access to external reference set by the Import 442 * and Include element is restricted to the protocols specified by the 443 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. 444 * If access is denied during the creation of new Schema due to the restriction 445 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 446 * {@link #newSchema(Source)} or {@link #newSchema(File)} 447 * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method.</p> 448 * </li> 449 * </ul> 450 * 451 * @param name The property name, which is a non-null fully-qualified URI. 452 * @param object The requested value for the property. 453 * 454 * @throws SAXNotRecognizedException If the property 455 * value can't be assigned or retrieved. 456 * @throws SAXNotSupportedException When the 457 * {@link SchemaFactory} recognizes the property name but 458 * cannot set the requested value. 459 * @throws NullPointerException If <code>name</code> is <code>null</code>. 460 */ 461 public void setProperty(String name, Object object) 462 throws SAXNotRecognizedException, SAXNotSupportedException { 463 464 if (name == null) { 465 throw new NullPointerException("the name parameter is null"); 466 } 467 throw new SAXNotRecognizedException(name); 468 } 469 470 /** 471 * Look up the value of a property. 472 * 473 * <p>The property name is any fully-qualified URI. It is 474 * possible for a {@link SchemaFactory} to recognize a property name but 475 * temporarily be unable to return its value.</p> 476 * 477 * <p>{@link SchemaFactory}s are not required to recognize any specific 478 * property names.</p> 479 * 480 * <p>Implementors are free (and encouraged) to invent their own properties, 481 * using names built on their own URIs.</p> 482 * 483 * @param name The property name, which is a non-null fully-qualified URI. 484 * 485 * @return The current value of the property. 486 * 487 * @throws SAXNotRecognizedException If the property 488 * value can't be assigned or retrieved. 489 * @throws SAXNotSupportedException When the 490 * XMLReader recognizes the property name but 491 * cannot determine its value at this time. 492 * @throws NullPointerException If <code>name</code> is <code>null</code>. 493 * 494 * @see #setProperty(String, Object) 495 */ 496 public Object getProperty(String name) 497 throws SAXNotRecognizedException, SAXNotSupportedException { 498 499 if (name == null) { 500 throw new NullPointerException("the name parameter is null"); 501 } 502 throw new SAXNotRecognizedException(name); 503 } 504 505 /** 506 * Sets the {@link ErrorHandler} to receive errors encountered 507 * during the <code>newSchema</code> method invocation. 508 * 509 * <p> 510 * Error handler can be used to customize the error handling process 511 * during schema parsing. When an {@link ErrorHandler} is set, 512 * errors found during the parsing of schemas will be first sent 513 * to the {@link ErrorHandler}. 514 * 515 * <p> 516 * The error handler can abort the parsing of a schema immediately 517 * by throwing {@link SAXException} from the handler. Or for example 518 * it can print an error to the screen and try to continue the 519 * processing by returning normally from the {@link ErrorHandler} 520 * 521 * <p> 522 * If any {@link Throwable} (or instances of its derived classes) 523 * is thrown from an {@link ErrorHandler}, 524 * the caller of the <code>newSchema</code> method will be thrown 525 * the same {@link Throwable} object. 526 * 527 * <p> 528 * {@link SchemaFactory} is not allowed to 529 * throw {@link SAXException} without first reporting it to 530 * {@link ErrorHandler}. 531 * 532 * <p> 533 * Applications can call this method even during a {@link Schema} 534 * is being parsed. 535 * 536 * <p> 537 * When the {@link ErrorHandler} is null, the implementation will 538 * behave as if the following {@link ErrorHandler} is set: 539 * <pre> 540 * class DraconianErrorHandler implements {@link ErrorHandler} { 541 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 542 * throw e; 543 * } 544 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 545 * throw e; 546 * } 547 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 548 * // noop 549 * } 550 * } 551 * </pre> 552 * 553 * <p> 554 * When a new {@link SchemaFactory} object is created, initially 555 * this field is set to null. This field will <em>NOT</em> be 556 * inherited to {@link Schema}s, {@link Validator}s, or 557 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 558 * 559 * @param errorHandler A new error handler to be set. 560 * This parameter can be <code>null</code>. 561 */ 562 public abstract void setErrorHandler(ErrorHandler errorHandler); 563 564 /** 565 * Gets the current {@link ErrorHandler} set to this {@link SchemaFactory}. 566 * 567 * @return 568 * This method returns the object that was last set through 569 * the {@link #setErrorHandler(ErrorHandler)} method, or null 570 * if that method has never been called since this {@link SchemaFactory} 571 * has created. 572 * 573 * @see #setErrorHandler(ErrorHandler) 574 */ 575 public abstract ErrorHandler getErrorHandler(); 576 577 /** 578 * Sets the {@link LSResourceResolver} to customize 579 * resource resolution when parsing schemas. 580 * 581 * <p> 582 * {@link SchemaFactory} uses a {@link LSResourceResolver} 583 * when it needs to locate external resources while parsing schemas, 584 * although exactly what constitutes "locating external resources" is 585 * up to each schema language. For example, for W3C XML Schema, 586 * this includes files <code><include></code>d or <code><import></code>ed, 587 * and DTD referenced from schema files, etc. 588 * 589 * <p> 590 * Applications can call this method even during a {@link Schema} 591 * is being parsed. 592 * 593 * <p> 594 * When the {@link LSResourceResolver} is null, the implementation will 595 * behave as if the following {@link LSResourceResolver} is set: 596 * <pre> 597 * class DumbDOMResourceResolver implements {@link LSResourceResolver} { 598 * public {@link org.w3c.dom.ls.LSInput} resolveResource( 599 * String publicId, String systemId, String baseURI) { 600 * 601 * return null; // always return null 602 * } 603 * } 604 * </pre> 605 * 606 * <p> 607 * If a {@link LSResourceResolver} throws a {@link RuntimeException} 608 * (or instances of its derived classes), 609 * then the {@link SchemaFactory} will abort the parsing and 610 * the caller of the <code>newSchema</code> method will receive 611 * the same {@link RuntimeException}. 612 * 613 * <p> 614 * When a new {@link SchemaFactory} object is created, initially 615 * this field is set to null. This field will <em>NOT</em> be 616 * inherited to {@link Schema}s, {@link Validator}s, or 617 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 618 * 619 * @param resourceResolver 620 * A new resource resolver to be set. This parameter can be null. 621 */ 622 public abstract void setResourceResolver(LSResourceResolver resourceResolver); 623 624 /** 625 * Gets the current {@link LSResourceResolver} set to this {@link SchemaFactory}. 626 * 627 * @return 628 * This method returns the object that was last set through 629 * the {@link #setResourceResolver(LSResourceResolver)} method, or null 630 * if that method has never been called since this {@link SchemaFactory} 631 * has created. 632 * 633 * @see #setErrorHandler(ErrorHandler) 634 */ 635 public abstract LSResourceResolver getResourceResolver(); 636 637 /** 638 * <p>Parses the specified source as a schema and returns it as a schema.</p> 639 * 640 * <p>This is a convenience method for {@link #newSchema(Source[] schemas)}.</p> 641 * 642 * @param schema Source that represents a schema. 643 * 644 * @return New <code>Schema</code> from parsing <code>schema</code>. 645 * 646 * @throws SAXException If a SAX error occurs during parsing. 647 * @throws NullPointerException if <code>schema</code> is null. 648 */ 649 public Schema newSchema(Source schema) throws SAXException { 650 return newSchema(new Source[]{schema}); 651 } 652 653 /** 654 * <p>Parses the specified <code>File</code> as a schema and returns it as a <code>Schema</code>.</p> 655 * 656 * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p> 657 * 658 * @param schema File that represents a schema. 659 * 660 * @return New <code>Schema</code> from parsing <code>schema</code>. 661 * 662 * @throws SAXException If a SAX error occurs during parsing. 663 * @throws NullPointerException if <code>schema</code> is null. 664 */ 665 public Schema newSchema(File schema) throws SAXException { 666 return newSchema(new StreamSource(schema)); 667 } 668 669 /** 670 * <p>Parses the specified <code>URL</code> as a schema and returns it as a <code>Schema</code>.</p> 671 * 672 * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p> 673 * 674 * @param schema <code>URL</code> that represents a schema. 675 * 676 * @return New <code>Schema</code> from parsing <code>schema</code>. 677 * 678 * @throws SAXException If a SAX error occurs during parsing. 679 * @throws NullPointerException if <code>schema</code> is null. 680 */ 681 public Schema newSchema(URL schema) throws SAXException { 682 return newSchema(new StreamSource(schema.toExternalForm())); 683 } 684 685 /** 686 * Parses the specified source(s) as a schema and returns it as a schema. 687 * 688 * <p> 689 * The callee will read all the {@link Source}s and combine them into a 690 * single schema. The exact semantics of the combination depends on the schema 691 * language that this {@link SchemaFactory} object is created for. 692 * 693 * <p> 694 * When an {@link ErrorHandler} is set, the callee will report all the errors 695 * found in sources to the handler. If the handler throws an exception, it will 696 * abort the schema compilation and the same exception will be thrown from 697 * this method. Also, after an error is reported to a handler, the callee is allowed 698 * to abort the further processing by throwing it. If an error handler is not set, 699 * the callee will throw the first error it finds in the sources. 700 * 701 * <h2>W3C XML Schema 1.0</h2> 702 * <p> 703 * The resulting schema contains components from the specified sources. 704 * The same result would be achieved if all these sources were 705 * imported, using appropriate values for schemaLocation and namespace, 706 * into a single schema document with a different targetNamespace 707 * and no components of its own, if the import elements were given 708 * in the same order as the sources. Section 4.2.3 of the XML Schema 709 * recommendation describes the options processors have in this 710 * regard. While a processor should be consistent in its treatment of 711 * JAXP schema sources and XML Schema imports, the behaviour between 712 * JAXP-compliant parsers may vary; in particular, parsers may choose 713 * to ignore all but the first <import> for a given namespace, 714 * regardless of information provided in schemaLocation. 715 * 716 * <p> 717 * If the parsed set of schemas includes error(s) as 718 * specified in the section 5.1 of the XML Schema spec, then 719 * the error must be reported to the {@link ErrorHandler}. 720 * 721 * <h2>RELAX NG</h2> 722 * 723 * <p>For RELAX NG, this method must throw {@link UnsupportedOperationException} 724 * if <code>schemas.length!=1</code>. 725 * 726 * 727 * @param schemas 728 * inputs to be parsed. {@link SchemaFactory} is required 729 * to recognize {@link javax.xml.transform.sax.SAXSource}, 730 * {@link StreamSource}, 731 * {@link javax.xml.transform.stax.StAXSource}, 732 * and {@link javax.xml.transform.dom.DOMSource}. 733 * Input schemas must be XML documents or 734 * XML elements and must not be null. For backwards compatibility, 735 * the results of passing anything other than 736 * a document or element are implementation-dependent. 737 * Implementations must either recognize and process the input 738 * or thrown an IllegalArgumentException. 739 * 740 * @return 741 * Always return a non-null valid {@link Schema} object. 742 * Note that when an error has been reported, there is no 743 * guarantee that the returned {@link Schema} object is 744 * meaningful. 745 * 746 * @throws SAXException 747 * If an error is found during processing the specified inputs. 748 * When an {@link ErrorHandler} is set, errors are reported to 749 * there first. See {@link #setErrorHandler(ErrorHandler)}. 750 * @throws NullPointerException 751 * If the <code>schemas</code> parameter itself is null or 752 * any item in the array is null. 753 * @throws IllegalArgumentException 754 * If any item in the array is not recognized by this method. 755 * @throws UnsupportedOperationException 756 * If the schema language doesn't support this operation. 757 */ 758 public abstract Schema newSchema(Source[] schemas) throws SAXException; 759 760 /** 761 * Creates a special {@link Schema} object. 762 * 763 * <p>The exact semantics of the returned {@link Schema} object 764 * depend on the schema language for which this {@link SchemaFactory} 765 * is created. 766 * 767 * <p>Also, implementations are allowed to use implementation-specific 768 * property/feature to alter the semantics of this method.</p> 769 * 770 * <p>Implementors and developers should pay particular attention 771 * to how the features set on this {@link SchemaFactory} are 772 * processed by this special {@link Schema}. 773 * In some cases, for example, when the 774 * {@link SchemaFactory} and the class actually loading the 775 * schema come from different implementations, it may not be possible 776 * for {@link SchemaFactory} features to be inherited automatically. 777 * Developers should 778 * make sure that features, such as secure processing, are explicitly 779 * set in both places.</p> 780 * 781 * <h2>W3C XML Schema 1.0</h2> 782 * <p> 783 * For XML Schema, this method creates a {@link Schema} object that 784 * performs validation by using location hints specified in documents. 785 * 786 * <p> 787 * The returned {@link Schema} object assumes that if documents 788 * refer to the same URL in the schema location hints, 789 * they will always resolve to the same schema document. This 790 * asusmption allows implementations to reuse parsed results of 791 * schema documents so that multiple validations against the same 792 * schema will run faster. 793 * 794 * <p> 795 * Note that the use of schema location hints introduces a 796 * vulnerability to denial-of-service attacks. 797 * 798 * 799 * <h2>RELAX NG</h2> | 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.validation; 27 28 import java.io.File; 29 import java.net.URL; 30 import javax.xml.transform.Source; 31 import javax.xml.transform.stream.StreamSource; 32 import org.w3c.dom.ls.LSResourceResolver; 33 import org.xml.sax.ErrorHandler; 34 import org.xml.sax.SAXException; 35 import org.xml.sax.SAXNotRecognizedException; 36 import org.xml.sax.SAXNotSupportedException; 37 import org.xml.sax.SAXParseException; 38 39 /** 40 * Factory that creates {@link Schema} objects. Entry-point to 41 * the validation API. 42 * 43 * <p> 44 * {@link SchemaFactory} is a schema compiler. It reads external 45 * representations of schemas and prepares them for validation. 46 * 47 * <p> 48 * The {@link SchemaFactory} class is not thread-safe. In other words, 49 * it is the application's responsibility to ensure that at most 50 * one thread is using a {@link SchemaFactory} object at any 51 * given moment. Implementations are encouraged to mark methods 52 * as {@code synchronized} to protect themselves from broken clients. 53 * 54 * <p> 55 * {@link SchemaFactory} is not re-entrant. While one of the 56 * {@code newSchema} methods is being invoked, applications 57 * may not attempt to recursively invoke the {@code newSchema} method, 58 * even from the same thread. 59 * 60 * <h2><a name="schemaLanguage"></a>Schema Language</h2> 61 * <p> 62 * This spec uses a namespace URI to designate a schema language. 63 * The following table shows the values defined by this specification. 64 * <p> 65 * To be compliant with the spec, the implementation 66 * is only required to support W3C XML Schema 1.0. However, 67 * if it chooses to support other schema languages listed here, 68 * it must conform to the relevant behaviors described in this spec. 69 * 70 * <p> 71 * Schema languages not listed here are expected to 72 * introduce their own URIs to represent themselves. 73 * The {@link SchemaFactory} class is capable of locating other 74 * implementations for other schema languages at run-time. 75 * 76 * <p> 77 * Note that because the XML DTD is strongly tied to the parsing process 78 * and has a significant effect on the parsing process, it is impossible 79 * to define the DTD validation as a process independent from parsing. 80 * For this reason, this specification does not define the semantics for 81 * the XML DTD. This doesn't prohibit implementors from implementing it 82 * in a way they see fit, but <em>users are warned that any DTD 83 * validation implemented on this interface necessarily deviate from 84 * the XML DTD semantics as defined in the XML 1.0</em>. 85 * 86 * <table border="1" cellpadding="2"> 87 * <thead> 88 * <tr> 89 * <th>value</th> 90 * <th>language</th> 91 * </tr> 92 * </thead> 93 * <tbody> 94 * <tr> 95 * <td>{@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("{@code http://www.w3.org/2001/XMLSchema}")</td> 96 * <td><a href="http://www.w3.org/TR/xmlschema-1">W3C XML Schema 1.0</a></td> 97 * </tr> 98 * <tr> 99 * <td>{@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("{@code http://relaxng.org/ns/structure/1.0}")</td> 100 * <td><a href="http://www.relaxng.org/">RELAX NG 1.0</a></td> 101 * </tr> 102 * </tbody> 103 * </table> 104 * 105 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> 106 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> 107 * 108 * @since 1.5 109 */ 110 public abstract class SchemaFactory { 111 112 private static SecuritySupport ss = new SecuritySupport(); 113 114 /** 115 * Constructor for derived classes. 116 * 117 * <p>The constructor does nothing. 118 * 119 * <p>Derived classes must create {@link SchemaFactory} objects that have 120 * {@code null} {@link ErrorHandler} and 121 * {@code null} {@link LSResourceResolver}. 122 */ 123 protected SchemaFactory() { 124 } 125 126 /** 127 * Lookup an implementation of the {@code SchemaFactory} that supports the specified 128 * schema language and return it. 129 * 130 * <p>To find a {@code SchemaFactory} object for a given schema language, 131 * this method looks the following places in the following order 132 * where "the class loader" refers to the context class loader: 133 * <ol> 134 * <li> 135 * <p> 136 * If the system property 137 * {@code "javax.xml.validation.SchemaFactory:<i>schemaLanguage</i>"} 138 * is present (where <i>schemaLanguage</i> is the parameter 139 * to this method), then its value is read 140 * as a class name. The method will try to 141 * create a new instance of this class by using the class loader, 142 * and returns it if it is successfully created. 143 * </li> 144 * <li> 145 * <p> 146 * Use the configuration file "jaxp.properties". The file is in standard 147 * {@link java.util.Properties} format and typically located in the 148 * conf directory of the Java installation. It contains the fully qualified 149 * name of the implementation class with the key being the system property 150 * defined above. 151 * <p> 152 * The jaxp.properties file is read only once by the JAXP implementation 161 * {@link java.util.ServiceLoader} class, to attempt to locate and load an 162 * implementation of the service using the {@linkplain 163 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: 164 * the service-provider loading facility will use the {@linkplain 165 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 166 * to attempt to load the service. If the context class 167 * loader is null, the {@linkplain 168 * ClassLoader#getSystemClassLoader() system class loader} will be used. 169 * <br> 170 * Each potential service provider is required to implement the method 171 * {@link #isSchemaLanguageSupported(String schemaLanguage)}. 172 * <br> 173 * The first service provider found that supports the specified schema 174 * language is returned. 175 * <br> 176 * In case of {@link java.util.ServiceConfigurationError} a 177 * {@link SchemaFactoryConfigurationError} will be thrown. 178 * </li> 179 * <li> 180 * <p> 181 * Platform default {@code SchemaFactory} is located 182 * in a implementation specific way. There must be a platform default 183 * {@code SchemaFactory} for W3C XML Schema. 184 * </li> 185 * </ol> 186 * 187 * <p>If everything fails, {@link IllegalArgumentException} will be thrown. 188 * 189 * <p><strong>Tip for Trouble-shooting:</strong> 190 * <p>See {@link java.util.Properties#load(java.io.InputStream)} for 191 * exactly how a property file is parsed. In particular, colons ':' 192 * need to be escaped in a property file, so make sure schema language 193 * URIs are properly escaped in it. For example: 194 * <pre> 195 * http\://www.w3.org/2001/XMLSchema=org.acme.foo.XSSchemaFactory 196 * </pre> 197 * 198 * @param schemaLanguage 199 * Specifies the schema language which the returned 200 * SchemaFactory will understand. See 201 * <a href="#schemaLanguage">the list of available 202 * schema languages</a> for the possible values. 203 * 204 * @return New instance of a {@code SchemaFactory} 205 * 206 * @throws IllegalArgumentException 207 * If no implementation of the schema language is available. 208 * @throws NullPointerException 209 * If the {@code schemaLanguage} parameter is null. 210 * @throws SchemaFactoryConfigurationError 211 * If a configuration error is encountered. 212 * 213 * @see #newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) 214 */ 215 public static SchemaFactory newInstance(String schemaLanguage) { 216 ClassLoader cl; 217 cl = ss.getContextClassLoader(); 218 219 if (cl == null) { 220 //cl = ClassLoader.getSystemClassLoader(); 221 //use the current class loader 222 cl = SchemaFactory.class.getClassLoader(); 223 } 224 225 SchemaFactory f = new SchemaFactoryFinder(cl).newFactory(schemaLanguage); 226 if (f == null) { 227 throw new IllegalArgumentException( 228 "No SchemaFactory" 229 + " that implements the schema language specified by: " + schemaLanguage 230 + " could be loaded"); 231 } 232 return f; 233 } 234 235 /** 236 * Obtain a new instance of a {@code SchemaFactory} from class name. {@code SchemaFactory} 237 * is returned if specified factory class name supports the specified schema language. 238 * This function is useful when there are multiple providers in the classpath. 239 * It gives more control to the application as it can specify which provider 240 * should be loaded. 241 * 242 * <h2>Tip for Trouble-shooting</h2> 243 * <p>Setting the {@code jaxp.debug} system property will cause 244 * this method to print a lot of debug messages 245 * to {@code System.err} about what it is doing and where it is looking at. 246 * 247 * <p> If you have problems try: 248 * <pre> 249 * java -Djaxp.debug=1 YourProgram .... 250 * </pre> 251 * 252 * @param schemaLanguage Specifies the schema language which the returned 253 * {@code SchemaFactory} will understand. See 254 * <a href="#schemaLanguage">the list of available 255 * schema languages</a> for the possible values. 256 * 257 * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.validation.SchemaFactory}. 258 * 259 * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} 260 * current {@code Thread}'s context classLoader is used to load the factory class. 261 * 262 * @return New instance of a {@code SchemaFactory} 263 * 264 * @throws IllegalArgumentException 265 * if {@code factoryClassName} is {@code null}, or 266 * the factory class cannot be loaded, instantiated or doesn't 267 * support the schema language specified in {@code schemLanguage} 268 * parameter. 269 * 270 * @throws NullPointerException 271 * If the {@code schemaLanguage} parameter is null. 272 * 273 * @see #newInstance(String schemaLanguage) 274 * 275 * @since 1.6 276 */ 277 public static SchemaFactory newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader){ 278 ClassLoader cl = classLoader; 279 280 if (cl == null) { 281 cl = ss.getContextClassLoader(); 282 } 283 284 SchemaFactory f = new SchemaFactoryFinder(cl).createInstance(factoryClassName); 285 if (f == null) { 286 throw new IllegalArgumentException( 287 "Factory " + factoryClassName 288 + " could not be loaded to implement the schema language specified by: " + schemaLanguage); 289 } 290 //if this factory supports the given schemalanguage return this factory else thrown exception 291 if(f.isSchemaLanguageSupported(schemaLanguage)){ 292 return f; 293 }else{ 294 throw new IllegalArgumentException( 295 "Factory " + f.getClass().getName() 296 + " does not implement the schema language specified by: " + schemaLanguage); 297 } 298 299 } 300 301 /** 302 * Is specified schema supported by this {@code SchemaFactory}? 303 * 304 * @param schemaLanguage Specifies the schema language which the returned {@code SchemaFactory} will understand. 305 * {@code schemaLanguage} must specify a <a href="#schemaLanguage">valid</a> schema language. 306 * 307 * @return {@code true} if {@code SchemaFactory} supports {@code schemaLanguage}, else {@code false}. 308 * 309 * @throws NullPointerException If {@code schemaLanguage} is {@code null}. 310 * @throws IllegalArgumentException If {@code schemaLanguage.length() == 0} 311 * or {@code schemaLanguage} does not specify a <a href="#schemaLanguage">valid</a> schema language. 312 */ 313 public abstract boolean isSchemaLanguageSupported(String schemaLanguage); 314 315 /** 316 * Look up the value of a feature flag. 317 * 318 * <p>The feature name is any fully-qualified URI. It is 319 * possible for a {@link SchemaFactory} to recognize a feature name but 320 * temporarily be unable to return its value. 321 * 322 * <p>Implementors are free (and encouraged) to invent their own features, 323 * using names built on their own URIs. 324 * 325 * @param name The feature name, which is a non-null fully-qualified URI. 326 * 327 * @return The current value of the feature (true or false). 328 * 329 * @throws SAXNotRecognizedException If the feature 330 * value can't be assigned or retrieved. 331 * @throws SAXNotSupportedException When the 332 * {@link SchemaFactory} recognizes the feature name but 333 * cannot determine its value at this time. 334 * @throws NullPointerException If {@code name} is {@code null}. 335 * 336 * @see #setFeature(String, boolean) 337 */ 338 public boolean getFeature(String name) 339 throws SAXNotRecognizedException, SAXNotSupportedException { 340 341 if (name == null) { 342 throw new NullPointerException("the name parameter is null"); 343 } 344 throw new SAXNotRecognizedException(name); 345 } 346 347 /** 348 * Set a feature for this {@code SchemaFactory}, 349 * {@link Schema}s created by this factory, and by extension, 350 * {@link Validator}s and {@link ValidatorHandler}s created by 351 * those {@link Schema}s. 352 * 353 * 354 * <p>Implementors and developers should pay particular attention 355 * to how the special {@link Schema} object returned by {@link 356 * #newSchema()} is processed. In some cases, for example, when the 357 * {@code SchemaFactory} and the class actually loading the 358 * schema come from different implementations, it may not be possible 359 * for {@code SchemaFactory} features to be inherited automatically. 360 * Developers should 361 * make sure that features, such as secure processing, are explicitly 362 * set in both places. 363 * 364 * <p>The feature name is any fully-qualified URI. It is 365 * possible for a {@link SchemaFactory} to expose a feature value but 366 * to be unable to change the current value. 367 * 368 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. 369 * When the feature is: 370 * <ul> 371 * <li> 372 * {@code true}: the implementation will limit XML processing to conform to implementation limits. 373 * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. 374 * If XML processing is limited for security reasons, it will be reported via a call to the registered 375 * {@link ErrorHandler#fatalError(SAXParseException exception)}. 376 * See {@link #setErrorHandler(ErrorHandler errorHandler)}. 377 * </li> 378 * <li> 379 * {@code false}: the implementation will processing XML according to the XML specifications without 380 * regard to possible implementation limits. 381 * </li> 382 * </ul> 383 * 384 * @param name The feature name, which is a non-null fully-qualified URI. 385 * @param value The requested value of the feature (true or false). 386 * 387 * @throws SAXNotRecognizedException If the feature 388 * value can't be assigned or retrieved. 389 * @throws SAXNotSupportedException When the 390 * {@link SchemaFactory} recognizes the feature name but 391 * cannot set the requested value. 392 * @throws NullPointerException If {@code name} is {@code null}. 393 * 394 * @see #getFeature(String) 395 */ 396 public void setFeature(String name, boolean value) 397 throws SAXNotRecognizedException, SAXNotSupportedException { 398 399 if (name == null) { 400 throw new NullPointerException("the name parameter is null"); 401 } 402 throw new SAXNotRecognizedException(name); 403 } 404 405 /** 406 * Set the value of a property. 407 * 408 * <p>The property name is any fully-qualified URI. It is 409 * possible for a {@link SchemaFactory} to recognize a property name but 410 * to be unable to change the current value. 411 * 412 * <p> 413 * All implementations that implement JAXP 1.5 or newer are required to 414 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and 415 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. 416 * 417 * <ul> 418 * <li> 419 * <p>Access to external DTDs in Schema files is restricted to the protocols 420 * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. 421 * If access is denied during the creation of new Schema due to the restriction 422 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 423 * {@link #newSchema(Source)} or {@link #newSchema(File)} 424 * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method. 425 * 426 * <p>Access to external DTDs in xml source files is restricted to the protocols 427 * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. 428 * If access is denied during validation due to the restriction 429 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 430 * {@link javax.xml.validation.Validator#validate(Source)} or 431 * {@link javax.xml.validation.Validator#validate(Source, Result)} method. 432 * 433 * <p>Access to external reference set by the schemaLocation attribute is 434 * restricted to the protocols specified by the 435 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. 436 * If access is denied during validation due to the restriction of this property, 437 * {@link org.xml.sax.SAXException} will be thrown by the 438 * {@link javax.xml.validation.Validator#validate(Source)} or 439 * {@link javax.xml.validation.Validator#validate(Source, Result)} method. 440 * 441 * <p>Access to external reference set by the Import 442 * and Include element is restricted to the protocols specified by the 443 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. 444 * If access is denied during the creation of new Schema due to the restriction 445 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 446 * {@link #newSchema(Source)} or {@link #newSchema(File)} 447 * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method. 448 * </li> 449 * </ul> 450 * 451 * @param name The property name, which is a non-null fully-qualified URI. 452 * @param object The requested value for the property. 453 * 454 * @throws SAXNotRecognizedException If the property 455 * value can't be assigned or retrieved. 456 * @throws SAXNotSupportedException When the 457 * {@link SchemaFactory} recognizes the property name but 458 * cannot set the requested value. 459 * @throws NullPointerException If {@code name} is {@code null}. 460 */ 461 public void setProperty(String name, Object object) 462 throws SAXNotRecognizedException, SAXNotSupportedException { 463 464 if (name == null) { 465 throw new NullPointerException("the name parameter is null"); 466 } 467 throw new SAXNotRecognizedException(name); 468 } 469 470 /** 471 * Look up the value of a property. 472 * 473 * <p>The property name is any fully-qualified URI. It is 474 * possible for a {@link SchemaFactory} to recognize a property name but 475 * temporarily be unable to return its value. 476 * 477 * <p>{@link SchemaFactory}s are not required to recognize any specific 478 * property names. 479 * 480 * <p>Implementors are free (and encouraged) to invent their own properties, 481 * using names built on their own URIs. 482 * 483 * @param name The property name, which is a non-null fully-qualified URI. 484 * 485 * @return The current value of the property. 486 * 487 * @throws SAXNotRecognizedException If the property 488 * value can't be assigned or retrieved. 489 * @throws SAXNotSupportedException When the 490 * XMLReader recognizes the property name but 491 * cannot determine its value at this time. 492 * @throws NullPointerException If {@code name} is {@code null}. 493 * 494 * @see #setProperty(String, Object) 495 */ 496 public Object getProperty(String name) 497 throws SAXNotRecognizedException, SAXNotSupportedException { 498 499 if (name == null) { 500 throw new NullPointerException("the name parameter is null"); 501 } 502 throw new SAXNotRecognizedException(name); 503 } 504 505 /** 506 * Sets the {@link ErrorHandler} to receive errors encountered 507 * during the {@code newSchema} method invocation. 508 * 509 * <p> 510 * Error handler can be used to customize the error handling process 511 * during schema parsing. When an {@link ErrorHandler} is set, 512 * errors found during the parsing of schemas will be first sent 513 * to the {@link ErrorHandler}. 514 * 515 * <p> 516 * The error handler can abort the parsing of a schema immediately 517 * by throwing {@link SAXException} from the handler. Or for example 518 * it can print an error to the screen and try to continue the 519 * processing by returning normally from the {@link ErrorHandler} 520 * 521 * <p> 522 * If any {@link Throwable} (or instances of its derived classes) 523 * is thrown from an {@link ErrorHandler}, 524 * the caller of the {@code newSchema} method will be thrown 525 * the same {@link Throwable} object. 526 * 527 * <p> 528 * {@link SchemaFactory} is not allowed to 529 * throw {@link SAXException} without first reporting it to 530 * {@link ErrorHandler}. 531 * 532 * <p> 533 * Applications can call this method even during a {@link Schema} 534 * is being parsed. 535 * 536 * <p> 537 * When the {@link ErrorHandler} is null, the implementation will 538 * behave as if the following {@link ErrorHandler} is set: 539 * <pre> 540 * class DraconianErrorHandler implements {@link ErrorHandler} { 541 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 542 * throw e; 543 * } 544 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 545 * throw e; 546 * } 547 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 548 * // noop 549 * } 550 * } 551 * </pre> 552 * 553 * <p> 554 * When a new {@link SchemaFactory} object is created, initially 555 * this field is set to null. This field will <em>NOT</em> be 556 * inherited to {@link Schema}s, {@link Validator}s, or 557 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 558 * 559 * @param errorHandler A new error handler to be set. 560 * This parameter can be {@code null}. 561 */ 562 public abstract void setErrorHandler(ErrorHandler errorHandler); 563 564 /** 565 * Gets the current {@link ErrorHandler} set to this {@link SchemaFactory}. 566 * 567 * @return 568 * This method returns the object that was last set through 569 * the {@link #setErrorHandler(ErrorHandler)} method, or null 570 * if that method has never been called since this {@link SchemaFactory} 571 * has created. 572 * 573 * @see #setErrorHandler(ErrorHandler) 574 */ 575 public abstract ErrorHandler getErrorHandler(); 576 577 /** 578 * Sets the {@link LSResourceResolver} to customize 579 * resource resolution when parsing schemas. 580 * 581 * <p> 582 * {@link SchemaFactory} uses a {@link LSResourceResolver} 583 * when it needs to locate external resources while parsing schemas, 584 * although exactly what constitutes "locating external resources" is 585 * up to each schema language. For example, for W3C XML Schema, 586 * this includes files {@code <include>}d or {@code <import>}ed, 587 * and DTD referenced from schema files, etc. 588 * 589 * <p> 590 * Applications can call this method even during a {@link Schema} 591 * is being parsed. 592 * 593 * <p> 594 * When the {@link LSResourceResolver} is null, the implementation will 595 * behave as if the following {@link LSResourceResolver} is set: 596 * <pre> 597 * class DumbDOMResourceResolver implements {@link LSResourceResolver} { 598 * public {@link org.w3c.dom.ls.LSInput} resolveResource( 599 * String publicId, String systemId, String baseURI) { 600 * 601 * return null; // always return null 602 * } 603 * } 604 * </pre> 605 * 606 * <p> 607 * If a {@link LSResourceResolver} throws a {@link RuntimeException} 608 * (or instances of its derived classes), 609 * then the {@link SchemaFactory} will abort the parsing and 610 * the caller of the {@code newSchema} method will receive 611 * the same {@link RuntimeException}. 612 * 613 * <p> 614 * When a new {@link SchemaFactory} object is created, initially 615 * this field is set to null. This field will <em>NOT</em> be 616 * inherited to {@link Schema}s, {@link Validator}s, or 617 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 618 * 619 * @param resourceResolver 620 * A new resource resolver to be set. This parameter can be null. 621 */ 622 public abstract void setResourceResolver(LSResourceResolver resourceResolver); 623 624 /** 625 * Gets the current {@link LSResourceResolver} set to this {@link SchemaFactory}. 626 * 627 * @return 628 * This method returns the object that was last set through 629 * the {@link #setResourceResolver(LSResourceResolver)} method, or null 630 * if that method has never been called since this {@link SchemaFactory} 631 * has created. 632 * 633 * @see #setErrorHandler(ErrorHandler) 634 */ 635 public abstract LSResourceResolver getResourceResolver(); 636 637 /** 638 * Parses the specified source as a schema and returns it as a schema. 639 * 640 * <p>This is a convenience method for {@link #newSchema(Source[] schemas)}. 641 * 642 * @param schema Source that represents a schema. 643 * 644 * @return New {@code Schema} from parsing {@code schema}. 645 * 646 * @throws SAXException If a SAX error occurs during parsing. 647 * @throws NullPointerException if {@code schema} is null. 648 */ 649 public Schema newSchema(Source schema) throws SAXException { 650 return newSchema(new Source[]{schema}); 651 } 652 653 /** 654 * Parses the specified {@code File} as a schema and returns it as a {@code Schema}. 655 * 656 * <p>This is a convenience method for {@link #newSchema(Source schema)}. 657 * 658 * @param schema File that represents a schema. 659 * 660 * @return New {@code Schema} from parsing {@code schema}. 661 * 662 * @throws SAXException If a SAX error occurs during parsing. 663 * @throws NullPointerException if {@code schema} is null. 664 */ 665 public Schema newSchema(File schema) throws SAXException { 666 return newSchema(new StreamSource(schema)); 667 } 668 669 /** 670 * Parses the specified {@code URL} as a schema and returns it as a {@code Schema}. 671 * 672 * <p>This is a convenience method for {@link #newSchema(Source schema)}. 673 * 674 * @param schema {@code URL} that represents a schema. 675 * 676 * @return New {@code Schema} from parsing {@code schema}. 677 * 678 * @throws SAXException If a SAX error occurs during parsing. 679 * @throws NullPointerException if {@code schema} is null. 680 */ 681 public Schema newSchema(URL schema) throws SAXException { 682 return newSchema(new StreamSource(schema.toExternalForm())); 683 } 684 685 /** 686 * Parses the specified source(s) as a schema and returns it as a schema. 687 * 688 * <p> 689 * The callee will read all the {@link Source}s and combine them into a 690 * single schema. The exact semantics of the combination depends on the schema 691 * language that this {@link SchemaFactory} object is created for. 692 * 693 * <p> 694 * When an {@link ErrorHandler} is set, the callee will report all the errors 695 * found in sources to the handler. If the handler throws an exception, it will 696 * abort the schema compilation and the same exception will be thrown from 697 * this method. Also, after an error is reported to a handler, the callee is allowed 698 * to abort the further processing by throwing it. If an error handler is not set, 699 * the callee will throw the first error it finds in the sources. 700 * 701 * <h2>W3C XML Schema 1.0</h2> 702 * <p> 703 * The resulting schema contains components from the specified sources. 704 * The same result would be achieved if all these sources were 705 * imported, using appropriate values for schemaLocation and namespace, 706 * into a single schema document with a different targetNamespace 707 * and no components of its own, if the import elements were given 708 * in the same order as the sources. Section 4.2.3 of the XML Schema 709 * recommendation describes the options processors have in this 710 * regard. While a processor should be consistent in its treatment of 711 * JAXP schema sources and XML Schema imports, the behaviour between 712 * JAXP-compliant parsers may vary; in particular, parsers may choose 713 * to ignore all but the first {@code <import>} for a given namespace, 714 * regardless of information provided in schemaLocation. 715 * 716 * <p> 717 * If the parsed set of schemas includes error(s) as 718 * specified in the section 5.1 of the XML Schema spec, then 719 * the error must be reported to the {@link ErrorHandler}. 720 * 721 * <h2>RELAX NG</h2> 722 * 723 * <p>For RELAX NG, this method must throw {@link UnsupportedOperationException} 724 * if {@code schemas.length!=1}. 725 * 726 * 727 * @param schemas 728 * inputs to be parsed. {@link SchemaFactory} is required 729 * to recognize {@link javax.xml.transform.sax.SAXSource}, 730 * {@link StreamSource}, 731 * {@link javax.xml.transform.stax.StAXSource}, 732 * and {@link javax.xml.transform.dom.DOMSource}. 733 * Input schemas must be XML documents or 734 * XML elements and must not be null. For backwards compatibility, 735 * the results of passing anything other than 736 * a document or element are implementation-dependent. 737 * Implementations must either recognize and process the input 738 * or thrown an IllegalArgumentException. 739 * 740 * @return 741 * Always return a non-null valid {@link Schema} object. 742 * Note that when an error has been reported, there is no 743 * guarantee that the returned {@link Schema} object is 744 * meaningful. 745 * 746 * @throws SAXException 747 * If an error is found during processing the specified inputs. 748 * When an {@link ErrorHandler} is set, errors are reported to 749 * there first. See {@link #setErrorHandler(ErrorHandler)}. 750 * @throws NullPointerException 751 * If the {@code schemas} parameter itself is null or 752 * any item in the array is null. 753 * @throws IllegalArgumentException 754 * If any item in the array is not recognized by this method. 755 * @throws UnsupportedOperationException 756 * If the schema language doesn't support this operation. 757 */ 758 public abstract Schema newSchema(Source[] schemas) throws SAXException; 759 760 /** 761 * Creates a special {@link Schema} object. 762 * 763 * <p>The exact semantics of the returned {@link Schema} object 764 * depend on the schema language for which this {@link SchemaFactory} 765 * is created. 766 * 767 * <p>Also, implementations are allowed to use implementation-specific 768 * property/feature to alter the semantics of this method. 769 * 770 * <p>Implementors and developers should pay particular attention 771 * to how the features set on this {@link SchemaFactory} are 772 * processed by this special {@link Schema}. 773 * In some cases, for example, when the 774 * {@link SchemaFactory} and the class actually loading the 775 * schema come from different implementations, it may not be possible 776 * for {@link SchemaFactory} features to be inherited automatically. 777 * Developers should 778 * make sure that features, such as secure processing, are explicitly 779 * set in both places. 780 * 781 * <h2>W3C XML Schema 1.0</h2> 782 * <p> 783 * For XML Schema, this method creates a {@link Schema} object that 784 * performs validation by using location hints specified in documents. 785 * 786 * <p> 787 * The returned {@link Schema} object assumes that if documents 788 * refer to the same URL in the schema location hints, 789 * they will always resolve to the same schema document. This 790 * asusmption allows implementations to reuse parsed results of 791 * schema documents so that multiple validations against the same 792 * schema will run faster. 793 * 794 * <p> 795 * Note that the use of schema location hints introduces a 796 * vulnerability to denial-of-service attacks. 797 * 798 * 799 * <h2>RELAX NG</h2> |