Introduce ExtendedBeanInfo
Decorator for instances returned from Introspector#getBeanInfo(Class<?>) that supports detection and inclusion of non-void returning setter methods. Fully supports indexed properties and otherwise faithfully mimics the default BeanInfo#getPropertyDescriptors() behavior, e.g., PropertyDescriptor ordering, etc. This decorator has been integrated with CachedIntrospectionResults meaning that, in simple terms, the Spring container now supports injection of setter methods having any return type. Issue: SPR-8079
This commit is contained in:
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IndexedPropertyDescriptor;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.ExtendedBeanInfo.PropertyDescriptorComparator;
|
||||
|
||||
import test.beans.TestBean;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ExtendedBeanInfo}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ExtendedBeanInfoTests {
|
||||
|
||||
@Test
|
||||
public void standardReadMethodOnly() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public String getFoo() { return null; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardWriteMethodOnly() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public void setFoo(String f) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardReadAndWriteMethods() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public void setFoo(String f) { }
|
||||
public String getFoo() { return null; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonStandardWriteMethodOnly() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public C setFoo(String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardReadAndNonStandardWriteMethods() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public String getFoo() { return null; }
|
||||
public C setFoo(String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardReadMethodsAndOverloadedNonStandardWriteMethods() throws Exception {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public String getFoo() { return null; }
|
||||
public C setFoo(String foo) { return this; }
|
||||
public C setFoo(Number foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
|
||||
for (PropertyDescriptor pd : ebi.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals("foo")) {
|
||||
assertThat(pd.getWriteMethod(), is(C.class.getMethod("setFoo", String.class)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("never matched write method");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardReadMethodInSuperclassAndNonStandardWriteMethodInSubclass() throws Exception {
|
||||
@SuppressWarnings("unused") class B {
|
||||
public String getFoo() { return null; }
|
||||
}
|
||||
@SuppressWarnings("unused") class C extends B {
|
||||
public C setFoo(String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardReadMethodInSuperAndSubclassesAndGenericBuilderStyleNonStandardWriteMethodInSuperAndSubclasses() throws Exception {
|
||||
abstract class B<This extends B<This>> {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final This instance = (This) this;
|
||||
private String foo;
|
||||
public String getFoo() { return foo; }
|
||||
public This setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
class C extends B<C> {
|
||||
private int bar = -1;
|
||||
public int getBar() { return bar; }
|
||||
public C setBar(int bar) {
|
||||
this.bar = bar;
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
C c = new C()
|
||||
.setFoo("blue")
|
||||
.setBar(42);
|
||||
|
||||
assertThat(c.getFoo(), is("blue"));
|
||||
assertThat(c.getBar(), is(42));
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "bar"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "bar"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "bar"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "bar"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonPublicStandardReadAndWriteMethods() throws Exception {
|
||||
@SuppressWarnings("unused") class C {
|
||||
String getFoo() { return null; }
|
||||
C setFoo(String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ExtendedBeanInfo} should behave exactly like {@link BeanInfo}
|
||||
* in strange edge cases.
|
||||
*/
|
||||
@Test
|
||||
public void readMethodReturnsSupertypeOfWriteMethodParameter() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public Number getFoo() { return null; }
|
||||
public void setFoo(Integer foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadMethodReturnsSupertypeOfIndexedWriteMethodParameter() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public Number getFoos(int index) { return null; }
|
||||
public void setFoos(int index, Integer foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(false));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ExtendedBeanInfo} should behave exactly like {@link BeanInfo}
|
||||
* in strange edge cases.
|
||||
*/
|
||||
@Test
|
||||
public void readMethodReturnsSubtypeOfWriteMethodParameter() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public Integer getFoo() { return null; }
|
||||
public void setFoo(Number foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadMethodReturnsSubtypeOfIndexedWriteMethodParameter() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public Integer getFoos(int index) { return null; }
|
||||
public void setFoo(int index, Number foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(false));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadMethodOnly() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// indexed read method
|
||||
public String getFoos(int i) { return null; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foos"), is(false));
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foos"), is(false));
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedWriteMethodOnly() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// indexed write method
|
||||
public void setFoos(int i, String foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasWriteMethodForProperty(bi, "foos"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foos"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadAndIndexedWriteMethods() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// indexed read method
|
||||
public String getFoos(int i) { return null; }
|
||||
// indexed write method
|
||||
public void setFoos(int i, String foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foos"), is(false));
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foos"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foos"), is(false));
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foos"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readAndWriteAndIndexedReadAndIndexedWriteMethods() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// read method
|
||||
public String[] getFoos() { return null; }
|
||||
// indexed read method
|
||||
public String getFoos(int i) { return null; }
|
||||
// write method
|
||||
public void setFoos(String[] foos) { }
|
||||
// indexed write method
|
||||
public void setFoos(int i, String foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadAndNonStandardIndexedWrite() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// indexed read method
|
||||
public String getFoos(int i) { return null; }
|
||||
// non-standard indexed write method
|
||||
public C setFoos(int i, String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
// interesting! standard Inspector picks up non-void return types on indexed write methods by default
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexedReadAndNonStandardWriteAndNonStandardIndexedWrite() throws IntrospectionException {
|
||||
@SuppressWarnings("unused")
|
||||
class C {
|
||||
// non-standard write method
|
||||
public C setFoos(String[] foos) { return this; }
|
||||
// indexed read method
|
||||
public String getFoos(int i) { return null; }
|
||||
// non-standard indexed write method
|
||||
public C setFoos(int i, String foo) { return this; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foos"), is(false));
|
||||
// again as above, standard Inspector picks up non-void return types on indexed write methods by default
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true));
|
||||
|
||||
assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subclassWriteMethodWithCovariantReturnType() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class B {
|
||||
public String getFoo() { return null; }
|
||||
public Number setFoo(String foo) { return null; }
|
||||
}
|
||||
class C extends B {
|
||||
public String getFoo() { return null; }
|
||||
public Integer setFoo(String foo) { return null; }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(false));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors().length, equalTo(bi.getPropertyDescriptors().length));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonStandardReadMethodAndStandardWriteMethod() throws IntrospectionException {
|
||||
@SuppressWarnings("unused") class C {
|
||||
public void getFoo() { }
|
||||
public void setFoo(String foo) { }
|
||||
}
|
||||
|
||||
BeanInfo bi = Introspector.getBeanInfo(C.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(hasReadMethodForProperty(bi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(bi, "foo"), is(true));
|
||||
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo"), is(false));
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyCountsMatch() throws IntrospectionException {
|
||||
BeanInfo bi = Introspector.getBeanInfo(TestBean.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors().length, equalTo(bi.getPropertyDescriptors().length));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyCountsWithNonStandardWriteMethod() throws IntrospectionException {
|
||||
class ExtendedTestBean extends TestBean {
|
||||
@SuppressWarnings("unused")
|
||||
public ExtendedTestBean setFoo(String s) { return this; }
|
||||
}
|
||||
BeanInfo bi = Introspector.getBeanInfo(ExtendedTestBean.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
boolean found = false;
|
||||
for (PropertyDescriptor pd : ebi.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals("foo")) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assertThat(found, is(true));
|
||||
assertThat(ebi.getPropertyDescriptors().length, equalTo(bi.getPropertyDescriptors().length+1));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanInfo#getPropertyDescriptors()} returns alphanumerically sorted.
|
||||
* Test that {@link ExtendedBeanInfo#getPropertyDescriptors()} does the same.
|
||||
*/
|
||||
@Test
|
||||
public void propertyDescriptorOrderIsEqual() throws IntrospectionException {
|
||||
BeanInfo bi = Introspector.getBeanInfo(TestBean.class);
|
||||
ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
for (int i = 0; i < bi.getPropertyDescriptors().length; i++) {
|
||||
assertThat("element " + i + " in BeanInfo and ExtendedBeanInfo propertyDescriptor arrays do not match",
|
||||
ebi.getPropertyDescriptors()[i].getName(), equalTo(bi.getPropertyDescriptors()[i].getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyDescriptorComparator() throws IntrospectionException {
|
||||
PropertyDescriptorComparator c = new PropertyDescriptorComparator();
|
||||
assertThat(c.compare(new PropertyDescriptor("a", null, null), new PropertyDescriptor("a", null, null)), equalTo(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("abc", null, null), new PropertyDescriptor("abc", null, null)), equalTo(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("a", null, null), new PropertyDescriptor("b", null, null)), lessThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("b", null, null), new PropertyDescriptor("a", null, null)), greaterThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("abc", null, null), new PropertyDescriptor("abd", null, null)), lessThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("xyz", null, null), new PropertyDescriptor("123", null, null)), greaterThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("a", null, null), new PropertyDescriptor("abc", null, null)), lessThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("abc", null, null), new PropertyDescriptor("a", null, null)), greaterThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("abc", null, null), new PropertyDescriptor("b", null, null)), lessThan(0));
|
||||
|
||||
assertThat(c.compare(new PropertyDescriptor(" ", null, null), new PropertyDescriptor("a", null, null)), lessThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("1", null, null), new PropertyDescriptor("a", null, null)), lessThan(0));
|
||||
assertThat(c.compare(new PropertyDescriptor("a", null, null), new PropertyDescriptor("A", null, null)), greaterThan(0));
|
||||
}
|
||||
|
||||
|
||||
private boolean hasWriteMethodForProperty(BeanInfo beanInfo, String propertyName) {
|
||||
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals(propertyName)) {
|
||||
return pd.getWriteMethod() != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasReadMethodForProperty(BeanInfo beanInfo, String propertyName) {
|
||||
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals(propertyName)) {
|
||||
return pd.getReadMethod() != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasIndexedWriteMethodForProperty(BeanInfo beanInfo, String propertyName) {
|
||||
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals(propertyName)) {
|
||||
assertThat(propertyName + " property is not indexed", pd, instanceOf(IndexedPropertyDescriptor.class));
|
||||
return ((IndexedPropertyDescriptor)pd).getIndexedWriteMethod() != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasIndexedReadMethodForProperty(BeanInfo beanInfo, String propertyName) {
|
||||
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
|
||||
if (pd.getName().equals(propertyName)) {
|
||||
assertThat(propertyName + " property is not indexed", pd, instanceOf(IndexedPropertyDescriptor.class));
|
||||
return ((IndexedPropertyDescriptor)pd).getIndexedReadMethod() != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user