Coverage Report - org.apache.ojb.broker.metadata.FieldDescriptor
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldDescriptor
N/A
N/A
1.596
FieldDescriptor$1
N/A
N/A
1.596
 
 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.io.Serializable;
 19  
 import java.util.Comparator;
 20  
 
 21  
 import org.apache.commons.lang.SerializationUtils;
 22  
 import org.apache.commons.lang.SystemUtils;
 23  
 import org.apache.commons.lang.builder.ToStringBuilder;
 24  
 import org.apache.commons.lang.builder.ToStringStyle;
 25  
 import org.apache.ojb.broker.OJBRuntimeException;
 26  
 import org.apache.ojb.broker.metadata.fieldaccess.AnonymousPersistentField;
 27  
 import org.apache.ojb.broker.accesslayer.conversions.FieldConversion;
 28  
 import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl;
 29  
 import org.apache.ojb.broker.util.ClassHelper;
 30  
 
 31  
 /**
 32  
  * A FieldDescriptor holds the mapping information for a specific member-variable
 33  
  * of a persistent object.
 34  
  * <br>
 35  
  * Note: Be careful when use references of this class or caching instances of this class,
 36  
  * because instances could become invalid (see {@link MetadataManager}).
 37  
  *
 38  
  * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
 39  
  * @version $Id: FieldDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
 40  
  */
 41  
 public class FieldDescriptor extends AttributeDescriptorBase implements XmlCapable, Serializable
 42  
 {
 43  
         private static final long serialVersionUID = 7865777758296851949L;
 44  
 
 45  
     public static final String ACCESS_ANONYMOUS = RepositoryElements.TAG_ACCESS_ANONYMOUS;
 46  
     public static final String ACCESS_READONLY = RepositoryElements.TAG_ACCESS_READONLY;
 47  
     public static final String ACCESS_READWRITE = RepositoryElements.TAG_ACCESS_READWRITE;
 48  
 
 49  
     private int m_ColNo;
 50  
     private String m_ColumnName;
 51  
     private String m_ColumnType;
 52  
     private boolean m_IsKeyField = false;
 53  
     private boolean indexed = false;
 54  
     private boolean m_autoIncrement = false;
 55  
     private String m_sequenceName;
 56  
     private JdbcType m_jdbcType;
 57  
 
 58  
     private int length = 0;
 59  
     private int precision = 0;
 60  
     private int scale = 0;
 61  
     private boolean required = false;
 62  
     private boolean scaleSpecified = false;
 63  
     private boolean precisionSpecified = false;
 64  
     private boolean lengthSpecified = false;
 65  
     private FieldConversion fieldConversion = null;
 66  
     // true if field is used for optimistic locking BRJ
 67  
     private boolean m_locking = false;
 68  
     // if locking is true and updateLock is true then
 69  
     // on save lock columns will be updated.
 70  
     // if false then it is the responsibility of the
 71  
     // dbms to update all lock columns eg using triggers
 72  
     private boolean updateLock = true;
 73  
     private String m_access;
 74  
 
 75  
     /**
 76  
      * returns a comparator that allows to sort a Vector of FieldMappingDecriptors
 77  
      * according to their m_Order entries.
 78  
      */
 79  
     public static Comparator getComparator()
 80  
     {
 81  
         return new Comparator()
 82  
         {
 83  
             public int compare(Object o1, Object o2)
 84  
             {
 85  
                 FieldDescriptor fmd1 = (FieldDescriptor) o1;
 86  
                 FieldDescriptor fmd2 = (FieldDescriptor) o2;
 87  
                 if (fmd1.getColNo() < fmd2.getColNo())
 88  
                 {
 89  
                     return -1;
 90  
                 }
 91  
                 else if (fmd1.getColNo() > fmd2.getColNo())
 92  
                 {
 93  
                     return 1;
 94  
                 }
 95  
                 else
 96  
                 {
 97  
                     return 0;
 98  
                 }
 99  
             }
 100  
         };
 101  
     }
 102  
 
 103  
     /**
 104  
      * Constructor declaration
 105  
      *
 106  
      * @param cld The parent {@link ClassDescriptor}
 107  
      * @param id A field id - unique against all other fields in the {@link ClassDescriptor}
 108  
      */
 109  
     public FieldDescriptor(ClassDescriptor cld, int id)
 110  
     {
 111  
         super(cld);
 112  
         m_ColNo = id;
 113  
     }
 114  
 
 115  
     /**
 116  
      *
 117  
      */
 118  
     public String getColumnName()
 119  
     {
 120  
         return m_ColumnName;
 121  
     }
 122  
 
 123  
     /**
 124  
      * Answer the qualified ColumnName<br>
 125  
      * ie: myTab.name
 126  
      *
 127  
      * @return
 128  
      */
 129  
     public String getFullColumnName()                        // BRJ
 130  
     {
 131  
         return getClassDescriptor().getFullTableName() + "." + getColumnName();
 132  
     }
 133  
 
 134  
     public void setColumnName(String str)
 135  
     {
 136  
         m_ColumnName = str;
 137  
     }
 138  
 
 139  
     public String getColumnType()
 140  
     {
 141  
         return m_ColumnType;
 142  
     }
 143  
 
 144  
     public void setColumnType(String str)
 145  
     {
 146  
         m_ColumnType = str;
 147  
         m_jdbcType = lookupJdbcType();
 148  
     }
 149  
 
 150  
     /**
 151  
      * Returns the corresponding database {@link JdbcType}) of this field,
 152  
      * defined by the JDBC 3.0 specification, e.g. <em>VARCHAR</em>, <em>VARBINARY</em> ...
 153  
      * <p/>
 154  
      * The complement class is {@link FieldType}) which manage the java field
 155  
      * type, e.g. a <em>String</em>, <em>byte[]</em> ...
 156  
      *
 157  
      * Returns the mapped jdbc type of this field (see complement {@link FieldType}), defined by
 158  
      * the JDBC specification.
 159  
      * @return The jdbc database type of this field.
 160  
      */
 161  
     public JdbcType getJdbcType()
 162  
     {
 163  
         // check if jdbcType is assigned
 164  
         if(m_jdbcType == null)
 165  
         {
 166  
             m_jdbcType = lookupJdbcType();
 167  
         }
 168  
         return m_jdbcType;
 169  
     }
 170  
 
 171  
     /**
 172  
      * determines the JDBC type (represented as an int value as specified
 173  
      * by java.sql.Types) of a FIELDDESCRIPTOR.
 174  
      *
 175  
      * @return int the int value representing the Type according to
 176  
      * java.sql.Types.
 177  
      */
 178  
     private JdbcType lookupJdbcType()
 179  
     {
 180  
         JdbcType result = null;
 181  
         String columnType = getColumnType();
 182  
         // if sql type was not set in metadata we use reflection
 183  
         // to determine sql type by reflection
 184  
         if (columnType == null)
 185  
         {
 186  
             try
 187  
             {
 188  
                 result = JdbcTypesHelper.getJdbcTypeByReflection(m_PersistentField.getType().getName());
 189  
             }
 190  
             catch(Exception e)
 191  
             {
 192  
                 String eol = SystemUtils.LINE_SEPARATOR;
 193  
                 throw new OJBRuntimeException("Can't automatically assign a jdbc field-type for field: "
 194  
                         + eol + this.toXML() + eol + "in class: " + eol + getClassDescriptor(), e);
 195  
             }
 196  
         }
 197  
         else
 198  
         {
 199  
             try
 200  
             {
 201  
                 result = JdbcTypesHelper.getJdbcTypeByName(columnType);
 202  
             }
 203  
             catch(Exception e)
 204  
             {
 205  
                 String eol = SystemUtils.LINE_SEPARATOR;
 206  
                 throw new OJBRuntimeException("Can't assign the specified jdbc field-type '"+columnType+"' for field: "
 207  
                         + eol + this.toXML() + eol + "in class: " + eol + getClassDescriptor(), e);
 208  
             }
 209  
         }
 210  
         return result;
 211  
     }
 212  
 
 213  
     /**
 214  
      * Returns a string representation of this class.
 215  
      */
 216  
     public String toString()
 217  
     {
 218  
         ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE);
 219  
         buf.append("columnName", m_ColumnName);
 220  
         buf.append("columnType", m_ColumnType);
 221  
         buf.append("isPrimaryKey", m_IsKeyField);
 222  
         buf.append("isLocking", m_locking);
 223  
         buf.append("isAutoincrement", m_autoIncrement);
 224  
         buf.append("access", m_access);
 225  
         buf.append("sequenceName", m_sequenceName);
 226  
         buf.append("jdbcType", m_jdbcType);
 227  
         buf.append("super_class_fields ", "=> " + super.toString());
 228  
         buf.append(SystemUtils.LINE_SEPARATOR);
 229  
         return buf.toString();
 230  
     }
 231  
 
 232  
     /**
 233  
      * Gets the fieldConversion.
 234  
      * @return Returns a FieldConversion
 235  
      */
 236  
     public FieldConversion getFieldConversion()
 237  
     {
 238  
         // if no conversion is specified use the default conversion
 239  
         if (fieldConversion == null)
 240  
         {
 241  
             fieldConversion = new FieldConversionDefaultImpl();
 242  
         }
 243  
         return fieldConversion;
 244  
     }
 245  
 
 246  
     /**
 247  
      * Sets the fieldConversion.
 248  
      * @param fieldConversion The fieldConversion to set
 249  
      * @deprecated use setFieldConversionClassName instead
 250  
      */
 251  
     public void setFieldConversion(FieldConversion fieldConversion)
 252  
     {
 253  
         this.fieldConversion = fieldConversion;
 254  
     }
 255  
 
 256  
     /**
 257  
      * Sets the fieldConversion.
 258  
      * @param fieldConversionClassName The fieldConversion to set
 259  
      */
 260  
     public void setFieldConversionClassName(String fieldConversionClassName)
 261  
     {
 262  
         try
 263  
         {
 264  
             this.fieldConversion = (FieldConversion) ClassHelper.newInstance(fieldConversionClassName);
 265  
         }
 266  
         catch (Exception e)
 267  
         {
 268  
             throw new MetadataException(
 269  
                     "Could not instantiate FieldConversion class using default constructor", e);
 270  
         }
 271  
     }
 272  
 
 273  
     public boolean isIndexed()
 274  
     {
 275  
         return indexed;
 276  
     }
 277  
 
 278  
     public void setIndexed(boolean indexed)
 279  
     {
 280  
         this.indexed = indexed;
 281  
     }
 282  
 
 283  
     public boolean isAutoIncrement()
 284  
     {
 285  
         return m_autoIncrement;
 286  
     }
 287  
 
 288  
     public void setAutoIncrement(boolean autoIncrement)
 289  
     {
 290  
         m_autoIncrement = autoIncrement;
 291  
     }
 292  
 
 293  
     public String getSequenceName()
 294  
     {
 295  
         return m_sequenceName;
 296  
     }
 297  
 
 298  
     public void setSequenceName(String sequenceName)
 299  
     {
 300  
         m_sequenceName = sequenceName;
 301  
     }
 302  
 
 303  
     public boolean isPrimaryKey()
 304  
     {
 305  
         return m_IsKeyField;
 306  
     }
 307  
 
 308  
     public void setPrimaryKey(boolean b)
 309  
     {
 310  
         m_IsKeyField = b;
 311  
     }
 312  
 
 313  
     public int getColNo()
 314  
     {
 315  
         return m_ColNo;
 316  
     }
 317  
 
 318  
     /**
 319  
      * Gets the locking.
 320  
      * @return Returns a boolean
 321  
      */
 322  
     public boolean isLocking()
 323  
     {
 324  
         return m_locking;
 325  
     }
 326  
 
 327  
     /**
 328  
      * Sets the locking.
 329  
      * @param locking The locking to set
 330  
      */
 331  
     public void setLocking(boolean locking)
 332  
     {
 333  
         m_locking = locking;
 334  
     }
 335  
 
 336  
     /**
 337  
      * Gets the updateLock
 338  
      * updateLock controls whether the lock fields should be
 339  
      * updated by OJB when a row is saved
 340  
      * If false then the dbms needs to update the lock fields.
 341  
      * The default is true
 342  
      * @return Returns a boolean
 343  
      */
 344  
     public boolean isUpdateLock()
 345  
     {
 346  
         return updateLock;
 347  
     }
 348  
 
 349  
     /**
 350  
      * Sets the updateLock
 351  
      * updateLock controls whether the lock fields should be
 352  
      * updated by OJB when a row is saved.
 353  
      * If false then the dbms needs to update the lock fields.
 354  
      * The default is true
 355  
      * @param updateLock The updateLock to set
 356  
      */
 357  
     public void setUpdateLock(boolean updateLock)
 358  
     {
 359  
         this.updateLock = updateLock;
 360  
     }
 361  
 
 362  
     public void setLength(int length)
 363  
     {
 364  
         this.length = length;
 365  
     }
 366  
 
 367  
     public int getLength()
 368  
     {
 369  
         return this.length;
 370  
     }
 371  
 
 372  
     public void setPrecision(int precision)
 373  
     {
 374  
         this.precision = precision;
 375  
     }
 376  
 
 377  
     public int getPrecision()
 378  
     {
 379  
         return this.precision;
 380  
     }
 381  
 
 382  
     public void setScale(int scale)
 383  
     {
 384  
         this.scale = scale;
 385  
     }
 386  
 
 387  
     public int getScale()
 388  
     {
 389  
         return this.scale;
 390  
     }
 391  
 
 392  
     public boolean isRequired()
 393  
     {
 394  
         return required;
 395  
     }
 396  
 
 397  
     public void setRequired(boolean required)
 398  
     {
 399  
         this.required = required;
 400  
     }
 401  
 
 402  
     public boolean isScaleSpecified()
 403  
     {
 404  
         return scaleSpecified;
 405  
     }
 406  
 
 407  
     public void setScaleSpecified(boolean scaleSpecified)
 408  
     {
 409  
         this.scaleSpecified = scaleSpecified;
 410  
     }
 411  
 
 412  
     public boolean isPrecisionSpecified()
 413  
     {
 414  
         return precisionSpecified;
 415  
     }
 416  
 
 417  
     public void setPrecisionSpecified(boolean precisionSpecified)
 418  
     {
 419  
         this.precisionSpecified = precisionSpecified;
 420  
     }
 421  
 
 422  
     public boolean isLengthSpecified()
 423  
     {
 424  
         return lengthSpecified;
 425  
     }
 426  
 
 427  
     public void setLengthSpecified(boolean lengthSpecified)
 428  
     {
 429  
         this.lengthSpecified = lengthSpecified;
 430  
     }
 431  
 
 432  
     public String getAccess()
 433  
     {
 434  
         return m_access;
 435  
     }
 436  
 
 437  
     public void setAccess(String access)
 438  
     {
 439  
         if (access == null)
 440  
         {
 441  
             access = ACCESS_READWRITE;
 442  
         }
 443  
 
 444  
         if (ACCESS_ANONYMOUS.equals(access) ||
 445  
                 ACCESS_READONLY.equals(access) ||
 446  
                 ACCESS_READWRITE.equals(access))
 447  
         {
 448  
             m_access = access;
 449  
         }
 450  
         else
 451  
         {
 452  
             throw new OJBRuntimeException("Try to set unkown field 'access' value: " + access);
 453  
         }
 454  
     }
 455  
 
 456  
     public boolean isAccessReadOnly()
 457  
     {
 458  
         return ACCESS_READONLY.equals(getAccess());
 459  
     }
 460  
 
 461  
     /**
 462  
      * Returns <em>true</em> if this field is declared as anonymous field.
 463  
      */
 464  
     public boolean isAnonymous()
 465  
     {
 466  
         return AnonymousPersistentField.class.isAssignableFrom(getPersistentField().getClass()) ? true : false;
 467  
     }
 468  
 
 469  
     /*
 470  
      * @see XmlCapable#toXML()
 471  
      */
 472  
     public String toXML()
 473  
     {
 474  
         RepositoryTags tags = RepositoryTags.getInstance();
 475  
         String eol = SystemUtils.LINE_SEPARATOR;
 476  
 
 477  
         //opening tag + attributes
 478  
         StringBuffer result = new StringBuffer( 1024 );
 479  
         result.append( "      " );
 480  
         result.append( tags.getOpeningTagNonClosingById( FIELD_DESCRIPTOR ) );
 481  
         result.append( " " );
 482  
         result.append( eol );
 483  
 
 484  
         //        // id
 485  
         //        String id = new Integer(getColNo()).toString();
 486  
         //        result += /*"        " +*/ tags.getAttribute(ID, id) + eol;
 487  
 
 488  
         // name
 489  
         result.append( "        " );
 490  
         result.append( tags.getAttribute( FIELD_NAME, this.getAttributeName() ) );
 491  
         result.append( eol );
 492  
 
 493  
         // table not yet implemented
 494  
 
 495  
         // column
 496  
         result.append( "        " );
 497  
         result.append( tags.getAttribute( COLUMN_NAME, this.getColumnName() ) );
 498  
         result.append( eol );
 499  
 
 500  
         // jdbc-type
 501  
         result.append( "        " );
 502  
         result.append( tags.getAttribute( JDBC_TYPE, this.getColumnType() ) );
 503  
         result.append( eol );
 504  
 
 505  
         // primarykey
 506  
         if( this.isPrimaryKey() )
 507  
         {
 508  
             result.append( "        " );
 509  
             result.append( tags.getAttribute( PRIMARY_KEY, "true" ) );
 510  
             result.append( eol );
 511  
         }
 512  
 
 513  
         // nullable
 514  
         if( this.isRequired() )
 515  
         {
 516  
             result.append( "        " );
 517  
             result.append( tags.getAttribute( NULLABLE, "false" ) );
 518  
             result.append( eol );
 519  
         }
 520  
 
 521  
         // indexed not yet implemented
 522  
 
 523  
         // autoincrement
 524  
         if( this.isAutoIncrement() )
 525  
         {
 526  
             result.append( "        " );
 527  
             result.append( tags.getAttribute( AUTO_INCREMENT, "true" ) );
 528  
             result.append( eol );
 529  
         }
 530  
 
 531  
         // locking
 532  
         if( this.isLocking() )
 533  
         {
 534  
             result.append( "        " );
 535  
             result.append( tags.getAttribute( LOCKING, "true" ) );
 536  
             result.append( eol );
 537  
         }
 538  
 
 539  
         // updateLock
 540  
         // default is true so only write if false
 541  
         if( !this.isUpdateLock() )
 542  
         {
 543  
             result.append( "        " );
 544  
             result.append( tags.getAttribute( UPDATE_LOCK, "false" ) );
 545  
             result.append( eol );
 546  
         }
 547  
 
 548  
         // default-fetch not yet implemented
 549  
 
 550  
         // conversion
 551  
         if( this.getFieldConversion().getClass() != FieldConversionDefaultImpl.class )
 552  
         {
 553  
             result.append( "        " );
 554  
             result.append( tags.getAttribute( FIELD_CONVERSION, getFieldConversion().getClass().getName() ) );
 555  
             result.append( eol );
 556  
         }
 557  
 
 558  
         // length
 559  
         if( this.isLengthSpecified() )
 560  
         {
 561  
             result.append( "        " );
 562  
             result.append( tags.getAttribute( LENGTH, "" + getLength() ) );
 563  
             result.append( eol );
 564  
         }
 565  
 
 566  
         // precision
 567  
         if( this.isPrecisionSpecified() )
 568  
         {
 569  
             result.append( "        " );
 570  
             result.append( tags.getAttribute( PRECISION, "" + getPrecision() ) );
 571  
             result.append( eol );
 572  
         }
 573  
 
 574  
         // scale
 575  
         if( this.isScaleSpecified() )
 576  
         {
 577  
             result.append( "        " );
 578  
             result.append( tags.getAttribute( SCALE, "" + getScale() ) );
 579  
             result.append( eol );
 580  
         }
 581  
 
 582  
         // access
 583  
         result.append( "        " );
 584  
         result.append( tags.getAttribute( ACCESS, this.getAccess() ) );
 585  
         result.append( eol );
 586  
 
 587  
         result.append( "      />" );
 588  
         result.append( eol );
 589  
         return result.toString();
 590  
     }
 591  
 
 592  
     public Object clone()
 593  
     {
 594  
         return SerializationUtils.deserialize(SerializationUtils.serialize(this));
 595  
     }
 596  
 }