org.mapstruct.ap.internal.model.LifecycleMethodResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapstruct-processor Show documentation
Show all versions of mapstruct-processor Show documentation
An annotation processor for generating type-safe bean mappers
/*
* 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.internal.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods;
import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.model.source.SourceMethod;
import org.mapstruct.ap.internal.model.source.selector.MethodSelectors;
import org.mapstruct.ap.internal.model.source.selector.SelectedMethod;
import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria;
/**
* Factory for creating lists of appropriate {@link LifecycleCallbackMethodReference}s
*
* @author Andreas Gudian
*/
public final class LifecycleMethodResolver {
private LifecycleMethodResolver() {
}
/**
* @param method the method to obtain the beforeMapping methods for
* @param alternativeTarget alternative to {@link Method#getResultType()} e.g. when target is abstract
* @param selectionParameters method selectionParameters
* @param ctx the builder context
* @param existingVariableNames the existing variable names in the mapping method
* @return all applicable {@code @BeforeMapping} methods for the given method
*/
public static List beforeMappingMethods(Method method,
Type alternativeTarget,
SelectionParameters selectionParameters,
MappingBuilderContext ctx,
Set existingVariableNames) {
return collectLifecycleCallbackMethods( method,
alternativeTarget,
selectionParameters,
filterBeforeMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ),
ctx,
existingVariableNames );
}
/**
* @param method the method to obtain the afterMapping methods for
* @param alternativeTarget alternative to {@link Method#getResultType()} e.g. when target is abstract
* @param selectionParameters method selectionParameters
* @param ctx the builder context
* @param existingVariableNames list of already used variable names
* @return all applicable {@code @AfterMapping} methods for the given method
*/
public static List afterMappingMethods(Method method,
Type alternativeTarget,
SelectionParameters selectionParameters,
MappingBuilderContext ctx,
Set existingVariableNames) {
return collectLifecycleCallbackMethods( method,
alternativeTarget,
selectionParameters,
filterAfterMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ),
ctx,
existingVariableNames );
}
/**
* @param method the method to obtain the beforeMapping methods for
* @param selectionParameters method selectionParameters
* @param ctx the builder context
* @param existingVariableNames the existing variable names in the mapping method
* @return all applicable {@code @BeforeMapping} methods for the given method
*/
public static List beforeMappingMethods(Method method,
SelectionParameters selectionParameters,
MappingBuilderContext ctx,
Set existingVariableNames) {
return collectLifecycleCallbackMethods( method,
method.getResultType(),
selectionParameters,
filterBeforeMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ),
ctx,
existingVariableNames );
}
/**
* @param method the method to obtain the afterMapping methods for
* @param selectionParameters method selectionParameters
* @param ctx the builder context
* @param existingVariableNames list of already used variable names
* @return all applicable {@code @AfterMapping} methods for the given method
*/
public static List afterMappingMethods(Method method,
SelectionParameters selectionParameters,
MappingBuilderContext ctx,
Set existingVariableNames) {
return collectLifecycleCallbackMethods( method,
method.getResultType(),
selectionParameters,
filterAfterMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ),
ctx,
existingVariableNames );
}
private static List getAllAvailableMethods(Method method, List sourceModelMethods) {
ParameterProvidedMethods contextProvidedMethods = method.getContextProvidedMethods();
if ( contextProvidedMethods.isEmpty() ) {
return sourceModelMethods;
}
List methodsProvidedByParams = contextProvidedMethods
.getAllProvidedMethodsInParameterOrder( method.getContextParameters() );
List availableMethods =
new ArrayList<>( methodsProvidedByParams.size() + sourceModelMethods.size() );
availableMethods.addAll( methodsProvidedByParams );
availableMethods.addAll( sourceModelMethods );
return availableMethods;
}
private static List collectLifecycleCallbackMethods(
Method method, Type targetType, SelectionParameters selectionParameters, List callbackMethods,
MappingBuilderContext ctx, Set existingVariableNames) {
MethodSelectors selectors =
new MethodSelectors( ctx.getTypeUtils(), ctx.getElementUtils(), ctx.getTypeFactory(), ctx.getMessager() );
List> matchingMethods = selectors.getMatchingMethods(
method,
callbackMethods,
Collections.emptyList(),
targetType,
SelectionCriteria.forLifecycleMethods( selectionParameters ) );
return toLifecycleCallbackMethodRefs(
method,
matchingMethods,
ctx,
existingVariableNames );
}
private static List toLifecycleCallbackMethodRefs(Method method,
List> candidates,
MappingBuilderContext ctx,
Set existingVariableNames) {
List result = new ArrayList<>();
for ( SelectedMethod candidate : candidates ) {
Parameter providingParameter =
method.getContextProvidedMethods().getParameterForProvidedMethod( candidate.getMethod() );
if ( providingParameter != null ) {
result.add( LifecycleCallbackMethodReference.forParameterProvidedMethod(
candidate,
providingParameter,
method,
existingVariableNames ) );
}
else {
MapperReference mapperReference = MapperReference.findMapperReference(
ctx.getMapperReferences(),
candidate.getMethod() );
result.add( LifecycleCallbackMethodReference.forMethodReference(
candidate,
mapperReference,
method,
existingVariableNames ) );
}
}
return result;
}
private static List filterBeforeMappingMethods(List methods) {
return methods.stream()
.filter( SourceMethod::isBeforeMappingMethod )
.collect( Collectors.toList() );
}
private static List filterAfterMappingMethods(List methods) {
return methods.stream()
.filter( SourceMethod::isAfterMappingMethod )
.collect( Collectors.toList() );
}
}