From bc8dfab419eb81195c132f3d49a913500e2e09e6 Mon Sep 17 00:00:00 2001 From: "Kevin W. Sutter" Date: Mon, 8 Oct 2007 21:06:45 +0000 Subject: [PATCH] OPENJPA-396. Going ahead with the commit of the patch. Per the discussion in the Issue and the dev mailing list, I have added a few more comments to the clone() generation. Thanks. git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.0.x@582974 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/openjpa/util/ProxyManagerImpl.java | 26 +++++++ .../apache/openjpa/util/TestProxyManager.java | 76 +++++++++++++++++-- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java index f8325dfef..48fcad751 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java @@ -719,6 +719,32 @@ public class ProxyManagerImpl code.calculateMaxStack(); code.calculateMaxLocals(); + /* + * clone (return detached proxy object) + * Note: This method is only being provided to satisfy a quirk with + * the IBM JDK -- while comparing Calendar objects, the clone() method + * was invoked. So, we are now overriding the clone() method so as to + * provide a detached proxy object (null out the StateManager). + */ + m = bc.declareMethod("clone", Object.class, null); + m.makePublic(); + code = m.getCode(true); + code.aload().setThis(); + code.invokespecial().setMethod(bc.getSuperclassType(), "clone", + Object.class, null); + code.checkcast().setType(Proxy.class); + int other = code.getNextLocalsIndex(); + code.astore().setLocal(other); + code.aload().setLocal(other); + code.constant().setNull(); + code.constant().setValue(0); + code.invokeinterface().setMethod(Proxy.class, "setOwner", void.class, + new Class[] { OpenJPAStateManager.class, int.class }); + code.aload().setLocal(other); + code.areturn(); + code.calculateMaxStack(); + code.calculateMaxLocals(); + if (changeTracker) { m = bc.declareMethod("getChangeTracker", ChangeTracker.class, null); m.makePublic(); diff --git a/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java b/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java index ac9d66c21..53fa96c21 100644 --- a/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java +++ b/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java @@ -46,6 +46,7 @@ import java.util.TreeSet; import java.util.TreeMap; import java.util.Vector; +import org.apache.openjpa.util.Proxy; import junit.framework.TestCase; import junit.textui.TestRunner; @@ -151,12 +152,20 @@ public class TestProxyManager */ private static void assertSortedSetsEqual(SortedSet s1, SortedSet s2) { assertTrue(s1.getClass() == s2.getClass()); + assertSortedSetsEquals(s1, s2); + } + + /** + * Assert that the given sets are exactly the same (minus the class). + */ + private static void assertSortedSetsEquals(SortedSet s1, SortedSet s2) { assertEquals(s1.comparator(), s2.comparator()); assertEquals(s1.size(), s2.size()); Iterator itr1 = s1.iterator(); Iterator itr2 = s2.iterator(); while (itr1.hasNext()) assertTrue(itr1.next() == itr2.next()); + assertTrue(s1.equals(s2)); } public void testCopyNullCollection() { @@ -176,6 +185,16 @@ public class TestProxyManager _mgr.copyCollection(torig)); } + public void testCloneProxyCollection() { + // List doesn't support clone() + + TreeSet torig = (TreeSet) _mgr.newCollectionProxy(TreeSet.class, null, + new CustomComparator()); + assertTrue(torig.comparator() instanceof CustomComparator); + populate(torig); + assertSortedSetsEquals(new TreeSet(torig), (SortedSet) torig.clone()); + } + public void testListMethodsProxied() throws Exception { Class proxy = _mgr.newCollectionProxy(ArrayList.class, null, null). @@ -433,6 +452,13 @@ public class TestProxyManager */ private static void assertSortedMapsEqual(SortedMap m1, SortedMap m2) { assertTrue(m1.getClass() == m2.getClass()); + assertSortedMapsEquals(m1, m2); + } + + /** + * Assert that the given maps are exactly the same (minus the class). + */ + private static void assertSortedMapsEquals(SortedMap m1, SortedMap m2) { assertEquals(m1.comparator(), m2.comparator()); assertEquals(m1.size(), m2.size()); Map.Entry entry1; @@ -445,6 +471,7 @@ public class TestProxyManager assertTrue(entry1.getKey() == entry2.getKey()); assertTrue(entry1.getValue() == entry2.getValue()); } + assertTrue(m1.equals(m2)); } public void testCopyNullMap() { @@ -464,6 +491,16 @@ public class TestProxyManager _mgr.copyMap(torig)); } + public void testCloneProxyMap() { + // Map does not support clone() + + TreeMap torig = (TreeMap) _mgr.newMapProxy(TreeMap.class, null, null, + new CustomComparator()); + assertTrue(torig.comparator() instanceof CustomComparator); + populate(torig); + assertSortedMapsEquals(new TreeMap(torig), (SortedMap) torig.clone()); + } + public void testMapMethodsProxied() throws Exception { Class proxy = _mgr.newMapProxy(HashMap.class, null, null, null). @@ -551,8 +588,15 @@ public class TestProxyManager * Assert that the given dates are exactly the same. */ private static void assertDatesEqual(Date d1, Date d2) { - assertTrue(d1.getClass() == d1.getClass()); - assertEquals(d1, d2); + assertTrue(d1.getClass() == d2.getClass()); + assertDatesEquals(d1, d2); + } + + /** + * Assert that the given dates are exactly the same (minus the class). + */ + private static void assertDatesEquals(Date d1, Date d2) { + assertTrue(d1.equals(d2)); } public void testCopyNullDate() { @@ -562,7 +606,13 @@ public class TestProxyManager public void testCopyProxyDate() { Date orig = (Date) _mgr.newDateProxy(Time.class); orig.setTime(1999); - assertDatesEqual(new Date(orig.getTime()), (Date) _mgr.copyDate(orig)); + assertDatesEqual(new Time(orig.getTime()), (Date) _mgr.copyDate(orig)); + } + + public void testCloneProxyDate() { + Date orig = (Date) _mgr.newDateProxy(Time.class); + orig.setTime(1999); + assertDatesEquals(new Time(orig.getTime()), (Date) orig.clone()); } public void testDateMethodsProxied() @@ -647,8 +697,15 @@ public class TestProxyManager * Assert that the given dates are exactly the same. */ private static void assertCalendarsEqual(Calendar c1, Calendar c2) { - assertTrue(c1.getClass() == c1.getClass()); - assertEquals(c1, c2); + assertTrue(c1.getClass() == c2.getClass()); + assertCalendarsEquals(c1, c2); + } + + /** + * Assert that the given dates are exactly the same (minus the class). + */ + private static void assertCalendarsEquals(Calendar c1, Calendar c2) { + assertTrue(c1.equals(c2)); } public void testCopyNullCalendar() { @@ -664,6 +721,15 @@ public class TestProxyManager assertCalendarsEqual(cal, _mgr.copyCalendar(orig)); } + public void testCloneProxyCalendar() { + Calendar orig = (Calendar) _mgr.newCalendarProxy + (GregorianCalendar.class, TimeZone.getTimeZone("CST")); + populate(orig); + Calendar cal = new GregorianCalendar(); + populate(cal); + assertCalendarsEquals(cal, (Calendar)orig.clone()); + } + public void testCalendarAbstractClassProxy() { Proxy cal = _mgr.newCalendarProxy(Calendar.class, null); assertNotNull(cal);