summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2015-04-16 19:11:30 -0400
committerJames Moger <james.moger@gitblit.com>2015-04-16 19:11:30 -0400
commite4952b2465ae4167e24d416b4fc4f6996e2fe229 (patch)
tree8da93c36a6891c697e718cb3499869703c50942c
parentf897fc7d25c757fc0607ce010c1e8c50ce127131 (diff)
downloadiciql-e4952b2465ae4167e24d416b4fc4f6996e2fe229.tar.gz
iciql-e4952b2465ae4167e24d416b4fc4f6996e2fe229.zip
Move standard object deserialization into the dialect
-rw-r--r--src/main/java/com/iciql/DaoProxy.java56
-rw-r--r--src/main/java/com/iciql/Query.java19
-rw-r--r--src/main/java/com/iciql/SQLDialect.java8
-rw-r--r--src/main/java/com/iciql/SQLDialectDefault.java39
-rw-r--r--src/main/java/com/iciql/TableDefinition.java62
-rw-r--r--src/main/java/com/iciql/util/Utils.java57
6 files changed, 125 insertions, 116 deletions
diff --git a/src/main/java/com/iciql/DaoProxy.java b/src/main/java/com/iciql/DaoProxy.java
index d27753f..34187c4 100644
--- a/src/main/java/com/iciql/DaoProxy.java
+++ b/src/main/java/com/iciql/DaoProxy.java
@@ -38,7 +38,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.iciql.Iciql.DataTypeAdapter;
-import com.iciql.Iciql.TypeAdapter;
import com.iciql.util.JdbcUtils;
import com.iciql.util.StringUtils;
import com.iciql.util.Utils;
@@ -175,18 +174,9 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao {
|| java.util.Date.class.isAssignableFrom(returnType)
|| byte[].class.isAssignableFrom(returnType);
- // determine the return type adapter, if any
- DataTypeAdapter<?> adapter = null;
- for (Annotation annotation : method.getAnnotations()) {
- if (annotation.annotationType() == TypeAdapter.class) {
- TypeAdapter typeAdapter = (TypeAdapter) annotation;
- adapter = db.getDialect().getAdapter(typeAdapter.value());
- break;
- } else if (annotation.annotationType().isAnnotationPresent(TypeAdapter.class)) {
- TypeAdapter typeAdapter = annotation.annotationType().getAnnotation(TypeAdapter.class);
- adapter = db.getDialect().getAdapter(typeAdapter.value());
- break;
- }
+ Class<? extends DataTypeAdapter<?>> adapter = Utils.getDataTypeAdapter(method.getAnnotations());
+ if (adapter == null) {
+ adapter = Utils.getDataTypeAdapter(returnType.getAnnotations());
}
/*
@@ -209,17 +199,7 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao {
while (rs.next()) {
- Object o = rs.getObject(1);
- Object value;
-
- if (adapter == null) {
- // use internal Iciql type conversion
- value = Utils.convert(o, returnType);
- } else {
- // use the type adapter to convert the JDBC object to a domain type
- value = adapter.deserialize(o);
- }
-
+ Object value = db.getDialect().deserialize(rs, 1, returnType, adapter);
objects.add(value);
if (!isArray) {
@@ -704,7 +684,7 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao {
}
// prepare the parameter
- parameters[i] = prepareParameter(db, value, typeAdapter);
+ parameters[i] = db.getDialect().serialize(value, typeAdapter);
}
@@ -712,32 +692,6 @@ final class DaoProxy<X extends Dao> implements InvocationHandler, Dao {
}
- /**
- * Prepares a method argument to an sql parameter for transmission to a
- * database.
- *
- * @param db
- * @param arg
- * @param typeAdapter
- * @return a prepared parameter
- */
- private Object prepareParameter(Db db, Object arg, Class<? extends DataTypeAdapter<?>> typeAdapter) {
-
- if (typeAdapter != null) {
-
- // use a type adapter to serialize the method argument
- Object o = db.getDialect().serialize(arg, typeAdapter);
- return o;
-
- } else {
-
- // use the method argument
- return arg;
-
- }
-
- }
-
@Override
public String toString() {
return sql;
diff --git a/src/main/java/com/iciql/Query.java b/src/main/java/com/iciql/Query.java
index 7c5c985..d52451e 100644
--- a/src/main/java/com/iciql/Query.java
+++ b/src/main/java/com/iciql/Query.java
@@ -18,8 +18,6 @@
package com.iciql;
import java.lang.reflect.Field;
-import java.sql.Blob;
-import java.sql.Clob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -28,6 +26,7 @@ import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
+import com.iciql.Iciql.DataTypeAdapter;
import com.iciql.Iciql.EnumType;
import com.iciql.NestedConditions.And;
import com.iciql.NestedConditions.Or;
@@ -115,7 +114,6 @@ public class Query<T> {
return select(true);
}
- @SuppressWarnings("unchecked")
public <X, Z> X selectFirst(Z x) {
List<X> list = limit(1).select(x);
return list.isEmpty() ? null : list.get(0);
@@ -424,18 +422,10 @@ public class Query<T> {
appendFromWhere(stat);
ResultSet rs = stat.executeQuery();
List<X> result = Utils.newArrayList();
+ Class<? extends DataTypeAdapter<?>> typeAdapter = Utils.getDataTypeAdapter(x.getClass().getAnnotations());
try {
while (rs.next()) {
- X value;
- Object o = rs.getObject(1);
- // Convert CLOB and BLOB now because we close the resultset
- if (Clob.class.isAssignableFrom(o.getClass())) {
- value = (X) Utils.convert(o, String.class);
- } else if (Blob.class.isAssignableFrom(o.getClass())) {
- value = (X) Utils.convert(o, byte[].class);
- } else {
- value = (X) o;
- }
+ X value = (X) db.getDialect().deserialize(rs, 1, x.getClass(), typeAdapter);
result.add(value);
}
} catch (Exception e) {
@@ -850,7 +840,8 @@ public class Query<T> {
stat.addParameter(y);
} else if (col != null) {
// object
- Object parameter = db.getDialect().serialize(value, col.getFieldDefinition().typeAdapter);
+ Class<? extends DataTypeAdapter<?>> typeAdapter = col.getFieldDefinition().typeAdapter;
+ Object parameter = db.getDialect().serialize(value, typeAdapter);
stat.addParameter(parameter);
} else {
// primitive
diff --git a/src/main/java/com/iciql/SQLDialect.java b/src/main/java/com/iciql/SQLDialect.java
index 33c5369..ccc0452 100644
--- a/src/main/java/com/iciql/SQLDialect.java
+++ b/src/main/java/com/iciql/SQLDialect.java
@@ -18,6 +18,8 @@
package com.iciql;
+import java.sql.ResultSet;
+
import com.iciql.Iciql.DataTypeAdapter;
import com.iciql.TableDefinition.IndexDefinition;
@@ -54,11 +56,13 @@ public interface SQLDialect {
/**
* Deserialize the object received from the database into a Java type.
*
- * @param value
+ * @param rs
+ * @param columnIndex
+ * @param targetType
* @param typeAdapter
* @return the deserialized object
*/
- Object deserialize(Object value, Class<? extends DataTypeAdapter<?>> typeAdapter);
+ Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType, Class<? extends DataTypeAdapter<?>> typeAdapter);
/**
* Configure the dialect.
diff --git a/src/main/java/com/iciql/SQLDialectDefault.java b/src/main/java/com/iciql/SQLDialectDefault.java
index 7c656bd..8547f3c 100644
--- a/src/main/java/com/iciql/SQLDialectDefault.java
+++ b/src/main/java/com/iciql/SQLDialectDefault.java
@@ -18,8 +18,11 @@
package com.iciql;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
@@ -476,14 +479,40 @@ public class SQLDialectDefault implements SQLDialect {
}
@Override
- public Object deserialize(Object value, Class<? extends DataTypeAdapter<?>> typeAdapter) {
+ public Object deserialize(ResultSet rs, int columnIndex, Class<?> targetType, Class<? extends DataTypeAdapter<?>> typeAdapter) {
if (typeAdapter == null) {
- // pass-through
+ // standard object deserialization
+ Object value = null;
+ try {
+ // use internal Iciql type conversion
+ Object o = rs.getObject(columnIndex);
+ if (Clob.class.isAssignableFrom(o.getClass())) {
+ value = Utils.convert(o, String.class);
+ } else if (Blob.class.isAssignableFrom(o.getClass())) {
+ value = Utils.convert(o, byte[].class);
+ } else {
+ value = Utils.convert(o, targetType);
+ }
+ } catch (SQLException e) {
+ throw new IciqlException(e, "Can not convert the value at column {0} to {1}",
+ columnIndex, targetType.getName());
+ }
+
return value;
- }
+ } else {
+ // custom object deserialization with a DataTypeAdapter
+ DataTypeAdapter<?> dta = getAdapter(typeAdapter);
+ Object object = null;
+ try {
+ object = rs.getObject(columnIndex);
+ } catch (SQLException e) {
+ throw new IciqlException(e, "Can not convert the value at column {0} to {1}",
+ columnIndex, targetType.getName());
+ }
- DataTypeAdapter<?> dta = getAdapter(typeAdapter);
- return dta.deserialize(value);
+ Object value = dta.deserialize(object);
+ return value;
+ }
}
@Override
diff --git a/src/main/java/com/iciql/TableDefinition.java b/src/main/java/com/iciql/TableDefinition.java
index e07cee6..8248f18 100644
--- a/src/main/java/com/iciql/TableDefinition.java
+++ b/src/main/java/com/iciql/TableDefinition.java
@@ -42,7 +42,6 @@ import com.iciql.Iciql.IQContraintForeignKey;
import com.iciql.Iciql.IQContraintUnique;
import com.iciql.Iciql.IQContraintsForeignKey;
import com.iciql.Iciql.IQContraintsUnique;
-import com.iciql.Iciql.IQEnum;
import com.iciql.Iciql.IQIgnore;
import com.iciql.Iciql.IQIndex;
import com.iciql.Iciql.IQIndexes;
@@ -134,25 +133,17 @@ public class TableDefinition<T> {
private Object initWithNewObject(Object obj) {
Object o = Utils.newObject(field.getType());
- setValue(null, obj, o);
+ setValue(obj, o);
return o;
}
- private void setValue(SQLDialect dialect, Object obj, Object o) {
+ private void setValue(Object obj, Object o) {
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
- Class<?> targetType = field.getType();
- if (targetType.isEnum()) {
- o = Utils.convertEnum(o, targetType, enumType);
- } else if (dialect != null && typeAdapter != null) {
- o = dialect.deserialize(o, typeAdapter);
- } else {
- o = Utils.convert(o, targetType);
- }
- if (targetType.isPrimitive() && o == null) {
+ if (field.getType().isPrimitive() && o == null) {
// do not attempt to set a primitive to null
return;
}
@@ -165,14 +156,6 @@ public class TableDefinition<T> {
}
}
- private Object read(ResultSet rs, int columnIndex) {
- try {
- return rs.getObject(columnIndex);
- } catch (SQLException e) {
- throw new IciqlException(e);
- }
- }
-
@Override
public int hashCode() {
return columnName.hashCode();
@@ -457,32 +440,14 @@ public class TableDefinition<T> {
int scale = 0;
boolean trim = false;
boolean nullable = !f.getType().isPrimitive();
- EnumType enumType = null;
- Class<?> enumTypeClass = null;
String defaultValue = "";
String constraint = "";
String dataType = null;
Class<? extends DataTypeAdapter<?>> typeAdapter = null;
// configure Java -> SQL enum mapping
- if (f.getType().isEnum()) {
- enumType = EnumType.DEFAULT_TYPE;
- if (f.getType().isAnnotationPresent(IQEnum.class)) {
- // enum definition is annotated for all instances
- IQEnum iqenum = f.getType().getAnnotation(IQEnum.class);
- enumType = iqenum.value();
- }
- if (f.isAnnotationPresent(IQEnum.class)) {
- // this instance of the enum is annotated
- IQEnum iqenum = f.getAnnotation(IQEnum.class);
- enumType = iqenum.value();
- }
-
- if (EnumId.class.isAssignableFrom(f.getType())) {
- // custom enumid mapping
- enumTypeClass = ((EnumId<?>) f.getType().getEnumConstants()[0]).enumIdClass();
- }
- }
+ EnumType enumType = Utils.getEnumType(f);
+ Class<?> enumTypeClass = Utils.getEnumTypeClass(f);
// try using default object
try {
@@ -1201,9 +1166,20 @@ public class TableDefinition<T> {
void readRow(SQLDialect dialect, Object item, ResultSet rs, int[] columns) {
for (int i = 0; i < fields.size(); i++) {
FieldDefinition def = fields.get(i);
- int index = columns[i];
- Object o = def.read(rs, index);
- def.setValue(dialect, item, o);
+ Class<?> targetType = def.field.getType();
+ Object o;
+ if (targetType.isEnum()) {
+ Object obj;
+ try {
+ obj = rs.getObject(columns[i]);
+ } catch (SQLException e) {
+ throw new IciqlException(e);
+ }
+ o = Utils.convertEnum(obj, targetType, def.enumType);
+ } else {
+ o = dialect.deserialize(rs, columns[i], targetType, def.typeAdapter);
+ }
+ def.setValue(item, o);
}
}
diff --git a/src/main/java/com/iciql/util/Utils.java b/src/main/java/com/iciql/util/Utils.java
index bf66092..f4dbb81 100644
--- a/src/main/java/com/iciql/util/Utils.java
+++ b/src/main/java/com/iciql/util/Utils.java
@@ -24,6 +24,7 @@ import java.io.Reader;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
@@ -44,6 +45,7 @@ import java.util.concurrent.atomic.AtomicLong;
import com.iciql.Iciql.DataTypeAdapter;
import com.iciql.Iciql.EnumId;
import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.IQEnum;
import com.iciql.Iciql.TypeAdapter;
import com.iciql.IciqlException;
@@ -352,6 +354,59 @@ public class Utils {
throw new IciqlException("Can not convert the value {0} from {1} to {2}", o, currentType, targetType);
}
+ /**
+ * Identify the EnumType for the field.
+ *
+ * @param f
+ * @return null or the EnumType
+ */
+ public static EnumType getEnumType(Field f) {
+ EnumType enumType = null;
+ if (f.getType().isEnum()) {
+ enumType = EnumType.DEFAULT_TYPE;
+ if (f.getType().isAnnotationPresent(IQEnum.class)) {
+ // enum definition is annotated for all instances
+ IQEnum iqenum = f.getType().getAnnotation(IQEnum.class);
+ enumType = iqenum.value();
+ }
+ if (f.isAnnotationPresent(IQEnum.class)) {
+ // this instance of the enum is annotated
+ IQEnum iqenum = f.getAnnotation(IQEnum.class);
+ enumType = iqenum.value();
+ }
+ }
+ return enumType;
+ }
+
+ /**
+ * Identify the EnumType from the annotations.
+ *
+ * @param annotations
+ * @return null or the EnumType
+ */
+ public static EnumType getEnumType(Annotation [] annotations) {
+ EnumType enumType = null;
+ if (annotations != null) {
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof IQEnum) {
+ enumType = ((IQEnum) annotation).value();
+ break;
+ }
+ }
+ }
+ return enumType;
+ }
+
+ public static Class<?> getEnumTypeClass(Field f) {
+ if (f.getType().isEnum()) {
+ if (EnumId.class.isAssignableFrom(f.getType())) {
+ // custom enumid mapping
+ return ((EnumId<?>) f.getType().getEnumConstants()[0]).enumIdClass();
+ }
+ }
+ return null;
+ }
+
public static Object convertEnum(Enum<?> o, EnumType type) {
if (o == null) {
return null;
@@ -540,7 +595,7 @@ public class Utils {
* Identify the data type adapter class in the annotations.
*
* @param annotations
- * @return null or the dtaa type adapter class
+ * @return null or the data type adapter class
*/
public static Class<? extends DataTypeAdapter<?>> getDataTypeAdapter(Annotation [] annotations) {
Class<? extends DataTypeAdapter<?>> typeAdapter = null;