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