This commit is contained in:
Gunnar Morling 2014-10-12 18:24:17 +02:00
parent 9adbb423c6
commit a5dc5d78ab
5 changed files with 282 additions and 264 deletions

View File

@ -27,8 +27,8 @@ import java.util.Map;
import java.util.Set;
import javax.lang.model.element.ExecutableElement;
import javax.tools.Diagnostic;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Mapping;
@ -64,7 +64,7 @@ public class BeanMappingMethod extends MappingMethod {
return this;
}
public Builder souceMethod( SourceMethod sourceMethod ) {
public Builder souceMethod(SourceMethod sourceMethod) {
this.method = sourceMethod;
return this;
}
@ -339,11 +339,11 @@ public class BeanMappingMethod extends MappingMethod {
return !foundUnmappedProperty;
}
private void reportErrorForUnmappedTargetPropertiesIfRequired( SourceMethod method,
private void reportErrorForUnmappedTargetPropertiesIfRequired(SourceMethod method,
ReportingPolicy unmappedTargetPolicy,
Set<String> targetProperties,
Set<String> mappedTargetProperties,
Set<String> ignoredTargetProperties ) {
Set<String> ignoredTargetProperties) {
Set<String> unmappedTargetProperties = new HashSet<String>();
@ -366,7 +366,7 @@ public class BeanMappingMethod extends MappingMethod {
}
}
private boolean hasSourceProperty( String propertyName ) {
private boolean hasSourceProperty(String propertyName) {
for ( Parameter parameter : method.getSourceParameters() ) {
if ( hasSourceProperty( parameter, propertyName ) ) {
return true;
@ -376,7 +376,7 @@ public class BeanMappingMethod extends MappingMethod {
return false;
}
private boolean hasSourceProperty( Parameter parameter, String propertyName ) {
private boolean hasSourceProperty(Parameter parameter, String propertyName) {
List<ExecutableElement> getters = parameter.getType().getGetters();
return Executables.getPropertyNames( getters ).contains( propertyName );
}

View File

@ -18,11 +18,12 @@
*/
package org.mapstruct.ap.model;
import org.mapstruct.ap.model.assignment.Assignment;
import java.util.List;
import java.util.Set;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import org.mapstruct.ap.model.assignment.Assignment;
import org.mapstruct.ap.model.assignment.SetterWrapper;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
@ -48,27 +49,27 @@ public class IterableMappingMethod extends MappingMethod {
private String dateFormat;
private List<TypeMirror> qualifiers;
public Builder mappingContext( MappingContext mappingContext ) {
public Builder mappingContext(MappingContext mappingContext) {
this.ctx = mappingContext;
return this;
}
public Builder method( Method sourceMethod ) {
public Builder method(Method sourceMethod) {
this.method = sourceMethod;
return this;
}
public Builder dateFormat( String dateFormat ) {
public Builder dateFormat(String dateFormat) {
this.dateFormat = dateFormat;
return this;
}
public Builder qualifiers( List<TypeMirror> qualifiers ) {
public Builder qualifiers(List<TypeMirror> qualifiers) {
this.qualifiers = qualifiers;
return this;
}
public IterableMappingMethod build( ) {
public IterableMappingMethod build() {
Type sourceElementType =
method.getSourceParameters().iterator().next().getType().getTypeParameters().get( 0 );
Type targetElementType =
@ -77,7 +78,8 @@ public class IterableMappingMethod extends MappingMethod {
Strings.getSaveVariableName( sourceElementType.getName(), method.getParameterNames() );
Assignment assignment = ctx.getMappingResolver().getTargetAssignment( method,
Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
method,
"collection element",
sourceElementType,
targetElementType,
@ -177,7 +179,7 @@ public class IterableMappingMethod extends MappingMethod {
return false;
}
for (int i = 0; i < getSourceParameters().size(); i++ ) {
for ( int i = 0; i < getSourceParameters().size(); i++ ) {
if ( !getSourceParameters().get( i ).getType().getTypeParameters().get( 0 )
.equals( other.getSourceParameters().get( i ).getType().getTypeParameters().get( 0 ) ) ) {
return false;

View File

@ -18,11 +18,12 @@
*/
package org.mapstruct.ap.model;
import org.mapstruct.ap.model.assignment.Assignment;
import java.util.List;
import java.util.Set;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import org.mapstruct.ap.model.assignment.Assignment;
import org.mapstruct.ap.model.assignment.LocalVarWrapper;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
@ -51,32 +52,32 @@ public class MapMappingMethod extends MappingMethod {
private Method method;
private MappingContext ctx;
public Builder mappingContext( MappingContext mappingContext ) {
public Builder mappingContext(MappingContext mappingContext) {
this.ctx = mappingContext;
return this;
}
public Builder method( Method sourceMethod ) {
public Builder method(Method sourceMethod) {
this.method = sourceMethod;
return this;
}
public Builder keyDateFormat( String keyDateFormat ) {
public Builder keyDateFormat(String keyDateFormat) {
this.keyDateFormat = keyDateFormat;
return this;
}
public Builder valueDateFormat( String valueDateFormat ) {
public Builder valueDateFormat(String valueDateFormat) {
this.valueDateFormat = valueDateFormat;
return this;
}
public Builder keyQualifiers( List<TypeMirror> keyQualifiers ) {
public Builder keyQualifiers(List<TypeMirror> keyQualifiers) {
this.keyQualifiers = keyQualifiers;
return this;
}
public Builder valueQualifiers( List<TypeMirror> valueQualifiers ) {
public Builder valueQualifiers(List<TypeMirror> valueQualifiers) {
this.valueQualifiers = valueQualifiers;
return this;
}
@ -90,7 +91,8 @@ public class MapMappingMethod extends MappingMethod {
Type keySourceType = sourceTypeParams.get( 0 );
Type keyTargetType = resultTypeParams.get( 0 );
Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment( method,
Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment(
method,
"map key",
keySourceType,
keyTargetType,
@ -101,8 +103,10 @@ public class MapMappingMethod extends MappingMethod {
);
if ( keyAssignment == null ) {
String message = String.format( "Can't create implementation of method %s. Found no method nor "
+ "built-in conversion for mapping source key type to target key type.", method );
String message = String.format(
"Can't create implementation of method %s. Found no method nor "
+ "built-in conversion for mapping source key type to target key type.", method
);
method.printMessage( ctx.getMessager(), Diagnostic.Kind.ERROR, message );
}
@ -110,7 +114,8 @@ public class MapMappingMethod extends MappingMethod {
Type valueSourceType = sourceTypeParams.get( 1 );
Type valueTargetType = resultTypeParams.get( 1 );
Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment( method,
Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment(
method,
"map value",
valueSourceType,
valueTargetType,
@ -121,8 +126,10 @@ public class MapMappingMethod extends MappingMethod {
);
if ( valueAssignment == null ) {
String message = String.format( "Can't create implementation of method %s. Found no method nor "
+ "built-in conversion for mapping source value type to target value type.", method );
String message = String.format(
"Can't create implementation of method %s. Found no method nor "
+ "built-in conversion for mapping source value type to target value type.", method
);
method.printMessage( ctx.getMessager(), Diagnostic.Kind.ERROR, message );
}
@ -232,7 +239,7 @@ public class MapMappingMethod extends MappingMethod {
return false;
}
for (int i = 0; i < getSourceParameters().size(); i++ ) {
for ( int i = 0; i < getSourceParameters().size(); i++ ) {
if ( !getSourceParameters().get( i ).getType().getTypeParameters().get( 0 )
.equals( other.getSourceParameters().get( i ).getType().getTypeParameters().get( 0 ) ) ) {
return false;

View File

@ -25,7 +25,6 @@ import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.processing.Messager;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
@ -88,7 +87,14 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
typeUtils,
messager,
options,
new MappingResolverImpl( context.getMessager(), elementUtils, typeUtils, typeFactory, sourceModel, mapperReferences ),
new MappingResolverImpl(
context.getMessager(),
elementUtils,
typeUtils,
typeFactory,
sourceModel,
mapperReferences
),
mapperTypeElement,
sourceModel,
mapperReferences
@ -232,7 +238,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
return extraImports;
}
private List<MappingMethod> getMappingMethods(List<SourceMethod> methods ) {
private List<MappingMethod> getMappingMethods(List<SourceMethod> methods) {
List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>();
for ( SourceMethod method : methods ) {
@ -245,7 +251,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
boolean hasFactoryMethod = false;
if ( method.isIterableMapping() ) {
IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder( );
IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder();
if ( method.getIterableMapping() == null && reverseMappingMethod != null &&
reverseMappingMethod.getIterableMapping() != null ) {
method.setIterableMapping( reverseMappingMethod.getIterableMapping() );
@ -270,7 +276,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
else if ( method.isMapMapping() ) {
MapMappingMethod.Builder builder = new MapMappingMethod.Builder( );
MapMappingMethod.Builder builder = new MapMappingMethod.Builder();
if ( method.getMapMapping() == null && reverseMappingMethod != null &&
reverseMappingMethod.getMapMapping() != null ) {
@ -320,7 +326,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
else {
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder( );
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
if ( method.getMappings().isEmpty() ) {
if ( reverseMappingMethod != null && !reverseMappingMethod.getMappings().isEmpty() ) {

View File

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.Messager;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
@ -74,7 +73,8 @@ public class MappingResolverImpl implements MappingResolver {
*/
private final Set<VirtualMappingMethod> usedVirtualMappings = new HashSet<VirtualMappingMethod>();
public MappingResolverImpl(Messager messager, Elements elementUtils, Types typeUtils, TypeFactory typeFactory, List<SourceMethod> sourceModel, List<MapperReference> mapperReferences) {
public MappingResolverImpl(Messager messager, Elements elementUtils, Types typeUtils, TypeFactory typeFactory,
List<SourceMethod> sourceModel, List<MapperReference> mapperReferences) {
this.messager = messager;
this.typeUtils = typeUtils;
this.typeFactory = typeFactory;
@ -120,9 +120,10 @@ public class MappingResolverImpl implements MappingResolver {
String targetPropertyName,
String dateFormat,
List<TypeMirror> qualifiers,
String sourceReference ) {
String sourceReference) {
ResolvingAttempt attempt = new ResolvingAttempt( sourceModel,
ResolvingAttempt attempt = new ResolvingAttempt(
sourceModel,
mapperReferences,
mappingMethod,
mappedElement,
@ -155,14 +156,14 @@ public class MappingResolverImpl implements MappingResolver {
// so this set must be cleared.
private final Set<VirtualMappingMethod> virtualMethodCandidates;
private ResolvingAttempt( List<SourceMethod> sourceModel,
private ResolvingAttempt(List<SourceMethod> sourceModel,
List<MapperReference> mapperReferences,
Method mappingMethod,
String mappedElement,
String targetPropertyName,
String dateFormat,
List<TypeMirror> qualifiers,
String sourceReference ) {
String sourceReference) {
this.mappingMethod = mappingMethod;
this.mappedElement = mappedElement;
this.methods = sourceModel;
@ -173,7 +174,7 @@ public class MappingResolverImpl implements MappingResolver {
this.virtualMethodCandidates = new HashSet<VirtualMappingMethod>();
}
private Assignment getTargetAssignment( Type sourceType, Type targetType ) {
private Assignment getTargetAssignment(Type sourceType, Type targetType) {
// first simple mapping method
Assignment referencedMethod = resolveViaMethod( sourceType, targetType );
@ -192,7 +193,7 @@ public class MappingResolverImpl implements MappingResolver {
// then type conversion
Assignment conversion = resolveViaConversion( sourceType, targetType );
if ( conversion != null ) {
conversion.setAssignment( AssignmentFactory.createSimple( sourceReference) );
conversion.setAssignment( AssignmentFactory.createSimple( sourceReference ) );
return conversion;
}
@ -221,7 +222,7 @@ public class MappingResolverImpl implements MappingResolver {
return null;
}
private Assignment resolveViaConversion( Type sourceType, Type targetType ) {
private Assignment resolveViaConversion(Type sourceType, Type targetType) {
ConversionProvider conversionProvider = conversions.getConversion( sourceType, targetType );
if ( conversionProvider == null ) {
@ -236,9 +237,8 @@ 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
* exists.
*
*/
private Assignment resolveViaMethod( Type sourceType, Type targetType ) {
private Assignment resolveViaMethod(Type sourceType, Type targetType) {
// first try to find a matching source method
SourceMethod matchingSourceMethod = getBestMatch( methods, sourceType, targetType );
@ -273,7 +273,7 @@ public class MappingResolverImpl implements MappingResolver {
* </ul>
* then this method tries to resolve this combination and make a mapping methodY( methodX ( parameter ) )
*/
private Assignment resolveViaMethodAndMethod( Type sourceType, Type targetType ) {
private Assignment resolveViaMethodAndMethod(Type sourceType, Type targetType) {
List<Method> methodYCandidates = new ArrayList<Method>( methods );
methodYCandidates.addAll( builtInMethods.getBuiltInMethods() );
@ -288,8 +288,10 @@ public class MappingResolverImpl implements MappingResolver {
// a nested method call can be called. so C = methodY( methodX (A) )
for ( Method methodYCandidate : methodYCandidates ) {
if ( methodYCandidate.getSourceParameters().size() == 1 ) {
methodRefY = resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetType );
methodRefY = resolveViaMethod(
methodYCandidate.getSourceParameters().get( 0 ).getType(),
targetType
);
if ( methodRefY != null ) {
Assignment methodRefX = resolveViaMethod(
sourceType,
@ -319,7 +321,7 @@ public class MappingResolverImpl implements MappingResolver {
* </ul>
* then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) )
*/
private Assignment resolveViaConversionAndMethod( Type sourceType, Type targetType ) {
private Assignment resolveViaConversionAndMethod(Type sourceType, Type targetType) {
List<Method> methodYCandidates = new ArrayList<Method>( methods );
methodYCandidates.addAll( builtInMethods.getBuiltInMethods() );
@ -361,7 +363,7 @@ public class MappingResolverImpl implements MappingResolver {
* </ul>
* then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) )
*/
private Assignment resolveViaMethodAndConversion( Type sourceType, Type targetType ) {
private Assignment resolveViaMethodAndConversion(Type sourceType, Type targetType) {
List<Method> methodXCandidates = new ArrayList<Method>( methods );
methodXCandidates.addAll( builtInMethods.getBuiltInMethods() );
@ -393,7 +395,7 @@ public class MappingResolverImpl implements MappingResolver {
return conversionYRef;
}
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(
mappingMethod,
@ -412,7 +414,8 @@ public class MappingResolverImpl implements MappingResolver {
"Ambiguous mapping methods found for mapping " + mappedElement + " from %s to %s: %s.",
sourceType,
returnType,
Strings.join( candidates, ", " ) );
Strings.join( candidates, ", " )
);
mappingMethod.printMessage( messager, Kind.ERROR, errorMsg );
}
@ -424,8 +427,8 @@ public class MappingResolverImpl implements MappingResolver {
return null;
}
private Assignment getMappingMethodReference( SourceMethod method,
Type targetType ) {
private Assignment getMappingMethodReference(SourceMethod method,
Type targetType) {
MapperReference mapperReference = findMapperReference( method );
return AssignmentFactory.createMethodReference(
@ -435,7 +438,7 @@ public class MappingResolverImpl implements MappingResolver {
);
}
private MapperReference findMapperReference( SourceMethod method ) {
private MapperReference findMapperReference(SourceMethod method) {
for ( MapperReference ref : mapperReferences ) {
if ( ref.getType().equals( method.getDeclaringMapper() ) ) {
return ref;
@ -459,7 +462,7 @@ public class MappingResolverImpl implements MappingResolver {
*
* @return {@code true} if the specified property can be mapped, {@code false} otherwise.
*/
private boolean isPropertyMappable( Type sourceType, Type targetType ) {
private boolean isPropertyMappable(Type sourceType, Type targetType) {
boolean collectionOrMapTargetTypeHasCompatibleConstructor = false;
if ( sourceType.isCollectionType() && targetType.isCollectionType() ) {
@ -495,7 +498,7 @@ public class MappingResolverImpl implements MappingResolver {
* @return {@code true} if the target type has a constructor accepting the given source type, {@code false}
* otherwise.
*/
private boolean collectionTypeHasCompatibleConstructor( Type sourceType, Type targetType ) {
private boolean collectionTypeHasCompatibleConstructor(Type sourceType, Type targetType) {
// note (issue #127): actually this should check for the presence of a matching constructor, with help of
// Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead
// we just check whether the target type is parameterized in a way that it implicitly should have a
@ -521,7 +524,7 @@ public class MappingResolverImpl implements MappingResolver {
* @return {@code true} if the target type has a constructor accepting the given source type, {@code false}
* otherwise.
*/
private boolean mapTypeHasCompatibleConstructor( Type sourceType, Type targetType ) {
private boolean mapTypeHasCompatibleConstructor(Type sourceType, Type targetType) {
// note (issue #127): actually this should check for the presence of a matching constructor, with help of
// Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead
// we just check whether the target type is parameterized in a way that it implicitly should have a