(no commit message)
[utils] / support / spring / src / main / java / org / wamblee / persistence / hibernate / HibernateSupport.java
index 8425facdf6d3c83ebfcf4d870c8eccf0e75a7b60..8eb7790bbf3e0d02fb607983945c7ad5c4a6375d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.wamblee.persistence.hibernate;
 
 import java.lang.reflect.InvocationTargetException;
@@ -22,9 +21,9 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.springframework.orm.hibernate3.HibernateTemplate;
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 import org.wamblee.persistence.Persistent;
@@ -32,36 +31,11 @@ import org.wamblee.persistence.Persistent;
 /**
  * Extension of
  * {@link org.springframework.orm.hibernate.support.HibernateDaoSupport}.
- *
+ * 
  * @author Erik Brakkee
  */
 public class HibernateSupport extends HibernateDaoSupport {
-
-    private static final Log LOG = LogFactory.getLog(HibernateSupport.class);
-
-    /**
-     * 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) {
-            return ((ObjectElem) aObj)._object == _object;
-        }
-
-        public int hashCode() {
-            return _object.hashCode();
-        }
-    }
+    private static final Logger LOG = Logger.getLogger(HibernateSupport.class.getName());
 
     /**
      * Constructs the object.
@@ -72,14 +46,13 @@ public class HibernateSupport extends HibernateDaoSupport {
     }
 
     /**
-     * Performes a hibernate <code>Session.merge()</code> and updates the
-     * object with the correct primary key and version. This is an extension to
-     * the hibernate merge operation because hibernate itself leaves the object
-     * passed to merge untouched.
-     * 
-     * Use this method with extreme caution since it will recursively load all
-     * objects that the current object has relations with and for which
-     * cascade="merge" was specified in the Hibernate mapping file.
+     * Performes a hibernate <code>Session.merge()</code> and updates the object
+     * with the correct primary key and version. This is an extension to the
+     * hibernate merge operation because hibernate itself leaves the object
+     * passed to merge untouched. Use this method with extreme caution since it
+     * will recursively load all objects that the current object has relations
+     * with and for which cascade="merge" was specified in the Hibernate mapping
+     * file.
      * 
      * @param aPersistent
      *            Object to merge.
@@ -116,34 +89,40 @@ public class HibernateSupport extends HibernateDaoSupport {
      * @param aProcessed
      *            List of already processed Persistent objects of the persistent
      *            part.
+     * 
      */
     public static void processPersistent(Persistent aPersistent,
-            Persistent aMerged, List<ObjectElem> aProcessed) {
-        if (aPersistent == null && aMerged == null) {
+        Persistent aMerged, List<ObjectElem> aProcessed) {
+        if ((aPersistent == null) && (aMerged == null)) {
             return;
         }
-        if (aPersistent == null || aMerged == null) {
-            throw new RuntimeException("persistent or merged object is null '"
-                    + aPersistent + "'" + "  '" + aMerged + "'");
+
+        if ((aPersistent == null) || (aMerged == null)) {
+            throw new RuntimeException("persistent or merged object is null '" +
+                aPersistent + "'" + "  '" + aMerged + "'");
         }
+
         ObjectElem elem = new ObjectElem(aPersistent);
+
         if (aProcessed.contains(elem)) {
             return; // already processed.
         }
+
         aProcessed.add(elem);
 
-        LOG.debug("Setting pk/version on " + aPersistent + " from " + aMerged);
+        LOG.fine("Setting pk/version on " + aPersistent + " from " + aMerged);
 
-        if (aPersistent.getPrimaryKey() != null
-                && !aMerged.getPrimaryKey().equals(aPersistent.getPrimaryKey())) {
-            LOG.error("Mismatch between primary key values: " + aPersistent
-                    + " " + aMerged);
+        if ((aPersistent.getPrimaryKey() != null) &&
+            !aMerged.getPrimaryKey().equals(aPersistent.getPrimaryKey())) {
+            LOG.warning("Mismatch between primary key values: " + aPersistent +
+                " " + aMerged);
         } else {
             aPersistent.setPersistedVersion(aMerged.getPersistedVersion());
             aPersistent.setPrimaryKey(aMerged.getPrimaryKey());
         }
 
         Method[] methods = aPersistent.getClass().getMethods();
+
         for (Method getter : methods) {
             if (getter.getName().startsWith("get")) {
                 Class returnType = getter.getReturnType();
@@ -164,18 +143,19 @@ public class HibernateSupport extends HibernateDaoSupport {
                     } else if (Persistent.class.isAssignableFrom(returnType)) {
                         Persistent merged = (Persistent) getter.invoke(aMerged);
                         Persistent persistent = (Persistent) getter
-                                .invoke(aPersistent);
+                            .invoke(aPersistent);
                         processPersistent(persistent, merged, aProcessed);
-                    } else if (returnType.isArray()
-                            && Persistent.class.isAssignableFrom(returnType
-                                    .getComponentType())) {
+                    } else if (returnType.isArray() &&
+                        Persistent.class.isAssignableFrom(returnType
+                            .getComponentType())) {
                         Persistent[] merged = (Persistent[]) getter
-                                .invoke(aMerged);
+                            .invoke(aMerged);
                         Persistent[] persistent = (Persistent[]) getter
-                                .invoke(aPersistent);
+                            .invoke(aPersistent);
+
                         for (int i = 0; i < persistent.length; i++) {
                             processPersistent(persistent[i], merged[i],
-                                    aProcessed);
+                                aProcessed);
                         }
                     }
                 } catch (InvocationTargetException e) {
@@ -185,7 +165,6 @@ public class HibernateSupport extends HibernateDaoSupport {
                 }
             }
         }
-
     }
 
     /**
@@ -197,20 +176,24 @@ public class HibernateSupport extends HibernateDaoSupport {
      *            Collection as a result of the merge.
      * @param aProcessed
      *            List of processed persistent objects.
+     * 
      */
     public static void processList(List aPersistent, List aMerged,
-            List<ObjectElem> aProcessed) {
+        List<ObjectElem> aProcessed) {
         Object[] merged = aMerged.toArray();
         Object[] persistent = aPersistent.toArray();
+
         if (merged.length != persistent.length) {
-            throw new RuntimeException("Array sizes differ " + merged.length
-                    + " " + persistent.length);
+            throw new RuntimeException("Array sizes differ " + merged.length +
+                " " + persistent.length);
         }
+
         for (int i = 0; i < merged.length; i++) {
             assert merged[i].equals(persistent[i]);
+
             if (merged[i] instanceof Persistent) {
                 processPersistent((Persistent) persistent[i],
-                        (Persistent) merged[i], aProcessed);
+                    (Persistent) merged[i], aProcessed);
             }
         }
     }
@@ -224,19 +207,22 @@ public class HibernateSupport extends HibernateDaoSupport {
      *            Collection as a result of the merge.
      * @param aProcessed
      *            List of processed persistent objects.
+     * 
      */
     public static void processSet(Set aPersistent, Set aMerged,
-            List<ObjectElem> aProcessed) {
+        List<ObjectElem> aProcessed) {
         if (aMerged.size() != aPersistent.size()) {
-            throw new RuntimeException("Array sizes differ " + aMerged.size()
-                    + " " + aPersistent.size());
+            throw new RuntimeException("Array sizes differ " + aMerged.size() +
+                " " + aPersistent.size());
         }
+
         for (Object merged : aMerged) {
             // Find the object that equals the merged[i]
             for (Object persistent : aPersistent) {
                 if (persistent.equals(merged)) {
                     processPersistent((Persistent) persistent,
-                            (Persistent) merged, aProcessed);
+                        (Persistent) merged, aProcessed);
+
                     break;
                 }
             }
@@ -252,30 +238,64 @@ public class HibernateSupport extends HibernateDaoSupport {
      *            Collection as a result of the merge.
      * @param aProcessed
      *            List of processed persistent objects.
+     * 
      */
-    public static void processMap(Map aPersistent, Map aMerged,
-            List<ObjectElem> aProcessed) {
+    public static <Key,Value> void processMap(Map<Key,Value> aPersistent, Map<Key,Value> aMerged,
+        List<ObjectElem> aProcessed) {
         if (aMerged.size() != aPersistent.size()) {
-            throw new RuntimeException("Sizes differ " + aMerged.size() + " "
-                    + aPersistent.size());
+            throw new RuntimeException("Sizes differ " + aMerged.size() + " " +
+                aPersistent.size());
         }
-        Set keys = aMerged.keySet();
-        for (Object key : keys) {
+
+        Set<Entry<Key,Value>> entries = aMerged.entrySet();
+
+        for (Entry<Key,Value> entry : entries) {
+            Key key = entry.getKey();
             if (!aPersistent.containsKey(key)) {
                 throw new RuntimeException("Key '" + key + "' not found");
             }
-            Object mergedValue = aMerged.get(key);
+
+            Value mergedValue = entry.getValue();
             Object persistentValue = aPersistent.get(key);
+
             if (mergedValue instanceof Persistent) {
                 if (persistentValue instanceof Persistent) {
                     processPersistent((Persistent) persistentValue,
-                            (Persistent) mergedValue, aProcessed);
+                        (Persistent) mergedValue, aProcessed);
                 } else {
                     throw new RuntimeException(
-                            "Value in original object is null, whereas merged object contains a value");
+                        "Value in original object is null, whereas merged object contains a value");
                 }
             }
         }
     }
 
+    /**
+     * 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();
+        }
+    }
 }