You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2017/07/28 12:50:02 UTC

empire-db git commit: EMPIREDB-257 extend collection type for setBeanProperties function

Repository: empire-db
Updated Branches:
  refs/heads/master f56a2dc5c -> ee8a32069


EMPIREDB-257
extend collection type for setBeanProperties function

Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo
Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/ee8a3206
Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/ee8a3206
Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/ee8a3206

Branch: refs/heads/master
Commit: ee8a32069647273c10abbf6112caf7a1b1a4942f
Parents: f56a2dc
Author: Rainer Döbele <do...@apache.org>
Authored: Fri Jul 28 14:49:57 2017 +0200
Committer: Rainer Döbele <do...@apache.org>
Committed: Fri Jul 28 14:49:57 2017 +0200

----------------------------------------------------------------------
 .../java/org/apache/empire/data/RecordData.java | 224 ++---
 .../empire/data/bean/BeanRecordProxy.java       | 880 +++++++++----------
 .../java/org/apache/empire/db/DBRecordData.java | 794 ++++++++---------
 3 files changed, 949 insertions(+), 949 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/empire-db/blob/ee8a3206/empire-db/src/main/java/org/apache/empire/data/RecordData.java
----------------------------------------------------------------------
diff --git a/empire-db/src/main/java/org/apache/empire/data/RecordData.java b/empire-db/src/main/java/org/apache/empire/data/RecordData.java
index 19da930..0fd9acf 100644
--- a/empire-db/src/main/java/org/apache/empire/data/RecordData.java
+++ b/empire-db/src/main/java/org/apache/empire/data/RecordData.java
@@ -1,112 +1,112 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.empire.data;
-
-import java.util.Collection;
-
-/**
- * The RecordData interface provides methods for accessing data and context specific metadata.
- * <P>
- * The Record interface is implemented by the classes {@link org.apache.empire.db.DBReader}
- * and {@link org.apache.empire.db.DBRecord}.
- * <P>
- */
-public interface RecordData
-{
-    /**
-     * returns the number of field available
-     * @return field count
-     */
-    int getFieldCount();
-
-    /**
-     * returns the index of the given column expression
-     * Indexed operations provide better performance for bulk processing  
-     * @param column the column for which to return the index
-     * @return the field index of the given column
-     */
-    int getFieldIndex(ColumnExpr column);
-    
-    /**
-     * returns the index of the column expression with the given name
-     * @param column the name of the column for which to return the index
-     * @return the field index of the given column
-     */
-    int getFieldIndex(String column);
-    
-    /**
-     * returns the column expression for a given column
-     * This is the reverse operation of getFieldIndex()
-     * @param i field index of the column expression
-     * @return the column expression object or null if the index is out of range
-     */
-    ColumnExpr getColumnExpr(int i);
-
-    /**
-     * returns the value of the field at the given index position 
-     * Indexed operations provide better performance for bulk processing compared to getValue(ColumnExpr)  
-     * @param index the field index for which to return the value
-     * @return the record value for the given field
-     */
-    Object getValue(int index);
-    
-    /**
-     * returns the record value for a particular column 
-     * @param column the column for which to return the value
-     * @return the record value for the given column
-     */
-    Object getValue(ColumnExpr column);
-    
-    /**
-     * checks if the field at the given index position contains no value (null) 
-     * Indexed operations provide better performance for bulk processing compared to isNull(ColumnExpr)  
-     * @param index the field index
-     * @return true if the field value is null or false otherwise
-     */
-    boolean isNull(int index);
-
-    /**
-     * checks if the record contains no value (null) for the given column  
-     * @param column the column
-     * @return true if the value for the column is null or false otherwise
-     */
-    boolean isNull(ColumnExpr column);
-
-    // ------- Java Bean Support -------
-
-    /**
-     * copies all field values into a static Java Bean.
-     * <P>
-     * In order to map column names to property names 
-     * the property name is detected by ColumnExpr.getBeanPropertyName()     
-     * @param bean the Java Bean for which to set the properties
-     * @param ignoreList list of columns to skip (optional)
-     */
-    int setBeanProperties(Object bean, Collection<ColumnExpr> ignoreList);
-
-    /**
-     * copies all field values into a static Java Bean.
-     * <P>
-     * In order to map column names to property names 
-     * the property name is detected by ColumnExpr.getBeanPropertyName()     
-     * @param bean the Java Bean for which to set the properties
-     */
-    int setBeanProperties(Object bean);
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.data;
+
+import java.util.Collection;
+
+/**
+ * The RecordData interface provides methods for accessing data and context specific metadata.
+ * <P>
+ * The Record interface is implemented by the classes {@link org.apache.empire.db.DBReader}
+ * and {@link org.apache.empire.db.DBRecord}.
+ * <P>
+ */
+public interface RecordData
+{
+    /**
+     * returns the number of field available
+     * @return field count
+     */
+    int getFieldCount();
+
+    /**
+     * returns the index of the given column expression
+     * Indexed operations provide better performance for bulk processing  
+     * @param column the column for which to return the index
+     * @return the field index of the given column
+     */
+    int getFieldIndex(ColumnExpr column);
+    
+    /**
+     * returns the index of the column expression with the given name
+     * @param column the name of the column for which to return the index
+     * @return the field index of the given column
+     */
+    int getFieldIndex(String column);
+    
+    /**
+     * returns the column expression for a given column
+     * This is the reverse operation of getFieldIndex()
+     * @param i field index of the column expression
+     * @return the column expression object or null if the index is out of range
+     */
+    ColumnExpr getColumnExpr(int i);
+
+    /**
+     * returns the value of the field at the given index position 
+     * Indexed operations provide better performance for bulk processing compared to getValue(ColumnExpr)  
+     * @param index the field index for which to return the value
+     * @return the record value for the given field
+     */
+    Object getValue(int index);
+    
+    /**
+     * returns the record value for a particular column 
+     * @param column the column for which to return the value
+     * @return the record value for the given column
+     */
+    Object getValue(ColumnExpr column);
+    
+    /**
+     * checks if the field at the given index position contains no value (null) 
+     * Indexed operations provide better performance for bulk processing compared to isNull(ColumnExpr)  
+     * @param index the field index
+     * @return true if the field value is null or false otherwise
+     */
+    boolean isNull(int index);
+
+    /**
+     * checks if the record contains no value (null) for the given column  
+     * @param column the column
+     * @return true if the value for the column is null or false otherwise
+     */
+    boolean isNull(ColumnExpr column);
+
+    // ------- Java Bean Support -------
+
+    /**
+     * copies all field values into a static Java Bean.
+     * <P>
+     * In order to map column names to property names 
+     * the property name is detected by ColumnExpr.getBeanPropertyName()     
+     * @param bean the Java Bean for which to set the properties
+     * @param ignoreList list of columns to skip (optional)
+     */
+    int setBeanProperties(Object bean, Collection<? extends ColumnExpr> ignoreList);
+
+    /**
+     * copies all field values into a static Java Bean.
+     * <P>
+     * In order to map column names to property names 
+     * the property name is detected by ColumnExpr.getBeanPropertyName()     
+     * @param bean the Java Bean for which to set the properties
+     */
+    int setBeanProperties(Object bean);
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/ee8a3206/empire-db/src/main/java/org/apache/empire/data/bean/BeanRecordProxy.java
----------------------------------------------------------------------
diff --git a/empire-db/src/main/java/org/apache/empire/data/bean/BeanRecordProxy.java b/empire-db/src/main/java/org/apache/empire/data/bean/BeanRecordProxy.java
index f481f68..b301a6c 100644
--- a/empire-db/src/main/java/org/apache/empire/data/bean/BeanRecordProxy.java
+++ b/empire-db/src/main/java/org/apache/empire/data/bean/BeanRecordProxy.java
@@ -1,440 +1,440 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.empire.data.bean;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.beanutils.BeanUtils;
-import org.apache.commons.beanutils.BeanUtilsBean;
-import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.commons.beanutils.PropertyUtilsBean;
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.Options;
-import org.apache.empire.data.Column;
-import org.apache.empire.data.ColumnExpr;
-import org.apache.empire.data.Record;
-import org.apache.empire.exceptions.BeanPropertyGetException;
-import org.apache.empire.exceptions.BeanPropertySetException;
-import org.apache.empire.exceptions.InvalidArgumentException;
-import org.apache.empire.exceptions.ItemNotFoundException;
-import org.apache.empire.exceptions.ObjectNotValidException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * BeanRecordProxy
- * This class defines proxy that allows any POJO to behave like a record object.
- *  
- * @param <T> the type of the class proxied by this {@code BeanRecordProxy}
- * 
- * @author Rainer
- */
-public class BeanRecordProxy<T> implements Record
-{
-    protected static final Logger log = LoggerFactory.getLogger(BeanRecordProxy.class);
-    
-    protected List<Column> columns;
-    protected Column[] keyColumns;
-    protected boolean[] modified;
-
-    protected T data;
-
-    public BeanRecordProxy(T data, List<Column> columns, Column[] keyColumns)
-    {
-        this.data = data;
-        this.columns = columns;
-        this.keyColumns = keyColumns;
-    }
-
-    public BeanRecordProxy(List<Column> columns, Column[] keyColumns)
-    {
-        this(null, columns, keyColumns);
-    }
-
-    public BeanRecordProxy(T data, BeanClass beanClass)
-    {
-        this(data, 
-             ObjectUtils.convert(Column.class, beanClass.getProperties()), 
-             beanClass.getKeyColumns());
-    }
-
-    public BeanRecordProxy(BeanClass beanClass)
-    {
-        this(null, 
-             ObjectUtils.convert(Column.class, beanClass.getProperties()), 
-             beanClass.getKeyColumns());
-    }
-    
-    public T getBean()
-    {
-        return data;
-    }
-
-    public void setBean(T data)
-    {
-        this.data = data;
-    }
-
-    @Override
-    public Column getColumn(int index)
-    {
-        return columns.get(index);
-    }
-
-    @Override
-    public ColumnExpr getColumnExpr(int index)
-    {
-        return columns.get(index);
-    }
-
-    @Override
-    public Column[] getKeyColumns()
-    {
-        return keyColumns;
-    }
-
-    /**
-     * Returns the array of primary key columns.
-     * @return the array of primary key columns
-     */
-    public Object[] getKeyValues()
-    {
-        if (keyColumns==null)
-            return null;
-        // Get key values
-        Object[] key = new Object[keyColumns.length];
-        for (int i=0; i<keyColumns.length; i++)
-            key[i] = this.getValue(keyColumns[i]);
-        // the key
-        return key;
-    }
-
-    @Override
-    public int getFieldCount()
-    {
-        return columns.size();
-    }
-
-    @Override
-    public int getFieldIndex(ColumnExpr column)
-    {
-        for (int i=0; i<columns.size(); i++)
-        {
-            if (columns.get(i).equals(column))
-                return i;
-        }
-        return -1;
-    }
-
-    @Override
-    public int getFieldIndex(String columnName)
-    {
-        for (int i=0; i<columns.size(); i++)
-        {
-            if (columns.get(i).getName().equals(columnName))
-                return i;
-        }
-        return -1;
-    }
-
-    @Override
-    public Options getFieldOptions(Column column)
-    {
-        return column.getOptions();
-    }
-
-    @Override
-    public boolean isFieldVisible(Column column)
-    {
-        return true;
-    }
-
-    @Override
-    public boolean isFieldReadOnly(Column column)
-    {
-    	if (isNew()==false && ObjectUtils.contains(keyColumns, column))
-    		return true;
-    	if (column.isAutoGenerated())
-    		return true;
-        return column.isReadOnly();
-    }
-
-    @Override
-    public boolean isFieldRequired(Column column)
-    {
-        return column.isRequired();
-    }
-
-    @Override
-    public boolean isModified()
-    {
-        return (modified!=null);
-    }
-
-    @Override
-    public boolean isNew()
-    {
-        if (!isValid())
-            throw new ObjectNotValidException(this);
-        // Record is new until all key fields have been supplied
-        if (keyColumns!=null)
-        {   // Check all Key Columns
-            for (int i=0; i<keyColumns.length; i++)
-            {
-                Object value = getValue(keyColumns[i]);
-                if ((value instanceof Number) && ((Number)value).longValue()==0)
-                    return true;
-                if (ObjectUtils.isEmpty(value))
-                    return true;
-            }
-        }
-        // Not new
-        return false;
-    }
-
-    @Override
-    public boolean isValid()
-    {
-        return (data!=null);
-    }
-
-    @Override
-    public boolean isReadOnly()
-    {
-        return (isValid() ? false : true);
-    }
-
-    @Override
-    public Object getValue(ColumnExpr column)
-    {
-        if (!isValid())
-            throw new ObjectNotValidException(this);
-        // getBeanPropertyValue 
-        return getBeanPropertyValue(data, column);
-    }
-
-    @Override
-    public Object getValue(int index)
-    {
-        return getValue(getColumn(index));
-    }
-
-    @Override
-    public boolean isNull(ColumnExpr column)
-    {
-        return ObjectUtils.isEmpty(getValue(column));
-    }
-
-    @Override
-    public boolean isNull(int index)
-    {
-        return isNull(getColumn(index));
-    }
-
-    /**
-     * Validates a value before it is set in the record.
-     */
-    @Override
-    public Object validateValue(Column column, Object value)
-    {
-        return column.validate(value);
-    }
-
-    /**
-     * sets the value of a field.
-     */
-    @Override
-    public void setValue(Column column, Object value)
-    {
-        if (!isValid())
-            throw new ObjectNotValidException(this);
-        // Track modification status
-        if (ObjectUtils.compareEqual(getValue(column), value)==false)
-        {
-            if (modified== null)
-                modified = new boolean[columns.size()]; 
-            modified[getFieldIndex(column)] = true;
-        }
-        // validate
-        value = validateValue(column, value);
-        // Set Value
-        setBeanPropertyValue(data, column, value);
-    }
-
-    /**
-     * sets the value of a field.
-     */
-    @Override
-    public final void setValue(int i, Object value)
-    {
-        setValue(getColumn(i), value);
-    }
-
-    /**
-     * Detects whether or not a particular field has been modified.
-     */
-    @Override
-    public boolean wasModified(Column column)
-    {
-        int index = getFieldIndex(column);
-        if (index<0)
-            throw new ItemNotFoundException(column.getName());
-        // check modified
-        return (modified!=null && modified[index]);
-    }
-
-    /**
-     * clears the modification status of the object and all fields.
-     */
-    public void clearModified()
-    {
-        modified = null;
-    }
-
-    // --------------- Bean support ------------------
-
-    @Override
-    public int setBeanProperties(Object bean)
-    {
-        return setBeanProperties(bean, null);
-    }
-
-    @Override
-    public int setBeanProperties(Object bean, Collection<ColumnExpr> ignoreList)
-    {
-        // Add all Columns
-        int count = 0;
-        for (int i = 0; i < getFieldCount(); i++)
-        { // Check Property
-            Column column = getColumn(i);
-            if (column.isReadOnly())
-                continue;
-            if (ignoreList != null && ignoreList.contains(column))
-                continue; // ignore this property
-            // Get Property Name
-            setBeanPropertyValue(bean, column, getValue(i));
-        }
-        return count;
-    }
-
-    @Override
-    public int setRecordValues(Object bean, Collection<Column> ignoreList)
-    {
-        // Add all Columns
-        int count = 0;
-        for (int i = 0; i < getFieldCount(); i++)
-        { // Check Property
-            Column column = getColumn(i);
-            if (column.isReadOnly())
-                continue;
-            if (ignoreList != null && ignoreList.contains(column))
-                continue; // ignore this property
-            // Get Property Name
-            String property = column.getBeanPropertyName();
-            Object value = getBeanPropertyValue(bean, property);
-            setValue(column, value);
-            count++;
-        }
-        return count;
-    }
-    
-    @Override
-    public int setRecordValues(Object bean)
-    {
-        return setRecordValues(bean, null);
-    }
-
-    // --------------- protected ------------------
-
-    protected Object getBeanPropertyValue(Object bean, ColumnExpr column)
-    {
-        // Check Params
-        if (bean==null)
-            throw new InvalidArgumentException("bean", bean);
-        if (column==null)
-            throw new InvalidArgumentException("column", column);
-        // getBeanPropertyValue 
-        return getBeanPropertyValue(bean, column.getBeanPropertyName()); 
-    }
-
-    protected Object getBeanPropertyValue(Object bean, String property)
-    {
-        // Check Params
-        if (bean==null)
-            throw new InvalidArgumentException("bean", bean);
-        if (property==null)
-            throw new InvalidArgumentException("property", property);
-        try
-        {   // Get Property Value
-            PropertyUtilsBean pub = BeanUtilsBean.getInstance().getPropertyUtils();
-            return pub.getSimpleProperty(bean, property);
-
-        } catch (IllegalAccessException e)
-        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
-            throw new BeanPropertyGetException(bean, property, e);
-        } catch (InvocationTargetException e)
-        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
-            throw new BeanPropertyGetException(bean, property, e);
-        } catch (NoSuchMethodException e)
-        {   log.warn(bean.getClass().getName() + ": no getter available for property '" + property + "'");
-            throw new BeanPropertyGetException(bean, property, e);
-        }
-    }
-
-    protected void setBeanPropertyValue(Object bean, Column column, Object value)
-    {
-        // Check Params
-        if (bean==null)
-            throw new InvalidArgumentException("bean", bean);
-        if (column==null)
-            throw new InvalidArgumentException("column", column);
-        // Get Property Name
-        String property = column.getBeanPropertyName(); 
-        try
-        {   // Get Property Value
-            if (ObjectUtils.isEmpty(value))
-                value = null;
-            // Set Property Value
-            if (value!=null)
-            {   // Bean utils will convert if necessary
-                BeanUtils.setProperty(bean, property, value);
-            }
-            else
-            {   // Don't convert, just set
-                PropertyUtils.setProperty(bean, property, null);
-            }
-        } catch (IllegalArgumentException e) {
-            log.error(bean.getClass().getName() + ": invalid argument for property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        } catch (IllegalAccessException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        } catch (InvocationTargetException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        } catch (NoSuchMethodException e) {
-            log.error(bean.getClass().getName() + ": no setter available for property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        }    
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.data.bean;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.beanutils.PropertyUtilsBean;
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.Options;
+import org.apache.empire.data.Column;
+import org.apache.empire.data.ColumnExpr;
+import org.apache.empire.data.Record;
+import org.apache.empire.exceptions.BeanPropertyGetException;
+import org.apache.empire.exceptions.BeanPropertySetException;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+import org.apache.empire.exceptions.ObjectNotValidException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * BeanRecordProxy
+ * This class defines proxy that allows any POJO to behave like a record object.
+ *  
+ * @param <T> the type of the class proxied by this {@code BeanRecordProxy}
+ * 
+ * @author Rainer
+ */
+public class BeanRecordProxy<T> implements Record
+{
+    protected static final Logger log = LoggerFactory.getLogger(BeanRecordProxy.class);
+    
+    protected List<Column> columns;
+    protected Column[] keyColumns;
+    protected boolean[] modified;
+
+    protected T data;
+
+    public BeanRecordProxy(T data, List<Column> columns, Column[] keyColumns)
+    {
+        this.data = data;
+        this.columns = columns;
+        this.keyColumns = keyColumns;
+    }
+
+    public BeanRecordProxy(List<Column> columns, Column[] keyColumns)
+    {
+        this(null, columns, keyColumns);
+    }
+
+    public BeanRecordProxy(T data, BeanClass beanClass)
+    {
+        this(data, 
+             ObjectUtils.convert(Column.class, beanClass.getProperties()), 
+             beanClass.getKeyColumns());
+    }
+
+    public BeanRecordProxy(BeanClass beanClass)
+    {
+        this(null, 
+             ObjectUtils.convert(Column.class, beanClass.getProperties()), 
+             beanClass.getKeyColumns());
+    }
+    
+    public T getBean()
+    {
+        return data;
+    }
+
+    public void setBean(T data)
+    {
+        this.data = data;
+    }
+
+    @Override
+    public Column getColumn(int index)
+    {
+        return columns.get(index);
+    }
+
+    @Override
+    public ColumnExpr getColumnExpr(int index)
+    {
+        return columns.get(index);
+    }
+
+    @Override
+    public Column[] getKeyColumns()
+    {
+        return keyColumns;
+    }
+
+    /**
+     * Returns the array of primary key columns.
+     * @return the array of primary key columns
+     */
+    public Object[] getKeyValues()
+    {
+        if (keyColumns==null)
+            return null;
+        // Get key values
+        Object[] key = new Object[keyColumns.length];
+        for (int i=0; i<keyColumns.length; i++)
+            key[i] = this.getValue(keyColumns[i]);
+        // the key
+        return key;
+    }
+
+    @Override
+    public int getFieldCount()
+    {
+        return columns.size();
+    }
+
+    @Override
+    public int getFieldIndex(ColumnExpr column)
+    {
+        for (int i=0; i<columns.size(); i++)
+        {
+            if (columns.get(i).equals(column))
+                return i;
+        }
+        return -1;
+    }
+
+    @Override
+    public int getFieldIndex(String columnName)
+    {
+        for (int i=0; i<columns.size(); i++)
+        {
+            if (columns.get(i).getName().equals(columnName))
+                return i;
+        }
+        return -1;
+    }
+
+    @Override
+    public Options getFieldOptions(Column column)
+    {
+        return column.getOptions();
+    }
+
+    @Override
+    public boolean isFieldVisible(Column column)
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isFieldReadOnly(Column column)
+    {
+    	if (isNew()==false && ObjectUtils.contains(keyColumns, column))
+    		return true;
+    	if (column.isAutoGenerated())
+    		return true;
+        return column.isReadOnly();
+    }
+
+    @Override
+    public boolean isFieldRequired(Column column)
+    {
+        return column.isRequired();
+    }
+
+    @Override
+    public boolean isModified()
+    {
+        return (modified!=null);
+    }
+
+    @Override
+    public boolean isNew()
+    {
+        if (!isValid())
+            throw new ObjectNotValidException(this);
+        // Record is new until all key fields have been supplied
+        if (keyColumns!=null)
+        {   // Check all Key Columns
+            for (int i=0; i<keyColumns.length; i++)
+            {
+                Object value = getValue(keyColumns[i]);
+                if ((value instanceof Number) && ((Number)value).longValue()==0)
+                    return true;
+                if (ObjectUtils.isEmpty(value))
+                    return true;
+            }
+        }
+        // Not new
+        return false;
+    }
+
+    @Override
+    public boolean isValid()
+    {
+        return (data!=null);
+    }
+
+    @Override
+    public boolean isReadOnly()
+    {
+        return (isValid() ? false : true);
+    }
+
+    @Override
+    public Object getValue(ColumnExpr column)
+    {
+        if (!isValid())
+            throw new ObjectNotValidException(this);
+        // getBeanPropertyValue 
+        return getBeanPropertyValue(data, column);
+    }
+
+    @Override
+    public Object getValue(int index)
+    {
+        return getValue(getColumn(index));
+    }
+
+    @Override
+    public boolean isNull(ColumnExpr column)
+    {
+        return ObjectUtils.isEmpty(getValue(column));
+    }
+
+    @Override
+    public boolean isNull(int index)
+    {
+        return isNull(getColumn(index));
+    }
+
+    /**
+     * Validates a value before it is set in the record.
+     */
+    @Override
+    public Object validateValue(Column column, Object value)
+    {
+        return column.validate(value);
+    }
+
+    /**
+     * sets the value of a field.
+     */
+    @Override
+    public void setValue(Column column, Object value)
+    {
+        if (!isValid())
+            throw new ObjectNotValidException(this);
+        // Track modification status
+        if (ObjectUtils.compareEqual(getValue(column), value)==false)
+        {
+            if (modified== null)
+                modified = new boolean[columns.size()]; 
+            modified[getFieldIndex(column)] = true;
+        }
+        // validate
+        value = validateValue(column, value);
+        // Set Value
+        setBeanPropertyValue(data, column, value);
+    }
+
+    /**
+     * sets the value of a field.
+     */
+    @Override
+    public final void setValue(int i, Object value)
+    {
+        setValue(getColumn(i), value);
+    }
+
+    /**
+     * Detects whether or not a particular field has been modified.
+     */
+    @Override
+    public boolean wasModified(Column column)
+    {
+        int index = getFieldIndex(column);
+        if (index<0)
+            throw new ItemNotFoundException(column.getName());
+        // check modified
+        return (modified!=null && modified[index]);
+    }
+
+    /**
+     * clears the modification status of the object and all fields.
+     */
+    public void clearModified()
+    {
+        modified = null;
+    }
+
+    // --------------- Bean support ------------------
+
+    @Override
+    public int setBeanProperties(Object bean)
+    {
+        return setBeanProperties(bean, null);
+    }
+
+    @Override
+    public int setBeanProperties(Object bean, Collection<? extends ColumnExpr> ignoreList)
+    {
+        // Add all Columns
+        int count = 0;
+        for (int i = 0; i < getFieldCount(); i++)
+        { // Check Property
+            Column column = getColumn(i);
+            if (column.isReadOnly())
+                continue;
+            if (ignoreList != null && ignoreList.contains(column))
+                continue; // ignore this property
+            // Get Property Name
+            setBeanPropertyValue(bean, column, getValue(i));
+        }
+        return count;
+    }
+
+    @Override
+    public int setRecordValues(Object bean, Collection<Column> ignoreList)
+    {
+        // Add all Columns
+        int count = 0;
+        for (int i = 0; i < getFieldCount(); i++)
+        { // Check Property
+            Column column = getColumn(i);
+            if (column.isReadOnly())
+                continue;
+            if (ignoreList != null && ignoreList.contains(column))
+                continue; // ignore this property
+            // Get Property Name
+            String property = column.getBeanPropertyName();
+            Object value = getBeanPropertyValue(bean, property);
+            setValue(column, value);
+            count++;
+        }
+        return count;
+    }
+    
+    @Override
+    public int setRecordValues(Object bean)
+    {
+        return setRecordValues(bean, null);
+    }
+
+    // --------------- protected ------------------
+
+    protected Object getBeanPropertyValue(Object bean, ColumnExpr column)
+    {
+        // Check Params
+        if (bean==null)
+            throw new InvalidArgumentException("bean", bean);
+        if (column==null)
+            throw new InvalidArgumentException("column", column);
+        // getBeanPropertyValue 
+        return getBeanPropertyValue(bean, column.getBeanPropertyName()); 
+    }
+
+    protected Object getBeanPropertyValue(Object bean, String property)
+    {
+        // Check Params
+        if (bean==null)
+            throw new InvalidArgumentException("bean", bean);
+        if (property==null)
+            throw new InvalidArgumentException("property", property);
+        try
+        {   // Get Property Value
+            PropertyUtilsBean pub = BeanUtilsBean.getInstance().getPropertyUtils();
+            return pub.getSimpleProperty(bean, property);
+
+        } catch (IllegalAccessException e)
+        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        } catch (InvocationTargetException e)
+        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        } catch (NoSuchMethodException e)
+        {   log.warn(bean.getClass().getName() + ": no getter available for property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        }
+    }
+
+    protected void setBeanPropertyValue(Object bean, Column column, Object value)
+    {
+        // Check Params
+        if (bean==null)
+            throw new InvalidArgumentException("bean", bean);
+        if (column==null)
+            throw new InvalidArgumentException("column", column);
+        // Get Property Name
+        String property = column.getBeanPropertyName(); 
+        try
+        {   // Get Property Value
+            if (ObjectUtils.isEmpty(value))
+                value = null;
+            // Set Property Value
+            if (value!=null)
+            {   // Bean utils will convert if necessary
+                BeanUtils.setProperty(bean, property, value);
+            }
+            else
+            {   // Don't convert, just set
+                PropertyUtils.setProperty(bean, property, null);
+            }
+        } catch (IllegalArgumentException e) {
+            log.error(bean.getClass().getName() + ": invalid argument for property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        } catch (IllegalAccessException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        } catch (InvocationTargetException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        } catch (NoSuchMethodException e) {
+            log.error(bean.getClass().getName() + ": no setter available for property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }    
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/ee8a3206/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
----------------------------------------------------------------------
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java b/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
index 173505b..a8626a6 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
@@ -1,397 +1,397 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.empire.db;
-// XML
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.Date;
-
-import org.apache.commons.beanutils.BeanUtils;
-import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.StringUtils;
-import org.apache.empire.data.Column;
-import org.apache.empire.data.ColumnExpr;
-import org.apache.empire.data.RecordData;
-import org.apache.empire.exceptions.BeanPropertySetException;
-import org.apache.empire.exceptions.InvalidArgumentException;
-import org.apache.empire.exceptions.ItemNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-
-/**
- * This interface defines for the classes DDRecordSet and DBRecord.
- * <P>
- * 
- *
- */
-public abstract class DBRecordData extends DBObject
-	implements RecordData
-{
-    private final static long serialVersionUID = 1L;
-  
-    // Logger
-    private static final Logger log = LoggerFactory.getLogger(DBRecordData.class);
-    
-    // Field Info
-    @Override
-    public abstract int     getFieldCount();
-    @Override
-    public abstract int  	getFieldIndex(ColumnExpr column);
-    @Override
-    public abstract int  	getFieldIndex(String column);
-    // Column lookup
-    @Override
-    public abstract ColumnExpr getColumnExpr(int i);
-    // xml
-    public abstract int     addColumnDesc(Element parent);
-    public abstract int     addRowValues (Element parent);
-    public abstract Document getXmlDocument();
-    // others
-    public abstract void    close();
-
-    /**
-     * Returns a value based on an index.
-     */
-    @Override
-    public abstract Object  getValue(int index);
-    
-    /**
-     * Returns a data value for the desired column .
-     * 
-     * @param column the column for which to obtain the value
-     * @return the record value
-     */
-    @Override
-    public final Object getValue(ColumnExpr column)
-    {
-        int index = getFieldIndex(column);
-        if (index<0)
-            throw new ItemNotFoundException(column.getName()); 
-        return getValue(index);
-    }
-
-    /**
-     * Returns a data value identified by the column index.
-     * The value is converted to integer if necessary .
-     * 
-     * @param index index of the column
-     * @return the record value
-     */
-    public int getInt(int index)
-    {
-        // Get Integer value
-        Object o = getValue(index);
-        return ObjectUtils.getInteger(o);
-    }
-    
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to integer if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final int getInt(ColumnExpr column)
-    {
-        return getInt(getFieldIndex(column));
-    }
-
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to a long if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public long getLong(int index)
-    {
-        // Get Integer value
-        Object o = getValue(index);
-        return ObjectUtils.getLong(o);
-    }
-    
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to a long if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final long getLong(ColumnExpr column)
-    {
-        return getLong(getFieldIndex(column));
-    }
-
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to double if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public double getDouble(int index)
-    {
-        // Get Double value
-        Object v = getValue(index);
-        return ObjectUtils.getDouble(v);
-    }
-
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to double if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final double getDouble(ColumnExpr column)
-    {
-        return getDouble(getFieldIndex(column));
-    }
-
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to double if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public BigDecimal getDecimal(int index)
-    {
-        // Get Double value
-        Object v = getValue(index);
-        return ObjectUtils.getDecimal(v);
-    }
-
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to BigDecimal if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final BigDecimal getDecimal(ColumnExpr column)
-    {
-        return getDecimal(getFieldIndex(column));
-    }
-    
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to boolean if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public boolean getBoolean(int index)
-    {
-        // Get Boolean value
-        Object o = getValue(index);
-        return ObjectUtils.getBoolean(o);
-    }
-    
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to boolean if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final boolean getBoolean(ColumnExpr column)
-    { return getBoolean(getFieldIndex(column)); }
-    
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to a string if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public String getString(int index)
-    {
-        // Get Integer value
-        Object o = getValue(index);
-        return StringUtils.toString(o);
-    }
-
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to a string if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final String getString(ColumnExpr column)
-    {
-        return getString(getFieldIndex(column));
-    }
-
-    /**
-     * Returns a data value identified by the column index.
-     * The data value is converted to a Date if necessary.
-     * 
-     * @param index index of the column
-     * @return the value
-     */
-    public Date getDateTime(int index)
-    {
-        // Get DateTime value
-        Object o = getValue(index);
-        return ObjectUtils.getDate(o);
-    }
-    
-    /**
-     * Returns a data value for the desired column.
-     * The data value is converted to a Date if necessary.
-     * 
-     * @param column identifying the column
-     * @return the value
-     */
-    public final Date getDateTime(ColumnExpr column)
-    {
-        return getDateTime(getFieldIndex(column));
-    }
-
-    /**
-     * Checks whether or not the value for the given column is null.
-     * 
-     * @param index index of the column
-     * @return true if the value is null or false otherwise
-     */
-    @Override
-    public boolean isNull(int index)
-    {
-        return (getValue(index) == null);
-    }
-
-    /**
-     * Checks whether or not the value for the given column is null.
-     * 
-     * @param column identifying the column
-     * @return true if the value is null or false otherwise
-     */
-    @Override
-    public final boolean isNull(ColumnExpr column)
-    {
-        return isNull(getFieldIndex(column));
-    }
-
-    /**
-     * Set a single property value of a java bean object used by readProperties.
-     */
-    @SuppressWarnings("rawtypes")
-    protected void setBeanProperty(ColumnExpr column, Object bean, String property, Object value)
-    {
-        if (StringUtils.isEmpty(property))
-            property = column.getBeanPropertyName();
-        try
-        {
-            if (bean==null)
-                throw new InvalidArgumentException("bean", bean);
-            if (StringUtils.isEmpty(property))
-                throw new InvalidArgumentException("property", property);
-            /*
-            if (log.isTraceEnabled())
-                log.trace(bean.getClass().getName() + ": setting property '" + property + "' to " + String.valueOf(value));
-            */
-            /*
-            if (value instanceof Date)
-            {   // Patch for date bug in BeanUtils
-                value = DateUtils.addDate((Date)value, 0, 0, 0);
-            }
-            */
-            Object type = column.getAttribute(Column.COLATTR_ENUMTYPE);
-            if (type!=null && value!=null)
-            {
-                String name = value.toString();
-                @SuppressWarnings("unchecked")
-                Class<Enum> enumType = (Class<Enum>)type;
-                for (Enum e : enumType.getEnumConstants())
-                    if (e.name().equals(name))
-                    {
-                        value = e;
-                        break;
-                    }
-            }
-            // Set Property Value
-            if (value!=null)
-            {   // Bean utils will convert if necessary
-                BeanUtils.setProperty(bean, property, value);
-            }
-            else
-            {   // Don't convert, just set
-                PropertyUtils.setProperty(bean, property, null);
-            }
-          // IllegalAccessException
-        } catch (IllegalAccessException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-          // InvocationTargetException  
-        } catch (InvocationTargetException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-          // NoSuchMethodException   
-        } catch (NoSuchMethodException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        } catch (NullPointerException e)
-        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
-            throw new BeanPropertySetException(bean, property, e);
-        }
-    }
-
-    /**
-     * Injects the current field values into a java bean.
-     * 
-     * @return the number of bean properties set on the supplied bean
-     */
-    @Override
-    public int setBeanProperties(Object bean, Collection<ColumnExpr> ignoreList)
-    {
-        // Add all Columns
-        int count = 0;
-        for (int i = 0; i < getFieldCount(); i++)
-        { // Check Property
-            ColumnExpr column = getColumnExpr(i);
-            if (ignoreList != null && ignoreList.contains(column))
-                continue; // ignore this property
-            // Get Property Name
-            String property = column.getBeanPropertyName();
-            if (property!=null)
-                setBeanProperty(column, bean, property, this.getValue(i));
-            count++;
-        }
-        return count;
-    }
-
-    /**
-     * Injects the current field values into a java bean.
-     * 
-     * @return the number of bean properties set on the supplied bean
-     */
-    @Override
-    public final int setBeanProperties(Object bean)
-    {
-        return setBeanProperties(bean, null);
-    }
-    
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.db;
+// XML
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.Column;
+import org.apache.empire.data.ColumnExpr;
+import org.apache.empire.data.RecordData;
+import org.apache.empire.exceptions.BeanPropertySetException;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * This interface defines for the classes DDRecordSet and DBRecord.
+ * <P>
+ * 
+ *
+ */
+public abstract class DBRecordData extends DBObject
+	implements RecordData
+{
+    private final static long serialVersionUID = 1L;
+  
+    // Logger
+    private static final Logger log = LoggerFactory.getLogger(DBRecordData.class);
+    
+    // Field Info
+    @Override
+    public abstract int     getFieldCount();
+    @Override
+    public abstract int  	getFieldIndex(ColumnExpr column);
+    @Override
+    public abstract int  	getFieldIndex(String column);
+    // Column lookup
+    @Override
+    public abstract ColumnExpr getColumnExpr(int i);
+    // xml
+    public abstract int     addColumnDesc(Element parent);
+    public abstract int     addRowValues (Element parent);
+    public abstract Document getXmlDocument();
+    // others
+    public abstract void    close();
+
+    /**
+     * Returns a value based on an index.
+     */
+    @Override
+    public abstract Object  getValue(int index);
+    
+    /**
+     * Returns a data value for the desired column .
+     * 
+     * @param column the column for which to obtain the value
+     * @return the record value
+     */
+    @Override
+    public final Object getValue(ColumnExpr column)
+    {
+        int index = getFieldIndex(column);
+        if (index<0)
+            throw new ItemNotFoundException(column.getName()); 
+        return getValue(index);
+    }
+
+    /**
+     * Returns a data value identified by the column index.
+     * The value is converted to integer if necessary .
+     * 
+     * @param index index of the column
+     * @return the record value
+     */
+    public int getInt(int index)
+    {
+        // Get Integer value
+        Object o = getValue(index);
+        return ObjectUtils.getInteger(o);
+    }
+    
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to integer if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final int getInt(ColumnExpr column)
+    {
+        return getInt(getFieldIndex(column));
+    }
+
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to a long if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public long getLong(int index)
+    {
+        // Get Integer value
+        Object o = getValue(index);
+        return ObjectUtils.getLong(o);
+    }
+    
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to a long if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final long getLong(ColumnExpr column)
+    {
+        return getLong(getFieldIndex(column));
+    }
+
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to double if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public double getDouble(int index)
+    {
+        // Get Double value
+        Object v = getValue(index);
+        return ObjectUtils.getDouble(v);
+    }
+
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to double if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final double getDouble(ColumnExpr column)
+    {
+        return getDouble(getFieldIndex(column));
+    }
+
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to double if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public BigDecimal getDecimal(int index)
+    {
+        // Get Double value
+        Object v = getValue(index);
+        return ObjectUtils.getDecimal(v);
+    }
+
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to BigDecimal if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final BigDecimal getDecimal(ColumnExpr column)
+    {
+        return getDecimal(getFieldIndex(column));
+    }
+    
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to boolean if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public boolean getBoolean(int index)
+    {
+        // Get Boolean value
+        Object o = getValue(index);
+        return ObjectUtils.getBoolean(o);
+    }
+    
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to boolean if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final boolean getBoolean(ColumnExpr column)
+    { return getBoolean(getFieldIndex(column)); }
+    
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to a string if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public String getString(int index)
+    {
+        // Get Integer value
+        Object o = getValue(index);
+        return StringUtils.toString(o);
+    }
+
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to a string if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final String getString(ColumnExpr column)
+    {
+        return getString(getFieldIndex(column));
+    }
+
+    /**
+     * Returns a data value identified by the column index.
+     * The data value is converted to a Date if necessary.
+     * 
+     * @param index index of the column
+     * @return the value
+     */
+    public Date getDateTime(int index)
+    {
+        // Get DateTime value
+        Object o = getValue(index);
+        return ObjectUtils.getDate(o);
+    }
+    
+    /**
+     * Returns a data value for the desired column.
+     * The data value is converted to a Date if necessary.
+     * 
+     * @param column identifying the column
+     * @return the value
+     */
+    public final Date getDateTime(ColumnExpr column)
+    {
+        return getDateTime(getFieldIndex(column));
+    }
+
+    /**
+     * Checks whether or not the value for the given column is null.
+     * 
+     * @param index index of the column
+     * @return true if the value is null or false otherwise
+     */
+    @Override
+    public boolean isNull(int index)
+    {
+        return (getValue(index) == null);
+    }
+
+    /**
+     * Checks whether or not the value for the given column is null.
+     * 
+     * @param column identifying the column
+     * @return true if the value is null or false otherwise
+     */
+    @Override
+    public final boolean isNull(ColumnExpr column)
+    {
+        return isNull(getFieldIndex(column));
+    }
+
+    /**
+     * Set a single property value of a java bean object used by readProperties.
+     */
+    @SuppressWarnings("rawtypes")
+    protected void setBeanProperty(ColumnExpr column, Object bean, String property, Object value)
+    {
+        if (StringUtils.isEmpty(property))
+            property = column.getBeanPropertyName();
+        try
+        {
+            if (bean==null)
+                throw new InvalidArgumentException("bean", bean);
+            if (StringUtils.isEmpty(property))
+                throw new InvalidArgumentException("property", property);
+            /*
+            if (log.isTraceEnabled())
+                log.trace(bean.getClass().getName() + ": setting property '" + property + "' to " + String.valueOf(value));
+            */
+            /*
+            if (value instanceof Date)
+            {   // Patch for date bug in BeanUtils
+                value = DateUtils.addDate((Date)value, 0, 0, 0);
+            }
+            */
+            Object type = column.getAttribute(Column.COLATTR_ENUMTYPE);
+            if (type!=null && value!=null)
+            {
+                String name = value.toString();
+                @SuppressWarnings("unchecked")
+                Class<Enum> enumType = (Class<Enum>)type;
+                for (Enum e : enumType.getEnumConstants())
+                    if (e.name().equals(name))
+                    {
+                        value = e;
+                        break;
+                    }
+            }
+            // Set Property Value
+            if (value!=null)
+            {   // Bean utils will convert if necessary
+                BeanUtils.setProperty(bean, property, value);
+            }
+            else
+            {   // Don't convert, just set
+                PropertyUtils.setProperty(bean, property, null);
+            }
+          // IllegalAccessException
+        } catch (IllegalAccessException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+          // InvocationTargetException  
+        } catch (InvocationTargetException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+          // NoSuchMethodException   
+        } catch (NoSuchMethodException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        } catch (NullPointerException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }
+    }
+
+    /**
+     * Injects the current field values into a java bean.
+     * 
+     * @return the number of bean properties set on the supplied bean
+     */
+    @Override
+    public int setBeanProperties(Object bean, Collection<? extends ColumnExpr> ignoreList)
+    {
+        // Add all Columns
+        int count = 0;
+        for (int i = 0; i < getFieldCount(); i++)
+        { // Check Property
+            ColumnExpr column = getColumnExpr(i);
+            if (ignoreList != null && ignoreList.contains(column))
+                continue; // ignore this property
+            // Get Property Name
+            String property = column.getBeanPropertyName();
+            if (property!=null)
+                setBeanProperty(column, bean, property, this.getValue(i));
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * Injects the current field values into a java bean.
+     * 
+     * @return the number of bean properties set on the supplied bean
+     */
+    @Override
+    public final int setBeanProperties(Object bean)
+    {
+        return setBeanProperties(bean, null);
+    }
+    
+}