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