#344 only consider methods as property mapping methods if they have one source parameter, a non-void return type, and no @MappingTarget parameter

This commit is contained in:
Andreas Gudian 2014-11-12 21:11:02 +01:00 committed by Gunnar Morling
parent 3948a2d58b
commit ce5bf3b498

View File

@ -164,7 +164,7 @@ public class MappingResolverImpl implements MappingResolver {
String sourceReference) { String sourceReference) {
this.mappingMethod = mappingMethod; this.mappingMethod = mappingMethod;
this.mappedElement = mappedElement; this.mappedElement = mappedElement;
this.methods = sourceModel; this.methods = filterPossibleCandidateMethods( sourceModel );
this.targetPropertyName = targetPropertyName; this.targetPropertyName = targetPropertyName;
this.dateFormat = dateFormat; this.dateFormat = dateFormat;
this.qualifiers = qualifiers; this.qualifiers = qualifiers;
@ -172,6 +172,17 @@ public class MappingResolverImpl implements MappingResolver {
this.virtualMethodCandidates = new HashSet<VirtualMappingMethod>(); this.virtualMethodCandidates = new HashSet<VirtualMappingMethod>();
} }
private <T extends Method> List<T> filterPossibleCandidateMethods(List<T> candidateMethods) {
List<T> result = new ArrayList<T>( candidateMethods.size() );
for ( T candidate : candidateMethods ) {
if ( isCandidateForMapping( candidate ) ) {
result.add( candidate );
}
}
return result;
}
private Assignment getTargetAssignment(Type sourceType, Type targetType) { private Assignment getTargetAssignment(Type sourceType, Type targetType) {
// first simple mapping method // first simple mapping method
@ -298,28 +309,21 @@ public class MappingResolverImpl implements MappingResolver {
// sourceMethod or builtIn that fits the signature B to C. Only then there is a match. If we have a match // sourceMethod or builtIn that fits the signature B to C. Only then there is a match. If we have a match
// a nested method call can be called. so C = methodY( methodX (A) ) // a nested method call can be called. so C = methodY( methodX (A) )
for ( Method methodYCandidate : methodYCandidates ) { for ( Method methodYCandidate : methodYCandidates ) {
if ( methodYCandidate.getSourceParameters().size() == 1 ) { methodRefY =
methodRefY = resolveViaMethod( resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType, true );
methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetType, if ( methodRefY != null ) {
true Assignment methodRefX =
); resolveViaMethod( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType(), true );
if ( methodRefY != null ) { if ( methodRefX != null ) {
Assignment methodRefX = resolveViaMethod( methodRefY.setAssignment( methodRefX );
sourceType, methodRefX.setAssignment( AssignmentFactory.createDirect( sourceReference ) );
methodYCandidate.getSourceParameters().get( 0 ).getType(), break;
true }
); else {
if ( methodRefX != null ) { // both should match;
methodRefY.setAssignment( methodRefX ); virtualMethodCandidates.clear();
methodRefX.setAssignment( AssignmentFactory.createDirect( sourceReference ) ); methodRefY = null;
break;
}
else {
// both should match;
virtualMethodCandidates.clear();
methodRefY = null;
}
} }
} }
} }
@ -342,27 +346,21 @@ public class MappingResolverImpl implements MappingResolver {
Assignment methodRefY = null; Assignment methodRefY = null;
for ( Method methodYCandidate : methodYCandidates ) { for ( Method methodYCandidate : methodYCandidates ) {
if ( methodYCandidate.getSourceParameters().size() == 1 ) { methodRefY =
methodRefY = resolveViaMethod( resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType, true );
methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetType, if ( methodRefY != null ) {
true Assignment conversionXRef =
); resolveViaConversion( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType() );
if ( methodRefY != null ) { if ( conversionXRef != null ) {
Assignment conversionXRef = resolveViaConversion( methodRefY.setAssignment( conversionXRef );
sourceType, conversionXRef.setAssignment( AssignmentFactory.createDirect( sourceReference ) );
methodYCandidate.getSourceParameters().get( 0 ).getType() break;
); }
if ( conversionXRef != null ) { else {
methodRefY.setAssignment( conversionXRef ); // both should match
conversionXRef.setAssignment( AssignmentFactory.createDirect( sourceReference ) ); virtualMethodCandidates.clear();
break; methodRefY = null;
}
else {
// both should match
virtualMethodCandidates.clear();
methodRefY = null;
}
} }
} }
} }
@ -386,30 +384,34 @@ public class MappingResolverImpl implements MappingResolver {
// search the other way around // search the other way around
for ( Method methodXCandidate : methodXCandidates ) { for ( Method methodXCandidate : methodXCandidates ) {
if ( methodXCandidate.getSourceParameters().size() == 1 ) { Assignment methodRefX = resolveViaMethod(
Assignment methodRefX = resolveViaMethod( sourceType,
sourceType, methodXCandidate.getReturnType(),
methodXCandidate.getReturnType(), true
true );
); if ( methodRefX != null ) {
if ( methodRefX != null ) { conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType );
conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType ); if ( conversionYRef != null ) {
if ( conversionYRef != null ) { conversionYRef.setAssignment( methodRefX );
conversionYRef.setAssignment( methodRefX ); methodRefX.setAssignment( AssignmentFactory.createDirect( sourceReference ) );
methodRefX.setAssignment( AssignmentFactory.createDirect( sourceReference ) ); break;
break; }
} else {
else { // both should match;
// both should match; virtualMethodCandidates.clear();
virtualMethodCandidates.clear(); conversionYRef = null;
conversionYRef = null;
}
} }
} }
} }
return conversionYRef; return conversionYRef;
} }
private boolean isCandidateForMapping(Method methodCandidate) {
return methodCandidate.getSourceParameters().size() == 1 && !methodCandidate.getReturnType().isVoid()
&& methodCandidate.getTargetParameter() == null; // @MappingTarget is not yet supported for property
// mappings
}
private <T extends Method> T getBestMatch(List<T> methods, Type sourceType, Type returnType) { private <T extends Method> T getBestMatch(List<T> methods, Type sourceType, Type returnType) {
List<T> candidates = methodSelectors.getMatchingMethods( List<T> candidates = methodSelectors.getMatchingMethods(