Author: joshcanfield
Date: Sun Oct 17 05:33:49 2010
New Revision: 1023424

URL: http://svn.apache.org/viewvc?rev=1023424&view=rev
Log:
TAP5-921: Explicitly search interfaces when creating property adapters for 
abstract classes.

Modified:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java?rev=1023424&r1=1023423&r2=1023424&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
 Sun Oct 17 05:33:49 2010
@@ -90,7 +90,8 @@ public class PropertyAccessImpl implemen
 
             addAll(descriptors, info.getPropertyDescriptors());
 
-            if (forClass.isInterface())
+            // TAP5-921 - Introspector misses interface methods not 
implemented in an abstract class
+            if (forClass.isInterface() || 
Modifier.isAbstract(forClass.getModifiers()) )
                 addPropertiesFromExtendedInterfaces(forClass, descriptors);
 
             addPropertiesFromScala(forClass, descriptors);
@@ -122,6 +123,8 @@ public class PropertyAccessImpl implemen
 
             BeanInfo info = Introspector.getBeanInfo(c);
 
+            // Duplicates occur and are filtered out in ClassPropertyAdapter 
which stores
+            // a property name to descriptor map.
             addAll(descriptors, info.getPropertyDescriptors());
             addAll(queue, c.getInterfaces());
         }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java?rev=1023424&r1=1023423&r2=1023424&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java
 Sun Oct 17 05:33:49 2010
@@ -233,6 +233,56 @@ public class PropertyAccessImplTest exte
     {
     }
 
+    public static interface BeanInterface
+    {
+        String getValue();
+
+        void setValue(String v);
+
+        String getOtherValue();
+
+        void setOtherValue(String v);
+
+        int getIntValue(); // read-only
+    }
+
+    public static abstract class AbstractBean implements BeanInterface
+    {
+        // abstract class implements method from interface
+        private String other;
+        public String getOtherValue()
+        {
+            return other;
+        }
+
+        public void setOtherValue(String v)
+        {
+            other = v;
+        }
+    }
+
+    public static class ConcreteBean extends AbstractBean
+    {
+        private String value;
+        private int intValue;
+
+        public ConcreteBean(int intValue) {
+            this.intValue = intValue;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public void setValue(String v) {
+            value = v;
+        }
+
+        public int getIntValue() {
+            return intValue;
+        }
+    }
+
     @Test
     public void simple_read_access()
     {
@@ -656,6 +706,41 @@ public class PropertyAccessImplTest exte
     }
 
     @Test
+    public void 
access_property_from_unimplemented_interface_in_abstract_base_class()
+    {
+        AbstractBean bean = new ConcreteBean(33);
+
+        PropertyAdapter valueAdapter = 
access.getAdapter(AbstractBean.class).getPropertyAdapter("value");
+
+        assertNotNull(valueAdapter);
+        assertFalse(valueAdapter.isField());
+
+        valueAdapter.set(bean, "Hello");
+
+        assertSame(valueAdapter.get(bean), "Hello");
+        assertSame(bean.getValue(), "Hello");
+
+        PropertyAdapter otherValueAdapter = 
access.getAdapter(AbstractBean.class).getPropertyAdapter("otherValue");
+
+        assertNotNull(otherValueAdapter);
+        assertFalse(otherValueAdapter.isField());
+
+        otherValueAdapter.set(bean, "Other Value");
+
+        assertSame(otherValueAdapter.get(bean), "Other Value");
+        assertSame(bean.getOtherValue(), "Other Value");
+
+        PropertyAdapter intValueAdapter = 
access.getAdapter(AbstractBean.class).getPropertyAdapter("intvalue");
+        assertNotNull(intValueAdapter);
+
+        assertEquals(intValueAdapter.get(bean), 33);
+
+        assertTrue(intValueAdapter.isRead());
+        assertFalse(intValueAdapter.isUpdate());
+    }
+
+
+    @Test
     public void generic_field_is_recognized()
     {
         PropertyAdapter pa = 
access.getAdapter(GenericStringBean.class).getPropertyAdapter("value");


Reply via email to