1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.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 * If the system property 136 * <code>"javax.xml.validation.SchemaFactory:<i>schemaLanguage</i>"</code> 137 * is present (where <i>schemaLanguage</i> is the parameter 138 * to this method), then its value is read 139 * as a class name. The method will try to 140 * create a new instance of this class by using the class loader, 141 * and returns it if it is successfully created. 142 * </li> 143 * <li> 144 * <code>$java.home/lib/jaxp.properties</code> is read and 145 * the value associated with the key being the system property above 146 * is looked for. If present, the value is processed just like above. 147 * </li> 148 * <li> 149 * Use the service-provider loading facilities, defined by the 150 * {@link java.util.ServiceLoader} class, to attempt to locate and load an 151 * implementation of the service.<br> 152 * Each potential service provider is required to implement the method 153 * {@link #isSchemaLanguageSupported(String schemaLanguage)}. 154 * <br> 155 * The first service provider found that supports the specified schema 156 * language is returned. 157 * <br> 158 * In case of {@link java.util.ServiceConfigurationError} a 159 * {@link SchemaFactoryConfigurationError} will be thrown. 160 * </li> 161 * <li> 162 * Platform default <code>SchemaFactory</code> is located 163 * in a implementation specific way. There must be a platform default 164 * <code>SchemaFactory</code> for W3C XML Schema. 165 * </li> 166 * </ol> 167 * 168 * <p>If everything fails, {@link IllegalArgumentException} will be thrown.</p> 169 * 170 * <p><strong>Tip for Trouble-shooting:</strong></p> 171 * <p>See {@link java.util.Properties#load(java.io.InputStream)} for 172 * exactly how a property file is parsed. In particular, colons ':' 173 * need to be escaped in a property file, so make sure schema language 174 * URIs are properly escaped in it. For example:</p> 175 * <pre> 176 * http\://www.w3.org/2001/XMLSchema=org.acme.foo.XSSchemaFactory 177 * </pre> 178 * 179 * @param schemaLanguage 180 * Specifies the schema language which the returned 181 * SchemaFactory will understand. See 182 * <a href="#schemaLanguage">the list of available 183 * schema languages</a> for the possible values. 184 * 185 * @return New instance of a <code>SchemaFactory</code> 186 * 187 * @throws IllegalArgumentException 188 * If no implementation of the schema language is available. 189 * @throws NullPointerException 190 * If the <code>schemaLanguage</code> parameter is null. 191 * @throws SchemaFactoryConfigurationError 192 * If a configuration error is encountered. 193 * 194 * @see #newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) 195 */ 196 public static SchemaFactory newInstance(String schemaLanguage) { 197 ClassLoader cl; 198 cl = ss.getContextClassLoader(); 199 200 if (cl == null) { 201 //cl = ClassLoader.getSystemClassLoader(); 202 //use the current class loader 203 cl = SchemaFactory.class.getClassLoader(); 204 } 205 206 SchemaFactory f = new SchemaFactoryFinder(cl).newFactory(schemaLanguage); 207 if (f == null) { 208 throw new IllegalArgumentException( 209 "No SchemaFactory" 210 + " that implements the schema language specified by: " + schemaLanguage 211 + " could be loaded"); 212 } 213 return f; 214 } 215 216 /** 217 * <p>Obtain a new instance of a <code>SchemaFactory</code> from class name. <code>SchemaFactory</code> 218 * is returned if specified factory class name supports the specified schema language. 219 * This function is useful when there are multiple providers in the classpath. 220 * It gives more control to the application as it can specify which provider 221 * should be loaded.</p> 222 * 223 * <h2>Tip for Trouble-shooting</h2> 224 * <p>Setting the <code>jaxp.debug</code> system property will cause 225 * this method to print a lot of debug messages 226 * to <code>System.err</code> about what it is doing and where it is looking at.</p> 227 * 228 * <p> If you have problems try:</p> 229 * <pre> 230 * java -Djaxp.debug=1 YourProgram .... 231 * </pre> 232 * 233 * @param schemaLanguage Specifies the schema language which the returned 234 * <code>SchemaFactory</code> will understand. See 235 * <a href="#schemaLanguage">the list of available 236 * schema languages</a> for the possible values. 237 * 238 * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.validation.SchemaFactory</code>. 239 * 240 * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> 241 * current <code>Thread</code>'s context classLoader is used to load the factory class. 242 * 243 * @return New instance of a <code>SchemaFactory</code> 244 * 245 * @throws IllegalArgumentException 246 * if <code>factoryClassName</code> is <code>null</code>, or 247 * the factory class cannot be loaded, instantiated or doesn't 248 * support the schema language specified in <code>schemLanguage</code> 249 * parameter. 250 * 251 * @throws NullPointerException 252 * If the <code>schemaLanguage</code> parameter is null. 253 * 254 * @see #newInstance(String schemaLanguage) 255 * 256 * @since 1.6 257 */ 258 public static SchemaFactory newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader){ 259 ClassLoader cl = classLoader; 260 261 if (cl == null) { 262 cl = ss.getContextClassLoader(); 263 } 264 265 SchemaFactory f = new SchemaFactoryFinder(cl).createInstance(factoryClassName); 266 if (f == null) { 267 throw new IllegalArgumentException( 268 "Factory " + factoryClassName 269 + " could not be loaded to implement the schema language specified by: " + schemaLanguage); 270 } 271 //if this factory supports the given schemalanguage return this factory else thrown exception 272 if(f.isSchemaLanguageSupported(schemaLanguage)){ 273 return f; 274 }else{ 275 throw new IllegalArgumentException( 276 "Factory " + f.getClass().getName() 277 + " does not implement the schema language specified by: " + schemaLanguage); 278 } 279 280 } 281 282 /** 283 * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p> 284 * 285 * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand. 286 * <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language. 287 * 288 * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>. 289 * 290 * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>. 291 * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code> 292 * or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language. 293 */ 294 public abstract boolean isSchemaLanguageSupported(String schemaLanguage); 295 296 /** 297 * Look up the value of a feature flag. 298 * 299 * <p>The feature name is any fully-qualified URI. It is 300 * possible for a {@link SchemaFactory} to recognize a feature name but 301 * temporarily be unable to return its value. 302 * 303 * <p>Implementors are free (and encouraged) to invent their own features, 304 * using names built on their own URIs.</p> 305 * 306 * @param name The feature name, which is a non-null fully-qualified URI. 307 * 308 * @return The current value of the feature (true or false). 309 * 310 * @throws SAXNotRecognizedException If the feature 311 * value can't be assigned or retrieved. 312 * @throws SAXNotSupportedException When the 313 * {@link SchemaFactory} recognizes the feature name but 314 * cannot determine its value at this time. 315 * @throws NullPointerException If <code>name</code> is <code>null</code>. 316 * 317 * @see #setFeature(String, boolean) 318 */ 319 public boolean getFeature(String name) 320 throws SAXNotRecognizedException, SAXNotSupportedException { 321 322 if (name == null) { 323 throw new NullPointerException("the name parameter is null"); 324 } 325 throw new SAXNotRecognizedException(name); 326 } 327 328 /** 329 * <p>Set a feature for this <code>SchemaFactory</code>, 330 * {@link Schema}s created by this factory, and by extension, 331 * {@link Validator}s and {@link ValidatorHandler}s created by 332 * those {@link Schema}s. 333 * </p> 334 * 335 * <p>Implementors and developers should pay particular attention 336 * to how the special {@link Schema} object returned by {@link 337 * #newSchema()} is processed. In some cases, for example, when the 338 * <code>SchemaFactory</code> and the class actually loading the 339 * schema come from different implementations, it may not be possible 340 * for <code>SchemaFactory</code> features to be inherited automatically. 341 * Developers should 342 * make sure that features, such as secure processing, are explicitly 343 * set in both places.</p> 344 * 345 * <p>The feature name is any fully-qualified URI. It is 346 * possible for a {@link SchemaFactory} to expose a feature value but 347 * to be unable to change the current value.</p> 348 * 349 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. 350 * When the feature is:</p> 351 * <ul> 352 * <li> 353 * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. 354 * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. 355 * If XML processing is limited for security reasons, it will be reported via a call to the registered 356 * {@link ErrorHandler#fatalError(SAXParseException exception)}. 357 * See {@link #setErrorHandler(ErrorHandler errorHandler)}. 358 * </li> 359 * <li> 360 * <code>false</code>: the implementation will processing XML according to the XML specifications without 361 * regard to possible implementation limits. 362 * </li> 363 * </ul> 364 * 365 * @param name The feature name, which is a non-null fully-qualified URI. 366 * @param value The requested value of the feature (true or false). 367 * 368 * @throws SAXNotRecognizedException If the feature 369 * value can't be assigned or retrieved. 370 * @throws SAXNotSupportedException When the 371 * {@link SchemaFactory} recognizes the feature name but 372 * cannot set the requested value. 373 * @throws NullPointerException If <code>name</code> is <code>null</code>. 374 * 375 * @see #getFeature(String) 376 */ 377 public void setFeature(String name, boolean value) 378 throws SAXNotRecognizedException, SAXNotSupportedException { 379 380 if (name == null) { 381 throw new NullPointerException("the name parameter is null"); 382 } 383 throw new SAXNotRecognizedException(name); 384 } 385 386 /** 387 * Set the value of a property. 388 * 389 * <p>The property name is any fully-qualified URI. It is 390 * possible for a {@link SchemaFactory} to recognize a property name but 391 * to be unable to change the current value.</p> 392 * 393 * <p>{@link SchemaFactory}s are not required to recognize setting 394 * any specific property names.</p> 395 * 396 * @param name The property name, which is a non-null fully-qualified URI. 397 * @param object The requested value for the property. 398 * 399 * @throws SAXNotRecognizedException If the property 400 * value can't be assigned or retrieved. 401 * @throws SAXNotSupportedException When the 402 * {@link SchemaFactory} recognizes the property name but 403 * cannot set the requested value. 404 * @throws NullPointerException If <code>name</code> is <code>null</code>. 405 */ 406 public void setProperty(String name, Object object) 407 throws SAXNotRecognizedException, SAXNotSupportedException { 408 409 if (name == null) { 410 throw new NullPointerException("the name parameter is null"); 411 } 412 throw new SAXNotRecognizedException(name); 413 } 414 415 /** 416 * Look up the value of a property. 417 * 418 * <p>The property name is any fully-qualified URI. It is 419 * possible for a {@link SchemaFactory} to recognize a property name but 420 * temporarily be unable to return its value.</p> 421 * 422 * <p>{@link SchemaFactory}s are not required to recognize any specific 423 * property names.</p> 424 * 425 * <p>Implementors are free (and encouraged) to invent their own properties, 426 * using names built on their own URIs.</p> 427 * 428 * @param name The property name, which is a non-null fully-qualified URI. 429 * 430 * @return The current value of the property. 431 * 432 * @throws SAXNotRecognizedException If the property 433 * value can't be assigned or retrieved. 434 * @throws SAXNotSupportedException When the 435 * XMLReader recognizes the property name but 436 * cannot determine its value at this time. 437 * @throws NullPointerException If <code>name</code> is <code>null</code>. 438 * 439 * @see #setProperty(String, Object) 440 */ 441 public Object getProperty(String name) 442 throws SAXNotRecognizedException, SAXNotSupportedException { 443 444 if (name == null) { 445 throw new NullPointerException("the name parameter is null"); 446 } 447 throw new SAXNotRecognizedException(name); 448 } 449 450 /** 451 * Sets the {@link ErrorHandler} to receive errors encountered 452 * during the <code>newSchema</code> method invocation. 453 * 454 * <p> 455 * Error handler can be used to customize the error handling process 456 * during schema parsing. When an {@link ErrorHandler} is set, 457 * errors found during the parsing of schemas will be first sent 458 * to the {@link ErrorHandler}. 459 * 460 * <p> 461 * The error handler can abort the parsing of a schema immediately 462 * by throwing {@link SAXException} from the handler. Or for example 463 * it can print an error to the screen and try to continue the 464 * processing by returning normally from the {@link ErrorHandler} 465 * 466 * <p> 467 * If any {@link Throwable} (or instances of its derived classes) 468 * is thrown from an {@link ErrorHandler}, 469 * the caller of the <code>newSchema</code> method will be thrown 470 * the same {@link Throwable} object. 471 * 472 * <p> 473 * {@link SchemaFactory} is not allowed to 474 * throw {@link SAXException} without first reporting it to 475 * {@link ErrorHandler}. 476 * 477 * <p> 478 * Applications can call this method even during a {@link Schema} 479 * is being parsed. 480 * 481 * <p> 482 * When the {@link ErrorHandler} is null, the implementation will 483 * behave as if the following {@link ErrorHandler} is set: 484 * <pre> 485 * class DraconianErrorHandler implements {@link ErrorHandler} { 486 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 487 * throw e; 488 * } 489 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 490 * throw e; 491 * } 492 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 493 * // noop 494 * } 495 * } 496 * </pre> 497 * 498 * <p> 499 * When a new {@link SchemaFactory} object is created, initially 500 * this field is set to null. This field will <em>NOT</em> be 501 * inherited to {@link Schema}s, {@link Validator}s, or 502 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 503 * 504 * @param errorHandler A new error handler to be set. 505 * This parameter can be <code>null</code>. 506 */ 507 public abstract void setErrorHandler(ErrorHandler errorHandler); 508 509 /** 510 * Gets the current {@link ErrorHandler} set to this {@link SchemaFactory}. 511 * 512 * @return 513 * This method returns the object that was last set through 514 * the {@link #setErrorHandler(ErrorHandler)} method, or null 515 * if that method has never been called since this {@link SchemaFactory} 516 * has created. 517 * 518 * @see #setErrorHandler(ErrorHandler) 519 */ 520 public abstract ErrorHandler getErrorHandler(); 521 522 /** 523 * Sets the {@link LSResourceResolver} to customize 524 * resource resolution when parsing schemas. 525 * 526 * <p> 527 * {@link SchemaFactory} uses a {@link LSResourceResolver} 528 * when it needs to locate external resources while parsing schemas, 529 * although exactly what constitutes "locating external resources" is 530 * up to each schema language. For example, for W3C XML Schema, 531 * this includes files <code><include></code>d or <code><import></code>ed, 532 * and DTD referenced from schema files, etc. 533 * 534 * <p> 535 * Applications can call this method even during a {@link Schema} 536 * is being parsed. 537 * 538 * <p> 539 * When the {@link LSResourceResolver} is null, the implementation will 540 * behave as if the following {@link LSResourceResolver} is set: 541 * <pre> 542 * class DumbDOMResourceResolver implements {@link LSResourceResolver} { 543 * public {@link org.w3c.dom.ls.LSInput} resolveResource( 544 * String publicId, String systemId, String baseURI) { 545 * 546 * return null; // always return null 547 * } 548 * } 549 * </pre> 550 * 551 * <p> 552 * If a {@link LSResourceResolver} throws a {@link RuntimeException} 553 * (or instances of its derived classes), 554 * then the {@link SchemaFactory} will abort the parsing and 555 * the caller of the <code>newSchema</code> method will receive 556 * the same {@link RuntimeException}. 557 * 558 * <p> 559 * When a new {@link SchemaFactory} object is created, initially 560 * this field is set to null. This field will <em>NOT</em> be 561 * inherited to {@link Schema}s, {@link Validator}s, or 562 * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. 563 * 564 * @param resourceResolver 565 * A new resource resolver to be set. This parameter can be null. 566 */ 567 public abstract void setResourceResolver(LSResourceResolver resourceResolver); 568 569 /** 570 * Gets the current {@link LSResourceResolver} set to this {@link SchemaFactory}. 571 * 572 * @return 573 * This method returns the object that was last set through 574 * the {@link #setResourceResolver(LSResourceResolver)} method, or null 575 * if that method has never been called since this {@link SchemaFactory} 576 * has created. 577 * 578 * @see #setErrorHandler(ErrorHandler) 579 */ 580 public abstract LSResourceResolver getResourceResolver(); 581 582 /** 583 * <p>Parses the specified source as a schema and returns it as a schema.</p> 584 * 585 * <p>This is a convenience method for {@link #newSchema(Source[] schemas)}.</p> 586 * 587 * @param schema Source that represents a schema. 588 * 589 * @return New <code>Schema</code> from parsing <code>schema</code>. 590 * 591 * @throws SAXException If a SAX error occurs during parsing. 592 * @throws NullPointerException if <code>schema</code> is null. 593 */ 594 public Schema newSchema(Source schema) throws SAXException { 595 return newSchema(new Source[]{schema}); 596 } 597 598 /** 599 * <p>Parses the specified <code>File</code> as a schema and returns it as a <code>Schema</code>.</p> 600 * 601 * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p> 602 * 603 * @param schema File that represents a schema. 604 * 605 * @return New <code>Schema</code> from parsing <code>schema</code>. 606 * 607 * @throws SAXException If a SAX error occurs during parsing. 608 * @throws NullPointerException if <code>schema</code> is null. 609 */ 610 public Schema newSchema(File schema) throws SAXException { 611 return newSchema(new StreamSource(schema)); 612 } 613 614 /** 615 * <p>Parses the specified <code>URL</code> as a schema and returns it as a <code>Schema</code>.</p> 616 * 617 * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p> 618 * 619 * @param schema <code>URL</code> that represents a schema. 620 * 621 * @return New <code>Schema</code> from parsing <code>schema</code>. 622 * 623 * @throws SAXException If a SAX error occurs during parsing. 624 * @throws NullPointerException if <code>schema</code> is null. 625 */ 626 public Schema newSchema(URL schema) throws SAXException { 627 return newSchema(new StreamSource(schema.toExternalForm())); 628 } 629 630 /** 631 * Parses the specified source(s) as a schema and returns it as a schema. 632 * 633 * <p> 634 * The callee will read all the {@link Source}s and combine them into a 635 * single schema. The exact semantics of the combination depends on the schema 636 * language that this {@link SchemaFactory} object is created for. 637 * 638 * <p> 639 * When an {@link ErrorHandler} is set, the callee will report all the errors 640 * found in sources to the handler. If the handler throws an exception, it will 641 * abort the schema compilation and the same exception will be thrown from 642 * this method. Also, after an error is reported to a handler, the callee is allowed 643 * to abort the further processing by throwing it. If an error handler is not set, 644 * the callee will throw the first error it finds in the sources. 645 * 646 * <h2>W3C XML Schema 1.0</h2> 647 * <p> 648 * The resulting schema contains components from the specified sources. 649 * The same result would be achieved if all these sources were 650 * imported, using appropriate values for schemaLocation and namespace, 651 * into a single schema document with a different targetNamespace 652 * and no components of its own, if the import elements were given 653 * in the same order as the sources. Section 4.2.3 of the XML Schema 654 * recommendation describes the options processors have in this 655 * regard. While a processor should be consistent in its treatment of 656 * JAXP schema sources and XML Schema imports, the behaviour between 657 * JAXP-compliant parsers may vary; in particular, parsers may choose 658 * to ignore all but the first <import> for a given namespace, 659 * regardless of information provided in schemaLocation. 660 * 661 * <p> 662 * If the parsed set of schemas includes error(s) as 663 * specified in the section 5.1 of the XML Schema spec, then 664 * the error must be reported to the {@link ErrorHandler}. 665 * 666 * <h2>RELAX NG</h2> 667 * 668 * <p>For RELAX NG, this method must throw {@link UnsupportedOperationException} 669 * if <code>schemas.length!=1</code>. 670 * 671 * 672 * @param schemas 673 * inputs to be parsed. {@link SchemaFactory} is required 674 * to recognize {@link javax.xml.transform.sax.SAXSource}, 675 * {@link StreamSource}, 676 * {@link javax.xml.transform.stax.StAXSource}, 677 * and {@link javax.xml.transform.dom.DOMSource}. 678 * Input schemas must be XML documents or 679 * XML elements and must not be null. For backwards compatibility, 680 * the results of passing anything other than 681 * a document or element are implementation-dependent. 682 * Implementations must either recognize and process the input 683 * or thrown an IllegalArgumentException. 684 * 685 * @return 686 * Always return a non-null valid {@link Schema} object. 687 * Note that when an error has been reported, there is no 688 * guarantee that the returned {@link Schema} object is 689 * meaningful. 690 * 691 * @throws SAXException 692 * If an error is found during processing the specified inputs. 693 * When an {@link ErrorHandler} is set, errors are reported to 694 * there first. See {@link #setErrorHandler(ErrorHandler)}. 695 * @throws NullPointerException 696 * If the <code>schemas</code> parameter itself is null or 697 * any item in the array is null. 698 * @throws IllegalArgumentException 699 * If any item in the array is not recognized by this method. 700 * @throws UnsupportedOperationException 701 * If the schema language doesn't support this operation. 702 */ 703 public abstract Schema newSchema(Source[] schemas) throws SAXException; 704 705 /** 706 * Creates a special {@link Schema} object. 707 * 708 * <p>The exact semantics of the returned {@link Schema} object 709 * depend on the schema language for which this {@link SchemaFactory} 710 * is created. 711 * 712 * <p>Also, implementations are allowed to use implementation-specific 713 * property/feature to alter the semantics of this method.</p> 714 * 715 * <p>Implementors and developers should pay particular attention 716 * to how the features set on this {@link SchemaFactory} are 717 * processed by this special {@link Schema}. 718 * In some cases, for example, when the 719 * {@link SchemaFactory} and the class actually loading the 720 * schema come from different implementations, it may not be possible 721 * for {@link SchemaFactory} features to be inherited automatically. 722 * Developers should 723 * make sure that features, such as secure processing, are explicitly 724 * set in both places.</p> 725 * 726 * <h2>W3C XML Schema 1.0</h2> 727 * <p> 728 * For XML Schema, this method creates a {@link Schema} object that 729 * performs validation by using location hints specified in documents. 730 * 731 * <p> 732 * The returned {@link Schema} object assumes that if documents 733 * refer to the same URL in the schema location hints, 734 * they will always resolve to the same schema document. This 735 * asusmption allows implementations to reuse parsed results of 736 * schema documents so that multiple validations against the same 737 * schema will run faster. 738 * 739 * <p> 740 * Note that the use of schema location hints introduces a 741 * vulnerability to denial-of-service attacks. 742 * 743 * 744 * <h2>RELAX NG</h2> 745 * <p> 746 * RELAX NG does not support this operation. 747 * 748 * @return 749 * Always return non-null valid {@link Schema} object. 750 * 751 * @throws UnsupportedOperationException 752 * If this operation is not supported by the callee. 753 * @throws SAXException 754 * If this operation is supported but failed for some reason. 755 */ 756 public abstract Schema newSchema() throws SAXException; 757 }