Fixed type resolution in case of inconsistencies between read and write method
Issue: SPR-11361
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -59,7 +59,7 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
|||||||
* @return the type of the wrapped bean instance,
|
* @return the type of the wrapped bean instance,
|
||||||
* or {@code null} if no wrapped object has been set
|
* or {@code null} if no wrapped object has been set
|
||||||
*/
|
*/
|
||||||
Class getWrappedClass();
|
Class<?> getWrappedClass();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the PropertyDescriptors for the wrapped object
|
* Obtain the PropertyDescriptors for the wrapped object
|
||||||
@@ -79,11 +79,13 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
|||||||
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
|
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
|
* Set whether this BeanWrapper should attempt to "auto-grow" a
|
||||||
* <p>If "true", a null path location will be populated with a default object value and traversed
|
* nested path that contains a {@code null} value.
|
||||||
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also
|
* <p>If {@code true}, a {@code null} path location will be populated
|
||||||
* enables auto-growth of collection elements when accessing an out-of-bounds index.
|
* with a default object value and traversed instead of resulting in a
|
||||||
* <p>Default is "false" on a plain BeanWrapper.
|
* {@link NullValueInNestedPathException}. Turning this flag on also enables
|
||||||
|
* auto-growth of collection elements when accessing an out-of-bounds index.
|
||||||
|
* <p>Default is {@code false} on a plain BeanWrapper.
|
||||||
*/
|
*/
|
||||||
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
|
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -223,7 +223,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
return this.object;
|
return this.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Class getWrappedClass() {
|
public final Class<?> getWrappedClass() {
|
||||||
return (this.object != null ? this.object.getClass() : null);
|
return (this.object != null ? this.object.getClass() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
* Return the class of the root object at the top of the path of this BeanWrapper.
|
* Return the class of the root object at the top of the path of this BeanWrapper.
|
||||||
* @see #getNestedPath
|
* @see #getNestedPath
|
||||||
*/
|
*/
|
||||||
public final Class getRootClass() {
|
public final Class<?> getRootClass() {
|
||||||
return (this.rootObject != null ? this.rootObject.getClass() : null);
|
return (this.rootObject != null ? this.rootObject.getClass() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
* Needs to be called when the target object changes.
|
* Needs to be called when the target object changes.
|
||||||
* @param clazz the class to introspect
|
* @param clazz the class to introspect
|
||||||
*/
|
*/
|
||||||
protected void setIntrospectionClass(Class clazz) {
|
protected void setIntrospectionClass(Class<?> clazz) {
|
||||||
if (this.cachedIntrospectionResults != null &&
|
if (this.cachedIntrospectionResults != null &&
|
||||||
!clazz.equals(this.cachedIntrospectionResults.getBeanClass())) {
|
!clazz.equals(this.cachedIntrospectionResults.getBeanClass())) {
|
||||||
this.cachedIntrospectionResults = null;
|
this.cachedIntrospectionResults = null;
|
||||||
@@ -352,7 +352,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class getPropertyType(String propertyName) throws BeansException {
|
public Class<?> getPropertyType(String propertyName) throws BeansException {
|
||||||
try {
|
try {
|
||||||
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
|
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
|
||||||
if (pd != null) {
|
if (pd != null) {
|
||||||
@@ -366,7 +366,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
// Check to see if there is a custom editor,
|
// Check to see if there is a custom editor,
|
||||||
// which might give an indication on the desired target type.
|
// which might give an indication on the desired target type.
|
||||||
Class editorType = guessPropertyTypeFromEditors(propertyName);
|
Class<?> editorType = guessPropertyTypeFromEditors(propertyName);
|
||||||
if (editorType != null) {
|
if (editorType != null) {
|
||||||
return editorType;
|
return editorType;
|
||||||
}
|
}
|
||||||
@@ -485,13 +485,13 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||||
"No property '" + propertyName + "' found");
|
"No property '" + propertyName + "' found");
|
||||||
}
|
}
|
||||||
return convertForProperty(propertyName, null, value, pd);
|
return convertForProperty(propertyName, null, value, new TypeDescriptor(property(pd)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd)
|
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, TypeDescriptor td)
|
||||||
throws TypeMismatchException {
|
throws TypeMismatchException {
|
||||||
|
|
||||||
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(), new TypeDescriptor(property(pd)));
|
return convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Property property(PropertyDescriptor pd) {
|
private Property property(PropertyDescriptor pd) {
|
||||||
@@ -699,7 +699,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
return nestedBw.getPropertyValue(tokens);
|
return nestedBw.getPropertyValue(tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
|
@SuppressWarnings("unchecked")
|
||||||
|
private Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
|
||||||
String propertyName = tokens.canonicalName;
|
String propertyName = tokens.canonicalName;
|
||||||
String actualName = tokens.actualName;
|
String actualName = tokens.actualName;
|
||||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||||
@@ -766,20 +767,20 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
else if (value instanceof List) {
|
else if (value instanceof List) {
|
||||||
int index = Integer.parseInt(key);
|
int index = Integer.parseInt(key);
|
||||||
List list = (List) value;
|
List<Object> list = (List<Object>) value;
|
||||||
growCollectionIfNecessary(list, index, indexedPropertyName, pd, i + 1);
|
growCollectionIfNecessary(list, index, indexedPropertyName, pd, i + 1);
|
||||||
value = list.get(index);
|
value = list.get(index);
|
||||||
}
|
}
|
||||||
else if (value instanceof Set) {
|
else if (value instanceof Set) {
|
||||||
// Apply index to Iterator in case of a Set.
|
// Apply index to Iterator in case of a Set.
|
||||||
Set set = (Set) value;
|
Set<Object> set = (Set<Object>) value;
|
||||||
int index = Integer.parseInt(key);
|
int index = Integer.parseInt(key);
|
||||||
if (index < 0 || index >= set.size()) {
|
if (index < 0 || index >= set.size()) {
|
||||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||||
"Cannot get element with index " + index + " from Set of size " +
|
"Cannot get element with index " + index + " from Set of size " +
|
||||||
set.size() + ", accessed using property path '" + propertyName + "'");
|
set.size() + ", accessed using property path '" + propertyName + "'");
|
||||||
}
|
}
|
||||||
Iterator it = set.iterator();
|
Iterator<Object> it = set.iterator();
|
||||||
for (int j = 0; it.hasNext(); j++) {
|
for (int j = 0; it.hasNext(); j++) {
|
||||||
Object elem = it.next();
|
Object elem = it.next();
|
||||||
if (j == index) {
|
if (j == index) {
|
||||||
@@ -789,11 +790,12 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (value instanceof Map) {
|
else if (value instanceof Map) {
|
||||||
Map map = (Map) value;
|
Map<Object, Object> map = (Map<Object, Object>) value;
|
||||||
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
|
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
|
||||||
// IMPORTANT: Do not pass full property name in here - property editors
|
// IMPORTANT: Do not pass full property name in here - property editors
|
||||||
// must not kick in for map keys but rather only for map values.
|
// must not kick in for map keys but rather only for map values.
|
||||||
TypeDescriptor typeDescriptor = mapKeyType != null ? TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class);
|
TypeDescriptor typeDescriptor = (mapKeyType != null ?
|
||||||
|
TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class));
|
||||||
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
|
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
|
||||||
value = map.get(convertedMapKey);
|
value = map.get(convertedMapKey);
|
||||||
}
|
}
|
||||||
@@ -850,16 +852,15 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private void growCollectionIfNecessary(Collection<Object> collection, int index, String name,
|
||||||
private void growCollectionIfNecessary(
|
PropertyDescriptor pd, int nestingLevel) {
|
||||||
Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {
|
|
||||||
|
|
||||||
if (!this.autoGrowNestedPaths) {
|
if (!this.autoGrowNestedPaths) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int size = collection.size();
|
int size = collection.size();
|
||||||
if (index >= size && index < this.autoGrowCollectionLimit) {
|
if (index >= size && index < this.autoGrowCollectionLimit) {
|
||||||
Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel);
|
Class<?> elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel);
|
||||||
if (elementType != null) {
|
if (elementType != null) {
|
||||||
for (int i = collection.size(); i < index + 1; i++) {
|
for (int i = collection.size(); i < index + 1; i++) {
|
||||||
collection.add(newValue(elementType, name));
|
collection.add(newValue(elementType, name));
|
||||||
@@ -945,7 +946,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
if (propValue.getClass().isArray()) {
|
if (propValue.getClass().isArray()) {
|
||||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||||
Class requiredType = propValue.getClass().getComponentType();
|
Class<?> requiredType = propValue.getClass().getComponentType();
|
||||||
int arrayIndex = Integer.parseInt(key);
|
int arrayIndex = Integer.parseInt(key);
|
||||||
Object oldValue = null;
|
Object oldValue = null;
|
||||||
try {
|
try {
|
||||||
@@ -963,9 +964,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
else if (propValue instanceof List) {
|
else if (propValue instanceof List) {
|
||||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||||
Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
|
Class<?> requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
|
||||||
pd.getReadMethod(), tokens.keys.length);
|
pd.getReadMethod(), tokens.keys.length);
|
||||||
List list = (List) propValue;
|
List<Object> list = (List<Object>) propValue;
|
||||||
int index = Integer.parseInt(key);
|
int index = Integer.parseInt(key);
|
||||||
Object oldValue = null;
|
Object oldValue = null;
|
||||||
if (isExtractOldValueForEditor() && index < list.size()) {
|
if (isExtractOldValueForEditor() && index < list.size()) {
|
||||||
@@ -1000,11 +1001,11 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
else if (propValue instanceof Map) {
|
else if (propValue instanceof Map) {
|
||||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||||
Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
|
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
|
||||||
pd.getReadMethod(), tokens.keys.length);
|
pd.getReadMethod(), tokens.keys.length);
|
||||||
Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
|
Class<?> mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
|
||||||
pd.getReadMethod(), tokens.keys.length);
|
pd.getReadMethod(), tokens.keys.length);
|
||||||
Map map = (Map) propValue;
|
Map<Object, Object> map = (Map<Object, Object>) propValue;
|
||||||
// IMPORTANT: Do not pass full property name in here - property editors
|
// IMPORTANT: Do not pass full property name in here - property editors
|
||||||
// must not kick in for map keys but rather only for map values.
|
// must not kick in for map keys but rather only for map values.
|
||||||
TypeDescriptor typeDescriptor = (mapKeyType != null ?
|
TypeDescriptor typeDescriptor = (mapKeyType != null ?
|
||||||
@@ -1094,7 +1095,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
|
valueToApply = convertForProperty(
|
||||||
|
propertyName, oldValue, originalValue, new TypeDescriptor(property(pd)));
|
||||||
}
|
}
|
||||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,13 +16,6 @@
|
|||||||
|
|
||||||
package org.springframework.beans;
|
package org.springframework.beans;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertSame;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@@ -44,11 +37,16 @@ import java.util.TreeSet;
|
|||||||
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowire;
|
import org.springframework.beans.factory.annotation.Autowire;
|
||||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||||
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
|
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
|
||||||
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
||||||
import org.springframework.beans.support.DerivedFromProtectedBaseBean;
|
import org.springframework.beans.support.DerivedFromProtectedBaseBean;
|
||||||
|
import org.springframework.core.convert.ConversionFailedException;
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
|
import org.springframework.core.convert.support.GenericConversionService;
|
||||||
import org.springframework.tests.Assume;
|
import org.springframework.tests.Assume;
|
||||||
import org.springframework.tests.TestGroup;
|
import org.springframework.tests.TestGroup;
|
||||||
import org.springframework.tests.sample.beans.BooleanTestBean;
|
import org.springframework.tests.sample.beans.BooleanTestBean;
|
||||||
@@ -56,15 +54,10 @@ import org.springframework.tests.sample.beans.ITestBean;
|
|||||||
import org.springframework.tests.sample.beans.IndexedTestBean;
|
import org.springframework.tests.sample.beans.IndexedTestBean;
|
||||||
import org.springframework.tests.sample.beans.NumberTestBean;
|
import org.springframework.tests.sample.beans.NumberTestBean;
|
||||||
import org.springframework.tests.sample.beans.TestBean;
|
import org.springframework.tests.sample.beans.TestBean;
|
||||||
import org.springframework.core.convert.ConversionFailedException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
|
||||||
import org.springframework.core.convert.support.GenericConversionService;
|
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
||||||
@@ -1557,17 +1550,15 @@ public final class BeanWrapperTests {
|
|||||||
@Test
|
@Test
|
||||||
public void cornerSpr10115() {
|
public void cornerSpr10115() {
|
||||||
Spr10115Bean foo = new Spr10115Bean();
|
Spr10115Bean foo = new Spr10115Bean();
|
||||||
BeanWrapperImpl bwi = new BeanWrapperImpl();
|
BeanWrapperImpl bwi = new BeanWrapperImpl(foo);
|
||||||
bwi.setWrappedInstance(foo);
|
|
||||||
bwi.setPropertyValue("prop1", "val1");
|
bwi.setPropertyValue("prop1", "val1");
|
||||||
assertEquals("val1", Spr10115Bean.prop1);
|
assertEquals("val1", Spr10115Bean.prop1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArrayToObject() throws Exception {
|
public void testArrayToObject() {
|
||||||
ArrayToObject foo = new ArrayToObject();
|
ArrayToObject foo = new ArrayToObject();
|
||||||
BeanWrapperImpl bwi = new BeanWrapperImpl();
|
BeanWrapperImpl bwi = new BeanWrapperImpl(foo);
|
||||||
bwi.setWrappedInstance(foo);
|
|
||||||
|
|
||||||
Object[] array = new Object[] {"1","2"};
|
Object[] array = new Object[] {"1","2"};
|
||||||
bwi.setPropertyValue("object", array );
|
bwi.setPropertyValue("object", array );
|
||||||
@@ -1576,9 +1567,20 @@ public final class BeanWrapperTests {
|
|||||||
array = new Object[] {"1"};
|
array = new Object[] {"1"};
|
||||||
bwi.setPropertyValue("object", array );
|
bwi.setPropertyValue("object", array );
|
||||||
assertThat(foo.getObject(), equalTo((Object) array));
|
assertThat(foo.getObject(), equalTo((Object) array));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPropertyTypeMismatch() {
|
||||||
|
PropertyTypeMismatch foo = new PropertyTypeMismatch();
|
||||||
|
BeanWrapperImpl bwi = new BeanWrapperImpl(foo);
|
||||||
|
bwi.setPropertyValue("object", "a String");
|
||||||
|
assertEquals("a String", foo.value);
|
||||||
|
assertEquals(8, bwi.getPropertyValue("object"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static class Spr10115Bean {
|
static class Spr10115Bean {
|
||||||
|
|
||||||
private static String prop1;
|
private static String prop1;
|
||||||
|
|
||||||
public static void setProp1(String prop1) {
|
public static void setProp1(String prop1) {
|
||||||
@@ -1963,11 +1965,10 @@ public final class BeanWrapperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static class ArrayToObject {
|
public static class ArrayToObject {
|
||||||
|
|
||||||
private Object object;
|
private Object object;
|
||||||
|
|
||||||
|
|
||||||
public void setObject(Object object) {
|
public void setObject(Object object) {
|
||||||
this.object = object;
|
this.object = object;
|
||||||
}
|
}
|
||||||
@@ -1975,6 +1976,20 @@ public final class BeanWrapperTests {
|
|||||||
public Object getObject() {
|
public Object getObject() {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class PropertyTypeMismatch {
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public void setObject(String object) {
|
||||||
|
this.value = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getObject() {
|
||||||
|
return (this.value != null ? this.value.length() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user