mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
highly WIP
This commit is contained in:
parent
30651b989b
commit
d9566bab76
@ -5,8 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.model;
|
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.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
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.LocalVarWrapper;
|
||||||
import org.mapstruct.ap.internal.model.assignment.SetterWrapper;
|
import org.mapstruct.ap.internal.model.assignment.SetterWrapper;
|
||||||
import org.mapstruct.ap.internal.model.common.Assignment;
|
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.common.Type;
|
||||||
import org.mapstruct.ap.internal.model.source.Method;
|
import org.mapstruct.ap.internal.model.source.Method;
|
||||||
import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
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
|
* 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.
|
* 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 {
|
public class IterableMappingMethod extends ContainerMappingMethod {
|
||||||
|
|
||||||
|
private Method iterableConditionMethod;
|
||||||
|
|
||||||
public static class Builder extends ContainerMappingMethodBuilder<Builder, IterableMappingMethod> {
|
public static class Builder extends ContainerMappingMethodBuilder<Builder, IterableMappingMethod> {
|
||||||
|
|
||||||
|
private Method iterableConditionMethod;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super( Builder.class, "collection element" );
|
super( Builder.class, "collection element" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder iterableConditionMethod(Method iterableConditionMethod) {
|
||||||
|
this.iterableConditionMethod = iterableConditionMethod;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Type getElementType(Type parameterType) {
|
protected Type getElementType(Type parameterType) {
|
||||||
return parameterType.isArrayType() ? parameterType.getComponentType() : first(
|
return parameterType.isArrayType() ? parameterType.getComponentType() : first(
|
||||||
@ -65,17 +76,43 @@ public class IterableMappingMethod extends ContainerMappingMethod {
|
|||||||
loopVariableName,
|
loopVariableName,
|
||||||
beforeMappingMethods,
|
beforeMappingMethods,
|
||||||
afterMappingMethods,
|
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,
|
private IterableMappingMethod(Method method, List<Annotation> annotations,
|
||||||
Collection<String> existingVariables, Assignment parameterAssignment,
|
Collection<String> existingVariables, Assignment parameterAssignment,
|
||||||
MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName,
|
MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName,
|
||||||
List<LifecycleCallbackMethodReference> beforeMappingReferences,
|
List<LifecycleCallbackMethodReference> beforeMappingReferences,
|
||||||
List<LifecycleCallbackMethodReference> afterMappingReferences,
|
List<LifecycleCallbackMethodReference> afterMappingReferences,
|
||||||
SelectionParameters selectionParameters) {
|
SelectionParameters selectionParameters, Method iterableConditionMethod) {
|
||||||
super(
|
super(
|
||||||
method,
|
method,
|
||||||
annotations,
|
annotations,
|
||||||
@ -88,6 +125,7 @@ public class IterableMappingMethod extends ContainerMappingMethod {
|
|||||||
afterMappingReferences,
|
afterMappingReferences,
|
||||||
selectionParameters
|
selectionParameters
|
||||||
);
|
);
|
||||||
|
this.iterableConditionMethod = iterableConditionMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,6 +25,7 @@ import javax.lang.model.type.TypeMirror;
|
|||||||
import javax.lang.model.util.ElementFilter;
|
import javax.lang.model.util.ElementFilter;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.gem.BuilderGem;
|
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.DecoratedWithGem;
|
||||||
import org.mapstruct.ap.internal.gem.InheritConfigurationGem;
|
import org.mapstruct.ap.internal.gem.InheritConfigurationGem;
|
||||||
import org.mapstruct.ap.internal.gem.InheritInverseConfigurationGem;
|
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 );
|
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(
|
IterableMappingMethod iterableMappingMethod = createWithElementMappingMethod(
|
||||||
method,
|
method,
|
||||||
mappingOptions,
|
mappingOptions,
|
||||||
new IterableMappingMethod.Builder()
|
new IterableMappingMethod.Builder()
|
||||||
|
.iterableConditionMethod( iterableConditionMethod )
|
||||||
);
|
);
|
||||||
|
|
||||||
hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;
|
hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
<#if resultType.arrayType>
|
<#if resultType.arrayType>
|
||||||
<#if existingInstanceMapping>
|
<#if existingInstanceMapping>
|
||||||
<#-- we can't clear an existing array, so we've got to clear by setting values to default -->
|
<#-- we can't clear an existing array, so we've got to clear by setting values to default -->
|
||||||
// test
|
|
||||||
${resultName}[${index2Name}] = ${resultElementType.null};
|
${resultName}[${index2Name}] = ${resultElementType.null};
|
||||||
}
|
}
|
||||||
return<#if returnType.name != "void"> ${resultName}</#if>;
|
return<#if returnType.name != "void"> ${resultName}</#if>;
|
||||||
@ -74,9 +73,13 @@
|
|||||||
}
|
}
|
||||||
<#else>
|
<#else>
|
||||||
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
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/>
|
<@includeModel object=elementAssignment targetBeanName=resultName targetWriteAccessorName="add" targetType=resultElementType/>
|
||||||
}
|
}
|
||||||
|
<#else>
|
||||||
|
<@includeModel object=elementAssignment targetBeanName=resultName targetWriteAccessorName="add" targetType=resultElementType/>
|
||||||
|
</#if>
|
||||||
}
|
}
|
||||||
</#if>
|
</#if>
|
||||||
<#list afterMappingReferences as callback>
|
<#list afterMappingReferences as callback>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user