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() {
|
||||
return getIterableConditionMethod() != null;
|
||||
}
|
||||
|
||||
public Method getIterableConditionMethod() {
|
||||
return iterableConditionMethod;
|
||||
return iterableConditionMethod != null;
|
||||
}
|
||||
|
||||
public MethodReference getIterableConditionMethodReference() {
|
||||
@ -101,10 +97,7 @@ public class IterableMappingMethod extends ContainerMappingMethod {
|
||||
)
|
||||
);
|
||||
|
||||
return MethodReference.forForgedMethod(
|
||||
iterableConditionMethod,
|
||||
parameterBindings
|
||||
);
|
||||
return MethodReference.forForgedMethod( iterableConditionMethod, parameterBindings );
|
||||
}
|
||||
|
||||
private IterableMappingMethod(Method method, List<Annotation> annotations,
|
||||
|
@ -11,7 +11,7 @@
|
||||
</#list>
|
||||
<#if overridden>@Override</#if>
|
||||
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>)<@throws/> {
|
||||
<#list beforeMappingReferencesWithoutMappingTarget as callback>
|
||||
<#list beforeMappingReferencesWithoutMappingTarget as callback>
|
||||
<@includeModel object=callback targetBeanName=resultName targetType=resultType/>
|
||||
<#if !callback_has_next>
|
||||
|
||||
@ -41,19 +41,19 @@
|
||||
</#if>
|
||||
}
|
||||
|
||||
<#if resultType.arrayType>
|
||||
<#if !existingInstanceMapping>
|
||||
<#assign elementTypeString><@includeModel object=resultElementType/></#assign>
|
||||
${elementTypeString}[] ${resultName} = new ${elementTypeString?keep_before('[]')}[<@iterableSize/>]${elementTypeString?replace('[^\\[\\]]+', '', 'r')};
|
||||
</#if>
|
||||
<#else>
|
||||
<#-- <#if resultType.arrayType>-->
|
||||
<#-- <#if !existingInstanceMapping>-->
|
||||
<#-- <#assign elementTypeString><@includeModel object=resultElementType/></#assign>-->
|
||||
<#-- ${elementTypeString}[] ${resultName} = new ${elementTypeString?keep_before('[]')}[<@iterableSize/>]${elementTypeString?replace('[^\\[\\]]+', '', 'r')};-->
|
||||
<#-- </#if>-->
|
||||
<#-- <#else>-->
|
||||
<#if existingInstanceMapping>
|
||||
${resultName}.clear();
|
||||
<#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 -->
|
||||
<@iterableLocalVarDef/> ${resultName} = <@includeModel object=iterableCreation useSizeIfPossible=true/>;
|
||||
</#if>
|
||||
</#if>
|
||||
<#-- </#if>-->
|
||||
<#list beforeMappingReferencesWithMappingTarget as callback>
|
||||
<@includeModel object=callback targetBeanName=resultName targetType=resultType/>
|
||||
<#if !callback_has_next>
|
||||
@ -61,17 +61,32 @@
|
||||
</#if>
|
||||
</#list>
|
||||
<#if resultType.arrayType>
|
||||
int ${index1Name} = 0;
|
||||
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
||||
<#if existingInstanceMapping>
|
||||
if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= <@iterableSize/> ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
</#if>
|
||||
<@includeModel object=elementAssignment targetWriteAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>
|
||||
${index1Name}++;
|
||||
}
|
||||
<#else>
|
||||
<#if true>
|
||||
<#-- <#if resultType.arrayType>-->
|
||||
<#-- int ${index1Name} = 0;-->
|
||||
<#-- 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} ) {
|
||||
<#if hasIterableConditionMethod()>
|
||||
if ( <@includeModel object=iterableConditionMethodReference /> ) {
|
||||
@ -90,8 +105,12 @@
|
||||
</#list>
|
||||
|
||||
<#if returnType.name != "void">
|
||||
<#if hasIterableConditionMethod() && resultType.arrayType>
|
||||
${resultName}.toArray( new <@includeModel object=resultElementType/>[0] );
|
||||
<#else>
|
||||
return ${resultName};
|
||||
</#if>
|
||||
</#if>
|
||||
}
|
||||
<#macro throws>
|
||||
<#if (thrownTypes?size > 0)><#lt> throws </#if><@compress single_line=true>
|
||||
|
@ -27,7 +27,14 @@ public interface IterableElementConditionMapper {
|
||||
@Mapping(target = "ssid", source = "uniqueIdNumber")
|
||||
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
|
||||
default boolean countryIsNotNull(EmployeeDto value) {
|
||||
|
@ -6,7 +6,9 @@
|
||||
package org.mapstruct.ap.test.conditional.iterable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.mapstruct.ap.test.conditional.Employee;
|
||||
import org.mapstruct.ap.test.conditional.EmployeeDto;
|
||||
@ -22,16 +24,58 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@IssueKey("1610")
|
||||
@WithClasses({
|
||||
Employee.class,
|
||||
EmployeeDto.class
|
||||
EmployeeDto.class,
|
||||
IterableElementConditionMapper.class,
|
||||
})
|
||||
public class IterableElementConditionTest {
|
||||
|
||||
@ProcessorTest
|
||||
@WithClasses({
|
||||
IterableElementConditionMapper.class
|
||||
})
|
||||
public void conditionalMethodWithSourceParameter() {
|
||||
IterableElementConditionMapper mapper = IterableElementConditionMapper.INSTANCE;
|
||||
public void conditionalMethodListToList() {
|
||||
|
||||
List<Employee> result = IterableElementConditionMapper.INSTANCE.mapListToList( setupList() );
|
||||
|
||||
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();
|
||||
dtoWithoutCountry.setName( "Tester" );
|
||||
@ -47,13 +91,11 @@ public class IterableElementConditionTest {
|
||||
employees.add( dtoWithoutCountry );
|
||||
employees.add( dtoWithCountry );
|
||||
|
||||
List<Employee> result = mapper.map( employees );
|
||||
assertThat( result )
|
||||
.singleElement()
|
||||
.satisfies(
|
||||
d -> assertThat(d.getName()).isEqualTo( "Tester" )
|
||||
);
|
||||
return employees;
|
||||
}
|
||||
|
||||
private static EmployeeDto[] setupArray() {
|
||||
return setupList().toArray( new EmployeeDto[0] );
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user