org.unitils.mock.core.proxy
Class CloneUtil

java.lang.Object
  extended by org.unitils.mock.core.proxy.CloneUtil

public class CloneUtil
extends Object

Utility class for deep cloning objects. In a deep clone, not only the object itself is cloned, but also all the inner objects.

Author:
Tim Ducheyne, Filip Neven, Kenny Claes

Constructor Summary
CloneUtil()
           
 
Method Summary
protected static Object cloneArray(Object arrayToClone, Map<Object,Object> cloneCache)
          Clones the given array and all it's elements.
protected static void cloneFields(Class<?> clazz, Object instanceToClone, Object clonedInstance, Map<Object,Object> cloneCache)
          Clones all values in all fields of the given class and superclasses.
protected static Object cloneObject(Object instanceToClone, Map<Object,Object> cloneCache)
          Actual implementation of the cloning.
static
<T> T
createDeepClone(T object)
          Creates a deep clone of the given object.
protected static Object createInstanceUsingClone(Object instanceToClone)
          If the given value is cloneable and the cloning succeeds, the clone is returned, else null is returned.
protected static Object createInstanceUsingObjenesis(Object instanceToClone)
          Tries to create an instance of the same type as the given value using Objenesis.
protected static boolean isImmutable(Object instanceToClone)
           
protected static boolean isJdkClass(Object instanceToClone)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

CloneUtil

public CloneUtil()
Method Detail

createDeepClone

public static <T> T createDeepClone(T object)
Creates a deep clone of the given object. If for some reason, the clone cannot be made, a warning is logged and the object itself will be returned. This is also true for all inner objects. If an inner object cannot be cloned, the object itself is used instead.

Parameters:
object - The object to clone
Returns:
The cloned instance

cloneObject

protected static Object cloneObject(Object instanceToClone,
                                    Map<Object,Object> cloneCache)
                             throws Throwable
Actual implementation of the cloning. It will try several ways to clone the object. First it will look for the simple cases: null, primitives, immutables... If not it will check whether it's an array and clone it using the cloneArray(java.lang.Object, java.util.Map) method. Finally it will see whether the object is cloneable and the clone method can be used. If not, Objenisis is used to create the instance. The last step is to recursively do the same operation for the inner fields. An object is cloned once. All created clones are put in a cache and if an object is to be cloned a second time, the cached instance is used. This way the object graph is preserved.

Parameters:
instanceToClone - The instance, not null
cloneCache - The cached clones, not null
Returns:
The clone, the instance to clone if the clone could not be made
Throws:
Throwable

isImmutable

protected static boolean isImmutable(Object instanceToClone)
Parameters:
instanceToClone - The instance, not null
Returns:
True if the instance is immutable, e.g. a primitive

isJdkClass

protected static boolean isJdkClass(Object instanceToClone)
Parameters:
instanceToClone - The instance, not null
Returns:
True if the instance is should not be cloned, e.g. a java lang class or a data source

createInstanceUsingClone

protected static Object createInstanceUsingClone(Object instanceToClone)
If the given value is cloneable and the cloning succeeds, the clone is returned, else null is returned.

Parameters:
instanceToClone - The instance, not null
Returns:
The clone if it could be cloned, else null

createInstanceUsingObjenesis

protected static Object createInstanceUsingObjenesis(Object instanceToClone)
Tries to create an instance of the same type as the given value using Objenesis.

Parameters:
instanceToClone - The instance, not null
Returns:
The new instance if it could be created, else null

cloneFields

protected static void cloneFields(Class<?> clazz,
                                  Object instanceToClone,
                                  Object clonedInstance,
                                  Map<Object,Object> cloneCache)
                           throws Throwable
Clones all values in all fields of the given class and superclasses.

Parameters:
clazz - The current class
instanceToClone - The instance, not null
clonedInstance - The clone, not null
cloneCache - The cached clones, not null
Throws:
Throwable

cloneArray

protected static Object cloneArray(Object arrayToClone,
                                   Map<Object,Object> cloneCache)
                            throws Throwable
Clones the given array and all it's elements.

Parameters:
arrayToClone - The array, not null
cloneCache - The cached clones, not null
Returns:
The cloned array, not null
Throws:
Throwable


Copyright © 2011. All Rights Reserved.