akshayyn / cloning

Automatically exported from code.google.com/p/cloning
Other
0 stars 0 forks source link

Documentation says that I can use one instance of Cloner throughout the application #5

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create an instance of Cloner
2. Invoke the method 'nullInsteadOfClone' with a valid argument on that instance
3. 'deepClone' it
4. Invoke the method 'registerImmutable' with the same argument on step 2 on 
the same instance created
5. 'deepClone' it again. The line unit-test validation line 
'assertTrue(clonedPerson.profession != null);' in the unit-test below fails as 
profession is null.

What is the expected output? What do you see instead?
Expected: The cloned object with the same instance of its mutable internal 
object which was explicitly chosen not to be cloned.
Actual result: The internal object above is null.

What version of the product are you using? On what operating system?
Product version: 1.7.9
OS: Windows XP Professional SP3

Please provide any additional information below.
Please note that this issue relates to (what I believe to be) a bug in 
documentation which states "You can create a single instance of cloner and use 
it throughout your application[...]".
Find below the Utility class I created to encapsulate 'Cloner' and below it the 
relevant part of the unit-tests I was working on:
============= UTIL CLASS ===========================
import com.rits.cloning.Cloner;

/**
 * 
 * @author fabio.serragnoli
 */
public final class CloneUtils {
    private static final Cloner CLONER = new Cloner(); 

    public static <T> T shallowClone(final T pToBeClonedObject) {
    final T clonedObject = CLONER.shallowClone(pToBeClonedObject);

    return clonedObject;
    }

    public static <T> T deepCloneNullInsteadOfClone(final T pToBeClonedObject, final Class<?>... pNullInsteadOfClone) {
    CLONER.nullInsteadOfClone(pNullInsteadOfClone);
    final T clonedObject = CLONER.deepClone(pToBeClonedObject);

    return clonedObject;
    }

    public static <T> T deepCloneRegisterImmutable(final T pToBeClonedObject, final Class<?>... pImmutable) {
    CLONER.registerImmutable(pImmutable);
    final T clonedObject = CLONER.deepClone(pToBeClonedObject);

    return clonedObject;
    }
}

============= UNIT TEST CLASS ===========================
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;;

/**
 * 
 * @author fabio.serragnoli
 *
 */
public class CloneUtilsTest {

    @Test
    public void deepCloneWithInternalMutableObjectChosenToBeNull() {
    final Person person = new Person();
    final City nyc = new City("NYC");
    final Profession profession = new Profession("Musician");
    person.visitedCities.add(nyc);
    person.profession = profession;

    final Person clonedPerson = CloneUtils.deepCloneNullInsteadOfClone(person, Profession.class);   

    assertThat(clonedPerson.profession, is(nullValue()));   
    }

    @Test
    public void deepCloneWithInternaMutableObjectChosenNotToBeCloned() {
    final Person person = new Person();
    final City nyc = new City("NYC");
    final Profession profission = new Profession("Musician");
    person.visitedCities.add(nyc);
    person.profession = profission;

    final Person clonedPerson = CloneUtils.deepCloneRegisterImmutable(person, Profession.class);    

    assertTrue(clonedPerson.profession != null);
    }

   private static class Person {
    private String name = "Jerry Lee Lewis";
    private Set<City> visitedCities = new HashSet<City>();
    private Profession profession = new Profession("Singer");
    }

    private static class Profession {
    private String name;

    Profession(final String pName) {
        this.name = pName;
    }
    }

    private static class City {
    private String name;

    City(final String pName) {
        name = pName;
    }   
    }
}

Original issue reported on code.google.com by serragn...@gmail.com on 29 Feb 2012 at 6:51

GoogleCodeExporter commented 8 years ago
Hi, "You can create a single instance of cloner and use it throughout your 
application[...]". I've modified this to "You can create a single instance of 
cloner and use it throughout your application to deep clone objects. Once 
instantiated and configured, then the cloner is thread safe and can be reused, 
provided it's configuration is not altered. "

Cloner has to be configured once (i.e. register all nullsInsteadOfClone and all 
immutables) but then only used for deep cloning object. A builder might have 
been better to create an immutable Cloner instance but then things would be 
hard to configure cloner via spring as a bean.

I hope this solves the issue, please let me know if it's ok to close the bug.

Original comment by kostas.k...@googlemail.com on 7 Mar 2012 at 9:07

GoogleCodeExporter commented 8 years ago
Closing the issue, please let me know for any other issues.

Original comment by kostas.k...@googlemail.com on 14 Mar 2012 at 8:58