1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.validation; 27 28 import java.io.IOException; 29 30 import javax.xml.transform.Result; 31 import javax.xml.transform.Source; 32 33 import org.w3c.dom.ls.LSResourceResolver; 34 import org.xml.sax.ErrorHandler; 35 import org.xml.sax.SAXException; 36 import org.xml.sax.SAXNotRecognizedException; 37 import org.xml.sax.SAXNotSupportedException; 38 39 /** 40 * A processor that checks an XML document against {@link Schema}. 41 * 42 * <p> 43 * A validator object is not thread-safe and not reentrant. 44 * In other words, it is the application's responsibility to make 45 * sure that one {@link Validator} object is not used from 46 * more than one thread at any given time, and while the {@code validate} 47 * method is invoked, applications may not recursively call 48 * the {@code validate} method. 49 * 50 * 51 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> 52 * @since 1.5 53 */ 54 public abstract class Validator { 55 56 /** 57 * Constructor for derived classes. 58 * 59 * <p>The constructor does nothing. 60 * 61 * <p>Derived classes must create {@link Validator} objects that have 62 * {@code null} {@link ErrorHandler} and 63 * {@code null} {@link LSResourceResolver}. 64 * 65 */ 66 protected Validator() { 67 } 68 69 /** 70 * Reset this {@code Validator} to its original configuration. 71 * 72 * <p>{@code Validator} is reset to the same state as when it was created with 73 * {@link Schema#newValidator()}. 74 * {@code reset()} is designed to allow the reuse of existing {@code Validator}s 75 * thus saving resources associated with the creation of new {@code Validator}s. 76 * 77 * <p>The reset {@code Validator} is not guaranteed to have 78 * the same {@link LSResourceResolver} or {@link ErrorHandler} 79 * {@code Object}s, e.g. {@link Object#equals(Object obj)}. 80 * It is guaranteed to have a functionally equal 81 * {@code LSResourceResolver} and {@code ErrorHandler}. 82 */ 83 public abstract void reset(); 84 85 /** 86 * Validates the specified input. 87 * 88 * <p>This is just a convenience method for 89 * {@link #validate(Source source, Result result)} 90 * with {@code result} of {@code null}. 91 * 92 * @param source 93 * XML to be validated. Must be an XML document or 94 * XML element and must not be null. For backwards compatibility, 95 * the results of attempting to validate anything other than 96 * a document or element are implementation-dependent. 97 * Implementations must either recognize and process the input 98 * or throw an IllegalArgumentException. 99 * 100 * @throws IllegalArgumentException 101 * If the {@code Source} 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} is 118 * {@code null}. 119 * 120 * @see #validate(Source source, Result result) 121 */ 122 public void validate(Source source) 123 throws SAXException, IOException { 124 125 validate(source, null); 126 } 127 128 /** 129 * Validates the specified input and send the augmented validation 130 * result to the specified output. 131 * 132 * <p>This method places the following restrictions on the types of 133 * the {@link Source}/{@link Result} accepted. 134 * 135 * <table border=1> 136 * <thead> 137 * <tr> 138 * <th colspan="5">{@code Source} / {@code Result} 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}</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}</td> 160 * <td>{@code IllegalArgumentException}</td> 161 * <td>{@code IllegalArgumentException}</td> 162 * </tr> 163 * <tr> 164 * <th>{@link javax.xml.transform.sax.SAXResult}</th> 165 * <td>{@code IllegalArgumentException}</td> 166 * <td>OK</td> 167 * <td>{@code IllegalArgumentException}</td> 168 * <td>{@code IllegalArgumentException}</td> 169 * </tr> 170 * <tr> 171 * <th>{@link javax.xml.transform.dom.DOMResult}</th> 172 * <td>{@code IllegalArgumentException}</td> 173 * <td>{@code IllegalArgumentException}</td> 174 * <td>OK</td> 175 * <td>{@code IllegalArgumentException}</td> 176 * </tr> 177 * <tr> 178 * <th>{@link javax.xml.transform.stax.StAXResult}</th> 179 * <td>{@code IllegalArgumentException}</td> 180 * <td>{@code IllegalArgumentException}</td> 181 * <td>{@code IllegalArgumentException}</td> 182 * <td>OK</td> 183 * </tr> 184 * </tbody> 185 * </table> 186 * 187 * <p>To validate one {@code Source} into another kind of 188 * {@code Result}, use the identity transformer (see 189 * {@link javax.xml.transform.TransformerFactory#newTransformer()}). 190 * 191 * <p>Errors found during the validation is sent to the specified 192 * {@link ErrorHandler}. 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} didn't 196 * throw any exception, then the method returns normally. 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} 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} is used, 212 * a validator might just pass the same DOM node from 213 * {@code DOMSource} to {@code DOMResult} 214 * (in which case {@code source.getNode()==result.getNode()}), 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} type doesn't match the 220 * {@code Source} type of if the {@code Source} 221 * is an XML artifact that the implementation cannot 222 * validate (for example, a processing instruction). 223 * @throws SAXException 224 * If the {@code ErrorHandler} throws a 225 * {@code SAXException} or 226 * if a fatal error is found and the {@code ErrorHandler} returns 227 * normally. 228 * @throws IOException 229 * If the validator is processing a 230 * {@code SAXSource} and the 231 * underlying {@link org.xml.sax.XMLReader} throws an 232 * {@code IOException}. 233 * @throws NullPointerException 234 * If the {@code source} parameter is {@code null}. 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} 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} 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} 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(LSResourceResolver resourceResolver); 344 345 /** 346 * Gets the current {@link LSResourceResolver} set to this {@link Validator}. 347 * 348 * @return 349 * This method returns the object that was last set through 350 * the {@link #setResourceResolver(LSResourceResolver)} method, or null 351 * if that method has never been called since this {@link Validator} 352 * has created. 353 * 354 * @see #setErrorHandler(ErrorHandler) 355 */ 356 public abstract LSResourceResolver getResourceResolver(); 357 358 359 360 /** 361 * Look up the value of a feature flag. 362 * 363 * <p>The feature name is any fully-qualified URI. It is 364 * possible for a {@link Validator} to recognize a feature name but 365 * temporarily be unable to return its value. 366 * Some feature values may be available only in specific 367 * contexts, such as before, during, or after a validation. 368 * 369 * <p>Implementors are free (and encouraged) to invent their own features, 370 * using names built on their own URIs. 371 * 372 * @param name The feature name, which is a non-null fully-qualified URI. 373 * 374 * @return The current value of the feature (true or false). 375 * 376 * @throws SAXNotRecognizedException If the feature 377 * value can't be assigned or retrieved. 378 * @throws SAXNotSupportedException When the 379 * {@link Validator} recognizes the feature name but 380 * cannot determine its value at this time. 381 * @throws NullPointerException 382 * When the name parameter is null. 383 * 384 * @see #setFeature(String, boolean) 385 */ 386 public boolean getFeature(String name) 387 throws SAXNotRecognizedException, SAXNotSupportedException { 388 389 if (name == null) { 390 throw new NullPointerException("the name parameter is null"); 391 } 392 393 throw new SAXNotRecognizedException(name); 394 } 395 396 /** 397 * Set the value of a feature flag. 398 * 399 * <p> 400 * Feature can be used to control the way a {@link Validator} 401 * parses schemas, although {@link Validator}s are not required 402 * to recognize any specific feature names. 403 * 404 * <p>The feature name is any fully-qualified URI. It is 405 * possible for a {@link Validator} to expose a feature value but 406 * to be unable to change the current value. 407 * Some feature values may be immutable or mutable only 408 * in specific contexts, such as before, during, or after 409 * a validation. 410 * 411 * @param name The feature name, which is a non-null fully-qualified URI. 412 * @param value The requested value of the feature (true or false). 413 * 414 * @throws SAXNotRecognizedException If the feature 415 * value can't be assigned or retrieved. 416 * @throws SAXNotSupportedException When the 417 * {@link Validator} recognizes the feature name but 418 * cannot set the requested value. 419 * @throws NullPointerException 420 * When the name parameter is null. 421 * 422 * @see #getFeature(String) 423 */ 424 public void setFeature(String name, boolean value) 425 throws SAXNotRecognizedException, SAXNotSupportedException { 426 427 if (name == null) { 428 throw new NullPointerException("the name parameter is null"); 429 } 430 431 throw new SAXNotRecognizedException(name); 432 } 433 434 /** 435 * Set the value of a property. 436 * 437 * <p>The property name is any fully-qualified URI. It is 438 * possible for a {@link Validator} to recognize a property name but 439 * to be unable to change the current value. 440 * Some property values may be immutable or mutable only 441 * in specific contexts, such as before, during, or after 442 * a validation. 443 * 444 * <p> 445 * All implementations that implement JAXP 1.5 or newer are required to 446 * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and 447 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. 448 * 449 * <ul> 450 * <li> 451 * <p>Access to external DTDs in source or Schema file is restricted to 452 * the protocols specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} 453 * property. If access is denied during validation due to the restriction 454 * of this property, {@link org.xml.sax.SAXException} will be thrown by the 455 * {@link #validate(Source)} method. 456 * 457 * <p>Access to external reference set by the schemaLocation attribute is 458 * restricted to the protocols specified by the 459 * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. 460 * If access is denied during validation due to the restriction of this property, 461 * {@link org.xml.sax.SAXException} will be thrown by the 462 * {@link #validate(Source)} method. 463 * </li> 464 * </ul> 465 * 466 * @param name The property name, which is a non-null fully-qualified URI. 467 * @param object The requested value for the property. 468 * 469 * @throws SAXNotRecognizedException If the property 470 * value can't be assigned or retrieved. 471 * @throws SAXNotSupportedException When the 472 * {@link Validator} recognizes the property name but 473 * cannot set the requested value. 474 * @throws NullPointerException 475 * When the name parameter is null. 476 */ 477 public void setProperty(String name, Object object) 478 throws SAXNotRecognizedException, SAXNotSupportedException { 479 480 if (name == null) { 481 throw new NullPointerException("the name parameter is null"); 482 } 483 484 throw new SAXNotRecognizedException(name); 485 } 486 487 /** 488 * Look up the value of a property. 489 * 490 * <p>The property name is any fully-qualified URI. It is 491 * possible for a {@link Validator} to recognize a property name but 492 * temporarily be unable to return its value. 493 * Some property values may be available only in specific 494 * contexts, such as before, during, or after a validation. 495 * 496 * <p>{@link Validator}s are not required to recognize any specific 497 * property names. 498 * 499 * <p>Implementors are free (and encouraged) to invent their own properties, 500 * using names built on their own URIs. 501 * 502 * @param name The property name, which is a non-null fully-qualified URI. 503 * 504 * @return The current value of the property. 505 * 506 * @throws SAXNotRecognizedException If the property 507 * value can't be assigned or retrieved. 508 * @throws SAXNotSupportedException When the 509 * XMLReader recognizes the property name but 510 * cannot determine its value at this time. 511 * @throws NullPointerException 512 * When the name parameter is null. 513 * 514 * @see #setProperty(String, Object) 515 */ 516 public Object getProperty(String name) 517 throws SAXNotRecognizedException, SAXNotSupportedException { 518 519 if (name == null) { 520 throw new NullPointerException("the name parameter is null"); 521 } 522 523 throw new SAXNotRecognizedException(name); 524 } 525 }