mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
tried to support arrays as target - stopped because of null values in target array - intermediate method used for lists and then resultList.toArray(new Employee[0]);
would be nice - or somehow using a list in the forged method anyways:
``` public Employee[] mapListToArray(List<EmployeeDto> employees) { if (employees == null) { return null; } List<Employee> resultList = new ArrayList<>(); for ( EmployeeDto employeeDto : employees ) { if ( countryIsNotNull( employeeDto ) ) { resultList.add(map(employeeDto)); } } return resultList.toArray(new Employee[0]); } ```
This commit is contained in:
parent
d9566bab76
commit
728b42ac25
@ -83,11 +83,7 @@ public class IterableMappingMethod extends ContainerMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasIterableConditionMethod() {
|
public boolean hasIterableConditionMethod() {
|
||||||
return getIterableConditionMethod() != null;
|
return iterableConditionMethod != null;
|
||||||
}
|
|
||||||
|
|
||||||
public Method getIterableConditionMethod() {
|
|
||||||
return iterableConditionMethod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference getIterableConditionMethodReference() {
|
public MethodReference getIterableConditionMethodReference() {
|
||||||
@ -101,10 +97,7 @@ public class IterableMappingMethod extends ContainerMappingMethod {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return MethodReference.forForgedMethod(
|
return MethodReference.forForgedMethod( iterableConditionMethod, parameterBindings );
|
||||||
iterableConditionMethod,
|
|
||||||
parameterBindings
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IterableMappingMethod(Method method, List<Annotation> annotations,
|
private IterableMappingMethod(Method method, List<Annotation> annotations,
|
||||||
|
@ -41,19 +41,19 @@
|
|||||||
</#if>
|
</#if>
|
||||||
}
|
}
|
||||||
|
|
||||||
<#if resultType.arrayType>
|
<#-- <#if resultType.arrayType>-->
|
||||||
<#if !existingInstanceMapping>
|
<#-- <#if !existingInstanceMapping>-->
|
||||||
<#assign elementTypeString><@includeModel object=resultElementType/></#assign>
|
<#-- <#assign elementTypeString><@includeModel object=resultElementType/></#assign>-->
|
||||||
${elementTypeString}[] ${resultName} = new ${elementTypeString?keep_before('[]')}[<@iterableSize/>]${elementTypeString?replace('[^\\[\\]]+', '', 'r')};
|
<#-- ${elementTypeString}[] ${resultName} = new ${elementTypeString?keep_before('[]')}[<@iterableSize/>]${elementTypeString?replace('[^\\[\\]]+', '', 'r')};-->
|
||||||
</#if>
|
<#-- </#if>-->
|
||||||
<#else>
|
<#-- <#else>-->
|
||||||
<#if existingInstanceMapping>
|
<#if existingInstanceMapping>
|
||||||
${resultName}.clear();
|
${resultName}.clear();
|
||||||
<#else>
|
<#else>
|
||||||
<#-- Use the interface type on the left side, except it is java.lang.Iterable; use the implementation type - if present - on the right side -->
|
<#-- Use the interface type on the left side, except it is java.lang.Iterable; use the implementation type - if present - on the right side -->
|
||||||
<@iterableLocalVarDef/> ${resultName} = <@includeModel object=iterableCreation useSizeIfPossible=true/>;
|
<@iterableLocalVarDef/> ${resultName} = <@includeModel object=iterableCreation useSizeIfPossible=true/>;
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
<#-- </#if>-->
|
||||||
<#list beforeMappingReferencesWithMappingTarget as callback>
|
<#list beforeMappingReferencesWithMappingTarget as callback>
|
||||||
<@includeModel object=callback targetBeanName=resultName targetType=resultType/>
|
<@includeModel object=callback targetBeanName=resultName targetType=resultType/>
|
||||||
<#if !callback_has_next>
|
<#if !callback_has_next>
|
||||||
@ -61,17 +61,32 @@
|
|||||||
</#if>
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
<#if resultType.arrayType>
|
<#if resultType.arrayType>
|
||||||
int ${index1Name} = 0;
|
|
||||||
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
|
||||||
<#if existingInstanceMapping>
|
|
||||||
if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= <@iterableSize/> ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
</#if>
|
</#if>
|
||||||
<@includeModel object=elementAssignment targetWriteAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>
|
<#if true>
|
||||||
${index1Name}++;
|
<#-- <#if resultType.arrayType>-->
|
||||||
}
|
<#-- int ${index1Name} = 0;-->
|
||||||
<#else>
|
<#-- for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {-->
|
||||||
|
<#-- <#if existingInstanceMapping>-->
|
||||||
|
<#-- if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= <@iterableSize/> ) ) {-->
|
||||||
|
<#-- break;-->
|
||||||
|
<#-- }-->
|
||||||
|
<#-- </#if>-->
|
||||||
|
<#-- <#if hasIterableConditionMethod()>-->
|
||||||
|
<#-- if ( <@includeModel object=iterableConditionMethodReference /> ) {-->
|
||||||
|
<#-- <@includeModel object=elementAssignment targetWriteAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>-->
|
||||||
|
<#-- ${index1Name}++;-->
|
||||||
|
<#-- }-->
|
||||||
|
<#-- <#else>-->
|
||||||
|
<#-- <@includeModel object=elementAssignment targetWriteAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>-->
|
||||||
|
<#-- ${index1Name}++;-->
|
||||||
|
<#-- </#if>-->
|
||||||
|
<#-- }-->
|
||||||
|
<#-- Employee[] employeeTmp = employees.stream()-->
|
||||||
|
<#-- .filter(this::countryIsNotNull)-->
|
||||||
|
<#-- .map(this::map)-->
|
||||||
|
<#-- .toArray(Employee[]::new);-->
|
||||||
|
<#-- <#else>-->
|
||||||
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
||||||
<#if hasIterableConditionMethod()>
|
<#if hasIterableConditionMethod()>
|
||||||
if ( <@includeModel object=iterableConditionMethodReference /> ) {
|
if ( <@includeModel object=iterableConditionMethodReference /> ) {
|
||||||
@ -90,8 +105,12 @@
|
|||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
<#if returnType.name != "void">
|
<#if returnType.name != "void">
|
||||||
|
<#if hasIterableConditionMethod() && resultType.arrayType>
|
||||||
|
${resultName}.toArray( new <@includeModel object=resultElementType/>[0] );
|
||||||
|
<#else>
|
||||||
return ${resultName};
|
return ${resultName};
|
||||||
</#if>
|
</#if>
|
||||||
|
</#if>
|
||||||
}
|
}
|
||||||
<#macro throws>
|
<#macro throws>
|
||||||
<#if (thrownTypes?size > 0)><#lt> throws </#if><@compress single_line=true>
|
<#if (thrownTypes?size > 0)><#lt> throws </#if><@compress single_line=true>
|
||||||
|
@ -27,7 +27,14 @@ public interface IterableElementConditionMapper {
|
|||||||
@Mapping(target = "ssid", source = "uniqueIdNumber")
|
@Mapping(target = "ssid", source = "uniqueIdNumber")
|
||||||
Employee map(EmployeeDto employee);
|
Employee map(EmployeeDto employee);
|
||||||
|
|
||||||
List<Employee> map(List<EmployeeDto> employees);
|
List<Employee> mapListToList(List<EmployeeDto> employees);
|
||||||
|
|
||||||
|
List<Employee> mapArrayToList(EmployeeDto[] employees);
|
||||||
|
|
||||||
|
// Employee[] mapListToArray(List<EmployeeDto> employees);
|
||||||
|
//
|
||||||
|
// Employee[] mapArrayToArray(EmployeeDto[] employees);
|
||||||
|
|
||||||
|
|
||||||
@IterableElementCondition
|
@IterableElementCondition
|
||||||
default boolean countryIsNotNull(EmployeeDto value) {
|
default boolean countryIsNotNull(EmployeeDto value) {
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
package org.mapstruct.ap.test.conditional.iterable;
|
package org.mapstruct.ap.test.conditional.iterable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.mapstruct.ap.test.conditional.Employee;
|
import org.mapstruct.ap.test.conditional.Employee;
|
||||||
import org.mapstruct.ap.test.conditional.EmployeeDto;
|
import org.mapstruct.ap.test.conditional.EmployeeDto;
|
||||||
@ -22,16 +24,58 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@IssueKey("1610")
|
@IssueKey("1610")
|
||||||
@WithClasses({
|
@WithClasses({
|
||||||
Employee.class,
|
Employee.class,
|
||||||
EmployeeDto.class
|
EmployeeDto.class,
|
||||||
|
IterableElementConditionMapper.class,
|
||||||
})
|
})
|
||||||
public class IterableElementConditionTest {
|
public class IterableElementConditionTest {
|
||||||
|
|
||||||
@ProcessorTest
|
@ProcessorTest
|
||||||
@WithClasses({
|
public void conditionalMethodListToList() {
|
||||||
IterableElementConditionMapper.class
|
|
||||||
})
|
List<Employee> result = IterableElementConditionMapper.INSTANCE.mapListToList( setupList() );
|
||||||
public void conditionalMethodWithSourceParameter() {
|
|
||||||
IterableElementConditionMapper mapper = IterableElementConditionMapper.INSTANCE;
|
assertThatOnlyFilteredValuesMapped( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProcessorTest
|
||||||
|
public void conditionalMethodArrayToList() {
|
||||||
|
|
||||||
|
List<Employee> result = IterableElementConditionMapper.INSTANCE.mapArrayToList( setupArray() );
|
||||||
|
|
||||||
|
assertThatOnlyFilteredValuesMapped( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ProcessorTest
|
||||||
|
// public void conditionalMethodListToArray() {
|
||||||
|
//
|
||||||
|
// Employee[] result = IterableElementConditionMapper.INSTANCE.mapListToArray( setupList() );
|
||||||
|
//
|
||||||
|
// assertThatOnlyFilteredValuesMapped( result );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @ProcessorTest
|
||||||
|
// public void conditionalMethodArrayToArray() {
|
||||||
|
//
|
||||||
|
// Employee[] result = IterableElementConditionMapper.INSTANCE.mapArrayToArray( setupArray() );
|
||||||
|
//
|
||||||
|
// assertThatOnlyFilteredValuesMapped( result );
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static void assertThatOnlyFilteredValuesMapped(List<Employee> result) {
|
||||||
|
assertThat( result )
|
||||||
|
.singleElement()
|
||||||
|
.satisfies(
|
||||||
|
d -> assertThat( d.getName() ).isEqualTo( "Tester" )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertThatOnlyFilteredValuesMapped(Employee[] result) {
|
||||||
|
assertThatOnlyFilteredValuesMapped(
|
||||||
|
Arrays.stream( result ).collect( Collectors.toList() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArrayList<EmployeeDto> setupList() {
|
||||||
|
|
||||||
EmployeeDto dtoWithoutCountry = new EmployeeDto();
|
EmployeeDto dtoWithoutCountry = new EmployeeDto();
|
||||||
dtoWithoutCountry.setName( "Tester" );
|
dtoWithoutCountry.setName( "Tester" );
|
||||||
@ -47,13 +91,11 @@ public class IterableElementConditionTest {
|
|||||||
employees.add( dtoWithoutCountry );
|
employees.add( dtoWithoutCountry );
|
||||||
employees.add( dtoWithCountry );
|
employees.add( dtoWithCountry );
|
||||||
|
|
||||||
List<Employee> result = mapper.map( employees );
|
return employees;
|
||||||
assertThat( result )
|
}
|
||||||
.singleElement()
|
|
||||||
.satisfies(
|
|
||||||
d -> assertThat(d.getName()).isEqualTo( "Tester" )
|
|
||||||
);
|
|
||||||
|
|
||||||
|
private static EmployeeDto[] setupArray() {
|
||||||
|
return setupList().toArray( new EmployeeDto[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user