From 3ba4bb31facfe3d0d309b944ab162f34d47b592c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 Jun 2012 11:39:16 +0100 Subject: [PATCH 1/3] Add Maven artifacts to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 51274577d12..85cd49b777c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .DS_Store .settings .springBeans +target bin build.sh integration-repo @@ -17,6 +18,7 @@ build .classpath .project argfile* +pom.xml # IDEA metadata and output dirs *.iml From 8e754e9065b5703f93909f480933488a2b180429 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 Jun 2012 11:40:28 +0100 Subject: [PATCH 2/3] SPR-9498: don't make assumptions about equality if ConversionService has failed The failure of the conversion service is not fatal, but the check that was in there (line 248) was inadequate to detect the cases that could already be handled by the default property editors. This code path was also not tested anywhere in spring-beans tests until now. --- .../beans/TypeConverterDelegate.java | 3 +- .../beans/BeanWrapperTests.java | 29 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java index 9776b460b76..64f437320f3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java +++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java @@ -44,6 +44,7 @@ import org.springframework.util.StringUtils; * * @author Juergen Hoeller * @author Rob Harrop + * @author Dave Syer * @since 2.0 * @see BeanWrapperImpl * @see SimpleTypeConverter @@ -244,7 +245,7 @@ class TypeConverterDelegate { } if (firstAttemptEx != null) { - if (editor == null && convertedValue == newValue) { + if (editor == null && convertedValue == newValue && requiredType!=null && !ClassUtils.isAssignableValue(requiredType, convertedValue)) { throw firstAttemptEx; } logger.debug("Original ConversionService attempt failed - ignored since " + diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java index 49c301284a5..f6e68234bbb 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java @@ -43,14 +43,16 @@ import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.logging.LogFactory; -import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.beans.propertyeditors.StringArrayPropertyEditor; import org.springframework.beans.propertyeditors.StringTrimmerEditor; 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.util.StopWatch; import org.springframework.util.StringUtils; @@ -66,9 +68,34 @@ import test.beans.TestBean; * @author Alef Arendsen * @author Arjen Poutsma * @author Chris Beams + * @author Dave Syer */ public final class BeanWrapperTests { + @Test + public void testNullNestedTypeDescriptorWithNoConversionService() { + Foo foo = new Foo(); + BeanWrapperImpl wrapper = new BeanWrapperImpl(foo); + wrapper.setAutoGrowNestedPaths(true); + wrapper.setPropertyValue("listOfMaps[0]['luckyNumber']", "9"); + assertEquals("9", foo.listOfMaps.get(0).get("luckyNumber")); + } + + @Test + public void testNullNestedTypeDescriptorWithBadConversionService() { + Foo foo = new Foo(); + BeanWrapperImpl wrapper = new BeanWrapperImpl(foo); + wrapper.setConversionService(new GenericConversionService() { + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + throw new ConversionFailedException(sourceType, targetType, source, null); + } + }); + wrapper.setAutoGrowNestedPaths(true); + wrapper.setPropertyValue("listOfMaps[0]['luckyNumber']", "9"); + assertEquals("9", foo.listOfMaps.get(0).get("luckyNumber")); + } + @Test public void testNullNestedTypeDescriptor() { Foo foo = new Foo(); From cd6f7de4082258f9dcf78657633035da5abfcd65 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 Jun 2012 11:42:23 +0100 Subject: [PATCH 3/3] SPR-9498: Add support for MultiValueMap to CollectionFactory This turns out not to be the main problem exposed in SPR-9498 but it seems like a sensible addition anyway. --- .../java/org/springframework/core/CollectionFactory.java | 5 +++++ .../org/springframework/core/CollectionFactoryTests.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java index e34d65fe493..2d31fc362a4 100644 --- a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java +++ b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java @@ -35,6 +35,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import org.springframework.util.LinkedCaseInsensitiveMap; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; /** * Factory for collections, being aware of Java 5 and Java 6 collections. @@ -305,6 +307,9 @@ public abstract class CollectionFactory { else if (SortedMap.class.equals(mapType) || mapType.equals(navigableMapClass)) { return new TreeMap(); } + else if (MultiValueMap.class.equals(mapType)) { + return new LinkedMultiValueMap(); + } else { throw new IllegalArgumentException("Unsupported Map interface: " + mapType.getName()); } diff --git a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java index 2bdd6df41a0..978f4302b4e 100644 --- a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java +++ b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java @@ -24,9 +24,12 @@ import java.util.Set; import junit.framework.TestCase; +import org.springframework.util.MultiValueMap; + /** * @author Darren Davison * @author Juergen Hoeller + * @author Dave Syer */ public class CollectionFactoryTests extends TestCase { @@ -50,6 +53,11 @@ public class CollectionFactoryTests extends TestCase { assertTrue(map.getClass().getName().endsWith("ConcurrentHashMap")); } + public void testMultiValueMap() { + Map map = CollectionFactory.createMap(MultiValueMap.class, 16); + assertTrue(map.getClass().getName().endsWith("MultiValueMap")); + } + public void testConcurrentMapWithExplicitInterface() { ConcurrentMap map = CollectionFactory.createConcurrentMap(16); assertTrue(map.getClass().getSuperclass().getName().endsWith("ConcurrentHashMap"));