diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java b/org.springframework.beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java index 191d5fa1dd6..2b9927cd3f6 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java @@ -22,6 +22,7 @@ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -29,12 +30,12 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import java.util.Collection; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; /** * Internal class that caches JavaBeans {@link java.beans.PropertyDescriptor} @@ -130,7 +131,7 @@ public class CachedIntrospectionResults { * @throws BeansException in case of introspection failure */ static CachedIntrospectionResults forClass(Class beanClass) throws BeansException { - CachedIntrospectionResults results = null; + CachedIntrospectionResults results; Object value = classCache.get(beanClass); if (value instanceof Reference) { Reference ref = (Reference) value; @@ -265,8 +266,15 @@ public class CachedIntrospectionResults { return this.beanInfo.getBeanDescriptor().getBeanClass(); } - PropertyDescriptor getPropertyDescriptor(String propertyName) { - return this.propertyDescriptorCache.get(propertyName); + PropertyDescriptor getPropertyDescriptor(String name) { + PropertyDescriptor pd = this.propertyDescriptorCache.get(name); + if (pd == null && StringUtils.hasLength(name)) { + pd = this.propertyDescriptorCache.get(name.substring(0, 1).toLowerCase() + name.substring(1)); + if (pd == null) { + pd = this.propertyDescriptorCache.get(name.substring(0, 1).toUpperCase() + name.substring(1)); + } + } + return pd; } PropertyDescriptor[] getPropertyDescriptors() { diff --git a/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java b/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java index 2e6b73b3979..097f42e7a1c 100644 --- a/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java @@ -625,6 +625,29 @@ public class DataBinderTests extends TestCase { assertEquals("value", tb.getName()); } + public void testJavaBeanPropertyConventions() { + Book book = new Book(); + DataBinder binder = new DataBinder(book); + + MutablePropertyValues pvs = new MutablePropertyValues(); + pvs.add("title", "my book"); + pvs.add("ISBN", "1234"); + pvs.add("NInStock", "5"); + binder.bind(pvs); + assertEquals("my book", book.getTitle()); + assertEquals("1234", book.getISBN()); + assertEquals(5, book.getNInStock()); + + pvs = new MutablePropertyValues(); + pvs.add("Title", "my other book"); + pvs.add("iSBN", "6789"); + pvs.add("nInStock", "0"); + binder.bind(pvs); + assertEquals("my other book", book.getTitle()); + assertEquals("6789", book.getISBN()); + assertEquals(0, book.getNInStock()); + } + public void testValidatorNoErrors() { TestBean tb = new TestBean(); tb.setAge(33); @@ -1336,6 +1359,40 @@ public class DataBinderTests extends TestCase { } + private static class Book { + + private String Title; + + private String ISBN; + + private int nInStock; + + public String getTitle() { + return Title; + } + + public void setTitle(String title) { + Title = title; + } + + public String getISBN() { + return ISBN; + } + + public void setISBN(String ISBN) { + this.ISBN = ISBN; + } + + public int getNInStock() { + return nInStock; + } + + public void setNInStock(int nInStock) { + this.nInStock = nInStock; + } + } + + private static class TestBeanValidator implements Validator { public boolean supports(Class clazz) {