mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#385 Refactoring, factory methods should use selectors, preparing selector api for more criteria
This commit is contained in:
parent
7d2932c9b5
commit
65c272286f
@ -21,15 +21,12 @@ package org.mapstruct.ap.model;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.tools.Diagnostic;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.model.assignment.Assignment;
|
import org.mapstruct.ap.model.assignment.Assignment;
|
||||||
import org.mapstruct.ap.model.common.ConversionContext;
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.model.source.SourceMethod;
|
|
||||||
import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
||||||
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory class for creating all types of assignments
|
* Factory class for creating all types of assignments
|
||||||
@ -57,50 +54,5 @@ public class AssignmentFactory {
|
|||||||
public static Direct createDirect(String sourceRef) {
|
public static Direct createDirect(String sourceRef) {
|
||||||
return new Direct( sourceRef );
|
return new Direct( sourceRef );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodReference createFactoryMethod( Type returnType, MappingBuilderContext ctx ) {
|
|
||||||
MethodReference result = null;
|
|
||||||
for ( SourceMethod method : ctx.getSourceModel() ) {
|
|
||||||
if ( !method.overridesMethod() && !method.isIterableMapping() && !method.isMapMapping()
|
|
||||||
&& method.getSourceParameters().isEmpty() ) {
|
|
||||||
|
|
||||||
List<Type> parameterTypes = MethodSelectors.getParameterTypes(
|
|
||||||
ctx.getTypeFactory(),
|
|
||||||
method.getParameters(),
|
|
||||||
null,
|
|
||||||
returnType
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( method.matches( parameterTypes, returnType ) ) {
|
|
||||||
if ( result == null ) {
|
|
||||||
MapperReference mapperReference = findMapperReference( ctx.getMapperReferences(), method );
|
|
||||||
result = new MethodReference( method, mapperReference, null );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ctx.getMessager().printMessage(
|
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Ambiguous factory methods: \"%s\" conflicts with \"%s\".",
|
|
||||||
result,
|
|
||||||
method
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MapperReference findMapperReference( List<MapperReference> mapperReferences, SourceMethod method ) {
|
|
||||||
for ( MapperReference ref : mapperReferences ) {
|
|
||||||
if ( ref.getType().equals( method.getDeclaringMapper() ) ) {
|
|
||||||
ref.setUsed( !method.isStatic() );
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
boolean mapNullToDefault =
|
boolean mapNullToDefault =
|
||||||
MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
||||||
|
|
||||||
MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx );
|
MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() );
|
||||||
return new BeanMappingMethod( method, propertyMappings, factoryMethod, mapNullToDefault );
|
return new BeanMappingMethod( method, propertyMappings, factoryMethod, mapNullToDefault );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +124,7 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
boolean mapNullToDefault
|
boolean mapNullToDefault
|
||||||
= MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
= MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
||||||
|
|
||||||
MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx );
|
MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() );
|
||||||
|
|
||||||
return new IterableMappingMethod(
|
return new IterableMappingMethod(
|
||||||
method,
|
method,
|
||||||
assignment,
|
assignment,
|
||||||
|
@ -141,7 +141,7 @@ public class MapMappingMethod extends MappingMethod {
|
|||||||
boolean mapNullToDefault =
|
boolean mapNullToDefault =
|
||||||
MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
||||||
|
|
||||||
MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx );
|
MethodReference factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType() );
|
||||||
|
|
||||||
keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes() );
|
keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes() );
|
||||||
valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes() );
|
valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes() );
|
||||||
|
@ -94,6 +94,17 @@ public class MappingBuilderContext {
|
|||||||
String targetPropertyName, String dateFormat, List<TypeMirror> qualifiers,
|
String targetPropertyName, String dateFormat, List<TypeMirror> qualifiers,
|
||||||
String sourceReference);
|
String sourceReference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a no arg factory method
|
||||||
|
*
|
||||||
|
* @param mappingMethod target mapping method
|
||||||
|
* @param targetType return type to match
|
||||||
|
*
|
||||||
|
* @return a method reference to the factory method, or null if no suitable, or ambiguous method found
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MethodReference getFactoryMethod(Method mappingMethod, Type targetType);
|
||||||
|
|
||||||
Set<VirtualMappingMethod> getUsedVirtualMappings();
|
Set<VirtualMappingMethod> getUsedVirtualMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,4 +201,5 @@ public class MappingBuilderContext {
|
|||||||
public Set<VirtualMappingMethod> getUsedVirtualMappings() {
|
public Set<VirtualMappingMethod> getUsedVirtualMappings() {
|
||||||
return mappingResolver.getUsedVirtualMappings();
|
return mappingResolver.getUsedVirtualMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ package org.mapstruct.ap.model.source.selector;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
@ -37,12 +36,15 @@ public class InheritanceSelector implements MethodSelector {
|
|||||||
public <T extends Method> List<T> getMatchingMethods(
|
public <T extends Method> List<T> getMatchingMethods(
|
||||||
Method mappingMethod,
|
Method mappingMethod,
|
||||||
List<T> methods,
|
List<T> methods,
|
||||||
Type parameterType,
|
Type sourceType,
|
||||||
Type returnType,
|
Type targetType,
|
||||||
List<TypeMirror> qualifiers,
|
SelectionCriteria criteria
|
||||||
String targetPropertyName
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
if ( sourceType == null ) {
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
List<T> candidatesWithBestMatchingSourceType = new ArrayList<T>();
|
List<T> candidatesWithBestMatchingSourceType = new ArrayList<T>();
|
||||||
int bestMatchingSourceTypeDistance = Integer.MAX_VALUE;
|
int bestMatchingSourceTypeDistance = Integer.MAX_VALUE;
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ public class InheritanceSelector implements MethodSelector {
|
|||||||
for ( T method : methods ) {
|
for ( T method : methods ) {
|
||||||
Parameter singleSourceParam = method.getSourceParameters().iterator().next();
|
Parameter singleSourceParam = method.getSourceParameters().iterator().next();
|
||||||
|
|
||||||
int sourceTypeDistance = parameterType.distanceTo( singleSourceParam.getType() );
|
int sourceTypeDistance = sourceType.distanceTo( singleSourceParam.getType() );
|
||||||
bestMatchingSourceTypeDistance =
|
bestMatchingSourceTypeDistance =
|
||||||
addToCandidateListIfMinimal(
|
addToCandidateListIfMinimal(
|
||||||
candidatesWithBestMatchingSourceType,
|
candidatesWithBestMatchingSourceType,
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
package org.mapstruct.ap.model.source.selector;
|
package org.mapstruct.ap.model.source.selector;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
@ -39,14 +38,12 @@ public interface MethodSelector {
|
|||||||
* @param <T> either SourceMethod or BuiltInMethod
|
* @param <T> either SourceMethod or BuiltInMethod
|
||||||
* @param mappingMethod mapping method, defined in Mapper for which this selection is carried out
|
* @param mappingMethod mapping method, defined in Mapper for which this selection is carried out
|
||||||
* @param methods list of available methods
|
* @param methods list of available methods
|
||||||
* @param parameterType parameter type that should be matched
|
* @param sourceType parameter type that should be matched
|
||||||
* @param returnType return type that should be matched
|
* @param targetType return type that should be matched
|
||||||
* @param qualifiers list of custom annotations, used in the qualifying process
|
* @param criteria criteria used in the selection process
|
||||||
* @param targetPropertyName some information can be derived from the target property
|
|
||||||
*
|
*
|
||||||
* @return list of methods that passes the matching process
|
* @return list of methods that passes the matching process
|
||||||
*/
|
*/
|
||||||
<T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
|
<T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type sourceType,
|
||||||
Type returnType, List<TypeMirror> qualifiers,
|
Type targetType, SelectionCriteria criteria);
|
||||||
String targetPropertyName);
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ package org.mapstruct.ap.model.source.selector;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
@ -51,9 +50,8 @@ public class MethodSelectors implements MethodSelector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||||
Type parameterType, Type returnType,
|
Type sourceType, Type targetType,
|
||||||
List<TypeMirror> qualifiers,
|
SelectionCriteria criteria) {
|
||||||
String targetPropertyName) {
|
|
||||||
|
|
||||||
List<T> candidates = new ArrayList<T>( methods );
|
List<T> candidates = new ArrayList<T>( methods );
|
||||||
|
|
||||||
@ -61,10 +59,9 @@ public class MethodSelectors implements MethodSelector {
|
|||||||
candidates = selector.getMatchingMethods(
|
candidates = selector.getMatchingMethods(
|
||||||
mappingMethod,
|
mappingMethod,
|
||||||
candidates,
|
candidates,
|
||||||
parameterType,
|
sourceType,
|
||||||
returnType,
|
targetType,
|
||||||
qualifiers,
|
criteria
|
||||||
targetPropertyName
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return candidates;
|
return candidates;
|
||||||
@ -80,15 +77,18 @@ public class MethodSelectors implements MethodSelector {
|
|||||||
*/
|
*/
|
||||||
public static List<Type> getParameterTypes(TypeFactory typeFactory, List<Parameter> parameters, Type sourceType,
|
public static List<Type> getParameterTypes(TypeFactory typeFactory, List<Parameter> parameters, Type sourceType,
|
||||||
Type returnType) {
|
Type returnType) {
|
||||||
List<Type> result = new ArrayList<Type>( parameters.size() );
|
List<Type> result = new ArrayList<Type>();
|
||||||
for ( Parameter param : parameters ) {
|
for ( Parameter param : parameters ) {
|
||||||
if ( param.isTargetType() ) {
|
if ( param.isTargetType() ) {
|
||||||
result.add( typeFactory.classTypeOf( returnType ) );
|
result.add( typeFactory.classTypeOf( returnType ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ( sourceType != null ) {
|
||||||
|
/* for factory methods (sourceType==null), no parameter must be added */
|
||||||
result.add( sourceType );
|
result.add( sourceType );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,10 @@ public class QualifierSelector implements MethodSelector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||||
Type parameterType, Type returnType,
|
Type sourceType, Type targetType,
|
||||||
List<TypeMirror> qualifiers,
|
SelectionCriteria criteria) {
|
||||||
String targetPropertyName) {
|
|
||||||
|
|
||||||
|
List<TypeMirror> qualifiers = criteria.getQualifiers();
|
||||||
if ( qualifiers == null || qualifiers.isEmpty() ) {
|
if ( qualifiers == null || qualifiers.isEmpty() ) {
|
||||||
// remove the method marked as qualifier from the list
|
// remove the method marked as qualifier from the list
|
||||||
List<T> nonQualiferAnnotatedMethods = new ArrayList<T>();
|
List<T> nonQualiferAnnotatedMethods = new ArrayList<T>();
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.model.source.selector;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class groups the selection criteria in one class
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class SelectionCriteria {
|
||||||
|
|
||||||
|
private final List<TypeMirror> qualifiers;
|
||||||
|
private final String targetPropertyName;
|
||||||
|
|
||||||
|
public SelectionCriteria(List<TypeMirror> qualifiers, String targetPropertyName) {
|
||||||
|
this.qualifiers = qualifiers;
|
||||||
|
this.targetPropertyName = targetPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TypeMirror> getQualifiers() {
|
||||||
|
return qualifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTargetPropertyName() {
|
||||||
|
return targetPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,6 @@ package org.mapstruct.ap.model.source.selector;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -43,19 +42,18 @@ public class TypeSelector implements MethodSelector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||||
Type parameterType, Type returnType,
|
Type sourceType, Type targetType,
|
||||||
List<TypeMirror> qualifiers,
|
SelectionCriteria criteria) {
|
||||||
String targetPropertyName) {
|
|
||||||
|
|
||||||
List<T> result = new ArrayList<T>();
|
List<T> result = new ArrayList<T>();
|
||||||
for ( T method : methods ) {
|
for ( T method : methods ) {
|
||||||
if ( method.getSourceParameters().size() != 1 ) {
|
if ( method.getSourceParameters().size() > 1 ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Type> parameterTypes =
|
List<Type> parameterTypes =
|
||||||
MethodSelectors.getParameterTypes( typeFactory, method.getParameters(), parameterType, returnType );
|
MethodSelectors.getParameterTypes( typeFactory, method.getParameters(), sourceType, targetType );
|
||||||
if ( method.matches( parameterTypes, returnType ) ) {
|
if ( method.matches( parameterTypes, targetType ) ) {
|
||||||
result.add( method );
|
result.add( method );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,8 @@ public class XmlElementDeclSelector implements MethodSelector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||||
Type parameterType, Type returnType,
|
Type sourceType, Type targetType,
|
||||||
List<TypeMirror> qualifiers,
|
SelectionCriteria criteria) {
|
||||||
String targetPropertyName) {
|
|
||||||
|
|
||||||
// only true source methods are qualifying
|
// only true source methods are qualifying
|
||||||
if ( !(mappingMethod instanceof SourceMethod) ) {
|
if ( !(mappingMethod instanceof SourceMethod) ) {
|
||||||
@ -83,7 +82,7 @@ public class XmlElementDeclSelector implements MethodSelector {
|
|||||||
TypeMirror scope = xmlElememtDecl.scope();
|
TypeMirror scope = xmlElememtDecl.scope();
|
||||||
TypeMirror target = sourceMappingMethod.getExecutable().getReturnType();
|
TypeMirror target = sourceMappingMethod.getExecutable().getReturnType();
|
||||||
|
|
||||||
boolean nameIsSetAndMatches = name != null && name.equals( targetPropertyName );
|
boolean nameIsSetAndMatches = name != null && name.equals( criteria.getTargetPropertyName() );
|
||||||
boolean scopeIsSetAndMatches = scope != null && typeUtils.isSameType( scope, target );
|
boolean scopeIsSetAndMatches = scope != null && typeUtils.isSameType( scope, target );
|
||||||
|
|
||||||
if ( nameIsSetAndMatches ) {
|
if ( nameIsSetAndMatches ) {
|
||||||
|
@ -34,6 +34,7 @@ import org.mapstruct.ap.conversion.Conversions;
|
|||||||
import org.mapstruct.ap.model.AssignmentFactory;
|
import org.mapstruct.ap.model.AssignmentFactory;
|
||||||
import org.mapstruct.ap.model.MapperReference;
|
import org.mapstruct.ap.model.MapperReference;
|
||||||
import org.mapstruct.ap.model.MappingBuilderContext.MappingResolver;
|
import org.mapstruct.ap.model.MappingBuilderContext.MappingResolver;
|
||||||
|
import org.mapstruct.ap.model.MethodReference;
|
||||||
import org.mapstruct.ap.model.VirtualMappingMethod;
|
import org.mapstruct.ap.model.VirtualMappingMethod;
|
||||||
import org.mapstruct.ap.model.assignment.Assignment;
|
import org.mapstruct.ap.model.assignment.Assignment;
|
||||||
import org.mapstruct.ap.model.common.ConversionContext;
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
@ -45,6 +46,7 @@ import org.mapstruct.ap.model.source.SourceMethod;
|
|||||||
import org.mapstruct.ap.model.source.builtin.BuiltInMappingMethods;
|
import org.mapstruct.ap.model.source.builtin.BuiltInMappingMethods;
|
||||||
import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
||||||
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
||||||
|
import org.mapstruct.ap.model.source.selector.SelectionCriteria;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,6 +142,28 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
return usedVirtualMappings;
|
return usedVirtualMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodReference getFactoryMethod( Method mappingMethod, Type targetType ) {
|
||||||
|
|
||||||
|
ResolvingAttempt attempt = new ResolvingAttempt(
|
||||||
|
sourceModel,
|
||||||
|
mappingMethod,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
SourceMethod matchingSourceMethod = attempt.getBestMatch( sourceModel, null, targetType );
|
||||||
|
if ( matchingSourceMethod != null ) {
|
||||||
|
MapperReference ref = attempt.findMapperReference( matchingSourceMethod );
|
||||||
|
return new MethodReference( matchingSourceMethod, ref, null );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private class ResolvingAttempt {
|
private class ResolvingAttempt {
|
||||||
|
|
||||||
private final Method mappingMethod;
|
private final Method mappingMethod;
|
||||||
@ -416,13 +440,13 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
|
|
||||||
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) {
|
||||||
|
|
||||||
|
SelectionCriteria criteria = new SelectionCriteria( qualifiers, targetPropertyName );
|
||||||
List<T> candidates = methodSelectors.getMatchingMethods(
|
List<T> candidates = methodSelectors.getMatchingMethods(
|
||||||
mappingMethod,
|
mappingMethod,
|
||||||
methods,
|
methods,
|
||||||
sourceType,
|
sourceType,
|
||||||
returnType,
|
returnType,
|
||||||
qualifiers,
|
criteria
|
||||||
targetPropertyName
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// raise an error if more than one mapping method is suitable to map the given source type
|
// raise an error if more than one mapping method is suitable to map the given source type
|
||||||
@ -430,7 +454,8 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
if ( candidates.size() > 1 ) {
|
if ( candidates.size() > 1 ) {
|
||||||
|
|
||||||
String errorMsg = String.format(
|
String errorMsg = String.format(
|
||||||
"Ambiguous mapping methods found for mapping " + mappedElement + " to %s: %s.",
|
"Ambiguous mapping methods found for %s %s: %s.",
|
||||||
|
mappedElement != null ? "mapping " + mappedElement + " to" : "factorizing",
|
||||||
returnType,
|
returnType,
|
||||||
Strings.join( candidates, ", " )
|
Strings.join( candidates, ", " )
|
||||||
);
|
);
|
||||||
|
@ -44,14 +44,13 @@ public class FactoryTest {
|
|||||||
@ExpectedCompilationOutcome(
|
@ExpectedCompilationOutcome(
|
||||||
value = CompilationResult.FAILED,
|
value = CompilationResult.FAILED,
|
||||||
diagnostics = {
|
diagnostics = {
|
||||||
@Diagnostic(type = BarFactory.class,
|
@Diagnostic(type = SourceTargetMapperAndBarFactory.class,
|
||||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
line = 29,
|
line = 35,
|
||||||
messageRegExp = "Ambiguous factory methods: \"org\\.mapstruct\\.ap\\.test\\.erroneous\\."
|
messageRegExp = "Ambiguous mapping methods found for factorizing "
|
||||||
+ "ambiguousfactorymethod\\.Bar createBar\\(\\)\" conflicts with "
|
+ "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar: "
|
||||||
+ "\"org\\.mapstruct\\.ap\\.test\\.erroneous\\.ambiguousfactorymethod\\.Bar "
|
+ "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar createBar\\(\\), "
|
||||||
+ "org\\.mapstruct\\.ap\\.test\\.erroneous\\.ambiguousfactorymethod"
|
+ "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar .*BarFactory.createBar\\(\\)." )
|
||||||
+ "\\.a\\.BarFactory\\.createBar\\(\\)\"\\")
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public void shouldUseTwoFactoryMethods() {
|
public void shouldUseTwoFactoryMethods() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user