1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// $Id: SchemaFactory.java 884952 2009-11-27 18:55:08Z mrglavas $
19
20package javax.xml.validation;
21
22import java.io.File;
23import java.net.URL;
24import javax.xml.transform.Source;
25import javax.xml.transform.stream.StreamSource;
26import org.w3c.dom.ls.LSResourceResolver;
27import org.xml.sax.ErrorHandler;
28import org.xml.sax.SAXException;
29import org.xml.sax.SAXNotRecognizedException;
30import org.xml.sax.SAXNotSupportedException;
31
32/**
33 * Factory that creates {@link Schema} objects. Entry-point to
34 * the validation API.
35 *
36 * <p>
37 * {@link SchemaFactory} is a schema compiler. It reads external
38 * representations of schemas and prepares them for validation.
39 *
40 * <p>
41 * The {@link SchemaFactory} class is not thread-safe. In other words,
42 * it is the application's responsibility to ensure that at most
43 * one thread is using a {@link SchemaFactory} object at any
44 * given moment. Implementations are encouraged to mark methods
45 * as <tt>synchronized</tt> to protect themselves from broken clients.
46 *
47 * <p>
48 * {@link SchemaFactory} is not re-entrant. While one of the
49 * <code>newSchema</code> methods is being invoked, applications
50 * may not attempt to recursively invoke the <code>newSchema</code> method,
51 * even from the same thread.
52 *
53 * <h2><a name="schemaLanguage"></a>Schema Language</h2>
54 * <p>
55 * This spec uses a namespace URI to designate a schema language.
56 * The following table shows the values defined by this specification.
57 * <p>
58 * To be compliant with the spec, the implementation
59 * is only required to support W3C XML Schema 1.0. However,
60 * if it chooses to support other schema languages listed here,
61 * it must conform to the relevant behaviors described in this spec.
62 *
63 * <p>
64 * Schema languages not listed here are expected to
65 * introduce their own URIs to represent themselves.
66 * The {@link SchemaFactory} class is capable of locating other
67 * implementations for other schema languages at run-time.
68 *
69 * <p>
70 * Note that because the XML DTD is strongly tied to the parsing process
71 * and has a significant effect on the parsing process, it is impossible
72 * to define the DTD validation as a process independent from parsing.
73 * For this reason, this specification does not define the semantics for
74 * the XML DTD. This doesn't prohibit implementers from implementing it
75 * in a way they see fit, but <em>users are warned that any DTD
76 * validation implemented on this interface necessarily deviate from
77 * the XML DTD semantics as defined in the XML 1.0</em>.
78 *
79 * <table border="1" cellpadding="2">
80 *   <thead>
81 *     <tr>
82 *       <th>value</th>
83 *       <th>language</th>
84 *     </tr>
85 *   </thead>
86 *   <tbody>
87 *     <tr>
88 *       <td>{@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("<code>http://www.w3.org/2001/XMLSchema</code>")</td>
89 *       <td><a href="http://www.w3.org/TR/xmlschema-1">W3C XML Schema 1.0</a></td>
90 *     </tr>
91 *     <tr>
92 *       <td>{@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("<code>http://relaxng.org/ns/structure/1.0</code>")</td>
93 *       <td><a href="http://www.relaxng.org/">RELAX NG 1.0</a></td>
94 *     </tr>
95 *   </tbody>
96 * </table>
97 *
98 * @author  <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
99 * @version $Revision: 884952 $, $Date: 2009-11-27 10:55:08 -0800 (Fri, 27 Nov 2009) $
100 * @since 1.5
101 */
102public abstract class SchemaFactory {
103
104    /**
105     * <p>Constructor for derived classes.</p>
106     *
107     * <p>The constructor does nothing.</p>
108     *
109     * <p>Derived classes must create {@link SchemaFactory} objects that have
110     * <code>null</code> {@link ErrorHandler} and
111     * <code>null</code> {@link LSResourceResolver}.</p>
112     */
113    protected SchemaFactory() {
114    }
115
116    /**
117     * <p>Lookup an implementation of the <code>SchemaFactory</code> that supports the specified
118     * schema language and return it.</p>
119     *
120     * <p>To find a <code>SchemaFactory</code> object for a given schema language,
121     * this method looks the following places in the following order
122     * where "the class loader" refers to the context class loader:</p>
123     * <ol>
124     *  <li>
125     *     If the system property
126     *     <code>"javax.xml.validation.SchemaFactory:<i>schemaLanguage</i>"</code>
127     *     is present (where <i>schemaLanguage</i> is the parameter
128     *     to this method), then its value is read
129     *     as a class name. The method will try to
130     *     create a new instance of this class by using the class loader,
131     *     and returns it if it is successfully created.
132     *   </li>
133     *   <li>
134     *     <code>$java.home/lib/jaxp.properties</code> is read and
135     *     the value associated with the key being the system property above
136     *     is looked for. If present, the value is processed just like above.
137     *   </li>
138     *   <li>
139     *     <p>The class loader is asked for service provider provider-configuration files matching
140     *     <code>javax.xml.validation.SchemaFactory</code> in the resource directory META-INF/services.
141     *     See the JAR File Specification for file format and parsing rules.
142     *     Each potential service provider is required to implement the method:</p>
143     *     <pre>
144     *        {@link #isSchemaLanguageSupported(String schemaLanguage)}
145     *     </pre>
146     *     The first service provider found in class loader order that supports the specified schema language is returned.
147     *   </li>
148     *   <li>
149     *     Platform default <code>SchemaFactory</code> is located
150     *     in a implementation specific way. There must be a platform default
151     *     <code>SchemaFactory</code> for W3C XML Schema.
152     *   </li>
153     * </ol>
154     *
155     * <p>If everything fails, {@link IllegalArgumentException} will be thrown.</p>
156     *
157     * <p><strong>Tip for Trouble-shooting:</strong></p>
158     * <p>See {@link java.util.Properties#load(java.io.InputStream)} for
159     * exactly how a property file is parsed. In particular, colons ':'
160     * need to be escaped in a property file, so make sure schema language
161     * URIs are properly escaped in it. For example:</p>
162     * <pre>
163     * http\://www.w3.org/2001/XMLSchema=org.acme.foo.XSSchemaFactory
164     * </pre>
165     *
166     * @param schemaLanguage
167     *      Specifies the schema language which the returned
168     *      SchemaFactory will understand. See
169     *      <a href="#schemaLanguage">the list of available
170     *      schema languages</a> for the possible values.
171     *
172     * @return New instance of a <code>SchemaFactory</code>
173     *
174     * @throws IllegalArgumentException
175     *      If no implementation of the schema language is available.
176     *
177     * @throws NullPointerException
178     *      If the <tt>schemaLanguage</tt> parameter is null.
179     */
180    public static SchemaFactory newInstance(String schemaLanguage) {
181        ClassLoader cl;
182        cl = Thread.currentThread().getContextClassLoader();
183
184        if (cl == null) {
185            //cl = ClassLoader.getSystemClassLoader();
186            //use the current class loader
187            cl = SchemaFactory.class.getClassLoader();
188        }
189
190        SchemaFactory f = new SchemaFactoryFinder(cl).newFactory(schemaLanguage);
191        if (f == null) {
192            throw new IllegalArgumentException(schemaLanguage);
193        }
194        return f;
195    }
196
197    /**
198     * Returns an instance of the named implementation of {@code SchemaFactory}.
199     *
200     * @throws IllegalArgumentException if {@code factoryClassName} is not available, cannot be
201     *     instantiated, or doesn't support {@code schemaLanguage}.
202     * @since 1.6
203     */
204    public static SchemaFactory newInstance(String schemaLanguage, String factoryClassName,
205            ClassLoader classLoader) {
206        if (schemaLanguage == null) {
207            throw new NullPointerException("schemaLanguage == null");
208        } else if (factoryClassName == null) {
209            throw new NullPointerException("factoryClassName == null");
210        }
211        if (classLoader == null) {
212            classLoader = Thread.currentThread().getContextClassLoader();
213        }
214        try {
215            Class<?> type = classLoader != null
216                    ? classLoader.loadClass(factoryClassName)
217                    : Class.forName(factoryClassName);
218            SchemaFactory result = (SchemaFactory) type.newInstance();
219            if (result == null || !result.isSchemaLanguageSupported(schemaLanguage)) {
220                throw new IllegalArgumentException(schemaLanguage);
221            }
222            return result;
223        } catch (ClassNotFoundException e) {
224            throw new IllegalArgumentException(e);
225        } catch (InstantiationException e) {
226            throw new IllegalArgumentException(e);
227        } catch (IllegalAccessException e) {
228            throw new IllegalArgumentException(e);
229        }
230    }
231
232    /**
233     * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p>
234     *
235     * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand.
236     *    <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language.
237     *
238     * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>.
239     *
240     * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>.
241     * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code>
242     *   or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language.
243     */
244    public abstract boolean isSchemaLanguageSupported(String schemaLanguage);
245
246    /**
247     * Look up the value of a feature flag.
248     *
249     * <p>The feature name is any fully-qualified URI.  It is
250     * possible for a {@link SchemaFactory} to recognize a feature name but
251     * temporarily be unable to return its value.
252     *
253     * <p>Implementers are free (and encouraged) to invent their own features,
254     * using names built on their own URIs.</p>
255     *
256     * @param name The feature name, which is a non-null fully-qualified URI.
257     * @return The current value of the feature (true or false).
258     * @exception org.xml.sax.SAXNotRecognizedException If the feature
259     *            value can't be assigned or retrieved.
260     * @exception org.xml.sax.SAXNotSupportedException When the
261     *            {@link SchemaFactory} recognizes the feature name but
262     *            cannot determine its value at this time.
263     * @exception NullPointerException
264     *              if the name parameter is null.
265     * @see #setFeature(String, boolean)
266     */
267    public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
268
269        if (name == null) {
270            throw new NullPointerException("name == null");
271        }
272        throw new SAXNotRecognizedException(name);
273    }
274
275    /**
276     * Set the value of a feature flag.
277     *
278     * <p>
279     * Feature can be used to control the way a {@link SchemaFactory}
280     * parses schemas, although {@link SchemaFactory}s are not required
281     * to recognize any specific feature names.</p>
282     *
283     * <p>The feature name is any fully-qualified URI.  It is
284     * possible for a {@link SchemaFactory} to expose a feature value but
285     * to be unable to change the current value.</p>
286     *
287     * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
288     * When the feature is:</p>
289     * <ul>
290     *   <li>
291     *     <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
292     *     Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources.
293     *     If XML processing is limited for security reasons, it will be reported via a call to the registered
294     *     {@link ErrorHandler#fatalError(org.xml.sax.SAXParseException)}.
295     *     See {@link  #setErrorHandler(ErrorHandler errorHandler)}.
296     *   </li>
297     *   <li>
298     *     <code>false</code>: the implementation will processing XML according to the XML specifications without
299     *     regard to possible implementation limits.
300     *   </li>
301     * </ul>
302     *
303     * @param name The feature name, which is a non-null fully-qualified URI.
304     * @param value The requested value of the feature (true or false).
305     *
306     * @exception org.xml.sax.SAXNotRecognizedException If the feature
307     *            value can't be assigned or retrieved.
308     * @exception org.xml.sax.SAXNotSupportedException When the
309     *            {@link SchemaFactory} recognizes the feature name but
310     *            cannot set the requested value.
311     * @exception NullPointerException
312     *              if the name parameter is null.
313     *
314     * @see #getFeature(String)
315     */
316    public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
317        if (name == null) {
318            throw new NullPointerException("name == null");
319        }
320        throw new SAXNotRecognizedException(name);
321    }
322
323    /**
324     * Set the value of a property.
325     *
326     * <p>The property name is any fully-qualified URI.  It is
327     * possible for a {@link SchemaFactory} to recognize a property name but
328     * to be unable to change the current value.</p>
329     *
330     * <p>{@link SchemaFactory}s are not required to recognize setting
331     * any specific property names.</p>
332     *
333     * @param name The property name, which is a non-null fully-qualified URI.
334     * @param object The requested value for the property.
335     * @exception org.xml.sax.SAXNotRecognizedException If the property
336     *            value can't be assigned or retrieved.
337     * @exception org.xml.sax.SAXNotSupportedException When the
338     *            {@link SchemaFactory} recognizes the property name but
339     *            cannot set the requested value.
340     * @exception NullPointerException
341     *              if the name parameter is null.
342     */
343    public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException {
344        if (name == null) {
345            throw new NullPointerException("name == null");
346        }
347        throw new SAXNotRecognizedException(name);
348    }
349
350    /**
351     * Look up the value of a property.
352     *
353     * <p>The property name is any fully-qualified URI.  It is
354     * possible for a {@link SchemaFactory} to recognize a property name but
355     * temporarily be unable to return its value.</p>
356     *
357     * <p>{@link SchemaFactory}s are not required to recognize any specific
358     * property names.</p>
359     *
360     * <p>Implementers are free (and encouraged) to invent their own properties,
361     * using names built on their own URIs.</p>
362     *
363     * @param name The property name, which is a non-null fully-qualified URI.
364     * @return The current value of the property.
365     * @exception org.xml.sax.SAXNotRecognizedException If the property
366     *            value can't be assigned or retrieved.
367     * @exception org.xml.sax.SAXNotSupportedException When the
368     *            XMLReader recognizes the property name but
369     *            cannot determine its value at this time.
370     * @exception NullPointerException
371     *              if the name parameter is null.
372     * @see #setProperty(String, Object)
373     */
374    public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
375        if (name == null) {
376            throw new NullPointerException("name == null");
377        }
378        throw new SAXNotRecognizedException(name);
379    }
380
381    /**
382     * Sets the {@link ErrorHandler} to receive errors encountered
383     * during the <code>newSchema</code> method invocation.
384     *
385     * <p>
386     * Error handler can be used to customize the error handling process
387     * during schema parsing. When an {@link ErrorHandler} is set,
388     * errors found during the parsing of schemas will be first sent
389     * to the {@link ErrorHandler}.
390     *
391     * <p>
392     * The error handler can abort the parsing of a schema immediately
393     * by throwing {@link SAXException} from the handler. Or for example
394     * it can print an error to the screen and try to continue the
395     * processing by returning normally from the {@link ErrorHandler}
396     *
397     * <p>
398     * If any {@link Throwable} (or instances of its derived classes)
399     * is thrown from an {@link ErrorHandler},
400     * the caller of the <code>newSchema</code> method will be thrown
401     * the same {@link Throwable} object.
402     *
403     * <p>
404     * {@link SchemaFactory} is not allowed to
405     * throw {@link SAXException} without first reporting it to
406     * {@link ErrorHandler}.
407     *
408     * <p>
409     * Applications can call this method even during a {@link Schema}
410     * is being parsed.
411     *
412     * <p>
413     * When the {@link ErrorHandler} is null, the implementation will
414     * behave as if the following {@link ErrorHandler} is set:
415     * <pre>
416     * class DraconianErrorHandler implements {@link ErrorHandler} {
417     *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
418     *         throw e;
419     *     }
420     *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
421     *         throw e;
422     *     }
423     *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
424     *         // noop
425     *     }
426     * }
427     * </pre>
428     *
429     * <p>
430     * When a new {@link SchemaFactory} object is created, initially
431     * this field is set to null. This field will <em>NOT</em> be
432     * inherited to {@link Schema}s, {@link Validator}s, or
433     * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}.
434     *
435     *
436     * @param   errorHandler
437     *      A new error handler to be set. This parameter can be null.
438     */
439    public abstract void setErrorHandler(ErrorHandler errorHandler);
440
441    /**
442     * Gets the current {@link ErrorHandler} set to this {@link SchemaFactory}.
443     *
444     * @return
445     *      This method returns the object that was last set through
446     *      the {@link #setErrorHandler(ErrorHandler)} method, or null
447     *      if that method has never been called since this {@link SchemaFactory}
448     *      has created.
449     *
450     * @see #setErrorHandler(ErrorHandler)
451     */
452    public abstract ErrorHandler getErrorHandler();
453
454    /**
455     * Sets the {@link LSResourceResolver} to customize
456     * resource resolution when parsing schemas.
457     *
458     * <p>
459     * {@link SchemaFactory} uses a {@link LSResourceResolver}
460     * when it needs to locate external resources while parsing schemas,
461     * although exactly what constitutes "locating external resources" is
462     * up to each schema language. For example, for W3C XML Schema,
463     * this includes files <tt>&lt;include></tt>d or <tt>&lt;import></tt>ed,
464     * and DTD referenced from schema files, etc.
465     *
466     * <p>
467     * Applications can call this method even during a {@link Schema}
468     * is being parsed.
469     *
470     * <p>
471     * When the {@link LSResourceResolver} is null, the implementation will
472     * behave as if the following {@link LSResourceResolver} is set:
473     * <pre>
474     * class DumbDOMResourceResolver implements {@link LSResourceResolver} {
475     *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
476     *         String publicId, String systemId, String baseURI) {
477     *
478     *         return null; // always return null
479     *     }
480     * }
481     * </pre>
482     *
483     * <p>
484     * If a {@link LSResourceResolver} throws a {@link RuntimeException}
485     *  (or instances of its derived classes),
486     * then the {@link SchemaFactory} will abort the parsing and
487     * the caller of the <code>newSchema</code> method will receive
488     * the same {@link RuntimeException}.
489     *
490     * <p>
491     * When a new {@link SchemaFactory} object is created, initially
492     * this field is set to null.  This field will <em>NOT</em> be
493     * inherited to {@link Schema}s, {@link Validator}s, or
494     * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}.
495     *
496     * @param   resourceResolver
497     *      A new resource resolver to be set. This parameter can be null.
498     */
499    public abstract void setResourceResolver(LSResourceResolver resourceResolver);
500
501    /**
502     * Gets the current {@link LSResourceResolver} set to this {@link SchemaFactory}.
503     *
504     * @return
505     *      This method returns the object that was last set through
506     *      the {@link #setResourceResolver(LSResourceResolver)} method, or null
507     *      if that method has never been called since this {@link SchemaFactory}
508     *      has created.
509     *
510     * @see #setErrorHandler(ErrorHandler)
511     */
512    public abstract LSResourceResolver getResourceResolver();
513
514    /**
515     * <p>Parses the specified source as a schema and returns it as a schema.</p>
516     *
517     * <p>This is a convenience method for {@link #newSchema(Source[] schemas)}.</p>
518     *
519     * @param schema Source that represents a schema.
520     *
521     * @return New <code>Schema</code> from parsing <code>schema</code>.
522     *
523     * @throws SAXException If a SAX error occurs during parsing.
524     * @throws NullPointerException if <tt>schema</tt> is null.
525     */
526    public Schema newSchema(Source schema) throws SAXException {
527        return newSchema(new Source[]{schema});
528    }
529
530    /**
531     * <p>Parses the specified <code>File</code> as a schema and returns it as a <code>Schema</code>.</p>
532     *
533     * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p>
534     *
535     * @param schema File that represents a schema.
536     *
537     * @return New <code>Schema</code> from parsing <code>schema</code>.
538     *
539     * @throws SAXException If a SAX error occurs during parsing.
540     * @throws NullPointerException if <tt>schema</tt> is null.
541     */
542    public Schema newSchema(File schema) throws SAXException {
543        return newSchema(new StreamSource(schema));
544    }
545
546    /**
547     * <p>Parses the specified <code>URL</code> as a schema and returns it as a <code>Schema</code>.</p>
548     *
549     * <p>This is a convenience method for {@link #newSchema(Source schema)}.</p>
550     *
551     * @param schema <code>URL</code> that represents a schema.
552     *
553     * @return New <code>Schema</code> from parsing <code>schema</code>.
554     *
555     * @throws SAXException If a SAX error occurs during parsing.
556     * @throws NullPointerException if <tt>schema</tt> is null.
557     */
558    public Schema newSchema(URL schema) throws SAXException {
559        return newSchema(new StreamSource(schema.toExternalForm()));
560    }
561
562    /**
563     * Parses the specified source(s) as a schema and returns it as a schema.
564     *
565     * <p>
566     * The callee will read all the {@link Source}s and combine them into a
567     * single schema. The exact semantics of the combination depends on the schema
568     * language that this {@link SchemaFactory} object is created for.
569     *
570     * <p>
571     * When an {@link ErrorHandler} is set, the callee will report all the errors
572     * found in sources to the handler. If the handler throws an exception, it will
573     * abort the schema compilation and the same exception will be thrown from
574     * this method. Also, after an error is reported to a handler, the callee is allowed
575     * to abort the further processing by throwing it. If an error handler is not set,
576     * the callee will throw the first error it finds in the sources.
577     *
578     * <h2>W3C XML Schema 1.0</h2>
579     * <p>
580     * The resulting schema contains components from the specified sources.
581     * The same result would be achieved if all these sources were
582     * imported, using appropriate values for schemaLocation and namespace,
583     * into a single schema document with a different targetNamespace
584     * and no components of its own, if the import elements were given
585     * in the same order as the sources.  Section 4.2.3 of the XML Schema
586     * recommendation describes the options processors have in this
587     * regard.  While a processor should be consistent in its treatment of
588     * JAXP schema sources and XML Schema imports, the behavior between
589     * JAXP-compliant parsers may vary; in particular, parsers may choose
590     * to ignore all but the first &lt;import> for a given namespace,
591     * regardless of information provided in schemaLocation.
592     *
593     * <p>
594     * If the parsed set of schemas includes error(s) as
595     * specified in the section 5.1 of the XML Schema spec, then
596     * the error must be reported to the {@link ErrorHandler}.
597     *
598     * <h2>RELAX NG</h2>
599     *
600     * <p>For RELAX NG, this method must throw {@link UnsupportedOperationException}
601     * if <tt>schemas.length!=1</tt>.
602     *
603     *
604     * @param schemas
605     *      inputs to be parsed. {@link SchemaFactory} is required
606     *      to recognize {@link StreamSource},
607     *      {@link javax.xml.transform.sax.SAXSource},
608     *      and {@link javax.xml.transform.dom.DOMSource}.
609     *
610     * @return
611     *      Always return a non-null valid {@link Schema} object.
612     *      Note that when an error has been reported, there is no
613     *      guarantee that the returned {@link Schema} object is
614     *      meaningful.
615     *
616     * @throws SAXException
617     *      If an error is found during processing the specified inputs.
618     *      When an {@link ErrorHandler} is set, errors are reported to
619     *      there first. See {@link #setErrorHandler(ErrorHandler)}.
620     * @throws NullPointerException
621     *      If the <code>schemas</code> parameter itself is null or
622     *      any item in the array is null.
623     * @throws IllegalArgumentException
624     *      If any item in the array is not recognized by this method.
625     * @throws UnsupportedOperationException
626     *      If the schema language doesn't support this operation.
627     */
628    public abstract Schema newSchema(Source[] schemas) throws SAXException;
629
630    /**
631     * Creates a special {@link Schema} object.
632     *
633     * <p>
634     * The exact semantics of the returned {@link Schema} object depends
635     * on the schema language that this {@link SchemaFactory} is created
636     * for.
637     *
638     * <p>
639     * Also, implementations are allowed to use implementation-specific
640     * property/feature to alter the semantics of this method.
641     *
642     *
643     * <h2>W3C XML Schema 1.0</h2>
644     * <p>
645     * For XML Schema, this method creates a {@link Schema} object that
646     * performs validation by using location hints specified in documents.
647     *
648     * <p>
649     * The returned {@link Schema} object assumes that if documents
650     * refer to the same URL in the schema location hints,
651     * they will always resolve to the same schema document. This
652     * assumption allows implementations to reuse parsed results of
653     * schema documents so that multiple validations against the same
654     * schema will run faster.
655     *
656     * <p>
657     * Note that the use of schema location hints introduces a
658     * vulnerability to denial-of-service attacks.
659     *
660     *
661     * <h2>RELAX NG</h2>
662     * <p>
663     * RELAX NG does not support this operation.
664     *
665     * @return
666     *      Always return non-null valid {@link Schema} object.
667     *
668     * @throws UnsupportedOperationException
669     *      If this operation is not supported by the callee.
670     * @throws SAXException
671     *      If this operation is supported but failed for some reason.
672     */
673    public abstract Schema newSchema() throws SAXException;
674}
675