highly WIP

This commit is contained in:
thunderhook 2024-09-22 22:24:10 +02:00
parent 30651b989b
commit d9566bab76
3 changed files with 57 additions and 7 deletions

View File

@ -5,8 +5,7 @@
*/
package org.mapstruct.ap.internal.model;
import static org.mapstruct.ap.internal.util.Collections.first;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@ -14,10 +13,13 @@ import java.util.Set;
import org.mapstruct.ap.internal.model.assignment.LocalVarWrapper;
import org.mapstruct.ap.internal.model.assignment.SetterWrapper;
import org.mapstruct.ap.internal.model.common.Assignment;
import org.mapstruct.ap.internal.model.common.ParameterBinding;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SelectionParameters;
import static org.mapstruct.ap.internal.util.Collections.first;
/**
* A {@link MappingMethod} implemented by a {@link Mapper} class which maps one iterable type to another. The collection
* elements are mapped either by a {@link TypeConversion} or another mapping method.
@ -26,12 +28,21 @@ import org.mapstruct.ap.internal.model.source.SelectionParameters;
*/
public class IterableMappingMethod extends ContainerMappingMethod {
private Method iterableConditionMethod;
public static class Builder extends ContainerMappingMethodBuilder<Builder, IterableMappingMethod> {
private Method iterableConditionMethod;
public Builder() {
super( Builder.class, "collection element" );
}
public Builder iterableConditionMethod(Method iterableConditionMethod) {
this.iterableConditionMethod = iterableConditionMethod;
return this;
}
@Override
protected Type getElementType(Type parameterType) {
return parameterType.isArrayType() ? parameterType.getComponentType() : first(
@ -65,17 +76,43 @@ public class IterableMappingMethod extends ContainerMappingMethod {
loopVariableName,
beforeMappingMethods,
afterMappingMethods,
selectionParameters
selectionParameters,
iterableConditionMethod
);
}
}
public boolean hasIterableConditionMethod() {
return getIterableConditionMethod() != null;
}
public Method getIterableConditionMethod() {
return iterableConditionMethod;
}
public MethodReference getIterableConditionMethodReference() {
ArrayList<ParameterBinding> parameterBindings = new ArrayList<>();
parameterBindings.add(
ParameterBinding.fromTypeAndName(
iterableConditionMethod.getParameters().get( 0 ).getType(),
getLoopVariableName()
)
);
return MethodReference.forForgedMethod(
iterableConditionMethod,
parameterBindings
);
}
private IterableMappingMethod(Method method, List<Annotation> annotations,
Collection<String> existingVariables, Assignment parameterAssignment,
MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName,
List<LifecycleCallbackMethodReference> beforeMappingReferences,
List<LifecycleCallbackMethodReference> afterMappingReferences,
SelectionParameters selectionParameters) {
SelectionParameters selectionParameters, Method iterableConditionMethod) {
super(
method,
annotations,
@ -88,6 +125,7 @@ public class IterableMappingMethod extends ContainerMappingMethod {
afterMappingReferences,
selectionParameters
);
this.iterableConditionMethod = iterableConditionMethod;
}
@Override

View File

@ -25,6 +25,7 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import org.mapstruct.ap.internal.gem.BuilderGem;
import org.mapstruct.ap.internal.gem.ConditionStrategyGem;
import org.mapstruct.ap.internal.gem.DecoratedWithGem;
import org.mapstruct.ap.internal.gem.InheritConfigurationGem;
import org.mapstruct.ap.internal.gem.InheritInverseConfigurationGem;
@ -340,10 +341,18 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
this.messager.note( 1, Message.ITERABLEMAPPING_CREATE_NOTE, method );
Method iterableConditionMethod = methods.stream()
.filter( m -> m.getConditionOptions()
.isStrategyApplicable( ConditionStrategyGem.ITERABLE_ELEMENTS ) )
.findFirst()
.orElse( null );
// TODO here are all methods - select them via MethodResolver (like PresenceCheckMethodResolver) and add it to the builder
IterableMappingMethod iterableMappingMethod = createWithElementMappingMethod(
method,
mappingOptions,
new IterableMappingMethod.Builder()
.iterableConditionMethod( iterableConditionMethod )
);
hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;

View File

@ -24,7 +24,6 @@
<#if resultType.arrayType>
<#if existingInstanceMapping>
<#-- we can't clear an existing array, so we've got to clear by setting values to default -->
// test
${resultName}[${index2Name}] = ${resultElementType.null};
}
return<#if returnType.name != "void"> ${resultName}</#if>;
@ -74,9 +73,13 @@
}
<#else>
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
if ( countryIsNotNull( employeeDto ) ) {
<#if hasIterableConditionMethod()>
if ( <@includeModel object=iterableConditionMethodReference /> ) {
<@includeModel object=elementAssignment targetBeanName=resultName targetWriteAccessorName="add" targetType=resultElementType/>
}
}
<#else>
<@includeModel object=elementAssignment targetBeanName=resultName targetWriteAccessorName="add" targetType=resultElementType/>
</#if>
}
</#if>
<#list afterMappingReferences as callback>