From e0eb0f6bb85970e534ebc4a5ea99c85c23bcf8be Mon Sep 17 00:00:00 2001 From: Sjaak Derksen Date: Sun, 30 Aug 2020 12:49:09 +0200 Subject: [PATCH] #2164 parameter matching should be done based on name when source name is absent (#2193) --- .../ap/internal/model/BeanMappingMethod.java | 29 ++++++++++---- .../ap/test/bugs/_2164/Issue2164Mapper.java | 40 +++++++++++++++++++ .../ap/test/bugs/_2164/Issue2164Test.java | 31 ++++++++++++++ 3 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.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 d6f06b49e..a0ea064f1 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 @@ -1068,10 +1068,23 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { // its a plain-old property mapping else { - // determine source parameter SourceReference sourceRef = mappingRef.getSourceReference(); + // sourceRef is not defined, check if a source property has the same name if ( sourceRef == null && method.getSourceParameters().size() == 1 ) { - sourceRef = getSourceRef( method.getSourceParameters().get( 0 ), targetPropertyName ); + sourceRef = getSourceRefByTargetName( method.getSourceParameters().get( 0 ), targetPropertyName ); + } + + if ( sourceRef == null ) { + // still no match. Try if one of the parameters has the same name + sourceRef = method.getSourceParameters() + .stream() + .filter( p -> targetPropertyName.equals( p.getName() ) ) + .findAny() + .map( p -> new SourceReference.BuilderFromProperty() + .sourceParameter( p ) + .name( targetPropertyName ) + .build() ) + .orElse( null ); } if ( sourceRef != null ) { @@ -1153,7 +1166,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { List sourceReferences = new ArrayList<>(); for ( String targetPropertyName : unprocessedTargetProperties.keySet() ) { for ( Parameter sourceParameter : method.getSourceParameters() ) { - SourceReference sourceRef = getSourceRef( sourceParameter, targetPropertyName ); + SourceReference sourceRef = getSourceRefByTargetName( sourceParameter, targetPropertyName ); if ( sourceRef != null ) { sourceReferences.add( sourceRef ); } @@ -1251,7 +1264,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { } } - private SourceReference getSourceRef(Parameter sourceParameter, String targetPropertyName) { + private SourceReference getSourceRefByTargetName(Parameter sourceParameter, String targetPropertyName) { SourceReference sourceRef = null; @@ -1261,11 +1274,11 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { Accessor sourceReadAccessor = sourceParameter.getType().getPropertyReadAccessors().get( targetPropertyName ); - - Accessor sourcePresenceChecker = - sourceParameter.getType().getPropertyPresenceCheckers().get( targetPropertyName ); - if ( sourceReadAccessor != null ) { + // property mapping + Accessor sourcePresenceChecker = + sourceParameter.getType().getPropertyPresenceCheckers().get( targetPropertyName ); + DeclaredType declaredSourceType = (DeclaredType) sourceParameter.getType().getTypeMirror(); Type returnType = ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ); sourceRef = new SourceReference.BuilderFromProperty().sourceParameter( sourceParameter ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java new file mode 100644 index 000000000..7d152e88c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java @@ -0,0 +1,40 @@ +/* + * 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._2164; + +import java.math.BigDecimal; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2164Mapper { + + Issue2164Mapper INSTANCE = Mappers.getMapper( Issue2164Mapper.class ); + + @Mapping(target = "value", qualifiedByName = "truncate2") + Target map(BigDecimal value); + + @Named( "truncate2" ) + default String truncate2(String in) { + return in.substring( 0, 2 ); + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java new file mode 100644 index 000000000..3ed5cf165 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java @@ -0,0 +1,31 @@ +/* + * 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._2164; + +import java.math.BigDecimal; + +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; + +@IssueKey("2164") +@WithClasses(Issue2164Mapper.class) +@RunWith(AnnotationProcessorTestRunner.class) +public class Issue2164Test { + + @Test + public void shouldSelectProperMethod() { + + Issue2164Mapper.Target target = Issue2164Mapper.INSTANCE.map( new BigDecimal( "1234" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "12" ); + } +}