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 23 import javax.xml.transform.Result; 24 import javax.xml.transform.Source; 25 26 import org.w3c.dom.ls.LSResourceResolver; 27 import org.xml.sax.ErrorHandler; 28 import org.xml.sax.SAXException; 29 import org.xml.sax.SAXNotRecognizedException; 30 import 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 12:36:46 -0500 (Wed, 09 Dec 2009) $ 50 * @since 1.5 51 */ 52 public 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.stax.StAXSource}</td> 113 * <td>{@link javax.xml.transform.stream.StreamSource}</td> 114 * </tr> 115 * </thead> 116 * <tbody> 117 * <tr> 118 * <td><tt>null</tt></td> 119 * <td>OK</td> 120 * <td>OK</td> 121 * <td>OK</td> 122 * <td>OK</td> 123 * </tr> 124 * <tr> 125 * <td>{@link javax.xml.transform.sax.SAXResult}</td> 126 * <td>OK</td> 127 * <td>Err</td> 128 * <td>Err</td> 129 * <td>Err</td> 130 * </tr> 131 * <tr> 132 * <td>{@link javax.xml.transform.dom.DOMResult}</td> 133 * <td>Err</td> 134 * <td>OK</td> 135 * <td>Err</td> 136 * <td>Err</td> 137 * </tr> 138 * <tr> 139 * <td>{@link javax.xml.transform.stax.StAXResult}</td> 140 * <td>Err</td> 141 * <td>Err</td> 142 * <td>OK</td> 143 * <td>Err</td> 144 * </tr> 145 * <tr> 146 * <td>{@link javax.xml.transform.stream.StreamResult}</td> 147 * <td>Err</td> 148 * <td>Err</td> 149 * <td>Err</td> 150 * <td>OK</td> 151 * </tr> 152 * </tbody> 153 * </table> 154 * 155 * <p> 156 * To validate one {@link Source} into another kind of {@link Result}, use the identity transformer 157 * (see {@link javax.xml.transform.TransformerFactory#newTransformer()}). 158 * 159 * <p> 160 * Errors found during the validation is sent to the specified 161 * {@link ErrorHandler}. 162 * 163 * <p> 164 * If a document is valid, or if a document contains some errors 165 * but none of them were fatal and the {@link ErrorHandler} didn't 166 * throw any exception, then the method returns normally. 167 * 168 * @param source 169 * XML to be validated. Must not be null. 170 * 171 * @param result 172 * The {@link Result} object that receives (possibly augmented) 173 * XML. This parameter can be null if the caller is not interested 174 * in it. 175 * 176 * Note that when a {@link javax.xml.transform.dom.DOMResult} is used, 177 * a validator might just pass the same DOM node from 178 * {@link javax.xml.transform.dom.DOMSource} to 179 * {@link javax.xml.transform.dom.DOMResult} 180 * (in which case <tt>source.getNode()==result.getNode()</tt>), 181 * it might copy the entire DOM tree, or it might alter the 182 * node given by the source. 183 * 184 * @throws IllegalArgumentException 185 * If the {@link Result} type doesn't match the {@link Source} type, 186 * or if the specified source is not a 187 * {@link javax.xml.transform.sax.SAXSource}, 188 * {@link javax.xml.transform.dom.DOMSource}, 189 * {@link javax.xml.transform.stax.StAXSource} or 190 * {@link javax.xml.transform.stream.StreamSource}. 191 * 192 * @throws SAXException 193 * If the {@link ErrorHandler} throws a {@link SAXException} or 194 * if a fatal error is found and the {@link ErrorHandler} returns 195 * normally. 196 * 197 * @throws IOException 198 * If the validator is processing a 199 * {@link javax.xml.transform.sax.SAXSource} and the 200 * underlying {@link org.xml.sax.XMLReader} throws an 201 * {@link IOException}. 202 * 203 * @throws NullPointerException 204 * If the <tt>source</tt> parameter is null. 205 * 206 * @see #validate(Source) 207 */ 208 public abstract void validate(Source source, Result result) throws SAXException, IOException; 209 210 /** 211 * Sets the {@link ErrorHandler} to receive errors encountered 212 * during the <code>validate</code> method invocation. 213 * 214 * <p> 215 * Error handler can be used to customize the error handling process 216 * during a validation. When an {@link ErrorHandler} is set, 217 * errors found during the validation will be first sent 218 * to the {@link ErrorHandler}. 219 * 220 * <p> 221 * The error handler can abort further validation immediately 222 * by throwing {@link SAXException} from the handler. Or for example 223 * it can print an error to the screen and try to continue the 224 * validation by returning normally from the {@link ErrorHandler} 225 * 226 * <p> 227 * If any {@link Throwable} is thrown from an {@link ErrorHandler}, 228 * the caller of the <code>validate</code> method will be thrown 229 * the same {@link Throwable} object. 230 * 231 * <p> 232 * {@link Validator} is not allowed to 233 * throw {@link SAXException} without first reporting it to 234 * {@link ErrorHandler}. 235 * 236 * <p> 237 * When the {@link ErrorHandler} is null, the implementation will 238 * behave as if the following {@link ErrorHandler} is set: 239 * <pre> 240 * class DraconianErrorHandler implements {@link ErrorHandler} { 241 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 242 * throw e; 243 * } 244 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 245 * throw e; 246 * } 247 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} { 248 * // noop 249 * } 250 * } 251 * </pre> 252 * 253 * <p> 254 * When a new {@link Validator} object is created, initially 255 * this field is set to null. 256 * 257 * @param errorHandler 258 * A new error handler to be set. This parameter can be null. 259 */ 260 public abstract void setErrorHandler(ErrorHandler errorHandler); 261 262 /** 263 * Gets the current {@link ErrorHandler} set to this {@link Validator}. 264 * 265 * @return 266 * This method returns the object that was last set through 267 * the {@link #setErrorHandler(ErrorHandler)} method, or null 268 * if that method has never been called since this {@link Validator} 269 * has created. 270 * 271 * @see #setErrorHandler(ErrorHandler) 272 */ 273 public abstract ErrorHandler getErrorHandler(); 274 275 /** 276 * Sets the {@link LSResourceResolver} to customize 277 * resource resolution while in a validation episode. 278 * 279 * <p> 280 * {@link Validator} uses a {@link LSResourceResolver} 281 * when it needs to locate external resources while a validation, 282 * although exactly what constitutes "locating external resources" is 283 * up to each schema language. 284 * 285 * <p> 286 * When the {@link LSResourceResolver} is null, the implementation will 287 * behave as if the following {@link LSResourceResolver} is set: 288 * <pre> 289 * class DumbLSResourceResolver implements {@link LSResourceResolver} { 290 * public {@link org.w3c.dom.ls.LSInput} resolveResource( 291 * String publicId, String systemId, String baseURI) { 292 * 293 * return null; // always return null 294 * } 295 * } 296 * </pre> 297 * 298 * <p> 299 * If a {@link LSResourceResolver} throws a {@link RuntimeException} 300 * (or instances of its derived classes), 301 * then the {@link Validator} will abort the parsing and 302 * the caller of the <code>validate</code> method will receive 303 * the same {@link RuntimeException}. 304 * 305 * <p> 306 * When a new {@link Validator} object is created, initially 307 * this field is set to null. 308 * 309 * @param resourceResolver 310 * A new resource resolver to be set. This parameter can be null. 311 */ 312 public abstract void setResourceResolver(LSResourceResolver resourceResolver); 313 314 /** 315 * Gets the current {@link LSResourceResolver} set to this {@link Validator}. 316 * 317 * @return 318 * This method returns the object that was last set through 319 * the {@link #setResourceResolver(LSResourceResolver)} method, or null 320 * if that method has never been called since this {@link Validator} 321 * has created. 322 * 323 * @see #setErrorHandler(ErrorHandler) 324 */ 325 public abstract LSResourceResolver getResourceResolver(); 326 327 328 329 /** 330 * Look up the value of a feature flag. 331 * 332 * <p>The feature name is any fully-qualified URI. It is 333 * possible for a {@link Validator} to recognize a feature name but 334 * temporarily be unable to return its value. 335 * Some feature values may be available only in specific 336 * contexts, such as before, during, or after a validation. 337 * 338 * <p>Implementors are free (and encouraged) to invent their own features, 339 * using names built on their own URIs.</p> 340 * 341 * @param name The feature name, which is a non-null fully-qualified URI. 342 * @return The current value of the feature (true or false). 343 * @exception org.xml.sax.SAXNotRecognizedException If the feature 344 * value can't be assigned or retrieved. 345 * @exception org.xml.sax.SAXNotSupportedException When the 346 * {@link Validator} recognizes the feature name but 347 * cannot determine its value at this time. 348 * @throws NullPointerException 349 * When the name parameter is null. 350 * @see #setFeature(String, boolean) 351 */ 352 public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { 353 if(name==null) throw new NullPointerException("the name parameter is null"); 354 throw new SAXNotRecognizedException(name); 355 } 356 357 /** 358 * Set the value of a feature flag. 359 * 360 * <p> 361 * Feature can be used to control the way a {@link Validator} 362 * parses schemas, although {@link Validator}s are not required 363 * to recognize any specific property names.</p> 364 * 365 * <p>The feature name is any fully-qualified URI. It is 366 * possible for a {@link Validator} to expose a feature value but 367 * to be unable to change the current value. 368 * Some feature values may be immutable or mutable only 369 * in specific contexts, such as before, during, or after 370 * a validation.</p> 371 * 372 * @param name The feature name, which is a non-null fully-qualified URI. 373 * @param value The requested value of the feature (true or false). 374 * 375 * @exception org.xml.sax.SAXNotRecognizedException If the feature 376 * value can't be assigned or retrieved. 377 * @exception org.xml.sax.SAXNotSupportedException When the 378 * {@link Validator} recognizes the feature name but 379 * cannot set the requested value. 380 * @throws NullPointerException 381 * When the name parameter is null. 382 * 383 * @see #getFeature(String) 384 */ 385 public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { 386 if(name==null) throw new NullPointerException("the name parameter is null"); 387 throw new SAXNotRecognizedException(name); 388 } 389 390 /** 391 * Set the value of a property. 392 * 393 * <p>The property name is any fully-qualified URI. It is 394 * possible for a {@link Validator} to recognize a property name but 395 * to be unable to change the current value. 396 * Some property values may be immutable or mutable only 397 * in specific contexts, such as before, during, or after 398 * a validation.</p> 399 * 400 * <p>{@link Validator}s are not required to recognize setting 401 * any specific property names.</p> 402 * 403 * @param name The property name, which is a non-null fully-qualified URI. 404 * @param object The requested value for the property. 405 * @exception org.xml.sax.SAXNotRecognizedException If the property 406 * value can't be assigned or retrieved. 407 * @exception org.xml.sax.SAXNotSupportedException When the 408 * {@link Validator} recognizes the property name but 409 * cannot set the requested value. 410 * @throws NullPointerException 411 * When the name parameter is null. 412 */ 413 public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException { 414 if(name==null) throw new NullPointerException("the name parameter is null"); 415 throw new SAXNotRecognizedException(name); 416 } 417 418 /** 419 * Look up the value of a property. 420 * 421 * <p>The property name is any fully-qualified URI. It is 422 * possible for a {@link Validator} to recognize a property name but 423 * temporarily be unable to return its value. 424 * Some property values may be available only in specific 425 * contexts, such as before, during, or after a validation.</p> 426 * 427 * <p>{@link Validator}s are not required to recognize any specific 428 * property names.</p> 429 * 430 * <p>Implementors are free (and encouraged) to invent their own properties, 431 * using names built on their own URIs.</p> 432 * 433 * @param name The property name, which is a non-null fully-qualified URI. 434 * @return The current value of the property. 435 * @exception org.xml.sax.SAXNotRecognizedException If the property 436 * value can't be assigned or retrieved. 437 * @exception org.xml.sax.SAXNotSupportedException When the 438 * XMLReader recognizes the property name but 439 * cannot determine its value at this time. 440 * @throws NullPointerException 441 * When the name parameter is null. 442 * @see #setProperty(String, Object) 443 */ 444 public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { 445 if(name==null) throw new NullPointerException("the name parameter is null"); 446 throw new SAXNotRecognizedException(name); 447 } 448 }