This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push:
new 3769626b EMPIREDB-459 DBRecordData and DataListEntry: sync functions
and behaviour
3769626b is described below
commit 3769626b04c07848cd3ad05af758ff10f62283bb
Author: Rainer Döbele <[email protected]>
AuthorDate: Fri Mar 21 10:48:44 2025 +0100
EMPIREDB-459
DBRecordData and DataListEntry: sync functions and behaviour
---
.../java/org/apache/empire/commons/ClassUtils.java | 58 +++
.../java/org/apache/empire/data/RecordData.java | 2 +-
.../org/apache/empire/data/list/DataListEntry.java | 508 +++++++++++++++++----
.../org/apache/empire/data/list/DataListHead.java | 6 +-
.../java/org/apache/empire/db/DBRecordData.java | 329 +++++++------
.../main/java/org/apache/empire/db/DBRowSet.java | 16 +
6 files changed, 666 insertions(+), 253 deletions(-)
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
index f78f5be1..8a10f6cb 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
@@ -18,6 +18,7 @@
*/
package org.apache.empire.commons;
+import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -31,13 +32,17 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
+import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConstructorUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.empire.exceptions.BeanPropertySetException;
import org.apache.empire.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.InvalidOperationException;
import org.apache.empire.exceptions.NotImplementedException;
import org.apache.empire.exceptions.NotSupportedException;
+import org.apache.empire.exceptions.PropertyReadOnlyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -803,4 +808,57 @@ public final class ClassUtils
}
}
+ /**
+ * Set a single property value of a java bean object used by
readProperties.
+ *
+ * @param column the column expression
+ * @param bean the bean
+ * @param property the property
+ * @param value the value
+ */
+ public static void setBeanProperty(Object bean, String property, Object
value)
+ {
+ try
+ {
+ if (bean==null)
+ throw new InvalidArgumentException("bean", bean);
+ if (StringUtils.isEmpty(property))
+ throw new InvalidArgumentException("property", property);
+ if (log.isTraceEnabled())
+ log.trace("{}: setting property '{}' to {}",
bean.getClass().getName(), property, value);
+ // Set Property Value
+ if (value!=null)
+ { // Bean utils will convert if necessary
+ BeanUtils.setProperty(bean, property, value);
+ }
+ else
+ { // Don't convert, just set
+ PropertyDescriptor pd =
PropertyUtils.getPropertyDescriptor(bean, property);
+ if (pd==null)
+ return; // No such property
+ // get the write method
+ final Method method = PropertyUtils.getWriteMethod(pd);
+ if (method == null)
+ throw new PropertyReadOnlyException(property);
+ // invoke
+ method.invoke(bean, value);
+ }
+ // 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);
+ }
+ }
+
}
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 4400344c..7655d464 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
@@ -91,7 +91,7 @@ public interface RecordData
/**
* 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
diff --git
a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
index c6e01907..b28ba7be 100644
--- a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
@@ -20,18 +20,24 @@ package org.apache.empire.data.list;
import java.io.Serializable;
import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
+import org.apache.empire.commons.ClassUtils;
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.EntityType;
import org.apache.empire.data.RecordData;
+import org.apache.empire.db.DBRecordBase;
+import org.apache.empire.db.exceptions.FieldIllegalValueException;
import org.apache.empire.db.exceptions.NoPrimaryKeyException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
-import org.apache.empire.exceptions.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -127,6 +133,7 @@ public class DataListEntry implements RecordData,
Serializable
public void updateData(RecordData recData)
{
ColumnExpr[] cols = head.getColumns();
+ DBRecordBase dbrb =(recData instanceof DBRecordBase) ?
(DBRecordBase)recData : null;
for (int i=0; i<cols.length; i++)
{
ColumnExpr col = ObjectUtils.unwrap(cols[i]);
@@ -141,6 +148,10 @@ public class DataListEntry implements RecordData,
Serializable
continue;
// update
try {
+ // check valid
+ if (dbrb!=null && !dbrb.isValueValid(ri))
+ continue;
+ // set data
values[i] = recData.getValue(ri);
} catch(Exception e) {
log.error("Failed to update value for column {}",
cols[i].getName());
@@ -148,6 +159,11 @@ public class DataListEntry implements RecordData,
Serializable
}
}
+ /**
+ * Modifies a particular value
+ * @param col the column to modify
+ * @param value the new value
+ */
public void modifyValue(ColumnExpr col, Object value)
{
int i = getFieldIndex(col);
@@ -157,6 +173,11 @@ public class DataListEntry implements RecordData,
Serializable
values[i] = value;
}
+ /**
+ * Returns the row-number
+ * This works only, if the row number has been set in the constructor
+ * @return the row number
+ */
public int getRownum()
{
return rownum;
@@ -193,6 +214,11 @@ public class DataListEntry implements RecordData,
Serializable
return head.columns[index];
}
+ /**
+ * Returns a value based on a field index.
+ * @param index the field index
+ * @return the field value
+ */
@Override
public Object getValue(int index)
{
@@ -201,176 +227,486 @@ public class DataListEntry implements RecordData,
Serializable
return values[index];
}
- @Override
- public final Object get(ColumnExpr column)
- {
- return getValue(indexOf(column));
- }
-
/**
- * Deprecated Renamed to get(...)
- * @param column the column
- * @return the field value
+ * Deprecated Renamed to get(...)
+ * @param column the column for which to obtain the value
+ * @return the record value
*/
@Deprecated
public Object getValue(ColumnExpr column)
{
return get(column);
}
-
- public final <T> T get(Column column, Class<T> returnType)
+
+ /**
+ * 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 get(ColumnExpr column)
{
- return ObjectUtils.convert(returnType, get(column));
+ return getValue(getFieldIndex(column));
}
- public final Object[] getArray(ColumnExpr... columns)
+ /**
+ * Returns the value of a field as an object of a given (wrapper)type
+ * @param <T> the value type
+ * @param column the column for which to retrieve the value
+ * @param returnType the type of the returned value
+ * @return the value
+ */
+ public final <T> T get(Column column, Class<T> returnType)
{
- Object[] values = new Object[columns.length];
- for (int i=0; i<columns.length; i++)
- {
- int index = getFieldIndex(columns[i]);
- if (index<0)
- throw new ItemNotFoundException(columns[i].getName());
- values[i] = getValue(index);
- }
- return values;
+ return ObjectUtils.convert(returnType, get(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 ObjectUtils.isEmpty(getValue(index));
}
+
+ /**
+ * 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));
+ }
+
+ /**
+ * Returns true if a numeric value is Zero
+ * For numeric columns only!
+ * @param column the column
+ * @return true if the value is zero or false otherwise
+ */
+ public boolean isZero(ColumnExpr column)
+ {
+ if (column==null || column.getDataType().isNumeric())
+ throw new InvalidArgumentException("column", column);
+ // check for zero
+ Object v = get(column);
+ return (v instanceof Number) ? ObjectUtils.isZero((Number)v) : true;
+ }
/*
* Conversion functions
*/
-
- public String getString(int index)
- { // Get String value
- Object o = getValue(index);
- return ObjectUtils.getString(o);
+
+ /**
+ * 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 final String getString(int index)
+ {
+ return ObjectUtils.getString(getValue(index));
}
+ /**
+ * 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(indexOf(column));
+ return getString(getFieldIndex(column));
}
- public int getInt(int index)
- { // Get Integer value
- Object o = getValue(index);
- return ObjectUtils.getInteger(o);
+ /**
+ * 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 final int getInt(int index)
+ {
+ return ObjectUtils.getInteger(getValue(index));
}
+ /**
+ * 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(indexOf(column));
+ return getInt(getFieldIndex(column));
}
- public long getLong(int index)
- { // Get Long value
- Object o = getValue(index);
- return ObjectUtils.getLong(o);
+ /**
+ * 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 final long getLong(int index)
+ {
+ return ObjectUtils.getLong(getValue(index));
}
+ /**
+ * 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(indexOf(column));
+ return getLong(getFieldIndex(column));
}
- public BigDecimal getDecimal(int index)
- { // Get Integer value
- Object o = getValue(index);
- return ObjectUtils.getDecimal(o);
+ /**
+ * 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)
+ {
+ return ObjectUtils.getDouble(getValue(index));
}
-
+
+ /**
+ * 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 final BigDecimal getDecimal(int index)
+ {
+ return ObjectUtils.getDecimal(getValue(index));
+ }
+
+ /**
+ * 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(indexOf(column));
+ return getDecimal(getFieldIndex(column));
}
- public boolean getBoolean(int index)
- { // Get Integer value
- Object o = getValue(index);
- return ObjectUtils.getBoolean(o);
+ /**
+ * 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 final boolean getBoolean(int index)
+ {
+ return ObjectUtils.getBoolean(getValue(index));
}
+ /**
+ * 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 the value as as a java.util.Date object
+ * The data value is converted to a Date if necessary.
+ *
+ * @param index index of the column
+ * @return the value
+ */
+ public final Date getDate(int index)
+ {
+ return ObjectUtils.getDate(getValue(index));
+ }
+
+ /**
+ * Returns the value as as a java.util.Date object
+ * The data value is converted to a Date if necessary.
+ *
+ * @param column identifying the column
+ * @return the value
+ */
+ public final Date getDate(ColumnExpr column)
+ {
+ return getDate(getFieldIndex(column));
+ }
+
+ /**
+ * Returns the value as as a java.sql.Timestamp object
+ * @return the Timestamp
+ */
+ public final Timestamp getTimestamp(int index)
+ {
+ return ObjectUtils.getTimestamp(getValue(index));
+ }
+
+ /**
+ * Returns the value as as a java.sql.Timestamp object
+ * @return the Timestamp
+ */
+ public final Timestamp getTimestamp(ColumnExpr column)
+ {
+ return getTimestamp(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 final LocalDate getLocalDate(int index)
+ {
+ return ObjectUtils.getLocalDate(getValue(index));
+ }
+
+ /**
+ * 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 LocalDate getLocalDate(ColumnExpr column)
+ {
+ return getLocalDate(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 final LocalDateTime getLocalDateTime(int index)
+ {
+ return ObjectUtils.getLocalDateTime(getValue(index));
+ }
+
+ /**
+ * 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 LocalDateTime getLocalDateTime(ColumnExpr column)
{
- return getBoolean(indexOf(column));
+ return getLocalDateTime(getFieldIndex(column));
}
+ /**
+ * Returns the value of a field as an enum
+ * For numeric columns the value is assumed to be an ordinal of the
enumeration item
+ * For non numeric columns the value is assumed to be the name of the
enumeration item
+ *
+ * @param <T> the enum type
+ * @param index index of the field
+ * @param enumType the enum type class
+ * @return the enum value
+ */
public <T extends Enum<?>> T getEnum(int index, Class<T> enumType)
{ // check for null
if (isNull(index))
return null;
- // check column data type
+ // convert
ColumnExpr col = getColumn(index);
- boolean numeric = col.getDataType().isNumeric();
- return ObjectUtils.getEnum(enumType, (numeric ? getInt(index) :
getValue(index)));
+ try {
+ // Convert to enum, depending on DataType
+ boolean numeric = col.getDataType().isNumeric();
+ return ObjectUtils.getEnum(enumType, (numeric ? getInt(index) :
getValue(index)));
+
+ } catch (Exception e) {
+ // Illegal value
+ String value = StringUtils.valueOf(getValue(index));
+ log.error("Unable to resolve enum value of '{}' for type {}",
value, enumType.getName());
+ throw new FieldIllegalValueException(col.getUpdateColumn(), value,
e);
+ }
}
+ /**
+ * Returns the value of a field as an enum
+ * For numeric columns the value is assumed to be an ordinal of the
enumeration item
+ * For non numeric columns the value is assumed to be the name of the
enumeration item
+ *
+ * @param <T> the enum type
+ * @param column the column for which to retrieve the value
+ * @param enumType the enum type class
+ * @return the enum value
+ */
public final <T extends Enum<?>> T getEnum(ColumnExpr column, Class<T>
enumType)
{
- return getEnum(indexOf(column), enumType);
+ return getEnum(getFieldIndex(column), enumType);
}
+ /**
+ * Returns the value of a field as an enum
+ * This assumes that the column attribute "enumType" has been set to an
enum type
+ * For numeric columns the value is assumed to be an ordinal of the
enumeration item
+ *
+ * @param <T> the enum type
+ * @param column the column for which to retrieve the value
+ * @return the enum value
+ */
@SuppressWarnings("unchecked")
public final <T extends Enum<?>> T getEnum(Column column)
{
- Class<T> enumType = (Class<T>)column.getEnumType();
+ Class<Enum<?>> enumType = column.getEnumType();
if (enumType==null)
{ // Not an enum column (Attribute "enumType" has not been set)
throw new InvalidArgumentException("column", column);
}
- return getEnum(indexOf(column), enumType);
+ return getEnum(getFieldIndex(column), (Class<T>)enumType);
}
-
- public Date getDate(int index)
+
+ /**
+ * Returns an array of values for the given column expressions
+ *
+ * @param columns the column expressions
+ * @return the corresponding record values
+ */
+ public final Object[] getArray(ColumnExpr... columns)
{
- Object o = getValue(index);
- return ObjectUtils.getDate(o);
+ Object[] values = new Object[columns.length];
+ for (int i=0; i<columns.length; i++)
+ {
+ int index = getFieldIndex(columns[i]);
+ if (index<0)
+ throw new ItemNotFoundException(columns[i].getName());
+ values[i] = getValue(index);
+ }
+ return values;
}
-
- public final Date getDate(ColumnExpr column)
+
+ /**
+ * Returns the value of a column as a formatted text
+ * This converts the value to a string if necessary and performs an
options lookup
+ * To customize conversion please override convertToString()
+ * @param column the column for which to get the formatted value
+ * @return the formatted value
+ */
+ public String getText(ColumnExpr col)
{
- return getDate(indexOf(column));
+ int idx = getFieldIndex(col);
+ return head.getText(idx, values[idx]);
}
-
- @Override
- public final boolean isNull(ColumnExpr column)
+
+ /**
+ * Returns the value of a column as a formatted text
+ * This converts the value to a string if necessary and performs an
options lookup
+ * To customize conversion please override convertToString()
+ * @param name the column for which to get the formatted value
+ * @return the formatted value
+ */
+ public final String getText(String name)
{
- return isNull(indexOf(column));
+ return getText(getColumn(getFieldIndex(name)));
}
-
+
+ /**
+ * Injects the current field values into a java bean.
+ * 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)
+ * @return the number of bean properties set on the supplied bean
+ */
@Override
public int setBeanProperties(Object bean, Collection<? extends ColumnExpr>
ignoreList)
{
- throw new NotImplementedException(this, "setBeanProperties");
+ // Add all Columns
+ int count = 0;
+ for (int i = 0; i < getFieldCount(); i++)
+ { // Check Property
+ ColumnExpr column = getColumn(i);
+ if ((column instanceof Column) && ((Column)column).isReadOnly())
+ continue;
+ if (ignoreList != null && ignoreList.contains(column))
+ continue; // ignore this property
+ // Get Property Name
+ setBeanProperty(column, bean, this.getValue(i));
+ count++;
+ }
+ return count;
}
-
- public int setBeanProperties(Object bean)
+
+ /**
+ * Injects the current field values into a java bean.
+ * The property name is detected by ColumnExpr.getBeanPropertyName()
+ * @param bean the Java Bean for which to set the properties
+ * @return the number of bean properties set on the supplied bean
+ */
+ public final int setBeanProperties(Object bean)
{
return setBeanProperties(bean, null);
}
- /*
- * Miscellaneous functions
+ /**
+ * Set a single property value on a java bean object
+ *
+ * @param column the column expression
+ * @param bean the bean
+ * @param value the value
*/
-
- public String getText(String name)
- {
- int idx = getFieldIndex(name);
- return head.getText(idx, values[idx]);
- }
-
- public String getText(ColumnExpr col)
+ protected void setBeanProperty(ColumnExpr column, Object bean, Object
value)
{
- int idx = getFieldIndex(col);
- return head.getText(idx, values[idx]);
+ if (value!=null)
+ { // Convert to enum
+ Class<Enum<?>> enumType = column.getEnumType();
+ if (enumType!=null)
+ value = ObjectUtils.getEnum(enumType, value);
+ }
+ String property = column.getBeanPropertyName();
+ ClassUtils.setBeanProperty(bean, property, value);
}
+ /*
+ * Miscellaneous functions
+ */
+
@Override
public String toString()
{
@@ -383,6 +719,11 @@ public class DataListEntry implements RecordData,
Serializable
return b.toString();
}
+ /**
+ * Returns the field index
+ * If the column cannot be found a ItemNotFoundException is thrown
+ * @param column the column for which to return the index
+ * @return the index
protected int indexOf(ColumnExpr column)
{
int index = head.getColumnIndex(column);
@@ -390,5 +731,6 @@ public class DataListEntry implements RecordData,
Serializable
throw new ItemNotFoundException(column.getName());
return index;
}
+ */
}
diff --git
a/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
b/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
index c48fa2e9..e4ca8bf4 100644
--- a/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
@@ -96,14 +96,14 @@ public class DataListHead implements Serializable
* Returns the value of a column as a formatted text
* This converts the value to a string if necessary and performs an
options lookup
* To customize conversion please override convertToString()
- * @param idx the field index for which to get the formatted value
+ * @param index the field index for which to get the formatted value
* @param value the value to format
* @return the formatted value
*/
- public String getText(int idx, Object value)
+ public String getText(int index, Object value)
{ // find text
String text;
- ColumnExpr column = columns[idx];
+ ColumnExpr column = columns[index];
// check options first
Options options = column.getOptions();
if (options!=null && options.has(value))
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 b4b1c9fc..ad769810 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
@@ -17,18 +17,14 @@
* under the License.
*/
package org.apache.empire.db;
-import java.beans.PropertyDescriptor;
-// XML
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.math.BigDecimal;
+import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
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.ClassUtils;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
@@ -37,10 +33,8 @@ import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.RecordData;
import org.apache.empire.db.context.DBContextAware;
import org.apache.empire.db.exceptions.FieldIllegalValueException;
-import org.apache.empire.exceptions.BeanPropertySetException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
-import org.apache.empire.exceptions.PropertyReadOnlyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -95,75 +89,96 @@ public abstract class DBRecordData extends DBObject
{
return get(column);
}
+
+ /**
+ * 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 get(ColumnExpr column)
+ {
+ return getValue(getFieldIndex(column));
+ }
/**
- * Deprecated Renamed to get(...)
+ * Returns the value of a field as an object of a given (wrapper)type
* @param <T> the value type
* @param column the column for which to retrieve the value
* @param returnType the type of the returned value
* @return the value
*/
- @Deprecated
- public final <T> T getValue(Column column, Class<T> returnType)
+ public final <T> T get(Column column, Class<T> returnType)
{
- return get(column, returnType);
+ return ObjectUtils.convert(returnType, get(column));
}
-
+
/**
- * Deprecated Renamed to get(...)
- * @param columns the columns for which to obtain the values
- * @return the record values
+ * 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
*/
- @Deprecated
- public final Object[] getValues(ColumnExpr... columns)
+ @Override
+ public boolean isNull(int index)
{
- return getArray(columns);
+ return ObjectUtils.isEmpty(getValue(index));
}
-
+
/**
- * Returns a data value for the desired column .
+ * Checks whether or not the value for the given column is null.
*
- * @param column the column for which to obtain the value
- * @return the record value
+ * @param column identifying the column
+ * @return true if the value is null or false otherwise
*/
@Override
- public final Object get(ColumnExpr column)
+ public final boolean isNull(ColumnExpr column)
{
- int index = getFieldIndex(column);
- if (index<0)
- throw new ItemNotFoundException(column.getName());
- return getValue(index);
+ return isNull(getFieldIndex(column));
}
/**
- * Returns the value of a field as an object of a given (wrapper)type
- * @param <T> the value type
- * @param column the column for which to retrieve the value
- * @param returnType the type of the returned value
+ * Returns true if a numeric value is Zero
+ * For numeric columns only!
+ * @param column the column
+ * @return true if the value is zero or false otherwise
+ */
+ public boolean isZero(ColumnExpr column)
+ {
+ if (column==null || column.getDataType().isNumeric())
+ throw new InvalidArgumentException("column", column);
+ // check for zero
+ Object v = get(column);
+ return (v instanceof Number) ? ObjectUtils.isZero((Number)v) : true;
+ }
+
+ /*
+ * Conversion functions
+ */
+
+ /**
+ * 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 final <T> T get(Column column, Class<T> returnType)
+ public final String getString(int index)
{
- return ObjectUtils.convert(returnType, get(column));
+ return ObjectUtils.getString(getValue(index));
}
/**
- * Returns an array of values for the given column expressions
+ * Returns a data value for the desired column.
+ * The data value is converted to a string if necessary.
*
- * @param columns the column expressions
- * @return the corresponding record values
+ * @param column identifying the column
+ * @return the value
*/
- public final Object[] getArray(ColumnExpr... columns)
+ public final String getString(ColumnExpr column)
{
- Object[] values = new Object[columns.length];
- for (int i=0; i<columns.length; i++)
- {
- int index = getFieldIndex(columns[i]);
- if (index<0)
- throw new ItemNotFoundException(columns[i].getName());
- values[i] = getValue(index);
- }
- return values;
+ return getString(getFieldIndex(column));
}
/**
@@ -173,7 +188,7 @@ public abstract class DBRecordData extends DBObject
* @param index index of the column
* @return the record value
*/
- public int getInt(int index)
+ public final int getInt(int index)
{
return ObjectUtils.getInteger(getValue(index));
}
@@ -197,7 +212,7 @@ public abstract class DBRecordData extends DBObject
* @param index index of the column
* @return the value
*/
- public long getLong(int index)
+ public final long getLong(int index)
{
return ObjectUtils.getLong(getValue(index));
}
@@ -245,7 +260,7 @@ public abstract class DBRecordData extends DBObject
* @param index index of the column
* @return the value
*/
- public BigDecimal getDecimal(int index)
+ public final BigDecimal getDecimal(int index)
{
return ObjectUtils.getDecimal(getValue(index));
}
@@ -269,7 +284,7 @@ public abstract class DBRecordData extends DBObject
* @param index index of the column
* @return the value
*/
- public boolean getBoolean(int index)
+ public final boolean getBoolean(int index)
{
return ObjectUtils.getBoolean(getValue(index));
}
@@ -287,51 +302,63 @@ public abstract class DBRecordData extends DBObject
}
/**
- * Returns a data value identified by the column index.
- * The data value is converted to a string if necessary.
+ * Returns the value as as a java.util.Date object
+ * The data value is converted to a Date if necessary.
*
* @param index index of the column
* @return the value
*/
- public String getString(int index)
+ public final Date getDate(int index)
{
- return ObjectUtils.getString(getValue(index));
+ return ObjectUtils.getDate(getValue(index));
}
-
+
/**
- * Returns a data value for the desired column.
- * The data value is converted to a string if necessary.
+ * Returns the value as as a java.util.Date object
+ * The data value is converted to a Date if necessary.
*
* @param column identifying the column
* @return the value
*/
- public final String getString(ColumnExpr column)
+ public final Date getDate(ColumnExpr column)
{
- return getString(getFieldIndex(column));
+ return getDate(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
+ * Deprecated: Use getDate(index) instead.
*/
+ @Deprecated
public final Date getDateTime(int index)
{
- return ObjectUtils.getDate(getValue(index));
+ return getDate(index);
}
/**
- * 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
+ * Deprecated: Use getDate(column) instead.
*/
+ @Deprecated
public final Date getDateTime(ColumnExpr column)
{
- return getDateTime(getFieldIndex(column));
+ return getDate(column);
+ }
+
+ /**
+ * Returns the value as as a java.sql.Timestamp object
+ * @return the Timestamp
+ */
+ public final Timestamp getTimestamp(int index)
+ {
+ return ObjectUtils.getTimestamp(getValue(index));
+ }
+
+ /**
+ * Returns the value as as a java.sql.Timestamp object
+ * @return the Timestamp
+ */
+ public final Timestamp getTimestamp(ColumnExpr column)
+ {
+ return getTimestamp(getFieldIndex(column));
}
/**
@@ -429,7 +456,9 @@ public abstract class DBRecordData extends DBObject
/**
* Returns the value of a field as an enum
* This assumes that the column attribute "enumType" has been set to an
enum type
+ * For numeric columns the value is assumed to be an ordinal of the
enumeration item
*
+ * @param <T> the enum type
* @param column the column for which to retrieve the value
* @return the enum value
*/
@@ -443,29 +472,24 @@ public abstract class DBRecordData extends DBObject
}
return getEnum(getFieldIndex(column), (Class<T>)enumType);
}
-
- /**
- * 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 ObjectUtils.isEmpty(getValue(index));
- }
/**
- * Checks whether or not the value for the given column is null.
+ * Returns an array of values for the given column expressions
*
- * @param column identifying the column
- * @return true if the value is null or false otherwise
+ * @param columns the column expressions
+ * @return the corresponding record values
*/
- @Override
- public final boolean isNull(ColumnExpr column)
+ public final Object[] getArray(ColumnExpr... columns)
{
- return isNull(getFieldIndex(column));
+ Object[] values = new Object[columns.length];
+ for (int i=0; i<columns.length; i++)
+ {
+ int index = getFieldIndex(columns[i]);
+ if (index<0)
+ throw new ItemNotFoundException(columns[i].getName());
+ values[i] = getValue(index);
+ }
+ return values;
}
/**
@@ -505,84 +529,22 @@ public abstract class DBRecordData extends DBObject
}
/**
- * Convert a non-string value to a string
- * @param column the column expression
- * @param value the value to format
- * @return the formatted string
- */
- protected String formatValue(ColumnExpr column, Object value)
- {
- return ObjectUtils.getString(value);
- }
-
- /**
- * Set a single property value of a java bean object used by
readProperties.
- *
- * @param column the column expression
- * @param bean the bean
- * @param property the property
- * @param value the value
+ * Returns the value of a column as a formatted text
+ * This converts the value to a string if necessary and performs an
options lookup
+ * To customize conversion please override convertToString()
+ * @param name the column for which to get the formatted value
+ * @return the formatted value
*/
- protected void setBeanProperty(ColumnExpr column, Object bean, String
property, Object value)
+ public final String getText(String name)
{
- 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("{}: setting property '{}' to {}",
bean.getClass().getName(), property, value);
- /*
- if (value instanceof Date)
- { // Patch for date bug in BeanUtils
- value = DateUtils.addDate((Date)value, 0, 0, 0);
- }
- */
- // Set Property Value
- if (value!=null)
- { // Convert to enum
- Class<Enum<?>> enumType = column.getEnumType();
- if (enumType!=null)
- value = ObjectUtils.getEnum(enumType, value);
- // Bean utils will convert if necessary
- BeanUtils.setProperty(bean, property, value);
- }
- else
- { // Don't convert, just set
- PropertyDescriptor pd =
PropertyUtils.getPropertyDescriptor(bean, property);
- if (pd==null)
- return; // No such property
- // get the write method
- final Method method = PropertyUtils.getWriteMethod(pd);
- if (method == null)
- throw new PropertyReadOnlyException(property);
- // invoke
- method.invoke(bean, value);
- }
- // 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);
- }
+ return getText(getColumn(getFieldIndex(name)));
}
/**
* Injects the current field values into a java bean.
- *
+ * 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)
* @return the number of bean properties set on the supplied bean
*/
@Override
@@ -593,12 +555,12 @@ public abstract class DBRecordData extends DBObject
for (int i = 0; i < getFieldCount(); i++)
{ // Check Property
ColumnExpr column = getColumn(i);
+ if ((column instanceof Column) && ((Column)column).isReadOnly())
+ continue;
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));
+ setBeanProperty(column, bean, this.getValue(i));
count++;
}
return count;
@@ -606,7 +568,8 @@ public abstract class DBRecordData extends DBObject
/**
* Injects the current field values into a java bean.
- * @param bean the bean
+ * The property name is detected by ColumnExpr.getBeanPropertyName()
+ * @param bean the Java Bean for which to set the properties
* @return the number of bean properties set on the supplied bean
*/
public final int setBeanProperties(Object bean)
@@ -614,4 +577,38 @@ public abstract class DBRecordData extends DBObject
return setBeanProperties(bean, null);
}
+ /**
+ * Set a single property value on a java bean object
+ *
+ * @param column the column expression
+ * @param bean the bean
+ * @param value the value
+ */
+ protected void setBeanProperty(ColumnExpr column, Object bean, Object
value)
+ {
+ if (value!=null)
+ { // Convert to enum
+ Class<Enum<?>> enumType = column.getEnumType();
+ if (enumType!=null)
+ value = ObjectUtils.getEnum(enumType, value);
+ }
+ String property = column.getBeanPropertyName();
+ ClassUtils.setBeanProperty(bean, property, value);
+ }
+
+ /*
+ * Miscellaneous functions
+ */
+
+ /**
+ * Convert a non-string value to a string
+ * @param column the column expression
+ * @param value the value to format
+ * @return the formatted string
+ */
+ protected String formatValue(ColumnExpr column, Object value)
+ {
+ return ObjectUtils.getString(value);
+ }
+
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index 44f0dcc6..2765d473 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -37,6 +37,7 @@ import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.DataType;
import org.apache.empire.data.EntityType;
import org.apache.empire.data.Record;
+import org.apache.empire.data.RecordData;
import org.apache.empire.db.DBRelation.DBCascadeAction;
import org.apache.empire.db.DBRelation.DBReference;
import org.apache.empire.db.context.DBContextBase;
@@ -1292,6 +1293,21 @@ public abstract class DBRowSet extends DBExpr implements
EntityType
// just use the context
return context.createCommand();
}
+
+ /**
+ * Adds key constraints to a DBCommand object
+ * @param cmd the command to add the constraints to
+ * @param data the record from which to take the values
+ */
+ public void addKeyConstraints(DBCommand cmd, RecordData data)
+ {
+ DBColumn[] keyColumns = getKeyColumns();
+ if (keyColumns==null || keyColumns.length==0)
+ throw new NoPrimaryKeyException(this);
+ // Collect key
+ for (int i=0; i<keyColumns.length; i++)
+ cmd.where(keyColumns[i].is(data.get(keyColumns[i])));
+ }
/**
* Returns additional data stored on a record by the RowSet