mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
parent
1c4bbba442
commit
ade4f4d7e2
@ -42,7 +42,6 @@ import org.mapstruct.ap.internal.model.source.MappingOptions;
|
|||||||
import org.mapstruct.ap.internal.model.source.Method;
|
import org.mapstruct.ap.internal.model.source.Method;
|
||||||
import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
||||||
import org.mapstruct.ap.internal.model.source.SourceMethod;
|
import org.mapstruct.ap.internal.model.source.SourceMethod;
|
||||||
import org.mapstruct.ap.internal.prism.BeanMappingPrism;
|
|
||||||
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
|
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.prism.ReportingPolicyPrism;
|
import org.mapstruct.ap.internal.prism.ReportingPolicyPrism;
|
||||||
@ -393,7 +392,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
if ( resultType.isAbstract() ) {
|
if ( resultType.isAbstract() ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
BeanMappingPrism.getInstanceOn( method.getExecutable() ).mirror,
|
method.getMappingOptions().getBeanMapping().getMirror(),
|
||||||
BEANMAPPING_ABSTRACT,
|
BEANMAPPING_ABSTRACT,
|
||||||
resultType,
|
resultType,
|
||||||
method.getResultType()
|
method.getResultType()
|
||||||
@ -403,7 +402,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
else if ( !resultType.isAssignableTo( method.getResultType() ) ) {
|
else if ( !resultType.isAssignableTo( method.getResultType() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
BeanMappingPrism.getInstanceOn( method.getExecutable() ).mirror,
|
method.getMappingOptions().getBeanMapping().getMirror(),
|
||||||
BEANMAPPING_NOT_ASSIGNABLE,
|
BEANMAPPING_NOT_ASSIGNABLE,
|
||||||
resultType,
|
resultType,
|
||||||
method.getResultType()
|
method.getResultType()
|
||||||
@ -413,7 +412,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
|||||||
else if ( !resultType.hasEmptyAccessibleConstructor() ) {
|
else if ( !resultType.hasEmptyAccessibleConstructor() ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
BeanMappingPrism.getInstanceOn( method.getExecutable() ).mirror,
|
method.getMappingOptions().getBeanMapping().getMirror(),
|
||||||
Message.GENERAL_NO_SUITABLE_CONSTRUCTOR,
|
Message.GENERAL_NO_SUITABLE_CONSTRUCTOR,
|
||||||
resultType
|
resultType
|
||||||
);
|
);
|
||||||
|
@ -6,11 +6,14 @@
|
|||||||
package org.mapstruct.ap.internal.model.source;
|
package org.mapstruct.ap.internal.model.source;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
||||||
import org.mapstruct.ap.internal.prism.BeanMappingPrism;
|
import org.mapstruct.ap.internal.prism.BeanMappingPrism;
|
||||||
import org.mapstruct.ap.internal.prism.BuilderPrism;
|
import org.mapstruct.ap.internal.prism.BuilderPrism;
|
||||||
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
||||||
@ -36,57 +39,101 @@ public class BeanMapping {
|
|||||||
private final BuilderPrism builder;
|
private final BuilderPrism builder;
|
||||||
private final NullValuePropertyMappingStrategyPrism nullValuePropertyMappingStrategy;
|
private final NullValuePropertyMappingStrategyPrism nullValuePropertyMappingStrategy;
|
||||||
|
|
||||||
|
private final AnnotationMirror mirror;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a mapping for inheritance. Will set ignoreByDefault to false.
|
* creates a mapping for inheritance. Will set
|
||||||
|
* - ignoreByDefault to false.
|
||||||
|
* - resultType to null
|
||||||
*
|
*
|
||||||
* @param map
|
* @return new mapping
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static BeanMapping forInheritance( BeanMapping map ) {
|
public static BeanMapping forInheritance(BeanMapping beanMapping) {
|
||||||
return new BeanMapping(
|
return new BeanMapping(
|
||||||
map.selectionParameters,
|
SelectionParameters.forInheritance( beanMapping.selectionParameters ),
|
||||||
map.nullValueMappingStrategy,
|
beanMapping.nullValueMappingStrategy,
|
||||||
map.nullValuePropertyMappingStrategy,
|
beanMapping.nullValuePropertyMappingStrategy,
|
||||||
map.nullValueCheckStrategy,
|
beanMapping.nullValueCheckStrategy,
|
||||||
map.reportingPolicy,
|
beanMapping.reportingPolicy,
|
||||||
false,
|
false,
|
||||||
map.ignoreUnmappedSourceProperties,
|
beanMapping.ignoreUnmappedSourceProperties,
|
||||||
map.builder
|
beanMapping.builder,
|
||||||
|
beanMapping.mirror
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeanMapping fromPrism(BeanMappingPrism beanMapping, ExecutableElement method,
|
public static class Builder {
|
||||||
FormattingMessager messager, Types typeUtils) {
|
|
||||||
|
|
||||||
if ( beanMapping == null ) {
|
private BeanMappingPrism prism;
|
||||||
|
private ExecutableElement method;
|
||||||
|
private FormattingMessager messager;
|
||||||
|
private Types typeUtils;
|
||||||
|
private TypeFactory typeFactory;
|
||||||
|
|
||||||
|
public Builder beanMappingPrism(BeanMappingPrism beanMappingPrism) {
|
||||||
|
this.prism = beanMappingPrism;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder method(ExecutableElement method) {
|
||||||
|
this.method = method;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder messager(FormattingMessager messager) {
|
||||||
|
this.messager = messager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder typeUtils(Types typeUtils) {
|
||||||
|
this.typeUtils = typeUtils;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder typeFactory(TypeFactory typeFactory) {
|
||||||
|
this.typeFactory = typeFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeanMapping build() {
|
||||||
|
|
||||||
|
if ( prism == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() );
|
Objects.requireNonNull( method );
|
||||||
|
Objects.requireNonNull( messager );
|
||||||
|
Objects.requireNonNull( method );
|
||||||
|
Objects.requireNonNull( typeUtils );
|
||||||
|
Objects.requireNonNull( typeFactory );
|
||||||
|
|
||||||
|
boolean resultTypeIsDefined = !TypeKind.VOID.equals( prism.resultType().getKind() );
|
||||||
|
|
||||||
NullValueMappingStrategyPrism nullValueMappingStrategy =
|
NullValueMappingStrategyPrism nullValueMappingStrategy =
|
||||||
null == beanMapping.values.nullValueMappingStrategy()
|
null == prism.values.nullValueMappingStrategy()
|
||||||
? null
|
? null
|
||||||
: NullValueMappingStrategyPrism.valueOf( beanMapping.nullValueMappingStrategy() );
|
: NullValueMappingStrategyPrism.valueOf( prism.nullValueMappingStrategy() );
|
||||||
|
|
||||||
NullValuePropertyMappingStrategyPrism nullValuePropertyMappingStrategy =
|
NullValuePropertyMappingStrategyPrism nullValuePropertyMappingStrategy =
|
||||||
null == beanMapping.values.nullValuePropertyMappingStrategy()
|
null == prism.values.nullValuePropertyMappingStrategy()
|
||||||
? null
|
? null
|
||||||
: NullValuePropertyMappingStrategyPrism.valueOf( beanMapping.nullValuePropertyMappingStrategy() );
|
:
|
||||||
|
NullValuePropertyMappingStrategyPrism.valueOf( prism.nullValuePropertyMappingStrategy() );
|
||||||
|
|
||||||
NullValueCheckStrategyPrism nullValueCheckStrategy =
|
NullValueCheckStrategyPrism nullValueCheckStrategy =
|
||||||
null == beanMapping.values.nullValueCheckStrategy()
|
null == prism.values.nullValueCheckStrategy()
|
||||||
? null
|
? null
|
||||||
: NullValueCheckStrategyPrism.valueOf( beanMapping.nullValueCheckStrategy() );
|
: NullValueCheckStrategyPrism.valueOf( prism.nullValueCheckStrategy() );
|
||||||
|
|
||||||
boolean ignoreByDefault = beanMapping.ignoreByDefault();
|
boolean ignoreByDefault = prism.ignoreByDefault();
|
||||||
BuilderPrism builderMapping = null;
|
BuilderPrism builderMapping = null;
|
||||||
if ( beanMapping.values.builder() != null ) {
|
if ( prism.values.builder() != null ) {
|
||||||
builderMapping = beanMapping.builder();
|
builderMapping = prism.builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() && beanMapping.qualifiedByName().isEmpty()
|
if ( !resultTypeIsDefined && prism.qualifiedBy().isEmpty() &&
|
||||||
&& beanMapping.ignoreUnmappedSourceProperties().isEmpty()
|
prism.qualifiedByName().isEmpty()
|
||||||
|
&& prism.ignoreUnmappedSourceProperties().isEmpty()
|
||||||
&& ( nullValueMappingStrategy == null ) && ( nullValuePropertyMappingStrategy == null )
|
&& ( nullValueMappingStrategy == null ) && ( nullValuePropertyMappingStrategy == null )
|
||||||
&& ( nullValueCheckStrategy == null ) && !ignoreByDefault && builderMapping == null ) {
|
&& ( nullValueCheckStrategy == null ) && !ignoreByDefault && builderMapping == null ) {
|
||||||
|
|
||||||
@ -94,9 +141,9 @@ public class BeanMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SelectionParameters cmp = new SelectionParameters(
|
SelectionParameters cmp = new SelectionParameters(
|
||||||
beanMapping.qualifiedBy(),
|
prism.qualifiedBy(),
|
||||||
beanMapping.qualifiedByName(),
|
prism.qualifiedByName(),
|
||||||
resultTypeIsDefined ? beanMapping.resultType() : null,
|
resultTypeIsDefined ? prism.resultType() : null,
|
||||||
typeUtils
|
typeUtils
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -108,15 +155,18 @@ public class BeanMapping {
|
|||||||
nullValueCheckStrategy,
|
nullValueCheckStrategy,
|
||||||
null,
|
null,
|
||||||
ignoreByDefault,
|
ignoreByDefault,
|
||||||
beanMapping.ignoreUnmappedSourceProperties(),
|
prism.ignoreUnmappedSourceProperties(),
|
||||||
builderMapping
|
builderMapping,
|
||||||
|
prism.mirror
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BeanMapping(SelectionParameters selectionParameters, NullValueMappingStrategyPrism nvms,
|
private BeanMapping(SelectionParameters selectionParameters, NullValueMappingStrategyPrism nvms,
|
||||||
NullValuePropertyMappingStrategyPrism nvpms, NullValueCheckStrategyPrism nvcs,
|
NullValuePropertyMappingStrategyPrism nvpms, NullValueCheckStrategyPrism nvcs,
|
||||||
ReportingPolicyPrism reportingPolicy, boolean ignoreByDefault,
|
ReportingPolicyPrism reportingPolicy, boolean ignoreByDefault,
|
||||||
List<String> ignoreUnmappedSourceProperties, BuilderPrism builder) {
|
List<String> ignoreUnmappedSourceProperties, BuilderPrism builder,
|
||||||
|
AnnotationMirror mirror) {
|
||||||
this.selectionParameters = selectionParameters;
|
this.selectionParameters = selectionParameters;
|
||||||
this.nullValueMappingStrategy = nvms;
|
this.nullValueMappingStrategy = nvms;
|
||||||
this.nullValuePropertyMappingStrategy = nvpms;
|
this.nullValuePropertyMappingStrategy = nvpms;
|
||||||
@ -125,6 +175,7 @@ public class BeanMapping {
|
|||||||
this.ignoreByDefault = ignoreByDefault;
|
this.ignoreByDefault = ignoreByDefault;
|
||||||
this.ignoreUnmappedSourceProperties = ignoreUnmappedSourceProperties;
|
this.ignoreUnmappedSourceProperties = ignoreUnmappedSourceProperties;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
this.mirror = mirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectionParameters getSelectionParameters() {
|
public SelectionParameters getSelectionParameters() {
|
||||||
@ -155,6 +206,10 @@ public class BeanMapping {
|
|||||||
return ignoreUnmappedSourceProperties;
|
return ignoreUnmappedSourceProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AnnotationMirror getMirror() {
|
||||||
|
return mirror;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derives the builder prism given the options and configuration
|
* derives the builder prism given the options and configuration
|
||||||
* @param method containing mandatory configuration and the mapping options (optionally containing a beanmapping)
|
* @param method containing mandatory configuration and the mapping options (optionally containing a beanmapping)
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.internal.model.source;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the mapping between one enum constant and another.
|
|
||||||
*
|
|
||||||
* @author Gunnar Morling
|
|
||||||
*/
|
|
||||||
public class EnumMapping {
|
|
||||||
|
|
||||||
private final String source;
|
|
||||||
private final String target;
|
|
||||||
|
|
||||||
public EnumMapping(String source, String target) {
|
|
||||||
this.source = source;
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the name of the constant in the source enum.
|
|
||||||
*/
|
|
||||||
public String getSource() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the name of the constant in the target enum.
|
|
||||||
*/
|
|
||||||
public String getTarget() {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,6 +26,23 @@ public class SelectionParameters {
|
|||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private final SourceRHS sourceRHS;
|
private final SourceRHS sourceRHS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns new selection parameters
|
||||||
|
*
|
||||||
|
* ResultType is not inherited.
|
||||||
|
*
|
||||||
|
* @param selectionParameters
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SelectionParameters forInheritance(SelectionParameters selectionParameters) {
|
||||||
|
return new SelectionParameters(
|
||||||
|
selectionParameters.qualifiers,
|
||||||
|
selectionParameters.qualifyingNames,
|
||||||
|
null,
|
||||||
|
selectionParameters.typeUtils
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public SelectionParameters(List<TypeMirror> qualifiers, List<String> qualifyingNames, TypeMirror resultType,
|
public SelectionParameters(List<TypeMirror> qualifiers, List<String> qualifyingNames, TypeMirror resultType,
|
||||||
Types typeUtils) {
|
Types typeUtils) {
|
||||||
this( qualifiers, qualifyingNames, resultType, typeUtils, null );
|
this( qualifiers, qualifyingNames, resultType, typeUtils, null );
|
||||||
|
@ -254,7 +254,14 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
.setMapMapping(
|
.setMapMapping(
|
||||||
MapMapping.fromPrism( MapMappingPrism.getInstanceOn( method ), method, messager, typeUtils ) )
|
MapMapping.fromPrism( MapMappingPrism.getInstanceOn( method ), method, messager, typeUtils ) )
|
||||||
.setBeanMapping(
|
.setBeanMapping(
|
||||||
BeanMapping.fromPrism( BeanMappingPrism.getInstanceOn( method ), method, messager, typeUtils ) )
|
new BeanMapping.Builder()
|
||||||
|
.beanMappingPrism( BeanMappingPrism.getInstanceOn( method ) )
|
||||||
|
.messager( messager )
|
||||||
|
.method( method )
|
||||||
|
.typeUtils( typeUtils )
|
||||||
|
.typeFactory( typeFactory )
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.setValueMappings( getValueMappings( method ) )
|
.setValueMappings( getValueMappings( method ) )
|
||||||
.setTypeUtils( typeUtils )
|
.setTypeUtils( typeUtils )
|
||||||
.setTypeFactory( typeFactory )
|
.setTypeFactory( typeFactory )
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.bugs._1821;
|
||||||
|
|
||||||
|
import org.mapstruct.BeanMapping;
|
||||||
|
import org.mapstruct.InheritConfiguration;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface Issue1821Mapper {
|
||||||
|
|
||||||
|
Issue1821Mapper INSTANCE = Mappers.getMapper( Issue1821Mapper.class );
|
||||||
|
|
||||||
|
@BeanMapping( resultType = Target.class )
|
||||||
|
Target map(Source source);
|
||||||
|
|
||||||
|
@InheritConfiguration( name = "map" )
|
||||||
|
ExtendedTarget mapExtended(Source source);
|
||||||
|
|
||||||
|
class Target {
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtendedTarget extends Target {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Source {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.bugs._1821;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
|
||||||
|
@IssueKey("1797")
|
||||||
|
@RunWith( AnnotationProcessorTestRunner.class)
|
||||||
|
@WithClasses( Issue1821Mapper.class )
|
||||||
|
public class Issue1821Test {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotGiveNullPtr() {
|
||||||
|
Issue1821Mapper.INSTANCE.map( new Issue1821Mapper.Source() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user