Fixed ExtendedBeanInfo and its tests to accept JDK 8 b117+ introspection results
Specifically, read and write methods are allowed to express property types with superclass/subclass relationships in both directions now. Issue: SPR-11139
This commit is contained in:
parent
92816492ed
commit
cb624e25c5
|
@ -209,37 +209,37 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BeanInfo[] getAdditionalBeanInfo() {
|
public BeanInfo[] getAdditionalBeanInfo() {
|
||||||
return delegate.getAdditionalBeanInfo();
|
return this.delegate.getAdditionalBeanInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BeanDescriptor getBeanDescriptor() {
|
public BeanDescriptor getBeanDescriptor() {
|
||||||
return delegate.getBeanDescriptor();
|
return this.delegate.getBeanDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDefaultEventIndex() {
|
public int getDefaultEventIndex() {
|
||||||
return delegate.getDefaultEventIndex();
|
return this.delegate.getDefaultEventIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDefaultPropertyIndex() {
|
public int getDefaultPropertyIndex() {
|
||||||
return delegate.getDefaultPropertyIndex();
|
return this.delegate.getDefaultPropertyIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventSetDescriptor[] getEventSetDescriptors() {
|
public EventSetDescriptor[] getEventSetDescriptors() {
|
||||||
return delegate.getEventSetDescriptors();
|
return this.delegate.getEventSetDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Image getIcon(int iconKind) {
|
public Image getIcon(int iconKind) {
|
||||||
return delegate.getIcon(iconKind);
|
return this.delegate.getIcon(iconKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodDescriptor[] getMethodDescriptors() {
|
public MethodDescriptor[] getMethodDescriptors() {
|
||||||
return delegate.getMethodDescriptors();
|
return this.delegate.getMethodDescriptors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ class SimplePropertyDescriptor extends PropertyDescriptor {
|
||||||
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
|
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
|
||||||
}
|
}
|
||||||
catch (IntrospectionException ex) {
|
catch (IntrospectionException ex) {
|
||||||
// ignore, as does PropertyDescriptor#getPropertyType
|
// Ignore, as does PropertyDescriptor#getPropertyType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.propertyType;
|
return this.propertyType;
|
||||||
|
@ -383,7 +383,7 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
|
||||||
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
|
this.propertyType = findPropertyType(this.readMethod, this.writeMethod);
|
||||||
}
|
}
|
||||||
catch (IntrospectionException ex) {
|
catch (IntrospectionException ex) {
|
||||||
// ignore, as does IndexedPropertyDescriptor#getPropertyType
|
// Ignore, as does IndexedPropertyDescriptor#getPropertyType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.propertyType;
|
return this.propertyType;
|
||||||
|
@ -417,7 +417,7 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
|
||||||
getName(), getPropertyType(), this.indexedReadMethod, this.indexedWriteMethod);
|
getName(), getPropertyType(), this.indexedReadMethod, this.indexedWriteMethod);
|
||||||
}
|
}
|
||||||
catch (IntrospectionException ex) {
|
catch (IntrospectionException ex) {
|
||||||
// ignore, as does IndexedPropertyDescriptor#getIndexedPropertyType
|
// Ignore, as does IndexedPropertyDescriptor#getIndexedPropertyType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.indexedPropertyType;
|
return this.indexedPropertyType;
|
||||||
|
@ -482,14 +482,14 @@ class PropertyDescriptorUtils {
|
||||||
target.setShortDescription(source.getShortDescription());
|
target.setShortDescription(source.getShortDescription());
|
||||||
target.setDisplayName(source.getDisplayName());
|
target.setDisplayName(source.getDisplayName());
|
||||||
|
|
||||||
// copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
|
// Copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
|
||||||
Enumeration<String> keys = source.attributeNames();
|
Enumeration<String> keys = source.attributeNames();
|
||||||
while (keys.hasMoreElements()) {
|
while (keys.hasMoreElements()) {
|
||||||
String key = keys.nextElement();
|
String key = keys.nextElement();
|
||||||
target.setValue(key, source.getValue(key));
|
target.setValue(key, source.getValue(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// see java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
|
// See java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
|
||||||
target.setPropertyEditorClass(source.getPropertyEditorClass());
|
target.setPropertyEditorClass(source.getPropertyEditorClass());
|
||||||
target.setBound(source.isBound());
|
target.setBound(source.isBound());
|
||||||
target.setConstrained(source.isConstrained());
|
target.setConstrained(source.isConstrained());
|
||||||
|
@ -503,24 +503,34 @@ class PropertyDescriptorUtils {
|
||||||
if (readMethod != null) {
|
if (readMethod != null) {
|
||||||
Class<?>[] params = readMethod.getParameterTypes();
|
Class<?>[] params = readMethod.getParameterTypes();
|
||||||
if (params.length != 0) {
|
if (params.length != 0) {
|
||||||
throw new IntrospectionException("bad read method arg count: " + readMethod);
|
throw new IntrospectionException("Bad read method arg count: " + readMethod);
|
||||||
}
|
}
|
||||||
propertyType = readMethod.getReturnType();
|
propertyType = readMethod.getReturnType();
|
||||||
if (propertyType == Void.TYPE) {
|
if (propertyType == Void.TYPE) {
|
||||||
throw new IntrospectionException("read method "
|
throw new IntrospectionException("Read method returns void: " + readMethod);
|
||||||
+ readMethod.getName() + " returns void");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (writeMethod != null) {
|
if (writeMethod != null) {
|
||||||
Class<?> params[] = writeMethod.getParameterTypes();
|
Class<?> params[] = writeMethod.getParameterTypes();
|
||||||
if (params.length != 1) {
|
if (params.length != 1) {
|
||||||
throw new IntrospectionException("bad write method arg count: " + writeMethod);
|
throw new IntrospectionException("Bad write method arg count: " + writeMethod);
|
||||||
}
|
}
|
||||||
if (propertyType != null
|
if (propertyType != null) {
|
||||||
&& !params[0].isAssignableFrom(propertyType)) {
|
if (propertyType.isAssignableFrom(params[0])) {
|
||||||
throw new IntrospectionException("type mismatch between read and write methods");
|
// Write method's property type potentially more specific
|
||||||
|
propertyType = params[0];
|
||||||
|
}
|
||||||
|
else if (params[0].isAssignableFrom(propertyType)) {
|
||||||
|
// Proceed with read method's property type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IntrospectionException(
|
||||||
|
"Type mismatch between read and write methods: " + readMethod + " - " + writeMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
propertyType = params[0];
|
||||||
}
|
}
|
||||||
propertyType = params[0];
|
|
||||||
}
|
}
|
||||||
return propertyType;
|
return propertyType;
|
||||||
}
|
}
|
||||||
|
@ -532,44 +542,48 @@ class PropertyDescriptorUtils {
|
||||||
Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException {
|
Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException {
|
||||||
|
|
||||||
Class<?> indexedPropertyType = null;
|
Class<?> indexedPropertyType = null;
|
||||||
|
|
||||||
if (indexedReadMethod != null) {
|
if (indexedReadMethod != null) {
|
||||||
Class<?> params[] = indexedReadMethod.getParameterTypes();
|
Class<?> params[] = indexedReadMethod.getParameterTypes();
|
||||||
if (params.length != 1) {
|
if (params.length != 1) {
|
||||||
throw new IntrospectionException(
|
throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod);
|
||||||
"bad indexed read method arg count");
|
|
||||||
}
|
}
|
||||||
if (params[0] != Integer.TYPE) {
|
if (params[0] != Integer.TYPE) {
|
||||||
throw new IntrospectionException(
|
throw new IntrospectionException("Non int index to indexed read method: " + indexedReadMethod);
|
||||||
"non int index to indexed read method");
|
|
||||||
}
|
}
|
||||||
indexedPropertyType = indexedReadMethod.getReturnType();
|
indexedPropertyType = indexedReadMethod.getReturnType();
|
||||||
if (indexedPropertyType == Void.TYPE) {
|
if (indexedPropertyType == Void.TYPE) {
|
||||||
throw new IntrospectionException(
|
throw new IntrospectionException("Indexed read method returns void: " + indexedReadMethod);
|
||||||
"indexed read method returns void");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (indexedWriteMethod != null) {
|
if (indexedWriteMethod != null) {
|
||||||
Class<?> params[] = indexedWriteMethod.getParameterTypes();
|
Class<?> params[] = indexedWriteMethod.getParameterTypes();
|
||||||
if (params.length != 2) {
|
if (params.length != 2) {
|
||||||
throw new IntrospectionException(
|
throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod);
|
||||||
"bad indexed write method arg count");
|
|
||||||
}
|
}
|
||||||
if (params[0] != Integer.TYPE) {
|
if (params[0] != Integer.TYPE) {
|
||||||
throw new IntrospectionException(
|
throw new IntrospectionException("Non int index to indexed write method: " + indexedWriteMethod);
|
||||||
"non int index to indexed write method");
|
|
||||||
}
|
}
|
||||||
if (indexedPropertyType != null && indexedPropertyType != params[1]) {
|
if (indexedPropertyType != null) {
|
||||||
throw new IntrospectionException(
|
if (indexedPropertyType.isAssignableFrom(params[1])) {
|
||||||
"type mismatch between indexed read and indexed write methods: " + name);
|
// Write method's property type potentially more specific
|
||||||
|
indexedPropertyType = params[1];
|
||||||
|
}
|
||||||
|
else if (params[1].isAssignableFrom(indexedPropertyType)) {
|
||||||
|
// Proceed with read method's property type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IntrospectionException("Type mismatch between indexed read and write methods: " +
|
||||||
|
indexedReadMethod + " - " + indexedWriteMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
indexedPropertyType = params[1];
|
||||||
}
|
}
|
||||||
indexedPropertyType = params[1];
|
|
||||||
}
|
}
|
||||||
if (propertyType != null
|
if (propertyType != null && (!propertyType.isArray() ||
|
||||||
&& (!propertyType.isArray() ||
|
propertyType.getComponentType() != indexedPropertyType)) {
|
||||||
propertyType.getComponentType() != indexedPropertyType)) {
|
throw new IntrospectionException("Type mismatch between indexed and non-indexed methods: " +
|
||||||
throw new IntrospectionException(
|
indexedReadMethod + " - " + indexedWriteMethod);
|
||||||
"type mismatch between indexed and non-indexed methods: " + name);
|
|
||||||
}
|
}
|
||||||
return indexedPropertyType;
|
return indexedPropertyType;
|
||||||
}
|
}
|
||||||
|
@ -590,15 +604,12 @@ class PropertyDescriptorUtils {
|
||||||
if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
|
if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
|
if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (pd1.getPropertyType() == pd2.getPropertyType() &&
|
||||||
if (pd1.getPropertyType() == pd2.getPropertyType()
|
pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass() &&
|
||||||
&& pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass()
|
pd1.isBound() == pd2.isBound() && pd1.isConstrained() == pd2.isConstrained()) {
|
||||||
&& pd1.isBound() == pd2.isBound()
|
|
||||||
&& pd1.isConstrained() == pd2.isConstrained()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,7 +623,7 @@ class PropertyDescriptorUtils {
|
||||||
if ((a == null) != (b == null)) {
|
if ((a == null) != (b == null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (a != null && b != null) {
|
if (a != null) {
|
||||||
if (!a.equals(b)) {
|
if (!a.equals(b)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,10 +323,8 @@ public class ExtendedBeanInfoTests {
|
||||||
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||||
|
|
||||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
|
||||||
|
|
||||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(false));
|
assertEquals(hasWriteMethodForProperty(bi, "foo"), hasWriteMethodForProperty(ebi, "foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -340,10 +338,8 @@ public class ExtendedBeanInfoTests {
|
||||||
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||||
|
|
||||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(false));
|
|
||||||
|
|
||||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(false));
|
assertEquals(hasIndexedWriteMethodForProperty(bi, "foos"), hasIndexedWriteMethodForProperty(ebi, "foos"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue