#1851 Do not allow using qualifiedBy and qualifiedByName with expression in Mapping

This commit is contained in:
dekelpilli 2019-09-22 21:53:19 +10:00 committed by Filip Hrisafov
parent 55fe94a93e
commit f84f6501c8
6 changed files with 84 additions and 1 deletions

View File

@ -136,7 +136,7 @@ public @interface Mapping {
* imported via {@link Mapper#imports()}.
* <p>
* This attribute can not be used together with {@link #source()}, {@link #defaultValue()},
* {@link #defaultExpression()} or {@link #constant()}.
* {@link #defaultExpression()}, {@link #qualifiedBy()}, {@link #qualifiedByName()} or {@link #constant()}.
*
* @return An expression specifying the value for the designated target property
*/

View File

@ -236,6 +236,10 @@ public class Mapping {
else if ( mappingPrism.values.defaultValue() != null && mappingPrism.values.defaultExpression() != null ) {
message = Message.PROPERTYMAPPING_DEFAULT_VALUE_AND_DEFAULT_EXPRESSION_BOTH_DEFINED;
}
else if ( mappingPrism.values.expression() != null
&& ( mappingPrism.values.qualifiedByName() != null || mappingPrism.values.qualifiedBy() != null ) ) {
message = Message.PROPERTYMAPPING_EXPRESSION_AND_QUALIFIER_BOTH_DEFINED;
}
else if ( mappingPrism.values.nullValuePropertyMappingStrategy() != null
&& mappingPrism.values.defaultValue() != null ) {
message = Message.PROPERTYMAPPING_DEFAULT_VALUE_AND_NVPMS;

View File

@ -57,6 +57,7 @@ public enum Message {
PROPERTYMAPPING_CONSTANT_VALUE_AND_NVPMS( "Constant and nullValuePropertyMappingStrategy are both defined in @Mapping, either define a constant or an nullValuePropertyMappingStrategy." ),
PROPERTYMAPPING_DEFAULT_EXPERSSION_AND_NVPMS( "DefaultExpression and nullValuePropertyMappingStrategy are both defined in @Mapping, either define a defaultExpression or an nullValuePropertyMappingStrategy." ),
PROPERTYMAPPING_IGNORE_AND_NVPMS( "Ignore and nullValuePropertyMappingStrategy are both defined in @Mapping, either define ignore or an nullValuePropertyMappingStrategy." ),
PROPERTYMAPPING_EXPRESSION_AND_QUALIFIER_BOTH_DEFINED("Expression and a qualifier both defined in @Mapping, either define an expression or a qualifier."),
PROPERTYMAPPING_INVALID_EXPRESSION( "Value for expression must be given in the form \"java(<EXPRESSION>)\"." ),
PROPERTYMAPPING_INVALID_DEFAULT_EXPRESSION( "Value for default expression must be given in the form \"java(<EXPRESSION>)\"." ),
PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no source parameter named \"%s\". Method source parameters are: \"%s\"." ),

View File

@ -0,0 +1,29 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.source.expressions.java;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.ReportingPolicy;
@Mapper( uses = QualifierProvider.class, unmappedTargetPolicy = ReportingPolicy.IGNORE )
public interface ErroneousSourceTargetMapperExpressionAndQualifiers {
@Mappings( {
@Mapping( target = "anotherProp", expression = "java( s.getClass().getName() )", qualifiedByName = "toUpper" ),
@Mapping( target = "timeAndFormat", ignore = true )
} )
Target sourceToTargetWithExpressionAndNamedQualifier(Source s, @MappingTarget Target t);
@Mappings( {
@Mapping( target = "anotherProp", expression = "java( s.getClass().getName() )",
qualifiedBy = QualifierProvider.ToUpper.class ),
@Mapping( target = "timeAndFormat", ignore = true )
} )
Target sourceToTargetWithExpressionAndQualifier(Source s, @MappingTarget Target t);
}

View File

@ -17,6 +17,9 @@ import org.junit.runner.RunWith;
import org.mapstruct.ap.test.source.expressions.java.mapper.TimeAndFormat;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
/**
@ -131,4 +134,33 @@ public class JavaExpressionTest {
assertThat( target ).isNotNull();
assertThat( target.getList() ).isEqualTo( Arrays.asList( "test2" ) );
}
@IssueKey( "1851" )
@Test
@WithClasses({
Source.class,
Target.class,
QualifierProvider.class,
TimeAndFormat.class,
ErroneousSourceTargetMapperExpressionAndQualifiers.class
})
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(type = ErroneousSourceTargetMapperExpressionAndQualifiers.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
line = 18,
messageRegExp = "Expression and a qualifier both defined in @Mapping," +
" either define an expression or a qualifier."
),
@Diagnostic(type = ErroneousSourceTargetMapperExpressionAndQualifiers.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
line = 24,
messageRegExp = "Expression and a qualifier both defined in @Mapping," +
" either define an expression or a qualifier."
)
}
)
public void testExpressionAndQualifiedDoesNotCompile() {
}
}

View File

@ -0,0 +1,17 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.source.expressions.java;
public class QualifierProvider {
public @interface ToUpper {
}
@ToUpper
public String toUpper( String string ) {
return string.toUpperCase();
}
}