Added: incubator/openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java?view=auto&rev=484693 ============================================================================== --- incubator/openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java (added) +++ incubator/openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/util/TestProxyManager.java Fri Dec 8 10:32:07 2006 @@ -0,0 +1,971 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.util; + +import java.io.InputStream; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.AbstractMap; +import java.util.AbstractSequentialList; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TimeZone; +import java.util.TreeSet; +import java.util.TreeMap; +import java.util.Vector; + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * Test proxies generated by the proxy manager. + * + * @author Abe White + */ +public class TestProxyManager + extends TestCase { + + private ProxyManagerImpl _mgr; + + public void setUp() { + _mgr = new ProxyManagerImpl(); + } + + public void testCopyLists() { + List orig = new ArrayList(); + populate(orig); + assertListsEqual(orig, (List) _mgr.copyCollection(orig)); + + orig = new LinkedList(); + populate(orig); + assertListsEqual(orig, (List) _mgr.copyCollection(orig)); + + orig = new CustomList(); + populate(orig); + assertListsEqual(orig, (List) _mgr.copyCollection(orig)); + } + + /** + * Populate the given list with arbitrary data. + */ + private static void populate(Collection coll) { + coll.add(new Integer(1)); + coll.add("foo"); + coll.add(new Long(99)); + coll.add("bar"); + coll.add(new Short((short) 50)); + } + + /** + * Assert that the given lists are exactly the same. + */ + private static void assertListsEqual(List l1, List l2) { + assertTrue(l1.getClass() == l2.getClass()); + assertEquals(l1.size(), l2.size()); + for (int i = 0; i < l1.size(); i++) + assertTrue(l1.get(i) + " != " + l2.get(i), l1.get(i) == l2.get(i)); + } + + public void testCopySets() { + Set orig = new HashSet(); + populate(orig); + assertSetsEqual(orig, (Set) _mgr.copyCollection(orig)); + + orig = new CustomSet(); + populate(orig); + assertSetsEqual(orig, (Set) _mgr.copyCollection(orig)); + } + + /** + * Assert that the given sets are exactly the same. + */ + private static void assertSetsEqual(Set s1, Set s2) { + assertTrue(s1.getClass() == s2.getClass()); + assertEquals(s1.size(), s2.size()); + assertEquals(s1, s2); + } + + public void testCopySortedSets() { + SortedSet orig = new TreeSet(); + populate(orig); + assertSortedSetsEqual(orig, (SortedSet) _mgr.copyCollection(orig)); + + orig = new TreeSet(new CustomComparator()); + populate(orig); + assertSortedSetsEqual(orig, (SortedSet) _mgr.copyCollection(orig)); + + orig = new CustomSortedSet(); + populate(orig); + assertSortedSetsEqual(orig, (SortedSet) _mgr.copyCollection(orig)); + + orig = new CustomComparatorSortedSet(new CustomComparator()); + populate(orig); + assertSortedSetsEqual(orig, (SortedSet) _mgr.copyCollection(orig)); + } + + /** + * Populate the given sorted set with arbitrary data. + */ + private static void populate(SortedSet coll) { + coll.add(new Integer(1)); + coll.add(new Integer(99)); + coll.add(new Integer(50)); + coll.add(new Integer(-5)); + coll.add(new Integer(10)); + } + + /** + * Assert that the given sets are exactly the same. + */ + private static void assertSortedSetsEqual(SortedSet s1, SortedSet s2) { + assertTrue(s1.getClass() == s2.getClass()); + 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()); + } + + public void testCopyNullCollection() { + assertNull(_mgr.copyCollection(null)); + } + + public void testCopyProxyCollection() { + List orig = (List) _mgr.newCollectionProxy(ArrayList.class, null, null); + populate(orig); + assertListsEqual(new ArrayList(orig), (List) _mgr.copyCollection(orig)); + + TreeSet torig = (TreeSet) _mgr.newCollectionProxy(TreeSet.class, null, + new CustomComparator()); + assertTrue(torig.comparator() instanceof CustomComparator); + populate(torig); + assertSortedSetsEqual(new TreeSet(torig), (SortedSet) + _mgr.copyCollection(torig)); + } + + public void testListMethodsProxied() + throws Exception { + Class proxy = _mgr.newCollectionProxy(ArrayList.class, null, null). + getClass(); + assertListMethodsProxied(proxy); + + proxy = _mgr.newCollectionProxy(CustomList.class, null, null). + getClass(); + assertListMethodsProxied(proxy); + } + + /** + * Assert that the methods we need to override to dirty the collection are + * proxied appropriately. + */ + private void assertCollectionMethodsProxied(Class cls) + throws Exception { + assertNotNull(cls.getDeclaredMethod("add", new Class[] {Object.class})); + assertNotNull(cls.getDeclaredMethod("addAll", + new Class[] {Collection.class})); + assertNotNull(cls.getDeclaredMethod("clear", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("iterator", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("remove", + new Class[] {Object.class})); + assertNotNull(cls.getDeclaredMethod("removeAll", + new Class[] {Collection.class})); + assertNotNull(cls.getDeclaredMethod("retainAll", + new Class[] {Collection.class})); + + // check a non-mutating method to make sure we're not just proxying + // everything + try { + cls.getDeclaredMethod("contains", new Class[] {Object.class}); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + /** + * Assert that the methods we need to override to dirty the list are + * proxied appropriately. + */ + private void assertListMethodsProxied(Class cls) + throws Exception { + assertCollectionMethodsProxied(cls); + assertNotNull(cls.getDeclaredMethod("add", + new Class[] {int.class, Object.class})); + assertNotNull(cls.getDeclaredMethod("addAll", + new Class[] {int.class, Collection.class})); + assertNotNull(cls.getDeclaredMethod("listIterator", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("listIterator", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("remove", new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("set", + new Class[] {int.class, Object.class})); + } + + public void testSetMethodsProxied() + throws Exception { + Class proxy = _mgr.newCollectionProxy(HashSet.class, null, null). + getClass(); + assertCollectionMethodsProxied(proxy); + + proxy = _mgr.newCollectionProxy(CustomSet.class, null, null).getClass(); + assertCollectionMethodsProxied(proxy); + + proxy = _mgr.newCollectionProxy(CustomSortedSet.class, null, null). + getClass(); + assertCollectionMethodsProxied(proxy); + + proxy = _mgr.newCollectionProxy(CustomComparatorSortedSet.class, null, + new CustomComparator()).getClass(); + assertCollectionMethodsProxied(proxy); + } + + public void testQueueMethodsProxied() + throws Exception { + Class queue = getQueueClass(); + if (queue == null) + return; + + Class proxy = _mgr.newCollectionProxy(LinkedList.class, null, null). + getClass(); + assertTrue(queue.isAssignableFrom(proxy)); + assertCollectionMethodsProxied(proxy); + assertNotNull(proxy.getDeclaredMethod("offer", + new Class[] {Object.class})); + assertNotNull(proxy.getDeclaredMethod("poll", (Class[]) null)); + assertNotNull(proxy.getDeclaredMethod("remove", (Class[]) null)); + try { + proxy.getDeclaredMethod("peek", (Class[]) null); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + public void testLinkedListMethodsProxied() + throws Exception { + Class proxy = _mgr.newCollectionProxy(LinkedList.class, null, null). + getClass(); + assertListMethodsProxied(proxy); + assertNotNull(proxy.getDeclaredMethod("addFirst", + new Class[] {Object.class})); + assertNotNull(proxy.getDeclaredMethod("addLast", + new Class[] {Object.class})); + assertNotNull(proxy.getDeclaredMethod("removeFirst", (Class[]) null)); + assertNotNull(proxy.getDeclaredMethod("removeLast", (Class[]) null)); + } + + public void testVectorMethodsProxied() + throws Exception { + Class proxy = _mgr.newCollectionProxy(Vector.class, null, null). + getClass(); + assertListMethodsProxied(proxy); + assertNotNull(proxy.getDeclaredMethod("addElement", + new Class[] {Object.class})); + assertNotNull(proxy.getDeclaredMethod("insertElementAt", + new Class[] {Object.class, int.class})); + assertNotNull(proxy.getDeclaredMethod("removeAllElements", + (Class[]) null)); + assertNotNull(proxy.getDeclaredMethod("removeElement", + new Class[] {Object.class})); + assertNotNull(proxy.getDeclaredMethod("removeElementAt", + new Class[] {int.class})); + assertNotNull(proxy.getDeclaredMethod("setElementAt", + new Class[] {Object.class, int.class})); + } + + public void testListChangeTracker() { + Proxy coll = _mgr.newCollectionProxy(ArrayList.class, null, null); + assertNotNull(coll); + assertNotNull(coll.getChangeTracker()); + assertTrue(coll.getChangeTracker() + instanceof CollectionChangeTrackerImpl); + CollectionChangeTrackerImpl ct = (CollectionChangeTrackerImpl) + coll.getChangeTracker(); + assertTrue(ct.allowsDuplicates()); + assertTrue(ct.isOrdered()); + } + + public void testSetChangeTracker() { + Proxy coll = _mgr.newCollectionProxy(HashSet.class, null, null); + assertNotNull(coll); + assertNotNull(coll.getChangeTracker()); + assertTrue(coll.getChangeTracker() + instanceof CollectionChangeTrackerImpl); + CollectionChangeTrackerImpl ct = (CollectionChangeTrackerImpl) + coll.getChangeTracker(); + assertFalse(ct.allowsDuplicates()); + assertFalse(ct.isOrdered()); + } + + public void testCollectionInterfaceProxy() { + Proxy coll = _mgr.newCollectionProxy(Collection.class, null, null); + assertNotNull(coll); + } + + public void testListInterfaceProxy() { + Proxy coll = _mgr.newCollectionProxy(List.class, null, null); + assertNotNull(coll); + assertTrue(coll instanceof List); + } + + public void testSetInterfaceProxy() { + Proxy coll = _mgr.newCollectionProxy(Set.class, null, null); + assertNotNull(coll); + assertTrue(coll instanceof Set); + assertFalse(coll instanceof SortedSet); + } + + public void testSortedSetInterfaceProxy() { + Proxy coll = _mgr.newCollectionProxy(SortedSet.class, null, null); + assertNotNull(coll); + assertTrue(coll instanceof SortedSet); + } + + public void testQueueInterfaceProxy() { + Class queue = getQueueClass(); + if (queue == null) + return; + + Proxy coll = _mgr.newCollectionProxy(queue, null, null); + assertNotNull(coll); + assertTrue(queue.isInstance(coll)); + } + + /** + * Return the [EMAIL PROTECTED] java.util.Queue} class if avaialble. + */ + private static Class getQueueClass() { + try { + return Class.forName("java.util.Queue"); + } catch (Throwable t) { + return null; + } + } + + public void testCopyMaps() { + Map orig = new HashMap(); + populate(orig); + assertMapsEqual(orig, (Map) _mgr.copyMap(orig)); + + orig = new CustomMap(); + populate(orig); + assertMapsEqual(orig, (Map) _mgr.copyMap(orig)); + + Properties porig = new Properties(); + porig.setProperty("foo", "bar"); + porig.setProperty("bar", "biz"); + porig.setProperty("biz", "baz"); + assertMapsEqual(orig, (Map) _mgr.copyMap(orig)); + } + + /** + * Populate the given map with arbitrary data. + */ + private static void populate(Map map) { + map.put(new Integer(1), "1"); + map.put(new Integer(99), "99"); + map.put(new Integer(-2), "-2"); + map.put(new Integer(50), "50"); + } + + /** + * Assert that the given maps are exactly the same. + */ + private static void assertMapsEqual(Map m1, Map m2) { + assertTrue(m1.getClass() == m2.getClass()); + assertEquals(m1.size(), m2.size()); + assertEquals(m1, m2); + } + + public void testCopySortedMaps() { + SortedMap orig = new TreeMap(); + populate(orig); + assertSortedMapsEqual(orig, (SortedMap) _mgr.copyMap(orig)); + + orig = new TreeMap(new CustomComparator()); + populate(orig); + assertSortedMapsEqual(orig, (SortedMap) _mgr.copyMap(orig)); + + orig = new CustomSortedMap(); + populate(orig); + assertSortedMapsEqual(orig, (SortedMap) _mgr.copyMap(orig)); + + orig = new CustomComparatorSortedMap(new CustomComparator()); + populate(orig); + assertSortedMapsEqual(orig, (SortedMap) _mgr.copyMap(orig)); + } + + /** + * Assert that the given maps are exactly the same. + */ + private static void assertSortedMapsEqual(SortedMap m1, SortedMap m2) { + assertTrue(m1.getClass() == m2.getClass()); + assertEquals(m1.comparator(), m2.comparator()); + assertEquals(m1.size(), m2.size()); + Map.Entry entry1; + Map.Entry entry2; + Iterator itr1 = m1.entrySet().iterator(); + Iterator itr2 = m2.entrySet().iterator(); + while (itr1.hasNext()) { + entry1 = (Map.Entry) itr1.next(); + entry2 = (Map.Entry) itr2.next(); + assertTrue(entry1.getKey() == entry2.getKey()); + assertTrue(entry1.getValue() == entry2.getValue()); + } + } + + public void testCopyNullMap() { + assertNull(_mgr.copyMap(null)); + } + + public void testCopyProxyMap() { + Map orig = (Map) _mgr.newMapProxy(HashMap.class, null, null, null); + populate(orig); + assertMapsEqual(new HashMap(orig), (Map) _mgr.copyMap(orig)); + + TreeMap torig = (TreeMap) _mgr.newMapProxy(TreeMap.class, null, null, + new CustomComparator()); + assertTrue(torig.comparator() instanceof CustomComparator); + populate(torig); + assertSortedMapsEqual(new TreeMap(torig), (SortedMap) + _mgr.copyMap(torig)); + } + + public void testMapMethodsProxied() + throws Exception { + Class proxy = _mgr.newMapProxy(HashMap.class, null, null, null). + getClass(); + assertMapMethodsProxied(proxy); + + proxy = _mgr.newMapProxy(TreeMap.class, null, null, null).getClass(); + assertMapMethodsProxied(proxy); + + proxy = _mgr.newMapProxy(TreeMap.class, null, null, + new CustomComparator()).getClass(); + assertMapMethodsProxied(proxy); + + proxy = _mgr.newMapProxy(CustomMap.class, null, null, null).getClass(); + assertMapMethodsProxied(proxy); + + proxy = _mgr.newMapProxy(CustomSortedMap.class, null, null, null). + getClass(); + assertMapMethodsProxied(proxy); + + proxy = _mgr.newMapProxy(CustomComparatorSortedMap.class, null, null, + new CustomComparator()).getClass(); + assertMapMethodsProxied(proxy); + } + + /** + * Assert that the methods we need to override to dirty the collection are + * proxied appropriately. + */ + private void assertMapMethodsProxied(Class cls) + throws Exception { + assertNotNull(cls.getDeclaredMethod("put", + new Class[] {Object.class, Object.class})); + assertNotNull(cls.getDeclaredMethod("putAll", new Class[] {Map.class})); + assertNotNull(cls.getDeclaredMethod("clear", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("remove", + new Class[] {Object.class})); + assertNotNull(cls.getDeclaredMethod("keySet", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("values", (Class[]) null)); + assertNotNull(cls.getDeclaredMethod("entrySet", (Class[]) null)); + + // check a non-mutating method to make sure we're not just proxying + // everything + try { + cls.getDeclaredMethod("containsKey", new Class[] {Object.class}); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + public void testPropertiesMethodsProxied() + throws Exception { + Class proxy = _mgr.newMapProxy(Properties.class, null, null, null). + getClass(); + assertMapMethodsProxied(proxy); + assertNotNull(proxy.getDeclaredMethod("setProperty", + new Class[] {String.class, String.class})); + assertNotNull(proxy.getDeclaredMethod("load", + new Class[] {InputStream.class})); + assertNotNull(proxy.getDeclaredMethod("loadFromXML", + new Class[] {InputStream.class})); + } + + public void testCopyDates() { + Date orig = new Date(1999); + assertDatesEqual(orig, (Date) _mgr.copyDate(orig)); + + orig = new java.sql.Date(1999); + assertDatesEqual(orig, (Date) _mgr.copyDate(orig)); + + orig = new Time(1999); + assertDatesEqual(orig, (Date) _mgr.copyDate(orig)); + + Timestamp torig = new Timestamp(1999); + torig.setNanos(2001); + assertDatesEqual(torig, (Date) _mgr.copyDate(torig)); + + torig = new CustomDate(1999); + torig.setNanos(2001); + assertDatesEqual(torig, (Date) _mgr.copyDate(torig)); + } + + /** + * 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); + } + + public void testCopyNullDate() { + assertNull(_mgr.copyDate(null)); + } + + public void testCopyProxyDate() { + Date orig = (Date) _mgr.newDateProxy(Time.class); + orig.setTime(1999); + assertDatesEqual(new Date(orig.getTime()), (Date) _mgr.copyDate(orig)); + } + + public void testDateMethodsProxied() + throws Exception { + Class proxy = _mgr.newDateProxy(Date.class).getClass(); + assertDateMethodsProxied(proxy); + + proxy = _mgr.newDateProxy(java.sql.Date.class).getClass(); + assertDateMethodsProxied(proxy); + + proxy = _mgr.newDateProxy(Time.class).getClass(); + assertDateMethodsProxied(proxy); + + proxy = _mgr.newDateProxy(Timestamp.class).getClass(); + assertTimestampMethodsProxied(proxy); + + proxy = _mgr.newDateProxy(CustomDate.class).getClass(); + assertTimestampMethodsProxied(proxy); + } + + /** + * Assert that the methods we need to override to dirty the date are + * proxied appropriately. + */ + private void assertDateMethodsProxied(Class cls) + throws Exception { + assertNotNull(cls.getDeclaredMethod("setDate", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("setHours", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("setMinutes", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("setMonth", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("setSeconds", + new Class[] {int.class})); + assertNotNull(cls.getDeclaredMethod("setTime", + new Class[] {long.class})); + assertNotNull(cls.getDeclaredMethod("setYear", + new Class[] {int.class})); + + // check a non-mutating method to make sure we're not just proxying + // everything + try { + cls.getDeclaredMethod("getTime", (Class[]) null); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + /** + * Assert that the methods we need to override to dirty the timestamp are + * proxied appropriately. + */ + private void assertTimestampMethodsProxied(Class cls) + throws Exception { + assertDateMethodsProxied(cls); + assertNotNull(cls.getDeclaredMethod("setNanos", + new Class[] {int.class})); + } + + public void testCopyCalendars() { + Calendar orig = new GregorianCalendar(); + populate(orig); + assertCalendarsEqual(orig, _mgr.copyCalendar(orig)); + + orig = new CustomCalendar(); + populate(orig); + assertCalendarsEqual(orig, _mgr.copyCalendar(orig)); + } + + /** + * Populate calendar with arbitrary data. + */ + private static void populate(Calendar cal) { + cal.setTimeInMillis(1999); + cal.setTimeZone(TimeZone.getTimeZone("CST")); + } + + /** + * 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); + } + + public void testCopyNullCalendar() { + assertNull(_mgr.copyCalendar(null)); + } + + public void testCopyProxyCalendar() { + Calendar orig = (Calendar) _mgr.newCalendarProxy + (GregorianCalendar.class, TimeZone.getTimeZone("CST")); + populate(orig); + Calendar cal = new GregorianCalendar(); + populate(cal); + assertCalendarsEqual(cal, _mgr.copyCalendar(orig)); + } + + public void testCalendarAbstractClassProxy() { + Proxy cal = _mgr.newCalendarProxy(Calendar.class, null); + assertNotNull(cal); + } + + public void testCalendarMethodsProxied() + throws Exception { + Class proxy = _mgr.newCalendarProxy(GregorianCalendar.class, + TimeZone.getDefault()).getClass(); + assertCalendarMethodsProxied(proxy); + + proxy = _mgr.newCalendarProxy(CustomCalendar.class, + TimeZone.getDefault()).getClass(); + assertCalendarMethodsProxied(proxy); + + proxy = _mgr.newCalendarProxy(Calendar.class, + TimeZone.getDefault()).getClass(); + assertCalendarMethodsProxied(proxy); + } + + /** + * Assert that the methods we need to override to dirty the calendar are + * proxied appropriately. + */ + private void assertCalendarMethodsProxied(Class cls) + throws Exception { + assertNotNull(cls.getDeclaredMethod("set", + new Class[] {int.class, int.class})); + assertNotNull(cls.getDeclaredMethod("roll", + new Class[] {int.class, int.class})); + assertNotNull(cls.getDeclaredMethod("setTimeInMillis", + new Class[] {long.class})); + assertNotNull(cls.getDeclaredMethod("setTimeZone", + new Class[] {TimeZone.class})); + assertNotNull(cls.getDeclaredMethod("computeFields", (Class[]) null)); + + // check a non-mutating method to make sure we're not just proxying + // everything + try { + cls.getDeclaredMethod("getTimeInMillis", (Class[]) null); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + public void testCopyBeans() { + CustomBean orig = new CustomBean(); + populate(orig); + assertBeansEqual(orig, (CustomBean) _mgr.copyCustom(orig)); + + orig = new CustomCopyConstructorBean(orig); + assertBeansEqual(orig, (CustomBean) _mgr.copyCustom(orig)); + } + + /** + * Populate the given bean with arbitrary data. + */ + private void populate(CustomBean bean) { + bean.setString("foo"); + bean.setNumber(99); + } + + public void testNonproxyableBean() { + NonproxyableBean orig = new NonproxyableBean(1); + populate(orig); + assertNull(_mgr.copyCustom(orig)); + assertNull(_mgr.newCustomProxy(orig)); + } + + + /** + * Assert that the given beans are exactly the same. + */ + private static void assertBeansEqual(CustomBean b1, CustomBean b2) { + assertTrue(b1.getClass() == b2.getClass()); + assertTrue(b1.getString() == b2.getString()); + assertTrue(b1.getNumber() == b2.getNumber()); + } + + public void testCopyNullBean() { + assertNull(_mgr.copyCustom(null)); + } + + public void testCopyProxyBean() { + CustomBean orig = (CustomBean) _mgr.newCustomProxy(new CustomBean()); + populate(orig); + CustomBean comp = new CustomBean(); + populate(comp); + assertBeansEqual(comp, (CustomBean) _mgr.copyCustom(orig)); + } + + public void testBeanMethodsProxied() + throws Exception { + Class proxy = _mgr.newCustomProxy(new CustomBean()).getClass(); + assertBeanMethodsProxied(proxy); + + proxy = _mgr.newCustomProxy(new CustomCopyConstructorBean + (new CustomBean())).getClass(); + assertBeanMethodsProxied(proxy); + } + + /** + * Assert that the methods we need to override to dirty the bean are + * proxied appropriately. + */ + private void assertBeanMethodsProxied(Class cls) + throws Exception { + assertNotNull(cls.getDeclaredMethod("setString", + new Class[] {String.class})); + assertNotNull(cls.getDeclaredMethod("setNumber", + new Class[] {int.class})); + + // check a non-mutating method to make sure we're not just proxying + // everything + try { + cls.getDeclaredMethod("getString", (Class[]) null); + fail("Proxied non-mutating method."); + } catch (NoSuchMethodException nsme) { + // expected + } + } + + public static void main(String[] args) { + TestRunner.run(TestProxyManager.class); + } + + /** + * Used to test custom list handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomList + extends AbstractSequentialList { + + private final List _delegate = new ArrayList(); + + public int size() { + return _delegate.size(); + } + + public ListIterator listIterator(int idx) { + return _delegate.listIterator(idx); + } + } + + /** + * Used to test custom set handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomSet + extends AbstractSet { + + private final Set _delegate = new HashSet(); + + public int size() { + return _delegate.size(); + } + + public Iterator iterator() { + return _delegate.iterator(); + } + + public boolean add(Object o) { + return _delegate.add(o); + } + } + + /** + * Used to test custom set handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomSortedSet + extends TreeSet { + } + + /** + * Used to test custom set handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomComparatorSortedSet + extends TreeSet { + + public CustomComparatorSortedSet() { + } + + public CustomComparatorSortedSet(Comparator comp) { + super(comp); + } + } + + /** + * Used to test custom map handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomMap + extends AbstractMap { + + private final Map _delegate = new HashMap(); + + public Object put(Object key, Object value) { + return _delegate.put(key, value); + } + + public Set entrySet() { + return _delegate.entrySet(); + } + } + + /** + * Used to test custom map handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomSortedMap + extends TreeMap { + } + + /** + * Used to test custom map handling. Copy constructor intentionally + * ommitted. + */ + public static class CustomComparatorSortedMap + extends TreeMap { + + public CustomComparatorSortedMap() { + } + + public CustomComparatorSortedMap(Comparator comp) { + super(comp); + } + } + + /** + * Used to test transfer of comparators to proxies. + */ + private static class CustomComparator + implements Comparator { + + public int compare(Object o1, Object o2) { + return ((Comparable) o1).compareTo(o2); + } + } + + /** + * Used to test custom date handling. + */ + public static class CustomDate + extends Timestamp { + + public CustomDate(long time) { + super(time); + } + } + + /** + * Used to test custom bean handling. + */ + public static class CustomBean { + private String _string; + private int _number; + + public String getString() { + return _string; + } + + public void setString(String str) { + _string = str; + } + + public int getNumber() { + return _number; + } + + public void setNumber(int number) { + _number = number; + } + } + + /** + * Used to test custom bean handling. + */ + public static class CustomCopyConstructorBean + extends CustomBean { + + public CustomCopyConstructorBean(CustomBean bean) { + setString(bean.getString()); + setNumber(bean.getNumber()); + } + } + + /** + * Used to non-proxyable custom bean handling. + */ + public static class NonproxyableBean + extends CustomBean { + + public NonproxyableBean(long x) { + // single non-default, non-copy constructor + } + } + + /** + * Used to test custom calendar handling. + */ + public static class CustomCalendar + extends GregorianCalendar { + } +} +
