diff options
author | James Moger <james.moger@gitblit.com> | 2015-04-16 19:11:30 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2015-04-16 19:11:30 -0400 |
commit | e4952b2465ae4167e24d416b4fc4f6996e2fe229 (patch) | |
tree | 8da93c36a6891c697e718cb3499869703c50942c | |
parent | f897fc7d25c757fc0607ce010c1e8c50ce127131 (diff) | |
download | iciql-e4952b2465ae4167e24d416b4fc4f6996e2fe229.tar.gz iciql-e4952b2465ae4167e24d416b4fc4f6996e2fe229.zip |
Move standard object deserialization into the dialect
-rw-r--r-- | src/main/java/com/iciql/DaoProxy.java | 56 | ||||
-rw-r--r-- | src/main/java/com/iciql/Query.java | 19 | ||||
-rw-r--r-- | src/main/java/com/iciql/SQLDialect.java | 8 | ||||
-rw-r--r-- | src/main/java/com/iciql/SQLDialectDefault.java | 39 | ||||
-rw-r--r-- | src/main/java/com/iciql/TableDefinition.java | 62 | ||||
-rw-r--r-- | src/main/java/com/iciql/util/Utils.java | 57 |
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;
|