Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions core/src/main/java/org/mapstruct/BeanMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy()
*/
String[] ignoreUnmappedSourceProperties() default {};

/**
* How unmapped properties of the source type of a mapping should be reported.
* If no policy is configured, the policy given via {@link MapperConfig#unmappedSourcePolicy()} or
* {@link Mapper#unmappedSourcePolicy()} will be applied, using {@link ReportingPolicy#IGNORE} by default.
*
* @return The reporting policy for unmapped source properties.
*
* @since 1.6
*/
ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE;

/**
* How unmapped properties of the target type of a mapping should be reported.
* If no policy is configured, the policy given via {@link MapperConfig#unmappedTargetPolicy()} or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,7 @@ private ReportingPolicyGem getUnmappedSourcePolicy() {
if ( method.getOptions().getBeanMapping().isignoreByDefault() ) {
return ReportingPolicyGem.IGNORE;
}
return method.getOptions().getMapper().unmappedSourcePolicy();
return method.getOptions().getBeanMapping().unmappedSourcePolicy();
}

private void reportErrorForUnmappedSourcePropertiesIfRequired() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ private static boolean isConsistent(BeanMappingGem gem, ExecutableElement method
&& !gem.nullValueMappingStrategy().hasValue()
&& !gem.subclassExhaustiveStrategy().hasValue()
&& !gem.unmappedTargetPolicy().hasValue()
&& !gem.unmappedSourcePolicy().hasValue()
&& !gem.ignoreByDefault().hasValue()
&& !gem.builder().hasValue() ) {

Expand Down Expand Up @@ -179,6 +180,15 @@ public ReportingPolicyGem unmappedTargetPolicy() {
.orElse( next().unmappedTargetPolicy() );
}

@Override
public ReportingPolicyGem unmappedSourcePolicy() {
return Optional.ofNullable( beanMapping ).map( BeanMappingGem::unmappedSourcePolicy )
.filter( GemValue::hasValue )
.map( GemValue::getValue )
.map( ReportingPolicyGem::valueOf )
.orElse( next().unmappedSourcePolicy() );
}

@Override
public BuilderGem getBuilder() {
return Optional.ofNullable( beanMapping ).map( BeanMappingGem::builder )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,5 @@ public void shouldRaiseErrorDueToUnsetSourcePropertyWithPolicySetViaProcessorOpt
)
public void shouldLeaveUnmappedSourcePropertyUnsetWithWarnPolicySetViaProcessorOption() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.unmappedsource.beanmapping;

import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;

@Mapper(unmappedSourcePolicy = ReportingPolicy.WARN)
public interface BeanMappingSourcePolicyErroneousMapper {

@BeanMapping(unmappedSourcePolicy = ReportingPolicy.ERROR)
Target map(Source source);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.unmappedsource.beanmapping;

import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import org.mapstruct.factory.Mappers;

@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR)
public interface BeanMappingSourcePolicyMapper {

BeanMappingSourcePolicyMapper MAPPER =
Mappers.getMapper( BeanMappingSourcePolicyMapper.class );

@BeanMapping(unmappedSourcePolicy = ReportingPolicy.WARN)
Target map(Source source);

@BeanMapping(unmappedSourcePolicy = ReportingPolicy.IGNORE)
Target map2(Source source);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.unmappedsource.beanmapping;

public class Source {

private int foo;

private int bar;

public int getFoo() {
return foo;
}

public void setFoo(int foo) {
this.foo = foo;
}

public int getBar() {
return bar;
}

public void setBar(int bar) {
this.bar = bar;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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.unmappedsource.beanmapping;

public class Target {

private int foo;

public int getFoo() {
return foo;
}

public void setFoo(int foo) {
this.foo = foo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.unmappedsource.beanmapping;

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

import javax.tools.Diagnostic.Kind;

import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
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;

@IssueKey("3309")
class UnmappedSourceTest {

@ProcessorTest
@WithClasses({ Source.class, Target.class, BeanMappingSourcePolicyMapper.class })
@ExpectedCompilationOutcome(
value = CompilationResult.SUCCEEDED,
diagnostics = {
@Diagnostic(type = BeanMappingSourcePolicyMapper.class,
kind = Kind.WARNING,
line = 20,
message = "Unmapped source property: \"bar\".")
}
)
public void shouldCompileWithUnmappedSourcePolicySetToWarnWithBeanMapping() {
Source source = new Source();
Source source2 = new Source();

source.setFoo( 10 );
source.setBar( 20 );

source2.setFoo( 1 );
source2.setBar( 2 );

Target target = BeanMappingSourcePolicyMapper.MAPPER.map( source );
Target target2 = BeanMappingSourcePolicyMapper.MAPPER.map2( source2 );

assertThat( target ).isNotNull();
assertThat( target.getFoo() ).isEqualTo( 10 );

assertThat( target2 ).isNotNull();
assertThat( target2.getFoo() ).isEqualTo( 1 );
}

@ProcessorTest
@WithClasses({ Source.class, Target.class, BeanMappingSourcePolicyErroneousMapper.class })
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(type = BeanMappingSourcePolicyErroneousMapper.class,
kind = Kind.ERROR,
line = 16,
message = "Unmapped source property: \"bar\".")
}
)
public void shouldErrorWithUnmappedSourcePolicySetToErrorWithBeanMapping() {
}

}