Home | History | Annotate | Download | only in validation
      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 (at) 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      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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