Search in sources :

Example 1 with SourceMethod

use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.

the class QualifierSelector method getQualifierAnnotationMirrors.

private Set<AnnotationMirror> getQualifierAnnotationMirrors(Method candidate) {
    // retrieve annotations
    Set<AnnotationMirror> qualiferAnnotations = new HashSet<AnnotationMirror>();
    // first from the method itself
    SourceMethod candidateSM = (SourceMethod) candidate;
    List<? extends AnnotationMirror> methodAnnotations = candidateSM.getExecutable().getAnnotationMirrors();
    for (AnnotationMirror methodAnnotation : methodAnnotations) {
        addOnlyWhenQualifier(qualiferAnnotations, methodAnnotation);
    }
    // then from the mapper (if declared)
    Type mapper = candidate.getDeclaringMapper();
    if (mapper != null) {
        List<? extends AnnotationMirror> mapperAnnotations = mapper.getTypeElement().getAnnotationMirrors();
        for (AnnotationMirror mapperAnnotation : mapperAnnotations) {
            addOnlyWhenQualifier(qualiferAnnotations, mapperAnnotation);
        }
    }
    return qualiferAnnotations;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Type(org.mapstruct.ap.internal.model.common.Type) DeclaredType(javax.lang.model.type.DeclaredType) SourceMethod(org.mapstruct.ap.internal.model.source.SourceMethod) HashSet(java.util.HashSet)

Example 2 with SourceMethod

use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.

the class QualifierSelector method getMatchingMethods.

@Override
public <T extends Method> List<SelectedMethod<T>> getMatchingMethods(Method mappingMethod, List<SelectedMethod<T>> methods, List<Type> sourceTypes, Type targetType, SelectionCriteria criteria) {
    int numberOfQualifiersToMatch = 0;
    // Define some local collections and make sure that they are defined.
    List<TypeMirror> qualifierTypes = new ArrayList<TypeMirror>();
    if (criteria.getQualifiers() != null) {
        qualifierTypes.addAll(criteria.getQualifiers());
        numberOfQualifiersToMatch += criteria.getQualifiers().size();
    }
    List<String> qualfiedByNames = new ArrayList<String>();
    if (criteria.getQualifiedByNames() != null) {
        qualfiedByNames.addAll(criteria.getQualifiedByNames());
        numberOfQualifiersToMatch += criteria.getQualifiedByNames().size();
    }
    // add the mapstruct @Named annotation as annotation to look for
    if (!qualfiedByNames.isEmpty()) {
        qualifierTypes.add(namedAnnotationTypeMirror);
    }
    // Check there are qualfiers for this mapping: Mapping#qualifier or Mapping#qualfiedByName
    if (qualifierTypes.isEmpty()) {
        // When no qualifiers, disqualify all methods marked with a qualifier by removing them from the candidates
        List<SelectedMethod<T>> nonQualiferAnnotatedMethods = new ArrayList<SelectedMethod<T>>(methods.size());
        for (SelectedMethod<T> candidate : methods) {
            if (candidate.getMethod() instanceof SourceMethod) {
                Set<AnnotationMirror> qualifierAnnotations = getQualifierAnnotationMirrors(candidate.getMethod());
                if (qualifierAnnotations.isEmpty()) {
                    nonQualiferAnnotatedMethods.add(candidate);
                }
            } else {
                nonQualiferAnnotatedMethods.add(candidate);
            }
        }
        return nonQualiferAnnotatedMethods;
    } else {
        // Check all methods marked with qualfier (or methods in Mappers marked wiht a qualfier) for matches.
        List<SelectedMethod<T>> matches = new ArrayList<SelectedMethod<T>>(methods.size());
        for (SelectedMethod<T> candidate : methods) {
            if (!(candidate.getMethod() instanceof SourceMethod)) {
                continue;
            }
            // retrieve annotations
            Set<AnnotationMirror> qualifierAnnotationMirrors = getQualifierAnnotationMirrors(candidate.getMethod());
            // now count if all qualifiers are matched
            int matchingQualifierCounter = 0;
            for (AnnotationMirror qualifierAnnotationMirror : qualifierAnnotationMirrors) {
                for (TypeMirror qualifierType : qualifierTypes) {
                    // get the type of the annotation mirror.
                    DeclaredType qualifierAnnotationType = qualifierAnnotationMirror.getAnnotationType();
                    if (typeUtils.isSameType(qualifierType, qualifierAnnotationType)) {
                        // Match! we have an annotation which has the @Qualifer marker ( could be @Named as well )
                        if (typeUtils.isSameType(qualifierAnnotationType, namedAnnotationTypeMirror)) {
                            // Match! its an @Named, so do the additional check on name.
                            NamedPrism namedPrism = NamedPrism.getInstance(qualifierAnnotationMirror);
                            if (namedPrism.value() != null && qualfiedByNames.contains(namedPrism.value())) {
                                // Match! its an @Name and the value matches as well. Oh boy.
                                matchingQualifierCounter++;
                            }
                        } else {
                            // Match! its a self declared qualifer annoation (marked with @Qualifier)
                            matchingQualifierCounter++;
                        }
                        break;
                    }
                }
            }
            if (matchingQualifierCounter == numberOfQualifiersToMatch) {
                // Only if all qualifiers are matched with a qualifying annotation, add candidate
                matches.add(candidate);
            }
        }
        if (!matches.isEmpty()) {
            return matches;
        } else {
            return methods;
        }
    }
}
Also used : ArrayList(java.util.ArrayList) NamedPrism(org.mapstruct.ap.internal.prism.NamedPrism) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) SourceMethod(org.mapstruct.ap.internal.model.source.SourceMethod) DeclaredType(javax.lang.model.type.DeclaredType)

Example 3 with SourceMethod

use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.

the class MapperCreationProcessor method reportErrorWhenAmbigousReverseMapping.

private void reportErrorWhenAmbigousReverseMapping(List<SourceMethod> candidates, SourceMethod method, InheritInverseConfigurationPrism reversePrism) {
    List<String> candidateNames = new ArrayList<String>();
    for (SourceMethod candidate : candidates) {
        candidateNames.add(candidate.getName());
    }
    String name = reversePrism.name();
    if (name.isEmpty()) {
        messager.printMessage(method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_DUPLICATES, Strings.join(candidateNames, "(), "));
    } else {
        messager.printMessage(method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_INVALID_NAME, Strings.join(candidateNames, "(), "), name);
    }
}
Also used : ArrayList(java.util.ArrayList) SourceMethod(org.mapstruct.ap.internal.model.source.SourceMethod)

Example 4 with SourceMethod

use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.

the class MapperCreationProcessor method getMappingMethods.

private List<MappingMethod> getMappingMethods(MapperConfiguration mapperConfig, List<SourceMethod> methods) {
    List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>();
    for (SourceMethod method : methods) {
        if (!method.overridesMethod()) {
            continue;
        }
        mergeInheritedOptions(method, mapperConfig, methods, new ArrayList<SourceMethod>());
        MappingOptions mappingOptions = method.getMappingOptions();
        boolean hasFactoryMethod = false;
        if (method.isIterableMapping()) {
            IterableMappingMethod iterableMappingMethod = createWithElementMappingMethod(method, mappingOptions, new IterableMappingMethod.Builder());
            hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;
            mappingMethods.add(iterableMappingMethod);
        } else if (method.isMapMapping()) {
            MapMappingMethod.Builder builder = new MapMappingMethod.Builder();
            SelectionParameters keySelectionParameters = null;
            FormattingParameters keyFormattingParameters = null;
            SelectionParameters valueSelectionParameters = null;
            FormattingParameters valueFormattingParameters = null;
            NullValueMappingStrategyPrism nullValueMappingStrategy = null;
            if (mappingOptions.getMapMapping() != null) {
                keySelectionParameters = mappingOptions.getMapMapping().getKeySelectionParameters();
                keyFormattingParameters = mappingOptions.getMapMapping().getKeyFormattingParameters();
                valueSelectionParameters = mappingOptions.getMapMapping().getValueSelectionParameters();
                valueFormattingParameters = mappingOptions.getMapMapping().getValueFormattingParameters();
                nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy();
            }
            MapMappingMethod mapMappingMethod = builder.mappingContext(mappingContext).method(method).keyFormattingParameters(keyFormattingParameters).keySelectionParameters(keySelectionParameters).valueFormattingParameters(valueFormattingParameters).valueSelectionParameters(valueSelectionParameters).nullValueMappingStrategy(nullValueMappingStrategy).build();
            hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null;
            mappingMethods.add(mapMappingMethod);
        } else if (method.isValueMapping()) {
            // prefer value mappings over enum mapping
            ValueMappingMethod valueMappingMethod = new ValueMappingMethod.Builder().mappingContext(mappingContext).method(method).valueMappings(mappingOptions.getValueMappings()).build();
            mappingMethods.add(valueMappingMethod);
        } else if (method.isEnumMapping()) {
            messager.printMessage(method.getExecutable(), Message.ENUMMAPPING_DEPRECATED);
            EnumMappingMethod.Builder builder = new EnumMappingMethod.Builder();
            MappingMethod enumMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).build();
            if (enumMappingMethod != null) {
                mappingMethods.add(enumMappingMethod);
            }
        } else if (method.isStreamMapping()) {
            StreamMappingMethod streamMappingMethod = createWithElementMappingMethod(method, mappingOptions, new StreamMappingMethod.Builder());
            // If we do StreamMapping that means that internally there is a way to generate the result type
            hasFactoryMethod = streamMappingMethod.getFactoryMethod() != null || method.getResultType().isStreamType();
            mappingMethods.add(streamMappingMethod);
        } else {
            NullValueMappingStrategyPrism nullValueMappingStrategy = null;
            SelectionParameters selectionParameters = null;
            if (mappingOptions.getBeanMapping() != null) {
                nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy();
                selectionParameters = mappingOptions.getBeanMapping().getSelectionParameters();
            }
            BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
            BeanMappingMethod beanMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).nullValueMappingStrategy(nullValueMappingStrategy).selectionParameters(selectionParameters).build();
            if (beanMappingMethod != null) {
                // We can consider that the bean mapping method can always be constructed. If there is a problem
                // it would have been reported in its build
                hasFactoryMethod = true;
                mappingMethods.add(beanMappingMethod);
            }
        }
        if (!hasFactoryMethod) {
            // A factory method  is allowed to return an interface type and hence, the generated
            // implementation as well. The check below must only be executed if there's no factory
            // method that could be responsible.
            reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType(method);
        }
    }
    return mappingMethods;
}
Also used : MapMappingMethod(org.mapstruct.ap.internal.model.MapMappingMethod) ValueMappingMethod(org.mapstruct.ap.internal.model.ValueMappingMethod) ContainerMappingMethodBuilder(org.mapstruct.ap.internal.model.ContainerMappingMethodBuilder) MapMappingMethod(org.mapstruct.ap.internal.model.MapMappingMethod) EnumMappingMethod(org.mapstruct.ap.internal.model.EnumMappingMethod) IterableMappingMethod(org.mapstruct.ap.internal.model.IterableMappingMethod) ValueMappingMethod(org.mapstruct.ap.internal.model.ValueMappingMethod) MappingMethod(org.mapstruct.ap.internal.model.MappingMethod) StreamMappingMethod(org.mapstruct.ap.internal.model.StreamMappingMethod) ContainerMappingMethod(org.mapstruct.ap.internal.model.ContainerMappingMethod) BeanMappingMethod(org.mapstruct.ap.internal.model.BeanMappingMethod) ArrayList(java.util.ArrayList) NullValueMappingStrategyPrism(org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism) StreamMappingMethod(org.mapstruct.ap.internal.model.StreamMappingMethod) MappingOptions(org.mapstruct.ap.internal.model.source.MappingOptions) BeanMappingMethod(org.mapstruct.ap.internal.model.BeanMappingMethod) IterableMappingMethod(org.mapstruct.ap.internal.model.IterableMappingMethod) FormattingParameters(org.mapstruct.ap.internal.model.common.FormattingParameters) SelectionParameters(org.mapstruct.ap.internal.model.source.SelectionParameters) EnumMappingMethod(org.mapstruct.ap.internal.model.EnumMappingMethod) SourceMethod(org.mapstruct.ap.internal.model.source.SourceMethod)

Example 5 with SourceMethod

use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.

the class MapperCreationProcessor method reportErrorWhenAmbigousMapping.

private void reportErrorWhenAmbigousMapping(List<SourceMethod> candidates, SourceMethod method, InheritConfigurationPrism prism) {
    List<String> candidateNames = new ArrayList<String>();
    for (SourceMethod candidate : candidates) {
        candidateNames.add(candidate.getName());
    }
    String name = prism.name();
    if (name.isEmpty()) {
        messager.printMessage(method.getExecutable(), prism.mirror, Message.INHERITCONFIGURATION_DUPLICATES, Strings.join(candidateNames, "(), "));
    } else {
        messager.printMessage(method.getExecutable(), prism.mirror, Message.INHERITCONFIGURATION_INVALIDNAME, Strings.join(candidateNames, "(), "), name);
    }
}
Also used : ArrayList(java.util.ArrayList) SourceMethod(org.mapstruct.ap.internal.model.source.SourceMethod)

Aggregations

SourceMethod (org.mapstruct.ap.internal.model.source.SourceMethod)16 ArrayList (java.util.ArrayList)12 DeclaredType (javax.lang.model.type.DeclaredType)3 Parameter (org.mapstruct.ap.internal.model.common.Parameter)3 Type (org.mapstruct.ap.internal.model.common.Type)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 TypeElement (javax.lang.model.element.TypeElement)2 ExecutableType (javax.lang.model.type.ExecutableType)2 TypeMirror (javax.lang.model.type.TypeMirror)2 BeanMappingMethod (org.mapstruct.ap.internal.model.BeanMappingMethod)2 ContainerMappingMethod (org.mapstruct.ap.internal.model.ContainerMappingMethod)2 ContainerMappingMethodBuilder (org.mapstruct.ap.internal.model.ContainerMappingMethodBuilder)2 EnumMappingMethod (org.mapstruct.ap.internal.model.EnumMappingMethod)2 IterableMappingMethod (org.mapstruct.ap.internal.model.IterableMappingMethod)2 MapMappingMethod (org.mapstruct.ap.internal.model.MapMappingMethod)2 MappingMethod (org.mapstruct.ap.internal.model.MappingMethod)2 StreamMappingMethod (org.mapstruct.ap.internal.model.StreamMappingMethod)2