You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2021/04/28 12:32:51 UTC
[empire-db] branch master updated: EMPIREDB-346 Improve Enum value
conversion / allow custom conversion
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 db76b56 EMPIREDB-346 Improve Enum value conversion / allow custom conversion
db76b56 is described below
commit db76b5688743eb264fb7d4b395ab2fa5c9b8ac36
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Wed Apr 28 14:32:47 2021 +0200
EMPIREDB-346
Improve Enum value conversion / allow custom conversion
---
.../apache/empire/jsf2/components/SelectTag.java | 8 +--
.../apache/empire/jsf2/controls/InputControl.java | 2 +-
.../empire/jsf2/controls/RadioInputControl.java | 6 +-
.../empire/jsf2/controls/SelectInputControl.java | 6 +-
.../org/apache/empire/commons/ObjectUtils.java | 82 ++++++++++++++++++++--
.../org/apache/empire/commons/OptionEntry.java | 4 +-
.../main/java/org/apache/empire/db/DBCmdParam.java | 5 +-
.../java/org/apache/empire/db/DBColumnExpr.java | 6 +-
.../src/main/java/org/apache/empire/db/DBExpr.java | 10 ++-
.../main/java/org/apache/empire/db/DBRecord.java | 4 +-
.../main/java/org/apache/empire/db/DBTable.java | 3 +-
.../java/org/apache/empire/db/DBTableColumn.java | 20 ++++--
.../apache/empire/db/expr/column/DBValueExpr.java | 8 +--
13 files changed, 122 insertions(+), 42 deletions(-)
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
index 3c91b95..575fb00 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
@@ -76,8 +76,8 @@ public class SelectTag extends UIInput implements NamingContainer
Object value = SelectTag.this.getValue();
if (value != null)
{
- if (value.getClass().isEnum())
- value = ((Enum<?>) value).name();
+ if (value instanceof Enum<?>)
+ value = ((Enum<?>)value).name();
else
value = String.valueOf(value);
}
@@ -391,8 +391,8 @@ public class SelectTag extends UIInput implements NamingContainer
Object value = getValue();
if (value != null)
{
- if (value.getClass().isEnum())
- value = ((Enum<?>) value).name();
+ if (value instanceof Enum<?>)
+ value = ((Enum<?>)value).name();
else
value = String.valueOf(value);
}
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
index fddd02b..f940c72 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
@@ -704,7 +704,7 @@ public abstract class InputControl
protected String formatValue(Object value, ValueInfo vi)
{
// For Enums use toString() to retrieve Value
- if (value != null && value.getClass().isEnum() && !hasFormatOption(vi, "nolookup"))
+ if ((value instanceof Enum<?>) && !hasFormatOption(vi, "nolookup"))
{ // Handle enum
String text = ((Enum<?>) value).toString();
if (text != null)
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
index 97e0af7..5231521 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
@@ -318,10 +318,8 @@ public class RadioInputControl extends InputControl
protected Object formatInputValue(Object value, InputInfo ii)
{
// the enum Value
- if (value != null && value.getClass().isEnum())
- {
+ if (value instanceof Enum<?>)
return ((Enum<?>) value).name();
- }
// the value
return value;
}
@@ -332,7 +330,7 @@ public class RadioInputControl extends InputControl
Class<Enum<?>> enumType = ii.getColumn().getEnumType();
if (enumType!=null)
{ // convert to enum
- return ObjectUtils.getEnum(enumType, value);
+ return ObjectUtils.getEnumByName(enumType, value);
}
return value;
}
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java
index 99f96b6..cdfbecd 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectInputControl.java
@@ -354,10 +354,8 @@ public class SelectInputControl extends InputControl
protected Object formatInputValue(Object value)
{
// the enum Value
- if (value != null && value.getClass().isEnum())
- {
+ if (value instanceof Enum<?>)
return ((Enum<?>) value).name();
- }
// the value
return value;
}
@@ -368,7 +366,7 @@ public class SelectInputControl extends InputControl
Class<Enum<?>> enumType = ii.getColumn().getEnumType();
if (enumType!=null)
{ // convert to enum
- return ObjectUtils.getEnum(enumType, value);
+ return ObjectUtils.getEnumByName(enumType, value);
}
return value;
}
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 ff2f882..42df629 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
@@ -74,7 +74,7 @@ public final class ObjectUtils
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
-
+
private ObjectUtils()
{
// Static Function only
@@ -151,7 +151,7 @@ public final class ObjectUtils
return (d1==d2);
}
// Enum
- if (o1.getClass().isEnum())
+ if (o1 instanceof Enum<?>)
{ // Special enum handling
if (o2 instanceof Number)
return ((Enum<?>)o1).ordinal()==((Number)o2).intValue();
@@ -160,7 +160,7 @@ public final class ObjectUtils
else
return ((Enum<?>)o1).name().equals(o2);
}
- else if (o2.getClass().isEnum())
+ else if (o2 instanceof Enum<?>)
{ // Special enum handling
if (o1 instanceof Number)
return ((Enum<?>)o2).ordinal()==((Number)o1).intValue();
@@ -469,8 +469,20 @@ public final class ObjectUtils
value = ((Enum<?>)value).name();
}
// check column data type
+ boolean numeric = (value instanceof Number);
T[] items = enumType.getEnumConstants();
- if (value instanceof Number)
+ 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
@@ -490,6 +502,68 @@ public final class ObjectUtils
throw new ItemNotFoundException(name);
}
}
+
+ /**
+ * find by name
+ * @param enumType the enum type
+ * @param name the enum name
+ * @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);
+ }
+
+ /**
+ * Convert Enum<?> to Object
+ */
+ 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));
+ }
+
+ /**
+ * Convert Enum<?> to String
+ */
+ 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();
+ }
+
+ /**
+ * Convert Object to String
+ */
+ public static String getString(Object value)
+ {
+ // convert
+ if (value instanceof Enum<?>)
+ return getString((Enum<?>)value);
+ if (value instanceof Date)
+ return formatDate((Date)value, true);
+ if (value==NO_VALUE)
+ return null;
+ // toString
+ return (value!=null ? value.toString() : null);
+ }
/**
* Converts an object value to a Date.
diff --git a/empire-db/src/main/java/org/apache/empire/commons/OptionEntry.java b/empire-db/src/main/java/org/apache/empire/commons/OptionEntry.java
index f5ef540..d4e8f3a 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/OptionEntry.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/OptionEntry.java
@@ -68,8 +68,8 @@ public class OptionEntry implements Serializable
if (value==null)
return "";
// check enum
- if (value.getClass().isEnum())
- return ((Enum<?>)value).name();
+ if (value instanceof Enum<?>)
+ return ObjectUtils.getString((Enum<?>)value);
// convert
return String.valueOf(value);
}
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 0d70f12..68323b0 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
@@ -79,10 +79,9 @@ public class DBCmdParam extends DBExpr
return ObjectUtils.getBoolean(value);
default:
// check for enum
- if (value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // convert enum
- Enum<?> enumValue = ((Enum<?>)value);
- return (type.isNumeric() ? enumValue.ordinal() : enumValue.name());
+ return ObjectUtils.getEnumValue((Enum<?>)value, type.isNumeric());
}
// use as is
return value;
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
index fd78c4c..99c146a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.empire.commons.Attributes;
+import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.OptionEntry;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
@@ -1095,7 +1096,7 @@ public abstract class DBColumnExpr extends DBExpr
Map<Object, String> enumMap = new LinkedHashMap<Object, String>(items.length);
for (int i=0; i<items.length; i++)
{ // key: ordinal (for numeric columns) or name (for CHAR columns)
- Object key = (byOrdinal ? items[i].ordinal() : items[i].name());
+ Object key = ObjectUtils.getEnumValue(items[i], byOrdinal);
enumMap.put(key, items[i].toString());
}
// Create the decode function
@@ -1122,7 +1123,8 @@ public abstract class DBColumnExpr extends DBExpr
for (int i=0; i<items.length; i++)
{
int sortValue = items[i].ordinal();
- enumMap.put(items[i].name(), sortValue + sortOffset);
+ String value = ObjectUtils.getString(items[i]);
+ enumMap.put(value, sortValue + sortOffset);
}
// Create the decode function
int defaultValue = (defaultToEnd ? items.length : 0);
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
index 4ee04a6..23e34f1 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.Set;
+import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.OptionEntry;
// java
import org.apache.empire.data.DataType;
@@ -85,16 +86,13 @@ public abstract class DBExpr extends DBObject
}
// check option entry
if (value instanceof OptionEntry)
- {
+ { // option value
value = ((OptionEntry)value).getValue();
}
// check enum
- if (value!=null && value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // check enum
- if (dataType.isNumeric())
- value = ((Enum<?>)value).ordinal();
- else
- value = ((Enum<?>)value).name();
+ value = ObjectUtils.getEnumValue((Enum<?>)value, dataType.isNumeric());
}
else if (value instanceof Collection<?>)
{ // collection 2 array
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
index f612f09..d3ac89b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
@@ -650,11 +650,11 @@ public class DBRecord extends DBRecordData implements Record, Cloneable
// convert
DBColumn column = rowset.getColumn(index);
// must convert enums
- if (value!=null && value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // convert enum
Enum<?> enumVal = ((Enum<?>)value);
boolean numeric = column.getDataType().isNumeric();
- value = (numeric ? enumVal.ordinal() : enumVal.name());
+ value = ObjectUtils.getEnumValue(enumVal, numeric);
}
// Has Value changed?
if (ObjectUtils.compareEqual(current, value))
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index 153d5b4..d31cc64 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataMode;
@@ -416,7 +417,7 @@ public class DBTable extends DBRowSet implements Cloneable
*/
public final DBTableColumn addColumn(String columnName, DataType type, double size, boolean required, Enum<?> enumValue)
{
- Object defValue = type.isNumeric() ? enumValue.ordinal() : enumValue.name();
+ Object defValue = ObjectUtils.getEnumValue(enumValue, type.isNumeric());
DBTableColumn col = this.crateAndAppendColumn(columnName, type, size, required, defValue);
col.setEnumOptions(enumValue.getClass());
return col;
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
index 7400e49..4a3447a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
@@ -26,6 +26,7 @@ import java.util.Date;
import org.apache.empire.commons.Attributes;
import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.OptionEntry;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
@@ -36,6 +37,7 @@ import org.apache.empire.db.exceptions.FieldNotNullException;
import org.apache.empire.db.exceptions.FieldValueOutOfRangeException;
import org.apache.empire.db.exceptions.FieldValueTooLongException;
import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.InvalidPropertyException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.exceptions.PropertyReadOnlyException;
import org.apache.empire.xml.XMLUtil;
@@ -339,6 +341,16 @@ public class DBTableColumn extends DBColumn
this.options = new Options(enumType);
// set enumType
setAttribute(Column.COLATTR_ENUMTYPE, enumType);
+ // check length
+ if (getDataType().isNumeric())
+ return; // no check required
+ int maxLength = (int)size;
+ for (OptionEntry oe : options)
+ { // check length
+ String val = oe.getValueString();
+ if (val!=null && val.length()>maxLength)
+ throw new InvalidPropertyException(enumType.getName(), val);
+ }
}
/**
@@ -420,7 +432,7 @@ public class DBTableColumn extends DBColumn
case DECIMAL:
// check enum
- if (value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // convert enum
value = ((Enum<?>)value).ordinal();
}
@@ -458,7 +470,7 @@ public class DBTableColumn extends DBColumn
case INTEGER:
// check enum
- if (value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // convert enum
value = ((Enum<?>)value).ordinal();
}
@@ -482,9 +494,9 @@ public class DBTableColumn extends DBColumn
case VARCHAR:
case CHAR:
// check enum
- if (value.getClass().isEnum())
+ if (value instanceof Enum<?>)
{ // convert enum
- value = ((Enum<?>)value).name();
+ value = ObjectUtils.getString((Enum<?>)value);
}
// check length
if (value.toString().length() > size)
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
index 1ae26c6..9a61d3b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
@@ -20,6 +20,7 @@ package org.apache.empire.db.expr.column;
import java.util.Set;
+import org.apache.empire.commons.ObjectUtils;
// Java
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBColumn;
@@ -195,11 +196,8 @@ public class DBValueExpr extends DBColumnExpr
Object val = value;
// unwrap enum
if (value instanceof Enum)
- { // its an enum
- if (dataType.isNumeric())
- val = ((Enum<?>) value).ordinal();
- else
- val = ((Enum<?>) value).name();
+ { // Convert value
+ value = ObjectUtils.getEnumValue((Enum<?>) value, dataType.isNumeric());
}
// convert value to sql literal
DBDatabaseDriver driver = db.getDriver();