mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#157 moving duplicated code from MapperCreationProcessor (PropertyMapping, IterableMapping and MapMapping) to MappingResolver
This commit is contained in:
parent
59719dc6cb
commit
6f68512406
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright 2012-2014 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;
|
||||
|
||||
/**
|
||||
* This class carries the possible ways to do an assignment to a parameter on a mapping target
|
||||
*
|
||||
* The following options exist:
|
||||
* <ol>
|
||||
* <li>MethodReference</li>
|
||||
* <li>TypeConversion</li>
|
||||
* <li>Simple Assignment (empty ParameterAssignment)</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class ParameterAssignment {
|
||||
|
||||
|
||||
private MethodReference methodReference;
|
||||
private TypeConversion typeConversion;
|
||||
|
||||
public ParameterAssignment() {
|
||||
}
|
||||
|
||||
public ParameterAssignment( MethodReference methodReference ) {
|
||||
this.methodReference = methodReference;
|
||||
}
|
||||
|
||||
public ParameterAssignment( TypeConversion typeConversion ) {
|
||||
this.typeConversion = typeConversion;
|
||||
}
|
||||
|
||||
public MethodReference getMethodReference() {
|
||||
return methodReference;
|
||||
}
|
||||
|
||||
public TypeConversion getTypeConversion() {
|
||||
return typeConversion;
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.mapstruct.ap.processor;
|
||||
|
||||
import org.mapstruct.ap.model.ParameterAssignment;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -48,7 +49,6 @@ import org.mapstruct.ap.model.MapperReference;
|
||||
import org.mapstruct.ap.model.MappingMethod;
|
||||
import org.mapstruct.ap.model.MethodReference;
|
||||
import org.mapstruct.ap.model.PropertyMapping;
|
||||
import org.mapstruct.ap.model.TypeConversion;
|
||||
import org.mapstruct.ap.model.common.Parameter;
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.common.TypeFactory;
|
||||
@ -79,7 +79,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
|
||||
private TypeFactory typeFactory;
|
||||
|
||||
private MappingMethodResolver mappingMethodResolver;
|
||||
private MappingResolver mappingResolver;
|
||||
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
|
||||
this.typeFactory = context.getTypeFactory();
|
||||
|
||||
this.mappingMethodResolver = new MappingMethodResolver(messager, typeFactory, elementUtils, typeUtils );
|
||||
this.mappingResolver = new MappingResolver(messager, typeFactory, elementUtils, typeUtils );
|
||||
|
||||
|
||||
return getMapper( mapperTypeElement, sourceModel );
|
||||
@ -107,7 +107,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
ReportingPolicy unmappedTargetPolicy = getEffectiveUnmappedTargetPolicy( element );
|
||||
List<MapperReference> mapperReferences = getReferencedMappers( element );
|
||||
List<MappingMethod> mappingMethods = getMappingMethods( mapperReferences, methods, unmappedTargetPolicy );
|
||||
mappingMethods.addAll( mappingMethodResolver.getVirtualMethodsToCreate() );
|
||||
mappingMethods.addAll( mappingResolver.getVirtualMethodsToGenerate() );
|
||||
|
||||
Mapper mapper = new Mapper.Builder()
|
||||
.element( element )
|
||||
@ -641,7 +641,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
String targetPropertyName = Executables.getPropertyName( targetAcessor );
|
||||
|
||||
String mappedElement = "property '" + Executables.getPropertyName( sourceAccessor ) + "'";
|
||||
MethodReference mappingMethodReference = mappingMethodResolver.getMappingMethodReferenceBasedOnMethod(
|
||||
|
||||
ParameterAssignment parameterAssignment = mappingResolver.getParameterAssignment(
|
||||
method,
|
||||
mappedElement,
|
||||
mapperReferences,
|
||||
@ -649,12 +650,6 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
sourceType,
|
||||
targetType,
|
||||
targetPropertyName,
|
||||
dateFormat
|
||||
);
|
||||
|
||||
TypeConversion conversion = mappingMethodResolver.getConversion(
|
||||
sourceType,
|
||||
targetType,
|
||||
dateFormat,
|
||||
conversionString
|
||||
);
|
||||
@ -667,37 +662,10 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
Executables.getPropertyName( targetAcessor ),
|
||||
targetAcessor.getSimpleName().toString(),
|
||||
targetType,
|
||||
mappingMethodReference,
|
||||
conversion
|
||||
parameterAssignment != null ? parameterAssignment.getMethodReference() : null,
|
||||
parameterAssignment != null ? parameterAssignment.getTypeConversion() : null
|
||||
);
|
||||
|
||||
if ( !isPropertyMappable( property ) ) {
|
||||
|
||||
// when not mappable, try again with another property mapping method based on parameter only.
|
||||
mappingMethodReference = mappingMethodResolver.getMappingMethodReferenceBasedOnParameter(
|
||||
method,
|
||||
"property '" + Executables.getPropertyName( sourceAccessor ) + "'",
|
||||
mapperReferences,
|
||||
methods,
|
||||
sourceType,
|
||||
targetType,
|
||||
targetPropertyName,
|
||||
dateFormat
|
||||
);
|
||||
|
||||
property = new PropertyMapping(
|
||||
parameter.getName(),
|
||||
Executables.getPropertyName( sourceAccessor ),
|
||||
sourceAccessor.getSimpleName().toString(),
|
||||
sourceType,
|
||||
Executables.getPropertyName( targetAcessor ),
|
||||
targetAcessor.getSimpleName().toString(),
|
||||
targetType,
|
||||
mappingMethodReference,
|
||||
conversion
|
||||
);
|
||||
}
|
||||
|
||||
if ( !isPropertyMappable( property ) ) {
|
||||
messager.printMessage(
|
||||
Kind.ERROR,
|
||||
@ -720,18 +688,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
Type sourceElementType = method.getSourceParameters().iterator().next().getType().getTypeParameters().get( 0 );
|
||||
Type targetElementType = method.getResultType().getTypeParameters().get( 0 );
|
||||
String dateFormat = method.getIterableMapping() != null ? method.getIterableMapping().getDateFormat() : null;
|
||||
String conversionStr = Strings.getSaveVariableName( sourceElementType.getName(), method.getParameterNames() );
|
||||
|
||||
TypeConversion conversion = mappingMethodResolver.getConversion(
|
||||
sourceElementType,
|
||||
targetElementType,
|
||||
dateFormat,
|
||||
Strings.getSaveVariableName(
|
||||
sourceElementType.getName(),
|
||||
method.getParameterNames()
|
||||
)
|
||||
);
|
||||
|
||||
MethodReference mappingMethodReference = mappingMethodResolver.getMappingMethodReferenceBasedOnMethod(
|
||||
ParameterAssignment parameterAssignment = mappingResolver.getParameterAssignment(
|
||||
method,
|
||||
"collection element",
|
||||
mapperReferences,
|
||||
@ -739,26 +698,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
sourceElementType,
|
||||
targetElementType,
|
||||
null, // there is no targetPropertyName
|
||||
dateFormat
|
||||
dateFormat,
|
||||
conversionStr
|
||||
);
|
||||
|
||||
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
|
||||
mappingMethodReference == null ) {
|
||||
// when no conversion is found and no mapping method try match based on parameter only
|
||||
mappingMethodReference = mappingMethodResolver.getMappingMethodReferenceBasedOnParameter(
|
||||
method,
|
||||
"collection element",
|
||||
mapperReferences,
|
||||
methods,
|
||||
sourceElementType,
|
||||
targetElementType,
|
||||
null, // there is no targetPropertyName
|
||||
dateFormat
|
||||
);
|
||||
}
|
||||
|
||||
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
|
||||
mappingMethodReference == null ) {
|
||||
if ( parameterAssignment == null ) {
|
||||
messager.printMessage(
|
||||
Kind.ERROR,
|
||||
String.format(
|
||||
@ -773,8 +717,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
MethodReference factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
|
||||
return new IterableMappingMethod(
|
||||
method,
|
||||
mappingMethodReference,
|
||||
conversion,
|
||||
parameterAssignment != null ? parameterAssignment.getMethodReference() : null,
|
||||
parameterAssignment != null ? parameterAssignment.getTypeConversion() : null,
|
||||
factoryMethod
|
||||
);
|
||||
}
|
||||
@ -789,7 +733,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
Type keyTargetType = resultTypeParams.get( 0 );
|
||||
String keyDateFormat = method.getMapMapping() != null ? method.getMapMapping().getKeyFormat() : null;
|
||||
|
||||
MethodReference keyMappingMethod = mappingMethodResolver.getMappingMethodReferenceBasedOnMethod(
|
||||
ParameterAssignment parameterAssignmentKey = mappingResolver.getParameterAssignment(
|
||||
method,
|
||||
"map key",
|
||||
mapperReferences,
|
||||
@ -797,26 +741,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
keySourceType,
|
||||
keyTargetType,
|
||||
null, // there is no targetPropertyName
|
||||
keyDateFormat
|
||||
keyDateFormat,
|
||||
"entry.getKey()"
|
||||
);
|
||||
TypeConversion keyConversion = mappingMethodResolver.getConversion( keySourceType, keyTargetType,
|
||||
keyDateFormat, "entry.getKey()" );
|
||||
|
||||
if ( !keySourceType.isAssignableTo( keyTargetType ) && keyConversion == null && keyMappingMethod == null ) {
|
||||
// when no conversion is found and no mapping method try match based on parameter only
|
||||
keyMappingMethod = mappingMethodResolver.getMappingMethodReferenceBasedOnParameter(
|
||||
method,
|
||||
"map key",
|
||||
mapperReferences,
|
||||
methods,
|
||||
keySourceType,
|
||||
keyTargetType,
|
||||
null, // there is no targetPropertyName
|
||||
keyDateFormat
|
||||
);
|
||||
}
|
||||
|
||||
if ( !keySourceType.isAssignableTo( keyTargetType ) && keyConversion == null && keyMappingMethod == null ) {
|
||||
if ( parameterAssignmentKey == null ) {
|
||||
messager.printMessage(
|
||||
Kind.ERROR,
|
||||
String.format(
|
||||
@ -833,7 +762,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
Type valueTargetType = resultTypeParams.get( 1 );
|
||||
String valueDateFormat = method.getMapMapping() != null ? method.getMapMapping().getValueFormat() : null;
|
||||
|
||||
MethodReference valueMappingMethod = mappingMethodResolver.getMappingMethodReferenceBasedOnMethod(
|
||||
ParameterAssignment parameterAssignmentValue = mappingResolver.getParameterAssignment(
|
||||
method,
|
||||
"map value",
|
||||
mapperReferences,
|
||||
@ -841,32 +770,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
valueSourceType,
|
||||
valueTargetType,
|
||||
null, // there is no targetPropertyName
|
||||
valueDateFormat
|
||||
);
|
||||
TypeConversion valueConversion = mappingMethodResolver.getConversion(
|
||||
valueSourceType,
|
||||
valueTargetType,
|
||||
valueDateFormat,
|
||||
"entry.getValue()"
|
||||
);
|
||||
|
||||
if ( !valueSourceType.isAssignableTo( valueTargetType ) && valueConversion == null &&
|
||||
valueMappingMethod == null ) {
|
||||
// when no conversion is found and no mapping method try match based on parameter only
|
||||
keyMappingMethod = mappingMethodResolver.getMappingMethodReferenceBasedOnParameter(
|
||||
method,
|
||||
"map value",
|
||||
mapperReferences,
|
||||
methods,
|
||||
valueSourceType,
|
||||
valueTargetType,
|
||||
null, // there is no targetPropertyName
|
||||
valueDateFormat
|
||||
);
|
||||
}
|
||||
|
||||
if ( !valueSourceType.isAssignableTo( valueTargetType ) && valueConversion == null &&
|
||||
valueMappingMethod == null ) {
|
||||
if ( parameterAssignmentValue == null ) {
|
||||
messager.printMessage(
|
||||
Kind.ERROR,
|
||||
String.format(
|
||||
@ -881,8 +789,12 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
MethodReference factoryMethod = getFactoryMethod( mapperReferences, methods, method.getReturnType() );
|
||||
|
||||
return new MapMappingMethod(
|
||||
method, keyMappingMethod, keyConversion, valueMappingMethod, valueConversion,
|
||||
factoryMethod
|
||||
method,
|
||||
parameterAssignmentKey != null ? parameterAssignmentKey.getMethodReference() : null,
|
||||
parameterAssignmentKey != null ? parameterAssignmentKey.getTypeConversion() : null,
|
||||
parameterAssignmentValue != null ? parameterAssignmentValue.getMethodReference() : null,
|
||||
parameterAssignmentValue != null ? parameterAssignmentValue.getTypeConversion() : null,
|
||||
factoryMethod
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.mapstruct.ap.processor;
|
||||
|
||||
import org.mapstruct.ap.model.ParameterAssignment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -64,7 +65,7 @@ import org.mapstruct.ap.util.Strings;
|
||||
*
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class MappingMethodResolver {
|
||||
public class MappingResolver {
|
||||
|
||||
private final Messager messager;
|
||||
private final TypeFactory typeFactory;
|
||||
@ -78,7 +79,8 @@ public class MappingMethodResolver {
|
||||
*/
|
||||
private final Set<VirtualMappingMethod> virtualMethods;
|
||||
|
||||
public MappingMethodResolver(Messager messager, TypeFactory typeFactory, Elements elementUtils, Types typeUtils) {
|
||||
|
||||
public MappingResolver(Messager messager, TypeFactory typeFactory, Elements elementUtils, Types typeUtils) {
|
||||
this.messager = messager;
|
||||
this.typeFactory = typeFactory;
|
||||
this.conversions = new Conversions( elementUtils, typeFactory );
|
||||
@ -88,7 +90,82 @@ public class MappingMethodResolver {
|
||||
}
|
||||
|
||||
|
||||
public TypeConversion getConversion(Type sourceType, Type targetType, String dateFormat, String sourceReference) {
|
||||
/**
|
||||
* returns a parameter assignment
|
||||
*
|
||||
* @param mappingMethod target mapping method
|
||||
* @param mappedElement used for error messages
|
||||
* @param mapperReferences list of references to mapper
|
||||
* @param methods list of candidate methods
|
||||
* @param sourceType parameter to match
|
||||
* @param targetType return type to match
|
||||
* @param targetPropertyName name of the target property
|
||||
* @param dateFormat used for formatting dates in build in methods that need context information
|
||||
* @param sourceReference call to source type as string
|
||||
*
|
||||
* @return an assignment to a method parameter, which can either be:
|
||||
* <ol>
|
||||
* <li>MethodReference</li>
|
||||
* <li>TypeConversion</li>
|
||||
* <li>Simple Assignment (empty ParameterAssignment)</li>
|
||||
* <li>null, no assignment found</li>
|
||||
* </ol>
|
||||
*/
|
||||
public ParameterAssignment getParameterAssignment( SourceMethod mappingMethod,
|
||||
String mappedElement,
|
||||
List<MapperReference> mapperReferences,
|
||||
List<SourceMethod> methods,
|
||||
Type sourceType,
|
||||
Type targetType,
|
||||
String targetPropertyName,
|
||||
String dateFormat,
|
||||
String sourceReference ) {
|
||||
|
||||
MethodReference mappingMethodReference = getMappingMethodReferenceBasedOnMethod(
|
||||
mappingMethod,
|
||||
mappedElement,
|
||||
mapperReferences,
|
||||
methods,
|
||||
sourceType,
|
||||
targetType,
|
||||
targetPropertyName,
|
||||
dateFormat
|
||||
);
|
||||
|
||||
ParameterAssignment parameterAssignment = null;
|
||||
|
||||
if (mappingMethodReference != null ) {
|
||||
parameterAssignment = new ParameterAssignment(mappingMethodReference );
|
||||
}
|
||||
else if (sourceType.isAssignableTo( targetType ) ) {
|
||||
parameterAssignment = new ParameterAssignment();
|
||||
}
|
||||
else {
|
||||
TypeConversion conversion = getConversion( sourceType, targetType, dateFormat, sourceReference );
|
||||
if ( conversion != null ) {
|
||||
parameterAssignment = new ParameterAssignment(conversion );
|
||||
}
|
||||
else {
|
||||
mappingMethodReference = getMappingMethodReferenceBasedOnParameter(
|
||||
mappingMethod,
|
||||
mappedElement,
|
||||
mapperReferences,
|
||||
methods,
|
||||
sourceType,
|
||||
targetType,
|
||||
targetPropertyName,
|
||||
dateFormat
|
||||
);
|
||||
if ( mappingMethodReference != null ) {
|
||||
parameterAssignment = new ParameterAssignment( mappingMethodReference );
|
||||
}
|
||||
}
|
||||
}
|
||||
return parameterAssignment;
|
||||
}
|
||||
|
||||
|
||||
private TypeConversion getConversion(Type sourceType, Type targetType, String dateFormat, String sourceReference) {
|
||||
ConversionProvider conversionProvider = conversions.getConversion( sourceType, targetType );
|
||||
|
||||
if ( conversionProvider == null ) {
|
||||
@ -115,7 +192,7 @@ public class MappingMethodResolver {
|
||||
*
|
||||
* @return a method reference.
|
||||
*/
|
||||
public MethodReference getMappingMethodReferenceBasedOnMethod(SourceMethod mappingMethod,
|
||||
private MethodReference getMappingMethodReferenceBasedOnMethod(SourceMethod mappingMethod,
|
||||
String mappedElement,
|
||||
List<MapperReference> mapperReferences,
|
||||
List<SourceMethod> methods,
|
||||
@ -172,7 +249,7 @@ public class MappingMethodResolver {
|
||||
*
|
||||
* @return a method reference.
|
||||
*/
|
||||
public MethodReference getMappingMethodReferenceBasedOnParameter(SourceMethod mappingMethod,
|
||||
private MethodReference getMappingMethodReferenceBasedOnParameter(SourceMethod mappingMethod,
|
||||
String mappedElement,
|
||||
List<MapperReference> mapperReferences,
|
||||
List<SourceMethod> methods,
|
||||
@ -267,7 +344,7 @@ public class MappingMethodResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<VirtualMappingMethod> getVirtualMethodsToCreate() {
|
||||
public Set<VirtualMappingMethod> getVirtualMethodsToGenerate() {
|
||||
return virtualMethods;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user