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 c6166e8c EMPIREDB-444 New class ValueUtils to override value type
conversion
c6166e8c is described below
commit c6166e8cc6811685122939a5445956241c938fc8
Author: Rainer Döbele <[email protected]>
AuthorDate: Thu Oct 24 14:47:58 2024 +0200
EMPIREDB-444
New class ValueUtils to override value type conversion
---
.../org/apache/empire/commons/ObjectUtils.java | 605 ++++--------------
.../commons/{ObjectUtils.java => ValueUtils.java} | 699 ++++-----------------
.../main/java/org/apache/empire/db/DBCmdParam.java | 27 +-
.../java/org/apache/empire/db/DBRecordBase.java | 12 +-
.../main/java/org/apache/empire/db/DBRowSet.java | 2 -
.../java/org/apache/empire/db/DBSQLBuilder.java | 19 +-
6 files changed, 250 insertions(+), 1114 deletions(-)
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
index 03fb6d47..015e0339 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
@@ -18,14 +18,11 @@
*/
package org.apache.empire.commons;
+import java.io.Serializable;
import java.math.BigDecimal;
-import java.math.BigInteger;
import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -35,26 +32,31 @@ import java.util.Locale;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.empire.data.ColumnExpr;
-import org.apache.empire.db.expr.column.DBValueExpr;
+import org.apache.empire.data.DataType;
import org.apache.empire.exceptions.InvalidArgumentException;
-import org.apache.empire.exceptions.InvalidValueException;
-import org.apache.empire.exceptions.ItemNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * This class contains common functions for comparing and converting values of
type Object.
+ * This class contains common functions for comparing and converting values
from and to the database
+ * As well as other useful Array and List related functions.
*
+ * Value and value related conversion functions my be overridden by setting a
customized version of the
+ * ValueUtils object via
+ * setValueUtils(ValueUtils valueUtils)
*/
public final class ObjectUtils
{
+ // Logger
+ private static final Logger log =
LoggerFactory.getLogger(ObjectUtils.class);
+
/**
* This class explicitly defines that an Object has not been assigned a
value.<BR>
* This may be used in cases where the value of null may be a valid value.
*/
- private static final class NoValue // *Deprecated* implements Serializable
+ private static final class NoValue implements Serializable
{
- // *Deprecated* private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
private NoValue()
{ /* dummy */
}
@@ -71,37 +73,28 @@ public final class ObjectUtils
*/
public static final NoValue NO_VALUE = new NoValue();
- // Logger
- private static final Logger log =
LoggerFactory.getLogger(ObjectUtils.class);
-
- private static final String DATE_FORMAT = "yyyy-MM-dd";
- private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
-
- // DateOnly Formatter
- private static final ThreadLocal<SimpleDateFormat> dateOnlyFormatter = new
ThreadLocal<SimpleDateFormat>() {
- @Override
- protected SimpleDateFormat initialValue()
- {
- return new SimpleDateFormat(DATE_FORMAT);
- }
- };
+ /**
+ * The instance of ValueUtils to be used for value type conversion
+ */
+ static private ValueUtils valueUtils = new ValueUtils();
+
+ public static ValueUtils getValueUtils()
+ {
+ return valueUtils;
+ }
- // DateTime Formatter
- private static final ThreadLocal<SimpleDateFormat> dateTimeFormatter = new
ThreadLocal<SimpleDateFormat>() {
- @Override
- protected SimpleDateFormat initialValue()
- {
- return new SimpleDateFormat(DATETIME_FORMAT);
- }
- };
+ public static void setValueUtils(ValueUtils valueUtils)
+ {
+ ObjectUtils.valueUtils = valueUtils;
+ }
- // Interal literal for NULL
- private static final String NULL = "NULL";
-
+ /**
+ * Private Constructor
+ * Static functions only
+ * No instance may be created
+ */
private ObjectUtils()
{
- // Static Function only
- // No instance may be created
}
/**
@@ -112,20 +105,7 @@ public final class ObjectUtils
*/
public static boolean isEmpty(Object o)
{
- if (o==null)
- return true;
- if (o==NO_VALUE)
- throw new InvalidValueException(o);
- if ((o instanceof String) && ((String)o).length()==0)
- return true;
- if ((o instanceof Object[]) && ((Object[])o).length==0)
- return true;
- if ((o instanceof Collection<?>) && ((Collection<?>)o).isEmpty())
- return true;
- if (o instanceof DBValueExpr)
- return isEmpty(((DBValueExpr)o).getValue());
- // not empty
- return false;
+ return valueUtils.isEmpty(o);
}
/**
@@ -146,18 +126,7 @@ public final class ObjectUtils
*/
public static boolean isZero(Number value)
{
- if (value==null)
- return true;
- if (value instanceof BigDecimal)
- return (BigDecimal.ZERO.compareTo((BigDecimal)value) == 0);
- if (value instanceof Float)
- return (((Float) value).compareTo(0.0f)==0);
- if (value instanceof Double)
- return (((Double) value).compareTo(0.0d)==0);
- if (value instanceof Long)
- return (value.longValue()==0l);
- // default: check int value
- return (value.intValue()==0);
+ return valueUtils.isZero(value);
}
/**
@@ -177,12 +146,7 @@ public final class ObjectUtils
*/
public static int lengthOf(Object o)
{
- if (o==null || o==NO_VALUE)
- return 0;
- if ((o instanceof String))
- return ((String)o).length();
- // convert
- return o.toString().length();
+ return valueUtils.lengthOf(o);
}
/**
@@ -193,113 +157,9 @@ public final class ObjectUtils
*
* @return true if both objects are equal or false otherwise
*/
- @SuppressWarnings("unchecked")
public static boolean compareEqual(Object o1, Object o2)
{
- // simple case
- if (o1==o2)
- return true;
- // Check for Empty Values
- if (isEmpty(o1))
- return isEmpty(o2);
- if (isEmpty(o2))
- return isEmpty(o1);
- // Check classes
- if (o1.getClass().equals(o2.getClass()))
- { // Check simple array
- if ((o1 instanceof Object[]) && (o2 instanceof Object[]))
- return compareEqual((Object[])o1, (Object[])o2);
- // Check if object implements comparable
- if (o1 instanceof Comparable)
- return (((Comparable<Object>)o1).compareTo(o2)==0);
- else
- return o1.equals(o2);
- }
- // Classes don't match
- // Use equal check first
- if (o1.equals(o2) || o2.equals(o1))
- return true;
- // Compare Numbers
- if (o1 instanceof Number && o2 instanceof Number)
- { // boolean test = obj1.equals(obj2);
- double d1 = ((Number)o1).doubleValue();
- double d2 = ((Number)o2).doubleValue();
- return (d1==d2);
- }
- // Compare Date with LocalDate / LocalDateTime
- if (o1 instanceof Temporal && o2 instanceof Date)
- { // swap
- Object tmp = o2; o2 = o1; o1 = tmp;
- }
- if (o1 instanceof Date && o2 instanceof LocalDate)
- return o1.equals(DateUtils.toDate((LocalDate)o2));
- if (o1 instanceof Date && o2 instanceof LocalDateTime)
- return o1.equals(DateUtils.toDate((LocalDateTime)o2));
- // Enum
- if (o1 instanceof Enum<?>)
- { // Special enum handling
- if (o2 instanceof Number)
- return ((Enum<?>)o1).ordinal()==((Number)o2).intValue();
- // Compare Strings
- String strVal = StringUtils.coalesce(getString((Enum<?>)o1), NULL);
- return strVal.equals(getString(o2));
- }
- else if (o2 instanceof Enum<?>)
- { // Special enum handling
- if (o1 instanceof Number)
- return ((Enum<?>)o2).ordinal()==((Number)o1).intValue();
- // Compare Strings
- String strVal = StringUtils.coalesce(getString((Enum<?>)o2),
NULL);
- return strVal.equals(getString(o1));
- }
- // Compare Strings
- if (o1 instanceof String)
- return ((String)o1).equals(o2.toString());
- if (o2 instanceof String)
- return ((String)o2).equals(o1.toString());
- // Not equal
- return false;
- }
-
- /**
- * Compares two arrays for equality
- *
- * @param array1 the first array
- * @param array2 the second array
- *
- * @return true if both arrays are equal or false otherwise
- */
- public static boolean compareEqual(Object[] array1, Object[] array2)
- { // Compare Length
- int len1 = (array1!=null ? array1.length : 0);
- int len2 = (array2!=null ? array2.length : 0);
- if (len1!= len2)
- return false;
- // Compare Key Values
- for (int i = 0; i < len1; i++)
- { // Check String Values
- if (!ObjectUtils.compareEqual(array1[i], array2[i]))
- return false;
- }
- return true;
- }
-
- /**
- * Compares two ColumnExpr for equality
- *
- * @param expr a column expression
- * @param other a column expression
- *
- * @return true if both expressions are equal or false otherwise
- */
- public static boolean compareEqual(ColumnExpr expr, ColumnExpr other)
- {
- if (isWrapper(other) && !isWrapper(expr))
- return expr.equals(unwrap(other));
- else if (!isWrapper(other) && isWrapper(expr))
- return unwrap(expr).equals(other);
- // both wrapped or both unwrapped
- return expr.equals(other);
+ return valueUtils.compareEqual(o1, o2);
}
/**
@@ -310,46 +170,9 @@ public final class ObjectUtils
*
* @return true if both objects are equal or false otherwise
*/
- @SuppressWarnings("unchecked")
public static int compare(Object o1, Object o2)
{
- // simple case
- if (o1==o2)
- return 0;
- // Check for Empty Values
- if (isEmpty(o1))
- return isEmpty(o2) ? 0 : -1;
- if (isEmpty(o2))
- return isEmpty(o1) ? 0 : 1;
- // Check classes
- if (o1.getClass().equals(o2.getClass()))
- { // Check if object implements comparable
- if (o1 instanceof Comparable)
- return ((Comparable<Object>)o1).compareTo(o2);
- if (o2 instanceof Comparable)
- return ((Comparable<Object>)o2).compareTo(o1);
- }
- // Use equal check first
- if (o1.equals(o2) || o2.equals(o1))
- return 0;
- // Compare Numbers
- if (o1 instanceof Number && o2 instanceof Number)
- { // boolean test = obj1.equals(obj2);
- double d1 = ((Number)o1).doubleValue();
- double d2 = ((Number)o2).doubleValue();
- return ((d1<d2) ? -1 : ((d1>d2) ? 1 : 0));
- }
- // Compare Date with LocalDate / LocalDateTime
- if (o1 instanceof Temporal && o2 instanceof Date)
- { // swap
- Object tmp = o2; o2 = o1; o1 = tmp;
- }
- if (o1 instanceof Date && o2 instanceof LocalDate)
- return compare(o1, DateUtils.toDate((LocalDate)o2));
- if (o1 instanceof Date && o2 instanceof LocalDateTime)
- return compare(o1, DateUtils.toDate((LocalDateTime)o2));
- // Compare Strings
- return o1.toString().compareTo(o2.toString());
+ return valueUtils.compare(o1, o2);
}
/**
@@ -371,13 +194,7 @@ public final class ObjectUtils
*/
public static int toInteger(Object v)
{
- if (ObjectUtils.isEmpty(v))
- return 0;
- if (v instanceof Number)
- return ((Number)v).intValue();
- // Try to convert
- String str = v.toString();
- return Integer.parseInt(str);
+ return valueUtils.toInteger(v);
}
/**
@@ -397,7 +214,7 @@ public final class ObjectUtils
{ // Try to convert
return toInteger(v);
} catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to int", v));
+ log.error(String.format("Cannot convert value [%s] to int", v));
return defValue;
}
}
@@ -421,13 +238,7 @@ public final class ObjectUtils
*/
public static long toLong(Object v)
{
- if (ObjectUtils.isEmpty(v))
- return 0;
- if (v instanceof Number)
- return ((Number)v).longValue();
- // Try to convert
- String str = v.toString();
- return Long.parseLong(str);
+ return valueUtils.toLong(v);
}
/**
@@ -447,7 +258,7 @@ public final class ObjectUtils
{ // Try to convert
return toLong(v);
} catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to long",
v));
+ log.error(String.format("Cannot convert value [%s] to long", v));
return defValue;
}
}
@@ -471,14 +282,7 @@ public final class ObjectUtils
*/
public static double toDouble(Object v)
{
- // Get Double value
- if (ObjectUtils.isEmpty(v))
- return 0.0;
- if (v instanceof Number)
- return ((Number)v).doubleValue();
- // parse String for Integer value
- String val = v.toString();
- return Double.parseDouble(val);
+ return valueUtils.toDouble(v);
}
/**
@@ -522,26 +326,7 @@ public final class ObjectUtils
*/
public static BigDecimal toDecimal(Object v)
{
- // Get Double value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof BigDecimal)
- return ((BigDecimal)v);
- // Find a suitable converter
- if (v instanceof Number)
- { // check other number types
- if (v instanceof BigInteger)
- return new BigDecimal((BigInteger)v);
- if (v instanceof Integer)
- return BigDecimal.valueOf(((Number)v).intValue());
- if (v instanceof Long)
- return BigDecimal.valueOf(((Number)v).longValue());
- // Default: convert via double
- return BigDecimal.valueOf(((Number)v).doubleValue());
- }
- // parse String for Integer value
- // Last-Chance > Try a string conversion
- return new BigDecimal(v.toString());
+ return valueUtils.toDecimal(v);
}
/**
@@ -590,21 +375,7 @@ public final class ObjectUtils
*/
public static boolean getBoolean(Object v, boolean defValue)
{
- // Get Boolean value
- if (ObjectUtils.isEmpty(v))
- return defValue;
- if (v instanceof Boolean)
- return ((Boolean)v).booleanValue();
- if (v instanceof Number)
- return (((Number)v).intValue()!=0);
- if (v instanceof String) {
- String val = ((String)v);
- if (StringUtils.isEmpty(val))
- return defValue;
- // check for allowed true values
- return (val.equalsIgnoreCase("true") || val.equalsIgnoreCase("Y"));
- }
- return defValue;
+ return valueUtils.getBoolean(v, defValue);
}
/**
@@ -625,52 +396,9 @@ public final class ObjectUtils
* @param value the value to convert
* @return the enum
*/
- @SuppressWarnings("unchecked")
public static <T extends Enum<?>> T getEnum(Class<T> enumType, Object
value)
- { // check for null
- if (isEmpty(value))
- return null;
- // check enum
- if (value instanceof Enum<?>)
- { // already an enum: Check type
- if (value.getClass().equals(enumType))
- return (T)value;
- // try to match names
- value = ((Enum<?>)value).name();
- }
- // check column data type
- boolean numeric = (value instanceof Number);
- T[] items = enumType.getEnumConstants();
- if (items.length>0 && (items[0] instanceof EnumValue))
- { // custom conversion
- for (T e : items)
- {
- Object eVal = ((EnumValue)e).toValue(numeric);
- if (ObjectUtils.compareEqual(eVal, value))
- return e;
- }
- // error: not found
- throw new ItemNotFoundException(StringUtils.toString(value));
- }
- else if (numeric)
- { // by ordinal
- int ordinal = ((Number)value).intValue();
- // check range
- if (ordinal<0 || ordinal>=items.length)
- throw new ItemNotFoundException(String.valueOf(ordinal));
- // return enum
- return items[ordinal];
- }
- else
- { // by name
- String name = StringUtils.toString(value);
- // find name
- for (T e : items)
- if (e.name().equals(name))
- return e;
- // error: not found
- throw new ItemNotFoundException(name);
- }
+ {
+ return valueUtils.getEnum(enumType, value);
}
/**
@@ -681,16 +409,8 @@ public final class ObjectUtils
* @return the enum
*/
public static <T extends Enum<?>> T getEnumByName(Class<T> enumType,
String name)
- { // check for null
- if (isEmpty(name))
- return null;
- // check column data type
- T[] items = enumType.getEnumConstants();
- for (T e : items)
- if (e.name().equals(name))
- return e;
- // error: not found
- throw new ItemNotFoundException(name);
+ {
+ return valueUtils.getEnumByName(enumType, name);
}
/**
@@ -701,11 +421,7 @@ public final class ObjectUtils
*/
public static Object getEnumValue(Enum<?> enumValue, boolean isNumeric)
{
- // convert
- if (enumValue instanceof EnumValue)
- return ((EnumValue)enumValue).toValue(isNumeric);
- // default
- return (isNumeric ? enumValue.ordinal() : getString(enumValue));
+ return valueUtils.getEnumValue(enumValue, isNumeric);
}
/**
@@ -715,14 +431,7 @@ public final class ObjectUtils
*/
public static String getString(Enum<?> enumValue)
{
- // convert
- if (enumValue instanceof EnumValue)
- return StringUtils.toString(((EnumValue)enumValue).toValue(false));
- /* special case */
- if (enumValue==null || enumValue.name().equals(NULL))
- return null;
- /* use name */
- return enumValue.name();
+ return valueUtils.getString(enumValue);
}
/**
@@ -732,19 +441,7 @@ public final class ObjectUtils
*/
public static String getString(Object value)
{
- if (value==null)
- return null;
- if (value instanceof String)
- return (String)value;
- if (value==NO_VALUE)
- throw new InvalidValueException(value);
- // convert
- if (value instanceof Enum<?>)
- return getString((Enum<?>)value);
- if (value instanceof Date)
- return formatDate((Date)value, true);
- // default
- return value.toString();
+ return valueUtils.getString(value);
}
/**
@@ -757,21 +454,7 @@ public final class ObjectUtils
public static Date toDate(Object v)
throws ParseException
{
- // Get DateTime value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof java.util.Date)
- return ((java.util.Date)v);
- if (v instanceof java.time.LocalDate)
- return DateUtils.toDate((LocalDate)v);
- if (v instanceof java.time.LocalDateTime)
- return DateUtils.toDate((LocalDateTime)v);
- // Convert from String
- String str = v.toString();
- if (str.length() > 10)
- return dateTimeFormatter.get().parse(str);
- else
- return dateOnlyFormatter.get().parse(str);
+ return valueUtils.toDate(v);
}
/**
@@ -784,35 +467,7 @@ public final class ObjectUtils
*/
public static Date getDate(Object v, Locale locale)
{
- // Get DateTime value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof Date)
- return ((Date)v);
- if (v instanceof java.time.LocalDate)
- return DateUtils.toDate((LocalDate)v);
- if (v instanceof java.time.LocalDateTime)
- return DateUtils.toDate((LocalDateTime)v);
- // Get Calendar
- if (v instanceof Number)
- { // Get Date from a number
- long l = ((Number)v).longValue();
- if (l==0)
- return DateUtils.getDateNow();
- // Year or full date/time?
- /*
- if (l<10000)
- { // Year only
- Calendar calendar =
Calendar.getInstance(getSafeLocale(locale));
- calendar.set((int)l, 1, 1);
- return calendar.getTime();
- }
- */
- // Date from long
- return new Date(l);
- }
- // Try to parse
- return DateUtils.parseDate(v.toString(), locale);
+ return valueUtils.getDate(v, locale);
}
/**
@@ -823,26 +478,7 @@ public final class ObjectUtils
*/
public static Date getDate(Object v)
{
- // Get DateTime value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof java.util.Date)
- return ((java.util.Date)v);
- if (v instanceof java.time.LocalDate)
- return DateUtils.toDate((LocalDate)v);
- if (v instanceof java.time.LocalDateTime)
- return DateUtils.toDate((LocalDateTime)v);
- // Convert from String
- String str = v.toString();
- try
- { if (str.length() > 10)
- return dateTimeFormatter.get().parse(str);
- else
- return dateOnlyFormatter.get().parse(str);
- } catch (ParseException e) {
- log.error(String.format("Cannot convert value [%s] to Date", str),
e);
- return null;
- }
+ return valueUtils.getDate(v);
}
/**
@@ -853,28 +489,7 @@ public final class ObjectUtils
*/
public static LocalDate getLocalDate(Object v)
{
- // Get DateTime value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof java.time.LocalDate)
- return (LocalDate)v;
- if (v instanceof java.time.LocalDateTime)
- return ((LocalDateTime)v).toLocalDate();
- if (v instanceof java.sql.Timestamp)
- return ((java.sql.Timestamp)v).toLocalDateTime().toLocalDate();
- if (v instanceof java.sql.Date)
- return ((java.sql.Date)v).toLocalDate();
- if (v instanceof java.util.Date)
- return DateUtils.toLocalDate((Date)v);
- // Convert from String
- String str = v.toString();
- try
- { // DateTimeFormatter ISO_LOCAL_DATE
- return LocalDate.parse(str);
- } catch (DateTimeParseException e) {
- log.error(String.format("Cannot convert value [%s] to LocalDate",
str), e);
- return null;
- }
+ return valueUtils.getLocalDate(v);
}
/**
@@ -885,28 +500,7 @@ public final class ObjectUtils
*/
public static LocalDateTime getLocalDateTime(Object v)
{
- // Get DateTime value
- if (ObjectUtils.isEmpty(v))
- return null;
- if (v instanceof java.time.LocalDate)
- return ((LocalDate)v).atStartOfDay();
- if (v instanceof java.time.LocalDateTime)
- return (LocalDateTime)v;
- if (v instanceof java.sql.Timestamp)
- return ((java.sql.Timestamp)v).toLocalDateTime();
- if (v instanceof java.sql.Date)
- return ((java.sql.Date)v).toLocalDate().atStartOfDay();
- if (v instanceof java.util.Date)
- return DateUtils.toLocalDateTime((Date)v);
- // Convert from String
- String str = v.toString();
- try
- { // DateTimeFormatter.ISO_LOCAL_DATE_TIME
- return LocalDateTime.parse(str);
- } catch (DateTimeParseException e) {
- log.error(String.format("Cannot convert value [%s] to
LocalDateTime", str), e);
- return null;
- }
+ return valueUtils.getLocalDateTime(v);
}
/**
@@ -919,12 +513,7 @@ public final class ObjectUtils
*/
public static String formatDate(Date date, boolean withTime)
{
- if (date==null)
- return null;
- if (withTime)
- return dateTimeFormatter.get().format(date);
- else
- return dateOnlyFormatter.get().format(date);
+ return valueUtils.formatDate(date, withTime);
}
/**
@@ -938,39 +527,22 @@ public final class ObjectUtils
*
* @throws ClassCastException if the object is not null and is not
assignable to the type T.
*/
- @SuppressWarnings("unchecked")
public static <T> T convert(Class<T> c, Object v)
throws ClassCastException
{
- if (v==null || c.isInstance(v))
- return (T)v;
- if (v==NO_VALUE)
- throw new InvalidValueException(v);
- // Get Class form Primitive Type
- if (c.isPrimitive())
- { // Get's the Java Class representing the primitive type
- c = (Class<T>) MethodUtils.getPrimitiveWrapper(c);
- }
- // Convert
- if (c.isEnum())
- { // convert to enum
- Object ev = getEnum((Class<? extends Enum<?>>)c, v);
- return (T)ev;
- }
- if (c.isAssignableFrom(Boolean.class))
- return c.cast(getBoolean(v));
- if (c.isAssignableFrom(Integer.class))
- return c.cast(getInteger(v));
- if (c.isAssignableFrom(Long.class))
- return c.cast(getLong(v));
- if(c.isAssignableFrom(Double.class))
- return c.cast(getDouble(v));
- if(c.isAssignableFrom(BigDecimal.class))
- return c.cast(getDecimal(v));
- if (c.isAssignableFrom(String.class))
- return c.cast(v.toString());
- // other
- return c.cast(v);
+ return valueUtils.convert(c, v);
+ }
+
+ /**
+ * Converts a value to a specific DataType
+ * The returned value is used for generating SQL statements
+ * @param dataType the target data type
+ * @param value the value to convert
+ * @return the value to be used in SQL statements
+ */
+ public static Object convertValue(DataType type, Object value)
+ {
+ return valueUtils.convertValue(type, value);
}
/**
@@ -1017,6 +589,47 @@ public final class ObjectUtils
// Not compatible
return false;
}
+
+ /**
+ * Compares two arrays for equality
+ *
+ * @param array1 the first array
+ * @param array2 the second array
+ *
+ * @return true if both arrays are equal or false otherwise
+ */
+ public static boolean compareEqual(Object[] array1, Object[] array2)
+ { // Compare Length
+ int len1 = (array1!=null ? array1.length : 0);
+ int len2 = (array2!=null ? array2.length : 0);
+ if (len1!= len2)
+ return false;
+ // Compare Key Values
+ for (int i = 0; i < len1; i++)
+ { // Check String Values
+ if (!ObjectUtils.compareEqual(array1[i], array2[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compares two ColumnExpr for equality
+ *
+ * @param expr a column expression
+ * @param other a column expression
+ *
+ * @return true if both expressions are equal or false otherwise
+ */
+ public static boolean compareEqual(ColumnExpr expr, ColumnExpr other)
+ {
+ if (isWrapper(other) && !isWrapper(expr))
+ return expr.equals(unwrap(other));
+ else if (!isWrapper(other) && isWrapper(expr))
+ return unwrap(expr).equals(other);
+ // both wrapped or both unwrapped
+ return expr.equals(other);
+ }
/**
* Generic conversion function that will convert a list to another list
type.
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
similarity index 53%
copy from empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
copy to empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
index 03fb6d47..9385365b 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
@@ -26,59 +26,39 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.time.temporal.Temporal;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
-import java.util.List;
import java.util.Locale;
import org.apache.commons.beanutils.MethodUtils;
-import org.apache.empire.data.ColumnExpr;
+import org.apache.empire.data.DataType;
import org.apache.empire.db.expr.column.DBValueExpr;
-import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.InvalidValueException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * This class contains common functions for comparing and converting values of
type Object.
+ * This class allows to customize value type conversion as well as other value
related functions.
+ * The functions and methods are called indirectly via the corresponding
static functions in the ObjectUtils class.
*
+ * You may create your own derived class and overwrite the methods.
+ * In order to activate your ValueUtils implementation use the static function
+ *
+ * OjectUtils.setValueUtils(myValueUtils)
+ *
+ * @author doebele
*/
-public final class ObjectUtils
+public class ValueUtils
{
- /**
- * This class explicitly defines that an Object has not been assigned a
value.<BR>
- * This may be used in cases where the value of null may be a valid value.
- */
- private static final class NoValue // *Deprecated* implements Serializable
- {
- // *Deprecated* private static final long serialVersionUID = 1L;
- private NoValue()
- { /* dummy */
- }
- @Override
- public String toString()
- {
- return "[NO-VALUE]";
- }
- }
-
- /**
- * Constant that defines a object of type NoValue.
- * This may be used in cases where the value of null is a valid value.
- */
- public static final NoValue NO_VALUE = new NoValue();
-
// Logger
- private static final Logger log =
LoggerFactory.getLogger(ObjectUtils.class);
+ private static final Logger log =
LoggerFactory.getLogger(ValueUtils.class);
- private static final String DATE_FORMAT = "yyyy-MM-dd";
- private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
-
+ protected static final String DATE_FORMAT = "yyyy-MM-dd";
+ protected static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
// DateOnly Formatter
- private static final ThreadLocal<SimpleDateFormat> dateOnlyFormatter = new
ThreadLocal<SimpleDateFormat>() {
+ protected static final ThreadLocal<SimpleDateFormat> dateOnlyFormatter =
new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue()
{
@@ -87,21 +67,17 @@ public final class ObjectUtils
};
// DateTime Formatter
- private static final ThreadLocal<SimpleDateFormat> dateTimeFormatter = new
ThreadLocal<SimpleDateFormat>() {
+ protected static final ThreadLocal<SimpleDateFormat> dateTimeFormatter =
new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat(DATETIME_FORMAT);
}
};
-
- // Interal literal for NULL
- private static final String NULL = "NULL";
- private ObjectUtils()
+ protected ValueUtils()
{
- // Static Function only
- // No instance may be created
+ /* subclass to override */
}
/**
@@ -110,11 +86,11 @@ public final class ObjectUtils
* @param o the object to check
* @return true if the Object is null or if its an empty string.
*/
- public static boolean isEmpty(Object o)
+ public boolean isEmpty(Object o)
{
if (o==null)
return true;
- if (o==NO_VALUE)
+ if (o==ObjectUtils.NO_VALUE)
throw new InvalidValueException(o);
if ((o instanceof String) && ((String)o).length()==0)
return true;
@@ -128,23 +104,12 @@ public final class ObjectUtils
return false;
}
- /**
- * Checks whether an object has a value.
- * A Object is considered to have a value if it is not null and not an
empty string
- * @param o the object to check
- * @return true if the Object is neither null nor an empty string.
- */
- public static boolean isNotEmpty(Object o)
- {
- return !isEmpty(o);
- }
-
/**
* Checks whether a number is null or zero
* @param value the number to check
* @return true if the value is null or zero
*/
- public static boolean isZero(Number value)
+ public boolean isZero(Number value)
{
if (value==null)
return true;
@@ -159,31 +124,6 @@ public final class ObjectUtils
// default: check int value
return (value.intValue()==0);
}
-
- /**
- * Checks whether a number is NOT null or zero
- * @param value the number to check
- * @return true if the value is NOT null or zero
- */
- public static boolean isNonZero(Number value)
- {
- return !isZero(value);
- }
-
- /**
- * returns the string length of an object
- * @param o the object to check
- * @return the string length of the object
- */
- public static int lengthOf(Object o)
- {
- if (o==null || o==NO_VALUE)
- return 0;
- if ((o instanceof String))
- return ((String)o).length();
- // convert
- return o.toString().length();
- }
/**
* Compares two objects for equality
@@ -194,11 +134,11 @@ public final class ObjectUtils
* @return true if both objects are equal or false otherwise
*/
@SuppressWarnings("unchecked")
- public static boolean compareEqual(Object o1, Object o2)
+ public boolean compareEqual(Object o1, Object o2)
{
- // simple case
- if (o1==o2)
- return true;
+ // simple case
+ if (o1==o2)
+ return true;
// Check for Empty Values
if (isEmpty(o1))
return isEmpty(o2);
@@ -208,7 +148,7 @@ public final class ObjectUtils
if (o1.getClass().equals(o2.getClass()))
{ // Check simple array
if ((o1 instanceof Object[]) && (o2 instanceof Object[]))
- return compareEqual((Object[])o1, (Object[])o2);
+ return compareEqual(o1, o2);
// Check if object implements comparable
if (o1 instanceof Comparable)
return (((Comparable<Object>)o1).compareTo(o2)==0);
@@ -241,7 +181,7 @@ public final class ObjectUtils
if (o2 instanceof Number)
return ((Enum<?>)o1).ordinal()==((Number)o2).intValue();
// Compare Strings
- String strVal = StringUtils.coalesce(getString((Enum<?>)o1), NULL);
+ String strVal = StringUtils.coalesce(getString((Enum<?>)o1),
StringUtils.NULL);
return strVal.equals(getString(o2));
}
else if (o2 instanceof Enum<?>)
@@ -249,7 +189,7 @@ public final class ObjectUtils
if (o1 instanceof Number)
return ((Enum<?>)o2).ordinal()==((Number)o1).intValue();
// Compare Strings
- String strVal = StringUtils.coalesce(getString((Enum<?>)o2),
NULL);
+ String strVal = StringUtils.coalesce(getString((Enum<?>)o2),
StringUtils.NULL);
return strVal.equals(getString(o1));
}
// Compare Strings
@@ -260,47 +200,6 @@ public final class ObjectUtils
// Not equal
return false;
}
-
- /**
- * Compares two arrays for equality
- *
- * @param array1 the first array
- * @param array2 the second array
- *
- * @return true if both arrays are equal or false otherwise
- */
- public static boolean compareEqual(Object[] array1, Object[] array2)
- { // Compare Length
- int len1 = (array1!=null ? array1.length : 0);
- int len2 = (array2!=null ? array2.length : 0);
- if (len1!= len2)
- return false;
- // Compare Key Values
- for (int i = 0; i < len1; i++)
- { // Check String Values
- if (!ObjectUtils.compareEqual(array1[i], array2[i]))
- return false;
- }
- return true;
- }
-
- /**
- * Compares two ColumnExpr for equality
- *
- * @param expr a column expression
- * @param other a column expression
- *
- * @return true if both expressions are equal or false otherwise
- */
- public static boolean compareEqual(ColumnExpr expr, ColumnExpr other)
- {
- if (isWrapper(other) && !isWrapper(expr))
- return expr.equals(unwrap(other));
- else if (!isWrapper(other) && isWrapper(expr))
- return unwrap(expr).equals(other);
- // both wrapped or both unwrapped
- return expr.equals(other);
- }
/**
* Compares two objects for equality
@@ -311,7 +210,7 @@ public final class ObjectUtils
* @return true if both objects are equal or false otherwise
*/
@SuppressWarnings("unchecked")
- public static int compare(Object o1, Object o2)
+ public int compare(Object o1, Object o2)
{
// simple case
if (o1==o2)
@@ -351,27 +250,15 @@ public final class ObjectUtils
// Compare Strings
return o1.toString().compareTo(o2.toString());
}
-
- /**
- * Checks whether a preferred value is valid and returns an alternative
value if not.
- * @param <T> the type of the values
- * @param preferred the preferred return value
- * @param alternative the alternative return value used if the preferred
value is null
- * @return the preferred value if it is not null or the alternative value
otherwise
- */
- public static <T> T coalesce(T preferred, T alternative)
- {
- return (preferred!=null ? preferred : alternative);
- }
/**
* converts an object to an integer. If conversion is not possible, an
error is thrown
* @param v the value to convert
* @return the integer value
*/
- public static int toInteger(Object v)
+ public int toInteger(Object v)
{
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return 0;
if (v instanceof Number)
return ((Number)v).intValue();
@@ -379,49 +266,15 @@ public final class ObjectUtils
String str = v.toString();
return Integer.parseInt(str);
}
-
- /**
- * Converts an object value to an integer.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then the default value is returned.
- * @param v the obect to convert
- * @param defValue the default value if o is null or conversion is not
possible
- * @return the Integer value of o or a default value
- */
- public static int getInteger(Object v, int defValue)
- {
- // Check empty
- if (ObjectUtils.isEmpty(v))
- return defValue;
- try
- { // Try to convert
- return toInteger(v);
- } catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to int", v));
- return defValue;
- }
- }
-
- /**
- * Converts an object value to an integer.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then 0 is returned.
- * @param v the object value to convert
- * @return the Integer value of o or 0
- */
- public static int getInteger(Object v)
- {
- return getInteger(v, 0);
- }
/**
* converts an object to a long. If conversion is not possible, an error
is thrown
* @param v the value to convert
* @return the long value
*/
- public static long toLong(Object v)
+ public long toLong(Object v)
{
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return 0;
if (v instanceof Number)
return ((Number)v).longValue();
@@ -429,50 +282,16 @@ public final class ObjectUtils
String str = v.toString();
return Long.parseLong(str);
}
-
- /**
- * Converts an object value to a long.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then the default value is returned.
- * @param v the obect to convert
- * @param defValue the default value if o is null or conversion is not
possible
- * @return the Integer value of o or a default value
- */
- public static long getLong(Object v, long defValue)
- {
- // Check empty
- if (ObjectUtils.isEmpty(v))
- return defValue;
- try
- { // Try to convert
- return toLong(v);
- } catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to long",
v));
- return defValue;
- }
- }
-
- /**
- * Converts an object value to a long.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then 0 is returned.
- * @param v the object value to convert
- * @return the Long value of o or 0
- */
- public static long getLong(Object v)
- {
- return getLong(v, 0);
- }
/**
* converts an object to a double. If conversion is not possible, an error
is thrown
* @param v the value to convert
* @return the double value
*/
- public static double toDouble(Object v)
+ public double toDouble(Object v)
{
// Get Double value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return 0.0;
if (v instanceof Number)
return ((Number)v).doubleValue();
@@ -480,50 +299,16 @@ public final class ObjectUtils
String val = v.toString();
return Double.parseDouble(val);
}
-
- /**
- * Converts an object value to a double.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then defValue is returned.
- * @param v the object value to convert
- * @param defValue the default value
- * @return the Long value of o or defValue
- */
- public static double getDouble(Object v, double defValue)
- {
- // Check empty
- if (ObjectUtils.isEmpty(v))
- return defValue;
- try
- { // Try to convert
- return toDouble(v);
- } catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to double", v));
- return defValue;
- }
- }
-
- /**
- * Converts an object value to a double.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then 0.0 is returned.
- * @param v the object value to convert
- * @return the Long value of o or 0
- */
- public static double getDouble(Object v)
- {
- return getDouble(v, 0.0);
- }
/**
* converts an object to a decimal. If conversion is not possible, an
error is thrown
* @param v the value to convert
* @return the decimal value
*/
- public static BigDecimal toDecimal(Object v)
+ public BigDecimal toDecimal(Object v)
{
// Get Double value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof BigDecimal)
return ((BigDecimal)v);
@@ -544,40 +329,6 @@ public final class ObjectUtils
return new BigDecimal(v.toString());
}
- /**
- * Converts an object value to a BigDecimal.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then defValue is returned.
- * @param v the object value to convert
- * @param defValue the default value
- * @return the BigDecimal value of v or defValue
- */
- public static BigDecimal getDecimal(Object v, BigDecimal defValue)
- {
- // Check empty
- if (ObjectUtils.isEmpty(v))
- return defValue;
- try
- { // Try to convert
- return toDecimal(v);
- } catch (NumberFormatException e) {
- log.error(String.format("Cannot convert value [%s] to BigDecimal",
v));
- return defValue;
- }
- }
-
- /**
- * Converts an object value to a BigDecimal.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then 0.0 is returned.
- * @param v the object value to convert
- * @return the Long value of o or 0
- */
- public static BigDecimal getDecimal(Object v)
- {
- return getDecimal(v, BigDecimal.ZERO);
- }
-
/**
* Converts an object value to a boolean.
* <P>
@@ -588,10 +339,10 @@ public final class ObjectUtils
* @param defValue the default value
* @return the boolean value or defValue if v is null or empty
*/
- public static boolean getBoolean(Object v, boolean defValue)
+ public boolean getBoolean(Object v, boolean defValue)
{
// Get Boolean value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return defValue;
if (v instanceof Boolean)
return ((Boolean)v).booleanValue();
@@ -607,17 +358,6 @@ public final class ObjectUtils
return defValue;
}
- /**
- * Converts an object value to a boolean.
- * see getBoolean(Object v, boolean defValue) for details.
- * @param v the object to convert
- * @return the boolean value or false if v is null or empty
- */
- public static boolean getBoolean(Object v)
- {
- return getBoolean(v, false);
- }
-
/**
* Converts an object to an enum of the given type
* @param <T> the type of the enum
@@ -626,7 +366,7 @@ public final class ObjectUtils
* @return the enum
*/
@SuppressWarnings("unchecked")
- public static <T extends Enum<?>> T getEnum(Class<T> enumType, Object
value)
+ public <T extends Enum<?>> T getEnum(Class<T> enumType, Object value)
{ // check for null
if (isEmpty(value))
return null;
@@ -646,7 +386,7 @@ public final class ObjectUtils
for (T e : items)
{
Object eVal = ((EnumValue)e).toValue(numeric);
- if (ObjectUtils.compareEqual(eVal, value))
+ if (compareEqual(eVal, value))
return e;
}
// error: not found
@@ -680,7 +420,7 @@ public final class ObjectUtils
* @param name the enum name
* @return the enum
*/
- public static <T extends Enum<?>> T getEnumByName(Class<T> enumType,
String name)
+ public <T extends Enum<?>> T getEnumByName(Class<T> enumType, String name)
{ // check for null
if (isEmpty(name))
return null;
@@ -699,7 +439,7 @@ public final class ObjectUtils
* @param isNumeric flag if number or string is required
* @return the number or string representing this enum
*/
- public static Object getEnumValue(Enum<?> enumValue, boolean isNumeric)
+ public Object getEnumValue(Enum<?> enumValue, boolean isNumeric)
{
// convert
if (enumValue instanceof EnumValue)
@@ -713,13 +453,13 @@ public final class ObjectUtils
* @param enumValue the enum
* @return the corresponding string value
*/
- public static String getString(Enum<?> enumValue)
+ public String getString(Enum<?> enumValue)
{
// convert
if (enumValue instanceof EnumValue)
return StringUtils.toString(((EnumValue)enumValue).toValue(false));
/* special case */
- if (enumValue==null || enumValue.name().equals(NULL))
+ if (enumValue==null || enumValue.name().equals(StringUtils.NULL))
return null;
/* use name */
return enumValue.name();
@@ -730,13 +470,13 @@ public final class ObjectUtils
* @param value the value to convert
* @return the corresponding string value
*/
- public static String getString(Object value)
+ public String getString(Object value)
{
if (value==null)
return null;
if (value instanceof String)
return (String)value;
- if (value==NO_VALUE)
+ if (value==ObjectUtils.NO_VALUE)
throw new InvalidValueException(value);
// convert
if (value instanceof Enum<?>)
@@ -747,6 +487,21 @@ public final class ObjectUtils
return value.toString();
}
+ /**
+ * returns the string length of an object
+ * @param o the object to check
+ * @return the string length of the object
+ */
+ public int lengthOf(Object o)
+ {
+ if (o==null || o==ObjectUtils.NO_VALUE)
+ return 0;
+ if ((o instanceof String))
+ return ((String)o).length();
+ // convert
+ return o.toString().length();
+ }
+
/**
* Converts an object value to a Date.
* <P>
@@ -754,11 +509,11 @@ public final class ObjectUtils
* @return the Date value of o or null
* @throws ParseException
*/
- public static Date toDate(Object v)
+ public Date toDate(Object v)
throws ParseException
{
// Get DateTime value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof java.util.Date)
return ((java.util.Date)v);
@@ -782,10 +537,10 @@ public final class ObjectUtils
* @param locale the locale used for conversion
* @return the Date value of o or null
*/
- public static Date getDate(Object v, Locale locale)
+ public Date getDate(Object v, Locale locale)
{
// Get DateTime value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof Date)
return ((Date)v);
@@ -821,10 +576,10 @@ public final class ObjectUtils
* @param v the object to convert
* @return the Date value of o or null
*/
- public static Date getDate(Object v)
+ public Date getDate(Object v)
{
// Get DateTime value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof java.util.Date)
return ((java.util.Date)v);
@@ -851,10 +606,10 @@ public final class ObjectUtils
* @param v the object to convert
* @return the Date value of o or null
*/
- public static LocalDate getLocalDate(Object v)
+ public LocalDate getLocalDate(Object v)
{
// Get DateTime value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof java.time.LocalDate)
return (LocalDate)v;
@@ -883,10 +638,10 @@ public final class ObjectUtils
* @param v the object to convert
* @return the Date value of o or null
*/
- public static LocalDateTime getLocalDateTime(Object v)
+ public LocalDateTime getLocalDateTime(Object v)
{
// Get DateTime value
- if (ObjectUtils.isEmpty(v))
+ if (isEmpty(v))
return null;
if (v instanceof java.time.LocalDate)
return ((LocalDate)v).atStartOfDay();
@@ -917,34 +672,35 @@ public final class ObjectUtils
* @param withTime indicates whether the date string should include the
time or not
* @return the date string
*/
- public static String formatDate(Date date, boolean withTime)
+ public String formatDate(Date date, boolean withTime)
{
if (date==null)
return null;
- if (withTime)
- return dateTimeFormatter.get().format(date);
- else
- return dateOnlyFormatter.get().format(date);
+ if (withTime)
+ return dateTimeFormatter.get().format(date);
+ else
+ return dateOnlyFormatter.get().format(date);
}
/**
* Generic conversion function that will convert a object to another value
type.
+ * This function is intended to be used for converting values coming from
the database
+ * to be used by the program
*
- * @param <T> the type to convert to
* @param c the class type to convert to
- * @param v the object to convert
+ * @param v the value to convert
*
- * @return the Date value of o or null
+ * @return the converted value
*
* @throws ClassCastException if the object is not null and is not
assignable to the type T.
*/
@SuppressWarnings("unchecked")
- public static <T> T convert(Class<T> c, Object v)
+ public <T> T convert(Class<T> c, Object v)
throws ClassCastException
{
if (v==null || c.isInstance(v))
return (T)v;
- if (v==NO_VALUE)
+ if (v==ObjectUtils.NO_VALUE)
throw new InvalidValueException(v);
// Get Class form Primitive Type
if (c.isPrimitive())
@@ -958,267 +714,66 @@ public final class ObjectUtils
return (T)ev;
}
if (c.isAssignableFrom(Boolean.class))
- return c.cast(getBoolean(v));
+ return c.cast(getBoolean(v, false));
if (c.isAssignableFrom(Integer.class))
- return c.cast(getInteger(v));
+ return c.cast(isEmpty(v) ? 0 : toInteger(v));
if (c.isAssignableFrom(Long.class))
- return c.cast(getLong(v));
+ return c.cast(isEmpty(v) ? 0 : toLong(v));
if(c.isAssignableFrom(Double.class))
- return c.cast(getDouble(v));
+ return c.cast(isEmpty(v) ? 0.0f : toDouble(v));
if(c.isAssignableFrom(BigDecimal.class))
- return c.cast(getDecimal(v));
+ return c.cast(isEmpty(v) ? BigDecimal.ZERO : toDecimal(v));
if (c.isAssignableFrom(String.class))
- return c.cast(v.toString());
+ return c.cast(getString(v));
// other
return c.cast(v);
}
/**
- * Checks if a class is assignment compatible with another class
- * @param target the target class
- * @param source the source class
- * @return true if assignment compatible or false otherwise
- */
- public static boolean isAssignmentCompatible(Class<?> target, Class<?>
source)
- {
- // try plain assignment
- if (target.isAssignableFrom(source))
- return true;
- // Get Class form Primitive Type
- if (source.isPrimitive())
- { // Get's the Java Class representing the primitive type
- source = MethodUtils.getPrimitiveWrapper(source);
- if (source == null)
- return false;
- if (target.isAssignableFrom(source))
- return true;
- }
- // Get Class form Primitive Type
- if (target.isPrimitive())
- { // Get's the Java Class representing the primitive type
- target = MethodUtils.getPrimitiveWrapper(target);
- if (target == null)
- return false;
- if (target.isAssignableFrom(source))
- return true;
- }
- // Assume all numeric types can be converted to target class
- Class<Number> numberClass = Number.class;
- if (numberClass.isAssignableFrom(target) &&
- numberClass.isAssignableFrom(source))
- { // Both are numeric
- return true;
- }
- // Special case: Allow character to string assignment
- if (source==Character.class && target==String.class)
- {
- return true;
- }
- // Not compatible
- return false;
- }
-
- /**
- * Generic conversion function that will convert a list to another list
type.
- *
- * @param <T> the type of elements
- * @param t the type class
- * @param source the source collection
- *
- * @return the new list type
- */
- public static <T> List<T> convert(Class<T> t, Collection<? extends T>
source)
- {
- if (source==null)
- return null;
- List<T> target = new ArrayList<T>(source.size());
- target.addAll(source);
- return target;
- }
-
- /**
- * Converts varArgs to an array
- *
- * @param <T> the type of elements
- * @param t the type of the array
- * @param values the array values
- *
- * @return the array
- */
- @SafeVarargs
- public static <T> T[] toArray(Class<T> t, T... values)
- {
- if (values.length==0)
- throw new InvalidArgumentException("values", values);
- return values;
- }
-
- /**
- * Converts an array to a list
- *
- * @param <T> the type of elements
- * @param t the type of the list items
- * @param array the array to be converted
- *
- * @return the list
- */
- public static <T> List<T> arrayToList(Class<T> t, T[] array)
- {
- if (array==null)
- return null;
- List<T> list = new ArrayList<T>(array.length);
- for (int i=0; i<array.length; i++)
- list.add(array[i]);
- return list;
- }
-
- /**
- * Converts an Object array to a String array.
- * @param objArray the object array to convert
- * @param defValue default value which will be set for all null objects
- * @return the String array
+ * Converts a value to a specific DataType
+ * The returned value is used for generating SQL statements
+ * @param dataType the target data type
+ * @param value the value to convert
+ * @return the value to be used in SQL statements
*/
- public static String[] toStringArray(Object[] objArray, String defValue)
+ public Object convertValue(DataType dataType, Object value)
{
- if (objArray==null)
+ // check null
+ if (value == null)
return null;
- String[] strArray = new String[objArray.length];
- for (int i=0; i<objArray.length; i++)
- {
- if (objArray[i]!=null)
- strArray[i]=objArray[i].toString();
- else
- strArray[i]=defValue;
- }
- return strArray;
- }
-
- /**
- * Checks whether a object implements the Unwrappable interface and is
also a wrapper
- * If the object does not Implement the Interface or is not a wrapper then
false is returned
- * @param object the object to check
- * @return true if the object is a wrapper or false otherwise
- */
- public static boolean isWrapper(Object object)
- {
- return ((object instanceof Unwrappable<?>)) &&
((Unwrappable<?>)object).isWrapper();
- }
-
- /**
- * Unwraps an object implementing the Unwrappable interface
- * If the object does not Implement the Interface or is not a wrapper then
the object itself is returned
- * @param <T> the type of the object
- * @param object the object to unwrap
- * @return the unwrapped object or the object itself
- */
- @SuppressWarnings("unchecked")
- public static <T> T unwrap(T object)
- {
- if ((object instanceof Unwrappable<?>) &&
((Unwrappable<?>)object).isWrapper())
- { // recursive
- return unwrap(((Unwrappable<T>)object).unwrap());
- }
- return object;
- }
-
- /**
- * returns whether or not a array contains a certain item
- * performs a quick (==) comparison first
- * if not found a second check is made using equals and unwrapping of
items
- *
- * @param <T> the type of the object
- * @param array the array to search
- * @param item the item to search for
- *
- * @return true if the array contains the item or false otherwise
- */
- @SuppressWarnings("unchecked")
- public static <T> int indexOf(T[] array, T item)
- {
- if (array==null || array.length==0)
- return -1;
- // 1st try (quick)
- for (int i=0; i<array.length; i++)
- {
- if (array[i]==item)
- return i;
+ // Strings special
+ if ((value instanceof String) && ((String)value).length()==0)
+ value = null;
+ // check for enum
+ if (value instanceof Enum<?>)
+ { // convert enum
+ value = getEnumValue((Enum<?>)value, dataType.isNumeric());
}
- // 2nd try (equals)
- for (int i=0; i<array.length; i++)
- {
- T ai = array[i];
- if (ai!=null && ai.equals(item))
- return i;
+ // check option entry
+ else if (value instanceof OptionEntry)
+ { // option value
+ value = ((OptionEntry)value).getValue();
}
- // 3rd try (unwrap)
- for (int i=0; i<array.length; i++)
+ // check type
+ switch (dataType)
{
- T ai = array[i];
- // check wrapper
- if ((ai instanceof Unwrappable) &&
((Unwrappable<?>)ai).isWrapper())
- { // unwrap
- Object unwrapped = ((Unwrappable<?>)ai).unwrap();
- if (unwrapped==item || unwrapped.equals(item))
- return i;
- }
- }
- // 3rd try (unwrap)
- if ((item instanceof Unwrappable) &&
((Unwrappable<?>)item).isWrapper())
- { // unwrap
- return indexOf(array, ((Unwrappable<T>)item).unwrap());
+ case BLOB:
+ return value; // unchanged
+ case BOOL:
+ return getBoolean(value, false);
+ case INTEGER:
+ return (value instanceof Number) ? value : toLong(value);
+ case FLOAT:
+ return (value instanceof Number) ? value : toDouble(value);
+ case DECIMAL:
+ return (value instanceof Number) ? value : toDecimal(value);
+ case CHAR:
+ case CLOB:
+ case VARCHAR:
+ return (value instanceof String) ? value : value.toString();
// not not call getString(...);
+ default:
+ // use as is
+ return value;
}
- // not found
- return -1;
- }
-
- /**
- * returns whether or not a array contains a certain item
- * performs a simple (==) comparison (fast)
- *
- * @param <T> the type of elements
- * @param array the array to search
- * @param item the item to search for
- *
- * @return true if the array contains the item or false otherwise
- */
- public static <T> boolean contains(T[] array, T item)
- {
- return (indexOf(array, item)>=0);
- }
-
- /**
- * combines two arrays
- * @param <T> the type of the array items
- * @param left the left array
- * @param right the right array
- * @return the combined array
- */
- public static <T> T[] combine(T[] left, T[] right)
- {
- if (left==null || left.length==0)
- return right;
- if (right==null || right.length==0)
- return left;
- // combine both
- T[] result = Arrays.copyOf(left, left.length + right.length);
- System.arraycopy(right, 0, result, left.length, right.length);
- return result;
- }
-
- /**
- * appends an element to an array
- * @param <T> the type of the array items
- * @param array the array
- * @param element the new element
- * @return the combined array
- */
- public static <T> T[] append(T[] array, T element)
- {
- if (array==null)
- throw new InvalidArgumentException("array", array);
- // append element
- T[] result = Arrays.copyOf(array, array.length + 1);
- result[array.length] = element;
- return result;
}
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
index 94f0225f..f532e203 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
@@ -57,15 +57,11 @@ public class DBCmdParam extends DBExpr
*/
protected Object getCmdParamValue(Object value)
{
- // check null
- if (value == null)
- return null;
- // check for enum
- if (value instanceof Enum<?>)
- { // convert enum
- return ObjectUtils.getEnumValue((Enum<?>)value, type.isNumeric());
- }
- // check type
+ if (value!=null)
+ value = ObjectUtils.convertValue(type, value);
+ if (value==null)
+ return value;
+ // Check CLOB and BLOB
switch (type)
{
case BLOB:
@@ -80,19 +76,8 @@ public class DBCmdParam extends DBExpr
return value;
// create a clob data
return new DBClobData(value.toString());
- case BOOL:
- return ObjectUtils.getBoolean(value);
- case INTEGER:
- return (value instanceof Number) ? value :
ObjectUtils.toLong(value);
- case FLOAT:
- return (value instanceof Number) ? value :
ObjectUtils.toDouble(value);
- case DECIMAL:
- return (value instanceof Number) ? value :
ObjectUtils.toDecimal(value);
- case CHAR:
- case VARCHAR:
- return (value instanceof String) ? value : value.toString();
default:
- // use as is
+ // the value
return value;
}
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
index 9b8be573..02c548ce 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
@@ -656,23 +656,15 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
setParentRecord(getColumn(index), (DBRecordBase)value);
return;
}
- // Strings special
- if ((value instanceof String) && ((String)value).length()==0)
- value = null;
// Is value valid
Object current = fields[index];
if (current==ObjectUtils.NO_VALUE)
throw new FieldValueNotFetchedException(getColumn(index));
// convert
DBColumn column = getColumn(index);
- // must convert enums
- if (value instanceof Enum<?>)
- { // convert enum
- Enum<?> enumVal = ((Enum<?>)value);
- boolean numeric = column.getDataType().isNumeric();
- value = ObjectUtils.getEnumValue(enumVal, numeric);
- }
// Has Value changed?
+ if (value!= null)
+ value = ObjectUtils.convertValue(column.getDataType(), value);
if (ObjectUtils.compareEqual(current, value))
{ // value has not changed!
return;
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 b29511ad..564c730c 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
@@ -1088,8 +1088,6 @@ public abstract class DBRowSet extends DBExpr implements
EntityType
{ // Update a field
if (col.isReadOnly())
log.warn("updateRecord: Read-only column '" +
col.getName() + " has been modified!");
- // *** unnecessary check removed 2.5.0 ***
- // col.validate(value);
// Set the column
cmd.set(col.to(value));
setCount++;
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
index 3b689f87..8c83aefb 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
@@ -27,7 +27,6 @@ import java.util.Collection;
import java.util.Date;
import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.OptionEntry;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataType;
import org.apache.empire.dbms.DBMSHandler;
@@ -186,18 +185,9 @@ public abstract class DBSQLBuilder implements Appendable
{ // it's an expression
((DBExpr) value).addSQL(this, context);
return;
- }
- // check option entry
- if (value instanceof OptionEntry)
- { // option value
- value = ((OptionEntry)value).getValue();
- }
- // check enum
- if (value instanceof Enum<?>)
- { // check enum
- value = ObjectUtils.getEnumValue((Enum<?>)value,
dataType.isNumeric());
}
- else if (value instanceof Collection<?>)
+ // Check colletion
+ if (value instanceof Collection<?>)
{ // collection 2 array
value = ((Collection<?>)value).toArray();
}
@@ -215,7 +205,10 @@ public abstract class DBSQLBuilder implements Appendable
return;
}
else
- { // Get Value Expression from dmbs
+ { // Convert to database format
+ if (value!= null)
+ value = ObjectUtils.convertValue(dataType, value);
+ // append now
appendSimpleValue(dataType, value);
}
}