#32 Replacing BeanMapping with plain list of mapping methods

This commit is contained in:
Gunnar Morling 2013-06-23 10:07:49 +02:00
parent 335b9d77ac
commit cd0306683f
9 changed files with 122 additions and 351 deletions

View File

@ -45,7 +45,6 @@ import javax.tools.JavaFileObject;
import org.mapstruct.ap.conversion.Conversion; import org.mapstruct.ap.conversion.Conversion;
import org.mapstruct.ap.conversion.Conversions; import org.mapstruct.ap.conversion.Conversions;
import org.mapstruct.ap.model.BeanMapping;
import org.mapstruct.ap.model.IterableMappingMethod; import org.mapstruct.ap.model.IterableMappingMethod;
import org.mapstruct.ap.model.Mapper; import org.mapstruct.ap.model.Mapper;
import org.mapstruct.ap.model.MappingMethod; import org.mapstruct.ap.model.MappingMethod;
@ -143,7 +142,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
List<Method> methods = retrieveMethods( element, true ); List<Method> methods = retrieveMethods( element, true );
//2.) build up aggregated "target" model //2.) build up aggregated "target" model
List<BeanMapping> mappings = getMappings( List<MappingMethod> mappings = getMappingMethods(
methods, methods,
getEffectiveUnmappedTargetPolicy( element ) getEffectiveUnmappedTargetPolicy( element )
); );
@ -186,48 +185,55 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
} }
} }
private List<BeanMapping> getMappings(List<Method> methods, private List<MappingMethod> getMappingMethods(List<Method> methods, ReportingPolicy unmappedTargetPolicy) {
ReportingPolicy unmappedTargetPolicy) { List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>();
List<BeanMapping> mappings = new ArrayList<BeanMapping>();
Set<Method> processedMethods = new HashSet<Method>();
for ( Method method : methods ) { for ( Method method : methods ) {
if ( processedMethods.contains( method ) || method.getDeclaringMapper() != null ) { if ( method.getDeclaringMapper() != null ) {
continue; continue;
} }
Method reverseMappingMethod = getReverseMappingMethod( methods, method ); if ( method.getMappings().isEmpty() ) {
Method reverseMappingMethod = getReverseMappingMethod( methods, method );
if ( reverseMappingMethod != null ) { if ( reverseMappingMethod != null && !reverseMappingMethod.getMappings().isEmpty() ) {
processedMethods.add( reverseMappingMethod ); method.setMappings( reverse( reverseMappingMethod.getMappings() ) );
}
} }
boolean isIterableMapping = method.getSourceType().isIterableType() && method.getTargetType() if ( method.isIterableMapping() ) {
.isIterableType(); mappingMethods.add( getIterableMappingMethod( methods, method ) );
if ( isIterableMapping ) {
mappings.add( getIterableBeanMapping( methods, method, reverseMappingMethod ) );
} }
else { else {
mappings.add( getSimpleBeanMapping( methods, unmappedTargetPolicy, method, reverseMappingMethod ) ); mappingMethods.add( getSimpleMappingMethod( methods, method, unmappedTargetPolicy ) );
} }
} }
return mappings; return mappingMethods;
} }
private BeanMapping getSimpleBeanMapping(List<Method> methods, ReportingPolicy unmappedTargetPolicy, Method method, private Map<String, Mapping> reverse(Map<String, Mapping> mappings) {
Method rawReverseMappingMethod) { Map<String, Mapping> reversed = new HashMap<String, Mapping>();
for ( Mapping mapping : mappings.values() ) {
reversed.put( mapping.getTargetName(), mapping.reverse() );
}
return reversed;
}
private MappingMethod getSimpleMappingMethod(List<Method> methods, Method method,
ReportingPolicy unmappedTargetPolicy) {
List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>(); List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>();
List<PropertyMapping> reversePropertyMappings = new ArrayList<PropertyMapping>();
Set<String> mappedSourceProperties = new HashSet<String>();
Set<String> mappedTargetProperties = new HashSet<String>(); Set<String> mappedTargetProperties = new HashSet<String>();
for ( MappedProperty property : method.getMappedProperties() ) { List<MappedProperty> mappedProperties = retrieveMappedProperties( method );
mappedSourceProperties.add( property.getSourceName() );
for ( MappedProperty property : mappedProperties ) {
mappedTargetProperties.add( property.getTargetName() ); mappedTargetProperties.add( property.getTargetName() );
Method propertyMappingMethod = getPropertyMappingMethod( methods, property ); MappingMethodReference propertyMappingMethod = getMappingMethodReference(
Method reversePropertyMappingMethod = getReversePropertyMappingMethod( methods, property ); methods,
property.getSourceType(),
property.getTargetType()
);
Conversion conversion = conversions.getConversion( Conversion conversion = conversions.getConversion(
property.getSourceType(), property.getSourceType(),
property.getTargetType() property.getTargetType()
@ -235,10 +241,8 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
reportErrorIfPropertyCanNotBeMapped( reportErrorIfPropertyCanNotBeMapped(
method, method,
rawReverseMappingMethod,
property, property,
propertyMappingMethod, propertyMappingMethod,
reversePropertyMappingMethod,
conversion conversion
); );
@ -250,84 +254,31 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
property.getSourceType(), property.getSourceType(),
property.getTargetWriteAccessorName(), property.getTargetWriteAccessorName(),
property.getTargetType(), property.getTargetType(),
propertyMappingMethod != null ? new MappingMethodReference( propertyMappingMethod,
propertyMappingMethod.getDeclaringMapper(),
propertyMappingMethod.getName(),
propertyMappingMethod.getParameterName(),
property.getSourceType(),
property.getTargetType()
) : null,
conversion != null ? conversion.to( conversion != null ? conversion.to(
method.getParameterName() + "." + property.getSourceReadAccessorName() + "()", method.getParameterName() + "." + property.getSourceReadAccessorName() + "()",
property.getTargetType() property.getTargetType()
) : null ) : null
) )
); );
if ( rawReverseMappingMethod != null ) {
reversePropertyMappings.add(
new PropertyMapping(
rawReverseMappingMethod.getParameterName(),
Introspector.decapitalize( rawReverseMappingMethod.getTargetType().getName() ),
property.getTargetReadAccessorName(),
property.getTargetType(),
property.getSourceWriteAccessorName(),
property.getSourceType(),
reversePropertyMappingMethod != null ? new MappingMethodReference(
reversePropertyMappingMethod.getDeclaringMapper(),
reversePropertyMappingMethod.getName(),
reversePropertyMappingMethod.getParameterName(),
property.getTargetType(),
property.getSourceType()
) : null,
conversion != null && rawReverseMappingMethod != null ? conversion.from(
rawReverseMappingMethod.getParameterName() + "." +
property.getTargetReadAccessorName() +
"()",
property.getSourceType()
) : null
)
);
}
} }
MappingMethod mappingMethod = new SimpleMappingMethod( reportErrorForUnmappedTargetPropertiesIfRequired(
method,
unmappedTargetPolicy,
mappedTargetProperties
);
return new SimpleMappingMethod(
method.getName(), method.getName(),
method.getParameterName(), method.getParameterName(),
method.getSourceType(), method.getSourceType(),
method.getTargetType(), method.getTargetType(),
propertyMappings propertyMappings
); );
reportErrorForUnmappedTargetPropertiesIfRequired(
method.getExecutable(),
unmappedTargetPolicy,
method.getTargetProeprties(),
mappedTargetProperties
);
MappingMethod reverseMappingMethod = null;
if ( rawReverseMappingMethod != null ) {
reverseMappingMethod = new SimpleMappingMethod(
rawReverseMappingMethod.getName(),
rawReverseMappingMethod.getParameterName(),
method.getTargetType(),
method.getSourceType(),
reversePropertyMappings
);
reportErrorForUnmappedTargetPropertiesIfRequired(
rawReverseMappingMethod.getExecutable(),
unmappedTargetPolicy,
method.getSourceProperties(),
mappedSourceProperties
);
}
return new BeanMapping( mappingMethod, reverseMappingMethod );
} }
private BeanMapping getIterableBeanMapping(List<Method> methods, Method method, Method rawReverseMappingMethod) { private MappingMethod getIterableMappingMethod(List<Method> methods, Method method) {
String toConversionString = getIterableConversionString( String toConversionString = getIterableConversionString(
conversions, conversions,
method.getSourceType().getElementType(), method.getSourceType().getElementType(),
@ -335,59 +286,41 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
true true
); );
String fromConversionString = getIterableConversionString( return new IterableMappingMethod(
conversions,
method.getTargetType().getElementType(),
method.getSourceType().getElementType(),
false
);
MappingMethod mappingMethod = new IterableMappingMethod(
method.getName(), method.getName(),
method.getParameterName(), method.getParameterName(),
method.getSourceType(), method.getSourceType(),
method.getTargetType(), method.getTargetType(),
getElementMappingMethod( methods, method ), getMappingMethodReference(
methods,
method.getSourceType().getElementType(),
method.getTargetType().getElementType()
),
toConversionString toConversionString
); );
MappingMethod reverseMappingMethod = null;
if ( rawReverseMappingMethod != null ) {
reverseMappingMethod = new IterableMappingMethod(
rawReverseMappingMethod.getName(),
rawReverseMappingMethod.getParameterName(),
method.getTargetType(),
method.getSourceType(),
getElementMappingMethod( methods, rawReverseMappingMethod ),
fromConversionString
);
}
return new BeanMapping( mappingMethod, reverseMappingMethod );
} }
private void reportErrorForUnmappedTargetPropertiesIfRequired(ExecutableElement method, private void reportErrorForUnmappedTargetPropertiesIfRequired(Method method,
ReportingPolicy unmappedTargetPolicy, ReportingPolicy unmappedTargetPolicy,
Set<String> targetProperties,
Set<String> mappedTargetProperties) { Set<String> mappedTargetProperties) {
if ( targetProperties.size() > mappedTargetProperties.size() && unmappedTargetPolicy.requiresReport() ) { if ( method.getTargetProeprties().size() > mappedTargetProperties.size() &&
targetProperties.removeAll( mappedTargetProperties ); unmappedTargetPolicy.requiresReport() ) {
method.getTargetProeprties().removeAll( mappedTargetProperties );
printMessage( printMessage(
unmappedTargetPolicy, unmappedTargetPolicy,
MessageFormat.format( MessageFormat.format(
"Unmapped target {0,choice,1#property|1<properties}: \"{1}\"", "Unmapped target {0,choice,1#property|1<properties}: \"{1}\"",
targetProperties.size(), method.getTargetProeprties().size(),
Strings.join( targetProperties, ", " ) Strings.join( method.getTargetProeprties(), ", " )
), ),
method method.getExecutable()
); );
} }
} }
private void reportErrorIfPropertyCanNotBeMapped(Method method, Method reverseMethod, MappedProperty property, private void reportErrorIfPropertyCanNotBeMapped(Method method, MappedProperty property,
Method propertyMappingMethod, Method reversePropertyMappingMethod, MappingMethodReference propertyMappingMethod,
Conversion conversion) { Conversion conversion) {
if ( property.getSourceType().equals( property.getTargetType() ) ) { if ( property.getSourceType().equals( property.getTargetType() ) ) {
return; return;
@ -412,29 +345,6 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
method.getExecutable() method.getExecutable()
); );
} }
if ( reverseMethod == null ) {
return;
}
if ( !(
reversePropertyMappingMethod != null ||
conversion != null ||
( property.getSourceType().isCollectionType() && property.getSourceType()
.getCollectionImplementationType() != null ) ) ) {
printMessage(
ReportingPolicy.ERROR,
String.format(
"Can't map property \"%s %s\" to \"%s %s\".",
property.getTargetType(),
property.getTargetName(),
property.getSourceType(),
property.getSourceName()
),
reverseMethod.getExecutable()
);
}
} }
private String getIterableConversionString(Conversions conversions, Type sourceElementType, Type targetElementType, private String getIterableConversionString(Conversions conversions, Type sourceElementType, Type targetElementType,
@ -460,45 +370,24 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
return usedMapperTypes; return usedMapperTypes;
} }
private MappingMethodReference getElementMappingMethod(Iterable<Method> methods, Method method) { private MappingMethodReference getMappingMethodReference(Iterable<Method> methods, Type parameterType,
Method elementMappingMethod = null; Type returnType) {
for ( Method oneMethod : methods ) { for ( Method oneMethod : methods ) {
if ( oneMethod.getSourceType().equals( method.getSourceType().getElementType() ) ) { if ( oneMethod.getSourceType().equals( parameterType ) && oneMethod.getTargetType().equals( returnType ) ) {
elementMappingMethod = oneMethod; return new MappingMethodReference(
break; oneMethod.getDeclaringMapper(),
oneMethod.getName(),
oneMethod.getParameterName(),
oneMethod.getSourceType(),
oneMethod.getTargetType()
);
} }
} }
return elementMappingMethod == null ? null : new MappingMethodReference(
elementMappingMethod.getDeclaringMapper(),
elementMappingMethod.getName(),
elementMappingMethod.getParameterName(),
elementMappingMethod.getSourceType(),
elementMappingMethod.getTargetType()
);
}
private Method getPropertyMappingMethod(Iterable<Method> rawMethods, MappedProperty property) {
for ( Method oneMethod : rawMethods ) {
if ( oneMethod.getSourceType().equals( property.getSourceType() ) && oneMethod.getTargetType()
.equals( property.getTargetType() ) ) {
return oneMethod;
}
}
return null; return null;
} }
private Method getReversePropertyMappingMethod(Iterable<Method> methods, MappedProperty property) { private Method getReverseMappingMethod(List<Method> rawMethods, Method method) {
for ( Method method : methods ) {
if ( method.getSourceType().equals( property.getTargetType() ) && method.getTargetType()
.equals( property.getSourceType() ) ) {
return method;
}
}
return null;
}
private Method getReverseMappingMethod(List<Method> rawMethods,
Method method) {
for ( Method oneMethod : rawMethods ) { for ( Method oneMethod : rawMethods ) {
if ( oneMethod.reverses( method ) ) { if ( oneMethod.reverses( method ) ) {
return oneMethod; return oneMethod;
@ -588,7 +477,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
returnType, returnType,
sourceProperties, sourceProperties,
targetProperties, targetProperties,
retrieveMappedProperties( method, sourceProperties, targetProperties ) getMappings( method )
) )
); );
} }
@ -627,18 +516,19 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
* method. * method.
* *
* @param method The method of interest * @param method The method of interest
* @param targetProperties
* @param sourceProperties
* *
* @return All mapped properties for the given method * @return All mapped properties for the given method
*/ */
private List<MappedProperty> retrieveMappedProperties(ExecutableElement method, Set<String> sourceProperties, private List<MappedProperty> retrieveMappedProperties(Method method) {
Set<String> targetProperties) { Map<String, Mapping> mappings = method.getMappings();
Map<String, Mapping> mappings = getMappings( method ); TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getExecutable().getReturnType() );
TypeElement parameterElement = (TypeElement) typeUtils.asElement(
TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getReturnType() ); method.getExecutable()
TypeElement parameterElement = (TypeElement) typeUtils.asElement( method.getParameters().get( 0 ).asType() ); .getParameters()
.get( 0 )
.asType()
);
List<MappedProperty> properties = new ArrayList<MappedProperty>(); List<MappedProperty> properties = new ArrayList<MappedProperty>();
@ -648,14 +538,8 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
List<ExecutableElement> targetSetters = Filters.setterMethodsIn( List<ExecutableElement> targetSetters = Filters.setterMethodsIn(
elementUtils.getAllMembers( returnTypeElement ) elementUtils.getAllMembers( returnTypeElement )
); );
List<ExecutableElement> sourceSetters = Filters.setterMethodsIn(
elementUtils.getAllMembers( parameterElement )
);
List<ExecutableElement> targetGetters = Filters.getterMethodsIn(
elementUtils.getAllMembers( returnTypeElement )
);
reportErrorIfMappedPropertiesDontExist( method, sourceProperties, targetProperties, mappings ); reportErrorIfMappedPropertiesDontExist( method );
for ( ExecutableElement getterMethod : sourceGetters ) { for ( ExecutableElement getterMethod : sourceGetters ) {
String sourcePropertyName = Executables.getPropertyName( getterMethod ); String sourcePropertyName = Executables.getPropertyName( getterMethod );
@ -665,22 +549,12 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
String targetPropertyName = Executables.getPropertyName( setterMethod ); String targetPropertyName = Executables.getPropertyName( setterMethod );
if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) { if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) {
ExecutableElement correspondingSetter = Executables.getCorrespondingPropertyAccessor(
getterMethod,
sourceSetters
);
ExecutableElement correspondingGetter = Executables.getCorrespondingPropertyAccessor(
setterMethod,
targetGetters
);
properties.add( properties.add(
new MappedProperty( new MappedProperty(
sourcePropertyName, sourcePropertyName,
getterMethod.getSimpleName().toString(), getterMethod.getSimpleName().toString(),
correspondingSetter != null ? correspondingSetter.getSimpleName().toString() : null,
retrieveReturnType( getterMethod ), retrieveReturnType( getterMethod ),
mapping != null ? mapping.getTargetName() : targetPropertyName, mapping != null ? mapping.getTargetName() : targetPropertyName,
correspondingGetter != null ? correspondingGetter.getSimpleName().toString() : null,
setterMethod.getSimpleName().toString(), setterMethod.getSimpleName().toString(),
retrieveParameter( setterMethod ).getType() retrieveParameter( setterMethod ).getType()
) )
@ -692,29 +566,26 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
return properties; return properties;
} }
private void reportErrorIfMappedPropertiesDontExist(ExecutableElement method, Set<String> sourcePropertyNames, private void reportErrorIfMappedPropertiesDontExist(Method method) {
Set<String> targetPropertyNames, for ( Mapping mappedProperty : method.getMappings().values() ) {
Map<String, Mapping> mappings) { if ( !method.getSourceProperties().contains( mappedProperty.getSourceName() ) ) {
for ( Mapping mappedProperty : mappings.values() ) {
if ( !sourcePropertyNames.contains( mappedProperty.getSourceName() ) ) {
printMessage( printMessage(
ReportingPolicy.ERROR, ReportingPolicy.ERROR,
String.format( String.format(
"Unknown property \"%s\" in parameter type %s.", "Unknown property \"%s\" in parameter type %s.",
mappedProperty.getSourceName(), mappedProperty.getSourceName(),
retrieveParameter( method ).getType() method.getSourceType()
), method, mappedProperty.getMirror(), mappedProperty.getSourceAnnotationValue() ), method.getExecutable(), mappedProperty.getMirror(), mappedProperty.getSourceAnnotationValue()
); );
} }
if ( !targetPropertyNames.contains( mappedProperty.getTargetName() ) ) { if ( !method.getTargetProeprties().contains( mappedProperty.getTargetName() ) ) {
printMessage( printMessage(
ReportingPolicy.ERROR, ReportingPolicy.ERROR,
String.format( String.format(
"Unknown property \"%s\" in return type %s.", "Unknown property \"%s\" in return type %s.",
mappedProperty.getTargetName(), mappedProperty.getTargetName(),
retrieveReturnType( method ) method.getTargetType()
), method, mappedProperty.getMirror(), mappedProperty.getTargetAnnotationValue() ), method.getExecutable(), mappedProperty.getMirror(), mappedProperty.getTargetAnnotationValue()
); );
} }
} }

View File

@ -1,48 +0,0 @@
/**
* Copyright 2012-2013 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;
public class BeanMapping extends AbstractModelElement {
private final MappingMethod mappingMethod;
private final MappingMethod reverseMappingMethod;
public BeanMapping(MappingMethod mappingMethod, MappingMethod reverseMappingMethod) {
this.mappingMethod = mappingMethod;
this.reverseMappingMethod = reverseMappingMethod;
}
public MappingMethod getMappingMethod() {
return mappingMethod;
}
public MappingMethod getReverseMappingMethod() {
return reverseMappingMethod;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "BeanMapping {" );
sb.append( "\n mappingMethod=" + mappingMethod.toString().replaceAll( "\n", "\n " ) + ',' );
sb.append( "\n reverseMappingMethod=" + reverseMappingMethod + ',' );
sb.append( "\n}" );
return sb.toString();
}
}

View File

@ -29,18 +29,18 @@ public class Mapper extends AbstractModelElement {
private final String packageName; private final String packageName;
private final String interfaceName; private final String interfaceName;
private final String implementationName; private final String implementationName;
private final List<BeanMapping> beanMappings; private final List<MappingMethod> mappingMethods;
private final List<Type> usedMapperTypes; private final List<Type> usedMapperTypes;
private final Options options; private final Options options;
private final SortedSet<Type> importedTypes; private final SortedSet<Type> importedTypes;
public Mapper(String packageName, String interfaceName, public Mapper(String packageName, String interfaceName,
String implementationName, List<BeanMapping> beanMappings, List<Type> usedMapperTypes, String implementationName, List<MappingMethod> mappingMethods, List<Type> usedMapperTypes,
Options options) { Options options) {
this.packageName = packageName; this.packageName = packageName;
this.interfaceName = interfaceName; this.interfaceName = interfaceName;
this.implementationName = implementationName; this.implementationName = implementationName;
this.beanMappings = beanMappings; this.mappingMethods = mappingMethods;
this.usedMapperTypes = usedMapperTypes; this.usedMapperTypes = usedMapperTypes;
this.options = options; this.options = options;
this.importedTypes = determineImportedTypes(); this.importedTypes = determineImportedTypes();
@ -50,9 +50,9 @@ public class Mapper extends AbstractModelElement {
SortedSet<Type> importedTypes = new TreeSet<Type>(); SortedSet<Type> importedTypes = new TreeSet<Type>();
importedTypes.add( Type.forClass( Generated.class ) ); importedTypes.add( Type.forClass( Generated.class ) );
for ( BeanMapping beanMapping : beanMappings ) { for ( MappingMethod mappingMethod : mappingMethods ) {
for ( Type type : beanMapping.getMappingMethod().getReferencedTypes() ) { for ( Type type : mappingMethod.getReferencedTypes() ) {
addWithDependents( importedTypes, type ); addWithDependents( importedTypes, type );
} }
} }
@ -85,7 +85,7 @@ public class Mapper extends AbstractModelElement {
sb.append( "\n implementationName='" + implementationName + "\'," ); sb.append( "\n implementationName='" + implementationName + "\'," );
sb.append( "\n beanMappings=[" ); sb.append( "\n beanMappings=[" );
for ( BeanMapping beanMapping : beanMappings ) { for ( MappingMethod beanMapping : mappingMethods ) {
sb.append( "\n " + beanMapping.toString().replaceAll( "\n", "\n " ) ); sb.append( "\n " + beanMapping.toString().replaceAll( "\n", "\n " ) );
} }
sb.append( "\n ]" ); sb.append( "\n ]" );
@ -107,8 +107,8 @@ public class Mapper extends AbstractModelElement {
return implementationName; return implementationName;
} }
public List<BeanMapping> getBeanMappings() { public List<MappingMethod> getMappingMethods() {
return beanMappings; return mappingMethods;
} }
public List<Type> getUsedMapperTypes() { public List<Type> getUsedMapperTypes() {

View File

@ -30,23 +30,17 @@ public class MappedProperty {
private final String sourceName; private final String sourceName;
private final String sourceReadAccessorName; private final String sourceReadAccessorName;
private final String sourceWriteAccessorName;
private final Type sourceType; private final Type sourceType;
private final String targetName; private final String targetName;
private final String targetReadAccessorName;
private final String targetWriteAccessorName; private final String targetWriteAccessorName;
private final Type targetType; private final Type targetType;
public MappedProperty(String sourceName, String sourceReadAccessorName, String sourceWriteAccessorName, public MappedProperty(String sourceName, String sourceReadAccessorName, Type sourceType, String targetName,
Type sourceType, String targetName, String targetReadAccessorName, String targetWriteAccessorName, Type targetType) {
String targetWriteAccessorName,
Type targetType) {
this.sourceName = sourceName; this.sourceName = sourceName;
this.sourceReadAccessorName = sourceReadAccessorName; this.sourceReadAccessorName = sourceReadAccessorName;
this.sourceWriteAccessorName = sourceWriteAccessorName;
this.sourceType = sourceType; this.sourceType = sourceType;
this.targetName = targetName; this.targetName = targetName;
this.targetReadAccessorName = targetReadAccessorName;
this.targetWriteAccessorName = targetWriteAccessorName; this.targetWriteAccessorName = targetWriteAccessorName;
this.targetType = targetType; this.targetType = targetType;
} }
@ -59,10 +53,6 @@ public class MappedProperty {
return sourceReadAccessorName; return sourceReadAccessorName;
} }
public String getSourceWriteAccessorName() {
return sourceWriteAccessorName;
}
public Type getSourceType() { public Type getSourceType() {
return sourceType; return sourceType;
} }
@ -71,10 +61,6 @@ public class MappedProperty {
return targetName; return targetName;
} }
public String getTargetReadAccessorName() {
return targetReadAccessorName;
}
public String getTargetWriteAccessorName() { public String getTargetWriteAccessorName() {
return targetWriteAccessorName; return targetWriteAccessorName;
} }

View File

@ -89,6 +89,10 @@ public class Mapping {
return targetAnnotationValue; return targetAnnotationValue;
} }
public Mapping reverse() {
return new Mapping( targetName, sourceName, mirror, sourceAnnotationValue, targetAnnotationValue );
}
@Override @Override
public String toString() { public String toString() {
return "Mapping {" + return "Mapping {" +

View File

@ -19,7 +19,7 @@
package org.mapstruct.ap.model.source; package org.mapstruct.ap.model.source;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
@ -38,15 +38,15 @@ public class Method {
private final String parameterName; private final String parameterName;
private final Type sourceType; private final Type sourceType;
private final Type targetType; private final Type targetType;
private Set<String> sourceProperties; private final Set<String> sourceProperties;
private Set<String> targetProeprties; private final Set<String> targetProeprties;
private final List<MappedProperty> mappedProperties; private Map<String, Mapping> mappings;
public static Method forMethodRequiringImplementation(ExecutableElement executable, String parameterName, public static Method forMethodRequiringImplementation(ExecutableElement executable, String parameterName,
Type sourceType, Type sourceType,
Type targetType, Set<String> sourceProperties, Type targetType, Set<String> sourceProperties,
Set<String> targetProperties, Set<String> targetProperties,
List<MappedProperty> mappedProperties) { Map<String, Mapping> mappings) {
return new Method( return new Method(
null, null,
@ -56,13 +56,12 @@ public class Method {
targetType, targetType,
sourceProperties, sourceProperties,
targetProperties, targetProperties,
mappedProperties mappings
); );
} }
public static Method forReferencedMethod(Type declaringMapper, ExecutableElement executable, String parameterName, public static Method forReferencedMethod(Type declaringMapper, ExecutableElement executable, String parameterName,
Type sourceType, Type sourceType, Type targetType) {
Type targetType) {
return new Method( return new Method(
declaringMapper, declaringMapper,
@ -72,13 +71,13 @@ public class Method {
targetType, targetType,
Collections.<String>emptySet(), Collections.<String>emptySet(),
Collections.<String>emptySet(), Collections.<String>emptySet(),
Collections.<MappedProperty>emptyList() Collections.<String, Mapping>emptyMap()
); );
} }
private Method(Type declaringMapper, ExecutableElement executable, String parameterName, Type sourceType, private Method(Type declaringMapper, ExecutableElement executable, String parameterName, Type sourceType,
Type targetType, Set<String> sourceProperties, Set<String> targetProperties, Type targetType, Set<String> sourceProperties, Set<String> targetProperties,
List<MappedProperty> mappedProperties) { Map<String, Mapping> mappings) {
this.declaringMapper = declaringMapper; this.declaringMapper = declaringMapper;
this.executable = executable; this.executable = executable;
this.parameterName = parameterName; this.parameterName = parameterName;
@ -86,7 +85,7 @@ public class Method {
this.targetType = targetType; this.targetType = targetType;
this.sourceProperties = sourceProperties; this.sourceProperties = sourceProperties;
this.targetProeprties = targetProperties; this.targetProeprties = targetProperties;
this.mappedProperties = mappedProperties; this.mappings = mappings;
} }
/** /**
@ -128,8 +127,12 @@ public class Method {
return targetProeprties; return targetProeprties;
} }
public List<MappedProperty> getMappedProperties() { public Map<String, Mapping> getMappings() {
return mappedProperties; return mappings;
}
public void setMappings(Map<String, Mapping> mappings) {
this.mappings = mappings;
} }
public boolean reverses(Method method) { public boolean reverses(Method method) {
@ -138,6 +141,10 @@ public class Method {
equals( targetType, method.getSourceType() ); equals( targetType, method.getSourceType() );
} }
public boolean isIterableMapping() {
return sourceType.isIterableType() && targetType.isIterableType();
}
private boolean equals(Object o1, Object o2) { private boolean equals(Object o1, Object o2) {
return ( o1 == null && o2 == null ) || ( o1 != null ) && o1.equals( o2 ); return ( o1 == null && o2 == null ) || ( o1 != null ) && o1.equals( o2 );
} }

View File

@ -88,30 +88,6 @@ public class Executables {
throw new IllegalArgumentException( "Executable " + getterOrSetterMethod + " is not getter or setter method." ); throw new IllegalArgumentException( "Executable " + getterOrSetterMethod + " is not getter or setter method." );
} }
/**
* Returns that setter or getter from the given list of executables which
* corresponds to the given getter or setter method.
*
* @param getterOrSetter The getter or setter method of interest.
* @param elements A list of executables to retrieve the corresponding accessor
* from.
*
* @return The setter corresponding to the given getter or the getter
* corresponding to the given getter
*/
public static ExecutableElement getCorrespondingPropertyAccessor(ExecutableElement getterOrSetter,
List<ExecutableElement> elements) {
String propertyName = getPropertyName( getterOrSetter );
for ( ExecutableElement method : elements ) {
if ( getPropertyName( method ).equals( propertyName ) ) {
return method;
}
}
return null;
}
public static Set<String> getPropertyNames(List<ExecutableElement> propertyAccessors) { public static Set<String> getPropertyNames(List<ExecutableElement> propertyAccessors) {
Set<String> propertyNames = new HashSet<String>(); Set<String> propertyNames = new HashSet<String>();

View File

@ -1,25 +0,0 @@
<#--
Copyright 2012-2013 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.
-->
<@includeModel object=mappingMethod/>
<#if reverseMappingMethod??>
<@includeModel object=reverseMappingMethod/>
</#if>

View File

@ -34,7 +34,7 @@ public class ${implementationName} implements ${interfaceName} {
private final ${mapperType.name} ${mapperType.name?uncap_first} = new ${mapperType.name}(); private final ${mapperType.name} ${mapperType.name?uncap_first} = new ${mapperType.name}();
</#list> </#list>
<#list beanMappings as beanMapping> <#list mappingMethods as mappingMethod>
<@includeModel object=beanMapping/> <@includeModel object=mappingMethod/>
</#list> </#list>
} }