do not try to convert read-only Collections/Maps (SPR-6808)
This commit is contained in:
parent
81649d5c3b
commit
6c0d934b92
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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.
|
||||||
|
|
@ -576,7 +576,16 @@ class TypeConverterDelegate {
|
||||||
if (methodParam != null) {
|
if (methodParam != null) {
|
||||||
methodParam.decreaseNestingLevel();
|
methodParam.decreaseNestingLevel();
|
||||||
}
|
}
|
||||||
convertedCopy.add(convertedElement);
|
try {
|
||||||
|
convertedCopy.add(convertedElement);
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Collection type [" + original.getClass().getName() +
|
||||||
|
"] seems to be read-only - injecting original Collection as-is", ex);
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
originalAllowed = originalAllowed && (element == convertedElement);
|
originalAllowed = originalAllowed && (element == convertedElement);
|
||||||
}
|
}
|
||||||
return (originalAllowed ? original : convertedCopy);
|
return (originalAllowed ? original : convertedCopy);
|
||||||
|
|
@ -650,7 +659,16 @@ class TypeConverterDelegate {
|
||||||
if (methodParam != null) {
|
if (methodParam != null) {
|
||||||
methodParam.decreaseNestingLevel();
|
methodParam.decreaseNestingLevel();
|
||||||
}
|
}
|
||||||
convertedCopy.put(convertedKey, convertedValue);
|
try {
|
||||||
|
convertedCopy.put(convertedKey, convertedValue);
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Map type [" + original.getClass().getName() +
|
||||||
|
"] seems to be read-only - injecting original Map as-is", ex);
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
originalAllowed = originalAllowed && (key == convertedKey) && (value == convertedValue);
|
originalAllowed = originalAllowed && (key == convertedKey) && (value == convertedValue);
|
||||||
}
|
}
|
||||||
return (originalAllowed ? original : convertedCopy);
|
return (originalAllowed ? original : convertedCopy);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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,8 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.beans;
|
package org.springframework.beans;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
@ -38,7 +36,14 @@ import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import test.beans.BooleanTestBean;
|
||||||
|
import test.beans.ITestBean;
|
||||||
|
import test.beans.IndexedTestBean;
|
||||||
|
import test.beans.NumberTestBean;
|
||||||
|
import test.beans.TestBean;
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -47,12 +52,6 @@ import org.springframework.beans.support.DerivedFromProtectedBaseBean;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import test.beans.BooleanTestBean;
|
|
||||||
import test.beans.ITestBean;
|
|
||||||
import test.beans.IndexedTestBean;
|
|
||||||
import test.beans.NumberTestBean;
|
|
||||||
import test.beans.TestBean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
|
@ -1056,6 +1055,14 @@ public final class BeanWrapperTests {
|
||||||
assertFalse(readOnlyMap.isAccessed());
|
assertFalse(readOnlyMap.isAccessed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypedMapReadOnlyMap() {
|
||||||
|
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
|
||||||
|
TypedReadOnlyMapClient bean = new TypedReadOnlyMapClient();
|
||||||
|
BeanWrapper bw = new BeanWrapperImpl(bean);
|
||||||
|
bw.setPropertyValue("map", map);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPrimitiveArray() {
|
public void testPrimitiveArray() {
|
||||||
PrimitiveArrayBean tb = new PrimitiveArrayBean();
|
PrimitiveArrayBean tb = new PrimitiveArrayBean();
|
||||||
|
|
@ -1717,7 +1724,7 @@ public final class BeanWrapperTests {
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class ReadOnlyMap extends HashMap<Object, Object> {
|
public static class ReadOnlyMap<K, V> extends HashMap<K, V> {
|
||||||
|
|
||||||
private boolean frozen = false;
|
private boolean frozen = false;
|
||||||
|
|
||||||
|
|
@ -1727,12 +1734,12 @@ public final class BeanWrapperTests {
|
||||||
this.frozen = true;
|
this.frozen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyMap(Map<Object, Object> map) {
|
public ReadOnlyMap(Map<? extends K, ? extends V> map) {
|
||||||
super(map);
|
super(map);
|
||||||
this.frozen = true;
|
this.frozen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object put(Object key, Object value) {
|
public V put(K key, V value) {
|
||||||
if (this.frozen) {
|
if (this.frozen) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
@ -1741,12 +1748,12 @@ public final class BeanWrapperTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Map.Entry<Object, Object>> entrySet() {
|
public Set<Map.Entry<K, V>> entrySet() {
|
||||||
this.accessed = true;
|
this.accessed = true;
|
||||||
return super.entrySet();
|
return super.entrySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Object> keySet() {
|
public Set<K> keySet() {
|
||||||
this.accessed = true;
|
this.accessed = true;
|
||||||
return super.keySet();
|
return super.keySet();
|
||||||
}
|
}
|
||||||
|
|
@ -1761,7 +1768,27 @@ public final class BeanWrapperTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class TypedReadOnlyMap extends ReadOnlyMap<String, TestBean> {
|
||||||
|
|
||||||
|
public TypedReadOnlyMap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypedReadOnlyMap(Map<? extends String, ? extends TestBean> map) {
|
||||||
|
super(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class TypedReadOnlyMapClient {
|
||||||
|
|
||||||
|
public void setMap(TypedReadOnlyMap map) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class EnumConsumer {
|
public static class EnumConsumer {
|
||||||
|
|
||||||
private Enum<TestEnum> enumValue;
|
private Enum<TestEnum> enumValue;
|
||||||
|
|
||||||
public Enum<TestEnum> getEnumValue() {
|
public Enum<TestEnum> getEnumValue() {
|
||||||
|
|
@ -1773,7 +1800,9 @@ public final class BeanWrapperTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class WildcardEnumConsumer {
|
public static class WildcardEnumConsumer {
|
||||||
|
|
||||||
private Enum<?> enumValue;
|
private Enum<?> enumValue;
|
||||||
|
|
||||||
public Enum<?> getEnumValue() {
|
public Enum<?> getEnumValue() {
|
||||||
|
|
@ -1785,7 +1814,9 @@ public final class BeanWrapperTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum TestEnum {
|
public enum TestEnum {
|
||||||
|
|
||||||
TEST_VALUE
|
TEST_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue