(no commit message)
[utils] / support / general / src / main / java / org / wamblee / persistence / PersistentFactory.java
index 91fd2b380095a66707aa578b7a0efb29dfb16059..2ad1526599adf13e29df8a6afe21b9671b02e948 100644 (file)
 package org.wamblee.persistence;
 
 import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -27,10 +23,11 @@ import java.util.concurrent.ConcurrentHashMap;
 import javax.persistence.Id;
 import javax.persistence.Version;
 
-import org.wamblee.reflection.ReflectionUtils;
+import org.wamblee.reflection.Accessor;
+import org.wamblee.reflection.AnnotationUtils;
 
 /**
- * Factory which creates a {@link Persistent} object for a given entity for
+ * Factory which creates a {@link Persistent} object for a given JPA entity for
  * interfacing with the primary key and version of the entity.
  * 
  * This utility only treats primary keys and fields that are annotated with @Id
@@ -47,81 +44,6 @@ public class PersistentFactory {
      */
     private static Map<String, EntityAccessor> CACHE = new ConcurrentHashMap<String, EntityAccessor>();
 
-    static interface Accessor<T> {
-        void set(Object aEntity, T aValue);
-
-        T get(Object aEntity);
-    }
-
-    static class FieldAccessor<T> implements Accessor<T> {
-        private Field field;
-
-        public FieldAccessor(Field aField) {
-            field = aField;
-            field.setAccessible(true);
-        }
-
-        @Override
-        public T get(Object aEntity) {
-            try {
-                return (T) field.get(aEntity);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            } 
-        }
-
-        @Override
-        public void set(Object aEntity, T aValue) {
-            try {
-                field.set(aEntity, aValue);
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException(e.getMessage(), e);
-            }
-        }
-
-        public Field getField() {
-            return field;
-        }
-    }
-
-    static class PropertyAccessor<T> implements Accessor<T> {
-        private Method getter;
-        private Method setter;
-
-        public PropertyAccessor(Method aGetter, Method aSetter) {
-            getter = aGetter;
-            setter = aSetter;
-            getter.setAccessible(true);
-            setter.setAccessible(true);
-        }
-
-        @Override
-        public T get(Object aEntity) {
-            try {
-                return (T) getter.invoke(aEntity);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        @Override
-        public void set(Object aEntity, T aValue) {
-            try {
-                setter.invoke(aEntity, aValue);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            } 
-        }
-
-        public Method getGetter() {
-            return getter;
-        }
-
-        public Method getSetter() {
-            return setter;
-        }
-    }
-
     static class EntityAccessor {
         private Accessor pk;
         private Accessor version;
@@ -155,21 +77,33 @@ public class PersistentFactory {
 
         @Override
         public Serializable getPrimaryKey() {
-            return (Serializable)accessor.getPk().get(entity);
+            if (accessor == null || accessor.getPk() == null) {
+                return null;
+            }
+            return (Serializable) accessor.getPk().get(entity);
         }
 
         @Override
         public void setPrimaryKey(Serializable aKey) {
+            if (accessor == null || accessor.getPk() == null) {
+                return;
+            }
             accessor.getPk().set(entity, aKey);
-        } 
+        }
 
         @Override
         public Number getPersistedVersion() {
-            return (Number)accessor.getVersion().get(entity);
+            if (accessor == null || accessor.getVersion() == null) {
+                return null;
+            }
+            return (Number) accessor.getVersion().get(entity);
         }
 
         @Override
         public void setPersistedVersion(Number aVersion) {
+            if (accessor == null || accessor.getVersion() == null) {
+                return;
+            }
             accessor.getVersion().set(entity, aVersion);
         }
     }
@@ -195,8 +129,17 @@ public class PersistentFactory {
     }
 
     private static EntityAccessor analyse(Class aClass) {
-        Accessor<Serializable> pk = analyse(aClass, Id.class);
-        Accessor<Integer> version = analyse(aClass, Version.class);
+        List<Accessor> pkAccessors = AnnotationUtils.analyse(aClass, Id.class);
+        List<Accessor> versionAccessors = AnnotationUtils.analyse(aClass,
+            Version.class);
+        Accessor<Serializable> pk = null;
+        if (pkAccessors.size() > 0) {
+            pk = pkAccessors.get(0);
+        }
+        Accessor<Integer> version = null;
+        if (versionAccessors.size() > 0) {
+            version = versionAccessors.get(0);
+        }
         if (pk != null || version != null) {
             return new EntityAccessor(pk, version);
         }
@@ -204,55 +147,17 @@ public class PersistentFactory {
     }
 
     /**
-     * Returns the accessor for a given annotation.
+     * Creates the {@link Persistent} wrapper for interfacing with primary key
+     * and version of the entity.
      * 
-     * @param aClass
-     *            Class to analyse.
-     * @param aAnnotation
-     *            Annotation that must be present.
-     * @return Accessor to use or null if the annotation is not present.
-     */
-    private static Accessor analyse(Class aClass,
-        Class<? extends Annotation> aAnnotation) {
-        List<Field> fields = ReflectionUtils.getAllFields(aClass);
-        for (Field field : fields) {
-            if (field.isAnnotationPresent(aAnnotation)) {
-                return new FieldAccessor(field);
-            }
-        }
-        List<Method> methods = ReflectionUtils.getAllMethods(aClass,
-            Object.class);
-        for (Method method : methods) {
-            if (method.isAnnotationPresent(aAnnotation)) {
-                String setterName = null;
-                if (method.getName().startsWith("get")) {
-                    setterName = method.getName().replaceFirst("get", "set");
-                } else if (method.getName().startsWith("is")) {
-                    setterName = method.getName().replaceFirst("is", "set");
-                }
-                try {
-                    Class returnType = method.getReturnType();
-                    Method setter = method.getDeclaringClass().getDeclaredMethod(setterName, returnType);
-                    return new PropertyAccessor(method, setter);
-                } catch (NoSuchMethodException e) {
-                    throw new RuntimeException("Error obtaining setter for " +
-                        method.getName() + " in class " + aClass.getName(), e);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Creates the {@link Persistent} wrapper for interfacing with primary key and 
-     * version of the entity. 
-     * @param aEntity Entity to use. 
-     * @return Persistent object or null if this is not an entity. 
+     * @param aEntity
+     *            Entity to use.
+     * @return Persistent object or null if this is not an entity.
      */
-    public static Persistent create(Object aEntity) { 
+    public static Persistent create(Object aEntity) {
         EntityAccessor accessor = createEntityAccessor(aEntity.getClass());
-        if ( accessor == null ) { 
-            return null; 
+        if (accessor == null) {
+            return null;
         }
         return new EntityObjectAccessor(aEntity, accessor);
     }