#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. * Configures the mapping between two bean types.
* <p> * <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 * @author Sjaak Derksen
*/ */
@ -43,13 +44,22 @@ public @interface BeanMapping {
Class<?> resultType() default void.class; Class<?> resultType() default void.class;
/** /**
* A qualifier can be specified to aid the selection process of a suitable factory method. This is useful in * A qualifier can be specified to aid the selection process of a suitable factory method. This is useful in case
* case multiple factory method (hand written of internal) qualify and result in an 'Ambiguous factory methods' * multiple factory method (hand written of internal) qualify and result in an 'Ambiguous factory methods' error.
* error.
* *
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
* *
* @return the qualifiers * @return the qualifiers
*/ */
Class<? extends Annotation>[] qualifiedBy() default { }; 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 * @return the elementTargetType to select
*/ */
Class<?> elementTargetType() default void.class; 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 * @return the resultType to select
*/ */
Class<?> valueTargetType() default void.class; 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.option.ReportingPolicy;
import org.mapstruct.ap.prism.BeanMappingPrism; import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism; import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.util.Executables; import org.mapstruct.ap.util.Executables;
import org.mapstruct.ap.util.MapperConfiguration; import org.mapstruct.ap.util.MapperConfiguration;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
@ -54,7 +53,6 @@ import org.mapstruct.ap.util.Strings;
* configured by one or more {@link PropertyMapping}s. * configured by one or more {@link PropertyMapping}s.
* *
* @author Gunnar Morling * @author Gunnar Morling
* @author Sjaak Derksen
*/ */
public class BeanMappingMethod extends MappingMethod { public class BeanMappingMethod extends MappingMethod {
@ -106,16 +104,15 @@ public class BeanMappingMethod extends MappingMethod {
reportErrorForUnmappedTargetPropertiesIfRequired(); reportErrorForUnmappedTargetPropertiesIfRequired();
// mapNullToDefault // mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() ); BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault = boolean mapNullToDefault =
MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism ); MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( beanMappingPrism );
MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() ); MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() );
// if there's no factory method, try the resultType in the @BeanMapping // if there's no factory method, try the resultType in the @BeanMapping
Type resultType = null; Type resultType = null;
if ( factoryMethod == null ) { if ( factoryMethod == null ) {
BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() );
BeanMapping beanMapping BeanMapping beanMapping
= BeanMapping.fromPrism( beanMappingPrism, method.getExecutable(), ctx.getMessager() ); = BeanMapping.fromPrism( beanMappingPrism, method.getExecutable(), ctx.getMessager() );
if ( beanMapping != null && beanMapping.getResultType() != null ) { 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.Parameter;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method; 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.MapperConfiguration;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
import org.mapstruct.ap.util.Strings; import org.mapstruct.ap.util.Strings;
@ -125,7 +125,7 @@ public class IterableMappingMethod extends MappingMethod {
assignment = new SetterWrapper( assignment, method.getThrownTypes() ); assignment = new SetterWrapper( assignment, method.getThrownTypes() );
} }
// mapNullToDefault // mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() ); IterableMappingPrism prism = IterableMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault boolean mapNullToDefault
= MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism ); = 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.Parameter;
import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method; 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.MapperConfiguration;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
import org.mapstruct.ap.util.Strings; import org.mapstruct.ap.util.Strings;
@ -146,7 +146,7 @@ public class MapMappingMethod extends MappingMethod {
} }
// mapNullToDefault // mapNullToDefault
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() ); MapMappingPrism prism = MapMappingPrism.getInstanceOn( method.getExecutable() );
boolean mapNullToDefault = boolean mapNullToDefault =
MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism ); 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.TypeKind;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.BeanMappingPrism; import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
@ -44,7 +45,9 @@ public class BeanMapping {
} }
boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() ); 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 ); 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 javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.IterableMappingPrism; import org.mapstruct.ap.prism.IterableMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
/** /**
@ -49,9 +50,12 @@ public class IterableMapping {
} }
boolean elementTargetTypeIsDefined = !TypeKind.VOID.equals( iterableMapping.elementTargetType().getKind() ); boolean elementTargetTypeIsDefined = !TypeKind.VOID.equals( iterableMapping.elementTargetType().getKind() );
boolean nullValueMappingIsDefault =
iterableMapping.nullValueMappingStrategy().equals( NullValueMappingStrategyPrism.DEFAULT.toString() );
if ( !elementTargetTypeIsDefined if ( !elementTargetTypeIsDefined
&& iterableMapping.dateFormat().isEmpty() && iterableMapping.dateFormat().isEmpty()
&& iterableMapping.qualifiedBy().isEmpty() ) { && iterableMapping.qualifiedBy().isEmpty()
&& nullValueMappingIsDefault) {
messager.printMessage( method, Message.ITERABLEMAPPING_NO_ELEMENTS ); 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 javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.MapMappingPrism; import org.mapstruct.ap.prism.MapMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
import org.mapstruct.ap.util.Message; import org.mapstruct.ap.util.Message;
/** /**
@ -48,7 +49,8 @@ public class MapMapping {
if ( mapMapping == null ) { if ( mapMapping == null ) {
return null; return null;
} }
boolean nullValueMappingIsDefault =
mapMapping.nullValueMappingStrategy().equals( NullValueMappingStrategyPrism.DEFAULT.toString() );
boolean keyTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.keyTargetType().getKind() ); boolean keyTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.keyTargetType().getKind() );
boolean valueTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.valueTargetType().getKind() ); boolean valueTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.valueTargetType().getKind() );
if ( mapMapping.keyDateFormat().isEmpty() if ( mapMapping.keyDateFormat().isEmpty()
@ -56,7 +58,8 @@ public class MapMapping {
&& mapMapping.valueDateFormat().isEmpty() && mapMapping.valueDateFormat().isEmpty()
&& mapMapping.valueQualifiedBy().isEmpty() && mapMapping.valueQualifiedBy().isEmpty()
&& !keyTargetTypeIsDefined && !keyTargetTypeIsDefined
&& !valueTargetTypeIsDefined ) { && !valueTargetTypeIsDefined
&& nullValueMappingIsDefault ) {
messager.printMessage( method, Message.MAPMAPPING_NO_ELEMENTS ); messager.printMessage( method, Message.MAPMAPPING_NO_ELEMENTS );
} }

View File

@ -33,7 +33,6 @@ import org.mapstruct.MapperConfig;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings; import org.mapstruct.Mappings;
import org.mapstruct.NullValueMapping;
import org.mapstruct.Qualifier; import org.mapstruct.Qualifier;
import org.mapstruct.TargetType; import org.mapstruct.TargetType;
@ -56,7 +55,6 @@ import org.mapstruct.TargetType;
@GeneratePrism(value = InheritConfiguration.class, publicAccess = true), @GeneratePrism(value = InheritConfiguration.class, publicAccess = true),
@GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true), @GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true),
@GeneratePrism(value = Qualifier.class, publicAccess = true), @GeneratePrism(value = Qualifier.class, publicAccess = true),
@GeneratePrism(value = NullValueMapping.class, publicAccess = true),
// external types // external types
@GeneratePrism(value = XmlElementDecl.class, publicAccess = true) @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 javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.option.ReportingPolicy; import org.mapstruct.ap.option.ReportingPolicy;
import org.mapstruct.ap.prism.BeanMappingPrism;
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism; 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.MapperConfigPrism;
import org.mapstruct.ap.prism.MapperPrism; import org.mapstruct.ap.prism.MapperPrism;
import org.mapstruct.ap.prism.MappingInheritanceStrategyPrism; import org.mapstruct.ap.prism.MappingInheritanceStrategyPrism;
import org.mapstruct.ap.prism.NullValueMappingPrism;
import org.mapstruct.ap.prism.NullValueMappingStrategyPrism; import org.mapstruct.ap.prism.NullValueMappingStrategyPrism;
/** /**
@ -132,17 +134,52 @@ public class MapperConfiguration {
return MappingInheritanceStrategyPrism.EXPLICIT; return MappingInheritanceStrategyPrism.EXPLICIT;
} }
public boolean isMapToDefault(NullValueMappingPrism mapNullToDefault) { public boolean isMapToDefault(BeanMappingPrism mapNullToDefault) {
// check on method level // check on method level
if ( mapNullToDefault != null ) { if ( mapNullToDefault != null ) {
NullValueMappingStrategyPrism methodPolicy NullValueMappingStrategyPrism methodPolicy
= NullValueMappingStrategyPrism.valueOf( mapNullToDefault.value() ); = NullValueMappingStrategyPrism.valueOf( mapNullToDefault.nullValueMappingStrategy() );
if ( methodPolicy != NullValueMappingStrategyPrism.DEFAULT ) { if ( methodPolicy != NullValueMappingStrategyPrism.DEFAULT ) {
return methodPolicy == NullValueMappingStrategyPrism.RETURN_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 // check on mapper level
NullValueMappingStrategyPrism mapperPolicy = NullValueMappingStrategyPrism mapperPolicy =
NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() ); NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() );

View File

@ -28,7 +28,7 @@ import javax.tools.Diagnostic;
public enum Message { public enum Message {
// CHECKSTYLE:OFF // 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_NOT_ASSIGNABLE( "%s not assignable to: %s." ),
BEANMAPPING_UNKNOWN_PROPERTY_IN_RETURNTYPE( "Unknown property \"%s\" in return type." ), BEANMAPPING_UNKNOWN_PROPERTY_IN_RETURNTYPE( "Unknown property \"%s\" in return type." ),
BEANMAPPING_SEVERAL_POSSIBLE_SOURCES( "Several possible source properties for target property \"%s\"." ), 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_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_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_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_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." ), 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; package org.mapstruct.ap.test.array;
import java.util.List; import java.util.List;
import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.ap.test.array._target.ScientistDto; import org.mapstruct.ap.test.array._target.ScientistDto;
import org.mapstruct.ap.test.array.source.Scientist; import org.mapstruct.ap.test.array.source.Scientist;
@ -43,33 +43,33 @@ public interface ScienceMapper {
ScientistDto[] scientistsToDtos(Scientist[] scientists, @MappingTarget ScientistDto[] target); ScientistDto[] scientistsToDtos(Scientist[] scientists, @MappingTarget ScientistDto[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
boolean[] nvmMapping(boolean[] source, @MappingTarget boolean[] target); boolean[] nvmMapping(boolean[] source, @MappingTarget boolean[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
short[] nvmMapping(int[] source, @MappingTarget short[] target); short[] nvmMapping(int[] source, @MappingTarget short[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
char[] nvmMapping(String[] source, @MappingTarget char[] target); char[] nvmMapping(String[] source, @MappingTarget char[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
int[] nvmMapping(int[] source, @MappingTarget int[] target); int[] nvmMapping(int[] source, @MappingTarget int[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
long[] nvmMapping(int[] source, @MappingTarget long[] target); long[] nvmMapping(int[] source, @MappingTarget long[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
float[] nvmMapping(int[] source, @MappingTarget float[] target); float[] nvmMapping(int[] source, @MappingTarget float[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
double[] nvmMapping(int[] source, @MappingTarget double[] target); double[] nvmMapping(int[] source, @MappingTarget double[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
String[] nvmMapping(int[] source, @MappingTarget String[] target); String[] nvmMapping(int[] source, @MappingTarget String[] target);
void nvmMappingVoidReturnNull(int[] source, @MappingTarget long[] target); void nvmMappingVoidReturnNull(int[] source, @MappingTarget long[] target);
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT ) @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT )
void nvmMappingVoidReturnDefault(int[] source, @MappingTarget long[] target); 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.List;
import java.util.Map; import java.util.Map;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueMapping;
import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
@ -39,7 +39,7 @@ public interface Issue374Mapper {
@Mapping(target = "constant", constant = "test") @Mapping(target = "constant", constant = "test")
Target map(Source source, @MappingTarget Target target); Target map(Source source, @MappingTarget Target target);
@NullValueMapping( NullValueMappingStrategy.RETURN_NULL ) @BeanMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL )
@Mapping(target = "constant", constant = "test") @Mapping(target = "constant", constant = "test")
Target map2(Source source, @MappingTarget Target target); Target map2(Source source, @MappingTarget Target target);

View File

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

View File

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

View File

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