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