From a420906d61b0fd54ede8906fb494b5378c4bac5f Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Sat, 11 Oct 2014 17:41:48 +0300 Subject: [PATCH] Use workaround for JDK6 Introspection bug JDK-6788525 (#14839). Change-Id: Ib7ef769b7537675c681ac1fab24a425d19a267e7 --- server/src/com/vaadin/data/util/BeanItem.java | 68 ++++++++++++++++++- .../com/vaadin/data/util/BeanItemTest.java | 41 +++++++++++ 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/server/src/com/vaadin/data/util/BeanItem.java b/server/src/com/vaadin/data/util/BeanItem.java index ac3ef86434..12d9b23d0a 100644 --- a/server/src/com/vaadin/data/util/BeanItem.java +++ b/server/src/com/vaadin/data/util/BeanItem.java @@ -214,13 +214,75 @@ public class BeanItem 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 getPropertyDescriptors( + BeanInfo beanInfo) { + PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); + List result = new ArrayList( + 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; } } diff --git a/server/tests/src/com/vaadin/data/util/BeanItemTest.java b/server/tests/src/com/vaadin/data/util/BeanItemTest.java index b458856826..89c56b1779 100644 --- a/server/tests/src/com/vaadin/data/util/BeanItemTest.java +++ b/server/tests/src/com/vaadin/data/util/BeanItemTest.java @@ -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 { + + public T getProperty() { + return null; + } + + public void setProperty(T t) { + throw new UnsupportedOperationException(); + } + } + + protected static class SubClass extends Generic { + + @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 item = new BeanItem(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); + } } -- 2.39.5