]> source.dussan.org Git - iciql.git/commitdiff
Move standard object deserialization into the dialect
authorJames Moger <james.moger@gitblit.com>
Thu, 16 Apr 2015 23:11:30 +0000 (19:11 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 16 Apr 2015 23:11:30 +0000 (19:11 -0400)
src/main/java/com/iciql/DaoProxy.java
src/main/java/com/iciql/Query.java
src/main/java/com/iciql/SQLDialect.java
src/main/java/com/iciql/SQLDialectDefault.java
src/main/java/com/iciql/TableDefinition.java
src/main/java/com/iciql/util/Utils.java

index d27753f312d5a8f32826b91338ff71d12e2b0456..34187c4388c28744713f72a9185b366d1bd0eaa0 100644 (file)
@@ -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;
index 7c5c985153931bbcde73da5a07c14e013cc5ceda..d52451eb6d427b0cb8c5c986bdde0e8add2a15bc 100644 (file)
@@ -18,8 +18,6 @@
 package com.iciql;\r
 \r
 import java.lang.reflect.Field;\r
-import java.sql.Blob;\r
-import java.sql.Clob;\r
 import java.sql.ResultSet;\r
 import java.sql.SQLException;\r
 import java.util.ArrayList;\r
@@ -28,6 +26,7 @@ import java.util.HashMap;
 import java.util.IdentityHashMap;\r
 import java.util.List;\r
 \r
+import com.iciql.Iciql.DataTypeAdapter;\r
 import com.iciql.Iciql.EnumType;\r
 import com.iciql.NestedConditions.And;\r
 import com.iciql.NestedConditions.Or;\r
@@ -115,7 +114,6 @@ public class Query<T> {
                return select(true);\r
        }\r
 \r
-       @SuppressWarnings("unchecked")\r
        public <X, Z> X selectFirst(Z x) {\r
                List<X> list = limit(1).select(x);\r
                return list.isEmpty() ? null : list.get(0);\r
@@ -424,18 +422,10 @@ public class Query<T> {
                appendFromWhere(stat);\r
                ResultSet rs = stat.executeQuery();\r
                List<X> result = Utils.newArrayList();\r
+               Class<? extends DataTypeAdapter<?>> typeAdapter = Utils.getDataTypeAdapter(x.getClass().getAnnotations());\r
                try {\r
                        while (rs.next()) {\r
-                               X value;\r
-                               Object o = rs.getObject(1);\r
-                               // Convert CLOB and BLOB now because we close the resultset\r
-                               if (Clob.class.isAssignableFrom(o.getClass())) {\r
-                                       value = (X) Utils.convert(o, String.class);\r
-                               } else if (Blob.class.isAssignableFrom(o.getClass())) {\r
-                                       value = (X) Utils.convert(o, byte[].class);\r
-                               } else {\r
-                                       value = (X) o;\r
-                               }\r
+                               X value = (X) db.getDialect().deserialize(rs, 1, x.getClass(), typeAdapter);\r
                                result.add(value);\r
                        }\r
                } catch (Exception e) {\r
@@ -850,7 +840,8 @@ public class Query<T> {
                        stat.addParameter(y);\r
                } else if (col != null) {\r
                        // object\r
-                       Object parameter = db.getDialect().serialize(value, col.getFieldDefinition().typeAdapter);\r
+                       Class<? extends DataTypeAdapter<?>> typeAdapter = col.getFieldDefinition().typeAdapter;\r
+                       Object parameter = db.getDialect().serialize(value, typeAdapter);\r
                        stat.addParameter(parameter);\r
                } else {\r
                        // primitive\r
index 33c5369ffa21d8fc307d9193178d69cca7d80823..ccc04529fbeddffcd6c9d428fd76bc51c2670587 100644 (file)
@@ -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.
index 7c656bd5fff8f43740a0e7979915189b99f86d12..8547f3c8a1a14cbfb16392df97d56db7726d2375 100644 (file)
 
 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
index e07cee6ccb37a4c398370e0a488529dae701cd40..8248f187edf8f8c18446ddb04e8b897737039332 100644 (file)
@@ -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);
                }
        }
 
index bf660921b8f796b53f869e275ef560e5ae872b39..f4dbb816928de88fa306d5b815f2c735fd7db700 100644 (file)
@@ -24,6 +24,7 @@ import java.io.Reader;
 import java.io.StringWriter;\r
 import java.lang.annotation.Annotation;\r
 import java.lang.reflect.Constructor;\r
+import java.lang.reflect.Field;\r
 import java.math.BigDecimal;\r
 import java.math.BigInteger;\r
 import java.sql.Blob;\r
@@ -44,6 +45,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import com.iciql.Iciql.DataTypeAdapter;\r
 import com.iciql.Iciql.EnumId;\r
 import com.iciql.Iciql.EnumType;\r
+import com.iciql.Iciql.IQEnum;\r
 import com.iciql.Iciql.TypeAdapter;\r
 import com.iciql.IciqlException;\r
 \r
@@ -352,6 +354,59 @@ public class Utils {
                throw new IciqlException("Can not convert the value {0} from {1} to {2}", o, currentType, targetType);\r
        }\r
 \r
+       /**\r
+        * Identify the EnumType for the field.\r
+        *\r
+        * @param f\r
+        * @return null or the EnumType\r
+        */\r
+       public static EnumType getEnumType(Field f) {\r
+               EnumType enumType = null;\r
+               if (f.getType().isEnum()) {\r
+                       enumType = EnumType.DEFAULT_TYPE;\r
+                       if (f.getType().isAnnotationPresent(IQEnum.class)) {\r
+                               // enum definition is annotated for all instances\r
+                               IQEnum iqenum = f.getType().getAnnotation(IQEnum.class);\r
+                               enumType = iqenum.value();\r
+                       }\r
+                       if (f.isAnnotationPresent(IQEnum.class)) {\r
+                               // this instance of the enum is annotated\r
+                               IQEnum iqenum = f.getAnnotation(IQEnum.class);\r
+                               enumType = iqenum.value();\r
+                       }\r
+               }\r
+               return enumType;\r
+       }\r
+\r
+       /**\r
+        * Identify the EnumType from the annotations.\r
+        *\r
+        * @param annotations\r
+        * @return null or the EnumType\r
+        */\r
+       public static EnumType getEnumType(Annotation [] annotations) {\r
+               EnumType enumType = null;\r
+               if (annotations != null) {\r
+                       for (Annotation annotation : annotations) {\r
+                               if (annotation instanceof IQEnum) {\r
+                                       enumType = ((IQEnum) annotation).value();\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               return enumType;\r
+       }\r
+\r
+       public static Class<?> getEnumTypeClass(Field f) {\r
+               if (f.getType().isEnum()) {\r
+                       if (EnumId.class.isAssignableFrom(f.getType())) {\r
+                               // custom enumid mapping\r
+                               return ((EnumId<?>) f.getType().getEnumConstants()[0]).enumIdClass();\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
        public static Object convertEnum(Enum<?> o, EnumType type) {\r
                if (o == null) {\r
                        return null;\r
@@ -540,7 +595,7 @@ public class Utils {
         * Identify the data type adapter class in the annotations.\r
         *\r
         * @param annotations\r
-        * @return null or the dtaa type adapter class\r
+        * @return null or the data type adapter class\r
         */\r
        public static Class<? extends DataTypeAdapter<?>> getDataTypeAdapter(Annotation [] annotations) {\r
                Class<? extends DataTypeAdapter<?>> typeAdapter = null;\r