From 68fc3af64554dfc3535f140145dfac15ef712ad9 Mon Sep 17 00:00:00 2001 From: Andreas Gudian Date: Sat, 4 Apr 2015 17:42:45 +0200 Subject: [PATCH] #14 Consider qualifiers when selecting @BeforeMapping/@AfterMapping methods --- .../mapstruct/ap/model/BeanMappingMethod.java | 4 +- .../ap/model/IterableMappingMethod.java | 4 +- .../ap/model/LifecycleCallbackFactory.java | 100 ++++++++++++++---- .../mapstruct/ap/model/MapMappingMethod.java | 4 +- .../source/selector/QualifierSelector.java | 10 +- .../ap/test/callbacks/BaseMapper.java | 37 ++++++- .../ap/test/callbacks/CallbackMethodTest.java | 44 +++++++- .../callbacks/ClassContainingCallbacks.java | 66 +++++++++--- .../ap/test/callbacks/Qualified.java | 30 ++++++ .../SourceTargetCollectionMapper.java | 4 + .../ap/test/callbacks/SourceTargetMapper.java | 4 + 11 files changed, 257 insertions(+), 50 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java diff --git a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java index d2b0c970f..78da09954 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java @@ -163,9 +163,9 @@ public class BeanMappingMethod extends MappingMethod { sortPropertyMappingsByDependencies(); List beforeMappingMethods = - LifecycleCallbackFactory.beforeMappingMethods( method, ctx ); + LifecycleCallbackFactory.beforeMappingMethods( method, qualifiers, ctx ); List afterMappingMethods = - LifecycleCallbackFactory.afterMappingMethods( method, ctx ); + LifecycleCallbackFactory.afterMappingMethods( method, qualifiers, ctx ); return new BeanMappingMethod( method, diff --git a/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java index 1088e1016..8cdf5a028 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java @@ -150,9 +150,9 @@ public class IterableMappingMethod extends MappingMethod { = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType(), null, null ); List beforeMappingMethods = - LifecycleCallbackFactory.beforeMappingMethods( method, ctx ); + LifecycleCallbackFactory.beforeMappingMethods( method, qualifiers, ctx ); List afterMappingMethods = - LifecycleCallbackFactory.afterMappingMethods( method, ctx ); + LifecycleCallbackFactory.afterMappingMethods( method, qualifiers, ctx ); return new IterableMappingMethod( method, diff --git a/processor/src/main/java/org/mapstruct/ap/model/LifecycleCallbackFactory.java b/processor/src/main/java/org/mapstruct/ap/model/LifecycleCallbackFactory.java index 4e8919c20..18c13b38a 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/LifecycleCallbackFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/model/LifecycleCallbackFactory.java @@ -19,14 +19,19 @@ package org.mapstruct.ap.model; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.model.common.Parameter; import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.source.Method; import org.mapstruct.ap.model.source.SourceMethod; +import org.mapstruct.ap.model.source.selector.QualifierSelector; +import org.mapstruct.ap.model.source.selector.SelectionCriteria; /** * Factory for creating lists of appropriate {@link LifecycleCallbackMethodReference}s @@ -40,27 +45,95 @@ public final class LifecycleCallbackFactory { /** * @param method the method to obtain the beforeMapping methods for + * @param qualifiers method qualifiers * @param ctx the builder context * @return all applicable {@code @BeforeMapping} methods for the given method */ public static List beforeMappingMethods( - Method method, MappingBuilderContext ctx) { - return collectLifecycleCallbackMethods( method, filterBeforeMappingMethods( ctx.getSourceModel() ), ctx ); + Method method, List qualifiers, MappingBuilderContext ctx) { + return collectLifecycleCallbackMethods( + method, + qualifiers, + filterBeforeMappingMethods( ctx.getSourceModel() ), + ctx ); } /** * @param method the method to obtain the afterMapping methods for + * @param qualifiers method qualifiers * @param ctx the builder context * @return all applicable {@code @AfterMapping} methods for the given method */ public static List afterMappingMethods( - Method method, MappingBuilderContext ctx) { - return collectLifecycleCallbackMethods( method, filterAfterMappingMethods( ctx.getSourceModel() ), ctx ); + Method method, List qualifiers, MappingBuilderContext ctx) { + return collectLifecycleCallbackMethods( + method, + qualifiers, + filterAfterMappingMethods( ctx.getSourceModel() ), + ctx ); } private static List collectLifecycleCallbackMethods( - Method method, List callbackMethods, MappingBuilderContext ctx) { + Method method, List qualifiers, List callbackMethods, MappingBuilderContext ctx) { + Map> parameterAssignmentsForSourceMethod = + new HashMap>(); + + List candidates = + filterCandidatesByType( method, callbackMethods, parameterAssignmentsForSourceMethod, ctx ); + + candidates = filterCandidatesByQualifiers( method, qualifiers, candidates, ctx ); + + return toLifecycleCallbackMethodRefs( candidates, parameterAssignmentsForSourceMethod, ctx ); + } + + private static List filterCandidatesByQualifiers(Method method, List qualifiers, + List candidates, + MappingBuilderContext ctx) { + QualifierSelector selector = new QualifierSelector( ctx.getTypeUtils(), ctx.getElementUtils() ); + + return selector.getMatchingMethods( method, candidates, null, null, new SelectionCriteria( + qualifiers, + null, + null, + false ) ); + } + + private static List toLifecycleCallbackMethodRefs( + List candidates, Map> parameterAssignmentsForSourceMethod, + MappingBuilderContext ctx) { + + List result = new ArrayList(); + for ( SourceMethod candidate : candidates ) { + markMapperReferenceAsUsed( ctx.getMapperReferences(), candidate ); + result.add( new LifecycleCallbackMethodReference( + candidate, + parameterAssignmentsForSourceMethod.get( candidate ) ) ); + } + return result; + } + + private static List filterCandidatesByType(Method method, + List callbackMethods, Map> parameterAssignmentsForSourceMethod, + MappingBuilderContext ctx) { + + List candidates = new ArrayList(); + + List availableParams = getAvailableParameters( method, ctx ); + for ( SourceMethod callback : callbackMethods ) { + List parameterAssignments = getParameterAssignments( availableParams, callback.getParameters() ); + + if ( parameterAssignments != null + && callback.matches( extractSourceTypes( parameterAssignments ), method.getResultType() ) ) { + + parameterAssignmentsForSourceMethod.put( callback, parameterAssignments ); + candidates.add( callback ); + } + } + return candidates; + } + + private static List getAvailableParameters(Method method, MappingBuilderContext ctx) { List availableParams = new ArrayList( method.getParameters() ); if ( method.getMappingTargetParameter() == null ) { availableParams.add( new Parameter( null, method.getResultType(), true, false ) ); @@ -73,23 +146,10 @@ public final class LifecycleCallbackFactory { true ); availableParams.add( targetTypeParameter ); - - List result = new ArrayList(); - - for ( SourceMethod callback : callbackMethods ) { - List parameterAssignments = getParameterAssignments( availableParams, callback.getParameters() ); - - if ( parameterAssignments != null - && callback.matches( extractSourceTypes( parameterAssignments ), method.getResultType() ) ) { - - markMapperReferenceAsUsed( ctx.getMapperReferences(), callback ); - result.add( new LifecycleCallbackMethodReference( callback, parameterAssignments ) ); - } - } - return result; + return availableParams; } - private static void markMapperReferenceAsUsed(List references, SourceMethod method) { + private static void markMapperReferenceAsUsed(List references, Method method) { for ( MapperReference ref : references ) { if ( ref.getType().equals( method.getDeclaringMapper() ) ) { ref.setUsed( !method.isStatic() ); diff --git a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java index 202cc01d1..8af6f9da4 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java @@ -192,9 +192,9 @@ public class MapMappingMethod extends MappingMethod { valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes() ); List beforeMappingMethods = - LifecycleCallbackFactory.beforeMappingMethods( method, ctx ); + LifecycleCallbackFactory.beforeMappingMethods( method, null, ctx ); List afterMappingMethods = - LifecycleCallbackFactory.afterMappingMethods( method, ctx ); + LifecycleCallbackFactory.afterMappingMethods( method, null, ctx ); return new MapMappingMethod( method, diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/QualifierSelector.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/QualifierSelector.java index 504021b56..a64a683d1 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/selector/QualifierSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/QualifierSelector.java @@ -34,16 +34,18 @@ import org.mapstruct.ap.model.source.SourceMethod; import org.mapstruct.ap.prism.QualifierPrism; /** - * This selector selects a best match based on qualifiers name. + * This selector selects a best match based on qualifier annotations. *

* A method is said to be marked with a qualifier annotation if the class in which it resides is annotated with a * qualifier annotation or if the method itself is annotated with a qualifier annotation or both. *

* Rules: *

    - *
  1. If a method is marked with a qualifier annotation, it does not contribute to a match otherwise and is hence - * removed from the list of potential mapping methods
  2. - *
  3. If multiple qualifiers (qualifedBy) are specified, all should match to make a match.
  4. + *
  5. If no qualifiers are requested in the selection criteria, then only candidate methods without any qualifier + * annotations remain in the list of potential candidates
  6. + *
  7. If multiple qualifiers (qualifedBy) are specified, then all of them need to be present at a candidate for it to + * match.
  8. + *
  9. If no candidate matches the required qualifiers, then all candidates are returned.
  10. *
* * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java index bebd543e0..52742d4db 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java @@ -46,16 +46,34 @@ public abstract class BaseMapper { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceBeforeMapping(List source) { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceBeforeMapping(Map source) { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceAsObjectBeforeMapping(Object source) { INVOCATIONS.add( new Invocation( "withSourceAsObjectBeforeMapping", source ) ); @@ -157,16 +175,34 @@ public abstract class BaseMapper { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAfterMapping(@MappingTarget List target) { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAfterMapping(@MappingTarget Map target) { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAsObjectAfterMapping(@MappingTarget Object target) { INVOCATIONS.add( new Invocation( "withTargetAsObjectAfterMapping", target ) ); @@ -184,5 +220,4 @@ public abstract class BaseMapper { public static void reset() { INVOCATIONS.clear(); } - } diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java index dcde75f6b..cb95c2738 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.fest.assertions.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,6 +34,8 @@ import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import static org.fest.assertions.Assertions.assertThat; + /** * Test for callback methods that are defined using {@link BeforeMapping} / {@link AfterMapping} * @@ -42,7 +43,7 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; */ @RunWith( AnnotationProcessorTestRunner.class ) @WithClasses( { ClassContainingCallbacks.class, Invocation.class, Source.class, Target.class, SourceTargetMapper.class, - SourceTargetCollectionMapper.class, BaseMapper.class } ) + SourceTargetCollectionMapper.class, BaseMapper.class, Qualified.class }) @IssueKey("14") public class CallbackMethodTest { @@ -103,12 +104,29 @@ public class CallbackMethodTest { assertMapMappingInvocations( BaseMapper.getInvocations() ); } + @Test + public void qualifiersAreEvaluatedCorrectly() { + Source source = createSource(); + Target target = SourceTargetMapper.INSTANCE.qualifiedSourceToTarget( source ); + + assertQualifiedInvocations( ClassContainingCallbacks.getInvocations(), source, target ); + assertQualifiedInvocations( BaseMapper.getInvocations(), source, target ); + + reset(); + + List sourceList = Arrays.asList( createSource() ); + List targetList = SourceTargetCollectionMapper.INSTANCE.qualifiedSourceToTarget( sourceList ); + + assertQualifiedInvocations( ClassContainingCallbacks.getInvocations(), sourceList, targetList ); + assertQualifiedInvocations( BaseMapper.getInvocations(), sourceList, targetList ); + } + private void assertBeanMappingInvocations(List invocations) { Source source = createSource(); Target target = createResultTarget(); Target emptyTarget = createEmptyTarget(); - Assertions.assertThat( invocations ).isEqualTo( beanMappingInvocationList( source, target, emptyTarget ) ); + assertThat( invocations ).isEqualTo( beanMappingInvocationList( source, target, emptyTarget ) ); } private void assertIterableMappingInvocations(List invocations) { @@ -168,7 +186,7 @@ public class CallbackMethodTest { expected.addAll( beanMappingInvocationList( source, target, emptyTarget ) ); expected.addAll( allAfterMappingMethods( sourceCollection, targetCollection, targetCollectionClass ) ); - Assertions.assertThat( invocations ).isEqualTo( expected ); + assertThat( invocations ).isEqualTo( expected ); } private List beanMappingInvocationList(Object source, Object target, Object emptyTarget) { @@ -202,6 +220,24 @@ public class CallbackMethodTest { new Invocation( "withTargetAsObjectBeforeMapping", emptyTarget ) ) ); } + private void assertQualifiedInvocations(List actual, Object source, Object target) { + assertThat( actual ).isEqualTo( allQualifiedCallbackMethods( source, target ) ); + } + + private List allQualifiedCallbackMethods(Object source, Object target) { + List invocations = new ArrayList(); + invocations.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + + if ( source instanceof List || source instanceof Map ) { + invocations.addAll( + beanMappingInvocationList( createSource(), createResultTarget(), createEmptyTarget() ) ); + } + + invocations.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + + return invocations; + } + private Source createSource() { Source source = new Source(); source.setFoo( "foo" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java index c3052f5e3..71c47e7e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java @@ -43,21 +43,54 @@ public class ClassContainingCallbacks { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceBeforeMapping(List source) { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceBeforeMapping(Map source) { INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); } + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + @BeforeMapping public void withSourceAsObjectBeforeMapping(Object source) { INVOCATIONS.add( new Invocation( "withSourceAsObjectBeforeMapping", source ) ); } + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Source source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(List source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Map source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + @BeforeMapping public void withSourceAndTargetBeforeMapping(Source source, @MappingTarget Target target) { INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); @@ -94,21 +127,6 @@ public class ClassContainingCallbacks { INVOCATIONS.add( new Invocation( "withTargetAsObjectBeforeMapping", target ) ); } - @BeforeMapping - public void withSourceAndTargetTypeBeforeMapping(Source source, @TargetType Class targetClass) { - INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); - } - - @BeforeMapping - public void withSourceAndTargetTypeBeforeMapping(List source, @TargetType Class targetClass) { - INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); - } - - @BeforeMapping - public void withSourceAndTargetTypeBeforeMapping(Map source, @TargetType Class targetClass) { - INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); - } - @AfterMapping public void noArgsAfterMapping() { INVOCATIONS.add( new Invocation( "noArgsAfterMapping" ) ); @@ -154,16 +172,34 @@ public class ClassContainingCallbacks { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAfterMapping(@MappingTarget List target) { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAfterMapping(@MappingTarget Map target) { INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); } + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + @AfterMapping public void withTargetAsObjectAfterMapping(@MappingTarget Object target) { INVOCATIONS.add( new Invocation( "withTargetAsObjectAfterMapping", target ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java new file mode 100644 index 000000000..3d6e78a97 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java @@ -0,0 +1,30 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.callbacks; + +import org.mapstruct.Qualifier; + +/** + * @author Andreas Gudian + * + */ +@Qualifier +public @interface Qualified { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java index 810c11a2a..f0eab4df1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java @@ -21,6 +21,7 @@ package org.mapstruct.ap.test.callbacks; import java.util.List; import java.util.Map; +import org.mapstruct.IterableMapping; import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.factory.Mappers; @@ -36,6 +37,9 @@ public abstract class SourceTargetCollectionMapper extends BaseMapper { public abstract void sourceToTarget(List source, @MappingTarget List target); + @IterableMapping(qualifiedBy = Qualified.class) + public abstract List qualifiedSourceToTarget(List source); + public abstract Map sourceToTarget(Map source); public abstract void sourceToTarget(Map source, @MappingTarget Map target); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java index a13d99605..96d713ec8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java @@ -18,6 +18,7 @@ */ package org.mapstruct.ap.test.callbacks; +import org.mapstruct.BeanMapping; import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.factory.Mappers; @@ -30,4 +31,7 @@ public abstract class SourceTargetMapper extends BaseMapper { public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); public abstract void sourceToTarget(Source source, @MappingTarget Target target); + + @BeanMapping(qualifiedBy = Qualified.class) + public abstract Target qualifiedSourceToTarget(Source source); }