From 76783edc1cfc79cbfb9a500c8559df6bfb063b2c Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Sun, 23 Feb 2014 17:22:48 +0100 Subject: [PATCH] #128 Raising an error in case source enum constant without corresponding constant in target is not mapped --- .../ap/processor/MapperCreationProcessor.java | 34 +++++++++++++++++- .../ap/test/enums/EnumMappingTest.java | 21 +++++++++-- ...usOrderMapperMappingSameConstantTwice.java | 2 ++ ...ppingConstantWithoutMatchInTargetType.java | 35 +++++++++++++++++++ 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java index 56bb23ee6..60f22b2ab 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java @@ -26,6 +26,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; + import javax.annotation.processing.Messager; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -755,7 +756,8 @@ public class MapperCreationProcessor implements ModelElementProcessor sourceEnumConstants = method.getSourceParameters().iterator().next().getType().getEnumConstants(); + List targetEnumConstants = method.getReturnType().getEnumConstants(); + Set mappedSourceEnumConstants = method.getMappings().keySet(); + List unmappedSourceEnumConstants = new ArrayList(); + + for ( String sourceEnumConstant : sourceEnumConstants ) { + if ( !targetEnumConstants.contains( sourceEnumConstant ) && + !mappedSourceEnumConstants.contains( sourceEnumConstant ) ) { + unmappedSourceEnumConstants.add( sourceEnumConstant ); + } + } + + if ( !unmappedSourceEnumConstants.isEmpty() ) { + messager.printMessage( + Kind.ERROR, + String.format( + "The following constants from the source enum have no corresponding constant in the target enum " + + "and must be be mapped via @Mapping: %s", + Strings.join( unmappedSourceEnumConstants, ", " ) + ), + method.getExecutable() + ); + } + + return unmappedSourceEnumConstants.isEmpty(); + } + private TypeConversion getConversion(Type sourceType, Type targetType, String dateFormat, String sourceReference) { ConversionProvider conversionProvider = conversions.getConversion( sourceType, targetType ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java index 511dd7f66..8274f507d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java @@ -77,7 +77,7 @@ public class EnumMappingTest extends MapperTestBase { diagnostics = { @Diagnostic(type = ErroneousOrderMapperMappingSameConstantTwice.class, kind = Kind.ERROR, - line = 39, + line = 42, messageRegExp = "One enum constant must not be mapped to more than one target constant, but " + "constant EXTRA is mapped to SPECIAL, DEFAULT\\.") } @@ -92,15 +92,30 @@ public class EnumMappingTest extends MapperTestBase { diagnostics = { @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, kind = Kind.ERROR, - line = 35, + line = 37, messageRegExp = "Constant FOO doesn't exist in enum type org.mapstruct.ap.test.enums.OrderType\\."), @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, kind = Kind.ERROR, - line = 36, + line = 38, messageRegExp = "Constant BAR doesn't exist in enum type org.mapstruct.ap.test.enums." + "ExternalOrderType\\.") } ) public void shouldRaiseErrorIfUnknownEnumConstantsAreSpecifiedInMapping() { } + + @Test + @WithClasses(ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class, + kind = Kind.ERROR, + line = 34, + messageRegExp = "The following constants from the source enum have no corresponding constant in the " + + "target enum and must be be mapped via @Mapping: EXTRA, STANDARD, NORMAL"), + } + ) + public void shouldRaiseErrorIfSourceConstantWithoutMatchingConstantInTargetTypeIsNotMapped() { + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java index e2725d3ae..65fb4effe 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java +++ b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java @@ -36,6 +36,8 @@ public interface ErroneousOrderMapperMappingSameConstantTwice { @Mappings({ @Mapping(source = "EXTRA", target = "SPECIAL"), @Mapping(source = "EXTRA", target = "DEFAULT"), + @Mapping(source = "STANDARD", target = "DEFAULT"), + @Mapping(source = "NORMAL", target = "DEFAULT") }) ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java new file mode 100644 index 000000000..7f4caa567 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java @@ -0,0 +1,35 @@ +/** + * Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.enums; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Gunnar Morling + */ +@Mapper +public interface ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType { + + ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType INSTANCE = Mappers.getMapper( + ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class + ); + + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); +}