Skip to content

Commit f0a13bb

Browse files
Yusuf Kemal Özcanfiliphr
authored andcommitted
mapstruct#2555 Add unmappedSourcePolicy annotation processor argument
1 parent 9057d68 commit f0a13bb

File tree

6 files changed

+95
-0
lines changed

6 files changed

+95
-0
lines changed

documentation/src/main/asciidoc/chapter-2-set-up.asciidoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,19 @@ Supported values are:
247247
If a policy is given for a specific mapper via `@Mapper#unmappedTargetPolicy()`, the value from the annotation takes precedence.
248248
If a policy is given for a specific bean mapping via `@BeanMapping#unmappedTargetPolicy()`, it takes precedence over both `@Mapper#unmappedTargetPolicy()` and the option.
249249
|`WARN`
250+
251+
|`mapstruct.unmappedSourcePolicy`
252+
|The default reporting policy to be applied in case an attribute of the source object of a mapping method is not populated with a target value.
253+
254+
Supported values are:
255+
256+
* `ERROR`: any unmapped source property will cause the mapping code generation to fail
257+
* `WARN`: any unmapped source property will cause a warning at build time
258+
* `IGNORE`: unmapped source properties are ignored
259+
260+
If a policy is given for a specific mapper via `@Mapper#unmappedSourcePolicy()`, the value from the annotation takes precedence.
261+
If a policy is given for a specific bean mapping via `@BeanMapping#ignoreUnmappedSourceProperties()`, it takes precedence over both `@Mapper#unmappedSourcePolicy()` and the option.
262+
|`WARN`
250263
|===
251264

252265
=== Using MapStruct with the Java Module System

processor/src/main/java/org/mapstruct/ap/MappingProcessor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
MappingProcessor.SUPPRESS_GENERATOR_TIMESTAMP,
8585
MappingProcessor.SUPPRESS_GENERATOR_VERSION_INFO_COMMENT,
8686
MappingProcessor.UNMAPPED_TARGET_POLICY,
87+
MappingProcessor.UNMAPPED_SOURCE_POLICY,
8788
MappingProcessor.DEFAULT_COMPONENT_MODEL,
8889
MappingProcessor.DEFAULT_INJECTION_STRATEGY,
8990
MappingProcessor.VERBOSE
@@ -99,6 +100,7 @@ public class MappingProcessor extends AbstractProcessor {
99100
protected static final String SUPPRESS_GENERATOR_VERSION_INFO_COMMENT =
100101
"mapstruct.suppressGeneratorVersionInfoComment";
101102
protected static final String UNMAPPED_TARGET_POLICY = "mapstruct.unmappedTargetPolicy";
103+
protected static final String UNMAPPED_SOURCE_POLICY = "mapstruct.unmappedSourcePolicy";
102104
protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel";
103105
protected static final String DEFAULT_INJECTION_STRATEGY = "mapstruct.defaultInjectionStrategy";
104106
protected static final String ALWAYS_GENERATE_SERVICE_FILE = "mapstruct.alwaysGenerateServicesFile";
@@ -134,11 +136,13 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
134136

135137
private Options createOptions() {
136138
String unmappedTargetPolicy = processingEnv.getOptions().get( UNMAPPED_TARGET_POLICY );
139+
String unmappedSourcePolicy = processingEnv.getOptions().get( UNMAPPED_SOURCE_POLICY );
137140

138141
return new Options(
139142
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ),
140143
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ) ),
141144
unmappedTargetPolicy != null ? ReportingPolicyGem.valueOf( unmappedTargetPolicy.toUpperCase() ) : null,
145+
unmappedSourcePolicy != null ? ReportingPolicyGem.valueOf( unmappedSourcePolicy.toUpperCase() ) : null,
142146
processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL ),
143147
processingEnv.getOptions().get( DEFAULT_INJECTION_STRATEGY ),
144148
Boolean.valueOf( processingEnv.getOptions().get( ALWAYS_GENERATE_SERVICE_FILE ) ),

processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public ReportingPolicyGem unmappedTargetPolicy() {
6363

6464
@Override
6565
public ReportingPolicyGem unmappedSourcePolicy() {
66+
if ( options.getUnmappedSourcePolicy() != null ) {
67+
return options.getUnmappedSourcePolicy();
68+
}
6669
return ReportingPolicyGem.valueOf( mapper.unmappedSourcePolicy().getDefaultValue() );
6770
}
6871

processor/src/main/java/org/mapstruct/ap/internal/option/Options.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,21 @@ public class Options {
1717
private final boolean suppressGeneratorTimestamp;
1818
private final boolean suppressGeneratorVersionComment;
1919
private final ReportingPolicyGem unmappedTargetPolicy;
20+
private final ReportingPolicyGem unmappedSourcePolicy;
2021
private final boolean alwaysGenerateSpi;
2122
private final String defaultComponentModel;
2223
private final String defaultInjectionStrategy;
2324
private final boolean verbose;
2425

2526
public Options(boolean suppressGeneratorTimestamp, boolean suppressGeneratorVersionComment,
2627
ReportingPolicyGem unmappedTargetPolicy,
28+
ReportingPolicyGem unmappedSourcePolicy,
2729
String defaultComponentModel, String defaultInjectionStrategy,
2830
boolean alwaysGenerateSpi, boolean verbose) {
2931
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp;
3032
this.suppressGeneratorVersionComment = suppressGeneratorVersionComment;
3133
this.unmappedTargetPolicy = unmappedTargetPolicy;
34+
this.unmappedSourcePolicy = unmappedSourcePolicy;
3235
this.defaultComponentModel = defaultComponentModel;
3336
this.defaultInjectionStrategy = defaultInjectionStrategy;
3437
this.alwaysGenerateSpi = alwaysGenerateSpi;
@@ -47,6 +50,10 @@ public ReportingPolicyGem getUnmappedTargetPolicy() {
4750
return unmappedTargetPolicy;
4851
}
4952

53+
public ReportingPolicyGem getUnmappedSourcePolicy() {
54+
return unmappedSourcePolicy;
55+
}
56+
5057
public String getDefaultComponentModel() {
5158
return defaultComponentModel;
5259
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright MapStruct Authors.
3+
*
4+
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
package org.mapstruct.ap.test.unmappedsource;
7+
8+
import org.mapstruct.Mapper;
9+
import org.mapstruct.ap.test.unmappedtarget.Source;
10+
import org.mapstruct.ap.test.unmappedtarget.Target;
11+
import org.mapstruct.factory.Mappers;
12+
13+
/**
14+
*
15+
* @author Yusuf Kemal Ozcan
16+
*/
17+
@Mapper
18+
public interface SourceTargetMapperWithoutMapperConfig {
19+
20+
SourceTargetMapperWithoutMapperConfig INSTANCE = Mappers.getMapper( SourceTargetMapperWithoutMapperConfig.class );
21+
22+
Target sourceToTarget(Source source);
23+
24+
Source targetToSource(Target target);
25+
}

processor/src/test/java/org/mapstruct/ap/test/unmappedsource/UnmappedSourceTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
1515
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
1616
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
17+
import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption;
1718

1819
import static org.assertj.core.api.Assertions.assertThat;
1920

@@ -67,4 +68,46 @@ public void shouldLeaveUnmappedSourcePropertyUnset() {
6768
)
6869
public void shouldRaiseErrorDueToUnsetSourceProperty() {
6970
}
71+
72+
@ProcessorTest
73+
@WithClasses({ Source.class, Target.class,
74+
org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class })
75+
@ProcessorOption(name = "mapstruct.unmappedTargetPolicy", value = "IGNORE")
76+
@ProcessorOption(name = "mapstruct.unmappedSourcePolicy", value = "ERROR")
77+
@ExpectedCompilationOutcome(
78+
value = CompilationResult.FAILED,
79+
diagnostics = {
80+
@Diagnostic(type = org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class,
81+
kind = Kind.ERROR,
82+
line = 22,
83+
message = "Unmapped source property: \"qux\"."),
84+
@Diagnostic(type = org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class,
85+
kind = Kind.ERROR,
86+
line = 24,
87+
message = "Unmapped source property: \"bar\".")
88+
}
89+
)
90+
public void shouldRaiseErrorDueToUnsetSourcePropertyWithPolicySetViaProcessorOption() {
91+
}
92+
93+
@ProcessorTest
94+
@WithClasses({ Source.class, Target.class,
95+
org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class })
96+
@ProcessorOption(name = "mapstruct.unmappedTargetPolicy", value = "IGNORE")
97+
@ProcessorOption(name = "mapstruct.unmappedSourcePolicy", value = "WARN")
98+
@ExpectedCompilationOutcome(
99+
value = CompilationResult.SUCCEEDED,
100+
diagnostics = {
101+
@Diagnostic(type = org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class,
102+
kind = Kind.WARNING,
103+
line = 22,
104+
message = "Unmapped source property: \"qux\"."),
105+
@Diagnostic(type = org.mapstruct.ap.test.unmappedsource.SourceTargetMapperWithoutMapperConfig.class,
106+
kind = Kind.WARNING,
107+
line = 24,
108+
message = "Unmapped source property: \"bar\".")
109+
}
110+
)
111+
public void shouldLeaveUnmappedSourcePropertyUnsetWithWarnPolicySetViaProcessorOption() {
112+
}
70113
}

0 commit comments

Comments
 (0)