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
26package javax.xml.validation;
27
28import java.io.IOException;
29
30import javax.xml.transform.Result;
31import javax.xml.transform.Source;
32
33import org.w3c.dom.ls.LSResourceResolver;
34import org.xml.sax.ErrorHandler;
35import org.xml.sax.SAXException;
36import org.xml.sax.SAXNotRecognizedException;
37import org.xml.sax.SAXNotSupportedException;
38
39/**
40 * A processor that checks an XML document against {@link Schema}.
41 *
42 * <p>
43 * A validator object is not thread-safe and not reentrant.
44 * In other words, it is the application's responsibility to make
45 * sure that one {@link Validator} object is not used from
46 * more than one thread at any given time, and while the {@code validate}
47 * method is invoked, applications may not recursively call
48 * the {@code validate} method.
49 *
50 *
51 * @author  <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
52 * @since 1.5
53 */
54public abstract class Validator {
55
56    /**
57     * Constructor for derived classes.
58     *
59     * <p>The constructor does nothing.
60     *
61     * <p>Derived classes must create {@link Validator} objects that have
62     * {@code null} {@link ErrorHandler} and
63     * {@code null} {@link LSResourceResolver}.
64     */
65    protected Validator() {
66    }
67
68        /**
69         * Reset this {@code Validator} to its original configuration.
70         *
71         * <p>{@code Validator} is reset to the same state as when it was created with
72         * {@link Schema#newValidator()}.
73         * {@code reset()} is designed to allow the reuse of existing {@code Validator}s
74         * thus saving resources associated with the creation of new {@code Validator}s.
75         *
76         * <p>The reset {@code Validator} is not guaranteed to have
77         * the same {@link LSResourceResolver} or {@link ErrorHandler}
78         * {@code Object}s, e.g. {@link Object#equals(Object obj)}.
79         * It is guaranteed to have a functionally equal
80         * {@code LSResourceResolver} and {@code ErrorHandler}.
81         */
82        public abstract void reset();
83
84    /**
85     * Validates the specified input.
86     *
87     * <p>This is just a convenience method for
88     * {@link #validate(Source source, Result result)}
89     * with {@code result} of {@code null}.
90     *
91     * @param source
92     *      XML to be validated. Must be an XML document or
93     *      XML element and must not be null. For backwards compatibility,
94     *      the results of attempting to validate anything other than
95     *      a document or element are implementation-dependent.
96     *      Implementations must either recognize and process the input
97     *      or throw an IllegalArgumentException.
98     *
99     * @throws IllegalArgumentException
100     *      If the {@code Source}
101     *      is an XML artifact that the implementation cannot
102     *      validate (for example, a processing instruction).
103     *
104     * @throws SAXException
105     *      If the {@link ErrorHandler} throws a {@link SAXException} or
106     *      if a fatal error is found and the {@link ErrorHandler} returns
107     *      normally.
108     *
109     * @throws IOException
110     *      If the validator is processing a
111     *      {@link javax.xml.transform.sax.SAXSource} and the
112     *      underlying {@link org.xml.sax.XMLReader} throws an
113     *      {@link IOException}.
114     *
115     *
116     * @throws NullPointerException If {@code source} is
117     *   {@code null}.
118     *
119     * @see #validate(Source source, Result result)
120     */
121    public void validate(Source source)
122        throws SAXException, IOException {
123
124        validate(source, null);
125    }
126
127    /**
128     * Validates the specified input and send the augmented validation
129     * result to the specified output.
130     *
131     * <p>This method places the following restrictions on the types of
132     * the {@link Source}/{@link Result} accepted.
133     *
134     * <table class="plain">
135     * <caption>{@code Source} / {@code Result} Accepted</caption>
136     * <thead>
137     *  <tr>
138     *   <td></td>
139     *   <th scope="col">{@link javax.xml.transform.stream.StreamSource}</th>
140     *   <th scope="col">{@link javax.xml.transform.sax.SAXSource}</th>
141     *   <th scope="col">{@link javax.xml.transform.dom.DOMSource}</th>
142     *   <th scope="col">{@link javax.xml.transform.stax.StAXSource}</th>
143     *  </tr>
144     * </thead>
145     * <tbody style="text-align:center">
146     *  <tr>
147     *   <th scope="row">{@code null}</th>
148     *   <td>OK</td>
149     *   <td>OK</td>
150     *   <td>OK</td>
151     *   <td>OK</td>
152     *  </tr>
153     *  <tr>
154     *   <th scope="row">{@link javax.xml.transform.stream.StreamResult}</th>
155     *   <td>OK</td>
156     *   <td>{@code IllegalArgumentException}</td>
157     *   <td>{@code IllegalArgumentException}</td>
158     *   <td>{@code IllegalArgumentException}</td>
159     *  </tr>
160     *  <tr>
161     *   <th scope="row">{@link javax.xml.transform.sax.SAXResult}</th>
162     *   <td>{@code IllegalArgumentException}</td>
163     *   <td>OK</td>
164     *   <td>{@code IllegalArgumentException}</td>
165     *   <td>{@code IllegalArgumentException}</td>
166     *  </tr>
167     *  <tr>
168     *   <th scope="row">{@link javax.xml.transform.dom.DOMResult}</th>
169     *   <td>{@code IllegalArgumentException}</td>
170     *   <td>{@code IllegalArgumentException}</td>
171     *   <td>OK</td>
172     *   <td>{@code IllegalArgumentException}</td>
173     *  </tr>
174     *  <tr>
175     *   <th scope="row">{@link javax.xml.transform.stax.StAXResult}</th>
176     *   <td>{@code IllegalArgumentException}</td>
177     *   <td>{@code IllegalArgumentException}</td>
178     *   <td>{@code IllegalArgumentException}</td>
179     *   <td>OK</td>
180     *  </tr>
181     * </tbody>
182     * </table>
183     *
184     * <p>To validate one {@code Source} into another kind of
185     * {@code Result}, use the identity transformer (see
186     * {@link javax.xml.transform.TransformerFactory#newTransformer()}).
187     *
188     * <p>Errors found during the validation is sent to the specified
189     * {@link ErrorHandler}.
190     *
191     * <p>If a document is valid, or if a document contains some errors
192     * but none of them were fatal and the {@code ErrorHandler} didn't
193     * throw any exception, then the method returns normally.
194     *
195     * @param source
196     *      XML to be validated. Must be an XML document or
197     *      XML element and must not be null. For backwards compatibility,
198     *      the results of attempting to validate anything other than
199     *      a document or element are implementation-dependent.
200     *      Implementations must either recognize and process the input
201     *      or throw an IllegalArgumentException.
202     *
203     * @param result
204     *      The {@code Result} object that receives (possibly augmented)
205     *      XML. This parameter can be null if the caller is not interested
206     *      in it.
207     *
208     *      Note that when a {@code DOMResult} is used,
209     *      a validator might just pass the same DOM node from
210     *      {@code DOMSource} to {@code DOMResult}
211     *      (in which case {@code source.getNode()==result.getNode()}),
212     *      it might copy the entire DOM tree, or it might alter the
213     *      node given by the source.
214     *
215     * @throws IllegalArgumentException
216     *      If the {@code Result} type doesn't match the
217     *      {@code Source} type of if the {@code Source}
218     *      is an XML artifact that the implementation cannot
219     *      validate (for example, a processing instruction).
220     * @throws SAXException
221     *      If the {@code ErrorHandler} throws a
222     *      {@code SAXException} or
223     *      if a fatal error is found and the {@code ErrorHandler} returns
224     *      normally.
225     * @throws IOException
226     *      If the validator is processing a
227     *      {@code SAXSource} and the
228     *      underlying {@link org.xml.sax.XMLReader} throws an
229     *      {@code IOException}.
230     * @throws NullPointerException
231     *      If the {@code source} parameter is {@code null}.
232     *
233     * @see #validate(Source source)
234     */
235    public abstract void validate(Source source, Result result)
236        throws SAXException, IOException;
237
238    /**
239     * Sets the {@link ErrorHandler} to receive errors encountered
240     * during the {@code validate} method invocation.
241     *
242     * <p>
243     * Error handler can be used to customize the error handling process
244     * during a validation. When an {@link ErrorHandler} is set,
245     * errors found during the validation will be first sent
246     * to the {@link ErrorHandler}.
247     *
248     * <p>
249     * The error handler can abort further validation immediately
250     * by throwing {@link SAXException} from the handler. Or for example
251     * it can print an error to the screen and try to continue the
252     * validation by returning normally from the {@link ErrorHandler}
253     *
254     * <p>
255     * If any {@link Throwable} is thrown from an {@link ErrorHandler},
256     * the caller of the {@code validate} method will be thrown
257     * the same {@link Throwable} object.
258     *
259     * <p>
260     * {@link Validator} is not allowed to
261     * throw {@link SAXException} without first reporting it to
262     * {@link ErrorHandler}.
263     *
264     * <p>
265     * When the {@link ErrorHandler} is null, the implementation will
266     * behave as if the following {@link ErrorHandler} is set:
267     * <pre>
268     * class DraconianErrorHandler implements {@link ErrorHandler} {
269     *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
270     *         throw e;
271     *     }
272     *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
273     *         throw e;
274     *     }
275     *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
276     *         // noop
277     *     }
278     * }
279     * </pre>
280     *
281     * <p>
282     * When a new {@link Validator} object is created, initially
283     * this field is set to null.
284     *
285     * @param   errorHandler
286     *      A new error handler to be set. This parameter can be null.
287     */
288    public abstract void setErrorHandler(ErrorHandler errorHandler);
289
290    /**
291     * Gets the current {@link ErrorHandler} set to this {@link Validator}.
292     *
293     * @return
294     *      This method returns the object that was last set through
295     *      the {@link #setErrorHandler(ErrorHandler)} method, or null
296     *      if that method has never been called since this {@link Validator}
297     *      has created.
298     *
299     * @see #setErrorHandler(ErrorHandler)
300     */
301    public abstract ErrorHandler getErrorHandler();
302
303    /**
304     * Sets the {@link LSResourceResolver} to customize
305     * resource resolution while in a validation episode.
306     *
307     * <p>
308     * {@link Validator} uses a {@link LSResourceResolver}
309     * when it needs to locate external resources while a validation,
310     * although exactly what constitutes "locating external resources" is
311     * up to each schema language.
312     *
313     * <p>
314     * When the {@link LSResourceResolver} is null, the implementation will
315     * behave as if the following {@link LSResourceResolver} is set:
316     * <pre>
317     * class DumbLSResourceResolver implements {@link LSResourceResolver} {
318     *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
319     *         String publicId, String systemId, String baseURI) {
320     *
321     *         return null; // always return null
322     *     }
323     * }
324     * </pre>
325     *
326     * <p>
327     * If a {@link LSResourceResolver} throws a {@link RuntimeException}
328     *  (or instances of its derived classes),
329     * then the {@link Validator} will abort the parsing and
330     * the caller of the {@code validate} method will receive
331     * the same {@link RuntimeException}.
332     *
333     * <p>
334     * When a new {@link Validator} object is created, initially
335     * this field is set to null.
336     *
337     * @param   resourceResolver
338     *      A new resource resolver to be set. This parameter can be null.
339     */
340    public abstract void setResourceResolver(LSResourceResolver resourceResolver);
341
342    /**
343     * Gets the current {@link LSResourceResolver} set to this {@link Validator}.
344     *
345     * @return
346     *      This method returns the object that was last set through
347     *      the {@link #setResourceResolver(LSResourceResolver)} method, or null
348     *      if that method has never been called since this {@link Validator}
349     *      has created.
350     *
351     * @see #setErrorHandler(ErrorHandler)
352     */
353    public abstract LSResourceResolver getResourceResolver();
354
355
356
357    /**
358     * Look up the value of a feature flag.
359     *
360     * <p>The feature name is any fully-qualified URI.  It is
361     * possible for a {@link Validator} to recognize a feature name but
362     * temporarily be unable to return its value.
363     * Some feature values may be available only in specific
364     * contexts, such as before, during, or after a validation.
365     *
366     * <p>Implementors are free (and encouraged) to invent their own features,
367     * using names built on their own URIs.
368     *
369     * @param name The feature name, which is a non-null fully-qualified URI.
370     *
371     * @return The current value of the feature (true or false).
372     *
373     * @throws SAXNotRecognizedException If the feature
374     *   value can't be assigned or retrieved.
375     * @throws SAXNotSupportedException When the
376     *   {@link Validator} recognizes the feature name but
377     *   cannot determine its value at this time.
378     * @throws NullPointerException
379     *   When the name parameter is null.
380     *
381     * @see #setFeature(String, boolean)
382     */
383    public boolean getFeature(String name)
384        throws SAXNotRecognizedException, SAXNotSupportedException {
385
386        if (name == null) {
387            throw new NullPointerException("the name parameter is null");
388        }
389
390        throw new SAXNotRecognizedException(name);
391    }
392
393    /**
394     * Set the value of a feature flag.
395     *
396     * <p>
397     * Feature can be used to control the way a {@link Validator}
398     * parses schemas, although {@link Validator}s are not required
399     * to recognize any specific feature names.
400     *
401     * <p>The feature name is any fully-qualified URI.  It is
402     * possible for a {@link Validator} to expose a feature value but
403     * to be unable to change the current value.
404     * Some feature values may be immutable or mutable only
405     * in specific contexts, such as before, during, or after
406     * a validation.
407     *
408     * @param name The feature name, which is a non-null fully-qualified URI.
409     * @param value The requested value of the feature (true or false).
410     *
411     * @throws SAXNotRecognizedException If the feature
412     *   value can't be assigned or retrieved.
413     * @throws SAXNotSupportedException When the
414     *   {@link Validator} recognizes the feature name but
415     *   cannot set the requested value.
416     * @throws NullPointerException
417     *   When the name parameter is null.
418     *
419     * @see #getFeature(String)
420     */
421    public void setFeature(String name, boolean value)
422        throws SAXNotRecognizedException, SAXNotSupportedException {
423
424        if (name == null) {
425            throw new NullPointerException("the name parameter is null");
426        }
427
428        throw new SAXNotRecognizedException(name);
429    }
430
431    /**
432     * Set the value of a property.
433     *
434     * <p>The property name is any fully-qualified URI.  It is
435     * possible for a {@link Validator} to recognize a property name but
436     * to be unable to change the current value.
437     * Some property values may be immutable or mutable only
438     * in specific contexts, such as before, during, or after
439     * a validation.
440     *
441     * <p>
442     * All implementations that implement JAXP 1.5 or newer are required to
443     * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
444     * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
445     *
446     * <ul>
447     *   <li>
448     *      <p>Access to external DTDs in source or Schema file is restricted to
449     *      the protocols specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD}
450     *      property.  If access is denied during validation due to the restriction
451     *      of this property, {@link org.xml.sax.SAXException} will be thrown by the
452     *      {@link #validate(Source)} method.
453     *
454     *      <p>Access to external reference set by the schemaLocation attribute is
455     *      restricted to the protocols specified by the
456     *      {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property.
457     *      If access is denied during validation due to the restriction of this property,
458     *      {@link org.xml.sax.SAXException} will be thrown by the
459     *      {@link #validate(Source)} method.
460     *   </li>
461     * </ul>
462     *
463     * @param name The property name, which is a non-null fully-qualified URI.
464     * @param object The requested value for the property.
465     *
466     * @throws SAXNotRecognizedException If the property
467     *   value can't be assigned or retrieved.
468     * @throws SAXNotSupportedException When the
469     *   {@link Validator} recognizes the property name but
470     *   cannot set the requested value.
471     * @throws NullPointerException
472     *   When the name parameter is null.
473     */
474    public void setProperty(String name, Object object)
475        throws SAXNotRecognizedException, SAXNotSupportedException {
476
477        if (name == null) {
478            throw new NullPointerException("the name parameter is null");
479        }
480
481        throw new SAXNotRecognizedException(name);
482    }
483
484    /**
485     * Look up the value of a property.
486     *
487     * <p>The property name is any fully-qualified URI.  It is
488     * possible for a {@link Validator} to recognize a property name but
489     * temporarily be unable to return its value.
490     * Some property values may be available only in specific
491     * contexts, such as before, during, or after a validation.
492     *
493     * <p>{@link Validator}s are not required to recognize any specific
494     * property names.
495     *
496     * <p>Implementors are free (and encouraged) to invent their own properties,
497     * using names built on their own URIs.
498     *
499     * @param name The property name, which is a non-null fully-qualified URI.
500     *
501     * @return The current value of the property.
502     *
503     * @throws SAXNotRecognizedException If the property
504     *   value can't be assigned or retrieved.
505     * @throws SAXNotSupportedException When the
506     *   XMLReader recognizes the property name but
507     *   cannot determine its value at this time.
508     * @throws NullPointerException
509     *   When the name parameter is null.
510     *
511     * @see #setProperty(String, Object)
512     */
513    public Object getProperty(String name)
514        throws SAXNotRecognizedException, SAXNotSupportedException {
515
516        if (name == null) {
517            throw new NullPointerException("the name parameter is null");
518        }
519
520        throw new SAXNotRecognizedException(name);
521    }
522}
523