1 /**
   2  * Copyright (c) 2001, Thai Open Source Software Center Ltd
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions are
   7  * met:
   8  *
   9  *     Redistributions of source code must retain the above copyright
  10  *     notice, this list of conditions and the following disclaimer.
  11  *
  12  *     Redistributions in binary form must reproduce the above copyright
  13  *     notice, this list of conditions and the following disclaimer in
  14  *     the documentation and/or other materials provided with the
  15  *     distribution.
  16  *
  17  *     Neither the name of the Thai Open Source Software Center Ltd nor
  18  *     the names of its contributors may be used to endorse or promote
  19  *     products derived from this software without specific prior written
  20  *     permission.
  21  *
  22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
  26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  */
  34 package org.relaxng.datatype;
  35 
  36 /**
  37  * Datatype object.
  38  *
  39  * This object has the following functionality:
  40  *
  41  * <ol>
  42  *  <li> functionality to identify a class of character sequences. This is
  43  *       done through the isValid method.
  44  *
  45  *  <li> functionality to produce a "value object" from a character sequence and
  46  *               context information.
  47  *
  48  *  <li> functionality to test the equality of two value objects.
  49  * </ol>
  50  *
  51  * This interface also defines the createStreamingValidator method,
  52  * which is intended to efficiently support the validation of
  53  * large character sequences.
  54  *
  55  * @author <a href="mailto:jjc@jclark.com">James Clark</a>
  56  * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
  57  */
  58 public interface Datatype {
  59 
  60         /**
  61          * Checks if the specified 'literal' matches this Datatype
  62          * with respect to the current context.
  63          *
  64          * @param literal
  65          *              the lexical representation to be checked.
  66          * @param context
  67          *              If this datatype is context-dependent
  68          *              (i.e. the {@link #isContextDependent} method returns true),
  69          *              then the caller must provide a non-null valid context object.
  70          *              Otherwise, the caller can pass null.
  71          *
  72          * @return
  73          *              true if the 'literal' is a member of this Datatype;
  74          *              false if it's not a member of this Datatype.
  75          */
  76         boolean isValid( String literal, ValidationContext context );
  77 
  78         /**
  79          * Similar to the isValid method but throws an exception with diagnosis
  80          * in case of errors.
  81          *
  82          * <p>
  83          * If the specified 'literal' is a valid lexical representation for this
  84          * datatype, then this method must return without throwing any exception.
  85          * If not, the callee must throw an exception (with diagnosis message,
  86          * if possible.)
  87          *
  88          * <p>
  89          * The application can use this method to provide detailed error message
  90          * to users. This method is kept separate from the isValid method to
  91          * achieve higher performance during normal validation.
  92          *
  93          * @exception DatatypeException
  94          *              If the given literal is invalid, then this exception is thrown.
  95          *              If the callee supports error diagnosis, then the exception should
  96          *              contain a diagnosis message.
  97          */
  98         void checkValid( String literal, ValidationContext context )
  99                 throws DatatypeException;
 100 
 101         /**
 102          * Creates an instance of a streaming validator for this type.
 103          *
 104          * <p>
 105          * By using streaming validators instead of the isValid method,
 106          * the caller can avoid keeping the entire string, which is
 107          * sometimes quite big, in memory.
 108          *
 109          * @param context
 110          *              If this datatype is context-dependent
 111          *              (i.e. the {@link #isContextDependent} method returns true),
 112          *              then the caller must provide a non-null valid context object.
 113          *              Otherwise, the caller can pass null.
 114          *              The callee may keep a reference to this context object
 115          *              only while the returned streaming validator is being used.
 116          */
 117         DatatypeStreamingValidator createStreamingValidator( ValidationContext context );
 118 
 119         /**
 120          * Converts lexcial value and the current context to the corresponding
 121          * value object.
 122          *
 123          * <p>
 124          * The caller cannot generally assume that the value object is
 125          * a meaningful Java object. For example, the caller cannot expect
 126          * this method to return <code>java.lang.Number</code> type for
 127          * the "integer" type of XML Schema Part 2.
 128          *
 129          * <p>
 130          * Also, the caller cannot assume that the equals method and
 131          * the hashCode method of the value object are consistent with
 132          * the semantics of the datatype. For that purpose, the sameValue
 133          * method and the valueHashCode method have to be used. Note that
 134          * this means you cannot use classes like
 135          * <code>java.util.Hashtable</code> to store the value objects.
 136          *
 137          * <p>
 138          * The returned value object should be used solely for the sameValue
 139          * and valueHashCode methods.
 140          *
 141          * @param context
 142          *              If this datatype is context-dependent
 143          *              (when the {@link #isContextDependent} method returns true),
 144          *              then the caller must provide a non-null valid context object.
 145          *              Otherwise, the caller can pass null.
 146          *
 147          * @return      null
 148          *              when the given lexical value is not a valid lexical
 149          *              value for this type.
 150          */
 151         Object createValue( String literal, ValidationContext context );
 152 
 153         /**
 154          * Tests the equality of two value objects which were originally
 155          * created by the createValue method of this object.
 156          *
 157          * The behavior is undefined if objects not created by this type
 158          * are passed. It is the caller's responsibility to ensure that
 159          * value objects belong to this type.
 160          *
 161          * @return
 162          *              true if two value objects are considered equal according to
 163          *              the definition of this datatype; false if otherwise.
 164          */
 165         boolean sameValue( Object value1, Object value2 );
 166 
 167 
 168         /**
 169          * Computes the hash code for a value object,
 170          * which is consistent with the sameValue method.
 171          *
 172          * @return
 173          *              hash code for the specified value object.
 174          */
 175         int valueHashCode( Object value );
 176 
 177 
 178 
 179 
 180         /**
 181          * Indicates that the datatype doesn't have ID/IDREF semantics.
 182          *
 183          * This value is one of the possible return values of the
 184          * {@link #getIdType} method.
 185          */
 186         public static final int ID_TYPE_NULL = 0;
 187 
 188         /**
 189          * Indicates that RELAX NG compatibility processors should
 190          * treat this datatype as having ID semantics.
 191          *
 192          * This value is one of the possible return values of the
 193          * {@link #getIdType} method.
 194          */
 195         public static final int ID_TYPE_ID = 1;
 196 
 197         /**
 198          * Indicates that RELAX NG compatibility processors should
 199          * treat this datatype as having IDREF semantics.
 200          *
 201          * This value is one of the possible return values of the
 202          * {@link #getIdType} method.
 203          */
 204         public static final int ID_TYPE_IDREF = 2;
 205 
 206         /**
 207          * Indicates that RELAX NG compatibility processors should
 208          * treat this datatype as having IDREFS semantics.
 209          *
 210          * This value is one of the possible return values of the
 211          * {@link #getIdType} method.
 212          */
 213         public static final int ID_TYPE_IDREFS = 3;
 214 
 215         /**
 216          * Checks if the ID/IDREF semantics is associated with this
 217          * datatype.
 218          *
 219          * <p>
 220          * This method is introduced to support the RELAX NG DTD
 221          * compatibility spec. (Of course it's always free to use
 222          * this method for other purposes.)
 223          *
 224          * <p>
 225          * If you are implementing a datatype library and have no idea about
 226          * the "RELAX NG DTD compatibility" thing, just return
 227          * <code>ID_TYPE_NULL</code> is fine.
 228          *
 229          * @return
 230          *              If this datatype doesn't have any ID/IDREF semantics,
 231          *              it returns {@link #ID_TYPE_NULL}. If it has such a semantics
 232          *              (for example, XSD:ID, XSD:IDREF and comp:ID type), then
 233          *              it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or
 234          *              {@link #ID_TYPE_IDREFS}.
 235          */
 236         public int getIdType();
 237 
 238 
 239         /**
 240          * Checks if this datatype may need a context object for
 241          * the validation.
 242          *
 243          * <p>
 244          * The callee must return true even when the context
 245          * is not always necessary. (For example, the "QName" type
 246          * doesn't need a context object when validating unprefixed
 247          * string. But nonetheless QName must return true.)
 248          *
 249          * <p>
 250          * XSD's <code>string</code> and <code>short</code> types
 251          * are examples of context-independent datatypes.
 252          * Its <code>QName</code> and <code>ENTITY</code> types
 253          * are examples of context-dependent datatypes.
 254          *
 255          * <p>
 256          * When a datatype is context-independent, then
 257          * the {@link #isValid} method, the {@link #checkValid} method,
 258          * the {@link #createStreamingValidator} method and
 259          * the {@link #createValue} method can be called without
 260          * providing a context object.
 261          *
 262          * @return
 263          *              <b>true</b> if this datatype is context-dependent
 264          *              (it needs a context object sometimes);
 265          *
 266          *              <b>false</b> if this datatype is context-<b>in</b>dependent
 267          *              (it never needs a context object).
 268          */
 269         public boolean isContextDependent();
 270 }