(no commit message)
[utils] / support / general / src / main / java / org / wamblee / persistence / JpaMergeSupport.java
index be188e2dceccb5444c514abea4755e135208afd0..f82f8255d0ba7f542475a37973ef343f4487a459 100644 (file)
@@ -24,12 +24,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.logging.Logger;
 
 import javax.persistence.EntityManager;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.wamblee.persistence.PersistentFactory.EntityAccessor;
+import org.wamblee.general.ObjectElem;
 import org.wamblee.reflection.ReflectionUtils;
 
 /**
@@ -55,7 +54,7 @@ import org.wamblee.reflection.ReflectionUtils;
  * @author Erik Brakkee
  */
 public class JpaMergeSupport {
-    private static final Log LOG = LogFactory.getLog(JpaMergeSupport.class);
+    private static final Logger LOG = Logger.getLogger(JpaMergeSupport.class.getName());
 
     /**
      * Constructs the object.
@@ -81,9 +80,9 @@ public class JpaMergeSupport {
     /**
      * Copies primary keys and version from the result of the merged to the
      * object that was passed to the merge operation. It does this by traversing
-     * the properties of the object. It copies the primary key and version for
-     * objects that implement {@link Persistent} and applies the same rules to
-     * objects in maps and sets as well (i.e. recursively).
+     * the public properties of the object. It copies the primary key and
+     * version for objects that implement {@link Persistent} and applies the
+     * same rules to objects in maps and sets as well (i.e. recursively).
      * 
      * @param aPersistent
      *            Object whose primary key and version are to be set.
@@ -113,7 +112,7 @@ public class JpaMergeSupport {
 
         aProcessed.add(elem);
 
-        LOG.debug("Setting pk/version on " + aPersistent + " from " + aMerged);
+        LOG.fine("Setting pk/version on " + aPersistent + " from " + aMerged);
 
         Persistent persistentWrapper = PersistentFactory.create(aPersistent);
         Persistent mergedWrapper = PersistentFactory.create(aMerged);
@@ -140,11 +139,10 @@ public class JpaMergeSupport {
             throw new IllegalArgumentException(
                 "Mismatch between primary key values: " + aPersistent + " " +
                     aMerged);
-        } else {
-            persistentWrapper.setPersistedVersion(mergedWrapper
-                .getPersistedVersion());
-            persistentWrapper.setPrimaryKey(mergedWrapper.getPrimaryKey());
         }
+        persistentWrapper.setPersistedVersion(mergedWrapper
+            .getPersistedVersion());
+        persistentWrapper.setPrimaryKey(mergedWrapper.getPrimaryKey());
 
         List<Method> methods = ReflectionUtils.getAllMethods(aPersistent
             .getClass(), Object.class);
@@ -152,7 +150,10 @@ public class JpaMergeSupport {
         for (Method getter : methods) {
             if ((getter.getName().startsWith("get") || getter.getName()
                 .startsWith("is")) &&
-                !Modifier.isStatic(getter.getModifiers())) {
+                !Modifier.isStatic(getter.getModifiers()) &&
+                Modifier.isPublic(getter.getModifiers()) &&
+                getter.getParameterTypes().length == 0 &&
+                getter.getReturnType() != Void.class) {
                 Class returnType = getter.getReturnType();
 
                 try {
@@ -169,22 +170,17 @@ public class JpaMergeSupport {
                         Map persistent = (Map) getter.invoke(aPersistent);
                         processMap(merged, persistent, aProcessed);
                     } else if (returnType.isArray()) {
-                        // early detection of whether it is an array of entities
-                        // to avoid performance problems.
-                        EntityAccessor accessor = PersistentFactory
-                            .createEntityAccessor(returnType.getComponentType());
-                        if (accessor != null) {
-                            Object[] merged = (Object[]) getter.invoke(aMerged);
-                            Object[] persistent = (Object[]) getter
-                                .invoke(aPersistent);
-                            if (merged.length != persistent.length) {
-                                throw new IllegalArgumentException("Array sizes differ " + merged.length +
-                                    " " + persistent.length);
-                            }
-                            for (int i = 0; i < persistent.length; i++) {
-                                processPersistent(merged[i], persistent[i],
-                                    aProcessed);
-                            }
+                        Object[] merged = (Object[]) getter.invoke(aMerged);
+                        Object[] persistent = (Object[]) getter
+                            .invoke(aPersistent);
+                        if (merged.length != persistent.length) {
+                            throw new IllegalArgumentException(
+                                "Array sizes differ " + merged.length + " " +
+                                    persistent.length);
+                        }
+                        for (int i = 0; i < persistent.length; i++) {
+                            processPersistent(merged[i], persistent[i],
+                                aProcessed);
                         }
                     } else {
                         Object merged = getter.invoke(aMerged);
@@ -217,8 +213,8 @@ public class JpaMergeSupport {
         Object[] persistent = aPersistent.toArray();
 
         if (merged.length != persistent.length) {
-            throw new IllegalArgumentException("Array sizes differ " + merged.length +
-                " " + persistent.length);
+            throw new IllegalArgumentException("Array sizes differ " +
+                merged.length + " " + persistent.length);
         }
 
         for (int i = 0; i < merged.length; i++) {
@@ -241,8 +237,8 @@ public class JpaMergeSupport {
     public static void processSet(Set aMerged, Set aPersistent,
         List<ObjectElem> aProcessed) {
         if (aMerged.size() != aPersistent.size()) {
-            throw new IllegalArgumentException("Array sizes differ " + aMerged.size() +
-                " " + aPersistent.size());
+            throw new IllegalArgumentException("Array sizes differ " +
+                aMerged.size() + " " + aPersistent.size());
         }
 
         for (Object merged : aMerged) {
@@ -270,8 +266,8 @@ public class JpaMergeSupport {
     public static <Key, Value> void processMap(Map<Key, Value> aMerged,
         Map<Key, Value> aPersistent, List<ObjectElem> aProcessed) {
         if (aMerged.size() != aPersistent.size()) {
-            throw new IllegalArgumentException("Sizes differ " + aMerged.size() + " " +
-                aPersistent.size());
+            throw new IllegalArgumentException("Sizes differ " +
+                aMerged.size() + " " + aPersistent.size());
         }
 
         Set<Entry<Key, Value>> entries = aMerged.entrySet();
@@ -279,7 +275,8 @@ public class JpaMergeSupport {
         for (Entry<Key, Value> entry : entries) {
             Key key = entry.getKey();
             if (!aPersistent.containsKey(key)) {
-                throw new IllegalArgumentException("Key '" + key + "' not found");
+                throw new IllegalArgumentException("Key '" + key +
+                    "' not found");
             }
 
             Value mergedValue = entry.getValue();
@@ -288,33 +285,4 @@ public class JpaMergeSupport {
             processPersistent(mergedValue, persistentValue, aProcessed);
         }
     }
-
-    /**
-     * This class provided an equality operation based on the object reference
-     * of the wrapped object. This is required because we cannto assume that the
-     * equals operation has any meaning for different types of persistent
-     * objects. This allows us to use the standard collection classes for
-     * detecting cyclic dependences and avoiding recursion.
-     */
-    private static final class ObjectElem {
-        private Object object;
-
-        public ObjectElem(Object aObject) {
-            object = aObject;
-        }
-
-        public boolean equals(Object aObj) {
-            if (aObj == null) {
-                return false;
-            }
-            if (!(aObj instanceof ObjectElem)) {
-                return false;
-            }
-            return ((ObjectElem) aObj).object == object;
-        }
-
-        public int hashCode() {
-            return object.hashCode();
-        }
-    }
 }