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 org.w3c.dom.ls.LSResourceResolver;
029 import org.xml.sax.ContentHandler;
030 import org.xml.sax.ErrorHandler;
031 import org.xml.sax.SAXNotRecognizedException;
032 import org.xml.sax.SAXNotSupportedException;
033
034 /**
035 * Streaming validator that works on SAX stream.
036 *
037 * <p>
038 * A {@link ValidatorHandler} object is not thread-safe and not reentrant.
039 * In other words, it is the application's responsibility to make
040 * sure that one {@link ValidatorHandler} object is not used from
041 * more than one thread at any given time.
042 *
043 * <p>
044 * {@link ValidatorHandler} checks if the SAX events follow
045 * the set of constraints described in the associated {@link Schema},
046 * and additionally it may modify the SAX events (for example
047 * by adding default values, etc.)
048 *
049 * <p>
050 * {@link ValidatorHandler} extends from {@link ContentHandler},
051 * but it refines the underlying {@link ContentHandler} in
052 * the following way:
053 * <ol>
054 * <li>startElement/endElement events must receive non-null String
055 * for <code>uri</code>, <code>localName</code>, and <code>qname</code>,
056 * even though SAX allows some of them to be null.
057 * Similarly, the user-specified {@link ContentHandler} will receive non-null
058 * Strings for all three parameters.
059 *
060 * <li>Applications must ensure that {@link ValidatorHandler}'s
061 * {@link ContentHandler#startPrefixMapping(String,String)} and
062 * {@link ContentHandler#endPrefixMapping(String)} are invoked
063 * properly. Similarly, the user-specified {@link ContentHandler}
064 * will receive startPrefixMapping/endPrefixMapping events.
065 * If the {@link ValidatorHandler} introduces additional namespace
066 * bindings, the user-specified {@link ContentHandler} will receive
067 * additional startPrefixMapping/endPrefixMapping events.
068 *
069 * <li>{@link org.xml.sax.Attributes} for the
070 * {@link ContentHandler#startElement(String,String,String,Attributes)} method
071 * may or may not include xmlns* attributes.
072 * </ol>
073 *
074 * <p>
075 * A {@link ValidatorHandler} is automatically reset every time
076 * the startDocument method is invoked.
077 *
078 * <h2>Recognized Properties and Features</h2>
079 * <p>
080 * This spec defines the following feature that must be recognized
081 * by all {@link ValidatorHandler} implementations.
082 *
083 * <h3><code>http://xml.org/sax/features/namespace-prefixes</code></h3>
084 * <p>
085 * This feature controls how a {@link ValidatorHandler} introduces
086 * namespace bindings that were not present in the original SAX event
087 * stream.
088 * When this feature is set to true, it must make
089 * sure that the user's {@link ContentHandler} will see
090 * the corresponding <code>xmlns*</code> attribute in
091 * the {@link org.xml.sax.Attributes} object of the
092 * {@link ContentHandler#startElement(String,String,String,Attributes)}
093 * callback. Otherwise, <code>xmlns*</code> attributes must not be
094 * added to {@link org.xml.sax.Attributes} that's passed to the
095 * user-specified {@link ContentHandler}.
096 * <p>
097 * (Note that regardless of this switch, namespace bindings are
098 * always notified to applications through
099 * {@link ContentHandler#startPrefixMapping(String,String)} and
100 * {@link ContentHandler#endPrefixMapping(String)} methods of the
101 * {@link ContentHandler} specified by the user.)
102 *
103 * <p>
104 * Note that this feature does <em>NOT</em> affect the way
105 * a {@link ValidatorHandler} receives SAX events. It merely
106 * changes the way it augments SAX events.
107 *
108 * <p>This feature is set to <code>false</code> by default.</p>
109 *
110 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
111 * @version $Revision: 1.5 $, $Date: 2005/11/03 19:34:24 $
112 * @since 1.5
113 */
114 public abstract class ValidatorHandler implements ContentHandler {
115
116 /**
117 * <p>Constructor for derived classes.</p>
118 *
119 * <p>The constructor does nothing.</p>
120 *
121 * <p>Derived classes must create {@link ValidatorHandler} objects that have
122 * <code>null</code> {@link ErrorHandler} and
123 * <code>null</code> {@link LSResourceResolver}.</p>
124 */
125 protected ValidatorHandler() {
126 }
127
128 /**
129 * Sets the {@link ContentHandler} which receives
130 * the augmented validation result.
131 *
132 * <p>
133 * When a {@link ContentHandler} is specified, a
134 * {@link ValidatorHandler} will work as a filter
135 * and basically copy the incoming events to the
136 * specified {@link ContentHandler}.
137 *
138 * <p>
139 * In doing so, a {@link ValidatorHandler} may modify
140 * the events, for example by adding defaulted attributes.
141 *
142 * <p>
143 * A {@link ValidatorHandler} may buffer events to certain
144 * extent, but to allow {@link ValidatorHandler} to be used
145 * by a parser, the following requirement has to be met.
146 *
147 * <ol>
148 * <li>When
149 * {@link ContentHandler#startElement(String, String, String, Attributes)},
150 * {@link ContentHandler#endElement(String, String, String)},
151 * {@link ContentHandler#startDocument()}, or
152 * {@link ContentHandler#endDocument()}
153 * are invoked on a {@link ValidatorHandler},
154 * the same method on the user-specified {@link ContentHandler}
155 * must be invoked for the same event before the callback
156 * returns.
157 * <li>{@link ValidatorHandler} may not introduce new elements that
158 * were not present in the input.
159 *
160 * <li>{@link ValidatorHandler} may not remove attributes that were
161 * present in the input.
162 * </ol>
163 *
164 * <p>
165 * When a callback method on the specified {@link ContentHandler}
166 * throws an exception, the same exception object must be thrown
167 * from the {@link ValidatorHandler}. The {@link ErrorHandler}
168 * should not be notified of such an exception.
169 *
170 * <p>
171 * This method can be called even during a middle of a validation.
172 *
173 * @param receiver
174 * A {@link ContentHandler} or a null value.
175 */
176 public abstract void setContentHandler(ContentHandler receiver);
177
178 /**
179 * Gets the {@link ContentHandler} which receives the
180 * augmented validation result.
181 *
182 * @return
183 * This method returns the object that was last set through
184 * the {@link #getContentHandler()} method, or null
185 * if that method has never been called since this {@link ValidatorHandler}
186 * has created.
187 *
188 * @see #setContentHandler(ContentHandler)
189 */
190 public abstract ContentHandler getContentHandler();
191
192 /**
193 * Sets the {@link ErrorHandler} to receive errors encountered
194 * during the validation.
195 *
196 * <p>
197 * Error handler can be used to customize the error handling process
198 * during a validation. When an {@link ErrorHandler} is set,
199 * errors found during the validation will be first sent
200 * to the {@link ErrorHandler}.
201 *
202 * <p>
203 * The error handler can abort further validation immediately
204 * by throwing {@link org.xml.sax.SAXException} from the handler. Or for example
205 * it can print an error to the screen and try to continue the
206 * validation by returning normally from the {@link ErrorHandler}
207 *
208 * <p>
209 * If any {@link Throwable} is thrown from an {@link ErrorHandler},
210 * the same {@link Throwable} object will be thrown toward the
211 * root of the call stack.
212 *
213 * <p>
214 * {@link ValidatorHandler} is not allowed to
215 * throw {@link org.xml.sax.SAXException} without first reporting it to
216 * {@link ErrorHandler}.
217 *
218 * <p>
219 * When the {@link ErrorHandler} is null, the implementation will
220 * behave as if the following {@link ErrorHandler} is set:
221 * <pre>
222 * class DraconianErrorHandler implements {@link ErrorHandler} {
223 * public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
224 * throw e;
225 * }
226 * public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
227 * throw e;
228 * }
229 * public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
230 * // noop
231 * }
232 * }
233 * </pre>
234 *
235 * <p>
236 * When a new {@link ValidatorHandler} object is created, initially
237 * this field is set to null.
238 *
239 * @param errorHandler
240 * A new error handler to be set. This parameter can be null.
241 */
242 public abstract void setErrorHandler(ErrorHandler errorHandler);
243
244 /**
245 * Gets the current {@link ErrorHandler} set to this {@link ValidatorHandler}.
246 *
247 * @return
248 * This method returns the object that was last set through
249 * the {@link #setErrorHandler(ErrorHandler)} method, or null
250 * if that method has never been called since this {@link ValidatorHandler}
251 * has created.
252 *
253 * @see #setErrorHandler(ErrorHandler)
254 */
255 public abstract ErrorHandler getErrorHandler();
256
257 /**
258 * Sets the {@link LSResourceResolver} to customize
259 * resource resolution while in a validation episode.
260 *
261 * <p>
262 * {@link ValidatorHandler} uses a {@link LSResourceResolver}
263 * when it needs to locate external resources while a validation,
264 * although exactly what constitutes "locating external resources" is
265 * up to each schema language.
266 *
267 * <p>
268 * When the {@link LSResourceResolver} is null, the implementation will
269 * behave as if the following {@link LSResourceResolver} is set:
270 * <pre>
271 * class DumbLSResourceResolver implements {@link LSResourceResolver} {
272 * public {@link org.w3c.dom.ls.LSInput} resolveResource(
273 * String publicId, String systemId, String baseURI) {
274 *
275 * return null; // always return null
276 * }
277 * }
278 * </pre>
279 *
280 * <p>
281 * If a {@link LSResourceResolver} throws a {@link RuntimeException}
282 * (or instances of its derived classes),
283 * then the {@link ValidatorHandler} will abort the parsing and
284 * the caller of the <code>validate</code> method will receive
285 * the same {@link RuntimeException}.
286 *
287 * <p>
288 * When a new {@link ValidatorHandler} object is created, initially
289 * this field is set to null.
290 *
291 * @param resourceResolver
292 * A new resource resolver to be set. This parameter can be null.
293 */
294 public abstract void setResourceResolver(
295 LSResourceResolver resourceResolver);
296
297 /**
298 * Gets the current {@link LSResourceResolver} set to this {@link ValidatorHandler}.
299 *
300 * @return
301 * This method returns the object that was last set through
302 * the {@link #setResourceResolver(LSResourceResolver)} method, or null
303 * if that method has never been called since this {@link ValidatorHandler}
304 * has created.
305 *
306 * @see #setErrorHandler(ErrorHandler)
307 */
308 public abstract LSResourceResolver getResourceResolver();
309
310 /**
311 * Obtains the {@link TypeInfoProvider} implementation of this
312 * {@link ValidatorHandler}.
313 *
314 * <p>
315 * The obtained {@link TypeInfoProvider} can be queried during a parse
316 * to access the type information determined by the validator.
317 *
318 * <p>
319 * Some schema languages do not define the notion of type,
320 * for those languages, this method may not be supported.
321 * However, to be compliant with this specification, implementations
322 * for W3C XML Schema 1.0 must support this operation.
323 *
324 * @return
325 * null if the validator / schema language does not support
326 * the notion of {@link org.w3c.dom.TypeInfo}.
327 * Otherwise a non-null valid {@link TypeInfoProvider}.
328 */
329 public abstract TypeInfoProvider getTypeInfoProvider();
330
331 /**
332 * Look up the value of a feature flag.
333 *
334 * <p>The feature name is any fully-qualified URI. It is
335 * possible for a {@link ValidatorHandler} to recognize a feature name but
336 * temporarily be unable to return its value.
337 * Some feature values may be available only in specific
338 * contexts, such as before, during, or after a validation.
339 *
340 * <p>Implementors are free (and encouraged) to invent their own features,
341 * using names built on their own URIs.</p>
342 *
343 * @param name The feature name, which is a non-null fully-qualified URI.
344 *
345 * @return The current value of the feature (true or false).
346 *
347 * @throws SAXNotRecognizedException If the feature
348 * value can't be assigned or retrieved.
349 * @throws SAXNotSupportedException When the
350 * {@link ValidatorHandler} recognizes the feature name but
351 * cannot determine its value at this time.
352 * @throws NullPointerException When <code>name</code> is <code>null</code>.
353 *
354 * @see #setFeature(String, boolean)
355 */
356 public boolean getFeature(String name)
357 throws SAXNotRecognizedException, SAXNotSupportedException {
358
359 if (name == null) {
360 throw new NullPointerException();
361 }
362
363 throw new SAXNotRecognizedException(name);
364 }
365
366 /**
367 * <p>Set a feature for this <code>ValidatorHandler</code>.</p>
368 *
369 * <p>Feature can be used to control the way a
370 * {@link ValidatorHandler} parses schemas. The feature name is
371 * any fully-qualified URI. It is possible for a
372 * {@link SchemaFactory} to
373 * expose a feature value but to be unable to change the current
374 * value. Some feature values may be immutable or mutable only in
375 * specific contexts, such as before, during, or after a
376 * validation.</p>
377 *
378 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
379 * When the feature is:</p>
380 * <ul>
381 * <li>
382 * <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
383 * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources.
384 * If XML processing is limited for security reasons, it will be reported via a call to the registered
385 * {@link ErrorHandler#fatalError(SAXParseException exception)}.
386 * See {@link #setErrorHandler(ErrorHandler errorHandler)}.
387 * </li>
388 * <li>
389 * <code>false</code>: the implementation will processing XML according to the XML specifications without
390 * regard to possible implementation limits.
391 * </li>
392 * </ul>
393 *
394 * @param name The feature name, which is a non-null fully-qualified URI.
395 * @param value The requested value of the feature (true or false).
396 *
397 * @throws SAXNotRecognizedException If the feature
398 * value can't be assigned or retrieved.
399 * @throws SAXNotSupportedException When the
400 * {@link ValidatorHandler} recognizes the feature name but
401 * cannot set the requested value.
402 * @throws NullPointerException When <code>name</code> is <code>null</code>.
403 *
404 * @see #getFeature(String)
405 */
406 public void setFeature(String name, boolean value)
407 throws SAXNotRecognizedException, SAXNotSupportedException {
408
409 if (name == null) {
410 throw new NullPointerException();
411 }
412
413 throw new SAXNotRecognizedException(name);
414 }
415
416 /**
417 * Set the value of a property.
418 *
419 * <p>The property name is any fully-qualified URI. It is
420 * possible for a {@link ValidatorHandler} to recognize a property name but
421 * to be unable to change the current value.
422 * Some property values may be immutable or mutable only
423 * in specific contexts, such as before, during, or after
424 * a validation.</p>
425 *
426 * <p>{@link ValidatorHandler}s are not required to recognize setting
427 * any specific property names.</p>
428 *
429 * @param name The property name, which is a non-null fully-qualified URI.
430 * @param object The requested value for the property.
431 *
432 * @throws SAXNotRecognizedException If the property
433 * value can't be assigned or retrieved.
434 * @throws SAXNotSupportedException When the
435 * {@link ValidatorHandler} recognizes the property name but
436 * cannot set the requested value.
437 * @throws NullPointerException When <code>name</code> is <code>null</code>.
438 */
439 public void setProperty(String name, Object object)
440 throws SAXNotRecognizedException, SAXNotSupportedException {
441
442 if (name == null) {
443 throw new NullPointerException();
444 }
445
446 throw new SAXNotRecognizedException(name);
447 }
448
449 /**
450 * Look up the value of a property.
451 *
452 * <p>The property name is any fully-qualified URI. It is
453 * possible for a {@link ValidatorHandler} to recognize a property name but
454 * temporarily be unable to return its value.
455 * Some property values may be available only in specific
456 * contexts, such as before, during, or after a validation.</p>
457 *
458 * <p>{@link ValidatorHandler}s are not required to recognize any specific
459 * property names.</p>
460 *
461 * <p>Implementors are free (and encouraged) to invent their own properties,
462 * using names built on their own URIs.</p>
463 *
464 * @param name The property name, which is a non-null fully-qualified URI.
465 *
466 * @return The current value of the property.
467 *
468 * @throws SAXNotRecognizedException If the property
469 * value can't be assigned or retrieved.
470 * @throws SAXNotSupportedException When the
471 * XMLReader recognizes the property name but
472 * cannot determine its value at this time.
473 * @throws NullPointerException When <code>name</code> is <code>null</code>.
474 *
475 * @see #setProperty(String, Object)
476 */
477 public Object getProperty(String name)
478 throws SAXNotRecognizedException, SAXNotSupportedException {
479
480 if (name == null) {
481 throw new NullPointerException();
482 }
483
484 throw new SAXNotRecognizedException(name);
485 }
486 }
|