This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/version3 by this push:
     new 280e148  EMPIREDB-362 ClassUtils copy fix
280e148 is described below

commit 280e148dc44b7ab78a3a78150c9fcd21c024ea6e
Author: Rainer Döbele <[email protected]>
AuthorDate: Thu Feb 10 09:47:00 2022 +0100

    EMPIREDB-362 ClassUtils copy fix
---
 .../java/org/apache/empire/commons/ClassUtils.java | 51 ++++++++++++++++++----
 .../java/org/apache/empire/db/DBRecordBase.java    |  5 +--
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java 
b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
index 0ccc30a..6f255f1 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
@@ -82,13 +82,44 @@ public final class ClassUtils
     }
     
     /**
-     * Makes a copy of an object if possible or returns null 
+     * Namespace for Copy flags
+     * @author rainer
+     */
+    public static class Copy
+    {
+        public static final int RET_SELF        = 0x00; /* default */
+        public static final int RET_NULL        = 0x01;
+
+        public static final int RECURSE_SHALLOW = 0x02; /* only for default 
constructor cloning */
+
+        public static final int SKIP_CLONE      = 0x10;
+        public static final int SKIP_SERIAL     = 0x20;
+        public static final int SKIP_INST       = 0x40;
+        
+        public static boolean has(int flags, int flag)
+        {
+            return ((flags & flag)!=0);
+        }
+    }
+
+    /**
+     * Makes a copy of an object if possible or returns the object itself if 
copy is not supported 
      * @param obj the object to copy
-     * @return either a copy of the object or null if copy is not supported
+     * @return either a copy of the object or the object itself if copy is not 
supported
      */
-    @SuppressWarnings("unchecked")
     public static <T> T copy(T obj)
     {
+        return copy(obj, Copy.RET_SELF | Copy.SKIP_SERIAL); /* Serial is too 
hot */
+    }
+    
+    /**
+     * Makes a copy of an object if possible or returns null or self 
(depending on flags) 
+     * @param obj the object to copy
+     * @return either a copy of the object or null the object itself
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T copy(T obj, int flags)
+    {
         if (obj==null)
             return null;
         // the class
@@ -103,7 +134,7 @@ public final class ClassUtils
             return obj; 
         }
         // try clonable
-        if (obj instanceof Cloneable)
+        if ((obj instanceof Cloneable) && !Copy.has(flags, Copy.SKIP_CLONE))
         {   try {
                 return (T)invokeSimpleMethod(java.lang.Object.class, obj, 
"clone", true);
             } catch (Exception e) {
@@ -111,7 +142,7 @@ public final class ClassUtils
             }
         }
         // try serializable
-        if (obj instanceof Serializable)
+        if ((obj instanceof Serializable) && !Copy.has(flags, 
Copy.SKIP_SERIAL))
         {   try
             {   ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 // Write the object
@@ -127,7 +158,7 @@ public final class ClassUtils
             }
         }
         // try copy through Instantiation
-        Constructor<T> ctor = findMatchingConstructor(clazz, 0, clazz);
+        Constructor<T> ctor = (Copy.has(flags, Copy.SKIP_INST) ? null : 
findMatchingConstructor(clazz, 0, clazz));
         if (ctor!=null)
         {   try
             {   if (ctor.getParameterCount()==1)
@@ -147,8 +178,10 @@ public final class ClassUtils
                             if (!accessible)
                                 field.setAccessible(true);
                             // copy
-                            Object value = field.get(obj); // recurse ?
-                            field.set(copy, copy(value));
+                            Object value = field.get(obj);
+                            if (!Copy.has(flags, Copy.RECURSE_SHALLOW))
+                                value = copy(value, (flags & ~Copy.RET_NULL) | 
Copy.RECURSE_SHALLOW);
+                            field.set(copy, value);
                             // restore
                             if (!accessible)
                                 field.setAccessible(false);
@@ -161,7 +194,7 @@ public final class ClassUtils
             }
         }
         // not supported
-        return null;
+        return (Copy.has(flags, Copy.RET_NULL) ? null : obj);
     }
     
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java 
b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
index 3ec6dcc..ea452a5 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
@@ -186,10 +186,7 @@ public abstract class DBRecordBase extends DBRecordData 
implements Record, Clone
                 return null;
             if (other instanceof Object[])
                 return copy((Object[])other);
-            Object copy = ClassUtils.copy(other);
-            if (copy!=null)
-                return copy;
-            return other;
+            return ClassUtils.copy(other);
         }
     }
   

Reply via email to