#474 remove @NullValueMapping in favour of @Bean/@Map/@IterableMapping

This commit is contained in:
sjaakd 2015-02-25 21:57:52 +01:00
parent ea73669096
commit 1827d1125a
20 changed files with 134 additions and 100 deletions

View File

@ -27,7 +27,8 @@ import java.lang.annotation.Target;
/**
* Configures the mapping between two bean types.
* <p>
* Either {@link #resultType()} or {@link #qualifiedBy()} must be specified.
* Either {@link #resultType()} , {@link #qualifiedBy()} or {@link #qualifiedBy()}must be specified.
* </p>
*
* @author Sjaak Derksen
*/
@ -43,13 +44,22 @@ public @interface BeanMapping {
Class<?> resultType() default void.class;
/**
* A qualifier can be specified to aid the selection process of a suitable factory method. This is useful in
* case multiple factory method (hand written of internal) qualify and result in an 'Ambiguous factory methods'
* error.
* A qualifier can be specified to aid the selection process of a suitable factory method. This is useful in case
* multiple factory method (hand written of internal) qualify and result in an 'Ambiguous factory methods' error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] qualifiedBy() default { };
/**
* The strategy to be applied when {@code null} is passed as source value to this bean mapping. If no
* strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or
* {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL}
* by default.
*
* @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping.
*/
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.DEFAULT;
}

View File

@ -63,4 +63,15 @@ public @interface IterableMapping {
* @return the elementTargetType to select
*/
Class<?> elementTargetType() default void.class;
/**
* The strategy to be applied when {@code null} is passed as source value to this iterable mapping. If no
* strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or
* {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL}
* by default.
*
* @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping.
*/
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.DEFAULT;
}

View File

@ -93,4 +93,15 @@ public @interface MapMapping {
* @return the resultType to select
*/
Class<?> valueTargetType() default void.class;
/**
* The strategy to be applied when {@code null} is passed as source value to this map mapping. If no
* strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or
* {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL}
* by default.
*
* @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping.
*/
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.DEFAULT;
}

View File

@ -1,44 +0,0 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies how the annotated method should deal with {@code null} values.
* <p>
* If no strategy is configured explicitly for a given method, the configuration from the enclosing mapper will be
* applied, using {@link NullValueMappingStrategy#RETURN_NULL} by default.
*
* @author Sjaak Derksen
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.SOURCE)
public @interface NullValueMapping {
/**
* The strategy for mapping null values.
*
* @return The strategy for mapping null values
*/
NullValueMappingStrategy value();
}

View File

@ -43,7 +43,6 @@ import org.mapstruct.ap.model.source.SourceReference;
import org.mapstruct.ap.option.ReportingPolicy;
import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.util.Executables;
import org.mapstruct.ap.util.MapperConfiguration;
import org.mapstruct.ap.util.Message;
@ -54,7 +53,6 @@ import org.mapstruct.ap.util.Strings;
* configured by one or more {@link PropertyMapping}s.
*
* @author Gunnar Morling
* @author Sjaak Derksen
*/
public class BeanMappingMethod extends MappingMethod {
@ -106,16 +104,15 @@ public class BeanMappingMethod extends MappingMethod {
reportErrorForUnmappedTargetPropertiesIfRequired();
// mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() );
BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault =
MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( beanMappingPrism );
MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() );
// if there's no factory method, try the resultType in the @BeanMapping
Type resultType = null;
if ( factoryMethod == null ) {
BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() );
BeanMapping beanMapping
= BeanMapping.fromPrism( beanMappingPrism, method.getExecutable(), ctx.getMessager() );
if ( beanMapping != null && beanMapping.getResultType() != null ) {

View File

@ -30,7 +30,7 @@ import org.mapstruct.ap.model.assignment.SetterWrapper;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.prism.IterableMappingPrism;
import org.mapstruct.ap.util.MapperConfiguration;
import org.mapstruct.ap.util.Message;
import org.mapstruct.ap.util.Strings;
@ -125,7 +125,7 @@ public class IterableMappingMethod extends MappingMethod {
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
}
// mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() );
IterableMappingPrism prism = IterableMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault
= MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );

View File

@ -28,7 +28,7 @@ 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.source.Method;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.prism.MapMappingPrism;
import org.mapstruct.ap.util.MapperConfiguration;
import org.mapstruct.ap.util.Message;
import org.mapstruct.ap.util.Strings;
@ -146,7 +146,7 @@ public class MapMappingMethod extends MappingMethod {
}
// mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() );
MapMappingPrism prism = MapMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault =
MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );

View File

@ -24,6 +24,7 @@ import javax.lang.model.element.ExecutableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message;
@ -44,7 +45,9 @@ public class BeanMapping {
}
boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() );
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() ) {
boolean nullValueMappingIsDefault =
beanMapping.nullValueMappingStrategy().equals( NullValueMappingStrategyPrism.DEFAULT.toString() );
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() && nullValueMappingIsDefault ) {
messager.printMessage( method, Message.BEANMAPPING_NO_ELEMENTS );
}

View File

@ -27,6 +27,7 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.IterableMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message;
/**
@ -49,9 +50,12 @@ public class IterableMapping {
}
boolean elementTargetTypeIsDefined = !TypeKind.VOID.equals( iterableMapping.elementTargetType().getKind() );
boolean nullValueMappingIsDefault =
iterableMapping.nullValueMappingStrategy().equals( NullValueMappingStrategyPrism.DEFAULT.toString() );
if ( !elementTargetTypeIsDefined
&& iterableMapping.dateFormat().isEmpty()
&& iterableMapping.qualifiedBy().isEmpty() ) {
&& iterableMapping.qualifiedBy().isEmpty()
&& nullValueMappingIsDefault) {
messager.printMessage( method, Message.ITERABLEMAPPING_NO_ELEMENTS );
}

View File

@ -26,6 +26,7 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.MapMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message;
/**
@ -48,7 +49,8 @@ public class MapMapping {
if ( mapMapping == null ) {
return null;
}
boolean nullValueMappingIsDefault =
mapMapping.nullValueMappingStrategy().equals( NullValueMappingStrategyPrism.DEFAULT.toString() );
boolean keyTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.keyTargetType().getKind() );
boolean valueTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.valueTargetType().getKind() );
if ( mapMapping.keyDateFormat().isEmpty()
@ -56,7 +58,8 @@ public class MapMapping {
&& mapMapping.valueDateFormat().isEmpty()
&& mapMapping.valueQualifiedBy().isEmpty()
&& !keyTargetTypeIsDefined
&& !valueTargetTypeIsDefined ) {
&& !valueTargetTypeIsDefined
&& nullValueMappingIsDefault ) {
messager.printMessage( method, Message.MAPMAPPING_NO_ELEMENTS );
}

View File

@ -33,7 +33,6 @@ import org.mapstruct.MapperConfig;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.NullValueMapping;
import org.mapstruct.Qualifier;
import org.mapstruct.TargetType;
@ -56,7 +55,6 @@ import org.mapstruct.TargetType;
@GeneratePrism(value = InheritConfiguration.class, publicAccess = true),
@GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true),
@GeneratePrism(value = Qualifier.class, publicAccess = true),
@GeneratePrism(value = NullValueMapping.class, publicAccess = true),
// external types
@GeneratePrism(value = XmlElementDecl.class, publicAccess = true)

View File

@ -30,11 +30,13 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.option.ReportingPolicy;
import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
import org.mapstruct.ap.prism.IterableMappingPrism;
import org.mapstruct.ap.prism.MapMappingPrism;
import org.mapstruct.ap.prism.MapperConfigPrism;
import org.mapstruct.ap.prism.MapperPrism;
import org.mapstruct.ap.prism.MappingInheritanceStrategyPrism;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
/**
@ -132,17 +134,52 @@ public class MapperConfiguration {
return MappingInheritanceStrategyPrism.EXPLICIT;
}
public boolean isMapToDefault(NullValueMappingPrism mapNullToDefault) {
public boolean isMapToDefault(BeanMappingPrism mapNullToDefault) {
// check on method level
if ( mapNullToDefault != null ) {
NullValueMappingStrategyPrism methodPolicy
= NullValueMappingStrategyPrism.valueOf( mapNullToDefault.value() );
= NullValueMappingStrategyPrism.valueOf( mapNullToDefault.nullValueMappingStrategy() );
if ( methodPolicy != NullValueMappingStrategyPrism.DEFAULT ) {
return methodPolicy == NullValueMappingStrategyPrism.RETURN_DEFAULT;
}
}
return isMapToDefaultOnMapperAndMappingConfigLevel();
}
public boolean isMapToDefault(MapMappingPrism mapNullToDefault) {
// check on method level
if ( mapNullToDefault != null ) {
NullValueMappingStrategyPrism methodPolicy
= NullValueMappingStrategyPrism.valueOf( mapNullToDefault.nullValueMappingStrategy() );
if ( methodPolicy != NullValueMappingStrategyPrism.DEFAULT ) {
return methodPolicy == NullValueMappingStrategyPrism.RETURN_DEFAULT;
}
}
return isMapToDefaultOnMapperAndMappingConfigLevel();
}
public boolean isMapToDefault(IterableMappingPrism mapNullToDefault) {
// check on method level
if ( mapNullToDefault != null ) {
NullValueMappingStrategyPrism methodPolicy
= NullValueMappingStrategyPrism.valueOf( mapNullToDefault.nullValueMappingStrategy() );
if ( methodPolicy != NullValueMappingStrategyPrism.DEFAULT ) {
return methodPolicy == NullValueMappingStrategyPrism.RETURN_DEFAULT;
}
}
return isMapToDefaultOnMapperAndMappingConfigLevel();
}
private boolean isMapToDefaultOnMapperAndMappingConfigLevel() {
// check on mapper level
NullValueMappingStrategyPrism mapperPolicy =
NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() );

View File

@ -28,7 +28,7 @@ import javax.tools.Diagnostic;
public enum Message {
// CHECKSTYLE:OFF
BEANMAPPING_NO_ELEMENTS( "'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ),
BEANMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ),
BEANMAPPING_NOT_ASSIGNABLE( "%s not assignable to: %s." ),
BEANMAPPING_UNKNOWN_PROPERTY_IN_RETURNTYPE( "Unknown property \"%s\" in return type." ),
BEANMAPPING_SEVERAL_POSSIBLE_SOURCES( "Several possible source properties for target property \"%s\"." ),
@ -52,10 +52,10 @@ public enum Message {
MAPMAPPING_KEY_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source key type to target key type." ),
MAPMAPPING_VALUE_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source value type to target value type." ),
MAPMAPPING_NO_ELEMENTS( "'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, define at least one of them." ),
MAPMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, define at least one of them." ),
ITERABLEMAPPING_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source element type into target element type." ),
ITERABLEMAPPING_NO_ELEMENTS( "'dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in @IterableMapping, define at least one of them." ),
ITERABLEMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in @IterableMapping, define at least one of them." ),
ENUMMAPPING_MULTIPLE_TARGETS( "One enum constant must not be mapped to more than one target constant, but constant %s is mapped to %s." ),
ENUMMAPPING_UNDEFINED_SOURCE( "A source constant must be specified for mappings of an enum mapping method." ),

View File

@ -19,10 +19,10 @@
package org.mapstruct.ap.test.array;
import java.util.List;
import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.ap.test.array._target.ScientistDto;
import org.mapstruct.ap.test.array.source.Scientist;
@ -43,33 +43,33 @@ public interface ScienceMapper {
ScientistDto[] scientistsToDtos(Scientist[] scientists, @MappingTarget ScientistDto[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
boolean[] nvmMapping(boolean[] source, @MappingTarget boolean[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
short[] nvmMapping(int[] source, @MappingTarget short[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
char[] nvmMapping(String[] source, @MappingTarget char[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
int[] nvmMapping(int[] source, @MappingTarget int[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
long[] nvmMapping(int[] source, @MappingTarget long[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
float[] nvmMapping(int[] source, @MappingTarget float[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
double[] nvmMapping(int[] source, @MappingTarget double[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
String[] nvmMapping(int[] source, @MappingTarget String[] target);
void nvmMappingVoidReturnNull(int[] source, @MappingTarget long[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
@IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
void nvmMappingVoidReturnDefault(int[] source, @MappingTarget long[] target);

View File

@ -20,10 +20,10 @@ package org.mapstruct.ap.test.bugs._374;
import java.util.List;
import java.util.Map;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.factory.Mappers;
@ -39,7 +39,7 @@ public interface Issue374Mapper {
@Mapping(target = "constant", constant = "test")
Target map(Source source, @MappingTarget Target target);
@NullValueMapping( NullValueMappingStrategy.RETURN_NULL )
@BeanMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL )
@Mapping(target = "constant", constant = "test")
Target map2(Source source, @MappingTarget Target target);

View File

@ -65,8 +65,8 @@ public class ErroneousCollectionMappingTest {
@Diagnostic(type = EmptyItererableMappingMapper.class,
kind = Kind.ERROR,
line = 35,
messageRegExp = "'dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in "
+ "@IterableMapping, define at least one of them.")
messageRegExp = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are "
+ "undefined in @IterableMapping, define at least one of them.")
}
)
public void shouldFailOnEmptyIterableAnnotation() {
@ -81,9 +81,9 @@ public class ErroneousCollectionMappingTest {
@Diagnostic(type = EmptyMapMappingMapper.class,
kind = Kind.ERROR,
line = 34,
messageRegExp = "'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', "
+ "'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, define at least "
+ "one of them.")
messageRegExp = "'nullValueMappingStrategy', 'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', "
+ "'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, "
+ "define at least one of them.")
}
)
public void shouldFailOnEmptyMapAnnotation() {

View File

@ -21,11 +21,13 @@ package org.mapstruct.ap.test.nullvaluemapping;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.mapstruct.BeanMapping;
import org.mapstruct.IterableMapping;
import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.NullValueMapping;
import org.mapstruct.ap.test.nullvaluemapping._target.CarDto;
import org.mapstruct.ap.test.nullvaluemapping._target.DriverAndCarDto;
import org.mapstruct.ap.test.nullvaluemapping.source.Car;
@ -39,7 +41,7 @@ public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@NullValueMapping(RETURN_DEFAULT)
@BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT)
@Mappings({
@Mapping(target = "seatCount", source = "numberOfSeats"),
@Mapping(target = "model", constant = "ModelT"),
@ -47,7 +49,7 @@ public interface CarMapper {
})
CarDto carToCarDto(Car car);
@NullValueMapping(RETURN_DEFAULT)
@BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT)
@Mappings({
@Mapping(target = "seatCount", source = "car.numberOfSeats"),
@Mapping(target = "model", source = "model"), // TODO, should not be needed, must be made based on name only
@ -56,13 +58,13 @@ public interface CarMapper {
CarDto carToCarDto(Car car, String model);
@NullValueMapping(RETURN_DEFAULT)
@IterableMapping(nullValueMappingStrategy = RETURN_DEFAULT)
List<CarDto> carsToCarDtos(List<Car> cars);
@NullValueMapping(RETURN_DEFAULT)
@MapMapping(nullValueMappingStrategy = RETURN_DEFAULT)
Map<Integer, CarDto> carsToCarDtoMap(Map<Integer, Car> cars);
@NullValueMapping(RETURN_DEFAULT)
@BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT)
DriverAndCarDto driverAndCarToDto(Driver driver, Car car);
DriverAndCarDto driverAndCarToDtoReturningNull(Driver driver, Car car);

View File

@ -21,11 +21,12 @@ package org.mapstruct.ap.test.nullvaluemapping;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.mapstruct.IterableMapping;
import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.ap.test.nullvaluemapping._target.CarDto;
import org.mapstruct.ap.test.nullvaluemapping.source.Car;
@ -44,10 +45,10 @@ public interface CarMapperSettingOnConfig {
CarDto carToCarDto(Car car);
@NullValueMapping(NullValueMappingStrategy.DEFAULT)
@IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.DEFAULT, dateFormat = "dummy")
List<CarDto> carsToCarDtos(List<Car> cars);
@NullValueMapping(NullValueMappingStrategy.RETURN_NULL)
@MapMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
Map<Integer, CarDto> carsToCarDtoMap(Map<Integer, Car> cars);
}

View File

@ -21,11 +21,12 @@ package org.mapstruct.ap.test.nullvaluemapping;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.mapstruct.IterableMapping;
import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.ap.test.nullvaluemapping._target.CarDto;
import org.mapstruct.ap.test.nullvaluemapping.source.Car;
@ -44,10 +45,10 @@ public interface CarMapperSettingOnMapper {
CarDto carToCarDto(Car car);
@NullValueMapping(NullValueMappingStrategy.RETURN_DEFAULT)
@IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
List<CarDto> carsToCarDtos(List<Car> cars);
@NullValueMapping(NullValueMappingStrategy.RETURN_NULL)
@MapMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
Map<Integer, CarDto> carsToCarDtoMap(Map<Integer, Car> cars);
}

View File

@ -186,8 +186,8 @@ public class QualifierTest {
@Diagnostic( type = ErroneousMovieFactoryMapper.class,
kind = Kind.ERROR,
line = 37,
messageRegExp = "'resultType' and 'qualifiedBy' are undefined in @BeanMapping, "
+ "define at least one of them." )
messageRegExp = "'nullValueMappingStrategy', 'resultType' and 'qualifiedBy' are undefined in "
+ "@BeanMapping, define at least one of them." )
}
)
public void testEmptyBeanMapping() {