This commit is contained in:
Gunnar Morling 2014-02-28 19:54:47 +01:00
parent 53ff1b7e13
commit 8ddb2a9fb3
7 changed files with 102 additions and 98 deletions

View File

@ -72,7 +72,7 @@ public class MethodReference extends MappingMethod {
return contextParam;
}
public void setMethodRefChild( MethodReference methodRefChild ) {
public void setMethodRefChild(MethodReference methodRefChild) {
this.methodRefChild = methodRefChild;
}
@ -83,7 +83,7 @@ public class MethodReference extends MappingMethod {
@Override
public Set<Type> getImportTypes() {
Set<Type> imported = super.getImportTypes();
if (methodRefChild != null) {
if ( methodRefChild != null ) {
imported.addAll( methodRefChild.getImportTypes() );
}
return imported;

View File

@ -26,7 +26,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.Messager;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
@ -628,43 +627,44 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
conversion
);
if (!isPropertyMappable( property ) ) {
if ( !isPropertyMappable( property ) ) {
// when not mappable, try again with another property mapping method based on parameter only.
mappingMethodReference = getMappingMethodReferenceBasedOnParameter(
method,
"property '" + Executables.getPropertyName( sourceAccessor ) + "'",
mapperReferences,
methods,
sourceType,
targetType,
targetPropertyName,
dateFormat );
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
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,
String.format(
"Can't map property \"%s %s\" to \"%s %s\".",
property.getSourceType(),
property.getSourceName(),
property.getTargetType(),
property.getTargetName()
),
method.getExecutable()
Kind.ERROR,
String.format(
"Can't map property \"%s %s\" to \"%s %s\".",
property.getSourceType(),
property.getSourceName(),
property.getTargetType(),
property.getTargetName()
),
method.getExecutable()
);
}
return property;
@ -699,17 +699,18 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
);
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
mappingMethodReference == null ) {
mappingMethodReference == null ) {
// when no conversion is found and no mapping method try match based on parameter only
mappingMethodReference = getMappingMethodReferenceBasedOnParameter(
method,
"collection element",
mapperReferences,
methods,
sourceElementType,
targetElementType,
null, // there is no targetPropertyName
dateFormat );
method,
"collection element",
mapperReferences,
methods,
sourceElementType,
targetElementType,
null, // there is no targetPropertyName
dateFormat
);
}
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
@ -759,14 +760,15 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
if ( !keySourceType.isAssignableTo( keyTargetType ) && keyConversion == null && keyMappingMethod == null ) {
// when no conversion is found and no mapping method try match based on parameter only
keyMappingMethod = getMappingMethodReferenceBasedOnParameter(
method,
"map key",
mapperReferences,
methods,
keySourceType,
keyTargetType,
null, // there is no targetPropertyName
keyDateFormat );
method,
"map key",
mapperReferences,
methods,
keySourceType,
keyTargetType,
null, // there is no targetPropertyName
keyDateFormat
);
}
if ( !keySourceType.isAssignableTo( keyTargetType ) && keyConversion == null && keyMappingMethod == null ) {
@ -807,14 +809,15 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
valueMappingMethod == null ) {
// when no conversion is found and no mapping method try match based on parameter only
keyMappingMethod = getMappingMethodReferenceBasedOnParameter(
method,
"map value",
mapperReferences,
methods,
valueSourceType,
valueTargetType,
null, // there is no targetPropertyName
valueDateFormat );
method,
"map value",
mapperReferences,
methods,
valueSourceType,
valueTargetType,
null, // there is no targetPropertyName
valueDateFormat
);
}
if ( !valueSourceType.isAssignableTo( valueTargetType ) && valueConversion == null &&
@ -991,13 +994,13 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
* Returns a reference to a method mapping the given source type to the given target type, if such a method exists.
*/
private MethodReference getMappingMethodReferenceBasedOnMethod(SourceMethod method,
String mappedElement,
List<MapperReference> mapperReferences,
List<SourceMethod> methods,
Type sourceType,
Type targetType,
String targetPropertyName,
String dateFormat) {
String mappedElement,
List<MapperReference> mapperReferences,
List<SourceMethod> methods,
Type sourceType,
Type targetType,
String targetPropertyName,
String dateFormat) {
// first try to find a matching source method
SourceMethod matchingSourceMethod = getBestMatch(
method,
@ -1043,17 +1046,18 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
* @param parameterType parameter to match
* @param returnType return type to match
* @param dateFormat used for formatting dates in build in methods that need context information
*
* @return a method reference.
*/
private MethodReference getMappingMethodReferenceBasedOnParameter(SourceMethod mappingMethod,
String mappedElement,
List<MapperReference>
mapperReferences,
List<SourceMethod> methods,
Type parameterType,
Type returnType,
String targetPropertyName,
String dateFormat) {
String mappedElement,
List<MapperReference>
mapperReferences,
List<SourceMethod> methods,
Type parameterType,
Type returnType,
String targetPropertyName,
String dateFormat) {
List<Method> methodYCandidates = new ArrayList<Method>( methods );
methodYCandidates.addAll( builtInMethods.getBuiltInMethods() );
@ -1067,25 +1071,29 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
// For each of the candidates, we need to look if there's a methodY, either
// 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) )
for (Method methodYCandidate : methodYCandidates ) {
for ( Method methodYCandidate : methodYCandidates ) {
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
methodRefY = getMappingMethodReferenceBasedOnMethod( mappingMethod,
methodRefY = getMappingMethodReferenceBasedOnMethod(
mappingMethod,
mappedElement,
mapperReferences,
methods,
methodYCandidate.getParameters().get( 0 ).getType(),
returnType,
targetPropertyName,
dateFormat
);
if ( methodRefY != null ) {
MethodReference methodRefX = getMappingMethodReferenceBasedOnMethod(
mappingMethod,
mappedElement,
mapperReferences,
methods,
methodYCandidate.getParameters().get( 0 ).getType(),
returnType,
parameterType,
methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetPropertyName,
dateFormat );
if ( methodRefY != null ) {
MethodReference methodRefX = getMappingMethodReferenceBasedOnMethod( mappingMethod,
mappedElement,
mapperReferences,
methods,
parameterType,
methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetPropertyName,
dateFormat );
dateFormat
);
if ( methodRefX != null ) {
methodRefY.setMethodRefChild( methodRefX );
break;

View File

@ -21,7 +21,6 @@ package org.mapstruct.ap.test.nestedmethodcall;
import java.util.List;
/**
*
* @author Sjaak Derksen
*/
public class OrderDetailsDto {
@ -33,7 +32,7 @@ public class OrderDetailsDto {
return name;
}
public void setName( String name ) {
public void setName(String name) {
this.name = name;
}
@ -41,7 +40,7 @@ public class OrderDetailsDto {
return description;
}
public void setDescription( List<String> description ) {
public void setDescription(List<String> description) {
this.description = description;
}

View File

@ -23,7 +23,6 @@ import java.util.List;
import javax.xml.bind.JAXBElement;
/**
*
* @author Sjaak Derksen
*/
public class OrderDetailsType {
@ -39,7 +38,7 @@ public class OrderDetailsType {
this.name = value;
}
public void setDescription( List<JAXBElement<String>> description ) {
public void setDescription(List<JAXBElement<String>> description) {
this.description = description;
}

View File

@ -22,7 +22,6 @@ package org.mapstruct.ap.test.nestedmethodcall;
import java.util.List;
/**
*
* @author Sjaak Derksen
*/
public class OrderDto {
@ -35,7 +34,7 @@ public class OrderDto {
return orderNumber;
}
public void setOrderNumber( Long orderNumber ) {
public void setOrderNumber(Long orderNumber) {
this.orderNumber = orderNumber;
}
@ -43,7 +42,7 @@ public class OrderDto {
return orderDetails;
}
public void setOrderDetails( OrderDetailsDto orderDetails ) {
public void setOrderDetails(OrderDetailsDto orderDetails) {
this.orderDetails = orderDetails;
}
@ -51,7 +50,7 @@ public class OrderDto {
return dates;
}
public void setDates( List<String> dates ) {
public void setDates(List<String> dates) {
this.dates = dates;
}

View File

@ -24,7 +24,6 @@ import javax.xml.bind.JAXBElement;
import javax.xml.datatype.XMLGregorianCalendar;
/**
*
* @author Sjaak Derksen
*/
public class OrderType {
@ -54,7 +53,7 @@ public class OrderType {
return dates;
}
public void setDates( List<JAXBElement<XMLGregorianCalendar>> dates ) {
public void setDates(List<JAXBElement<XMLGregorianCalendar>> dates) {
this.dates = dates;
}

View File

@ -22,22 +22,22 @@ package org.mapstruct.ap.test.nestedmethodcall;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.datatype.XMLGregorianCalendar;
import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Sjaak Derksen
*/
@Mapper
public interface SourceTargetMapper {
public interface SourceTargetMapper {
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
OrderDto sourceToTarget(OrderType source);
OrderDetailsDto detailsToDto(OrderDetailsType source);
OrderDetailsDto detailsToDto(OrderDetailsType source);
@IterableMapping(dateFormat = "dd.MM.yyyy")
List<String> stringListToDateList(List<JAXBElement<XMLGregorianCalendar>> dates);