Coverage Report - org.apache.ojb.broker.metadata.FieldTypeClasses
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldTypeClasses
N/A
N/A
3.368
FieldTypeClasses$ArrayFieldType
N/A
N/A
3.368
FieldTypeClasses$BaseFieldType
N/A
N/A
3.368
FieldTypeClasses$BigDecimalFieldType
N/A
N/A
3.368
FieldTypeClasses$BlobFieldType
N/A
N/A
3.368
FieldTypeClasses$BooleanFieldType
N/A
N/A
3.368
FieldTypeClasses$ByteArrayFieldType
N/A
N/A
3.368
FieldTypeClasses$ByteFieldType
N/A
N/A
3.368
FieldTypeClasses$ClobFieldType
N/A
N/A
3.368
FieldTypeClasses$DateFieldType
N/A
N/A
3.368
FieldTypeClasses$DoubleFieldType
N/A
N/A
3.368
FieldTypeClasses$FloatFieldType
N/A
N/A
3.368
FieldTypeClasses$ImmutableFieldType
N/A
N/A
3.368
FieldTypeClasses$IntegerFieldType
N/A
N/A
3.368
FieldTypeClasses$JavaObjectFieldType
N/A
N/A
3.368
FieldTypeClasses$LongFieldType
N/A
N/A
3.368
FieldTypeClasses$MutableFieldType
N/A
N/A
3.368
FieldTypeClasses$RefFieldType
N/A
N/A
3.368
FieldTypeClasses$ShortFieldType
N/A
N/A
3.368
FieldTypeClasses$StringFieldType
N/A
N/A
3.368
FieldTypeClasses$StructFieldType
N/A
N/A
3.368
FieldTypeClasses$TimeFieldType
N/A
N/A
3.368
FieldTypeClasses$TimestampFieldType
N/A
N/A
3.368
FieldTypeClasses$URLFieldType
N/A
N/A
3.368
 
 1  
 package org.apache.ojb.broker.metadata;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * 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  
 
 18  
 import java.lang.reflect.Method;
 19  
 import java.sql.Date;
 20  
 import java.sql.Time;
 21  
 import java.sql.Timestamp;
 22  
 import java.sql.Types;
 23  
 import java.util.Arrays;
 24  
 import java.io.Serializable;
 25  
 
 26  
 import org.apache.commons.lang.ArrayUtils;
 27  
 import org.apache.commons.lang.ObjectUtils;
 28  
 import org.apache.commons.lang.SerializationUtils;
 29  
 import org.apache.commons.lang.builder.ToStringBuilder;
 30  
 import org.apache.ojb.broker.OJBRuntimeException;
 31  
 
 32  
 /**
 33  
  * Encapsulates all {@link FieldType} as inner classes.
 34  
  *
 35  
  * @version $Id: FieldTypeClasses.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
 36  
  */
 37  
 class FieldTypeClasses
 38  
 {
 39  
     private FieldTypeClasses()
 40  
     {
 41  
     }
 42  
 
 43  
     /**
 44  
      * Returns a {@link FieldType} instance for the given sql type
 45  
      * (see {@link java.sql.Types}) as specified in JDBC 3.0 specification
 46  
      * (see JDBC 3.0 specification <em>Appendix B, Data Type Conversion Tables</em>).
 47  
      *
 48  
      * @param jdbcType Specify the type to look for.
 49  
      * @return A new specific {@link FieldType} instance.
 50  
      */
 51  
     static FieldType newFieldType(JdbcType jdbcType)
 52  
     {
 53  
         FieldType result = null;
 54  
         switch (jdbcType.getType())
 55  
         {
 56  
             case Types.ARRAY:
 57  
                 result = new ArrayFieldType();
 58  
                 break;
 59  
             case Types.BIGINT:
 60  
                 result = new LongFieldType();
 61  
                 break;
 62  
             case Types.BINARY:
 63  
                 result = new ByteArrayFieldType();
 64  
                 break;
 65  
             case Types.BIT:
 66  
                 result = new BooleanFieldType();
 67  
                 break;
 68  
             case Types.BLOB:
 69  
                 result = new BlobFieldType();
 70  
                 break;
 71  
             case Types.CHAR:
 72  
                 result = new StringFieldType();
 73  
                 break;
 74  
             case Types.CLOB:
 75  
                 result = new ClobFieldType();
 76  
                 break;
 77  
             case Types.DATE:
 78  
                 result = new DateFieldType();
 79  
                 break;
 80  
             case Types.DECIMAL:
 81  
                 result = new BigDecimalFieldType();
 82  
                 break;
 83  
 // Not needed, user have to use the underlying sql datatype in OJB mapping files
 84  
 //            case Types.DISTINCT:
 85  
 //                result = new DistinctFieldType();
 86  
 //                break;
 87  
             case Types.DOUBLE:
 88  
                 result = new DoubleFieldType();
 89  
                 break;
 90  
             case Types.FLOAT:
 91  
                 result = new FloatFieldType();
 92  
                 break;
 93  
             case Types.INTEGER:
 94  
                 result = new IntegerFieldType();
 95  
                 break;
 96  
             case Types.JAVA_OBJECT:
 97  
                 result = new JavaObjectFieldType();
 98  
                 break;
 99  
             case Types.LONGVARBINARY:
 100  
                 result = new ByteArrayFieldType();
 101  
                 break;
 102  
             case Types.LONGVARCHAR:
 103  
                 result = new StringFieldType();
 104  
                 break;
 105  
             case Types.NUMERIC:
 106  
                 result = new BigDecimalFieldType();
 107  
                 break;
 108  
             case Types.REAL:
 109  
                 result = new FloatFieldType();
 110  
                 break;
 111  
             case Types.REF:
 112  
                 result = new RefFieldType();
 113  
                 break;
 114  
             case Types.SMALLINT:
 115  
                 result = new ShortFieldType();
 116  
                 break;
 117  
             case Types.STRUCT:
 118  
                 result = new StructFieldType();
 119  
                 break;
 120  
             case Types.TIME:
 121  
                 result = new TimeFieldType();
 122  
                 break;
 123  
             case Types.TIMESTAMP:
 124  
                 result = new TimestampFieldType();
 125  
                 break;
 126  
             case Types.TINYINT:
 127  
                 result = new ByteFieldType();
 128  
                 break;
 129  
             case Types.VARBINARY:
 130  
                 result = new ByteArrayFieldType();
 131  
                 break;
 132  
             case Types.VARCHAR:
 133  
                 result = new StringFieldType();
 134  
                 break;
 135  
             case Types.OTHER:
 136  
                 result = new JavaObjectFieldType();
 137  
                 break;
 138  
 //
 139  
 //            case Types.NULL:
 140  
 //                result = new NullFieldType();
 141  
 //                break;
 142  
 
 143  
 //#ifdef JDBC30
 144  
             case Types.BOOLEAN:
 145  
                 result = new BooleanFieldType();
 146  
                 break;
 147  
             case Types.DATALINK:
 148  
                 result = new URLFieldType();
 149  
                 break;
 150  
 //#endif
 151  
             default:
 152  
                 throw new OJBRuntimeException("Unkown or not supported field type specified, specified jdbc type was '"
 153  
                         + jdbcType + "', as string: " + JdbcTypesHelper.getSqlTypeAsString(jdbcType.getType()));
 154  
         }
 155  
         // make sure that the sql type was set
 156  
         result.setSqlType(jdbcType);
 157  
         return result;
 158  
     }
 159  
 
 160  
     /**
 161  
      * Base class for all fields.
 162  
      */
 163  
     abstract static class BaseFieldType implements FieldType
 164  
     {
 165  
         int sqlType;
 166  
 
 167  
         public void setSqlType(JdbcType jdbcType)
 168  
         {
 169  
             sqlType = jdbcType.getType();
 170  
         }
 171  
 
 172  
         public int getSqlType()
 173  
         {
 174  
             return sqlType;
 175  
         }
 176  
 
 177  
         /**
 178  
          * Helper method to copy an object if possible.
 179  
          *
 180  
          * @param toCopy The object to copy.
 181  
          * @return The copy of the object or <em>null</em> clone is not supported.
 182  
          */
 183  
         Object copyIfCloneable(Object toCopy)
 184  
         {
 185  
             Object result = null;
 186  
             if(toCopy instanceof Cloneable)
 187  
             {
 188  
                 try
 189  
                 {
 190  
                     Method m = toCopy.getClass().getMethod("clone", ArrayUtils.EMPTY_CLASS_ARRAY);
 191  
                     /*
 192  
                     arminw:
 193  
                     By definition the overrided object.clone() method has to be public
 194  
                     so we don't need to make it accessible
 195  
                     */
 196  
                     //m.setAccessible(true);
 197  
                     result = m.invoke(toCopy, null);
 198  
                 }
 199  
                 catch(Exception e)
 200  
                 {
 201  
                     throw new OJBRuntimeException("Can't invoke method 'clone' on object: " + toCopy, e);
 202  
                 }
 203  
             }
 204  
             return result;
 205  
         }
 206  
 
 207  
         /**
 208  
          * Helper method to copy an object if possible.
 209  
          *
 210  
          * @param toCopy The object to copy.
 211  
          * @return The copy of the object or <em>null</em> if serialization is not supported.
 212  
          */
 213  
         Object copyIfSerializeable(Object toCopy)
 214  
         {
 215  
             Object result = null;
 216  
             if(toCopy instanceof Serializable)
 217  
             {
 218  
                 result = SerializationUtils.clone((Serializable) toCopy);
 219  
             }
 220  
             return result;
 221  
         }
 222  
 
 223  
         public String toString()
 224  
         {
 225  
             return new ToStringBuilder(this)
 226  
                     .append("sqlType", sqlType)
 227  
                     .append("sqlTypeAsString", JdbcTypesHelper.getSqlTypeAsString(sqlType))
 228  
                     .append("isMutable", isMutable()).toString();
 229  
         }
 230  
     }
 231  
 
 232  
     /**
 233  
      * Base class for all <em>immutable</em> types, like Number fields, Strings, ...
 234  
      */
 235  
     abstract static class ImmutableFieldType extends BaseFieldType
 236  
     {
 237  
         public boolean isMutable()
 238  
         {
 239  
             return false;
 240  
         }
 241  
 
 242  
         public Object copy(Object source)
 243  
         {
 244  
             return source;
 245  
         }
 246  
 
 247  
         public boolean equals(Object firstValue, Object secondValue)
 248  
         {
 249  
             return ObjectUtils.equals(firstValue, secondValue);
 250  
         }
 251  
     }
 252  
 
 253  
     /**
 254  
      * Base class for all <em>mutable</em> fields.
 255  
      */
 256  
     abstract static class MutableFieldType extends BaseFieldType
 257  
     {
 258  
         public boolean isMutable()
 259  
         {
 260  
             return true;
 261  
         }
 262  
 
 263  
         public boolean equals(Object firstValue, Object secondValue)
 264  
         {
 265  
             return ObjectUtils.equals(firstValue, secondValue);
 266  
         }
 267  
     }
 268  
 
 269  
     /**
 270  
      * Clob fields are logical pointer to DB, so for OJB it's immutable
 271  
      * @see BlobFieldType
 272  
      */
 273  
     public static class ClobFieldType extends ImmutableFieldType
 274  
     {
 275  
     }
 276  
 
 277  
     /**
 278  
      * Blob fields are logical pointer to DB, so for OJB it's immutable.
 279  
      * Snip of JDBC specification:
 280  
      * "An application does not deal directly with the LOCATOR(blob) and
 281  
      * LOCATOR(clob) types that are defined in SQL. By default, a JDBC
 282  
      * driver should implement the Blob and Clob interfaces using the
 283  
      * appropriate locator type. Also by default, Blob and Clob objects
 284  
      * remain valid only during the transaction in which they are created."
 285  
      */
 286  
     public static class BlobFieldType extends ImmutableFieldType
 287  
     {
 288  
     }
 289  
 
 290  
     /**
 291  
      * Array fields are logical pointer to DB, so for OJB it's immutable.
 292  
      * Snip of JDBC specification:
 293  
      * "The Array object returned to an application by the ResultSet.getArray and
 294  
      * CallableStatement.getArray methods is a logical pointer to the SQL ARRAY
 295  
      * value in the database; it does not contain the contents of the SQL ARRAY value."
 296  
      */
 297  
     public static class ArrayFieldType extends ImmutableFieldType
 298  
     {
 299  
     }
 300  
 
 301  
     /**
 302  
      * Ref fields are logical pointer to DB, so for OJB it's immutable.
 303  
      * Snip of JDBC specification:
 304  
      * "An SQL REF value is a pointer; therefore, a Ref object, which is the mapping of a
 305  
      * REF value, is likewise a pointer and does not contain the data of the structured type
 306  
      * instance to which it refers."
 307  
      */
 308  
     public static class RefFieldType extends ImmutableFieldType
 309  
     {
 310  
     }
 311  
 
 312  
     /**
 313  
      * When using SQL UDT's it's possible that the jdbc-driver returns
 314  
      * full materialized java objects defined by the user.
 315  
      */
 316  
     public static class StructFieldType extends MutableFieldType
 317  
     {
 318  
         // TODO: does this make sense?? or Struct instances always Locator objects?
 319  
         public Object copy(Object fieldValue)
 320  
         {
 321  
             if(fieldValue == null) return null;
 322  
 
 323  
             Object copy = copyIfCloneable(fieldValue);
 324  
             if(copy == null)
 325  
             {
 326  
                 copy = copyIfSerializeable(fieldValue);
 327  
             }
 328  
             return copy == null ? fieldValue : copy;
 329  
         }
 330  
     }
 331  
 
 332  
     /**
 333  
      * If a user-defined object is used, we can check if object is
 334  
      * {@link Cloneable} or {@link Serializable} to copy the object.
 335  
      * If not possible return the specified object instance.
 336  
      */
 337  
     public static class JavaObjectFieldType extends MutableFieldType
 338  
     {
 339  
         public Object copy(Object fieldValue)
 340  
         {
 341  
             if(fieldValue == null) return null;
 342  
 
 343  
             Object copy = copyIfCloneable(fieldValue);
 344  
             if(copy == null)
 345  
             {
 346  
                 copy = copyIfSerializeable(fieldValue);
 347  
             }
 348  
             return copy == null ? fieldValue : copy;
 349  
         }
 350  
     }
 351  
 
 352  
     public static class ByteArrayFieldType extends MutableFieldType
 353  
     {
 354  
         public Object copy(Object fieldValue)
 355  
         {
 356  
             byte[] result = null;
 357  
             if(fieldValue != null)
 358  
             {
 359  
                 byte[] source = (byte[]) fieldValue;
 360  
                 int length = source.length;
 361  
                 result = new byte[length];
 362  
                 System.arraycopy(fieldValue, 0, result, 0, length);
 363  
             }
 364  
             return result;
 365  
         }
 366  
 
 367  
         public boolean equals(Object firstValue, Object secondValue)
 368  
         {
 369  
             return Arrays.equals((byte[]) firstValue, (byte[]) secondValue);
 370  
         }
 371  
     }
 372  
 
 373  
     public static class DateFieldType extends MutableFieldType
 374  
     {
 375  
         public Object copy(Object fieldValue)
 376  
         {
 377  
             Date source = (Date) fieldValue;
 378  
             return source != null ? new Date(source.getTime()) : null;
 379  
         }
 380  
     }
 381  
 
 382  
     public static class TimeFieldType extends MutableFieldType
 383  
     {
 384  
         public Object copy(Object fieldValue)
 385  
         {
 386  
             Time source = (Time) fieldValue;
 387  
             return source != null ? new Time(source.getTime()) : null;
 388  
         }
 389  
     }
 390  
 
 391  
     public static class TimestampFieldType extends MutableFieldType
 392  
     {
 393  
         public Object copy(Object fieldValue)
 394  
         {
 395  
             Timestamp result = null;
 396  
             if(fieldValue != null)
 397  
             {
 398  
                 Timestamp source = (Timestamp) fieldValue;
 399  
                 result = (Timestamp) source.clone();
 400  
             }
 401  
             return result;
 402  
         }
 403  
     }
 404  
 
 405  
     public static class StringFieldType extends ImmutableFieldType
 406  
     {
 407  
     }
 408  
 
 409  
     public static class BigDecimalFieldType extends ImmutableFieldType
 410  
     {
 411  
     }
 412  
 
 413  
     public static class BooleanFieldType extends ImmutableFieldType
 414  
     {
 415  
     }
 416  
 
 417  
     public static class ByteFieldType extends ImmutableFieldType
 418  
     {
 419  
     }
 420  
 
 421  
     public static class ShortFieldType extends ImmutableFieldType
 422  
     {
 423  
 
 424  
     }
 425  
 
 426  
     public static class IntegerFieldType extends ImmutableFieldType
 427  
     {
 428  
 
 429  
     }
 430  
 
 431  
     public static class LongFieldType extends ImmutableFieldType
 432  
     {
 433  
 
 434  
     }
 435  
 
 436  
     public static class FloatFieldType extends ImmutableFieldType
 437  
     {
 438  
 
 439  
     }
 440  
 
 441  
     public static class DoubleFieldType extends ImmutableFieldType
 442  
     {
 443  
 
 444  
     }
 445  
 
 446  
     public static class URLFieldType extends ImmutableFieldType
 447  
     {
 448  
 
 449  
     }
 450  
 }