/*
* Copyright 2002-2008 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 java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
/**
* @author Juergen Hoeller
* @author Rob Harrop
* @since 19.05.2003
*/
public class BeanUtilsTests extends TestCase {
public void testInstantiateClass() {
// give proper class
BeanUtils.instantiateClass(ArrayList.class);
try {
// give interface
BeanUtils.instantiateClass(List.class);
fail("Should have thrown FatalBeanException");
}
catch (FatalBeanException ex) {
// expected
}
try {
// give class without default constructor
BeanUtils.instantiateClass(CustomDateEditor.class);
fail("Should have thrown FatalBeanException");
}
catch (FatalBeanException ex) {
// expected
}
}
public void testGetPropertyDescriptors() throws Exception {
PropertyDescriptor[] actual = Introspector.getBeanInfo(TestBean.class).getPropertyDescriptors();
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(TestBean.class);
assertNotNull("Descriptors should not be null", descriptors);
assertEquals("Invalid number of descriptors returned", actual.length, descriptors.length);
}
public void testBeanPropertyIsArray() {
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(ContainerBean.class);
for (int i = 0; i < descriptors.length; i++) {
PropertyDescriptor descriptor = descriptors[i];
if ("containedBeans".equals(descriptor.getName())) {
assertTrue("Property should be an array", descriptor.getPropertyType().isArray());
assertEquals(descriptor.getPropertyType().getComponentType(), ContainedBean.class);
}
}
}
public void testFindEditorByConvention() {
assertEquals(ResourceEditor.class, BeanUtils.findEditorByConvention(Resource.class).getClass());
}
public void testCopyProperties() throws Exception {
TestBean tb = new TestBean();
tb.setName("rod");
tb.setAge(32);
tb.setTouchy("touchy");
TestBean tb2 = new TestBean();
assertTrue("Name empty", tb2.getName() == null);
assertTrue("Age empty", tb2.getAge() == 0);
assertTrue("Touchy empty", tb2.getTouchy() == null);
BeanUtils.copyProperties(tb, tb2);
assertTrue("Name copied", tb2.getName().equals(tb.getName()));
assertTrue("Age copied", tb2.getAge() == tb.getAge());
assertTrue("Touchy copied", tb2.getTouchy().equals(tb.getTouchy()));
}
public void testCopyPropertiesWithDifferentTypes1() throws Exception {
DerivedTestBean tb = new DerivedTestBean();
tb.setName("rod");
tb.setAge(32);
tb.setTouchy("touchy");
TestBean tb2 = new TestBean();
assertTrue("Name empty", tb2.getName() == null);
assertTrue("Age empty", tb2.getAge() == 0);
assertTrue("Touchy empty", tb2.getTouchy() == null);
BeanUtils.copyProperties(tb, tb2);
assertTrue("Name copied", tb2.getName().equals(tb.getName()));
assertTrue("Age copied", tb2.getAge() == tb.getAge());
assertTrue("Touchy copied", tb2.getTouchy().equals(tb.getTouchy()));
}
public void testCopyPropertiesWithDifferentTypes2() throws Exception {
TestBean tb = new TestBean();
tb.setName("rod");
tb.setAge(32);
tb.setTouchy("touchy");
DerivedTestBean tb2 = new DerivedTestBean();
assertTrue("Name empty", tb2.getName() == null);
assertTrue("Age empty", tb2.getAge() == 0);
assertTrue("Touchy empty", tb2.getTouchy() == null);
BeanUtils.copyProperties(tb, tb2);
assertTrue("Name copied", tb2.getName().equals(tb.getName()));
assertTrue("Age copied", tb2.getAge() == tb.getAge());
assertTrue("Touchy copied", tb2.getTouchy().equals(tb.getTouchy()));
}
public void testCopyPropertiesWithEditable() throws Exception {
TestBean tb = new TestBean();
assertTrue("Name empty", tb.getName() == null);
tb.setAge(32);
tb.setTouchy("bla");
TestBean tb2 = new TestBean();
tb2.setName("rod");
assertTrue("Age empty", tb2.getAge() == 0);
assertTrue("Touchy empty", tb2.getTouchy() == null);
// "touchy" should not be copied: it's not defined in ITestBean
BeanUtils.copyProperties(tb, tb2, ITestBean.class);
assertTrue("Name copied", tb2.getName() == null);
assertTrue("Age copied", tb2.getAge() == 32);
assertTrue("Touchy still empty", tb2.getTouchy() == null);
}
public void testCopyPropertiesWithIgnore() throws Exception {
TestBean tb = new TestBean();
assertTrue("Name empty", tb.getName() == null);
tb.setAge(32);
tb.setTouchy("bla");
TestBean tb2 = new TestBean();
tb2.setName("rod");
assertTrue("Age empty", tb2.getAge() == 0);
assertTrue("Touchy empty", tb2.getTouchy() == null);
// "spouse", "touchy", "age" should not be copied
BeanUtils.copyProperties(tb, tb2, new String[]{"spouse", "touchy", "age"});
assertTrue("Name copied", tb2.getName() == null);
assertTrue("Age still empty", tb2.getAge() == 0);
assertTrue("Touchy still empty", tb2.getTouchy() == null);
}
public void testCopyPropertiesWithIgnoredNonExistingProperty() {
NameAndSpecialProperty source = new NameAndSpecialProperty();
source.setName("name");
TestBean target = new TestBean();
BeanUtils.copyProperties(source, target, new String[]{"specialProperty"});
assertEquals(target.getName(), "name");
}
public void testResolveSimpleSignature() throws Exception {
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomething", null);
assertSignatureEquals(desiredMethod, "doSomething");
assertSignatureEquals(desiredMethod, "doSomething()");
}
public void testResolveInvalidSignature() throws Exception {
try {
BeanUtils.resolveSignature("doSomething(", MethodSignatureBean.class);
fail("Should not be able to parse with opening but no closing paren.");
}
catch (IllegalArgumentException ex) {
// success
}
try {
BeanUtils.resolveSignature("doSomething)", MethodSignatureBean.class);
fail("Should not be able to parse with closing but no opening paren.");
}
catch (IllegalArgumentException ex) {
// success
}
}
public void testResolveWithAndWithoutArgList() throws Exception {
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", new Class[]{String.class, int.class});
assertSignatureEquals(desiredMethod, "doSomethingElse");
assertNull(BeanUtils.resolveSignature("doSomethingElse()", MethodSignatureBean.class));
}
public void testResolveTypedSignature() throws Exception {
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", new Class[]{String.class, int.class});
assertSignatureEquals(desiredMethod, "doSomethingElse(java.lang.String, int)");
}
public void testResolveOverloadedSignature() throws Exception {
// test resolve with no args
Method desiredMethod = MethodSignatureBean.class.getMethod("overloaded", null);
assertSignatureEquals(desiredMethod, "overloaded()");
// resolve with single arg
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", new Class[]{String.class});
assertSignatureEquals(desiredMethod, "overloaded(java.lang.String)");
// resolve with two args
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", new Class[]{String.class, BeanFactory.class});
assertSignatureEquals(desiredMethod, "overloaded(java.lang.String, org.springframework.beans.factory.BeanFactory)");
}
public void testResolveSignatureWithArray() throws Exception {
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAnArray", new Class[]{String[].class});
assertSignatureEquals(desiredMethod, "doSomethingWithAnArray(java.lang.String[])");
desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAMultiDimensionalArray", new Class[]{String[][].class});
assertSignatureEquals(desiredMethod, "doSomethingWithAMultiDimensionalArray(java.lang.String[][])");
}
private void assertSignatureEquals(Method desiredMethod, String signature) {
assertEquals(desiredMethod, BeanUtils.resolveSignature(signature, MethodSignatureBean.class));
}
private static class NameAndSpecialProperty {
private String name;
private int specialProperty;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setSpecialProperty(int specialProperty) {
this.specialProperty = specialProperty;
}
public int getSpecialProperty() {
return specialProperty;
}
}
private static class ContainerBean {
private ContainedBean[] containedBeans;
public ContainedBean[] getContainedBeans() {
return containedBeans;
}
public void setContainedBeans(ContainedBean[] containedBeans) {
this.containedBeans = containedBeans;
}
}
private static class ContainedBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private static class MethodSignatureBean {
public void doSomething() {
}
public void doSomethingElse(String s, int x) {
}
public void overloaded() {
}
public void overloaded(String s) {
}
public void overloaded(String s, BeanFactory beanFactory) {
}
public void doSomethingWithAnArray(String[] strings) {
}
public void doSomethingWithAMultiDimensionalArray(String[][] strings) {
}
}
}