mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#328 if a source property is assignable to the target property, do not apply any built-in conversions
This commit is contained in:
parent
54b8747e09
commit
8c3e32472b
@ -178,10 +178,9 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
private Assignment getTargetAssignment(Type sourceType, Type targetType) {
|
private Assignment getTargetAssignment(Type sourceType, Type targetType) {
|
||||||
|
|
||||||
// first simple mapping method
|
// first simple mapping method
|
||||||
Assignment referencedMethod = resolveViaMethod( sourceType, targetType );
|
Assignment referencedMethod = resolveViaMethod( sourceType, targetType, false );
|
||||||
if ( referencedMethod != null ) {
|
if ( referencedMethod != null ) {
|
||||||
referencedMethod.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
|
referencedMethod.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
|
||||||
usedVirtualMappings.addAll( virtualMethodCandidates );
|
|
||||||
return referencedMethod;
|
return referencedMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,21 +197,29 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
return conversion;
|
return conversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 step method, first: method(method(souurce))
|
// check for a built-in method
|
||||||
|
Assignment builtInMethod = resolveViaBuiltInMethod( sourceType, targetType );
|
||||||
|
if ( builtInMethod != null ) {
|
||||||
|
builtInMethod.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
|
||||||
|
usedVirtualMappings.addAll( virtualMethodCandidates );
|
||||||
|
return builtInMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 step method, first: method(method(source))
|
||||||
referencedMethod = resolveViaMethodAndMethod( sourceType, targetType );
|
referencedMethod = resolveViaMethodAndMethod( sourceType, targetType );
|
||||||
if ( referencedMethod != null ) {
|
if ( referencedMethod != null ) {
|
||||||
usedVirtualMappings.addAll( virtualMethodCandidates );
|
usedVirtualMappings.addAll( virtualMethodCandidates );
|
||||||
return referencedMethod;
|
return referencedMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 step method, then: method(conversion(souurce))
|
// 2 step method, then: method(conversion(source))
|
||||||
referencedMethod = resolveViaConversionAndMethod( sourceType, targetType );
|
referencedMethod = resolveViaConversionAndMethod( sourceType, targetType );
|
||||||
if ( referencedMethod != null ) {
|
if ( referencedMethod != null ) {
|
||||||
usedVirtualMappings.addAll( virtualMethodCandidates );
|
usedVirtualMappings.addAll( virtualMethodCandidates );
|
||||||
return referencedMethod;
|
return referencedMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 step method, finally: conversion(method(souurce))
|
// 2 step method, finally: conversion(method(source))
|
||||||
conversion = resolveViaMethodAndConversion( sourceType, targetType );
|
conversion = resolveViaMethodAndConversion( sourceType, targetType );
|
||||||
if ( conversion != null ) {
|
if ( conversion != null ) {
|
||||||
usedVirtualMappings.addAll( virtualMethodCandidates );
|
usedVirtualMappings.addAll( virtualMethodCandidates );
|
||||||
@ -239,7 +246,7 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
* Returns a reference to a method mapping the given source type to the given target type, if such a method
|
* Returns a reference to a method mapping the given source type to the given target type, if such a method
|
||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
private Assignment resolveViaMethod(Type sourceType, Type targetType) {
|
private Assignment resolveViaMethod(Type sourceType, Type targetType, boolean considerBuiltInMethods) {
|
||||||
|
|
||||||
// first try to find a matching source method
|
// first try to find a matching source method
|
||||||
SourceMethod matchingSourceMethod = getBestMatch( methods, sourceType, targetType );
|
SourceMethod matchingSourceMethod = getBestMatch( methods, sourceType, targetType );
|
||||||
@ -248,14 +255,20 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
return getMappingMethodReference( matchingSourceMethod, targetType );
|
return getMappingMethodReference( matchingSourceMethod, targetType );
|
||||||
}
|
}
|
||||||
|
|
||||||
// then a matching built-in method
|
if ( considerBuiltInMethods ) {
|
||||||
|
return resolveViaBuiltInMethod( sourceType, targetType );
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Assignment resolveViaBuiltInMethod(Type sourceType, Type targetType) {
|
||||||
BuiltInMethod matchingBuiltInMethod =
|
BuiltInMethod matchingBuiltInMethod =
|
||||||
getBestMatch( builtInMethods.getBuiltInMethods(), sourceType, targetType );
|
getBestMatch( builtInMethods.getBuiltInMethods(), sourceType, targetType );
|
||||||
|
|
||||||
if ( matchingBuiltInMethod != null ) {
|
if ( matchingBuiltInMethod != null ) {
|
||||||
virtualMethodCandidates.add( new VirtualMappingMethod( matchingBuiltInMethod ) );
|
virtualMethodCandidates.add( new VirtualMappingMethod( matchingBuiltInMethod ) );
|
||||||
ConversionContext ctx =
|
ConversionContext ctx = new DefaultConversionContext( typeFactory, targetType, dateFormat );
|
||||||
new DefaultConversionContext( typeFactory, targetType, dateFormat );
|
|
||||||
Assignment methodReference = AssignmentFactory.createMethodReference( matchingBuiltInMethod, ctx );
|
Assignment methodReference = AssignmentFactory.createMethodReference( matchingBuiltInMethod, ctx );
|
||||||
methodReference.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
|
methodReference.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
|
||||||
return methodReference;
|
return methodReference;
|
||||||
@ -291,12 +304,14 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
|
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
|
||||||
methodRefY = resolveViaMethod(
|
methodRefY = resolveViaMethod(
|
||||||
methodYCandidate.getSourceParameters().get( 0 ).getType(),
|
methodYCandidate.getSourceParameters().get( 0 ).getType(),
|
||||||
targetType
|
targetType,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
if ( methodRefY != null ) {
|
if ( methodRefY != null ) {
|
||||||
Assignment methodRefX = resolveViaMethod(
|
Assignment methodRefX = resolveViaMethod(
|
||||||
sourceType,
|
sourceType,
|
||||||
methodYCandidate.getSourceParameters().get( 0 ).getType()
|
methodYCandidate.getSourceParameters().get( 0 ).getType(),
|
||||||
|
true
|
||||||
);
|
);
|
||||||
if ( methodRefX != null ) {
|
if ( methodRefX != null ) {
|
||||||
methodRefY.setAssignment( methodRefX );
|
methodRefY.setAssignment( methodRefX );
|
||||||
@ -333,7 +348,8 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
|
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
|
||||||
methodRefY = resolveViaMethod(
|
methodRefY = resolveViaMethod(
|
||||||
methodYCandidate.getSourceParameters().get( 0 ).getType(),
|
methodYCandidate.getSourceParameters().get( 0 ).getType(),
|
||||||
targetType
|
targetType,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
if ( methodRefY != null ) {
|
if ( methodRefY != null ) {
|
||||||
Assignment conversionXRef = resolveViaConversion(
|
Assignment conversionXRef = resolveViaConversion(
|
||||||
@ -376,7 +392,8 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
if ( methodXCandidate.getSourceParameters().size() == 1 ) {
|
if ( methodXCandidate.getSourceParameters().size() == 1 ) {
|
||||||
Assignment methodRefX = resolveViaMethod(
|
Assignment methodRefX = resolveViaMethod(
|
||||||
sourceType,
|
sourceType,
|
||||||
methodXCandidate.getReturnType()
|
methodXCandidate.getReturnType(),
|
||||||
|
true
|
||||||
);
|
);
|
||||||
if ( methodRefX != null ) {
|
if ( methodRefX != null ) {
|
||||||
conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType );
|
conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType );
|
||||||
|
@ -36,6 +36,7 @@ public class Source {
|
|||||||
private Boolean boolBool;
|
private Boolean boolBool;
|
||||||
private char c;
|
private char c;
|
||||||
private Character cc;
|
private Character cc;
|
||||||
|
private Object object;
|
||||||
|
|
||||||
public byte getB() {
|
public byte getB() {
|
||||||
return b;
|
return b;
|
||||||
@ -164,4 +165,12 @@ public class Source {
|
|||||||
public void setCc(Character cc) {
|
public void setCc(Character cc) {
|
||||||
this.cc = cc;
|
this.cc = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObject(Object object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package org.mapstruct.ap.test.conversion.string;
|
package org.mapstruct.ap.test.conversion.string;
|
||||||
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
@ -26,6 +27,7 @@ public interface SourceTargetMapper {
|
|||||||
|
|
||||||
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
||||||
|
|
||||||
|
@Mapping( source = "object", ignore = true )
|
||||||
Target sourceToTarget(Source source);
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
Source targetToSource(Target target);
|
Source targetToSource(Target target);
|
||||||
|
@ -18,13 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.conversion.string;
|
package org.mapstruct.ap.test.conversion.string;
|
||||||
|
|
||||||
import static org.fest.assertions.Assertions.assertThat;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
import org.mapstruct.ap.testutil.WithClasses;
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
@WithClasses({
|
@WithClasses({
|
||||||
Source.class,
|
Source.class,
|
||||||
Target.class,
|
Target.class,
|
||||||
@ -33,6 +34,8 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
|||||||
@RunWith(AnnotationProcessorTestRunner.class)
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
public class StringConversionTest {
|
public class StringConversionTest {
|
||||||
|
|
||||||
|
private static final String STRING_CONTANT = "String contant";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldApplyStringConversions() {
|
public void shouldApplyStringConversions() {
|
||||||
Source source = new Source();
|
Source source = new Source();
|
||||||
@ -114,4 +117,16 @@ public class StringConversionTest {
|
|||||||
assertThat( source.getC() ).isEqualTo( 'G' );
|
assertThat( source.getC() ).isEqualTo( 'G' );
|
||||||
assertThat( source.getCc() ).isEqualTo( 'H' );
|
assertThat( source.getCc() ).isEqualTo( 'H' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IssueKey( "328" )
|
||||||
|
public void stringShouldBeMappedToObjectByReference() {
|
||||||
|
Target target = new Target();
|
||||||
|
target.setObject( STRING_CONTANT );
|
||||||
|
|
||||||
|
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
|
||||||
|
|
||||||
|
// no conversion, no built-in method
|
||||||
|
assertThat( source.getObject() ).isSameAs( STRING_CONTANT );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ public class Target {
|
|||||||
private String boolBool;
|
private String boolBool;
|
||||||
private String c;
|
private String c;
|
||||||
private String cc;
|
private String cc;
|
||||||
|
private String object;
|
||||||
|
|
||||||
public String getB() {
|
public String getB() {
|
||||||
return b;
|
return b;
|
||||||
@ -165,4 +166,11 @@ public class Target {
|
|||||||
this.cc = cc;
|
this.cc = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObject(String object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user