com.is.jrf
Class AbstractColumnSpec

java.lang.Object
  |
  +--com.is.jrf.AbstractColumnSpec
All Implemented Interfaces:
ColumnSpec, JRFConstants
Direct Known Subclasses:
BigDecimalColumnSpec, BooleanColumnSpec, DoubleColumnSpec, FloatColumnSpec, IntegerColumnSpec, LongColumnSpec, NullableBooleanColumnSpec, ShortColumnSpec, SQLDateColumnSpec, SQLTimeColumnSpec, StringArrayColumnSpec, StringColumnSpec, TimestampColumnSpec

public abstract class AbstractColumnSpec
extends java.lang.Object
implements ColumnSpec

Subclass instances of this abstract class represent columns in the table represented by the domain class. This abstract class is subclassed for different java data types (like Integer, String, Boolean, Timestamp, etc). Adding another data type is as simple as subclassing, reimplementing the constructors, and implementing the formatForSql(anObject,aDatabasePolicy), getColumnClass(), and getColumnValueFrom(aJDBCHelper) methods.

Options that can go together..

  1. The PRIMARY_KEY options should be used by themselves.
  2. The OPTIMISTIC_LOCK option should be used by itself on a TimestampColumnSpec or IntegerColumnSpec only.
  3. The REQUIRED and UNIQUE options can be used together or separately.

Examples:

For an Integer sequenced primary key use something like this: (REQUIRED and UNIQUE are ignored when SEQUENCED_PRIMARY_KEY is present so don't use them)

        new IntegerColumnSpec(
             "PersonId",
             "getPersonId",
             "setPersonId",
             DEFAULT_TO_NULL,
             SEQUENCED_PRIMARY_KEY);
  
For a String natural primary key use something like this: (As opposed to SEQUENCED_PRIMARY_KEY, the REQUIRED and UNIQUE options are implied when NATURAL_PRIMARY_KEY is present so you don't need to specify them)
        new StringColumnSpec(
             "PersonCode",
             "getPersonCode",
             "setPersonCode",
             DEFAULT_TO_NULL,
             NATURAL_PRIMARY_KEY);
  
For a String attribute that is required and unique use something like this:
        new StringColumnSpec(
              "Name",
              "getName",
              "setName",
              DEFAULT_TO_NULL,
              REQUIRED,
              UNIQUE);
  
For an attribute that has a non-null default, use something like this:
        new IntegerColumnSpec(
              "Age",
              "getAge",
              "setAge",
              DEFAULT_TO_ZERO);
  
or any Integer:
        new IntegerColumnSpec(
              "Age",
              "getAge",
              "setAge",
              new Integer(99));
  
For a Timestamp that is used as an optimistic lock, use something like this: (REQUIRED and UNIQUE are ignored when OPTIMISTIC_LOCK is present so don't use them)
        new TimestampColumnSpec(
              "UpdatedOn",
              "getUpdatedOn",
              "setUpdatedOn",
              DEFAULT_TO_NOW,
              OPTIMISTIC_LOCK);
  
Here is an example of an AbstractDomain#buildColumnSpecs() method for a table with a compound primary key. ColumnSpecs in a compound primary key do not need any options (REQUIRED or UNIQUE) specified.
 public List buildColumnSpecs()
     {
     List returnValue = new ArrayList();
     returnValue.add(
         new CompoundPrimaryKeyColumnSpec(
             new IntegerColumnSpec(
                 "Id",
                  "getId",
                 "setId",
                 DEFAULT_TO_NULL),
             new StringColumnSpec(
                 "Code",
                 "getCode",
                 "setCode",
                 DEFAULT_TO_NULL)));
     returnValue.add(
         new StringColumnSpec(
             "Name",
             "getName",
             "setName",
             DEFAULT_TO_NULL,
             REQUIRED,
             UNIQUE));
     return returnValue;
     }
  


Field Summary
protected static java.lang.String EQUALS
           
protected  java.lang.String i_columnName
           
protected  java.lang.Object i_default
           
protected  java.lang.String i_getter
           
protected  boolean i_naturalPrimaryKey
           
protected  boolean i_optimisticLock
           
protected  boolean i_required
           
protected  boolean i_sequencedPrimaryKey
           
protected  java.lang.String i_setter
           
protected  boolean i_subtypeIdentifier
           
protected  boolean i_unique
           
protected static java.lang.String NOT_EQUALS
           
 
Fields inherited from interface com.is.jrf.JRFConstants
CURRENT_DATE, CURRENT_TIMESTAMP, DEFAULT_TO_EMPTY_STRING, DEFAULT_TO_FALSE, DEFAULT_TO_NOW, DEFAULT_TO_NULL, DEFAULT_TO_ONE, DEFAULT_TO_TODAY, DEFAULT_TO_TRUE, DEFAULT_TO_ZERO, NATURAL_PRIMARY_KEY, NO_POST_FIND, OPTIMISTIC_LOCK, REQUIRED, SEQUENCED_PRIMARY_KEY, SUBTYPE_IDENTIFIER, UNIQUE
 
Constructor Summary
AbstractColumnSpec(java.lang.String columnName, java.lang.String getter, java.lang.String setter, java.lang.Object defaultValue)
           
AbstractColumnSpec(java.lang.String columnName, java.lang.String getter, java.lang.String setter, java.lang.Object defaultValue, int option1)
           
AbstractColumnSpec(java.lang.String columnName, java.lang.String getter, java.lang.String setter, java.lang.Object defaultValue, int option1, int option2)
           
AbstractColumnSpec(java.lang.String columnName, java.lang.String getter, java.lang.String setter, java.lang.Object defaultValue, int option1, int option2, int option3)
           
 
Method Summary
abstract  JoinColumn buildJoinColumn()
           
 java.lang.String buildNameValuePair(java.lang.Object pkOrPersistentObject, java.lang.String separator, java.lang.String tableAlias, DatabasePolicy dbPolicy)
          This method is used to build an equals (or not-equals) String for WHERE clauses and UPDATE statements.
 java.lang.String buildWhereClause(java.lang.Object pkOrPersistentObject, java.lang.String separator, java.lang.String tableAlias, DatabasePolicy dbPolicy)
          Note: This method is overridden by CompoundPrimaryKeyColumnSpec to include " AND " between each name-value pair.
 java.lang.String columnDefinitionString(DatabasePolicy dbPolicy)
          Return something like: "Age INTEGER NOT NULL"
 void copyAttribute(PersistentObject aPO1, PersistentObject aPO2)
          Copy the attribute I represent from one persistent object to another.
 void copyColumnValueToPersistentObject(JDBCHelper helper, PersistentObject aPO)
          Copy the value of my column to the appropriate attribute for this persistent object.
protected abstract  java.lang.Object decode(java.lang.String aString)
          See IntegerColumnSpec for example of how to implement:
 void decodeToPersistentObject(java.lang.String aString, PersistentObject aPO)
          This method is similar in concept to the copyColumnValueToPersistentObject(...) method, but gets it's value from a String instead of a JDBCHelper.
 java.lang.String encode(java.lang.Object obj)
          "Encode" the given object into a string representation that can be decoded later.
 java.lang.String encodeFromPersistentObject(PersistentObject aPO)
          Convert the attribute for this object to a String that can be unconverted later by the decodeToPersistentObject(...) method.
abstract  java.lang.String formatForSql(java.lang.Object obj, DatabasePolicy dbPolicy)
          Returns a string representing the given attribute value.
abstract  java.lang.Class getColumnClass()
          See IntegerColumnSpec for example of how to implement:
 java.lang.String getColumnName()
           
abstract  java.lang.Object getColumnValueFrom(JDBCHelper helper)
          See IntegerColumnSpec for example of how to implement:
 java.lang.Object getDefault()
           
 java.lang.String getFullyQualifiedColumnName(java.lang.String tableAlias)
           
 java.lang.String getGetter()
           
 java.lang.String getSetter()
           
abstract  java.lang.String getSQLColumnType(DatabasePolicy dbPolicy)
          Return the type of column to be used in a CREATE TABLE or ALTER TABLE statement.
 java.lang.String getSqlValueFrom(PersistentObject aPO, DatabasePolicy dbPolicy)
          Get a string representation of the value of this attribute from aPO.
 java.lang.Object getValueFrom(PersistentObject aPO)
          Get the value of this attribute from aPO.
static java.lang.Object getValueFrom(PersistentObject aPO, java.lang.String getter, java.lang.Object defaultValue)
          Get the value of this attribute from aPO.
 boolean isNaturalPrimaryKey()
           
 boolean isOptimisticLock()
           
 boolean isPrimaryKey()
           
 boolean isRequired()
           
 boolean isSequencedPrimaryKey()
           
 boolean isSubtypeIdentifier()
           
 boolean isUnique()
           
 java.lang.Object optimisticLockDefaultValue()
          Unless this is overridden, an exception will be thrown.
 void setRequired(boolean b)
          CompoundPrimaryKeyColumnSpec uses this to force it's children to "REQUIRED".
 void setValueTo(java.lang.Object aValue, PersistentObject aPO)
          This is a pass-through method that passes along my setter and column class.
static void setValueTo(java.lang.Object aValue, PersistentObject aPO, java.lang.String setter, java.lang.Class valueClass)
          Sets the attribute value of a given persistent object using reflection.
 java.lang.Object validateRequired(PersistentObject aPO)
          Make sure the PersistentObject object has this attribute (if required).
static void validateUnique(PersistentObject aPO, JDBCHelper helper, ColumnSpec pkColumnSpec, ColumnSpec attrColumnSpec, DatabasePolicy dbPolicy, java.lang.String tableName)
          If Column is declared UNIQUE, make sure it doesn't already exist in the table.
 void validateUnique(PersistentObject aPO, JDBCHelper helper, ColumnSpec pkColumnSpec, DatabasePolicy dbPolicy, java.lang.String tableName)
          If this is a unique column (or columns), make sure the value doesn't already exist.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

EQUALS

protected static final java.lang.String EQUALS

NOT_EQUALS

protected static final java.lang.String NOT_EQUALS

i_columnName

protected java.lang.String i_columnName

i_getter

protected java.lang.String i_getter

i_setter

protected java.lang.String i_setter

i_default

protected java.lang.Object i_default

i_required

protected boolean i_required

i_sequencedPrimaryKey

protected boolean i_sequencedPrimaryKey

i_naturalPrimaryKey

protected boolean i_naturalPrimaryKey

i_unique

protected boolean i_unique

i_subtypeIdentifier

protected boolean i_subtypeIdentifier

i_optimisticLock

protected boolean i_optimisticLock
Constructor Detail

AbstractColumnSpec

public AbstractColumnSpec(java.lang.String columnName,
                          java.lang.String getter,
                          java.lang.String setter,
                          java.lang.Object defaultValue,
                          int option1,
                          int option2,
                          int option3)

AbstractColumnSpec

public AbstractColumnSpec(java.lang.String columnName,
                          java.lang.String getter,
                          java.lang.String setter,
                          java.lang.Object defaultValue)

AbstractColumnSpec

public AbstractColumnSpec(java.lang.String columnName,
                          java.lang.String getter,
                          java.lang.String setter,
                          java.lang.Object defaultValue,
                          int option1)

AbstractColumnSpec

public AbstractColumnSpec(java.lang.String columnName,
                          java.lang.String getter,
                          java.lang.String setter,
                          java.lang.Object defaultValue,
                          int option1,
                          int option2)
Method Detail

formatForSql

public abstract java.lang.String formatForSql(java.lang.Object obj,
                                              DatabasePolicy dbPolicy)
Returns a string representing the given attribute value. The string will be used in an SQL expression.
Specified by:
formatForSql in interface ColumnSpec
Parameters:
obj - a value of type 'Object'
Returns:
a value of type 'String'

getColumnClass

public abstract java.lang.Class getColumnClass()
See IntegerColumnSpec for example of how to implement:
Specified by:
getColumnClass in interface ColumnSpec

getColumnValueFrom

public abstract java.lang.Object getColumnValueFrom(JDBCHelper helper)
                                             throws java.sql.SQLException
See IntegerColumnSpec for example of how to implement:
Specified by:
getColumnValueFrom in interface ColumnSpec

decode

protected abstract java.lang.Object decode(java.lang.String aString)
See IntegerColumnSpec for example of how to implement:

getSQLColumnType

public abstract java.lang.String getSQLColumnType(DatabasePolicy dbPolicy)
Return the type of column to be used in a CREATE TABLE or ALTER TABLE statement.
Parameters:
dbPolicy - a value of type 'DatabasePolicy'
Returns:
a value of type 'String'

setValueTo

public static void setValueTo(java.lang.Object aValue,
                              PersistentObject aPO,
                              java.lang.String setter,
                              java.lang.Class valueClass)
Sets the attribute value of a given persistent object using reflection. This is static so it can be used by the JoinColumn subclasses.
Parameters:
aValue - a value of type 'Object'
aPO - a value of type 'PersistentObject'
setter - a value of type 'String'
valueClass - a value of type 'Class'

getValueFrom

public static java.lang.Object getValueFrom(PersistentObject aPO,
                                            java.lang.String getter,
                                            java.lang.Object defaultValue)
Get the value of this attribute from aPO. If the value is null, the default will be returned. This could be done in the persistent object when the variable is initialized, but the developer might forget to do that. More importantly, an attribute read from the database might be null which would override the variable initialization. When the save is executed, this assures that the new default value will be put into the database.

Note: The getter can be of the form: "getCustomer.getId"

Parameters:
aPO - a value of type 'PersistentObject'
getter - a value of type 'String' - can be of the form: "getCustomer.getId"
defaultValue - a value of type 'Object'
Returns:
a value of type 'Object'

validateUnique

public static void validateUnique(PersistentObject aPO,
                                  JDBCHelper helper,
                                  ColumnSpec pkColumnSpec,
                                  ColumnSpec attrColumnSpec,
                                  DatabasePolicy dbPolicy,
                                  java.lang.String tableName)
                           throws DuplicateRowException
If Column is declared UNIQUE, make sure it doesn't already exist in the table. This is static so that the CompoundPrimaryKeyColumnSpec can use it too.
Parameters:
aPO - a value of type 'PersistentObject'
helper - a value of type 'JDBCHelper'
pkColumnSpec - a value of type 'ColumnSpec'
Throws:
DuplicateRowException - if a row with this value already exists.

encode

public java.lang.String encode(java.lang.Object obj)
"Encode" the given object into a string representation that can be decoded later. This implementation is pretty basic. This method will *not* be used for generating SQL.
Parameters:
obj - a value of type 'Object'
Returns:
a value of type 'String'

decodeToPersistentObject

public void decodeToPersistentObject(java.lang.String aString,
                                     PersistentObject aPO)
This method is similar in concept to the copyColumnValueToPersistentObject(...) method, but gets it's value from a String instead of a JDBCHelper. The String parameter must have been encoded with the encodeFromPersistentObject() method.
Specified by:
decodeToPersistentObject in interface ColumnSpec
Parameters:
aString - a value of type 'String'
aPO - a value of type 'PersistentObject'
See Also:
encodeFromPersistentObject(com.is.jrf.PersistentObject)

encodeFromPersistentObject

public java.lang.String encodeFromPersistentObject(PersistentObject aPO)
Convert the attribute for this object to a String that can be unconverted later by the decodeToPersistentObject(...) method. The results of this method are not to be used in SQL.
Specified by:
encodeFromPersistentObject in interface ColumnSpec
Parameters:
aPO - a value of type 'PersistentObject'
Returns:
a value of type 'String'
See Also:
decodeToPersistentObject(java.lang.String, com.is.jrf.PersistentObject)

copyColumnValueToPersistentObject

public void copyColumnValueToPersistentObject(JDBCHelper helper,
                                              PersistentObject aPO)
                                       throws java.sql.SQLException
Copy the value of my column to the appropriate attribute for this persistent object.
Specified by:
copyColumnValueToPersistentObject in interface ColumnSpec
Parameters:
helper - a value of type 'JDBCHelper'
aPO - a value of type 'PersistentObject'
Throws:
java.sql.SQLException - if an error occurs

copyAttribute

public void copyAttribute(PersistentObject aPO1,
                          PersistentObject aPO2)
Copy the attribute I represent from one persistent object to another.
Specified by:
copyAttribute in interface ColumnSpec
Parameters:
aPO1 - a value of type 'PersistentObject'
aPO2 - a value of type 'PersistentObject'

buildWhereClause

public java.lang.String buildWhereClause(java.lang.Object pkOrPersistentObject,
                                         java.lang.String separator,
                                         java.lang.String tableAlias,
                                         DatabasePolicy dbPolicy)
Note: This method is overridden by CompoundPrimaryKeyColumnSpec to include " AND " between each name-value pair.
Specified by:
buildWhereClause in interface ColumnSpec
Parameters:
pkOrPersistentObject - a value of type 'Object'
dbPolicy - a value of type 'DatabasePolicy'
Returns:
a value of type 'String'

buildNameValuePair

public java.lang.String buildNameValuePair(java.lang.Object pkOrPersistentObject,
                                           java.lang.String separator,
                                           java.lang.String tableAlias,
                                           DatabasePolicy dbPolicy)
This method is used to build an equals (or not-equals) String for WHERE clauses and UPDATE statements.
Specified by:
buildNameValuePair in interface ColumnSpec
Parameters:
pkOrPersistentObject - a value of type 'Object'
separator - a value of type 'String' - use EQUALS or NOT_EQUALS static final variables.
tableName - a value of type 'String'
dbPolicy - a value of type 'DatabasePolicy'
Returns:
a value of type 'String'

validateRequired

public java.lang.Object validateRequired(PersistentObject aPO)
                                  throws MissingAttributeException
Make sure the PersistentObject object has this attribute (if required).
Specified by:
validateRequired in interface ColumnSpec
Parameters:
aPO - a value of type 'PersistentObject'
Returns:
a value of type 'Object' - This is the value of the attribute. This is so subclasses can call super.validateRequired().
Throws:
MissingAttributeException - if attribute should be populated and it is not.

validateUnique

public void validateUnique(PersistentObject aPO,
                           JDBCHelper helper,
                           ColumnSpec pkColumnSpec,
                           DatabasePolicy dbPolicy,
                           java.lang.String tableName)
                    throws DuplicateRowException
If this is a unique column (or columns), make sure the value doesn't already exist.
Specified by:
validateUnique in interface ColumnSpec
Parameters:
aPO - a value of type 'PersistentObject'
helper - a value of type 'JDBCHelper'
pkColumnSpec - a value of type 'ColumnSpec'
dbPolicy - a value of type 'DatabasePolicy'
tableName - a value of type 'String'
Throws:
DuplicateRowException - if an error occurs

getSqlValueFrom

public java.lang.String getSqlValueFrom(PersistentObject aPO,
                                        DatabasePolicy dbPolicy)
Get a string representation of the value of this attribute from aPO. This string can be inserted into a SQL statement.
Specified by:
getSqlValueFrom in interface ColumnSpec
Parameters:
aPO - a value of type 'PersistentObject'
Returns:
a value of type 'String'

getValueFrom

public java.lang.Object getValueFrom(PersistentObject aPO)
Get the value of this attribute from aPO. If the value is null, the default value will be returned.
Specified by:
getValueFrom in interface ColumnSpec
Parameters:
aPO - a value of type 'PersistentObject'
Returns:
a value of type 'Object'

setValueTo

public void setValueTo(java.lang.Object aValue,
                       PersistentObject aPO)
This is a pass-through method that passes along my setter and column class.
Specified by:
setValueTo in interface ColumnSpec
Parameters:
aValue - a value of type 'Object'
aPO - a value of type 'PersistentObject'

columnDefinitionString

public java.lang.String columnDefinitionString(DatabasePolicy dbPolicy)
Return something like: "Age INTEGER NOT NULL"
Specified by:
columnDefinitionString in interface ColumnSpec
Returns:
a value of type 'String'

getFullyQualifiedColumnName

public java.lang.String getFullyQualifiedColumnName(java.lang.String tableAlias)
Specified by:
getFullyQualifiedColumnName in interface ColumnSpec

getColumnName

public java.lang.String getColumnName()
Specified by:
getColumnName in interface ColumnSpec

getGetter

public java.lang.String getGetter()
Specified by:
getGetter in interface ColumnSpec

getSetter

public java.lang.String getSetter()
Specified by:
getSetter in interface ColumnSpec

isRequired

public boolean isRequired()
Specified by:
isRequired in interface ColumnSpec

isSequencedPrimaryKey

public boolean isSequencedPrimaryKey()
Specified by:
isSequencedPrimaryKey in interface ColumnSpec

isNaturalPrimaryKey

public boolean isNaturalPrimaryKey()
Specified by:
isNaturalPrimaryKey in interface ColumnSpec

isPrimaryKey

public boolean isPrimaryKey()
Specified by:
isPrimaryKey in interface ColumnSpec

isUnique

public boolean isUnique()
Specified by:
isUnique in interface ColumnSpec

isSubtypeIdentifier

public boolean isSubtypeIdentifier()
Specified by:
isSubtypeIdentifier in interface ColumnSpec

getDefault

public java.lang.Object getDefault()
Specified by:
getDefault in interface ColumnSpec

isOptimisticLock

public boolean isOptimisticLock()
Specified by:
isOptimisticLock in interface ColumnSpec

setRequired

public void setRequired(boolean b)
CompoundPrimaryKeyColumnSpec uses this to force it's children to "REQUIRED".
Specified by:
setRequired in interface ColumnSpec

optimisticLockDefaultValue

public java.lang.Object optimisticLockDefaultValue()
Unless this is overridden, an exception will be thrown.
Returns:
a value of type 'Object'

buildJoinColumn

public abstract JoinColumn buildJoinColumn()
Returns:
a JoinColumn subclass instance with data from myself.