diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java index cb809924b..6584053ff 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java @@ -21,6 +21,7 @@ package org.mapstruct.ap.internal.model; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.source.ForgedMethod; +import org.mapstruct.ap.internal.model.source.MappingMethodUtils; import org.mapstruct.ap.internal.model.source.Method; /** @@ -55,11 +56,21 @@ class AbstractBaseBuilder> { * * @return See above */ - Assignment createForgedBeanAssignment(SourceRHS sourceRHS, ForgedMethod forgedMethod) { - BeanMappingMethod forgedMappingMethod = new BeanMappingMethod.Builder() - .forgedMethod( forgedMethod ) - .mappingContext( ctx ) - .build(); + Assignment createForgedAssignment(SourceRHS sourceRHS, ForgedMethod forgedMethod) { + MappingMethod forgedMappingMethod; + if ( MappingMethodUtils.isEnumMapping( forgedMethod ) ) { + forgedMappingMethod = new ValueMappingMethod.Builder() + .method( forgedMethod ) + .valueMappings( forgedMethod.getMappingOptions().getValueMappings() ) + .mappingContext( ctx ) + .build(); + } + else { + forgedMappingMethod = new BeanMappingMethod.Builder() + .forgedMethod( forgedMethod ) + .mappingContext( ctx ) + .build(); + } return createForgedAssignment( sourceRHS, forgedMethod, forgedMappingMethod ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java index 1c34d85ad..f28540834 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java @@ -73,7 +73,7 @@ public abstract class AbstractMappingMethodBuilder trueValueMappings = new ArrayList(); private ValueMapping defaultTargetValue = null; @@ -64,7 +66,7 @@ public class ValueMappingMethod extends MappingMethod { return this; } - public Builder souceMethod(SourceMethod sourceMethod) { + public Builder method(Method sourceMethod) { this.method = sourceMethod; return this; } @@ -128,7 +130,7 @@ public class ValueMappingMethod extends MappingMethod { throwIllegalArgumentException, beforeMappingMethods, afterMappingMethods ); } - private List enumToEnumMapping(SourceMethod method) { + private List enumToEnumMapping(Method method) { List mappings = new ArrayList(); List unmappedSourceConstants @@ -161,10 +163,20 @@ public class ValueMappingMethod extends MappingMethod { } if ( defaultTargetValue == null && !unmappedSourceConstants.isEmpty() ) { + String sourceErrorMessage = "source"; + String targetErrorMessage = "target"; + if ( method instanceof ForgedMethod && ( (ForgedMethod) method ).getHistory() != null ) { + ForgedMethodHistory history = ( (ForgedMethod) method ).getHistory(); + sourceErrorMessage = history.createSourcePropertyErrorMessage(); + targetErrorMessage = + "\"" + history.getTargetType().toString() + " " + history.createTargetPropertyName() + "\""; + } // all sources should now be matched, there's no default to fall back to, so if sources remain, // we have an issue. ctx.getMessager().printMessage( method.getExecutable(), Message.VALUE_MAPPING_UNMAPPED_SOURCES, + sourceErrorMessage, + targetErrorMessage, Strings.join( unmappedSourceConstants, ", " ) ); @@ -173,7 +185,7 @@ public class ValueMappingMethod extends MappingMethod { return mappings; } - private SelectionParameters getSelectionParameters(SourceMethod method) { + private SelectionParameters getSelectionParameters(Method method) { BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() ); if ( beanMappingPrism != null ) { List qualifiers = beanMappingPrism.qualifiedBy(); @@ -184,7 +196,7 @@ public class ValueMappingMethod extends MappingMethod { return null; } - private boolean reportErrorIfMappedEnumConstantsDontExist(SourceMethod method) { + private boolean reportErrorIfMappedEnumConstantsDontExist(Method method) { List sourceEnumConstants = first( method.getSourceParameters() ).getType().getEnumConstants(); List targetEnumConstants = method.getReturnType().getEnumConstants(); @@ -251,6 +263,7 @@ public class ValueMappingMethod extends MappingMethod { this.nullTarget = nullTarget; this.defaultTarget = defaultTarget; this.throwIllegalArgumentException = throwIllegalArgumentException; + this.overridden = method.overridesMethod(); } public List getValueMappings() { @@ -273,6 +286,10 @@ public class ValueMappingMethod extends MappingMethod { return first( getParameters() ); } + public boolean isOverridden() { + return overridden; + } + public static class MappingEntry { private final String source; private final String target; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java new file mode 100644 index 000000000..d38451785 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java @@ -0,0 +1,48 @@ +/** + * 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.internal.model.source; + +import static org.mapstruct.ap.internal.util.Collections.first; + +/** + * @author Filip Hrisafov + */ +public final class MappingMethodUtils { + + /** + * Hide default constructor. + */ + private MappingMethodUtils() { + } + + + /** + * Checks if the provided {@code method} is for enum mapping. A Method is an Enum Mapping method when the + * source parameter and result type are enum types. + * + * @param method to check + * + * @return {@code true} if the method is for enum mapping, {@code false} otherwise + */ + public static boolean isEnumMapping(Method method) { + return method.getSourceParameters().size() == 1 + && first( method.getSourceParameters() ).getType().isEnumType() + && method.getResultType().isEnumType(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index f0f6108d8..3c7142395 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -381,9 +381,7 @@ public class SourceMethod implements Method { public boolean isEnumMapping() { if ( isEnumMapping == null ) { - isEnumMapping = getSourceParameters().size() == 1 - && first( getSourceParameters() ).getType().isEnumType() - && getResultType().isEnumType(); + isEnumMapping = MappingMethodUtils.isEnumMapping( this ); } return isEnumMapping; } 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 6c8e78a4d..6178754e6 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 @@ -317,7 +317,7 @@ public class MapperCreationProcessor implements ModelElementProcessor\" or \"\" can only be used once." ), - VALUE_MAPPING_UNMAPPED_SOURCES( "The following constants from the source enum have no corresponding constant in the target enum and must be be mapped via adding additional mappings: %s." ), + VALUE_MAPPING_UNMAPPED_SOURCES( "The following constants from the %s enum have no corresponding constant in the %s enum and must be be mapped via adding additional mappings: %s." ), VALUEMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." ); // CHECKSTYLE:ON diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl index 2f648fda9..ba2d8f965 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl @@ -19,8 +19,8 @@ limitations under the License. --> -@Override -public <@includeModel object=returnType/> ${name}(<@includeModel object=sourceParameter/>) { +<#if overridden>@Override +<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<@includeModel object=sourceParameter/>) { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> <#if !callback_has_next> diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java index c3923e6df..8fb7c3e2c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java @@ -31,10 +31,12 @@ import org.mapstruct.ap.test.nestedbeans.erroneous.Cat; import org.mapstruct.ap.test.nestedbeans.erroneous.CatDto; import org.mapstruct.ap.test.nestedbeans.erroneous.Info; import org.mapstruct.ap.test.nestedbeans.erroneous.InfoDto; +import org.mapstruct.ap.test.nestedbeans.erroneous.RoofTypeMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableCollectionElementPropertyMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableDeepListMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableDeepMapKeyMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableEnumMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableValuePropertyMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.UserDto; import org.mapstruct.ap.test.nestedbeans.erroneous.User; @@ -42,11 +44,13 @@ import org.mapstruct.ap.test.nestedbeans.erroneous.WheelDto; import org.mapstruct.ap.test.nestedbeans.erroneous.Wheel; import org.mapstruct.ap.test.nestedbeans.erroneous.Car; import org.mapstruct.ap.test.nestedbeans.erroneous.CarDto; +import org.mapstruct.ap.test.nestedbeans.erroneous.ExternalRoofType; import org.mapstruct.ap.test.nestedbeans.erroneous.House; import org.mapstruct.ap.test.nestedbeans.erroneous.HouseDto; import org.mapstruct.ap.test.nestedbeans.erroneous.Color; import org.mapstruct.ap.test.nestedbeans.erroneous.ColorDto; import org.mapstruct.ap.test.nestedbeans.erroneous.Roof; +import org.mapstruct.ap.test.nestedbeans.erroneous.RoofType; import org.mapstruct.ap.test.nestedbeans.erroneous.RoofDto; import org.mapstruct.ap.test.nestedbeans.erroneous.UnmappableDeepNestingMapper; import org.mapstruct.ap.test.nestedbeans.erroneous.Word; @@ -60,6 +64,7 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; @WithClasses({ Car.class, CarDto.class, Color.class, ColorDto.class, House.class, HouseDto.class, Roof.class, RoofDto.class, + RoofType.class, ExternalRoofType.class, RoofTypeMapper.class, User.class, UserDto.class, Wheel.class, WheelDto.class, Dictionary.class, DictionaryDto.class, Word.class, WordDto.class, ForeignWord.class, ForeignWordDto.class, @@ -183,4 +188,23 @@ public class DottedErrorMessageTest { ) public void testMapValueProperty() { } + + @Test + @WithClasses({ + UnmappableEnumMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableEnumMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 26, + messageRegExp = "The following constants from the property \".*RoofType house\\.roof\\.type\" enum " + + "have no corresponding constant in the \".*ExternalRoofType house\\.roof\\.type\" enum and must " + + "be be mapped via adding additional mappings: NORMAL\\." + ) + } + ) + public void testMapEnumProperty() { + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java new file mode 100644 index 000000000..9f86ca22c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java @@ -0,0 +1,28 @@ +/** + * 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.nestedbeans; + + +/** + * @author Filip Hrisafov + */ +public enum ExternalRoofType { + + OPEN, BOX, GAMBREL, STANDARD, NORMAL +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java index c01bc5406..0cfaf9ee0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java @@ -18,17 +18,28 @@ */ package org.mapstruct.ap.test.nestedbeans; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.assertj.core.groups.Tuple; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; @WithClasses({ User.class, UserDto.class, Car.class, CarDto.class, House.class, HouseDto.class, Wheel.class, WheelDto.class, Roof.class, RoofDto.class, + RoofType.class, ExternalRoofType.class, org.mapstruct.ap.test.nestedbeans.other.CarDto.class, org.mapstruct.ap.test.nestedbeans.other.UserDto.class, org.mapstruct.ap.test.nestedbeans.other.HouseDto.class, @@ -41,6 +52,59 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(AnnotationProcessorTestRunner.class) public class NestedSimpleBeansMappingTest { + @Rule + public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + UserDtoMapperClassic.class, + UserDtoMapperSmart.class, + UserDtoUpdateMapperSmart.class + ); + + /** + * Extracts all non synthetic declared fields from a class. This is needed, because jacoco adds a synthetic field + * to the classes and also assertj does not support testing that all fields are exactly there. + * This will be needed until 953 from + * assertj-core is implemented. + * + * @param clazz to extract from + * + * @return all the non synthetic declared fields + */ + private static List extractAllFields(Class clazz) { + List nonSyntheticFields = new ArrayList(); + for ( Field field : clazz.getDeclaredFields() ) { + if ( !field.isSynthetic() ) { + nonSyntheticFields.add( field ); + } + } + + return nonSyntheticFields; + } + + @Test + public void shouldHaveAllFields() throws Exception { + // If this test fails that means something new was added to the structure of the User/UserDto. + // Make sure that the other tests are also updated (the new field is asserted) + Object[] userFields = new String[] { "name", "car", "secondCar", "house" }; + assertThat( extractAllFields( User.class ) ).extracting( "name" ).containsExactlyInAnyOrder( userFields ); + assertThat( extractAllFields( UserDto.class ) ).extracting( "name" ).containsExactlyInAnyOrder( userFields ); + + Object[] carFields = new String[] { "name", "year", "wheels" }; + assertThat( extractAllFields( Car.class ) ).extracting( "name" ).containsExactlyInAnyOrder( carFields ); + assertThat( extractAllFields( CarDto.class ) ).extracting( "name" ).containsExactlyInAnyOrder( carFields ); + + Object[] wheelFields = new String[] { "front", "right" }; + assertThat( extractAllFields( Wheel.class ) ).extracting( "name" ).containsExactlyInAnyOrder( wheelFields ); + assertThat( extractAllFields( WheelDto.class ) ).extracting( "name" ).containsExactlyInAnyOrder( wheelFields ); + + Object[] houseFields = new String[] { "name", "year", "roof" }; + assertThat( extractAllFields( House.class ) ).extracting( "name" ).containsExactlyInAnyOrder( houseFields ); + assertThat( extractAllFields( HouseDto.class ) ).extracting( "name" ).containsExactlyInAnyOrder( houseFields ); + + Object[] roofFields = new String[] { "color", "type" }; + assertThat( extractAllFields( Roof.class ) ).extracting( "name" ).containsExactlyInAnyOrder( roofFields ); + assertThat( extractAllFields( RoofDto.class ) ).extracting( "name" ).containsExactlyInAnyOrder( roofFields ); + } + @Test public void shouldMapNestedBeans() { @@ -49,11 +113,8 @@ public class NestedSimpleBeansMappingTest { UserDto classicMapping = UserDtoMapperClassic.INSTANCE.userToUserDto( user ); UserDto smartMapping = UserDtoMapperSmart.INSTANCE.userToUserDto( user ); - System.out.println( smartMapping ); - System.out.println( classicMapping ); - - assertThat( smartMapping ).isNotNull(); - assertThat( smartMapping ).isEqualTo( classicMapping ); + assertUserDto( classicMapping, user ); + assertUserDto( smartMapping, user ); } @Test @@ -67,15 +128,58 @@ public class NestedSimpleBeansMappingTest { smartMapping.setCar( new CarDto() ); smartMapping.getCar().setName( "Toyota" ); - // create a classic mapping and adapt expected result to Toyota - UserDto classicMapping = UserDtoMapperClassic.INSTANCE.userToUserDto( TestData.createUser() ); - classicMapping.getCar().setName( "Toyota" ); - // action UserDtoUpdateMapperSmart.INSTANCE.userToUserDto( smartMapping, user ); // result - assertThat( smartMapping ).isNotNull(); - assertThat( smartMapping ).isEqualTo( classicMapping ); + assertThat( smartMapping.getName() ).isEqualTo( user.getName() ); + assertThat( smartMapping.getCar().getYear() ).isEqualTo( user.getCar().getYear() ); + assertThat( smartMapping.getCar().getName() ).isEqualTo( "Toyota" ); + assertThat( user.getCar().getName() ).isNull(); + assertWheels( smartMapping.getCar().getWheels(), user.getCar().getWheels() ); + assertCar( smartMapping.getSecondCar(), user.getSecondCar() ); + assertHouse( smartMapping.getHouse(), user.getHouse() ); + } + + private static void assertUserDto(UserDto userDto, User user) { + assertThat( userDto ).isNotNull(); + assertThat( userDto.getName() ).isEqualTo( user.getName() ); + assertCar( userDto.getCar(), user.getCar() ); + assertCar( userDto.getSecondCar(), user.getSecondCar() ); + assertHouse( userDto.getHouse(), user.getHouse() ); + } + + private static void assertCar(CarDto carDto, Car car) { + if ( car == null ) { + assertThat( carDto ).isNull(); + } + else { + assertThat( carDto.getName() ).isEqualTo( car.getName() ); + assertThat( carDto.getYear() ).isEqualTo( car.getYear() ); + assertWheels( carDto.getWheels(), car.getWheels() ); + } + } + + private static void assertWheels(List wheelDtos, List wheels) { + List wheelTuples = wheels.stream().map( new Function() { + @Override + public Tuple apply(Wheel wheel) { + return tuple( wheel.isFront(), wheel.isRight() ); + } + } ).collect( Collectors.toList() ); + assertThat( wheelDtos ) + .extracting( "front", "right" ) + .containsExactlyElementsOf( wheelTuples ); + } + + private static void assertHouse(HouseDto houseDto, House house) { + assertThat( houseDto.getName() ).isEqualTo( house.getName() ); + assertThat( houseDto.getYear() ).isEqualTo( house.getYear() ); + assertRoof( houseDto.getRoof(), house.getRoof() ); + } + + private static void assertRoof(RoofDto roofDto, Roof roof) { + assertThat( roofDto.getColor() ).isEqualTo( String.valueOf( roof.getColor() ) ); + assertThat( roofDto.getType().name() ).isEqualTo( roof.getType().name() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java index 52762dabb..e3c98cbb6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java @@ -20,12 +20,14 @@ package org.mapstruct.ap.test.nestedbeans; public class Roof { private int color; + private RoofType type; public Roof() { } - public Roof(int color) { + public Roof(int color, RoofType type) { this.color = color; + this.type = type; } public int getColor() { @@ -40,7 +42,16 @@ public class Roof { public String toString() { return "Roof{" + "color='" + color + '\'' + + "type='" + type + '\'' + '}'; } + public RoofType getType() { + return type; + } + + public Roof setType(RoofType type) { + this.type = type; + return this; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java index 3070408f5..c999cd10b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java @@ -20,6 +20,7 @@ package org.mapstruct.ap.test.nestedbeans; public class RoofDto { private String color; + private ExternalRoofType type; public RoofDto() { } @@ -36,6 +37,15 @@ public class RoofDto { this.color = color; } + public ExternalRoofType getType() { + return type; + } + + public RoofDto setType(ExternalRoofType type) { + this.type = type; + return this; + } + @Override public boolean equals(Object o) { if ( this == o ) { @@ -47,20 +57,26 @@ public class RoofDto { RoofDto roofDto = (RoofDto) o; + if ( type != ( (RoofDto) o ).type ) { + return false; + } + return color != null ? color.equals( roofDto.color ) : roofDto.color == null; } @Override public int hashCode() { - return color != null ? color.hashCode() : 0; + int result = color != null ? color.hashCode() : 0; + result = 31 * result + ( type != null ? type.hashCode() : 0 ); + return result; } @Override public String toString() { return "RoofDto{" + "color='" + color + '\'' + + "type='" + type + '\'' + '}'; } - } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java new file mode 100644 index 000000000..91abcb366 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java @@ -0,0 +1,28 @@ +/** + * 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.nestedbeans; + + +/** + * @author Filip Hrisafov + */ +public enum RoofType { + + OPEN, BOX, GAMBREL +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java index 7e602c206..3335e367e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java @@ -33,7 +33,7 @@ public class TestData { new Wheel().rear().left(), new Wheel().rear().right() ) ), - new House( "Black", 1834, new Roof( 1 ) ) + new House( "Black", 1834, new Roof( 1, RoofType.BOX ) ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java index 486c9bc81..d461d90d8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java @@ -40,4 +40,6 @@ public interface UserDtoMapperClassic { WheelDto mapWheel(Wheel wheels); + ExternalRoofType mapRoofType(RoofType roofType); + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/ExternalRoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/ExternalRoofType.java new file mode 100644 index 000000000..c7b5ac101 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/ExternalRoofType.java @@ -0,0 +1,28 @@ +/** + * 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.nestedbeans.erroneous; + + +/** + * @author Filip Hrisafov + */ +public enum ExternalRoofType { + + OPEN, BOX, GAMBREL, STANDARD +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/Roof.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/Roof.java index b62268a41..facb66842 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/Roof.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/Roof.java @@ -20,6 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; public class Roof { private Color color; + private RoofType type; public Color getColor() { return color; @@ -28,4 +29,13 @@ public class Roof { public void setColor(Color color) { this.color = color; } + + public RoofType getType() { + return type; + } + + public Roof setType(RoofType type) { + this.type = type; + return this; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofDto.java index 3768fd44d..aad665e93 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofDto.java @@ -20,6 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; public class RoofDto { private ColorDto color; + private ExternalRoofType type; public ColorDto getColor() { return color; @@ -28,4 +29,12 @@ public class RoofDto { public void setColor(ColorDto color) { this.color = color; } + + public ExternalRoofType getType() { + return type; + } + + public void setType(ExternalRoofType type) { + this.type = type; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofType.java new file mode 100644 index 000000000..2554c748f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofType.java @@ -0,0 +1,28 @@ +/** + * 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.nestedbeans.erroneous; + + +/** + * @author Filip Hrisafov + */ +public enum RoofType { + + OPEN, BOX, GAMBREL, NORMAL +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofTypeMapper.java new file mode 100644 index 000000000..2a54d6611 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/RoofTypeMapper.java @@ -0,0 +1,32 @@ +/** + * 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.nestedbeans.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface RoofTypeMapper { + + @ValueMapping( source = "NORMAL", target = "STANDARD") + ExternalRoofType map(RoofType type); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableCollectionElementPropertyMapper.java index 1fb4f584c..6005e977d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableCollectionElementPropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableCollectionElementPropertyMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableCollectionElementPropertyMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepListMapper.java index 78d6faabf..990505aa9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepListMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableDeepListMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapKeyMapper.java index 00fe65b56..371882c80 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapKeyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapKeyMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableDeepMapKeyMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapValueMapper.java index a2aafa267..ecd6255b2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapValueMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepMapValueMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableDeepMapValueMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepNestingMapper.java index a01896cad..b898f310a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepNestingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableDeepNestingMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableDeepNestingMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableEnumMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableEnumMapper.java new file mode 100644 index 000000000..7386c5941 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableEnumMapper.java @@ -0,0 +1,47 @@ +/** + * 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.nestedbeans.erroneous; + +import org.mapstruct.Mapper; + +@Mapper +public abstract class UnmappableEnumMapper { + + abstract UserDto userToUserDto(User user); + + public ColorDto map(Color color) { + return new ColorDto(); + } + + public CarDto map(Car carDto) { + return new CarDto(); + } + + public DictionaryDto map(Dictionary dictionary) { + return new DictionaryDto(); + } + + public ComputerDto map(Computer computer) { + return new ComputerDto(); + } + + public CatDto map(Cat cat) { + return new CatDto(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableValuePropertyMapper.java index 40f79307c..84d6ae826 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableValuePropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/erroneous/UnmappableValuePropertyMapper.java @@ -20,7 +20,7 @@ package org.mapstruct.ap.test.nestedbeans.erroneous; import org.mapstruct.Mapper; -@Mapper +@Mapper(uses = RoofTypeMapper.class) public abstract class UnmappableValuePropertyMapper { abstract UserDto userToUserDto(User user); diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassicImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassicImpl.java new file mode 100644 index 000000000..9c2711800 --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassicImpl.java @@ -0,0 +1,143 @@ +/** + * 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.nestedbeans; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2017-03-01T22:15:21+0100", + comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)" +) +public class UserDtoMapperClassicImpl implements UserDtoMapperClassic { + + @Override + public UserDto userToUserDto(User user) { + if ( user == null ) { + return null; + } + + UserDto userDto = new UserDto(); + + userDto.setName( user.getName() ); + userDto.setCar( carToCarDto( user.getCar() ) ); + userDto.setSecondCar( carToCarDto( user.getSecondCar() ) ); + userDto.setHouse( houseToHouseDto( user.getHouse() ) ); + + return userDto; + } + + @Override + public CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + carDto.setName( car.getName() ); + carDto.setYear( car.getYear() ); + List list = mapWheels( car.getWheels() ); + if ( list != null ) { + carDto.setWheels( list ); + } + + return carDto; + } + + @Override + public HouseDto houseToHouseDto(House house) { + if ( house == null ) { + return null; + } + + HouseDto houseDto = new HouseDto(); + + houseDto.setName( house.getName() ); + houseDto.setYear( house.getYear() ); + houseDto.setRoof( roofToRoofDto( house.getRoof() ) ); + + return houseDto; + } + + @Override + public RoofDto roofToRoofDto(Roof roof) { + if ( roof == null ) { + return null; + } + + RoofDto roofDto = new RoofDto(); + + roofDto.setColor( String.valueOf( roof.getColor() ) ); + roofDto.setType( mapRoofType( roof.getType() ) ); + + return roofDto; + } + + @Override + public List mapWheels(List wheels) { + if ( wheels == null ) { + return null; + } + + List list = new ArrayList(); + for ( Wheel wheel : wheels ) { + list.add( mapWheel( wheel ) ); + } + + return list; + } + + @Override + public WheelDto mapWheel(Wheel wheels) { + if ( wheels == null ) { + return null; + } + + WheelDto wheelDto = new WheelDto(); + + wheelDto.setFront( wheels.isFront() ); + wheelDto.setRight( wheels.isRight() ); + + return wheelDto; + } + + @Override + public ExternalRoofType mapRoofType(RoofType roofType) { + if ( roofType == null ) { + return null; + } + + ExternalRoofType externalRoofType; + + switch ( roofType ) { + case OPEN: externalRoofType = ExternalRoofType.OPEN; + break; + case BOX: externalRoofType = ExternalRoofType.BOX; + break; + case GAMBREL: externalRoofType = ExternalRoofType.GAMBREL; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + roofType ); + } + + return externalRoofType; + } +} diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmartImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmartImpl.java new file mode 100644 index 000000000..65347a32b --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmartImpl.java @@ -0,0 +1,221 @@ +/** + * 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.nestedbeans; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2017-03-01T22:15:23+0100", + comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)" +) +public class UserDtoMapperSmartImpl implements UserDtoMapperSmart { + + @Override + public UserDto userToUserDto(User user) { + if ( user == null ) { + return null; + } + + UserDto userDto = new UserDto(); + + userDto.setName( user.getName() ); + userDto.setCar( carToCarDto( user.getCar() ) ); + userDto.setSecondCar( carToCarDto( user.getSecondCar() ) ); + userDto.setHouse( houseToHouseDto( user.getHouse() ) ); + + return userDto; + } + + @Override + public org.mapstruct.ap.test.nestedbeans.other.UserDto userToUserDto2(User user) { + if ( user == null ) { + return null; + } + + org.mapstruct.ap.test.nestedbeans.other.UserDto userDto = new org.mapstruct.ap.test.nestedbeans.other.UserDto(); + + userDto.setName( user.getName() ); + userDto.setCar( carToCarDto1( user.getCar() ) ); + userDto.setHouse( houseToHouseDto1( user.getHouse() ) ); + + return userDto; + } + + protected WheelDto wheelToWheelDto(Wheel wheel) { + if ( wheel == null ) { + return null; + } + + WheelDto wheelDto = new WheelDto(); + + wheelDto.setFront( wheel.isFront() ); + wheelDto.setRight( wheel.isRight() ); + + return wheelDto; + } + + protected List wheelListToWheelDtoList(List list) { + if ( list == null ) { + return null; + } + + List list1 = new ArrayList(); + for ( Wheel wheel : list ) { + list1.add( wheelToWheelDto( wheel ) ); + } + + return list1; + } + + protected CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + carDto.setName( car.getName() ); + carDto.setYear( car.getYear() ); + List list = wheelListToWheelDtoList( car.getWheels() ); + if ( list != null ) { + carDto.setWheels( list ); + } + + return carDto; + } + + protected ExternalRoofType roofTypeToExternalRoofType(RoofType roofType) { + if ( roofType == null ) { + return null; + } + + ExternalRoofType externalRoofType; + + switch ( roofType ) { + case OPEN: externalRoofType = ExternalRoofType.OPEN; + break; + case BOX: externalRoofType = ExternalRoofType.BOX; + break; + case GAMBREL: externalRoofType = ExternalRoofType.GAMBREL; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + roofType ); + } + + return externalRoofType; + } + + protected RoofDto roofToRoofDto(Roof roof) { + if ( roof == null ) { + return null; + } + + RoofDto roofDto = new RoofDto(); + + roofDto.setColor( String.valueOf( roof.getColor() ) ); + roofDto.setType( roofTypeToExternalRoofType( roof.getType() ) ); + + return roofDto; + } + + protected HouseDto houseToHouseDto(House house) { + if ( house == null ) { + return null; + } + + HouseDto houseDto = new HouseDto(); + + houseDto.setName( house.getName() ); + houseDto.setYear( house.getYear() ); + houseDto.setRoof( roofToRoofDto( house.getRoof() ) ); + + return houseDto; + } + + protected org.mapstruct.ap.test.nestedbeans.other.WheelDto wheelToWheelDto1(Wheel wheel) { + if ( wheel == null ) { + return null; + } + + org.mapstruct.ap.test.nestedbeans.other.WheelDto wheelDto = new org.mapstruct.ap.test.nestedbeans.other.WheelDto(); + + wheelDto.setFront( wheel.isFront() ); + wheelDto.setRight( wheel.isRight() ); + + return wheelDto; + } + + protected List wheelListToWheelDtoList1(List list) { + if ( list == null ) { + return null; + } + + List list1 = new ArrayList(); + for ( Wheel wheel : list ) { + list1.add( wheelToWheelDto1( wheel ) ); + } + + return list1; + } + + protected org.mapstruct.ap.test.nestedbeans.other.CarDto carToCarDto1(Car car) { + if ( car == null ) { + return null; + } + + org.mapstruct.ap.test.nestedbeans.other.CarDto carDto = new org.mapstruct.ap.test.nestedbeans.other.CarDto(); + + carDto.setName( car.getName() ); + carDto.setYear( car.getYear() ); + List list = wheelListToWheelDtoList1( car.getWheels() ); + if ( list != null ) { + carDto.setWheels( list ); + } + + return carDto; + } + + protected org.mapstruct.ap.test.nestedbeans.other.RoofDto roofToRoofDto1(Roof roof) { + if ( roof == null ) { + return null; + } + + org.mapstruct.ap.test.nestedbeans.other.RoofDto roofDto = new org.mapstruct.ap.test.nestedbeans.other.RoofDto(); + + roofDto.setColor( String.valueOf( roof.getColor() ) ); + + return roofDto; + } + + protected org.mapstruct.ap.test.nestedbeans.other.HouseDto houseToHouseDto1(House house) { + if ( house == null ) { + return null; + } + + org.mapstruct.ap.test.nestedbeans.other.HouseDto houseDto = new org.mapstruct.ap.test.nestedbeans.other.HouseDto(); + + houseDto.setName( house.getName() ); + houseDto.setYear( house.getYear() ); + houseDto.setRoof( roofToRoofDto1( house.getRoof() ) ); + + return houseDto; + } +} diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java new file mode 100644 index 000000000..c24ec1707 --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmartImpl.java @@ -0,0 +1,170 @@ +/** + * 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.nestedbeans; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2017-03-01T22:15:22+0100", + comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)" +) +public class UserDtoUpdateMapperSmartImpl implements UserDtoUpdateMapperSmart { + + @Override + public void userToUserDto(UserDto userDto, User user) { + if ( user == null ) { + return; + } + + if ( user.getName() != null ) { + userDto.setName( user.getName() ); + } + if ( user.getCar() != null ) { + if ( userDto.getCar() == null ) { + userDto.setCar( new CarDto() ); + } + carToCarDto( user.getCar(), userDto.getCar() ); + } + else { + userDto.setCar( null ); + } + if ( user.getSecondCar() != null ) { + if ( userDto.getSecondCar() == null ) { + userDto.setSecondCar( new CarDto() ); + } + carToCarDto( user.getSecondCar(), userDto.getSecondCar() ); + } + else { + userDto.setSecondCar( null ); + } + if ( user.getHouse() != null ) { + if ( userDto.getHouse() == null ) { + userDto.setHouse( new HouseDto() ); + } + houseToHouseDto( user.getHouse(), userDto.getHouse() ); + } + else { + userDto.setHouse( null ); + } + } + + protected WheelDto wheelToWheelDto(Wheel wheel) { + if ( wheel == null ) { + return null; + } + + WheelDto wheelDto = new WheelDto(); + + wheelDto.setFront( wheel.isFront() ); + wheelDto.setRight( wheel.isRight() ); + + return wheelDto; + } + + protected List wheelListToWheelDtoList(List list) { + if ( list == null ) { + return null; + } + + List list1 = new ArrayList(); + for ( Wheel wheel : list ) { + list1.add( wheelToWheelDto( wheel ) ); + } + + return list1; + } + + protected void carToCarDto(Car car, CarDto mappingTarget) { + if ( car == null ) { + return; + } + + if ( car.getName() != null ) { + mappingTarget.setName( car.getName() ); + } + mappingTarget.setYear( car.getYear() ); + if ( mappingTarget.getWheels() != null ) { + List list = wheelListToWheelDtoList( car.getWheels() ); + if ( list != null ) { + mappingTarget.getWheels().clear(); + mappingTarget.getWheels().addAll( list ); + } + } + else { + List list = wheelListToWheelDtoList( car.getWheels() ); + if ( list != null ) { + mappingTarget.setWheels( list ); + } + } + } + + protected ExternalRoofType roofTypeToExternalRoofType(RoofType roofType) { + if ( roofType == null ) { + return null; + } + + ExternalRoofType externalRoofType; + + switch ( roofType ) { + case OPEN: externalRoofType = ExternalRoofType.OPEN; + break; + case BOX: externalRoofType = ExternalRoofType.BOX; + break; + case GAMBREL: externalRoofType = ExternalRoofType.GAMBREL; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + roofType ); + } + + return externalRoofType; + } + + protected void roofToRoofDto(Roof roof, RoofDto mappingTarget) { + if ( roof == null ) { + return; + } + + mappingTarget.setColor( String.valueOf( roof.getColor() ) ); + if ( roof.getType() != null ) { + mappingTarget.setType( roofTypeToExternalRoofType( roof.getType() ) ); + } + } + + protected void houseToHouseDto(House house, HouseDto mappingTarget) { + if ( house == null ) { + return; + } + + if ( house.getName() != null ) { + mappingTarget.setName( house.getName() ); + } + mappingTarget.setYear( house.getYear() ); + if ( house.getRoof() != null ) { + if ( mappingTarget.getRoof() == null ) { + mappingTarget.setRoof( new RoofDto() ); + } + roofToRoofDto( house.getRoof(), mappingTarget.getRoof() ); + } + else { + mappingTarget.setRoof( null ); + } + } +}