From 6df9243d92f66490ceccdc6df40ffe41def2e217 Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Fri, 6 Nov 2020 21:24:52 +0100 Subject: [PATCH] #2253 remove unmapped source properties when source parameter is directly mapped --- .../ap/internal/model/BeanMappingMethod.java | 10 ++++ .../ap/test/bugs/_2253/Issue2253Test.java | 34 +++++++++++++ .../ap/test/bugs/_2253/TestMapper.java | 48 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index b17e06084..d19fb4f39 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -1315,6 +1315,16 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { sourceParameters.remove(); unprocessedDefinedTargets.remove( targetProperty.getKey() ); unprocessedSourceProperties.remove( targetProperty.getKey() ); + + // The source parameter was directly mapped so ignore all of its source properties completely + if ( !sourceParameter.getType().isPrimitive() && !sourceParameter.getType().isArrayType() ) { + // We explicitly ignore source properties from primitives or array types + Map readAccessors = sourceParameter.getType().getPropertyReadAccessors(); + for ( String sourceProperty : readAccessors.keySet() ) { + unprocessedSourceProperties.remove( sourceProperty ); + } + } + unprocessedConstructorProperties.remove( targetProperty.getKey() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java new file mode 100644 index 000000000..fc0e007da --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java @@ -0,0 +1,34 @@ +/* + * 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._2253; + +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 static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2253") +@RunWith( AnnotationProcessorTestRunner.class ) +@WithClasses( { + TestMapper.class, +} ) +public class Issue2253Test { + + @Test + public void shouldNotTreatMatchedSourceParameterAsBean() { + + TestMapper.Person person = TestMapper.INSTANCE.map( new TestMapper.PersonDto( 20 ), "Tester" ); + + assertThat( person.getAge() ).isEqualTo( 20 ); + assertThat( person.getName() ).isEqualTo( "Tester" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java new file mode 100644 index 000000000..1e05e444a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java @@ -0,0 +1,48 @@ +/* + * 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._2253; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface TestMapper { + + TestMapper INSTANCE = Mappers.getMapper( TestMapper.class ); + + Person map(PersonDto personDto, String name); + + class Person { + private final int age; + private final String name; + + public Person(int age, String name) { + this.age = age; + this.name = name; + } + + public int getAge() { + return age; + } + + public String getName() { + return name; + } + } + + class PersonDto { + private final int age; + + public PersonDto(int age) { + this.age = age; + } + + public int getAge() { + return age; + } + } +}