001 /*
002 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.xml.validation;
027
028 import java.io.IOException;
029
030 import javax.xml.transform.Result;
031 import javax.xml.transform.Source;
032
033 import org.w3c.dom.ls.LSResourceResolver;
034 import org.xml.sax.ErrorHandler;
035 import org.xml.sax.SAXException;
036 import org.xml.sax.SAXNotRecognizedException;
037 import org.xml.sax.SAXNotSupportedException;
038
039 /**
040 * <p>A processor that checks an XML document against {@link Schema}.</p>
041 *
042 * <p>
043 * A validator object is not thread-safe and not reentrant.
044 * In other words, it is the application's responsibility to make
045 * sure that one {@link Validator} object is not used from
046 * more than one thread at any given time, and while the <code>validate</code>
047 * method is invoked, applications may not recursively call
048 * the <code>validate</code> method.
049 * <p>
050 *
051 *
052 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
053 * @version $Revision: 1.4 $, $Date: 2005/10/13 17:00:48 $
054 * @since 1.5
055 */
056 public abstract class Validator {
057
058 /**
059 * Constructor for derived classes.
060 *
061 * <p>The constructor does nothing.</p>
062 *
063 * <p>Derived classes must create {@link Validator} objects that have
064 * <code>null</code> {@link ErrorHandler} and
065 * <code>null</code> {@link LSResourceResolver}.
066 * </p>
067 */
068 protected Validator() {
069 }
070
071 /**
072 * <p>Reset this <code>Validator</code> to its original configuration.</p>
073 *
074 * <p><code>Validator</code> is reset to the same state as when it was created with
075 * {@link Schema#newValidator()}.
076 * <code>reset()</code> is designed to allow the reuse of existing <code>Validator</code>s
077 * thus saving resources associated with the creation of new <code>Validator</code>s.</p>
078 *
079 * <p>The reset <code>Validator</code> is not guaranteed to have the same {@link LSResourceResolver} or {@link ErrorHandler}
080 * <code>Object</code>s, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal
081 * <code>LSResourceResolver</code> and <code>ErrorHandler</code>.</p>
082 */
083 public abstract void reset();
084
085 /**
086 * Validates the specified input.
087 *
088 * <p>This is just a convenience method for
089 * {@link #validate(Source source, Result result)}
090 * with <code>result</code> of <code>null</code>.</p>
091 *
092 * @param source
093 * XML to be validated. Must be an XML document or
094 * XML element and must not be null. For backwards compatibility,
095 * the results of attempting to validate anything other than
096 * a document or element are implementation-dependent.
097 * Implementations must either recognize and process the input
098 * or throw an IllegalArgumentException.
099 *
100 * @throws IllegalArgumentException
101 * If the <code>Source</code>
102 * is an XML artifact that the implementation cannot
103 * validate (for example, a processing instruction).
104 *
105 * @throws SAXException
106 * If the {@link ErrorHandler} throws a {@link SAXException} or
107 * if a fatal error is found and the {@link ErrorHandler} returns
108 * normally.
109 *
110 * @throws IOException
111 * If the validator is processing a
112 * {@link javax.xml.transform.sax.SAXSource} and the
113 * underlying {@link org.xml.sax.XMLReader} throws an
114 * {@link IOException}.
115 *
116 *
117 * @throws NullPointerException If <code>source</code> is
118 * <code>null</code>.
119 *
120 * @see #validate(Source source, Result result)
121 */
122 public void validate(Source source) throws SAXException,
123 IOException {
124
125 validate(source, null);
126 }
127
128 /**
129 * <p>Validates the specified input and send the augmented validation
130 * result to the specified output.</p>
131 *
132 * <p>This method places the following restrictions on the types of
133 * the {@link Source}/{@link Result} accepted.</p>
134 *
135 * <table border=1>
136 * <thead>
137 * <tr>
138 * <th colspan="5"><code>Source</code> / <code>Result</code> Accepted</th>
139 * </tr>
140 * <tr>
141 * <th></th>
142 * <th>{@link javax.xml.transform.stream.StreamSource}</th>
143 * <th>{@link javax.xml.transform.sax.SAXSource}</th>
144 * <th>{@link javax.xml.transform.dom.DOMSource}</th>
145 * <th>{@link javax.xml.transform.stax.StAXSource}</th>
146 * </tr>
147 * </thead>
148 * <tbody align="center">
149 * <tr>
150 * <td><code>null</code></td>
151 * <td>OK</td>
152 * <td>OK</td>
153 * <td>OK</td>
154 * <td>OK</td>
155 * </tr>
156 * <tr>
157 * <th>{@link javax.xml.transform.stream.StreamResult}</th>
158 * <td>OK</td>
159 * <td><code>IllegalArgumentException</code></td>
160 * <td><code>IllegalArgumentException</code></td>
161 * <td><code>IllegalArgumentException</code></td>
162 * </tr>
163 * <tr>
164 * <th>{@link javax.xml.transform.sax.SAXResult}</th>
165 * <td><code>IllegalArgumentException</code></td>
166 * <td>OK</td>
167 * <td><code>IllegalArgumentException</code></td>
168 * <td><code>IllegalArgumentException</code></td>
169 * </tr>
170 * <tr>
171 * <th>{@link javax.xml.transform.dom.DOMResult}</th>
172 * <td><code>IllegalArgumentException</code></td>
173 * <td><code>IllegalArgumentException</code></td>
174 * <td>OK</td>
175 * <td><code>IllegalArgumentException</code></td>
176 * </tr>
177 * <tr>
178 * <th>{@link javax.xml.transform.stax.StAXResult}</th>
179 * <td><code>IllegalArgumentException</code></td>
180 * <td><code>IllegalArgumentException</code></td>
181 * <td><code>IllegalArgumentException</code></td>
182 * <td>OK</td>
183 * </tr>
184 * </tbody>
185 * </table>
186 *
187 * <p>To validate one <code>Source</code> into another kind of
188 * <code>Result</code>, use the identity transformer (see
189 * {@link javax.xml.transform.TransformerFactory#newTransformer()}).</p>
190 *
191 * <p>Errors found during the validation is sent to the specified
192 * {@link ErrorHandler}.</p>
193 *
194 * <p>If a document is valid, or if a document contains some errors
195 * but none of them were fatal and the <code>ErrorHandler</code> didn't
196 * throw any exception, then the method returns normally.</p>
197 *
198 * @param source
199 * XML to be validated. Must be an XML document or
200 * XML element and must not be null. For backwards compatibility,
201 * the results of attempting to validate anything other than
202 * a document or element are implementation-dependent.
203 * Implementations must either recognize and process the input
204 * or throw an IllegalArgumentException.
205 *
206 * @param result
207 * The <code>Result</code> object that receives (possibly augmented)
208 * XML. This parameter can be null if the caller is not interested
209 * in it.
210 *
211 * Note that when a <code>DOMResult</code> is used,
212 * a validator might just pass the same DOM node from
213 * <code>DOMSource</code> to <code>DOMResult</code>
214 * (in which case <code>source.getNode()==result.getNode()</code>),
215 * it might copy the entire DOM tree, or it might alter the
216 * node given by the source.
217 *
218 * @throws IllegalArgumentException
219 * If the <code>Result</code> type doesn't match the
220 * <code>Source</code> type of if the <code>Source</code>
221 * is an XML artifact that the implementation cannot
222 * validate (for example, a processing instruction).
223 * @throws SAXException
224 * If the <code>ErrorHandler</code> throws a
225 * <code>SAXException</code> or
226 * if a fatal error is found and the <code>ErrorHandler</code> returns
227 * normally.
228 * @throws IOException
229 * If the validator is processing a
230 * <code>SAXSource</code> and the
231 * underlying {@link org.xml.sax.XMLReader} throws an
232 * <code>IOException</code>.
233 * @throws NullPointerException
234 * If the <code>source</code> parameter is <code>null</code>.
235 *
236 * @see #validate(Source source)
237 */
238 public abstract void validate(Source source, Result result)
239 throws SAXException, IOException;
240
241 /**
242 * Sets the {@link ErrorHandler} to receive errors encountered
243 * during the <code>validate</code> method invocation.
244 *
245 * <p>
246 * Error handler can be used to customize the error handling process
247 * during a validation. When an {@link ErrorHandler} is set,
248 * errors found during the validation will be first sent
249 * to the {@link ErrorHandler}.
250 *
251 * <p>
252 * The error handler can abort further validation immediately
253 * by throwing {@link SAXException} from the handler. Or for example
254 * it can print an error to the screen and try to continue the
255 * validation by returning normally from the {@link ErrorHandler}
256 *
257 * <p>
258 * If any {@link Throwable} is thrown from an {@link ErrorHandler},
259 * the caller of the <code>validate</code> method will be thrown
260 * the same {@link Throwable} object.
261 *
262 * <p>
263 * {@link Validator} is not allowed to
264 * throw {@link SAXException} without first reporting it to
265 * {@link ErrorHandler}.
266 *
267 * <p>
268 * When the {@link ErrorHandler} is null, the implementation will
269 * behave as if the following {@link ErrorHandler} is set:
270 * <pre>
271 * class DraconianErrorHandler implements {@link ErrorHandler} {
272 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
273 * throw e;
274 * }
275 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
276 * throw e;
277 * }
278 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
279 * // noop
280 * }
281 * }
282 * </pre>
283 *
284 * <p>
285 * When a new {@link Validator} object is created, initially
286 * this field is set to null.
287 *
288 * @param errorHandler
289 * A new error handler to be set. This parameter can be null.
290 */
291 public abstract void setErrorHandler(ErrorHandler errorHandler);
292
293 /**
294 * Gets the current {@link ErrorHandler} set to this {@link Validator}.
295 *
296 * @return
297 * This method returns the object that was last set through
298 * the {@link #setErrorHandler(ErrorHandler)} method, or null
299 * if that method has never been called since this {@link Validator}
300 * has created.
301 *
302 * @see #setErrorHandler(ErrorHandler)
303 */
304 public abstract ErrorHandler getErrorHandler();
305
306 /**
307 * Sets the {@link LSResourceResolver} to customize
308 * resource resolution while in a validation episode.
309 *
310 * <p>
311 * {@link Validator} uses a {@link LSResourceResolver}
312 * when it needs to locate external resources while a validation,
313 * although exactly what constitutes "locating external resources" is
314 * up to each schema language.
315 *
316 * <p>
317 * When the {@link LSResourceResolver} is null, the implementation will
318 * behave as if the following {@link LSResourceResolver} is set:
319 * <pre>
320 * class DumbLSResourceResolver implements {@link LSResourceResolver} {
321 * public {@link org.w3c.dom.ls.LSInput} resolveResource(
322 * String publicId, String systemId, String baseURI) {
323 *
324 * return null; // always return null
325 * }
326 * }
327 * </pre>
328 *
329 * <p>
330 * If a {@link LSResourceResolver} throws a {@link RuntimeException}
331 * (or instances of its derived classes),
332 * then the {@link Validator} will abort the parsing and
333 * the caller of the <code>validate</code> method will receive
334 * the same {@link RuntimeException}.
335 *
336 * <p>
337 * When a new {@link Validator} object is created, initially
338 * this field is set to null.
339 *
340 * @param resourceResolver
341 * A new resource resolver to be set. This parameter can be null.
342 */
343 public abstract void setResourceResolver(
344 LSResourceResolver resourceResolver);
345
346 /**
347 * Gets the current {@link LSResourceResolver} set to this {@link Validator}.
348 *
349 * @return
350 * This method returns the object that was last set through
351 * the {@link #setResourceResolver(LSResourceResolver)} method, or null
352 * if that method has never been called since this {@link Validator}
353 * has created.
354 *
355 * @see #setErrorHandler(ErrorHandler)
356 */
357 public abstract LSResourceResolver getResourceResolver();
358
359 /**
360 * Look up the value of a feature flag.
361 *
362 * <p>The feature name is any fully-qualified URI. It is
363 * possible for a {@link Validator} to recognize a feature name but
364 * temporarily be unable to return its value.
365 * Some feature values may be available only in specific
366 * contexts, such as before, during, or after a validation.
367 *
368 * <p>Implementors are free (and encouraged) to invent their own features,
369 * using names built on their own URIs.</p>
370 *
371 * @param name The feature name, which is a non-null fully-qualified URI.
372 *
373 * @return The current value of the feature (true or false).
374 *
375 * @throws SAXNotRecognizedException If the feature
376 * value can't be assigned or retrieved.
377 * @throws SAXNotSupportedException When the
378 * {@link Validator} recognizes the feature name but
379 * cannot determine its value at this time.
380 * @throws NullPointerException
381 * When the name parameter is null.
382 *
383 * @see #setFeature(String, boolean)
384 */
385 public boolean getFeature(String name)
386 throws SAXNotRecognizedException, SAXNotSupportedException {
387
388 if (name == null) {
389 throw new NullPointerException("the name parameter is null");
390 }
391
392 throw new SAXNotRecognizedException(name);
393 }
394
395 /**
396 * Set the value of a feature flag.
397 *
398 * <p>
399 * Feature can be used to control the way a {@link Validator}
400 * parses schemas, although {@link Validator}s are not required
401 * to recognize any specific feature names.</p>
402 *
403 * <p>The feature name is any fully-qualified URI. It is
404 * possible for a {@link Validator} to expose a feature value but
405 * to be unable to change the current value.
406 * Some feature values may be immutable or mutable only
407 * in specific contexts, such as before, during, or after
408 * a validation.</p>
409 *
410 * @param name The feature name, which is a non-null fully-qualified URI.
411 * @param value The requested value of the feature (true or false).
412 *
413 * @throws SAXNotRecognizedException If the feature
414 * value can't be assigned or retrieved.
415 * @throws SAXNotSupportedException When the
416 * {@link Validator} recognizes the feature name but
417 * cannot set the requested value.
418 * @throws NullPointerException
419 * When the name parameter is null.
420 *
421 * @see #getFeature(String)
422 */
423 public void setFeature(String name, boolean value)
424 throws SAXNotRecognizedException, SAXNotSupportedException {
425
426 if (name == null) {
427 throw new NullPointerException("the name parameter is null");
428 }
429
430 throw new SAXNotRecognizedException(name);
431 }
432
433 /**
434 * Set the value of a property.
435 *
436 * <p>The property name is any fully-qualified URI. It is
437 * possible for a {@link Validator} to recognize a property name but
438 * to be unable to change the current value.
439 * Some property values may be immutable or mutable only
440 * in specific contexts, such as before, during, or after
441 * a validation.</p>
442 *
443 * <p>{@link Validator}s are not required to recognize setting
444 * any specific property names.</p>
445 *
446 * @param name The property name, which is a non-null fully-qualified URI.
447 * @param object The requested value for the property.
448 *
449 * @throws SAXNotRecognizedException If the property
450 * value can't be assigned or retrieved.
451 * @throws SAXNotSupportedException When the
452 * {@link Validator} recognizes the property name but
453 * cannot set the requested value.
454 * @throws NullPointerException
455 * When the name parameter is null.
456 */
457 public void setProperty(String name, Object object)
458 throws SAXNotRecognizedException, SAXNotSupportedException {
459
460 if (name == null) {
461 throw new NullPointerException("the name parameter is null");
462 }
463
464 throw new SAXNotRecognizedException(name);
465 }
466
467 /**
468 * Look up the value of a property.
469 *
470 * <p>The property name is any fully-qualified URI. It is
471 * possible for a {@link Validator} to recognize a property name but
472 * temporarily be unable to return its value.
473 * Some property values may be available only in specific
474 * contexts, such as before, during, or after a validation.</p>
475 *
476 * <p>{@link Validator}s are not required to recognize any specific
477 * property names.</p>
478 *
479 * <p>Implementors are free (and encouraged) to invent their own properties,
480 * using names built on their own URIs.</p>
481 *
482 * @param name The property name, which is a non-null fully-qualified URI.
483 *
484 * @return The current value of the property.
485 *
486 * @throws SAXNotRecognizedException If the property
487 * value can't be assigned or retrieved.
488 * @throws SAXNotSupportedException When the
489 * XMLReader recognizes the property name but
490 * cannot determine its value at this time.
491 * @throws NullPointerException
492 * When the name parameter is null.
493 *
494 * @see #setProperty(String, Object)
495 */
496 public Object getProperty(String name)
497 throws SAXNotRecognizedException, SAXNotSupportedException {
498
499 if (name == null) {
500 throw new NullPointerException("the name parameter is null");
501 }
502
503 throw new SAXNotRecognizedException(name);
504 }
505 }
|