diff --git a/core-common/src/main/java/org/mapstruct/InheritConfiguration.java b/core-common/src/main/java/org/mapstruct/InheritConfiguration.java
new file mode 100644
index 000000000..1f2a53fb3
--- /dev/null
+++ b/core-common/src/main/java/org/mapstruct/InheritConfiguration.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2012-2014 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Advises the code generator to apply all the {@link Mapping}s from a mapping method to the annotated method
+ * as well. The method should have the same source type and target type.
+ *
+ * A typical use case is annotating an update method (a method with the {@link MappingTarget} in which an existing
+ * target is updated) in order to copy all defined mappings.
+ *
+ * If more than one matching method exists, the name of the method to inherit the configuration from must be
+ * specified via {@link #name()}
+ *
+ * @author Sjaak Derksen
+ */
+@Target( ElementType.METHOD )
+@Retention( RetentionPolicy.SOURCE )
+public @interface InheritConfiguration {
+
+ /**
+ * The name of the mapping method to inherit the mappings from. Needs only to be specified in case more than
+ * one method with matching source and target type exists.
+ *
+ * @return The name of the mapping method to inherit the mappings from.
+ */
+ String name() default "";
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/model/source/SourceMethod.java
index 576baf676..17734ec91 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/source/SourceMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/source/SourceMethod.java
@@ -279,6 +279,14 @@ public class SourceMethod implements Method {
&& equals( getResultType(), method.getSourceParameters().iterator().next().getType() );
}
+
+ public boolean isSame(SourceMethod method) {
+ return getSourceParameters().size() == 1 && method.getSourceParameters().size() == 1
+ && equals( getSourceParameters().iterator().next().getType(),
+ method.getSourceParameters().iterator().next().getType())
+ && equals( getResultType(), method.getResultType() );
+ }
+
/**
* {@inheritDoc} {@link Method}
*/
@@ -405,13 +413,15 @@ public class SourceMethod implements Method {
/**
* Merges in all the mappings configured via the given inverse mapping method, giving the locally defined mappings
* precedence.
+ * @param inverseMethod
+ * @param templateMethod
*/
- public void mergeWithInverseMappings(SourceMethod inverseMethod) {
+ public void mergeWithInverseMappings(SourceMethod inverseMethod, SourceMethod templateMethod) {
Map> newMappings = new HashMap>();
if ( inverseMethod != null && !inverseMethod.getMappings().isEmpty() ) {
- for ( List mappings : inverseMethod.getMappings().values() ) {
- for ( Mapping inverseMapping : mappings ) {
+ for ( List lmappings : inverseMethod.getMappings().values() ) {
+ for ( Mapping inverseMapping : lmappings ) {
Mapping reversed = inverseMapping.reverse( this, messager, typeFactory );
if ( reversed != null ) {
List mappingsOfProperty = newMappings.get( reversed.getTargetName() );
@@ -425,6 +435,21 @@ public class SourceMethod implements Method {
}
}
+ if ( templateMethod != null && !templateMethod.getMappings().isEmpty() ) {
+ for ( List lmappings : templateMethod.getMappings().values() ) {
+ for ( Mapping templateMapping : lmappings ) {
+ if ( templateMapping != null ) {
+ List mappingsOfProperty = newMappings.get( templateMapping.getTargetName() );
+ if ( mappingsOfProperty == null ) {
+ mappingsOfProperty = new ArrayList();
+ newMappings.put( templateMapping.getTargetName(), mappingsOfProperty );
+ }
+ mappingsOfProperty.add( templateMapping );
+ }
+ }
+ }
+ }
+
if ( getMappings().isEmpty() ) {
// the mapping method is configuredByReverseMappingMethod, see SourceMethod#setMappings()
setMappings( newMappings );
diff --git a/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java b/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java
index 300cf8f97..9e062c4c5 100644
--- a/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java
+++ b/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java
@@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlElementDecl;
import net.java.dev.hickory.prism.GeneratePrism;
import net.java.dev.hickory.prism.GeneratePrisms;
import org.mapstruct.DecoratedWith;
+import org.mapstruct.InheritConfiguration;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.IterableMapping;
import org.mapstruct.MapMapping;
@@ -50,6 +51,7 @@ import org.mapstruct.TargetType;
@GeneratePrism(value = MappingTarget.class, publicAccess = true),
@GeneratePrism(value = DecoratedWith.class, publicAccess = true),
@GeneratePrism(value = MapperConfig.class, publicAccess = true),
+ @GeneratePrism(value = InheritConfiguration.class, publicAccess = true),
@GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true),
@GeneratePrism(value = Qualifier.class, publicAccess = true),
@GeneratePrism(value = NullValueMapping.class, publicAccess = true),
diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
index 4dbbf3e79..5f4c18b7d 100644
--- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
@@ -50,6 +50,7 @@ import org.mapstruct.ap.model.common.TypeFactory;
import org.mapstruct.ap.model.source.SourceMethod;
import org.mapstruct.ap.option.Options;
import org.mapstruct.ap.prism.DecoratedWithPrism;
+import org.mapstruct.ap.prism.InheritConfigurationPrism;
import org.mapstruct.ap.prism.InheritInverseConfigurationPrism;
import org.mapstruct.ap.prism.MapperPrism;
import org.mapstruct.ap.processor.creation.MappingResolverImpl;
@@ -247,14 +248,19 @@ public class MapperCreationProcessor implements ModelElementProcessor rawMethods, SourceMethod method) {
+ SourceMethod result = null;
+ InheritConfigurationPrism forwardPrism = InheritConfigurationPrism.getInstanceOn(
+ method.getExecutable()
+ );
+
+ if (forwardPrism != null) {
+ reportErrorWhenInheritForwardAlsoHasInheritReverseMapping( method );
+
+ // method is configured as being reverse method, collect candidates
+ List candidates = new ArrayList();
+ for ( SourceMethod oneMethod : rawMethods ) {
+ // method must be similar but not equal
+ if ( oneMethod.isSame( method ) && !( oneMethod.equals( method ) ) ) {
+ candidates.add( oneMethod );
+ }
+ }
+
+ String name = forwardPrism.name();
+ if ( candidates.size() == 1 ) {
+ // no ambiguity: if no configuredBy is specified, or configuredBy specified and match
+ if ( name.isEmpty() ) {
+ result = candidates.get( 0 );
+ }
+ else if ( candidates.get( 0 ).getName().equals( name ) ) {
+ result = candidates.get( 0 );
+ }
+ else {
+ reportErrorWhenNonMatchingName( candidates.get( 0 ), method, forwardPrism );
+ }
+ }
+ else if ( candidates.size() > 1 ) {
+ // ambiguity: find a matching method that matches configuredBy
+
+ List nameFilteredcandidates = new ArrayList();
+ for ( SourceMethod candidate : candidates ) {
+ if ( candidate.getName().equals( name ) ) {
+ nameFilteredcandidates.add( candidate );
+ }
+ }
+
+ if ( nameFilteredcandidates.size() == 1 ) {
+ result = nameFilteredcandidates.get( 0 );
+ }
+ else if ( nameFilteredcandidates.size() > 1 ) {
+ reportErrorWhenSeveralNamesMatch( nameFilteredcandidates, method, forwardPrism );
+ }
+
+ if ( result == null ) {
+ reportErrorWhenAmbigousMapping( candidates, method, forwardPrism );
+ }
+ }
+
+ if ( result != null ) {
+ reportErrorIfMethodHasAnnotation( result, method, forwardPrism );
+ }
+
+ }
+ return result;
+ }
+
+ private void reportErrorWhenInheritForwardAlsoHasInheritReverseMapping(SourceMethod method) {
+ InheritInverseConfigurationPrism reversePrism = InheritInverseConfigurationPrism.getInstanceOn(
+ method.getExecutable()
+ );
+ if ( reversePrism != null ) {
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ "Method cannot be annotated with both a @InheritConfiguration and @InheritInverseConfiguration",
+ method.getExecutable(),
+ reversePrism.mirror
+ );
+ }
+
+ }
+
private void reportErrorIfInverseMethodHasInheritAnnotation(SourceMethod candidate,
SourceMethod method,
InheritInverseConfigurationPrism reversePrism) {
@@ -442,6 +536,21 @@ public class MapperCreationProcessor implements ModelElementProcessor candidates, SourceMethod method,
@@ -492,7 +601,7 @@ public class MapperCreationProcessor implements ModelElementProcessor candidates, SourceMethod method,
+ InheritConfigurationPrism prism) {
+
+ List candidateNames = new ArrayList();
+ for ( SourceMethod candidate : candidates ) {
+ candidateNames.add( candidate.getName() );
+ }
+
+ String name = prism.name();
+ if ( name.isEmpty() ) {
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "Several matching methods exist: %s(). Specify a name explicitly.",
+ Strings.join( candidateNames, "(), " )
+ ),
+ method.getExecutable(),
+ prism.mirror
+ );
+ }
+ else {
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "None of the candidates %s() matches given name: \"%s\".",
+ Strings.join( candidateNames, "(), " ), name
+ ),
+ method.getExecutable(),
+ prism.mirror
+ );
+ }
+ }
+
+ private void reportErrorWhenSeveralNamesMatch(List candidates, SourceMethod method,
+ InheritConfigurationPrism prism) {
+
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "Given name \"%s\" matches several candidate methods: %s().",
+ prism.name(), Strings.join( candidates, "(), " )
+ ),
+ method.getExecutable(),
+ prism.mirror
+ );
+ }
+
+ private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method,
+ InheritConfigurationPrism prims) {
+
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "Given name \"%s\" does not match the only candidate. Did you mean: \"%s\".",
+ prims.name(), onlyCandidate.getName()
+ ),
+ method.getExecutable(),
+ prims.mirror
+ );
+ }
+
+
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/reverse/InheritInverseConfigurationTest.java b/processor/src/test/java/org/mapstruct/ap/test/reverse/InheritInverseConfigurationTest.java
index 9b5b75b00..a7a9686f1 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/reverse/InheritInverseConfigurationTest.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/reverse/InheritInverseConfigurationTest.java
@@ -120,18 +120,43 @@ public class InheritInverseConfigurationTest {
}
@Test
- @WithClasses({ SourceTargetMapperErroneouslyAnnotated.class })
+ @WithClasses({ SourceTargetMapperErroneouslyAnnotated1.class })
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
- @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated.class,
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated1.class,
kind = Kind.ERROR,
- line = 49,
+ line = 50,
messageRegExp = "Resolved inverse mapping method reverse\\(\\) should not carry the "
+ "@InheritInverseConfiguration annotation itself.")
}
)
- public void shouldUseWronglyAnnotatedError() {
+ public void shouldUseWronglyAnnotatedError1() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperErroneouslyAnnotated2.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated2.class,
+ kind = Kind.WARNING,
+ line = 45,
+ messageRegExp = "Unmapped target properties: \"stringPropX, integerPropX, "
+ + "someConstantDownstream, propertyToIgnoreDownstream\""),
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated2.class,
+ kind = Kind.ERROR,
+ line = 47,
+ messageRegExp = "Resolved inverse mapping method forward2\\(\\) should not carry "
+ + "the @InheritConfiguration annotation"),
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated2.class,
+ kind = Kind.WARNING,
+ line = 48,
+ messageRegExp = "Unmapped target properties: \"stringPropY, integerPropY, "
+ + "propertyNotToIgnoreUpstream\"")
+ }
+ )
+ public void shouldUseWronglyAnnotatedError2() {
}
@Test
@@ -152,4 +177,5 @@ public class InheritInverseConfigurationTest {
)
public void shouldAdviseOnSpecifyingCorrectName() {
}
+
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated.java b/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated1.java
similarity index 90%
rename from processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated.java
rename to processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated1.java
index 960e76bee..3fc072ee1 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated1.java
@@ -28,9 +28,10 @@ import org.mapstruct.factory.Mappers;
* @author Sjaak Derksen
*/
@Mapper
-public interface SourceTargetMapperErroneouslyAnnotated {
+public interface SourceTargetMapperErroneouslyAnnotated1 {
- SourceTargetMapperErroneouslyAnnotated INSTANCE = Mappers.getMapper( SourceTargetMapperErroneouslyAnnotated.class );
+ SourceTargetMapperErroneouslyAnnotated1 INSTANCE =
+ Mappers.getMapper( SourceTargetMapperErroneouslyAnnotated1.class );
@Mappings({
@Mapping(source = "stringPropX", target = "stringPropY"),
diff --git a/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated2.java b/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated2.java
new file mode 100644
index 000000000..a0513da60
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/reverse/SourceTargetMapperErroneouslyAnnotated2.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2012-2014 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.reverse;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperErroneouslyAnnotated2 {
+
+ SourceTargetMapperErroneouslyAnnotated2 INSTANCE
+ = Mappers.getMapper( SourceTargetMapperErroneouslyAnnotated2.class );
+
+ @Mappings({
+ @Mapping(source = "stringPropX", target = "stringPropY"),
+ @Mapping(source = "integerPropX", target = "integerPropY"),
+ @Mapping(source = "propertyToIgnoreDownstream", target = "propertyNotToIgnoreUpstream")
+ })
+ Target forward(Source source);
+
+ @InheritConfiguration(name = "forward2")
+ Source forward2(Target target);
+
+ @InheritInverseConfiguration(name = "forward2")
+ Target reverse(Source source);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/InheritConfigurationTest.java b/processor/src/test/java/org/mapstruct/ap/test/template/InheritConfigurationTest.java
new file mode 100644
index 000000000..4a9c86319
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/InheritConfigurationTest.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+
+import javax.tools.Diagnostic.Kind;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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;
+import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
+import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
+import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
+
+/**
+ * @author Sjaak Derksen
+ */
+@IssueKey("383")
+@WithClasses({ Source.class, NestedSource.class, Target.class })
+@RunWith(AnnotationProcessorTestRunner.class)
+public class InheritConfigurationTest {
+
+ @Test
+ @WithClasses({ SourceTargetMapperSingle.class })
+ public void shouldInheritConfigurationSingleCandidates() {
+
+ Source source = new Source();
+ source.setStringPropX( "1" );
+ source.setIntegerPropX( 2 );
+ source.setNestedSourceProp( new NestedSource("nested") );
+
+ Target createdTarget = SourceTargetMapperSingle.INSTANCE.forwardCreate( source );
+ assertThat( createdTarget ).isNotNull();
+ assertThat( createdTarget.getStringPropY() ).isEqualTo( "1" );
+ assertThat( createdTarget.getIntegerPropY() ).isEqualTo( 2 );
+ assertThat( createdTarget.getNestedResultProp() ).isEqualTo( "nested");
+ assertThat( createdTarget.getExpressionProp() ).isEqualTo( "expression" );
+ assertThat( createdTarget.getConstantProp() ).isEqualTo( "constant" );
+
+ Target updatedTarget = new Target();
+ SourceTargetMapperSingle.INSTANCE.forwardUpdate( source, updatedTarget );
+ assertThat( updatedTarget ).isNotNull();
+ assertThat( updatedTarget.getStringPropY() ).isEqualTo( "1" );
+ assertThat( updatedTarget.getIntegerPropY() ).isEqualTo( 2 );
+ assertThat( updatedTarget.getNestedResultProp() ).isEqualTo( "nested" );
+ assertThat( updatedTarget.getExpressionProp() ).isEqualTo( "expression" );
+ assertThat( updatedTarget.getConstantProp() ).isEqualTo( "constant" );
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperMultiple.class })
+ public void shouldInheritConfigurationMultipleCandidates() {
+
+ Source source = new Source();
+ source.setStringPropX( "1" );
+ source.setIntegerPropX( 2 );
+ source.setNestedSourceProp( new NestedSource("nested") );
+
+ Target createdTarget = SourceTargetMapperSingle.INSTANCE.forwardCreate( source );
+ assertThat( createdTarget ).isNotNull();
+ assertThat( createdTarget.getStringPropY() ).isEqualTo( "1" );
+ assertThat( createdTarget.getIntegerPropY() ).isEqualTo( 2 );
+ assertThat( createdTarget.getNestedResultProp() ).isEqualTo( "nested");
+ assertThat( createdTarget.getExpressionProp() ).isEqualTo( "expression" );
+ assertThat( createdTarget.getConstantProp() ).isEqualTo( "constant" );
+
+ Target updatedTarget = new Target();
+ SourceTargetMapperSingle.INSTANCE.forwardUpdate( source, updatedTarget );
+ assertThat( updatedTarget ).isNotNull();
+ assertThat( updatedTarget.getStringPropY() ).isEqualTo( "1" );
+ assertThat( updatedTarget.getIntegerPropY() ).isEqualTo( 2 );
+ assertThat( updatedTarget.getNestedResultProp() ).isEqualTo( "nested" );
+ assertThat( updatedTarget.getExpressionProp() ).isEqualTo( "expression" );
+ assertThat( updatedTarget.getConstantProp() ).isEqualTo( "constant" );
+
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperAmbiguous1.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperAmbiguous1.class,
+ kind = Kind.ERROR,
+ line = 54,
+ messageRegExp = "Several matching methods exist: forwardCreate\\(\\), "
+ + "forwardCreate1\\(\\). Specify a name explicitly."),
+ @Diagnostic(type = SourceTargetMapperAmbiguous1.class,
+ kind = Kind.WARNING,
+ line = 55,
+ messageRegExp = "Unmapped target properties: \"stringPropY, nestedResultProp, integerPropY, "
+ + "constantProp, expressionProp\"")
+ }
+ )
+ public void shouldRaiseAmbiguousReverseMethodError() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperAmbiguous2.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperAmbiguous2.class,
+ kind = Kind.ERROR,
+ line = 54,
+ messageRegExp = "None of the candidates forwardCreate\\(\\), forwardCreate1\\(\\) matches given "
+ + "name: \"blah\"."),
+ @Diagnostic(type = SourceTargetMapperAmbiguous2.class,
+ kind = Kind.WARNING,
+ line = 55,
+ messageRegExp = "Unmapped target properties: \"stringPropY, nestedResultProp, integerPropY, "
+ + "constantProp, expressionProp\"")
+ }
+ )
+ public void shouldRaiseAmbiguousReverseMethodErrorWrongName() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperAmbiguous3.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperAmbiguous3.class,
+ kind = Kind.ERROR,
+ line = 54,
+ messageRegExp = "Given name \"forwardCreate\" matches several candidate methods: "
+ + ".*forwardCreate.*\\(\\), .*forwardCreate.*\\(\\)"),
+ @Diagnostic(type = SourceTargetMapperAmbiguous3.class,
+ kind = Kind.WARNING,
+ line = 55,
+ messageRegExp = "Unmapped target properties: \"stringPropY, nestedResultProp, integerPropY, "
+ + "constantProp, expressionProp\"") }
+ )
+ public void shouldRaiseAmbiguousReverseMethodErrorDuplicatedName() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperErroneouslyAnnotated1.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated1.class,
+ kind = Kind.ERROR,
+ line = 49,
+ messageRegExp = "Resolved mapping method forwardCreate1\\(\\) should not carry the "
+ + "@InheritConfiguration annotation itself.")
+ }
+ )
+ public void shouldUseWronglyAnnotatedError1() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperErroneouslyAnnotated2.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperErroneouslyAnnotated2.class,
+ kind = Kind.ERROR,
+ line = 51,
+ messageRegExp = "Resolved mapping method forwardCreate\\(\\) should not carry the "
+ + "@InheritInverseConfiguration annotation.")
+ }
+ )
+ public void shouldUseWronglyAnnotatedError2() {
+ }
+
+ @Test
+ @WithClasses({ SourceTargetMapperNonMatchingName.class })
+ @ExpectedCompilationOutcome(
+ value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = SourceTargetMapperNonMatchingName.class,
+ kind = Kind.ERROR,
+ line = 45,
+ messageRegExp = "Given name \"blah\" does not match the only candidate. Did you mean: "
+ + "\"forwardCreate\"."),
+ @Diagnostic(type = SourceTargetMapperNonMatchingName.class,
+ kind = Kind.WARNING,
+ line = 46,
+ messageRegExp = "Unmapped target properties: \"stringPropY, nestedResultProp, integerPropY, "
+ + "constantProp, expressionProp\"")
+ }
+ )
+ public void shouldAdviseOnSpecifyingCorrectName() {
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/NestedSource.java b/processor/src/test/java/org/mapstruct/ap/test/template/NestedSource.java
new file mode 100644
index 000000000..9ee9f0e45
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/NestedSource.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+public class NestedSource {
+
+ private String nested;
+
+ public NestedSource(String nested) {
+ this.nested = nested;
+ }
+
+
+ public String getNested() {
+ return nested;
+ }
+
+ public void setNested(String nested) {
+ this.nested = nested;
+ }
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/Source.java b/processor/src/test/java/org/mapstruct/ap/test/template/Source.java
new file mode 100644
index 000000000..7b8c530c0
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/Source.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+
+/**
+ * @author Sjaak Derksen
+ */
+public class Source {
+
+ private String stringPropX;
+
+ private Integer integerPropX;
+
+ private NestedSource nestedSourceProp;
+
+
+ public String getStringPropX() {
+ return stringPropX;
+ }
+
+ public void setStringPropX(String stringPropX) {
+ this.stringPropX = stringPropX;
+ }
+
+ public Integer getIntegerPropX() {
+ return integerPropX;
+ }
+
+ public void setIntegerPropX(Integer integerPropX) {
+ this.integerPropX = integerPropX;
+ }
+
+ public NestedSource getNestedSourceProp() {
+ return nestedSourceProp;
+ }
+
+ public void setNestedSourceProp(NestedSource nestedSourceProp) {
+ this.nestedSourceProp = nestedSourceProp;
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous1.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous1.java
new file mode 100644
index 000000000..55fec6b86
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous1.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperAmbiguous1 {
+
+ SourceTargetMapperAmbiguous1 INSTANCE = Mappers.getMapper( SourceTargetMapperAmbiguous1.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate(Source source);
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate1(Source source);
+
+ @InheritConfiguration
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous2.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous2.java
new file mode 100644
index 000000000..9634e26f5
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous2.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperAmbiguous2 {
+
+ SourceTargetMapperAmbiguous2 INSTANCE = Mappers.getMapper( SourceTargetMapperAmbiguous2.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate(Source source);
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate1(Source source);
+
+ @InheritConfiguration( name = "blah" )
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous3.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous3.java
new file mode 100644
index 000000000..76c99f5ba
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperAmbiguous3.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperAmbiguous3 {
+
+ SourceTargetMapperAmbiguous3 INSTANCE = Mappers.getMapper( SourceTargetMapperAmbiguous3.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")"),
+ })
+ Target forwardCreate(Source source);
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")"),
+ })
+ void forwardCreate(Source source, @MappingTarget Target target);
+
+ @InheritConfiguration(name = "forwardCreate")
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated1.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated1.java
new file mode 100644
index 000000000..3973ed27e
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated1.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperErroneouslyAnnotated1 {
+
+ SourceTargetMapperErroneouslyAnnotated1 INSTANCE =
+ Mappers.getMapper( SourceTargetMapperErroneouslyAnnotated1.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX"),
+ @Mapping(target = "integerPropY", source = "integerPropX"),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate(Source source);
+
+ @InheritConfiguration( name = "forwardCreate" )
+ Target forwardCreate1(Source source);
+
+ @InheritConfiguration( name = "forwardCreate1" )
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated2.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated2.java
new file mode 100644
index 000000000..b8b9792f4
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperErroneouslyAnnotated2.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperErroneouslyAnnotated2 {
+
+ SourceTargetMapperErroneouslyAnnotated2 INSTANCE =
+ Mappers.getMapper( SourceTargetMapperErroneouslyAnnotated2.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX"),
+ @Mapping(target = "integerPropY", source = "integerPropX"),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate(Source source);
+
+ @InheritInverseConfiguration(name = "forwardCreate")
+ @Mapping(target = "nestedSourceProp", ignore = true)
+ Source forwardCreate(Target source);
+
+ @InheritConfiguration( name = "forwardCreate" )
+ void forwardUpdate(Target source, @MappingTarget Source target);
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperMultiple.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperMultiple.java
new file mode 100644
index 000000000..1d7fb59d2
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperMultiple.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperMultiple {
+
+ SourceTargetMapperMultiple INSTANCE = Mappers.getMapper( SourceTargetMapperMultiple.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")"),
+ })
+ Target forwardCreate(Source source);
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")"),
+ })
+ Target forwardCreate2(Source source);
+
+ @InheritConfiguration( name = "forwardCreate" )
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperNonMatchingName.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperNonMatchingName.java
new file mode 100644
index 000000000..5e1df20e5
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperNonMatchingName.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperNonMatchingName {
+
+ SourceTargetMapperNonMatchingName INSTANCE = Mappers.getMapper( SourceTargetMapperNonMatchingName.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")")
+ })
+ Target forwardCreate(Source source);
+
+ @InheritConfiguration( name = "blah" )
+ void forwardUpdate(Source source, @MappingTarget Target target);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperSingle.java b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperSingle.java
new file mode 100644
index 000000000..17a1675d8
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/SourceTargetMapperSingle.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+import org.mapstruct.InheritConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @author Sjaak Derksen
+ */
+@Mapper
+public interface SourceTargetMapperSingle {
+
+ SourceTargetMapperSingle INSTANCE = Mappers.getMapper( SourceTargetMapperSingle.class );
+
+ @Mappings({
+ @Mapping(target = "stringPropY", source = "stringPropX" ),
+ @Mapping(target = "integerPropY", source = "integerPropX" ),
+ @Mapping(target = "nestedResultProp", source = "nestedSourceProp.nested"),
+ @Mapping(target = "constantProp", constant = "constant"),
+ @Mapping(target = "expressionProp", expression = "java(\"expression\")"),
+ })
+ Target forwardCreate(Source source);
+
+
+ @InheritConfiguration
+ void forwardUpdate(Source source, @MappingTarget Target target);
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/template/Target.java b/processor/src/test/java/org/mapstruct/ap/test/template/Target.java
new file mode 100644
index 000000000..3567d228e
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/template/Target.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright 2012-2014 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.template;
+
+
+/**
+ * @author Sjaak Derksen
+ */
+public class Target {
+
+ private String stringPropY;
+
+ private Integer integerPropY;
+
+ private String constantProp;
+
+ private String expressionProp;
+
+ private String nestedResultProp;
+
+ public String getStringPropY() {
+ return stringPropY;
+ }
+
+ public void setStringPropY(String stringPropY) {
+ this.stringPropY = stringPropY;
+ }
+
+ public Integer getIntegerPropY() {
+ return integerPropY;
+ }
+
+ public void setIntegerPropY(Integer integerPropY) {
+ this.integerPropY = integerPropY;
+ }
+
+ public String getConstantProp() {
+ return constantProp;
+ }
+
+ public void setConstantProp(String constantProp) {
+ this.constantProp = constantProp;
+ }
+
+ public String getExpressionProp() {
+ return expressionProp;
+ }
+
+ public void setExpressionProp(String expressionProp) {
+ this.expressionProp = expressionProp;
+ }
+
+ public String getNestedResultProp() {
+ return nestedResultProp;
+ }
+
+ public void setNestedResultProp(String nestedResultProp) {
+ this.nestedResultProp = nestedResultProp;
+ }
+
+}