}
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;
}
}
import org.junit.Assert;
+import com.vaadin.data.Property;
+
/**
* Test BeanItem specific features.
*
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();
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);
+ }
}