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 97448470d..56bb23ee6 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java @@ -26,7 +26,6 @@ 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; @@ -756,6 +755,10 @@ public class MapperCreationProcessor implements ModelElementProcessor enumMappings = new ArrayList(); List sourceEnumConstants = method.getSourceParameters().iterator().next().getType().getEnumConstants(); @@ -779,19 +782,83 @@ public class MapperCreationProcessor implements ModelElementProcessor sourceEnumConstants = method.getSourceParameters().iterator().next().getType().getEnumConstants(); + List targetEnumConstants = method.getReturnType().getEnumConstants(); + + boolean foundIncorrectMapping = false; + + for ( List mappedConstants : method.getMappings().values() ) { + for ( Mapping mappedConstant : mappedConstants ) { + if ( mappedConstant.getSourceName() == null ) { + messager.printMessage( + Kind.ERROR, + "A source constant must be specified for mappings of an enum mapping method.", + method.getExecutable(), + mappedConstant.getMirror() + ); + foundIncorrectMapping = true; + } + else if ( !sourceEnumConstants.contains( mappedConstant.getSourceName() ) ) { + messager.printMessage( + Kind.ERROR, + String.format( + "Constant %s doesn't exist in enum type %s.", + mappedConstant.getSourceName(), + method.getSourceParameters().iterator().next().getType() + ), + method.getExecutable(), + mappedConstant.getMirror(), + mappedConstant.getSourceAnnotationValue() + ); + foundIncorrectMapping = true; + } + if ( mappedConstant.getTargetName() == null ) { + messager.printMessage( + Kind.ERROR, + "A target constant must be specified for mappings of an enum mapping method.", + method.getExecutable(), + mappedConstant.getMirror() + ); + foundIncorrectMapping = true; + } + else if ( !targetEnumConstants.contains( mappedConstant.getTargetName() ) ) { + messager.printMessage( + Kind.ERROR, + String.format( + "Constant %s doesn't exist in enum type %s.", + mappedConstant.getTargetName(), + method.getReturnType() + ), + method.getExecutable(), + mappedConstant.getMirror(), + mappedConstant.getTargetAnnotationValue() + ); + foundIncorrectMapping = true; + } + } + } + + return !foundIncorrectMapping; + } + 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 e3591a67f..511dd7f66 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 @@ -83,6 +83,24 @@ public class EnumMappingTest extends MapperTestBase { } ) public void shouldRaiseErrorIfSameSourceEnumConstantIsMappedTwice() { + } + @Test + @WithClasses(ErroneousOrderMapperUsingUnknownEnumConstants.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, + kind = Kind.ERROR, + line = 35, + messageRegExp = "Constant FOO doesn't exist in enum type org.mapstruct.ap.test.enums.OrderType\\."), + @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, + kind = Kind.ERROR, + line = 36, + messageRegExp = "Constant BAR doesn't exist in enum type org.mapstruct.ap.test.enums." + + "ExternalOrderType\\.") + } + ) + public void shouldRaiseErrorIfUnknownEnumConstantsAreSpecifiedInMapping() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java new file mode 100644 index 000000000..8c1f797aa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java @@ -0,0 +1,41 @@ +/** + * 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.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +/** + * @author Gunnar Morling + */ +@Mapper +public interface ErroneousOrderMapperUsingUnknownEnumConstants { + + ErroneousOrderMapperUsingUnknownEnumConstants INSTANCE = Mappers.getMapper( + ErroneousOrderMapperUsingUnknownEnumConstants.class + ); + + @Mappings({ + @Mapping(source = "FOO", target = "SPECIAL"), + @Mapping(source = "EXTRA", target = "BAR"), + }) + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); +}