#1661 Add support for globally disabling builders

This commit is contained in:
Filip Hrisafov 2022-01-29 11:46:34 +01:00 committed by GitHub
parent aade31f095
commit 5f4d355838
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 5 deletions

View File

@ -260,6 +260,11 @@ Supported values are:
If a policy is given for a specific mapper via `@Mapper#unmappedSourcePolicy()`, the value from the annotation takes precedence.
If a policy is given for a specific bean mapping via `@BeanMapping#ignoreUnmappedSourceProperties()`, it takes precedence over both `@Mapper#unmappedSourcePolicy()` and the option.
|`WARN`
|`mapstruct.
disableBuilders`
|If set to `true`, then MapStruct will not use builder patterns when doing the mapping. This is equivalent to doing `@Mapper( builder = @Builder( disableBuilder = true ) )` for all of your mappers.
|`false`
|===
=== Using MapStruct with the Java Module System

View File

@ -532,7 +532,7 @@ Otherwise, you would need to write a custom `BuilderProvider`
[TIP]
====
In case you want to disable using builders then you can use the `NoOpBuilderProvider` by creating a `org.mapstruct.ap.spi.BuilderProvider` file in the `META-INF/services` directory with `org.mapstruct.ap.spi.NoOpBuilderProvider` as it's content.
In case you want to disable using builders then you can pass the MapStruct processor option `mapstruct.disableBuilders` to the compiler. e.g. `-Amapstruct.disableBuilders=true`.
====
[[mapping-with-constructors]]

View File

@ -87,6 +87,7 @@ import static javax.lang.model.element.ElementKind.CLASS;
MappingProcessor.UNMAPPED_SOURCE_POLICY,
MappingProcessor.DEFAULT_COMPONENT_MODEL,
MappingProcessor.DEFAULT_INJECTION_STRATEGY,
MappingProcessor.DISABLE_BUILDERS,
MappingProcessor.VERBOSE
})
public class MappingProcessor extends AbstractProcessor {
@ -104,6 +105,7 @@ public class MappingProcessor extends AbstractProcessor {
protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel";
protected static final String DEFAULT_INJECTION_STRATEGY = "mapstruct.defaultInjectionStrategy";
protected static final String ALWAYS_GENERATE_SERVICE_FILE = "mapstruct.alwaysGenerateServicesFile";
protected static final String DISABLE_BUILDERS = "mapstruct.disableBuilders";
protected static final String VERBOSE = "mapstruct.verbose";
private Options options;
@ -130,6 +132,7 @@ public class MappingProcessor extends AbstractProcessor {
processingEnv.getElementUtils(),
processingEnv.getTypeUtils(),
processingEnv.getMessager(),
options.isDisableBuilders(),
options.isVerbose()
);
}
@ -146,6 +149,7 @@ public class MappingProcessor extends AbstractProcessor {
processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL ),
processingEnv.getOptions().get( DEFAULT_INJECTION_STRATEGY ),
Boolean.valueOf( processingEnv.getOptions().get( ALWAYS_GENERATE_SERVICE_FILE ) ),
Boolean.valueOf( processingEnv.getOptions().get( DISABLE_BUILDERS ) ),
Boolean.valueOf( processingEnv.getOptions().get( VERBOSE ) )
);
}

View File

@ -21,13 +21,16 @@ public class Options {
private final boolean alwaysGenerateSpi;
private final String defaultComponentModel;
private final String defaultInjectionStrategy;
private final boolean disableBuilders;
private final boolean verbose;
public Options(boolean suppressGeneratorTimestamp, boolean suppressGeneratorVersionComment,
ReportingPolicyGem unmappedTargetPolicy,
ReportingPolicyGem unmappedSourcePolicy,
String defaultComponentModel, String defaultInjectionStrategy,
boolean alwaysGenerateSpi, boolean verbose) {
boolean alwaysGenerateSpi,
boolean disableBuilders,
boolean verbose) {
this.suppressGeneratorTimestamp = suppressGeneratorTimestamp;
this.suppressGeneratorVersionComment = suppressGeneratorVersionComment;
this.unmappedTargetPolicy = unmappedTargetPolicy;
@ -35,6 +38,7 @@ public class Options {
this.defaultComponentModel = defaultComponentModel;
this.defaultInjectionStrategy = defaultInjectionStrategy;
this.alwaysGenerateSpi = alwaysGenerateSpi;
this.disableBuilders = disableBuilders;
this.verbose = verbose;
}
@ -66,6 +70,10 @@ public class Options {
return alwaysGenerateSpi;
}
public boolean isDisableBuilders() {
return disableBuilders;
}
public boolean isVerbose() {
return verbose;
}

View File

@ -31,6 +31,7 @@ import org.mapstruct.ap.spi.FreeBuilderAccessorNamingStrategy;
import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy;
import org.mapstruct.ap.spi.ImmutablesBuilderProvider;
import org.mapstruct.ap.spi.MapStructProcessingEnvironment;
import org.mapstruct.ap.spi.NoOpBuilderProvider;
/**
* Keeps contextual data in the scope of the entire annotation processor ("application scope").
@ -51,14 +52,17 @@ public class AnnotationProcessorContext implements MapStructProcessingEnvironmen
private Elements elementUtils;
private Types typeUtils;
private Messager messager;
private boolean disableBuilder;
private boolean verbose;
public AnnotationProcessorContext(Elements elementUtils, Types typeUtils, Messager messager, boolean verbose) {
public AnnotationProcessorContext(Elements elementUtils, Types typeUtils, Messager messager, boolean disableBuilder,
boolean verbose) {
astModifyingAnnotationProcessors = java.util.Collections.unmodifiableList(
findAstModifyingAnnotationProcessors( messager ) );
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
this.messager = messager;
this.disableBuilder = disableBuilder;
this.verbose = verbose;
}
@ -103,7 +107,9 @@ public class AnnotationProcessorContext implements MapStructProcessingEnvironmen
+ this.accessorNamingStrategy.getClass().getCanonicalName()
);
}
this.builderProvider = Services.get( BuilderProvider.class, defaultBuilderProvider );
this.builderProvider = this.disableBuilder ?
new NoOpBuilderProvider() :
Services.get( BuilderProvider.class, defaultBuilderProvider );
this.builderProvider.init( this );
if ( verbose ) {
messager.printMessage(

View File

@ -9,12 +9,13 @@ import org.junit.jupiter.api.extension.RegisterExtension;
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.ProcessorOption;
import org.mapstruct.ap.testutil.runner.GeneratedSource;
import org.mapstruct.factory.Mappers;
import static org.assertj.core.api.Assertions.assertThat;
@IssueKey("1743")
@IssueKey("1661")
@WithClasses({
SimpleMutablePerson.class,
SimpleNotRealyImmutablePerson.class
@ -36,4 +37,18 @@ public class SimpleNotRealyImmutableBuilderTest {
assertThat( targetObject.getName() ).isEqualTo( "Bob" );
}
@ProcessorTest
@WithClasses({ SimpleWithBuilderMapper.class })
@ProcessorOption( name = "mapstruct.disableBuilders", value = "true")
public void builderGloballyDisabled() {
SimpleWithBuilderMapper mapper = Mappers.getMapper( SimpleWithBuilderMapper.class );
SimpleMutablePerson source = new SimpleMutablePerson();
source.setFullName( "Bob" );
SimpleNotRealyImmutablePerson targetObject = mapper.toNotRealyImmutable( source );
assertThat( targetObject.getName() ).isEqualTo( "Bob" );
}
}

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.builder.off;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface SimpleWithBuilderMapper {
@Mapping(target = "name", source = "fullName")
SimpleNotRealyImmutablePerson toNotRealyImmutable(SimpleMutablePerson source);
}