From a73324bc24b0b7c960cae3d695a6d8c867031f11 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 7 Oct 2009 19:11:22 +0000 Subject: [PATCH] polish --- .../mapping/support/SpelMapper.java | 15 ++++++++++ .../mapping/support/SpelMapperTests.java | 28 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/org.springframework.context/src/main/java/org/springframework/mapping/support/SpelMapper.java b/org.springframework.context/src/main/java/org/springframework/mapping/support/SpelMapper.java index 628da8539c1..57ed8818606 100644 --- a/org.springframework.context/src/main/java/org/springframework/mapping/support/SpelMapper.java +++ b/org.springframework.context/src/main/java/org/springframework/mapping/support/SpelMapper.java @@ -24,6 +24,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.core.GenericTypeResolver; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterRegistry; @@ -115,6 +116,16 @@ public class SpelMapper implements Mapper { return mapping; } + /** + * Adds a Mapper to apply to complex nested property mappings of a specific sourceType/targetType pair. + * The source and target types are determined by introspecting the parameterized types on the implementation's Mapper generic interface. + * @param nestedMapper the nested mapper + */ + public void addNestedMapper(Mapper nestedMapper) { + Class[] typeInfo = getRequiredTypeInfo(nestedMapper); + addNestedMapper(typeInfo[0], typeInfo[1], nestedMapper); + } + /** * Adds a Mapper to apply to complex nested property mappings of a specific sourceType/targetType pair. * @param sourceType the source nested property type @@ -159,6 +170,10 @@ public class SpelMapper implements Mapper { // internal helpers + private Class[] getRequiredTypeInfo(Mapper mapper) { + return GenericTypeResolver.resolveTypeArguments(mapper.getClass(), Mapper.class); + } + private EvaluationContext getEvaluationContext(Object object) { return mappableTypeFactory.getMappableType(object).getEvaluationContext(object, this.conversionService); } diff --git a/org.springframework.context/src/test/java/org/springframework/mapping/support/SpelMapperTests.java b/org.springframework.context/src/test/java/org/springframework/mapping/support/SpelMapperTests.java index d4d977dda5f..320cc9466c8 100644 --- a/org.springframework.context/src/test/java/org/springframework/mapping/support/SpelMapperTests.java +++ b/org.springframework.context/src/test/java/org/springframework/mapping/support/SpelMapperTests.java @@ -12,6 +12,7 @@ import java.util.Map; import org.junit.Test; import org.springframework.core.convert.converter.Converter; +import org.springframework.mapping.Mapper; import org.springframework.mapping.MappingException; public class SpelMapperTests { @@ -147,7 +148,7 @@ public class SpelMapperTests { } @Test - public void mapBeanNestedCustomMapper() { + public void mapBeanNestedCustomNestedMapper() { PersonDto source = new PersonDto(); NestedDto nested = new NestedDto(); nested.foo = "bar"; @@ -171,6 +172,31 @@ public class SpelMapperTests { assertEquals("bar and baz", target.nested.foo); } + @Test + public void mapBeanNestedCustomNestedMapperHandCoded() { + PersonDto source = new PersonDto(); + NestedDto nested = new NestedDto(); + nested.foo = "bar"; + source.setNested(nested); + + Person target = new Person(); + + Mapper nestedMapper = new Mapper() { + public Object map(NestedDto source, Nested target) { + target.foo = source.foo + " and baz"; + return target; + } + + }; + mapper.addNestedMapper(nestedMapper); + + mapper.setAutoMappingEnabled(false); + mapper.addMapping("nested"); + mapper.map(source, target); + + assertEquals("bar and baz", target.nested.foo); + } + @Test public void mapList() { PersonDto source = new PersonDto();