jaxp/src/share/classes/javax/xml/validation/ValidatorHandler.java
changeset 6 7f561c08de6b
equal deleted inserted replaced
0:fd16c54261b3 6:7f561c08de6b
       
     1 /*
       
     2  * Copyright 2003-2005 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package javax.xml.validation;
       
    27 
       
    28 import org.w3c.dom.ls.LSResourceResolver;
       
    29 import org.xml.sax.ContentHandler;
       
    30 import org.xml.sax.ErrorHandler;
       
    31 import org.xml.sax.SAXNotRecognizedException;
       
    32 import org.xml.sax.SAXNotSupportedException;
       
    33 
       
    34 /**
       
    35  * Streaming validator that works on SAX stream.
       
    36  *
       
    37  * <p>
       
    38  * A {@link ValidatorHandler} object is not thread-safe and not reentrant.
       
    39  * In other words, it is the application's responsibility to make
       
    40  * sure that one {@link ValidatorHandler} object is not used from
       
    41  * more than one thread at any given time.
       
    42  *
       
    43  * <p>
       
    44  * {@link ValidatorHandler} checks if the SAX events follow
       
    45  * the set of constraints described in the associated {@link Schema},
       
    46  * and additionally it may modify the SAX events (for example
       
    47  * by adding default values, etc.)
       
    48  *
       
    49  * <p>
       
    50  * {@link ValidatorHandler} extends from {@link ContentHandler},
       
    51  * but it refines the underlying {@link ContentHandler} in
       
    52  * the following way:
       
    53  * <ol>
       
    54  *  <li>startElement/endElement events must receive non-null String
       
    55  *      for <code>uri</code>, <code>localName</code>, and <code>qname</code>,
       
    56  *      even though SAX allows some of them to be null.
       
    57  *      Similarly, the user-specified {@link ContentHandler} will receive non-null
       
    58  *      Strings for all three parameters.
       
    59  *
       
    60  *  <li>Applications must ensure that {@link ValidatorHandler}'s
       
    61  *      {@link ContentHandler#startPrefixMapping(String,String)} and
       
    62  *      {@link ContentHandler#endPrefixMapping(String)} are invoked
       
    63  *      properly. Similarly, the user-specified {@link ContentHandler}
       
    64  *      will receive startPrefixMapping/endPrefixMapping events.
       
    65  *      If the {@link ValidatorHandler} introduces additional namespace
       
    66  *      bindings, the user-specified {@link ContentHandler} will receive
       
    67  *      additional startPrefixMapping/endPrefixMapping events.
       
    68  *
       
    69  *  <li>{@link org.xml.sax.Attributes} for the
       
    70  *      {@link ContentHandler#startElement(String,String,String,Attributes)} method
       
    71  *      may or may not include xmlns* attributes.
       
    72  * </ol>
       
    73  *
       
    74  * <p>
       
    75  * A {@link ValidatorHandler} is automatically reset every time
       
    76  * the startDocument method is invoked.
       
    77  *
       
    78  * <h2>Recognized Properties and Features</h2>
       
    79  * <p>
       
    80  * This spec defines the following feature that must be recognized
       
    81  * by all {@link ValidatorHandler} implementations.
       
    82  *
       
    83  * <h3><code>http://xml.org/sax/features/namespace-prefixes</code></h3>
       
    84  * <p>
       
    85  * This feature controls how a {@link ValidatorHandler} introduces
       
    86  * namespace bindings that were not present in the original SAX event
       
    87  * stream.
       
    88  * When this feature is set to true, it must make
       
    89  * sure that the user's {@link ContentHandler} will see
       
    90  * the corresponding <code>xmlns*</code> attribute in
       
    91  * the {@link org.xml.sax.Attributes} object of the
       
    92  * {@link ContentHandler#startElement(String,String,String,Attributes)}
       
    93  * callback. Otherwise, <code>xmlns*</code> attributes must not be
       
    94  * added to {@link org.xml.sax.Attributes} that's passed to the
       
    95  * user-specified {@link ContentHandler}.
       
    96  * <p>
       
    97  * (Note that regardless of this switch, namespace bindings are
       
    98  * always notified to applications through
       
    99  * {@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  * @since 1.5
       
   112  */
       
   113 public abstract class ValidatorHandler implements ContentHandler {
       
   114 
       
   115     /**
       
   116      * <p>Constructor for derived classes.</p>
       
   117      *
       
   118      * <p>The constructor does nothing.</p>
       
   119      *
       
   120      * <p>Derived classes must create {@link ValidatorHandler} objects that have
       
   121      * <code>null</code> {@link ErrorHandler} and
       
   122      * <code>null</code> {@link LSResourceResolver}.</p>
       
   123      */
       
   124     protected ValidatorHandler() {
       
   125     }
       
   126 
       
   127     /**
       
   128      * Sets the {@link ContentHandler} which receives
       
   129      * the augmented validation result.
       
   130      *
       
   131      * <p>
       
   132      * When a {@link ContentHandler} is specified, a
       
   133      * {@link ValidatorHandler} will work as a filter
       
   134      * and basically copy the incoming events to the
       
   135      * specified {@link ContentHandler}.
       
   136      *
       
   137      * <p>
       
   138      * In doing so, a {@link ValidatorHandler} may modify
       
   139      * the events, for example by adding defaulted attributes.
       
   140      *
       
   141      * <p>
       
   142      * A {@link ValidatorHandler} may buffer events to certain
       
   143      * extent, but to allow {@link ValidatorHandler} to be used
       
   144      * by a parser, the following requirement has to be met.
       
   145      *
       
   146      * <ol>
       
   147      *  <li>When
       
   148      *      {@link ContentHandler#startElement(String, String, String, Attributes)},
       
   149      *      {@link ContentHandler#endElement(String, String, String)},
       
   150      *      {@link ContentHandler#startDocument()}, or
       
   151      *      {@link ContentHandler#endDocument()}
       
   152      *      are invoked on a {@link ValidatorHandler},
       
   153      *      the same method on the user-specified {@link ContentHandler}
       
   154      *      must be invoked for the same event before the callback
       
   155      *      returns.
       
   156      *  <li>{@link ValidatorHandler} may not introduce new elements that
       
   157      *      were not present in the input.
       
   158      *
       
   159      *  <li>{@link ValidatorHandler} may not remove attributes that were
       
   160      *      present in the input.
       
   161      * </ol>
       
   162      *
       
   163      * <p>
       
   164      * When a callback method on the specified {@link ContentHandler}
       
   165      * throws an exception, the same exception object must be thrown
       
   166      * from the {@link ValidatorHandler}. The {@link ErrorHandler}
       
   167      * should not be notified of such an exception.
       
   168      *
       
   169      * <p>
       
   170      * This method can be called even during a middle of a validation.
       
   171      *
       
   172      * @param receiver
       
   173      *      A {@link ContentHandler} or a null value.
       
   174      */
       
   175     public abstract void setContentHandler(ContentHandler receiver);
       
   176 
       
   177     /**
       
   178      * Gets the {@link ContentHandler} which receives the
       
   179      * augmented validation result.
       
   180      *
       
   181      * @return
       
   182      *      This method returns the object that was last set through
       
   183      *      the {@link #getContentHandler()} method, or null
       
   184      *      if that method has never been called since this {@link ValidatorHandler}
       
   185      *      has created.
       
   186      *
       
   187      * @see #setContentHandler(ContentHandler)
       
   188      */
       
   189     public abstract ContentHandler getContentHandler();
       
   190 
       
   191     /**
       
   192      * Sets the {@link ErrorHandler} to receive errors encountered
       
   193      * during the validation.
       
   194      *
       
   195      * <p>
       
   196      * Error handler can be used to customize the error handling process
       
   197      * during a validation. When an {@link ErrorHandler} is set,
       
   198      * errors found during the validation will be first sent
       
   199      * to the {@link ErrorHandler}.
       
   200      *
       
   201      * <p>
       
   202      * The error handler can abort further validation immediately
       
   203      * by throwing {@link org.xml.sax.SAXException} from the handler. Or for example
       
   204      * it can print an error to the screen and try to continue the
       
   205      * validation by returning normally from the {@link ErrorHandler}
       
   206      *
       
   207      * <p>
       
   208      * If any {@link Throwable} is thrown from an {@link ErrorHandler},
       
   209      * the same {@link Throwable} object will be thrown toward the
       
   210      * root of the call stack.
       
   211      *
       
   212      * <p>
       
   213      * {@link ValidatorHandler} is not allowed to
       
   214      * throw {@link org.xml.sax.SAXException} without first reporting it to
       
   215      * {@link ErrorHandler}.
       
   216      *
       
   217      * <p>
       
   218      * When the {@link ErrorHandler} is null, the implementation will
       
   219      * behave as if the following {@link ErrorHandler} is set:
       
   220      * <pre>
       
   221      * class DraconianErrorHandler implements {@link ErrorHandler} {
       
   222      *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
       
   223      *         throw e;
       
   224      *     }
       
   225      *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
       
   226      *         throw e;
       
   227      *     }
       
   228      *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
       
   229      *         // noop
       
   230      *     }
       
   231      * }
       
   232      * </pre>
       
   233      *
       
   234      * <p>
       
   235      * When a new {@link ValidatorHandler} object is created, initially
       
   236      * this field is set to null.
       
   237      *
       
   238      * @param   errorHandler
       
   239      *      A new error handler to be set. This parameter can be null.
       
   240      */
       
   241     public abstract void setErrorHandler(ErrorHandler errorHandler);
       
   242 
       
   243     /**
       
   244      * Gets the current {@link ErrorHandler} set to this {@link ValidatorHandler}.
       
   245      *
       
   246      * @return
       
   247      *      This method returns the object that was last set through
       
   248      *      the {@link #setErrorHandler(ErrorHandler)} method, or null
       
   249      *      if that method has never been called since this {@link ValidatorHandler}
       
   250      *      has created.
       
   251      *
       
   252      * @see #setErrorHandler(ErrorHandler)
       
   253      */
       
   254     public abstract ErrorHandler getErrorHandler();
       
   255 
       
   256     /**
       
   257      * Sets the {@link LSResourceResolver} to customize
       
   258      * resource resolution while in a validation episode.
       
   259      *
       
   260      * <p>
       
   261      * {@link ValidatorHandler} uses a {@link LSResourceResolver}
       
   262      * when it needs to locate external resources while a validation,
       
   263      * although exactly what constitutes "locating external resources" is
       
   264      * up to each schema language.
       
   265      *
       
   266      * <p>
       
   267      * When the {@link LSResourceResolver} is null, the implementation will
       
   268      * behave as if the following {@link LSResourceResolver} is set:
       
   269      * <pre>
       
   270      * class DumbLSResourceResolver implements {@link LSResourceResolver} {
       
   271      *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
       
   272      *         String publicId, String systemId, String baseURI) {
       
   273      *
       
   274      *         return null; // always return null
       
   275      *     }
       
   276      * }
       
   277      * </pre>
       
   278      *
       
   279      * <p>
       
   280      * If a {@link LSResourceResolver} throws a {@link RuntimeException}
       
   281      *  (or instances of its derived classes),
       
   282      * then the {@link ValidatorHandler} will abort the parsing and
       
   283      * the caller of the <code>validate</code> method will receive
       
   284      * the same {@link RuntimeException}.
       
   285      *
       
   286      * <p>
       
   287      * When a new {@link ValidatorHandler} object is created, initially
       
   288      * this field is set to null.
       
   289      *
       
   290      * @param   resourceResolver
       
   291      *      A new resource resolver to be set. This parameter can be null.
       
   292      */
       
   293     public abstract void setResourceResolver(LSResourceResolver resourceResolver);
       
   294 
       
   295     /**
       
   296      * Gets the current {@link LSResourceResolver} set to this {@link ValidatorHandler}.
       
   297      *
       
   298      * @return
       
   299      *      This method returns the object that was last set through
       
   300      *      the {@link #setResourceResolver(LSResourceResolver)} method, or null
       
   301      *      if that method has never been called since this {@link ValidatorHandler}
       
   302      *      has created.
       
   303      *
       
   304      * @see #setErrorHandler(ErrorHandler)
       
   305      */
       
   306     public abstract LSResourceResolver getResourceResolver();
       
   307 
       
   308     /**
       
   309      * Obtains the {@link TypeInfoProvider} implementation of this
       
   310      * {@link ValidatorHandler}.
       
   311      *
       
   312      * <p>
       
   313      * The obtained {@link TypeInfoProvider} can be queried during a parse
       
   314      * to access the type information determined by the validator.
       
   315      *
       
   316      * <p>
       
   317      * Some schema languages do not define the notion of type,
       
   318      * for those languages, this method may not be supported.
       
   319      * However, to be compliant with this specification, implementations
       
   320      * for W3C XML Schema 1.0 must support this operation.
       
   321      *
       
   322      * @return
       
   323      *      null if the validator / schema language does not support
       
   324      *      the notion of {@link org.w3c.dom.TypeInfo}.
       
   325      *      Otherwise a non-null valid {@link TypeInfoProvider}.
       
   326      */
       
   327     public abstract TypeInfoProvider getTypeInfoProvider();
       
   328 
       
   329 
       
   330     /**
       
   331      * Look up the value of a feature flag.
       
   332      *
       
   333      * <p>The feature name is any fully-qualified URI.  It is
       
   334      * possible for a {@link ValidatorHandler} to recognize a feature name but
       
   335      * temporarily be unable to return its value.
       
   336      * Some feature values may be available only in specific
       
   337      * contexts, such as before, during, or after a validation.
       
   338      *
       
   339      * <p>Implementors are free (and encouraged) to invent their own features,
       
   340      * using names built on their own URIs.</p>
       
   341      *
       
   342      * @param name The feature name, which is a non-null fully-qualified URI.
       
   343      *
       
   344      * @return The current value of the feature (true or false).
       
   345      *
       
   346      * @throws SAXNotRecognizedException If the feature
       
   347      *   value can't be assigned or retrieved.
       
   348      * @throws SAXNotSupportedException When the
       
   349      *   {@link ValidatorHandler} recognizes the feature name but
       
   350      *   cannot determine its value at this time.
       
   351      * @throws NullPointerException When <code>name</code> is <code>null</code>.
       
   352      *
       
   353      * @see #setFeature(String, boolean)
       
   354      */
       
   355     public boolean getFeature(String name)
       
   356         throws SAXNotRecognizedException, SAXNotSupportedException {
       
   357 
       
   358         if (name == null) {
       
   359             throw new NullPointerException();
       
   360         }
       
   361 
       
   362         throw new SAXNotRecognizedException(name);
       
   363     }
       
   364 
       
   365     /**
       
   366      * <p>Set a feature for this <code>ValidatorHandler</code>.</p>
       
   367      *
       
   368      * <p>Feature can be used to control the way a
       
   369      * {@link ValidatorHandler} parses schemas. The feature name is
       
   370      * any fully-qualified URI. It is possible for a
       
   371      * {@link SchemaFactory} to
       
   372      * expose a feature value but to be unable to change the current
       
   373      * value. Some feature values may be immutable or mutable only in
       
   374      * specific contexts, such as before, during, or after a
       
   375      * validation.</p>
       
   376      *
       
   377      * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
       
   378      * When the feature is:</p>
       
   379      * <ul>
       
   380      *   <li>
       
   381      *     <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
       
   382      *     Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources.
       
   383      *     If XML processing is limited for security reasons, it will be reported via a call to the registered
       
   384      *    {@link ErrorHandler#fatalError(SAXParseException exception)}.
       
   385      *     See {@link #setErrorHandler(ErrorHandler errorHandler)}.
       
   386      *   </li>
       
   387      *   <li>
       
   388      *     <code>false</code>: the implementation will processing XML according to the XML specifications without
       
   389      *     regard to possible implementation limits.
       
   390      *   </li>
       
   391      * </ul>
       
   392      *
       
   393      * @param name The feature name, which is a non-null fully-qualified URI.
       
   394      * @param value The requested value of the feature (true or false).
       
   395      *
       
   396      * @throws SAXNotRecognizedException If the feature
       
   397      *   value can't be assigned or retrieved.
       
   398      * @throws SAXNotSupportedException When the
       
   399      *   {@link ValidatorHandler} recognizes the feature name but
       
   400      *   cannot set the requested value.
       
   401      * @throws NullPointerException When <code>name</code> is <code>null</code>.
       
   402      *
       
   403      * @see #getFeature(String)
       
   404      */
       
   405     public void setFeature(String name, boolean value)
       
   406         throws SAXNotRecognizedException, SAXNotSupportedException {
       
   407 
       
   408         if (name == null) {
       
   409             throw new NullPointerException();
       
   410         }
       
   411 
       
   412         throw new SAXNotRecognizedException(name);
       
   413     }
       
   414 
       
   415     /**
       
   416      * Set the value of a property.
       
   417      *
       
   418      * <p>The property name is any fully-qualified URI.  It is
       
   419      * possible for a {@link ValidatorHandler} to recognize a property name but
       
   420      * to be unable to change the current value.
       
   421      * Some property values may be immutable or mutable only
       
   422      * in specific contexts, such as before, during, or after
       
   423      * a validation.</p>
       
   424      *
       
   425      * <p>{@link ValidatorHandler}s are not required to recognize setting
       
   426      * any specific property names.</p>
       
   427      *
       
   428      * @param name The property name, which is a non-null fully-qualified URI.
       
   429      * @param object The requested value for the property.
       
   430      *
       
   431      * @throws SAXNotRecognizedException If the property
       
   432      *   value can't be assigned or retrieved.
       
   433      * @throws SAXNotSupportedException When the
       
   434      *   {@link ValidatorHandler} recognizes the property name but
       
   435      *   cannot set the requested value.
       
   436      * @throws NullPointerException When <code>name</code> is <code>null</code>.
       
   437      */
       
   438     public void setProperty(String name, Object object)
       
   439         throws SAXNotRecognizedException, SAXNotSupportedException {
       
   440 
       
   441         if (name == null) {
       
   442             throw new NullPointerException();
       
   443         }
       
   444 
       
   445         throw new SAXNotRecognizedException(name);
       
   446     }
       
   447 
       
   448     /**
       
   449      * Look up the value of a property.
       
   450      *
       
   451      * <p>The property name is any fully-qualified URI.  It is
       
   452      * possible for a {@link ValidatorHandler} to recognize a property name but
       
   453      * temporarily be unable to return its value.
       
   454      * Some property values may be available only in specific
       
   455      * contexts, such as before, during, or after a validation.</p>
       
   456      *
       
   457      * <p>{@link ValidatorHandler}s are not required to recognize any specific
       
   458      * property names.</p>
       
   459      *
       
   460      * <p>Implementors are free (and encouraged) to invent their own properties,
       
   461      * using names built on their own URIs.</p>
       
   462      *
       
   463      * @param name The property name, which is a non-null fully-qualified URI.
       
   464      *
       
   465      * @return The current value of the property.
       
   466      *
       
   467      * @throws SAXNotRecognizedException If the property
       
   468      *   value can't be assigned or retrieved.
       
   469      * @throws SAXNotSupportedException When the
       
   470      *   XMLReader recognizes the property name but
       
   471      *   cannot determine its value at this time.
       
   472      * @throws NullPointerException When <code>name</code> is <code>null</code>.
       
   473      *
       
   474      * @see #setProperty(String, Object)
       
   475      */
       
   476     public Object getProperty(String name)
       
   477         throws SAXNotRecognizedException, SAXNotSupportedException {
       
   478 
       
   479         if (name == null) {
       
   480             throw new NullPointerException();
       
   481         }
       
   482 
       
   483         throw new SAXNotRecognizedException(name);
       
   484     }
       
   485 }