Skip to content

Commit 388edd7

Browse files
committed
lenient property name casing, beyond standard JavaBeans conventions (SPR-6491)
1 parent 0a36596 commit 388edd7

2 files changed

Lines changed: 69 additions & 4 deletions

File tree

org.springframework.beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@
2222
import java.beans.PropertyDescriptor;
2323
import java.lang.ref.Reference;
2424
import java.lang.ref.WeakReference;
25+
import java.util.Collection;
2526
import java.util.Collections;
2627
import java.util.HashMap;
2728
import java.util.HashSet;
2829
import java.util.Iterator;
2930
import java.util.Map;
3031
import java.util.Set;
3132
import java.util.WeakHashMap;
32-
import java.util.Collection;
3333

3434
import org.apache.commons.logging.Log;
3535
import org.apache.commons.logging.LogFactory;
3636

3737
import org.springframework.util.ClassUtils;
38+
import org.springframework.util.StringUtils;
3839

3940
/**
4041
* Internal class that caches JavaBeans {@link java.beans.PropertyDescriptor}
@@ -130,7 +131,7 @@ public static void clearClassLoader(ClassLoader classLoader) {
130131
* @throws BeansException in case of introspection failure
131132
*/
132133
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
133-
CachedIntrospectionResults results = null;
134+
CachedIntrospectionResults results;
134135
Object value = classCache.get(beanClass);
135136
if (value instanceof Reference) {
136137
Reference ref = (Reference) value;
@@ -265,8 +266,15 @@ Class getBeanClass() {
265266
return this.beanInfo.getBeanDescriptor().getBeanClass();
266267
}
267268

268-
PropertyDescriptor getPropertyDescriptor(String propertyName) {
269-
return this.propertyDescriptorCache.get(propertyName);
269+
PropertyDescriptor getPropertyDescriptor(String name) {
270+
PropertyDescriptor pd = this.propertyDescriptorCache.get(name);
271+
if (pd == null && StringUtils.hasLength(name)) {
272+
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toLowerCase() + name.substring(1));
273+
if (pd == null) {
274+
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toUpperCase() + name.substring(1));
275+
}
276+
}
277+
return pd;
270278
}
271279

272280
PropertyDescriptor[] getPropertyDescriptors() {

org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,29 @@ public void setAsText(String text) throws IllegalArgumentException {
625625
assertEquals("value", tb.getName());
626626
}
627627

628+
public void testJavaBeanPropertyConventions() {
629+
Book book = new Book();
630+
DataBinder binder = new DataBinder(book);
631+
632+
MutablePropertyValues pvs = new MutablePropertyValues();
633+
pvs.add("title", "my book");
634+
pvs.add("ISBN", "1234");
635+
pvs.add("NInStock", "5");
636+
binder.bind(pvs);
637+
assertEquals("my book", book.getTitle());
638+
assertEquals("1234", book.getISBN());
639+
assertEquals(5, book.getNInStock());
640+
641+
pvs = new MutablePropertyValues();
642+
pvs.add("Title", "my other book");
643+
pvs.add("iSBN", "6789");
644+
pvs.add("nInStock", "0");
645+
binder.bind(pvs);
646+
assertEquals("my other book", book.getTitle());
647+
assertEquals("6789", book.getISBN());
648+
assertEquals(0, book.getNInStock());
649+
}
650+
628651
public void testValidatorNoErrors() {
629652
TestBean tb = new TestBean();
630653
tb.setAge(33);
@@ -1336,6 +1359,40 @@ public void testTrackDisallowedFields() throws Exception {
13361359
}
13371360

13381361

1362+
private static class Book {
1363+
1364+
private String Title;
1365+
1366+
private String ISBN;
1367+
1368+
private int nInStock;
1369+
1370+
public String getTitle() {
1371+
return Title;
1372+
}
1373+
1374+
public void setTitle(String title) {
1375+
Title = title;
1376+
}
1377+
1378+
public String getISBN() {
1379+
return ISBN;
1380+
}
1381+
1382+
public void setISBN(String ISBN) {
1383+
this.ISBN = ISBN;
1384+
}
1385+
1386+
public int getNInStock() {
1387+
return nInStock;
1388+
}
1389+
1390+
public void setNInStock(int nInStock) {
1391+
this.nInStock = nInStock;
1392+
}
1393+
}
1394+
1395+
13391396
private static class TestBeanValidator implements Validator {
13401397

13411398
public boolean supports(Class clazz) {

0 commit comments

Comments
 (0)