From 27ad78d524d4ec6f075bfd9f89d3dd163556da99 Mon Sep 17 00:00:00 2001 From: sjaakd Date: Fri, 14 Nov 2014 21:34:01 +0100 Subject: [PATCH] #295 NullValueMapping for MapMapping on mapping method level --- .../mapstruct/ap/model/MapMappingMethod.java | 37 ++++++++++++++++--- ...rg.mapstruct.ap.model.MapMappingMethod.ftl | 4 ++ .../ap/test/mapnulltodefault/CarMapper.java | 4 ++ .../test/mapnulltodefault/CarMapperTest.java | 26 +++++++++++++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java index b2cc0a952..d1a87658a 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java @@ -18,6 +18,7 @@ */ package org.mapstruct.ap.model; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -28,7 +29,9 @@ import org.mapstruct.ap.model.assignment.Assignment; import org.mapstruct.ap.model.assignment.LocalVarWrapper; import org.mapstruct.ap.model.common.Parameter; import org.mapstruct.ap.model.common.Type; +import org.mapstruct.ap.model.common.TypeFactory; import org.mapstruct.ap.model.source.Method; +import org.mapstruct.ap.prism.MapNullToDefaultPrism; import org.mapstruct.ap.util.Strings; /** @@ -43,6 +46,8 @@ public class MapMappingMethod extends MappingMethod { private final Assignment valueAssignment; private final MethodReference factoryMethod; private final boolean overridden; + private final boolean mapNullToDefault; + private final TypeFactory typeFactory; public static class Builder { @@ -134,23 +139,36 @@ public class MapMappingMethod extends MappingMethod { ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, message, method.getExecutable() ); } + // mapNullToDefault + MapNullToDefaultPrism prism = MapNullToDefaultPrism.getInstanceOn( method.getExecutable() ); + boolean mapNullToDefault = ( prism != null ) && prism.value(); + MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx ); keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes() ); valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes() ); - return new MapMappingMethod( method, keyAssignment, valueAssignment, factoryMethod ); + return new MapMappingMethod( + method, + keyAssignment, + valueAssignment, + factoryMethod, + mapNullToDefault, + ctx.getTypeFactory() + ); } } private MapMappingMethod(Method method, Assignment keyAssignment, Assignment valueAssignment, - MethodReference factoryMethod) { + MethodReference factoryMethod, boolean mapNullToDefault, TypeFactory typeFactory) { super( method ); this.keyAssignment = keyAssignment; this.valueAssignment = valueAssignment; this.factoryMethod = factoryMethod; this.overridden = method.overridesMethod(); + this.mapNullToDefault = mapNullToDefault; + this.typeFactory = typeFactory; } public Parameter getSourceParameter() { @@ -182,6 +200,10 @@ public class MapMappingMethod extends MappingMethod { types.addAll( valueAssignment.getImportTypes() ); } + if (mapNullToDefault) { + types.add( typeFactory.getType( Collections.class ) ); + } + return types; } @@ -210,6 +232,14 @@ public class MapMappingMethod extends MappingMethod { return this.factoryMethod; } + public boolean isMapNullToDefault() { + return mapNullToDefault; + } + + public boolean isOverridden() { + return overridden; + } + @Override public int hashCode() { final int prime = 31; @@ -249,7 +279,4 @@ public class MapMappingMethod extends MappingMethod { return true; } - public boolean isOverridden() { - return overridden; - } } diff --git a/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl b/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl index 59c2fcaad..3cc52a273 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl @@ -21,7 +21,11 @@ <#if overridden>@Override <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) <@throws/> { if ( ${sourceParameter.name} == null ) { + <#if !mapNullToDefault> return<#if returnType.name != "void"> null; + <#else> + return Collections.<${resultType.typeParameters[0].name}, ${resultType.typeParameters[1].name}>emptyMap(); + } <#if existingInstanceMapping> diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapper.java index b4b3f9b79..3bf1b709e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapper.java @@ -19,6 +19,7 @@ package org.mapstruct.ap.test.mapnulltodefault; import java.util.List; +import java.util.Map; import java.util.UUID; import org.mapstruct.Mapper; @@ -54,4 +55,7 @@ public interface CarMapper { @MapNullToDefault List carsToCarDtos(List cars); + + @MapNullToDefault + Map carsToCarDtoMap(Map cars); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapperTest.java index 58a080bf8..40199ebe3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapnulltodefault/CarMapperTest.java @@ -19,7 +19,9 @@ package org.mapstruct.ap.test.mapnulltodefault; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.fest.assertions.Assertions.assertThat; @@ -115,4 +117,28 @@ public class CarMapperTest { assertThat( carDtos2.isEmpty() ).isTrue(); } + + @Test + public void shouldMapMapWithNullArg() { + + //given + Car car = new Car( "Morris", 2 ); + Map carMap = new HashMap(); + carMap.put( 1, car); + + //when + Map carDtoMap1 = CarMapper.INSTANCE.carsToCarDtoMap( carMap ); + + //then + assertThat( carDtoMap1 ).isNotNull(); + assertThat( carDtoMap1.size() ).isEqualTo( 1 ); + + //when + Map carDtoMap2 = CarMapper.INSTANCE.carsToCarDtoMap( null ); + + //then + assertThat( carDtoMap2 ).isNotNull(); + assertThat( carDtoMap2.isEmpty() ).isTrue(); + + } }