]> source.dussan.org Git - vaadin-framework.git/commitdiff
Use workaround for JDK6 Introspection bug JDK-6788525 (#14839).
authorDenis Anisimov <denis@vaadin.com>
Sat, 11 Oct 2014 14:41:48 +0000 (17:41 +0300)
committerDenis Anisimov <denis@vaadin.com>
Mon, 13 Oct 2014 09:24:57 +0000 (09:24 +0000)
Change-Id: Ib7ef769b7537675c681ac1fab24a425d19a267e7

server/src/com/vaadin/data/util/BeanItem.java
server/tests/src/com/vaadin/data/util/BeanItemTest.java

index ac3ef8643489c9b5ea990e798bebad4d4936cc09..12d9b23d0af5ef2279364fe93bad0ca023f7bb04 100644 (file)
@@ -214,13 +214,75 @@ public class BeanItem<BT> extends PropertysetItem {
             }
 
             BeanInfo info = Introspector.getBeanInfo(beanClass);
-            propertyDescriptors.addAll(Arrays.asList(info
-                    .getPropertyDescriptors()));
+            propertyDescriptors.addAll(getPropertyDescriptors(info));
 
             return propertyDescriptors;
         } else {
             BeanInfo info = Introspector.getBeanInfo(beanClass);
-            return Arrays.asList(info.getPropertyDescriptors());
+            return getPropertyDescriptors(info);
+        }
+    }
+
+    // Workaround for Java6 bug JDK-6788525. Do nothing for JDK7+.
+    private static List<PropertyDescriptor> getPropertyDescriptors(
+            BeanInfo beanInfo) {
+        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
+        List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>(
+                descriptors.length);
+        for (PropertyDescriptor descriptor : descriptors) {
+            try {
+                Method readMethod = getMethodFromBridge(descriptor
+                        .getReadMethod());
+                if (readMethod != null) {
+                    Method writeMethod = getMethodFromBridge(
+                            descriptor.getWriteMethod(),
+                            readMethod.getReturnType());
+                    if (writeMethod == null) {
+                        writeMethod = descriptor.getWriteMethod();
+                    }
+                    PropertyDescriptor descr = new PropertyDescriptor(
+                            descriptor.getName(), readMethod, writeMethod);
+                    result.add(descr);
+                } else {
+                    result.add(descriptor);
+                }
+            } catch (SecurityException ignore) {
+                // handle next descriptor
+            } catch (IntrospectionException e) {
+                result.add(descriptor);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Return not bridged method for bridge {@code bridgeMethod} method. If
+     * method {@code bridgeMethod} is not bridge method then return null.
+     */
+    private static Method getMethodFromBridge(Method bridgeMethod)
+            throws SecurityException {
+        if (bridgeMethod == null) {
+            return null;
+        }
+        return getMethodFromBridge(bridgeMethod,
+                bridgeMethod.getParameterTypes());
+    }
+
+    /**
+     * Return not bridged method for bridge {@code bridgeMethod} method and
+     * declared {@code paramTypes}. If method {@code bridgeMethod} is not bridge
+     * method then return null.
+     */
+    private static Method getMethodFromBridge(Method bridgeMethod,
+            Class<?>... paramTypes) throws SecurityException {
+        if (bridgeMethod == null || !bridgeMethod.isBridge()) {
+            return null;
+        }
+        try {
+            return bridgeMethod.getDeclaringClass().getMethod(
+                    bridgeMethod.getName(), paramTypes);
+        } catch (NoSuchMethodException e) {
+            return null;
         }
     }
 
index b458856826331a7b2cfa7403d4459ded1df91674..89c56b1779b838638b2663cf3c364392a834b49e 100644 (file)
@@ -13,6 +13,8 @@ import junit.framework.TestCase;
 
 import org.junit.Assert;
 
+import com.vaadin.data.Property;
+
 /**
  * Test BeanItem specific features.
  * 
@@ -122,6 +124,31 @@ public class BeanItemTest extends TestCase {
         public int getSuper2();
     }
 
+    protected static class Generic<T> {
+
+        public T getProperty() {
+            return null;
+        }
+
+        public void setProperty(T t) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    protected static class SubClass extends Generic<String> {
+
+        @Override
+        // Has a bridged method
+        public String getProperty() {
+            return "";
+        }
+
+        @Override
+        // Has a bridged method
+        public void setProperty(String t) {
+        }
+    }
+
     protected static interface MySubInterface extends MySuperInterface,
             MySuperInterface2 {
         public int getSub();
@@ -331,4 +358,18 @@ public class BeanItemTest extends TestCase {
         Assert.assertEquals(6, item.getItemPropertyIds().size());
         Assert.assertEquals(null, item.getItemProperty("myname"));
     }
+
+    public void testOverridenGenericMethods() {
+        BeanItem<SubClass> item = new BeanItem<SubClass>(new SubClass());
+
+        Property<?> property = item.getItemProperty("property");
+        Assert.assertEquals("Unexpected class for property type", String.class,
+                property.getType());
+
+        Assert.assertEquals("Unexpected property value", "",
+                property.getValue());
+
+        // Should not be exception
+        property.setValue(null);
+    }
 }