#128 Raising an error in case mapped enum constants don't exist

This commit is contained in:
Gunnar Morling 2014-02-23 16:48:16 +01:00
parent 033def2054
commit d8df52dbc0
3 changed files with 129 additions and 3 deletions

View File

@ -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<List<Sourc
}
private EnumMappingMethod getEnumMappingMethod(SourceMethod method) {
if ( !reportErrorIfMappedEnumConstantsDontExist( method ) ) {
return null;
}
List<EnumMapping> enumMappings = new ArrayList<EnumMapping>();
List<String> sourceEnumConstants = method.getSourceParameters().iterator().next().getType().getEnumConstants();
@ -779,19 +782,83 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
Kind.ERROR,
String.format(
"One enum constant must not be mapped to more than one target constant, but constant %s is " +
"mapped to %s.",
"mapped to %s.",
enumConstant,
Strings.join( targetConstants, ", " )
),
method.getExecutable()
);
}
}
return new EnumMappingMethod( method, enumMappings );
}
private boolean reportErrorIfMappedEnumConstantsDontExist(SourceMethod method) {
// only report errors if this method itself is configured
if ( method.isConfiguredByReverseMappingMethod() ) {
return true;
}
List<String> sourceEnumConstants = method.getSourceParameters().iterator().next().getType().getEnumConstants();
List<String> targetEnumConstants = method.getReturnType().getEnumConstants();
boolean foundIncorrectMapping = false;
for ( List<Mapping> 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 );

View File

@ -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() {
}
}

View File

@ -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);
}