From 57caee250f0e4ee0ac50083d7e993a3c011eb3be Mon Sep 17 00:00:00 2001 From: Sjaak Derksen Date: Sun, 27 Jan 2019 21:09:44 +0100 Subject: [PATCH] #1685 completing nullvaluepropertymappingstrategy (#1697) --- .../org/mapstruct/NullValueCheckStrategy.java | 5 + .../NullValuePropertyMappingStrategy.java | 10 +- .../mapstruct-reference-guide.asciidoc | 17 +- .../model/CollectionAssignmentBuilder.java | 6 +- .../ap/internal/model/PropertyMapping.java | 50 +++- .../model/assignment/ArrayCopyWrapper.java | 16 +- .../model/assignment/SetterWrapper.java | 62 +++-- .../model/assignment/UpdateWrapper.java | 23 +- .../model/assignment/UpdateWrapper.ftl | 4 +- .../ap/internal/model/macro/CommonMacros.ftl | 14 +- .../ap/test/bugs/_1685/ContactDataDTO.java | 56 ++++ .../ap/test/bugs/_1685/Issue1685Test.java | 117 +++++++++ .../mapstruct/ap/test/bugs/_1685/User.java | 68 +++++ .../mapstruct/ap/test/bugs/_1685/UserDTO.java | 27 ++ .../ap/test/bugs/_1685/UserMapper.java | 44 ++++ .../NestedSimpleBeansMappingTest.java | 2 +- .../ChartEntryToArtistUpdate.java | 6 +- .../CustomerDefaultMapper.java | 2 +- .../ap/test/bugs/_1685/UserMapperImpl.java | 241 ++++++++++++++++++ .../UserDtoUpdateMapperSmartImpl.java | 12 + .../nestedbeans/mixed/FishTankMapperImpl.java | 20 +- .../ArtistToChartEntryImpl.java | 30 +-- .../ChartEntryToArtistImpl.java | 25 +- 23 files changed, 739 insertions(+), 118 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java create mode 100644 processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java diff --git a/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java b/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java index 8d5b53c00..446b879d9 100644 --- a/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java +++ b/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java @@ -10,6 +10,11 @@ package org.mapstruct; * * Note: This strategy is not in effect when the a specific source presence check method is defined * in the service provider interface (SPI). + *

+ * Note: some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder + * as target accessor see {@link CollectionMappingStrategy}, MapStruct will always generate a source property null + * check, regardless the value of the {@link NullValueCheckStrategy} to avoid addition of {@code null} to the target + * collection or map. * * @author Sean Huang */ diff --git a/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java index c9182938f..6db84814c 100644 --- a/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java +++ b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java @@ -12,9 +12,15 @@ package org.mapstruct; * Precedence is arranged in the reverse order. So {@link Mapping} will override {@link BeanMapping}, will * overide {@link Mapper} * - * The enum only applies to update method: methods that update a pre-existing target (annotated with + * The enum only applies to update methods: methods that update a pre-existing target (annotated with * {@code @}{@link MappingTarget}). * + *

+ * Note: some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder + * as target accessor see {@link CollectionMappingStrategy}, MapStruct will always generate a source property + * null check, regardless the value of the {@link NullValuePropertyMappingStrategy} to avoid addition of {@code null} + * to the target collection or map. Since the target is assumed to be initialised this strategy will not be applied. + * * @author Sjaak Derksen * @since 1.3 */ @@ -27,6 +33,8 @@ public enum NullValuePropertyMappingStrategy { /** * If a source bean property equals {@code null} the target bean property will be set to its default value. + * Make sure that a {@link Mapping#defaultValue()} is defined if no empty constructor is available on + * the default value. */ SET_TO_DEFAULT, diff --git a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc index 782e47a31..3c1ea5649 100644 --- a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc +++ b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc @@ -2138,12 +2138,22 @@ MapStruct offers control over the property to set in an `@MappingTarget` annotat By default the source property will be set to null. However: -1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result can be altered to return *default* values (`Object`, `ArrayList`, `HashMap`). +1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result can be altered to return *default* values. Please note that a default constructor is required. If not available, use the `@Mapping#defaultValue`. For `List` MapStruct generates an `ArrayList`, for `Map` mapstruct generates a `HashMap`. 2. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MappingConfig`, the mapping result will be equal to the original value of the `@MappingTarget` annotated target. The strategy works in a hierarchical fashion. Setting `Mapping#nullValuePropertyMappingStrategy` on mapping level will override `nullValuePropertyMappingStrategy` on mapping method level will override `@Mapper#nullValuePropertyMappingStrategy`, and `@Mapper#nullValuePropertyMappingStrategy` will override `@MappingConfig#nullValuePropertyMappingStrategy`. +[NOTE] +==== +Some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder as target accessor see `CollectionMappingStrategy`, MapStruct will always generate a source property +null check, regardless the value of the `NullValuePropertyMappingStrategy` to avoid addition of `null` to the target collection or map. Since the target is assumed to be initialised this strategy will not be applied. +==== + +[TIP] +==== +`NullValuePropertyMappingStrategy` also applies when the presense checker returns `not present`. +==== [[checking-source-property-for-null-arguments]] === Controlling checking result for 'null' properties in bean mapping @@ -2171,6 +2181,11 @@ Some frameworks generate bean properties that have a source presence checker. Of The source presence checker name can be changed in the MapStruct service provider interface (SPI). It can also be deactivated in this way. ==== +[NOTE] +==== +Some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder as target accessor see `CollectionMappingStrategy`, MapStruct will always generate a source property +null check, regardless the value of the `NullValueheckStrategy` to avoid addition of `null` to the target collection or map. +==== [[exceptions]] === Exceptions diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java index dcef911e8..ad9defb9d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java @@ -21,6 +21,9 @@ import org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.accessor.Accessor; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_DEFAULT; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_NULL; + /** * A builder that is used for creating an assignment to a collection. * @@ -149,7 +152,8 @@ public class CollectionAssignmentBuilder { PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ), targetType, true, - nvpms + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT ); } else if ( method.isUpdateMethod() && !targetImmutable ) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java index 478cd76ae..e44c4d9a3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java @@ -49,7 +49,8 @@ import org.mapstruct.ap.internal.util.ValueProvider; import org.mapstruct.ap.internal.util.accessor.Accessor; import static org.mapstruct.ap.internal.model.common.Assignment.AssignmentType.DIRECT; -import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_DEFAULT; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_NULL; import static org.mapstruct.ap.internal.util.Collections.first; import static org.mapstruct.ap.internal.util.Collections.last; @@ -285,10 +286,12 @@ public class PropertyMapping extends ModelElement { // null value mapping strategy this.nvms = mapperConfiguration.getNullValueMappingStrategy(); - // null value property mapping strategy (determine true value based on hierarchy) - NullValuePropertyMappingStrategyPrism nvpmsBean = - beanMapping != null ? beanMapping.getNullValuePropertyMappingStrategy() : null; - this.nvpms = mapperConfiguration.getNullValuePropertyMappingStrategy( nvpmsBean, nvpms ); + // for update methods: determine null value property mapping strategy (determine value based on hierarchy) + if ( method.isUpdateMethod() ) { + NullValuePropertyMappingStrategyPrism nvpmsBean = + beanMapping != null ? beanMapping.getNullValuePropertyMappingStrategy() : null; + this.nvpms = mapperConfiguration.getNullValuePropertyMappingStrategy( nvpmsBean, nvpms ); + } // handle source this.rightHandSide = getSourceRHS( sourceReference ); @@ -463,14 +466,28 @@ public class PropertyMapping extends ModelElement { return new UpdateWrapper( rhs, method.getThrownTypes(), - factory, isFieldAssignment(), + factory, + isFieldAssignment(), targetType, !rhs.isSourceReferenceParameter(), - nvpms + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT ); } else { - return new SetterWrapper( rhs, method.getThrownTypes(), nvcs, isFieldAssignment(), targetType ); + boolean includeSourceNullCheck = SetterWrapper.doSourceNullCheck( rhs, nvcs, nvpms, targetType ); + if ( !includeSourceNullCheck ) { + // solution for #834 introduced a local var and null check for nested properties always. + // however, a local var is not needed if there's no need to check for null. + rhs.setSourceLocalVarName( null ); + } + return new SetterWrapper( + rhs, + method.getThrownTypes(), + isFieldAssignment(), + includeSourceNullCheck, + includeSourceNullCheck && nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT ); } } @@ -488,7 +505,14 @@ public class PropertyMapping extends ModelElement { } else { // Possibly adding null to a target collection. So should be surrounded by an null check. - result = new SetterWrapper( result, method.getThrownTypes(), ALWAYS, isFieldAssignment(), targetType ); + // TODO: what triggers this else branch? Should nvcs, nvpms be applied? + result = new SetterWrapper( result, + method.getThrownTypes(), + isFieldAssignment(), + true, + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT + ); } return result; } @@ -517,8 +541,9 @@ public class PropertyMapping extends ModelElement { targetPropertyName, arrayType, targetType, - isFieldAssignment() - ); + isFieldAssignment(), + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT ); return assignment; } @@ -875,7 +900,8 @@ public class PropertyMapping extends ModelElement { isFieldAssignment(), targetType, false, - null ); + false, + false ); } else { assignment = new SetterWrapper( assignment, method.getThrownTypes(), isFieldAssignment() ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java index 74549bd2e..4f70e4ec7 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java @@ -20,16 +20,22 @@ public class ArrayCopyWrapper extends AssignmentWrapper { private final Type arraysType; private final Type targetType; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; public ArrayCopyWrapper(Assignment rhs, String targetPropertyName, Type arraysType, Type targetType, - boolean fieldAssignment) { + boolean fieldAssignment, + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault) { super( rhs, fieldAssignment ); this.arraysType = arraysType; this.targetType = targetType; rhs.setSourceLocalVarName( rhs.createLocalVarName( targetPropertyName ) ); + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; } @Override @@ -44,4 +50,12 @@ public class ArrayCopyWrapper extends AssignmentWrapper { public boolean isIncludeSourceNullCheck() { return true; } + + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; + } + + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java index b4653dbb2..3d8de9fd5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java @@ -11,8 +11,11 @@ import java.util.List; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; +import org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism; import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.IGNORE; +import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_DEFAULT; /** * Wraps the assignment in a target setter. @@ -23,22 +26,29 @@ public class SetterWrapper extends AssignmentWrapper { private final List thrownTypesToExclude; private final boolean includeSourceNullCheck; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; public SetterWrapper(Assignment rhs, List thrownTypesToExclude, - NullValueCheckStrategyPrism nvms, boolean fieldAssignment, - Type targetType) { + boolean includeSourceNullCheck, + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault) { super( rhs, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; - this.includeSourceNullCheck = includeSourceNullCheck( rhs, nvms, targetType ); + this.includeSourceNullCheck = includeSourceNullCheck; + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; } public SetterWrapper(Assignment rhs, List thrownTypesToExclude, boolean fieldAssignment ) { super( rhs, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; this.includeSourceNullCheck = false; + this.setExplicitlyToNull = false; + this.setExplicitlyToDefault = false; } @Override @@ -55,30 +65,40 @@ public class SetterWrapper extends AssignmentWrapper { return result; } + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; + } + + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; + } + public boolean isIncludeSourceNullCheck() { return includeSourceNullCheck; } - /** - * Wraps the assignment in a target setter. include a null check when - * - * - Not if source is the parameter iso property, because the null check is than handled by the bean mapping - * - Not when source is primitive, you can't null check a primitive - * - The source property is fed to a conversion somehow before its assigned to the target - * - The user decided to ALLWAYS include a null check - * - When there's a source local variable name defined (e.g. nested source properties) - * - TODO: The last one I forgot..? - * - * @param rhs the source righthand side - * @param nvms null value check strategy - * @param targetType the target type - * - * @return include a null check - */ - private boolean includeSourceNullCheck(Assignment rhs, NullValueCheckStrategyPrism nvms, Type targetType) { + /** + * Wraps the assignment in a target setter. include a null check when + * + * - Not if source is the parameter iso property, because the null check is than handled by the bean mapping + * - Not when source is primitive, you can't null check a primitive + * - The source property is fed to a conversion somehow before its assigned to the target + * - The user decided to ALLWAYS include a null check + * + * @param rhs the source righthand side + * @param nvcs null value check strategy + * @param nvpms null value property mapping strategy + * @param targetType the target type + * + * @return include a null check + */ + public static boolean doSourceNullCheck(Assignment rhs, NullValueCheckStrategyPrism nvcs, + NullValuePropertyMappingStrategyPrism nvpms, Type targetType) { return !rhs.isSourceReferenceParameter() && !rhs.getSourceType().isPrimitive() - && (ALWAYS == nvms || rhs.getType().isConverted() || rhs.getSourceLocalVarName() != null + && (ALWAYS == nvcs + || SET_TO_DEFAULT == nvpms || IGNORE == nvpms + || rhs.getType().isConverted() || (rhs.getType().isDirect() && targetType.isPrimitive())); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java index 8176f6a8f..dede03145 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java @@ -12,10 +12,6 @@ import java.util.Set; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism; - -import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_DEFAULT; -import static org.mapstruct.ap.internal.prism.NullValuePropertyMappingStrategyPrism.SET_TO_NULL; /** * Wraps the assignment in a target setter. @@ -28,8 +24,8 @@ public class UpdateWrapper extends AssignmentWrapper { private final Assignment factoryMethod; private final Type targetImplementationType; private final boolean includeSourceNullCheck; - private final boolean includeExplicitNullWhenSourceIsNull; - private final boolean mapNullToDefault; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; public UpdateWrapper( Assignment decoratedAssignment, List thrownTypesToExclude, @@ -37,14 +33,15 @@ public class UpdateWrapper extends AssignmentWrapper { boolean fieldAssignment, Type targetType, boolean includeSourceNullCheck, - NullValuePropertyMappingStrategyPrism nvpms) { + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault ) { super( decoratedAssignment, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; this.factoryMethod = factoryMethod; this.targetImplementationType = determineImplType( factoryMethod, targetType ); this.includeSourceNullCheck = includeSourceNullCheck; - this.mapNullToDefault = nvpms == SET_TO_DEFAULT; - this.includeExplicitNullWhenSourceIsNull = nvpms == SET_TO_NULL; + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; } private static Type determineImplType(Assignment factoryMethod, Type targetType) { @@ -97,11 +94,11 @@ public class UpdateWrapper extends AssignmentWrapper { return includeSourceNullCheck; } - public boolean isIncludeExplicitNullWhenSourceIsNull() { - return includeExplicitNullWhenSourceIsNull; + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; } - public boolean isMapNullToDefault() { - return mapNullToDefault; + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; } } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl index bdcb438d0..58416fc63 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl @@ -14,9 +14,9 @@ <@assignToExistingTarget/> <@lib.handleAssignment/>; } - <#if mapNullToDefault || includeExplicitNullWhenSourceIsNull> + <#if setExplicitlyToDefault || setExplicitlyToNull> else { - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if mapNullToDefault><@lib.initTargetObject/><#else>null; + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if setExplicitlyToDefault><@lib.initTargetObject/><#else>null; } <#else> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl index 7f4d3bb86..8fe5c44fa 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl @@ -30,12 +30,18 @@ <#-- local macro related to handleSourceReferenceNullCheck + note: the <#elseif setExplicitlyToDefault || setExplicitlyToNull> is only relevant for update mappings + the default value takes precedence --> <#macro elseDefaultAssignment> <#if ext.defaultValueAssignment?? > else { <@handeDefaultAssigment/> } + <#elseif setExplicitlyToDefault || setExplicitlyToNull> + else { + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if setExplicitlyToDefault><@lib.initTargetObject/><#else>null; + } <#-- @@ -142,7 +148,7 @@ Performs a default assignment with a default value. <#if factoryMethod??> <@includeModel object=factoryMethod targetType=ext.targetType/> <#else> - new <@constructTargetObject/>() + <@constructTargetObject/> <#-- @@ -152,9 +158,11 @@ Performs a default assignment with a default value. --> <#macro constructTargetObject><@compress single_line=true> <#if ext.targetType.implementationType??> - <@includeModel object=ext.targetType.implementationType/> + new <@includeModel object=ext.targetType.implementationType/>() + <#elseif ext.targetType.arrayType> + new <@includeModel object=ext.targetType.componentType/>[0] <#else> - <@includeModel object=ext.targetType/> + new <@includeModel object=ext.targetType/>() <#-- diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java new file mode 100644 index 000000000..1d3fe69df --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import java.util.List; + +public class ContactDataDTO { + private String email; + private String phone; + private String address; + private List preferences; + private String[] settings; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public List getPreferences() { + return preferences; + } + + public void setPreferences(List preferences) { + this.preferences = preferences; + } + + public String[] getSettings() { + return settings; + } + + public void setSettings(String[] settings) { + this.settings = settings; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java new file mode 100644 index 000000000..5bff62f4c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java @@ -0,0 +1,117 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(AnnotationProcessorTestRunner.class) +@IssueKey("1685") +@WithClasses({ + User.class, + UserDTO.class, + UserMapper.class, + ContactDataDTO.class +}) +public class Issue1685Test { + + @Rule + public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + UserMapper.class + ); + + @Test + public void testSetToNullWhenNVPMSSetToNull() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isNull(); + assertThat( target.getPhone() ).isNull(); + assertThat( target.getName() ).isNull(); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).isNull(); + } + + @Test + public void testIgnoreWhenNVPMSIgnore() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserAndIgnoreDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isEqualTo( "email" ); + assertThat( target.getPhone() ).isEqualTo( 12345 ); + assertThat( target.getName() ).isEqualTo( "name" ); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).containsExactly( "test" ); + } + + @Test + public void testSetToDefaultWhenNVPMSSetToDefault() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserAndDefaultDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isEqualTo( "" ); + assertThat( target.getPhone() ).isEqualTo( 0 ); + assertThat( target.getName() ).isEqualTo( "" ); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java new file mode 100644 index 000000000..3216465fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import java.util.ArrayList; +import java.util.List; + +public class User { + private String name; + private String email; + private Integer phone; + private String address; + private List preferences = new ArrayList<>( ); + private String[] settings; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getPhone() { + return phone; + } + + public void setPhone(Integer phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public void addPreference(String preference) { + preferences.add( preference ); + } + + public List getPreferences() { + return preferences; + } + + public String[] getSettings() { + return settings; + } + + public void setSettings(String[] settings) { + this.settings = settings; + } +} + + diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java new file mode 100644 index 000000000..0ea035ee8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +public class UserDTO { + private String name; + private ContactDataDTO contactDataDTO; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ContactDataDTO getContactDataDTO() { + return contactDataDTO; + } + + public void setContactDataDTO(ContactDataDTO contactDataDTO) { + this.contactDataDTO = contactDataDTO; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java new file mode 100644 index 000000000..10ed334c0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import org.mapstruct.BeanMapping; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper( collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED ) +public interface UserMapper { + + UserMapper INSTANCE = Mappers.getMapper( UserMapper.class ); + + @Mappings({ + @Mapping(source = "email", target = "contactDataDTO.email"), + @Mapping(source = "phone", target = "contactDataDTO.phone"), + @Mapping(source = "address", target = "contactDataDTO.address"), + @Mapping(source = "preferences", target = "contactDataDTO.preferences"), + @Mapping(source = "settings", target = "contactDataDTO.settings") + }) + UserDTO userToUserDTO(User user); + + @InheritInverseConfiguration + void updateUserFromUserDTO(UserDTO userDTO, @MappingTarget User user); + + @InheritInverseConfiguration + @BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE ) + void updateUserFromUserAndIgnoreDTO(UserDTO userDTO, @MappingTarget User user); + + @InheritInverseConfiguration + @BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT ) + @Mapping( target = "phone", source = "contactDataDTO.phone", defaultValue = "0" ) + void updateUserFromUserAndDefaultDTO(UserDTO userDTO, @MappingTarget User user); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java index 847fd100f..08c5e2ec1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java @@ -98,7 +98,7 @@ public class NestedSimpleBeansMappingTest { // result assertThat( smartMapping.getName() ).isEqualTo( user.getName() ); assertThat( smartMapping.getCar().getYear() ).isEqualTo( user.getCar().getYear() ); - assertThat( smartMapping.getCar().getName() ).isEqualTo( "Toyota" ); + assertThat( smartMapping.getCar().getName() ).isNull(); assertThat( user.getCar().getName() ).isNull(); assertWheels( smartMapping.getCar().getWheels(), user.getCar().getWheels() ); assertCar( smartMapping.getSecondCar(), user.getSecondCar() ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java index 1121e4582..a65bfde8d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java @@ -14,6 +14,7 @@ import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry; import org.mapstruct.ap.test.nestedsourceproperties.source.Chart; import org.mapstruct.factory.Mappers; @@ -21,7 +22,10 @@ import org.mapstruct.factory.Mappers; /** * @author Sjaak Derksen */ -@Mapper( nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS ) +@Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE +) public abstract class ChartEntryToArtistUpdate { public static final ChartEntryToArtistUpdate MAPPER = Mappers.getMapper( ChartEntryToArtistUpdate.class ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java index 019327ede..362a12999 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java @@ -19,7 +19,7 @@ public interface CustomerDefaultMapper { @Mapping(source = "address", target = "homeDTO.addressDTO") void mapCustomer(Customer customer, @MappingTarget UserDTO userDTO); - @Mapping(source = "houseNumber", target = "houseNo") + @Mapping(source = "houseNumber", target = "houseNo", defaultValue = "0") void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); } diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java new file mode 100644 index 000000000..9c62462f5 --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/bugs/_1685/UserMapperImpl.java @@ -0,0 +1,241 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2019-01-27T12:40:32+0100", + comments = "version: , compiler: Eclipse JDT (Batch) 1.2.100.v20160418-1457, environment: Java 1.8.0_181 (Oracle Corporation)" +) +public class UserMapperImpl implements UserMapper { + + @Override + public UserDTO userToUserDTO(User user) { + if ( user == null ) { + return null; + } + + UserDTO userDTO = new UserDTO(); + + userDTO.setContactDataDTO( userToContactDataDTO( user ) ); + userDTO.setName( user.getName() ); + + return userDTO; + } + + @Override + public void updateUserFromUserDTO(UserDTO userDTO, User user) { + if ( userDTO == null ) { + return; + } + + String[] settings1 = userDTOContactDataDTOSettings( userDTO ); + if ( settings1 != null ) { + user.setSettings( Arrays.copyOf( settings1, settings1.length ) ); + } + else { + user.setSettings( null ); + } + if ( userDTOContactDataDTOPreferences( userDTO ) != null ) { + for ( String contactDataDTOPreference : userDTOContactDataDTOPreferences( userDTO ) ) { + user.addPreference( contactDataDTOPreference ); + } + } + user.setAddress( userDTOContactDataDTOAddress( userDTO ) ); + String phone = userDTOContactDataDTOPhone( userDTO ); + if ( phone != null ) { + user.setPhone( Integer.parseInt( phone ) ); + } + else { + user.setPhone( null ); + } + user.setEmail( userDTOContactDataDTOEmail( userDTO ) ); + user.setName( userDTO.getName() ); + } + + @Override + public void updateUserFromUserAndIgnoreDTO(UserDTO userDTO, User user) { + if ( userDTO == null ) { + return; + } + + String[] settings1 = userDTOContactDataDTOSettings( userDTO ); + if ( settings1 != null ) { + user.setSettings( Arrays.copyOf( settings1, settings1.length ) ); + } + if ( userDTOContactDataDTOPreferences( userDTO ) != null ) { + for ( String contactDataDTOPreference : userDTOContactDataDTOPreferences( userDTO ) ) { + user.addPreference( contactDataDTOPreference ); + } + } + String address = userDTOContactDataDTOAddress( userDTO ); + if ( address != null ) { + user.setAddress( address ); + } + String phone = userDTOContactDataDTOPhone( userDTO ); + if ( phone != null ) { + user.setPhone( Integer.parseInt( phone ) ); + } + String email = userDTOContactDataDTOEmail( userDTO ); + if ( email != null ) { + user.setEmail( email ); + } + if ( userDTO.getName() != null ) { + user.setName( userDTO.getName() ); + } + } + + @Override + public void updateUserFromUserAndDefaultDTO(UserDTO userDTO, User user) { + if ( userDTO == null ) { + return; + } + + String[] settings1 = userDTOContactDataDTOSettings( userDTO ); + if ( settings1 != null ) { + user.setSettings( Arrays.copyOf( settings1, settings1.length ) ); + } + else { + user.setSettings( new String[0] ); + } + if ( userDTOContactDataDTOPreferences( userDTO ) != null ) { + for ( String contactDataDTOPreference : userDTOContactDataDTOPreferences( userDTO ) ) { + user.addPreference( contactDataDTOPreference ); + } + } + String address = userDTOContactDataDTOAddress( userDTO ); + if ( address != null ) { + user.setAddress( address ); + } + else { + user.setAddress( new String() ); + } + String phone = userDTOContactDataDTOPhone( userDTO ); + if ( phone != null ) { + user.setPhone( Integer.parseInt( phone ) ); + } + else { + user.setPhone( 0 ); + } + String email = userDTOContactDataDTOEmail( userDTO ); + if ( email != null ) { + user.setEmail( email ); + } + else { + user.setEmail( new String() ); + } + if ( userDTO.getName() != null ) { + user.setName( userDTO.getName() ); + } + else { + user.setName( new String() ); + } + } + + protected ContactDataDTO userToContactDataDTO(User user) { + if ( user == null ) { + return null; + } + + ContactDataDTO contactDataDTO = new ContactDataDTO(); + + if ( user.getPhone() != null ) { + contactDataDTO.setPhone( String.valueOf( user.getPhone() ) ); + } + String[] settings = user.getSettings(); + if ( settings != null ) { + contactDataDTO.setSettings( Arrays.copyOf( settings, settings.length ) ); + } + List list = user.getPreferences(); + if ( list != null ) { + contactDataDTO.setPreferences( new ArrayList( list ) ); + } + contactDataDTO.setAddress( user.getAddress() ); + contactDataDTO.setEmail( user.getEmail() ); + + return contactDataDTO; + } + + private String[] userDTOContactDataDTOSettings(UserDTO userDTO) { + if ( userDTO == null ) { + return null; + } + ContactDataDTO contactDataDTO = userDTO.getContactDataDTO(); + if ( contactDataDTO == null ) { + return null; + } + String[] settings = contactDataDTO.getSettings(); + if ( settings == null ) { + return null; + } + return settings; + } + + private List userDTOContactDataDTOPreferences(UserDTO userDTO) { + if ( userDTO == null ) { + return null; + } + ContactDataDTO contactDataDTO = userDTO.getContactDataDTO(); + if ( contactDataDTO == null ) { + return null; + } + List preferences = contactDataDTO.getPreferences(); + if ( preferences == null ) { + return null; + } + return preferences; + } + + private String userDTOContactDataDTOAddress(UserDTO userDTO) { + if ( userDTO == null ) { + return null; + } + ContactDataDTO contactDataDTO = userDTO.getContactDataDTO(); + if ( contactDataDTO == null ) { + return null; + } + String address = contactDataDTO.getAddress(); + if ( address == null ) { + return null; + } + return address; + } + + private String userDTOContactDataDTOPhone(UserDTO userDTO) { + if ( userDTO == null ) { + return null; + } + ContactDataDTO contactDataDTO = userDTO.getContactDataDTO(); + if ( contactDataDTO == null ) { + return null; + } + String phone = contactDataDTO.getPhone(); + if ( phone == null ) { + return null; + } + return phone; + } + + private String userDTOContactDataDTOEmail(UserDTO userDTO) { + if ( userDTO == null ) { + return null; + } + ContactDataDTO contactDataDTO = userDTO.getContactDataDTO(); + if ( contactDataDTO == null ) { + return null; + } + String email = contactDataDTO.getEmail(); + if ( email == null ) { + return null; + } + return email; + } +} diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java index c503c8a2b..548d236e5 100644 --- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java @@ -25,6 +25,9 @@ public class UserDtoUpdateMapperSmartImpl implements UserDtoUpdateMapperSmart { if ( user.getName() != null ) { userDto.setName( user.getName() ); } + else { + userDto.setName( null ); + } if ( user.getCar() != null ) { if ( userDto.getCar() == null ) { userDto.setCar( new CarDto() ); @@ -88,6 +91,9 @@ public class UserDtoUpdateMapperSmartImpl implements UserDtoUpdateMapperSmart { if ( car.getName() != null ) { mappingTarget.setName( car.getName() ); } + else { + mappingTarget.setName( null ); + } mappingTarget.setYear( car.getYear() ); if ( mappingTarget.getWheels() != null ) { List list = wheelListToWheelDtoList( car.getWheels() ); @@ -133,6 +139,9 @@ public class UserDtoUpdateMapperSmartImpl implements UserDtoUpdateMapperSmart { if ( roof.getType() != null ) { mappingTarget.setType( roofTypeToExternalRoofType( roof.getType() ) ); } + else { + mappingTarget.setType( null ); + } } protected void houseToHouseDto(House house, HouseDto mappingTarget) { @@ -143,6 +152,9 @@ public class UserDtoUpdateMapperSmartImpl implements UserDtoUpdateMapperSmart { if ( house.getName() != null ) { mappingTarget.setName( house.getName() ); } + else { + mappingTarget.setName( null ); + } mappingTarget.setYear( house.getYear() ); if ( house.getRoof() != null ) { if ( mappingTarget.getRoof() == null ) { diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperImpl.java index 570fae4a7..5716b231e 100644 --- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperImpl.java +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperImpl.java @@ -42,10 +42,7 @@ public class FishTankMapperImpl implements FishTankMapper { fishTankDto.setFish( fishToFishDto( source.getFish() ) ); fishTankDto.setMaterial( fishTankToMaterialDto( source ) ); fishTankDto.setQuality( waterQualityToWaterQualityDto( source.getQuality() ) ); - Ornament ornament = sourceInteriorOrnament( source ); - if ( ornament != null ) { - fishTankDto.setOrnament( ornamentToOrnamentDto( ornament ) ); - } + fishTankDto.setOrnament( ornamentToOrnamentDto( sourceInteriorOrnament( source ) ) ); fishTankDto.setPlant( waterPlantToWaterPlantDto( source.getPlant() ) ); fishTankDto.setName( source.getName() ); @@ -63,10 +60,7 @@ public class FishTankMapperImpl implements FishTankMapper { fishTankDto.setFish( fishToFishDto( source.getFish() ) ); fishTankDto.setMaterial( fishTankToMaterialDto1( source ) ); fishTankDto.setQuality( waterQualityToWaterQualityDto( source.getQuality() ) ); - Ornament ornament = sourceInteriorOrnament( source ); - if ( ornament != null ) { - fishTankDto.setOrnament( ornamentToOrnamentDto( ornament ) ); - } + fishTankDto.setOrnament( ornamentToOrnamentDto( sourceInteriorOrnament( source ) ) ); fishTankDto.setPlant( waterPlantToWaterPlantDto( source.getPlant() ) ); fishTankDto.setName( source.getName() ); @@ -84,10 +78,7 @@ public class FishTankMapperImpl implements FishTankMapper { fishTank.setFish( fishDtoToFish( source.getFish() ) ); fishTank.setQuality( waterQualityDtoToWaterQuality( source.getQuality() ) ); fishTank.setInterior( fishTankDtoToInterior( source ) ); - MaterialTypeDto materialType = sourceMaterialMaterialType( source ); - if ( materialType != null ) { - fishTank.setMaterial( materialTypeDtoToMaterialType( materialType ) ); - } + fishTank.setMaterial( materialTypeDtoToMaterialType( sourceMaterialMaterialType( source ) ) ); fishTank.setPlant( waterPlantDtoToWaterPlant( source.getPlant() ) ); fishTank.setName( source.getName() ); @@ -264,10 +255,7 @@ public class FishTankMapperImpl implements FishTankMapper { WaterQualityReport waterQualityReport = new WaterQualityReport(); - String name = waterQualityReportDtoOrganisationName( waterQualityReportDto ); - if ( name != null ) { - waterQualityReport.setOrganisationName( name ); - } + waterQualityReport.setOrganisationName( waterQualityReportDtoOrganisationName( waterQualityReportDto ) ); waterQualityReport.setVerdict( waterQualityReportDto.getVerdict() ); return waterQualityReport; diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryImpl.java index 81d3e2974..48d276f00 100644 --- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryImpl.java +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryImpl.java @@ -33,18 +33,9 @@ public class ArtistToChartEntryImpl implements ArtistToChartEntry { } if ( song != null ) { chartEntry.setSongTitle( song.getTitle() ); - String city = songArtistLabelStudioCity( song ); - if ( city != null ) { - chartEntry.setCity( city ); - } - String name = songArtistLabelStudioName( song ); - if ( name != null ) { - chartEntry.setRecordedAt( name ); - } - String name1 = songArtistName( song ); - if ( name1 != null ) { - chartEntry.setArtistName( name1 ); - } + chartEntry.setCity( songArtistLabelStudioCity( song ) ); + chartEntry.setRecordedAt( songArtistLabelStudioName( song ) ); + chartEntry.setArtistName( songArtistName( song ) ); } if ( position != null ) { chartEntry.setPosition( position ); @@ -62,18 +53,9 @@ public class ArtistToChartEntryImpl implements ArtistToChartEntry { ChartEntry chartEntry = new ChartEntry(); chartEntry.setSongTitle( song.getTitle() ); - String city = songArtistLabelStudioCity( song ); - if ( city != null ) { - chartEntry.setCity( city ); - } - String name = songArtistLabelStudioName( song ); - if ( name != null ) { - chartEntry.setRecordedAt( name ); - } - String name1 = songArtistName( song ); - if ( name1 != null ) { - chartEntry.setArtistName( name1 ); - } + chartEntry.setCity( songArtistLabelStudioCity( song ) ); + chartEntry.setRecordedAt( songArtistLabelStudioName( song ) ); + chartEntry.setArtistName( songArtistName( song ) ); return chartEntry; } diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistImpl.java index 3c30a5ac8..f01afb428 100644 --- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistImpl.java +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistImpl.java @@ -68,27 +68,12 @@ public class ChartEntryToArtistImpl extends ChartEntryToArtist { ChartEntry chartEntry = new ChartEntry(); - String title = chartSongTitle( chart ); - if ( title != null ) { - chartEntry.setSongTitle( title ); - } + chartEntry.setSongTitle( chartSongTitle( chart ) ); chartEntry.setChartName( chart.getName() ); - String city = chartSongArtistLabelStudioCity( chart ); - if ( city != null ) { - chartEntry.setCity( city ); - } - String name = chartSongArtistLabelStudioName( chart ); - if ( name != null ) { - chartEntry.setRecordedAt( name ); - } - String name1 = chartSongArtistName( chart ); - if ( name1 != null ) { - chartEntry.setArtistName( name1 ); - } - List positions = chartSongPositions( chart ); - if ( positions != null ) { - chartEntry.setPosition( mapPosition( positions ) ); - } + chartEntry.setCity( chartSongArtistLabelStudioCity( chart ) ); + chartEntry.setRecordedAt( chartSongArtistLabelStudioName( chart ) ); + chartEntry.setArtistName( chartSongArtistName( chart ) ); + chartEntry.setPosition( mapPosition( chartSongPositions( chart ) ) ); return chartEntry; }