r1936 - in trunk/src: main/java/org/nuiton/util test/java/org/nuiton/util
Author: bpoussin Date: 2010-10-22 15:13:20 +0200 (Fri, 22 Oct 2010) New Revision: 1936 Url: http://nuiton.org/repositories/revision/nuiton-utils/1936 Log: add method clone and deepClone on ObjectUtil http://www.nuiton.org/issues/show/971 Modified: trunk/src/main/java/org/nuiton/util/ObjectUtil.java trunk/src/test/java/org/nuiton/util/ObjectUtilTest.java Modified: trunk/src/main/java/org/nuiton/util/ObjectUtil.java =================================================================== --- trunk/src/main/java/org/nuiton/util/ObjectUtil.java 2010-10-21 09:29:28 UTC (rev 1935) +++ trunk/src/main/java/org/nuiton/util/ObjectUtil.java 2010-10-22 13:13:20 UTC (rev 1936) @@ -36,9 +36,17 @@ package org.nuiton.util; +import com.sun.corba.se.impl.orbutil.ObjectWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.beanutils.MethodUtils; import static org.nuiton.i18n.I18n._; @@ -132,8 +140,61 @@ } return t; } - + /** + * Clone object by introspection because Cloneable interface don't permit + * to call clone :(. This methode replace next code that don't work :( + * + * <pre> + * if (o instanceof Cloneable) { + * Object n = ((Cloneable)o).clone(); + * } + * </pre> + * + * @param e object to clone + * @return new instance of E + * @throws CloneNotSupportedException if some error occur during clone + */ + static public <E extends Cloneable> E clone(E e) throws CloneNotSupportedException { + try { + E result = (E) MethodUtils.invokeExactMethod(e, "clone", null); + return result; + } catch (Exception eee) { + // on est oblige de faire un log, car CloneNotSupportedException + // ne prend pas d'exception en arguement :( + log.error("Can't clone object", eee); + throw new CloneNotSupportedException(); + } + } + + /** + * Use serialization/deserialization to do deep clone of object + * @param e object to clone + * @return new instance of E + * @throws CloneNotSupportedException if some error occur during clone + */ + static public <E> E deepClone(E e) throws CloneNotSupportedException { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(e); + oos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + E result = (E) ois.readObject(); + ois.close(); + + return result; + } catch (Exception eee) { + // on est oblige de faire un log, car CloneNotSupportedException + // ne prend pas d'exception en arguement :( + log.error("Can't clone object", eee); + throw new CloneNotSupportedException(); + } + } + + /** * Call method m with params as String. Each param is converted to required type for * method with beanutils converter * @param o object where method must be call Modified: trunk/src/test/java/org/nuiton/util/ObjectUtilTest.java =================================================================== --- trunk/src/test/java/org/nuiton/util/ObjectUtilTest.java 2010-10-21 09:29:28 UTC (rev 1935) +++ trunk/src/test/java/org/nuiton/util/ObjectUtilTest.java 2010-10-22 13:13:20 UTC (rev 1936) @@ -41,6 +41,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import org.junit.Assert; import org.junit.Test; @@ -53,7 +54,7 @@ public class ObjectUtilTest extends Assert { @Test - public void testCall() throws Exception { + public void testCall() throws Exception { Dummy dummy = new Dummy(); List<Method> methods = ObjectUtil.getMethod(Dummy.class, "setfile", true); @@ -72,10 +73,32 @@ assertEquals("toto", dummy.getName()); assertEquals(new ArrayList<File>(), Arrays.asList(dummy.getAllFile())); -} - -@Test - public void testCreate() throws Exception { + } + + @Test + public void testClone() throws Exception { + ArrayList c = new ArrayList(); + ArrayList inner = new ArrayList(); + c.add(inner); + + ArrayList n = ObjectUtil.clone(c); + Assert.assertNotSame(c, n); + Assert.assertSame(c.get(0), n.get(0)); + } + + @Test + public void testDeepClone() throws Exception { + ArrayList c = new ArrayList(); + ArrayList inner = new ArrayList(); + c.add(inner); + + ArrayList n = ObjectUtil.deepClone(c); + Assert.assertNotSame(c, n); + Assert.assertNotSame(c.get(0), n.get(0)); + } + + @Test + public void testCreate() throws Exception { Object o = ObjectUtil.create("java.lang.StringBuffer"); assertTrue(o != null); assertTrue(o instanceof StringBuffer);
Le Fri, 22 Oct 2010 15:13:20 +0200 (CEST), bpoussin@users.nuiton.org a écrit : Ben, Les méthodes close doivent tjs etre effectuées dans un block finally :)
+ /** + * Use serialization/deserialization to do deep clone of object + * @param e object to clone + * @return new instance of E + * @throws CloneNotSupportedException if some error occur during clone + */ + static public <E> E deepClone(E e) throws CloneNotSupportedException { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(e); + oos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + E result = (E) ois.readObject(); + ois.close(); + + return result; + } catch (Exception eee) { + // on est oblige de faire un log, car CloneNotSupportedException + // ne prend pas d'exception en arguement :( + log.error("Can't clone object", eee); + throw new CloneNotSupportedException(); + } + }
-- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
participants (2)
-
bpoussin@users.nuiton.org -
chemit