From ac356cab2529e1ab71205e2f9389686fe3b303c3 Mon Sep 17 00:00:00 2001 From: Orange Add <48479242+chenzijia12300@users.noreply.github.com> Date: Sun, 28 Aug 2022 18:33:46 +0800 Subject: [PATCH] #2983 Add `@AnnotateWith` support to non bean mapping methods --- .../model/AbstractMappingMethodBuilder.java | 14 ++++++ .../ap/internal/model/BeanMappingMethod.java | 16 +------ .../model/ContainerMappingMethod.java | 5 +- .../internal/model/IterableMappingMethod.java | 5 +- .../ap/internal/model/MapMappingMethod.java | 6 ++- .../model/NormalTypeMappingMethod.java | 13 +++++- .../internal/model/StreamMappingMethod.java | 21 +++++---- .../ap/internal/model/ValueMappingMethod.java | 20 +++++++- .../internal/model/IterableMappingMethod.ftl | 3 ++ .../ap/internal/model/MapMappingMethod.ftl | 3 ++ .../ap/internal/model/StreamMappingMethod.ftl | 3 ++ .../ap/internal/model/ValueMappingMethod.ftl | 3 ++ .../AnnotateBeanMappingMethodMapper.java | 46 +++++++++++++++++++ .../AnnotateIterableMappingMethodMapper.java | 21 +++++++++ .../AnnotateMapMappingMethodMapper.java | 24 ++++++++++ .../AnnotateStreamMappingMethodMapper.java | 21 +++++++++ .../AnnotateValueMappingMethodMapper.java | 26 +++++++++++ .../test/annotatewith/AnnotateWithTest.java | 46 ++++++++++++++++++- 18 files changed, 264 insertions(+), 32 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java index efc7a7146..6efb67ba9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java @@ -13,6 +13,9 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.util.Strings; +import java.util.ArrayList; +import java.util.List; + /** * An abstract builder that can be reused for building {@link MappingMethod}(s). * @@ -117,4 +120,15 @@ public abstract class AbstractMappingMethodBuilder getMethodAnnotations() { + AdditionalAnnotationsBuilder additionalAnnotationsBuilder = + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() ); + List annotations = new ArrayList<>(); + annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); + return annotations; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index e748c173a..4f2dc4e5f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -85,7 +85,6 @@ import static org.mapstruct.ap.internal.util.Message.PROPERTYMAPPING_CANNOT_DETE */ public class BeanMappingMethod extends NormalTypeMappingMethod { - private final List annotations; private final List propertyMappings; private final Map> mappingsByParameter; private final Map> constructorMappingsByParameter; @@ -113,7 +112,6 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final Set unprocessedSourceParameters = new HashSet<>(); private final Set existingVariableNames = new HashSet<>(); private final Map> unprocessedDefinedTargets = new LinkedHashMap<>(); - private final List annotations = new ArrayList<>(); private MappingReferences mappingReferences; private MethodReference factoryMethod; @@ -216,12 +214,6 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { // If the return type cannot be constructed then no need to try to create mappings return null; } - AdditionalAnnotationsBuilder additionalAnnotationsBuilder = - new AdditionalAnnotationsBuilder( - ctx.getElementUtils(), - ctx.getTypeFactory(), - ctx.getMessager() ); - annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); /* the type that needs to be used in the mapping process as target */ Type resultTypeToMap = returnTypeToConstruct == null ? method.getResultType() : returnTypeToConstruct; @@ -370,7 +362,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { return new BeanMappingMethod( method, - annotations, + getMethodAnnotations(), existingVariableNames, propertyMappings, factoryMethod, @@ -1724,6 +1716,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { List subclassMappings) { super( method, + annotations, existingVariableNames, factoryMethod, mapNullToDefault, @@ -1732,7 +1725,6 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { ); //CHECKSTYLE:ON - this.annotations = annotations; this.propertyMappings = propertyMappings; this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; @@ -1771,10 +1763,6 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { this.subclassMappings = subclassMappings; } - public List getAnnotations() { - return annotations; - } - public List getConstantMappings() { return constantMappings; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java index 382aff973..21e547eea 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java @@ -32,12 +32,13 @@ public abstract class ContainerMappingMethod extends NormalTypeMappingMethod { private final String index2Name; private IterableCreation iterableCreation; - ContainerMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + ContainerMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, SelectionParameters selectionParameters) { - super( method, existingVariables, factoryMethod, mapNullToDefault, beforeMappingReferences, + super( method, annotations, existingVariables, factoryMethod, mapNullToDefault, beforeMappingReferences, afterMappingReferences ); this.elementAssignment = parameterAssignment; this.loopVariableName = loopVariableName; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java index 38ec44f1e..10e64b700 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java @@ -57,6 +57,7 @@ public class IterableMappingMethod extends ContainerMappingMethod { List afterMappingMethods, SelectionParameters selectionParameters) { return new IterableMappingMethod( method, + getMethodAnnotations(), existingVariables, assignment, factoryMethod, @@ -69,13 +70,15 @@ public class IterableMappingMethod extends ContainerMappingMethod { } } - private IterableMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + private IterableMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, SelectionParameters selectionParameters) { super( method, + annotations, existingVariables, parameterAssignment, factoryMethod, diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java index a8b68b435..85766e2ec 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java @@ -199,6 +199,7 @@ public class MapMappingMethod extends NormalTypeMappingMethod { return new MapMappingMethod( method, + getMethodAnnotations(), existingVariables, keyAssignment, valueAssignment, @@ -224,11 +225,12 @@ public class MapMappingMethod extends NormalTypeMappingMethod { } - private MapMappingMethod(Method method, Collection existingVariableNames, Assignment keyAssignment, + private MapMappingMethod(Method method, List annotations, + Collection existingVariableNames, Assignment keyAssignment, Assignment valueAssignment, MethodReference factoryMethod, boolean mapNullToDefault, List beforeMappingReferences, List afterMappingReferences) { - super( method, existingVariableNames, factoryMethod, mapNullToDefault, beforeMappingReferences, + super( method, annotations, existingVariableNames, factoryMethod, mapNullToDefault, beforeMappingReferences, afterMappingReferences ); this.keyAssignment = keyAssignment; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java index fcd8d70d5..79cd0e056 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java @@ -24,7 +24,10 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { private final boolean overridden; private final boolean mapNullToDefault; - NormalTypeMappingMethod(Method method, Collection existingVariableNames, MethodReference factoryMethod, + private final List annotations; + + NormalTypeMappingMethod(Method method, List annotations, + Collection existingVariableNames, MethodReference factoryMethod, boolean mapNullToDefault, List beforeMappingReferences, List afterMappingReferences) { @@ -32,6 +35,7 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { this.factoryMethod = factoryMethod; this.overridden = method.overridesMethod(); this.mapNullToDefault = mapNullToDefault; + this.annotations = annotations; } @Override @@ -45,6 +49,9 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { else if ( factoryMethod != null ) { types.addAll( factoryMethod.getImportTypes() ); } + for ( Annotation annotation : annotations ) { + types.addAll( annotation.getImportTypes() ); + } return types; } @@ -60,6 +67,10 @@ public abstract class NormalTypeMappingMethod extends MappingMethod { return this.factoryMethod; } + public List getAnnotations() { + return annotations; + } + @Override public int hashCode() { final int prime = 31; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java index 552040d8c..57ee9ccdf 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java @@ -5,6 +5,12 @@ */ package org.mapstruct.ap.internal.model; +import org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper; +import org.mapstruct.ap.internal.model.common.Assignment; +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 java.util.Collection; import java.util.HashSet; import java.util.List; @@ -13,12 +19,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper; -import org.mapstruct.ap.internal.model.common.Assignment; -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; /** @@ -63,9 +63,9 @@ public class StreamMappingMethod extends ContainerMappingMethod { sourceParameterType.isIterableType() ) { helperImports.add( ctx.getTypeFactory().getType( StreamSupport.class ) ); } - return new StreamMappingMethod( method, + getMethodAnnotations(), existingVariables, assignment, factoryMethod, @@ -78,14 +78,16 @@ public class StreamMappingMethod extends ContainerMappingMethod { ); } } - - private StreamMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + //CHECKSTYLE:OFF + private StreamMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, SelectionParameters selectionParameters, Set helperImports) { super( method, + annotations, existingVariables, parameterAssignment, factoryMethod, @@ -95,6 +97,7 @@ public class StreamMappingMethod extends ContainerMappingMethod { afterMappingReferences, selectionParameters ); + //CHECKSTYLE:ON this.helperImports = helperImports; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java index 0d71ed550..f61e80c2d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java @@ -41,6 +41,7 @@ import static org.mapstruct.ap.internal.util.Collections.first; */ public class ValueMappingMethod extends MappingMethod { + private final List annotations; private final List valueMappings; private final MappingEntry defaultTarget; private final MappingEntry nullTarget; @@ -116,9 +117,16 @@ public class ValueMappingMethod extends MappingMethod { LifecycleMethodResolver.beforeMappingMethods( method, selectionParameters, ctx, existingVariables ); List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( method, selectionParameters, ctx, existingVariables ); - + AdditionalAnnotationsBuilder additionalAnnotationsBuilder = + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() ); + List annotations = new ArrayList<>(); + annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); // finally return a mapping return new ValueMappingMethod( method, + annotations, mappingEntries, valueMappings.nullValueTarget, valueMappings.defaultTargetValue, @@ -532,6 +540,7 @@ public class ValueMappingMethod extends MappingMethod { } private ValueMappingMethod(Method method, + List annotations, List enumMappings, String nullTarget, String defaultTarget, @@ -544,6 +553,7 @@ public class ValueMappingMethod extends MappingMethod { this.defaultTarget = new MappingEntry( null, defaultTarget != null ? defaultTarget : THROW_EXCEPTION); this.unexpectedValueMappingException = unexpectedValueMappingException; this.overridden = method.overridesMethod(); + this.annotations = annotations; } @Override @@ -556,7 +566,9 @@ public class ValueMappingMethod extends MappingMethod { importTypes.addAll( unexpectedValueMappingException.getImportTypes() ); } } - + for ( Annotation annotation : annotations ) { + importTypes.addAll( annotation.getImportTypes() ); + } return importTypes; } @@ -590,6 +602,10 @@ public class ValueMappingMethod extends MappingMethod { return overridden; } + public List getAnnotations() { + return annotations; + } + public static class MappingEntry { private final String source; private final String target; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 495111b7a..9af6e762b 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -6,6 +6,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#if overridden>@Override <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index 443d87cba..0e388da10 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -6,6 +6,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#if overridden>@Override <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index 860859fc3..7b5b44bd5 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -6,6 +6,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#if overridden>@Override <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl index 4d961c40a..2c3e2b641 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl @@ -6,6 +6,9 @@ --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ValueMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#if overridden>@Override <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { <#list beforeMappingReferencesWithoutMappingTarget as callback> diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java new file mode 100644 index 000000000..cc19c2d28 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java @@ -0,0 +1,46 @@ +/* + * 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.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateBeanMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Target map(Source source); + + class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java new file mode 100644 index 000000000..40c6e60fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java @@ -0,0 +1,21 @@ +/* + * 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.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +import java.util.List; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateIterableMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + List toStringList(List integers); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java new file mode 100644 index 000000000..458cb68d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java @@ -0,0 +1,24 @@ +/* + * 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.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; + +import java.util.Date; +import java.util.Map; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateMapMappingMethodMapper { + + @MapMapping(valueDateFormat = "dd.MM.yyyy") + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Map longDateMapToStringStringMap(Map source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java new file mode 100644 index 000000000..c574b5969 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java @@ -0,0 +1,21 @@ +/* + * 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.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +import java.util.stream.Stream; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateStreamMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Stream toStringStream(Stream integerStream); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java new file mode 100644 index 000000000..a9e7c7b51 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java @@ -0,0 +1,26 @@ +/* + * 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.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateValueMappingMethodMapper { + + @ValueMappings({ + @ValueMapping(target = "EXISTING", source = "EXISTING"), + @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "OTHER_EXISTING" ) + }) + @AnnotateWith(CustomMethodOnlyAnnotation.class) + AnnotateWithEnum map(String str); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java index c2055b4c5..31b8d8fad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java @@ -6,7 +6,6 @@ package org.mapstruct.ap.test.annotatewith; import org.junit.jupiter.api.extension.RegisterExtension; - import org.mapstruct.Mapper; import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.ProcessorTest; @@ -17,6 +16,11 @@ import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutco import org.mapstruct.ap.testutil.runner.GeneratedSource; import org.mapstruct.factory.Mappers; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -545,4 +549,44 @@ public class AnnotateWithTest { public void mapperWithIdenticalAnnotationRepeated() { } + @ProcessorTest + @WithClasses( {AnnotateBeanMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void beanMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateBeanMappingMethodMapper mapper = Mappers.getMapper( AnnotateBeanMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "map", AnnotateBeanMappingMethodMapper.Source.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateIterableMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void iterableMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateIterableMappingMethodMapper mapper = Mappers.getMapper( AnnotateIterableMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "toStringList", List.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateMapMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void mapMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateMapMappingMethodMapper mapper = Mappers.getMapper( AnnotateMapMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "longDateMapToStringStringMap", Map.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateStreamMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void streamMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateStreamMappingMethodMapper mapper = Mappers.getMapper( AnnotateStreamMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "toStringStream", Stream.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateValueMappingMethodMapper.class, AnnotateWithEnum.class, CustomMethodOnlyAnnotation.class} ) + public void valueMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateValueMappingMethodMapper mapper = Mappers.getMapper( AnnotateValueMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "map", String.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + }