#2221: Fix configuration inheritance when there are multiple matching source parameters of the same type

This commit is contained in:
Filip Hrisafov 2020-10-07 23:03:16 +02:00
parent 823b5edd9f
commit a5f49e591e
6 changed files with 172 additions and 6 deletions

View File

@ -10,7 +10,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.type.DeclaredType;
@ -239,11 +238,24 @@ public class SourceReference extends AbstractReference {
if ( isForwarded ) {
Parameter parameter = Parameter.getSourceParameter( templateMethod.getParameters(), parameterName );
if ( parameter != null ) {
result = method.getSourceParameters()
.stream()
.filter( p -> p.getType().isAssignableTo( parameter.getType() ) )
.collect( Collectors.reducing( (a, b) -> null ) )
.orElse( null );
// When forward inheriting we should find the matching source parameter by type
// If there are multiple parameters of the same type
// then we fallback to match the parameter name to the current method source parameters
for ( Parameter sourceParameter : method.getSourceParameters() ) {
if ( sourceParameter.getType().isAssignableTo( parameter.getType() ) ) {
if ( result == null ) {
result = sourceParameter;
}
else {
// When we reach here it means that we found a second source parameter
// that has the same type, then fallback to the matching source parameter
// in the current method
result = Parameter.getSourceParameter( method.getParameters(), parameterName );
break;
}
}
}
}
}
else {

View File

@ -0,0 +1,43 @@
/*
* 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._2221;
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("2221")
@RunWith(AnnotationProcessorTestRunner.class)
@WithClasses({
RestConfig.class,
RestSiteDto.class,
RestSiteMapper.class,
SiteDto.class,
})
public class Issue2221Test {
@Test
public void multiSourceInheritConfigurationShouldWork() {
SiteDto site = RestSiteMapper.INSTANCE.convert(
new RestSiteDto( "restTenant", "restSite", "restCti" ),
"parameterTenant",
"parameterSite"
);
assertThat( site ).isNotNull();
assertThat( site.getTenantId() ).isEqualTo( "parameterTenant" );
assertThat( site.getSiteId() ).isEqualTo( "parameterSite" );
assertThat( site.getCtiId() ).isEqualTo( "restCti" );
}
}

View File

@ -0,0 +1,21 @@
/*
* 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._2221;
import org.mapstruct.MapperConfig;
import org.mapstruct.Mapping;
/**
* @author Filip Hrisafov
*/
@MapperConfig
public interface RestConfig {
@Mapping(target = "tenantId", source = "tenantId")
@Mapping(target = "siteId", source = "siteId")
@Mapping(target = "ctiId", source = "source.cti", defaultValue = "unknown")
SiteDto convert(RestSiteDto source, String tenantId, String siteId);
}

View File

@ -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._2221;
/**
* @author Filip Hrisafov
*/
public class RestSiteDto {
private final String tenantId;
private final String siteId;
private final String cti;
public RestSiteDto(String tenantId, String siteId, String cti) {
this.tenantId = tenantId;
this.siteId = siteId;
this.cti = cti;
}
public String getTenantId() {
return tenantId;
}
public String getSiteId() {
return siteId;
}
public String getCti() {
return cti;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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._2221;
import org.mapstruct.InheritConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Filip Hrisafov
*/
@Mapper(config = RestConfig.class)
public interface RestSiteMapper {
RestSiteMapper INSTANCE = Mappers.getMapper( RestSiteMapper.class );
@InheritConfiguration
SiteDto convert(RestSiteDto source, String tenantId, String siteId);
}

View File

@ -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._2221;
/**
* @author Filip Hrisafov
*/
public class SiteDto {
private final String tenantId;
private final String siteId;
private final String ctiId;
public SiteDto(String tenantId, String siteId, String ctiId) {
this.tenantId = tenantId;
this.siteId = siteId;
this.ctiId = ctiId;
}
public String getTenantId() {
return tenantId;
}
public String getSiteId() {
return siteId;
}
public String getCtiId() {
return ctiId;
}
}