mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#880 Fix override behaviour for componentModel and unmappedTargetPolicy.
This commit is contained in:
parent
c73d007fc8
commit
8071723bae
@ -127,13 +127,12 @@ public class MappingProcessor extends AbstractProcessor {
|
|||||||
|
|
||||||
private Options createOptions() {
|
private Options createOptions() {
|
||||||
String unmappedTargetPolicy = processingEnv.getOptions().get( UNMAPPED_TARGET_POLICY );
|
String unmappedTargetPolicy = processingEnv.getOptions().get( UNMAPPED_TARGET_POLICY );
|
||||||
String defaultComponentModel = processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL );
|
|
||||||
|
|
||||||
return new Options(
|
return new Options(
|
||||||
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ),
|
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ),
|
||||||
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ) ),
|
Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ) ),
|
||||||
unmappedTargetPolicy != null ? ReportingPolicy.valueOf( unmappedTargetPolicy ) : null,
|
unmappedTargetPolicy != null ? ReportingPolicy.valueOf( unmappedTargetPolicy.toUpperCase() ) : null,
|
||||||
defaultComponentModel == null ? "default" : defaultComponentModel,
|
processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL ),
|
||||||
Boolean.valueOf( processingEnv.getOptions().get( ALWAYS_GENERATE_SERVICE_FILE ) )
|
Boolean.valueOf( processingEnv.getOptions().get( ALWAYS_GENERATE_SERVICE_FILE ) )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -508,32 +508,16 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
return method.getResultType().getPropertyReadAccessors().get( propertyName );
|
return method.getResultType().getPropertyReadAccessors().get( propertyName );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private ReportingPolicy getUnmappedTargetPolicy() {
|
||||||
* Returns the effective policy for reporting unmapped getReturnType properties. If explicitly set via
|
|
||||||
* {@code Mapper}, this value will be returned. Otherwise the value from the corresponding processor option will
|
|
||||||
* be returned. If that is not set either, the default value from {@code Mapper#unmappedTargetPolicy()} will be
|
|
||||||
* returned.
|
|
||||||
*
|
|
||||||
* @return The effective policy for reporting unmapped target properties.
|
|
||||||
*/
|
|
||||||
private ReportingPolicy getEffectiveUnmappedTargetPolicy() {
|
|
||||||
MapperConfiguration mapperSettings = MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() );
|
MapperConfiguration mapperSettings = MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() );
|
||||||
boolean setViaAnnotation = mapperSettings.isSetUnmappedTargetPolicy();
|
|
||||||
ReportingPolicy annotationValue = ReportingPolicy.valueOf( mapperSettings.unmappedTargetPolicy() );
|
|
||||||
|
|
||||||
if ( setViaAnnotation
|
return mapperSettings.unmappedTargetPolicy( ctx.getOptions() );
|
||||||
|| ctx.getOptions().getUnmappedTargetPolicy() == null ) {
|
|
||||||
return annotationValue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ctx.getOptions().getUnmappedTargetPolicy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportErrorForUnmappedTargetPropertiesIfRequired() {
|
private void reportErrorForUnmappedTargetPropertiesIfRequired() {
|
||||||
|
|
||||||
// fetch settings from element to implement
|
// fetch settings from element to implement
|
||||||
ReportingPolicy unmappedTargetPolicy = getEffectiveUnmappedTargetPolicy();
|
ReportingPolicy unmappedTargetPolicy = getUnmappedTargetPolicy();
|
||||||
|
|
||||||
if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) {
|
if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) {
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ import org.mapstruct.ap.internal.model.Field;
|
|||||||
import org.mapstruct.ap.internal.model.Mapper;
|
import org.mapstruct.ap.internal.model.Mapper;
|
||||||
import org.mapstruct.ap.internal.model.MapperReference;
|
import org.mapstruct.ap.internal.model.MapperReference;
|
||||||
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
||||||
import org.mapstruct.ap.internal.option.OptionsHelper;
|
|
||||||
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,13 +50,10 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle
|
|||||||
public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, Mapper mapper) {
|
public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, Mapper mapper) {
|
||||||
this.typeFactory = context.getTypeFactory();
|
this.typeFactory = context.getTypeFactory();
|
||||||
|
|
||||||
String componentModel = MapperConfiguration.getInstanceOn( mapperTypeElement ).componentModel();
|
String componentModel = MapperConfiguration.getInstanceOn( mapperTypeElement )
|
||||||
String effectiveComponentModel = OptionsHelper.getEffectiveComponentModel(
|
.componentModel( context.getOptions() );
|
||||||
context.getOptions(),
|
|
||||||
componentModel
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( !getComponentModelIdentifier().equalsIgnoreCase( effectiveComponentModel ) ) {
|
if ( !getComponentModelIdentifier().equalsIgnoreCase( componentModel ) ) {
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import javax.tools.StandardLocation;
|
|||||||
import org.mapstruct.ap.internal.model.GeneratedType;
|
import org.mapstruct.ap.internal.model.GeneratedType;
|
||||||
import org.mapstruct.ap.internal.model.Mapper;
|
import org.mapstruct.ap.internal.model.Mapper;
|
||||||
import org.mapstruct.ap.internal.model.ServicesEntry;
|
import org.mapstruct.ap.internal.model.ServicesEntry;
|
||||||
import org.mapstruct.ap.internal.option.OptionsHelper;
|
|
||||||
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
||||||
import org.mapstruct.ap.internal.writer.ModelWriter;
|
import org.mapstruct.ap.internal.writer.ModelWriter;
|
||||||
|
|
||||||
@ -50,13 +49,10 @@ public class MapperServiceProcessor implements ModelElementProcessor<Mapper, Vo
|
|||||||
spiGenerationNeeded = true;
|
spiGenerationNeeded = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String componentModel = MapperConfiguration.getInstanceOn( mapperTypeElement ).componentModel();
|
String componentModel =
|
||||||
String effectiveComponentModel = OptionsHelper.getEffectiveComponentModel(
|
MapperConfiguration.getInstanceOn( mapperTypeElement ).componentModel( context.getOptions() );
|
||||||
context.getOptions(),
|
|
||||||
componentModel
|
|
||||||
);
|
|
||||||
|
|
||||||
spiGenerationNeeded = "default".equals( effectiveComponentModel );
|
spiGenerationNeeded = "default".equals( componentModel );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !context.isErroneous() && spiGenerationNeeded && mapper.hasCustomImplementation() ) {
|
if ( !context.isErroneous() && spiGenerationNeeded && mapper.hasCustomImplementation() ) {
|
||||||
|
@ -27,12 +27,14 @@ import javax.lang.model.element.Element;
|
|||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.internal.option.Options;
|
||||||
|
import org.mapstruct.ap.internal.option.ReportingPolicy;
|
||||||
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.prism.MapperConfigPrism;
|
import org.mapstruct.ap.internal.prism.MapperConfigPrism;
|
||||||
import org.mapstruct.ap.internal.prism.MapperPrism;
|
import org.mapstruct.ap.internal.prism.MapperPrism;
|
||||||
import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism;
|
import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
|
|
||||||
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
||||||
|
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and
|
* Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and
|
||||||
@ -109,13 +111,21 @@ public class MapperConfiguration {
|
|||||||
return mapperPrism.imports();
|
return mapperPrism.imports();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String unmappedTargetPolicy() {
|
public ReportingPolicy unmappedTargetPolicy(Options options) {
|
||||||
if ( mapperConfigPrism != null && mapperPrism.values.unmappedTargetPolicy() == null ) {
|
if ( mapperPrism.values.unmappedTargetPolicy() != null ) {
|
||||||
return mapperConfigPrism.unmappedTargetPolicy();
|
return ReportingPolicy.valueOf( mapperPrism.unmappedTargetPolicy() );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return mapperPrism.unmappedTargetPolicy();
|
if ( mapperConfigPrism != null && mapperConfigPrism.values.unmappedTargetPolicy() != null ) {
|
||||||
|
return ReportingPolicy.valueOf( mapperConfigPrism.unmappedTargetPolicy() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( options.getUnmappedTargetPolicy() != null ) {
|
||||||
|
return options.getUnmappedTargetPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall back to default defined in the annotation
|
||||||
|
return ReportingPolicy.valueOf( mapperPrism.unmappedTargetPolicy() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollectionMappingStrategyPrism getCollectionMappingStrategy() {
|
public CollectionMappingStrategyPrism getCollectionMappingStrategy() {
|
||||||
@ -169,13 +179,20 @@ public class MapperConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String componentModel() {
|
public String componentModel(Options options) {
|
||||||
if ( mapperConfigPrism != null && mapperPrism.values.componentModel() == null ) {
|
if ( mapperPrism.values.componentModel() != null ) {
|
||||||
return mapperConfigPrism.componentModel();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return mapperPrism.componentModel();
|
return mapperPrism.componentModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( mapperConfigPrism != null && mapperConfigPrism.values.componentModel() != null ) {
|
||||||
|
return mapperConfigPrism.componentModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( options.getDefaultComponentModel() != null ) {
|
||||||
|
return options.getDefaultComponentModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapperPrism.componentModel(); // fall back to default defined in the annotation
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeclaredType config() {
|
public DeclaredType config() {
|
||||||
@ -186,12 +203,7 @@ public class MapperConfiguration {
|
|||||||
return mapperPrism.isValid;
|
return mapperPrism.isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSetUnmappedTargetPolicy() {
|
|
||||||
return mapperPrism.values.unmappedTargetPolicy() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnnotationMirror getAnnotationMirror() {
|
public AnnotationMirror getAnnotationMirror() {
|
||||||
return mapperPrism.mirror;
|
return mapperPrism.mirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2016 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.bugs._880;
|
||||||
|
|
||||||
|
import org.mapstruct.MapperConfig;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
@MapperConfig(unmappedTargetPolicy = ReportingPolicy.WARN)
|
||||||
|
public interface Config {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2016 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.bugs._880;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface DefaultsToProcessorOptionsMapper {
|
||||||
|
Poodle metamorph(Object essence);
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2016 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.bugs._880;
|
||||||
|
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
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.compilation.annotation.ProcessorOption;
|
||||||
|
import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOptions;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
import org.mapstruct.ap.testutil.runner.GeneratedSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*/
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@WithClasses({
|
||||||
|
UsesConfigFromAnnotationMapper.class,
|
||||||
|
DefaultsToProcessorOptionsMapper.class,
|
||||||
|
Poodle.class,
|
||||||
|
Config.class })
|
||||||
|
@ProcessorOptions({
|
||||||
|
@ProcessorOption(name = "mapstruct.defaultComponentModel", value = "spring"),
|
||||||
|
@ProcessorOption(name = "mapstruct.unmappedTargetPolicy", value = "ignore") })
|
||||||
|
public class Issue880Test {
|
||||||
|
@Rule
|
||||||
|
public GeneratedSource generatedSource = new GeneratedSource();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ExpectedCompilationOutcome(
|
||||||
|
value = CompilationResult.SUCCEEDED,
|
||||||
|
diagnostics = @Diagnostic(kind = Kind.WARNING,
|
||||||
|
type = UsesConfigFromAnnotationMapper.class, line = 29,
|
||||||
|
messageRegExp = "Unmapped target property: \"core\"\\."))
|
||||||
|
public void compilationSucceedsAndAppliesCorrectComponentModel() {
|
||||||
|
generatedSource.forMapper( UsesConfigFromAnnotationMapper.class ).containsNoImportFor( Component.class );
|
||||||
|
|
||||||
|
generatedSource.forMapper( DefaultsToProcessorOptionsMapper.class ).containsImportFor( Component.class );
|
||||||
|
}
|
||||||
|
}
|
@ -16,30 +16,20 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.option;
|
package org.mapstruct.ap.test.bugs._880;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for dealing with {@link Options}.
|
|
||||||
*
|
|
||||||
* @author Andreas Gudian
|
* @author Andreas Gudian
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class OptionsHelper {
|
public class Poodle {
|
||||||
|
private String core;
|
||||||
|
|
||||||
private OptionsHelper() {
|
public String getCore() {
|
||||||
|
return core;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setCore(String core) {
|
||||||
* @param options the options
|
this.core = core;
|
||||||
* @param locallyDeclaredComponentModel the locally declared component model
|
|
||||||
*
|
|
||||||
* @return the effective component model to be used
|
|
||||||
*/
|
|
||||||
public static String getEffectiveComponentModel(Options options, String locallyDeclaredComponentModel) {
|
|
||||||
if ( "default".equals( locallyDeclaredComponentModel ) ) {
|
|
||||||
return options.getDefaultComponentModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
return locallyDeclaredComponentModel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2016 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.bugs._880;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Gudian
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = "default", config = Config.class)
|
||||||
|
public interface UsesConfigFromAnnotationMapper {
|
||||||
|
Poodle metamorph(Object essence);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user