All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mapstruct.ap.internal.model.LifecycleMethodResolver Maven / Gradle / Ivy

There is a newer version: 1.6.3
Show newest version
/*
 * 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() );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy