#2624 Nested target methods should be inherited for forged Map to Bean methods

This commit is contained in:
Filip Hrisafov 2021-10-24 17:20:56 +02:00
parent ca2529f862
commit 907d605160
3 changed files with 124 additions and 14 deletions

View File

@ -309,7 +309,7 @@ public class PropertyMapping extends ModelElement {
assignment = forgeMapMapping( sourceType, targetType, rightHandSide ); assignment = forgeMapMapping( sourceType, targetType, rightHandSide );
} }
else if ( sourceType.isMapType() && !targetType.isMapType()) { else if ( sourceType.isMapType() && !targetType.isMapType()) {
assignment = forgeMapToBeanMapping( sourceType, targetType, rightHandSide ); assignment = forgeMapping( sourceType, targetType.withoutBounds(), rightHandSide );
} }
else if ( ( sourceType.isIterableType() && targetType.isStreamType() ) else if ( ( sourceType.isIterableType() && targetType.isStreamType() )
|| ( sourceType.isStreamType() && targetType.isStreamType() ) || ( sourceType.isStreamType() && targetType.isStreamType() )
@ -753,19 +753,6 @@ public class PropertyMapping extends ModelElement {
return createForgedAssignment( source, methodRef, mapMappingMethod ); return createForgedAssignment( source, methodRef, mapMappingMethod );
} }
private Assignment forgeMapToBeanMapping(Type sourceType, Type targetType, SourceRHS source) {
targetType = targetType.withoutBounds();
ForgedMethod methodRef = prepareForgedMethod( sourceType, targetType, source, "{}" );
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
final BeanMappingMethod mapToBeanMappingMethod = builder.mappingContext( ctx )
.forgedMethod( methodRef )
.build();
return createForgedAssignment( source, methodRef, mapToBeanMappingMethod );
}
private Assignment forgeMapping(SourceRHS sourceRHS) { private Assignment forgeMapping(SourceRHS sourceRHS) {
Type sourceType; Type sourceType;
if ( targetWriteAccessorType == AccessorType.ADDER ) { if ( targetWriteAccessorType == AccessorType.ADDER ) {
@ -778,6 +765,10 @@ public class PropertyMapping extends ModelElement {
return null; return null;
} }
return forgeMapping( sourceType, targetType, sourceRHS );
}
private Assignment forgeMapping(Type sourceType, Type targetType, SourceRHS sourceRHS) {
//Fail fast. If we could not find the method by now, no need to try //Fail fast. If we could not find the method by now, no need to try
if ( sourceType.isPrimitive() || targetType.isPrimitive() ) { if ( sourceType.isPrimitive() || targetType.isPrimitive() ) {

View File

@ -0,0 +1,76 @@
/*
* 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._2624;
import java.util.Map;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
* @author Filip Hrisafov
*/
@Mapper
public interface Issue2624Mapper {
Issue2624Mapper INSTANCE = Mappers.getMapper( Issue2624Mapper.class );
@Mapping( target = "department.id", source = "did")
@Mapping( target = "department.name", source = "dname")
Employee fromMap(Map<String, String> source);
class Employee {
private String id;
private String name;
private Department department;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
class Department {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

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._2624;
import java.util.HashMap;
import java.util.Map;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Filip Hrisafov
*/
@WithClasses({
Issue2624Mapper.class
})
class Issue2624Test {
@ProcessorTest
void shouldCorrectlyMapNestedTargetFromMap() {
Map<String, String> map = new HashMap<>();
map.put( "id", "1234" );
map.put( "name", "Tester" );
map.put( "did", "4321" ); //Department Id
map.put( "dname", "Test" ); // Department name
Issue2624Mapper.Employee employee = Issue2624Mapper.INSTANCE.fromMap( map );
assertThat( employee ).isNotNull();
assertThat( employee.getId() ).isEqualTo( "1234" );
assertThat( employee.getName() ).isEqualTo( "Tester" );
Issue2624Mapper.Department department = employee.getDepartment();
assertThat( department ).isNotNull();
assertThat( department.getId() ).isEqualTo( "4321" );
assertThat( department.getName() ).isEqualTo( "Test" );
}
}