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