From 4d8bc29347e37bcf22d121829802e7f58603afbb Mon Sep 17 00:00:00 2001 From: sjaakd Date: Thu, 17 Aug 2017 22:57:17 +0200 Subject: [PATCH] #1255 Extension of autoInheritanceStrategy, removing of name based ignore reverse mapping --- .../mapstruct/MappingInheritanceStrategy.java | 18 ++++- .../mapstruct/itest/simple/AnimalTest.java | 12 --- .../ap/internal/model/source/Mapping.java | 10 +-- .../MappingInheritanceStrategyPrism.java | 30 +++++++- .../processor/MapperCreationProcessor.java | 63 ++++++++------- .../mapstruct/ap/internal/util/Message.java | 1 + .../ap/test/bugs/_1255/AbstractA.java | 36 +++++++++ .../ap/test/bugs/_1255/Issue1255Test.java | 67 ++++++++++++++++ .../mapstruct/ap/test/bugs/_1255/SomeA.java | 36 +++++++++ .../mapstruct/ap/test/bugs/_1255/SomeB.java | 45 +++++++++++ .../ap/test/bugs/_1255/SomeMapper.java | 36 +++++++++ .../ap/test/bugs/_1255/SomeMapperConfig.java | 39 ++++++++++ .../ap/test/ignore/IgnorePropertyTest.java | 16 +--- .../AutoInheritedAllConfig.java | 40 ++++++++++ .../AutoInheritedReverseConfig.java | 40 ++++++++++ .../CarMapperAllWithAutoInheritance.java | 41 ++++++++++ .../CarMapperReverseWithAutoInheritance.java | 38 +++++++++ .../inheritfromconfig/Erroneous3Config.java | 46 +++++++++++ .../inheritfromconfig/Erroneous3Mapper.java | 37 +++++++++ .../ErroneousMapperAutoInheritance.java | 36 +++++++++ ...neousMapperReverseWithAutoInheritance.java | 38 +++++++++ .../InheritFromConfigTest.java | 77 +++++++++++++++++++ 22 files changed, 734 insertions(+), 68 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java diff --git a/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java b/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java index 082bfaf34..03f5ee0e7 100644 --- a/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java +++ b/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java @@ -32,8 +32,20 @@ public enum MappingInheritanceStrategy { EXPLICIT, /** - * Inherit the method-level configuration annotations automatically if source and target types of the prototype - * method are assignable from the types of a given mapping method. + * Inherit the method-level forward configuration annotations automatically if source and target types of the + * prototype method are assignable from the types of a given mapping method. */ - AUTO_INHERIT_FROM_CONFIG; + AUTO_INHERIT_FROM_CONFIG, + + /** + * Inherit the method-level reverse configuration annotations automatically if source and target types of the + * prototype method are assignable from the target and source types of a given mapping method. + */ + AUTO_INHERIT_REVERSE_FROM_CONFIG, + + /** + * Inherit the method-level forward and reverse configuration annotations automatically if source and target types + * of the prototype method are assignable from the types of a given mapping method. + */ + AUTO_INHERIT_ALL_FROM_CONFIG; } diff --git a/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java b/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java index 4c7485f95..26147bdf7 100644 --- a/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java +++ b/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java @@ -46,18 +46,6 @@ public class AnimalTest { assertThat( animalDto.getColor() ).isNull(); } - @Test - public void shouldNotPropagateIgnoredPropertyInReverseMappingWhenNameIsSame() { - AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); - - Animal animal = AnimalMapper.INSTANCE.animalDtoToAnimal( animalDto ); - - assertThat( animal ).isNotNull(); - assertThat( animalDto.getName() ).isEqualTo( "Bruno" ); - assertThat( animalDto.getSize() ).isEqualTo( 100 ); - assertThat( animal.getAge() ).isNull(); - } - @Test public void shouldNotPropagateIgnoredPropertyInReverseMappingWhenSourceAndTargetAreSpecified() { AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java index e26d43126..1536c54f7 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java @@ -398,17 +398,11 @@ public class Mapping { public Mapping reverse(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory) { // mapping can only be reversed if the source was not a constant nor an expression nor a nested property - if ( constant != null || javaExpression != null ) { + // and the mapping is not a 'target-source-ignore' mapping + if ( constant != null || javaExpression != null || ( isIgnored && sourceName == null ) ) { return null; } - // should only ignore a property when 1) there is a sourceName defined or 2) there's a name match - if ( isIgnored ) { - if ( sourceName == null && !hasPropertyInReverseMethod( targetName, method ) ) { - return null; - } - } - Mapping reverse = new Mapping( sourceName != null ? targetName : null, null, // constant diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java index 4bf88d119..5a18f8083 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java @@ -25,6 +25,32 @@ package org.mapstruct.ap.internal.prism; * @author Andreas Gudian */ public enum MappingInheritanceStrategyPrism { - EXPLICIT, - AUTO_INHERIT_FROM_CONFIG; + + EXPLICIT( false, false, false ), + AUTO_INHERIT_FROM_CONFIG( true, true, false ), + AUTO_INHERIT_REVERSE_FROM_CONFIG( true, false, true ), + AUTO_INHERIT_ALL_FROM_CONFIG( true, true, true ); + + private final boolean autoInherit; + private final boolean applyForward; + private final boolean applyReverse; + + MappingInheritanceStrategyPrism(boolean isAutoInherit, boolean applyForward, boolean applyReverse) { + this.autoInherit = isAutoInherit; + this.applyForward = applyForward; + this.applyReverse = applyReverse; + } + + public boolean isAutoInherit() { + return autoInherit; + } + + public boolean isApplyForward() { + return applyForward; + } + + public boolean isApplyReverse() { + return applyReverse; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java index a6908c4af..1ab5e9485 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java @@ -59,6 +59,7 @@ import org.mapstruct.ap.internal.prism.DecoratedWithPrism; import org.mapstruct.ap.internal.prism.InheritConfigurationPrism; import org.mapstruct.ap.internal.prism.InheritInverseConfigurationPrism; import org.mapstruct.ap.internal.prism.MapperPrism; +import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism; import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; import org.mapstruct.ap.internal.processor.creation.MappingResolverImpl; import org.mapstruct.ap.internal.util.FormattingMessager; @@ -67,7 +68,6 @@ import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.version.VersionInformation; -import static org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism.AUTO_INHERIT_FROM_CONFIG; import static org.mapstruct.ap.internal.util.Collections.first; import static org.mapstruct.ap.internal.util.Collections.join; @@ -446,41 +446,48 @@ public class MapperCreationProcessor implements ModelElementProcessor 1 ) { - messager.printMessage( - method.getExecutable(), - Message.INHERITCONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH, - Strings.join( applicablePrototypeMethods, ", " ) ); + else if ( inheritanceStrategy.isAutoInherit() ) { + + if ( inheritanceStrategy.isApplyForward() ) { + if ( applicablePrototypeMethods.size() == 1 ) { + mappingOptions.applyInheritedOptions( + first( applicablePrototypeMethods ).getMappingOptions(), + false, + method, + messager, + typeFactory ); + } + else if ( applicablePrototypeMethods.size() > 1 ) { + messager.printMessage( + method.getExecutable(), + Message.INHERITCONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH, + Strings.join( applicablePrototypeMethods, ", " ) ); + } } - if ( applicableReversePrototypeMethods.size() == 1 ) { - mappingOptions.applyInheritedOptions( - first( applicableReversePrototypeMethods ).getMappingOptions(), - true, - method, - messager, - typeFactory ); - } - else if ( applicableReversePrototypeMethods.size() > 1 ) { - messager.printMessage( - method.getExecutable(), - Message.INHERITINVERSECONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH, - Strings.join( applicablePrototypeMethods, ", " ) ); + if ( inheritanceStrategy.isApplyReverse() ) { + if ( applicableReversePrototypeMethods.size() == 1 ) { + mappingOptions.applyInheritedOptions( + first( applicableReversePrototypeMethods ).getMappingOptions(), + true, + method, + messager, + typeFactory ); + } + else if ( applicableReversePrototypeMethods.size() > 1 ) { + messager.printMessage( + method.getExecutable(), + Message.INHERITINVERSECONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH, + Strings.join( applicableReversePrototypeMethods, ", " ) ); + } } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java index 49edbef59..e3bd87950 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java @@ -47,6 +47,7 @@ public enum Message { PROPERTYMAPPING_DUPLICATE_TARGETS( "Target property \"%s\" must not be mapped more than once." ), PROPERTYMAPPING_EMPTY_TARGET( "Target must not be empty in @Mapping." ), PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED( "Source and constant are both defined in @Mapping, either define a source or a constant." ), + PROPERTYMAPPING_SOURCE_AND_IGNORE_BOTH_DEFINED( "Source and ignore are both defined in @Mapping, make explicit in reverse mapping when the intent is to ignore the reverse mapping." ), PROPERTYMAPPING_SOURCE_AND_EXPRESSION_BOTH_DEFINED( "Source and expression are both defined in @Mapping, either define a source or an expression." ), PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED( "Expression and constant are both defined in @Mapping, either define an expression or a constant." ), PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED( "Expression and default value are both defined in @Mapping, either define a defaultValue or an expression." ), diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java new file mode 100644 index 000000000..0b9c107ca --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java @@ -0,0 +1,36 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +/** + * + * @author Sjaak Derksen + */ +public abstract class AbstractA { + + private String field1; + + public String getField1() { + return field1; + } + + public void setField1(String field1) { + this.field1 = field1; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java new file mode 100644 index 000000000..924e8533b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java @@ -0,0 +1,67 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +import static org.assertj.core.api.Assertions.assertThat; +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; + +/** + * + * @author Sjaak Derksen + */ +@IssueKey("1255") +@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses({ + AbstractA.class, + SomeA.class, + SomeB.class, + SomeMapper.class, + SomeMapperConfig.class}) +public class Issue1255Test { + + @Test + public void shouldMapSomeBToSomeAWithoutField1() throws Exception { + SomeB someB = new SomeB(); + someB.setField1( "value1" ); + someB.setField2( "value2" ); + + SomeA someA = SomeMapper.INSTANCE.toSomeA( someB ); + + assertThat( someA.getField1() ) + .isNotEqualTo( someB.getField1() ) + .isNull(); + assertThat( someA.getField2() ).isEqualTo( someB.getField2() ); + } + + @Test + public void shouldMapSomeAToSomeB() throws Exception { + SomeA someA = new SomeA(); + someA.setField1( "value1" ); + someA.setField2( "value2" ); + + SomeB someB = SomeMapper.INSTANCE.toSomeB( someA ); + + assertThat( someB.getField1() ).isEqualTo( someA.getField1() ); + assertThat( someB.getField2() ).isEqualTo( someA.getField2() ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java new file mode 100644 index 000000000..a9e030f7d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java @@ -0,0 +1,36 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +/** + * + * @author Sjaak Derksen + */ +public class SomeA extends AbstractA { + + private String field2; + + public String getField2() { + return field2; + } + + public void setField2(String field2) { + this.field2 = field2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java new file mode 100644 index 000000000..1820b9676 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java @@ -0,0 +1,45 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +/** + * + * @author Sjaak Derksen + */ +public class SomeB { + + private String field1; + private String field2; + + public String getField1() { + return field1; + } + + public void setField1(String field1) { + this.field1 = field1; + } + + public String getField2() { + return field2; + } + + public void setField2(String field2) { + this.field2 = field2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java new file mode 100644 index 000000000..0fb3137c0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java @@ -0,0 +1,36 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper(config = SomeMapperConfig.class) +public interface SomeMapper { + + SomeMapper INSTANCE = Mappers.getMapper( SomeMapper.class ); + + SomeA toSomeA(SomeB source); + + SomeB toSomeB(SomeA source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java new file mode 100644 index 000000000..dfe711f50 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java @@ -0,0 +1,39 @@ +/** + * Copyright 2012-2017 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.bugs._1255; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; +import org.mapstruct.Mappings; + +/** + * + * @author Sjaak Derksen + */ +@MapperConfig( + mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG +) +public interface SomeMapperConfig { + + @Mappings({ + @Mapping(target = "field1", ignore = true) + }) + AbstractA toAbstractA(SomeB source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java index 525d18f7b..170fe3113 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java @@ -56,23 +56,9 @@ public class IgnorePropertyTest { assertThat( animalDto.publicColor ).isNull(); } - @Test - @IssueKey("72") - public void shouldNotPropagateIgnoredPropertyInReverseMappingWhenNameIsSame() { - AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); - - Animal animal = AnimalMapper.INSTANCE.animalDtoToAnimal( animalDto ); - - assertThat( animal ).isNotNull(); - assertThat( animalDto.getName() ).isEqualTo( "Bruno" ); - assertThat( animalDto.getSize() ).isEqualTo( 100 ); - assertThat( animal.getAge() ).isNull(); - assertThat( animal.publicAge ).isNull(); - } - @Test @IssueKey("337") - public void shouldNotPropagateIgnoredPropertyInReverseMappingWhenSourceAndTargetAreSpecified() { + public void propertyIsIgnoredInReverseMappingWhenSourceIsAlsoSpecifiedICWIgnore() { AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); Animal animal = AnimalMapper.INSTANCE.animalDtoToAnimal( animalDto ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java new file mode 100644 index 000000000..c9ab6eddc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@MapperConfig( + mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_ALL_FROM_CONFIG, + unmappedTargetPolicy = ReportingPolicy.ERROR +) +public interface AutoInheritedAllConfig { + @Mappings({ + @Mapping(target = "primaryKey", source = "id"), + @Mapping(target = "auditTrail", ignore = true) + }) + BaseVehicleEntity baseDtoToEntity(BaseVehicleDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java new file mode 100644 index 000000000..5be48cc9e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@MapperConfig( + mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_REVERSE_FROM_CONFIG, + unmappedTargetPolicy = ReportingPolicy.ERROR +) +public interface AutoInheritedReverseConfig { + @Mappings({ + @Mapping(target = "primaryKey", source = "id"), + @Mapping(target = "auditTrail", ignore = true) + }) + BaseVehicleEntity baseDtoToEntity(BaseVehicleDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java new file mode 100644 index 000000000..12eed022d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( + config = AutoInheritedAllConfig.class +) +public abstract class CarMapperAllWithAutoInheritance { + public static final CarMapperAllWithAutoInheritance INSTANCE = + Mappers.getMapper( CarMapperAllWithAutoInheritance.class ); + + @Mapping(target = "color", source = "colour") + public abstract CarEntity toCarEntity(CarDto carDto); + + @Mapping( target = "colour", source = "color" ) + public abstract CarDto toCarDto(CarEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java new file mode 100644 index 000000000..041f4e172 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( + config = AutoInheritedReverseConfig.class +) +public abstract class CarMapperReverseWithAutoInheritance { + public static final CarMapperReverseWithAutoInheritance INSTANCE = + Mappers.getMapper( CarMapperReverseWithAutoInheritance.class ); + + @Mapping( target = "colour", source = "color" ) + public abstract CarDto toCarDto(CarEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java new file mode 100644 index 000000000..ad53c8510 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java @@ -0,0 +1,46 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@MapperConfig( + mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_REVERSE_FROM_CONFIG, + unmappedTargetPolicy = ReportingPolicy.ERROR +) +public interface Erroneous3Config { + @Mappings({ + @Mapping(target = "primaryKey", source = "id"), + @Mapping(target = "auditTrail", ignore = true) + }) + BaseVehicleEntity baseDtoToEntity(BaseVehicleDto dto); + + @Mappings({ + @Mapping(target = "primaryKey", source = "id"), + @Mapping(target = "auditTrail", ignore = true) + }) + BaseVehicleEntity baseDtoToEntity2(BaseVehicleDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java new file mode 100644 index 000000000..34fae8634 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( + config = Erroneous3Config.class +) +public abstract class Erroneous3Mapper { + public static final Erroneous3Mapper INSTANCE = Mappers.getMapper( Erroneous3Mapper.class ); + + @Mapping( target = "colour", source = "color" ) + public abstract CarDto toCarDto(CarEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java new file mode 100644 index 000000000..8e7dccfb1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java @@ -0,0 +1,36 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( + config = AutoInheritedReverseConfig.class +) +public interface ErroneousMapperAutoInheritance { + ErroneousMapperAutoInheritance INSTANCE = Mappers.getMapper( ErroneousMapperAutoInheritance.class ); + + @Mapping(target = "color", source = "colour") + CarEntity toCarEntity(CarDto carDto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java new file mode 100644 index 000000000..7a32767a4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2017 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.inheritfromconfig; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( + config = AutoInheritedConfig.class +) +public abstract class ErroneousMapperReverseWithAutoInheritance { + public static final ErroneousMapperReverseWithAutoInheritance INSTANCE = + Mappers.getMapper( ErroneousMapperReverseWithAutoInheritance.class ); + + @Mapping( target = "colour", source = "color" ) + public abstract CarDto toCarDto(CarEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java index c3f6fd5bf..2cd07e7d0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java @@ -140,6 +140,35 @@ public class InheritFromConfigTest { assertThat( carDto.getId() ).isEqualTo( 42L ); } + @Test + @IssueKey( "1255" ) + @WithClasses({ CarMapperReverseWithAutoInheritance.class, AutoInheritedReverseConfig.class } ) + public void autoInheritedMappingIsAppliedInReverseDirectlyFromConfig() { + + CarEntity carEntity = new CarEntity(); + carEntity.setColor( "red" ); + carEntity.setPrimaryKey( 42L ); + + CarDto carDto = CarMapperReverseWithAutoInheritance.INSTANCE.toCarDto( carEntity ); + + assertThat( carDto.getColour() ).isEqualTo( "red" ); + assertThat( carDto.getId() ).isEqualTo( 42L ); + } + + @Test + @IssueKey( "1255" ) + @WithClasses({ CarMapperAllWithAutoInheritance.class, AutoInheritedAllConfig.class } ) + public void autoInheritedMappingIsAppliedInForwardAndReverseDirectlyFromConfig() { + + CarDto carDto = newTestDto(); + + CarEntity carEntity = CarMapperAllWithAutoInheritance.INSTANCE.toCarEntity( carDto ); + CarDto carDto2 = CarMapperAllWithAutoInheritance.INSTANCE.toCarDto( carEntity ); + + assertThat( carDto.getColour() ).isEqualTo( carDto2.getColour() ); + assertThat( carDto.getId() ).isEqualTo( carDto2.getId() ); + } + @Test public void explicitInheritedMappingWithTwoLevelsIsOverriddenAtMethodLevel() { CarDto carDto = newTestDto(); @@ -230,4 +259,52 @@ public class InheritFromConfigTest { public void erroneous2InheritanceCycle() { } + + @Test + @IssueKey( "1255" ) + @WithClasses({ ErroneousMapperAutoInheritance.class, AutoInheritedReverseConfig.class } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMapperAutoInheritance.class, + kind = Kind.ERROR, + line = 35, + messageRegExp = "Unmapped target properties: \"primaryKey, auditTrail\"\\.") + } + ) + public void erroneousWrongReverseConfigInherited() { } + + @Test + @IssueKey( "1255" ) + @WithClasses({ ErroneousMapperReverseWithAutoInheritance.class, AutoInheritedConfig.class } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMapperReverseWithAutoInheritance.class, + kind = Kind.ERROR, + line = 36, + messageRegExp = "Unmapped target property: \"id\"\\.") + } + ) + public void erroneousWrongConfigInherited() { } + + @Test + @IssueKey( "1255" ) + @WithClasses({ Erroneous3Mapper.class, Erroneous3Config.class } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Erroneous3Mapper.class, + kind = Kind.ERROR, + line = 35, + messageRegExp = "More than one configuration prototype method is applicable. " + + "Use @InheritInverseConfiguration.*"), + @Diagnostic(type = Erroneous3Mapper.class, + kind = Kind.ERROR, + line = 35, + messageRegExp = "Unmapped target property: \"id\"\\.") + } + ) + public void erroneousDuplicateReverse() { } + }