mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#32 Removing MappedProperty, creating PropertyMappings directly
This commit is contained in:
parent
cd0306683f
commit
cadc20f7b3
@ -54,7 +54,6 @@ import org.mapstruct.ap.model.PropertyMapping;
|
||||
import org.mapstruct.ap.model.ReportingPolicy;
|
||||
import org.mapstruct.ap.model.SimpleMappingMethod;
|
||||
import org.mapstruct.ap.model.Type;
|
||||
import org.mapstruct.ap.model.source.MappedProperty;
|
||||
import org.mapstruct.ap.model.source.Mapping;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
import org.mapstruct.ap.model.source.Parameter;
|
||||
@ -224,43 +223,45 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>();
|
||||
Set<String> mappedTargetProperties = new HashSet<String>();
|
||||
|
||||
List<MappedProperty> mappedProperties = retrieveMappedProperties( method );
|
||||
Map<String, Mapping> mappings = method.getMappings();
|
||||
|
||||
for ( MappedProperty property : mappedProperties ) {
|
||||
mappedTargetProperties.add( property.getTargetName() );
|
||||
TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getExecutable().getReturnType() );
|
||||
TypeElement parameterElement = (TypeElement) typeUtils.asElement(
|
||||
method.getExecutable()
|
||||
.getParameters()
|
||||
.get( 0 )
|
||||
.asType()
|
||||
);
|
||||
|
||||
MappingMethodReference propertyMappingMethod = getMappingMethodReference(
|
||||
methods,
|
||||
property.getSourceType(),
|
||||
property.getTargetType()
|
||||
);
|
||||
Conversion conversion = conversions.getConversion(
|
||||
property.getSourceType(),
|
||||
property.getTargetType()
|
||||
);
|
||||
List<ExecutableElement> sourceGetters = Filters.getterMethodsIn(
|
||||
elementUtils.getAllMembers( parameterElement )
|
||||
);
|
||||
List<ExecutableElement> targetSetters = Filters.setterMethodsIn(
|
||||
elementUtils.getAllMembers( returnTypeElement )
|
||||
);
|
||||
|
||||
reportErrorIfPropertyCanNotBeMapped(
|
||||
method,
|
||||
property,
|
||||
propertyMappingMethod,
|
||||
conversion
|
||||
);
|
||||
reportErrorIfMappedPropertiesDontExist( method );
|
||||
|
||||
propertyMappings.add(
|
||||
new PropertyMapping(
|
||||
method.getParameterName(),
|
||||
Introspector.decapitalize( method.getTargetType().getName() ),
|
||||
property.getSourceReadAccessorName(),
|
||||
property.getSourceType(),
|
||||
property.getTargetWriteAccessorName(),
|
||||
property.getTargetType(),
|
||||
propertyMappingMethod,
|
||||
conversion != null ? conversion.to(
|
||||
method.getParameterName() + "." + property.getSourceReadAccessorName() + "()",
|
||||
property.getTargetType()
|
||||
) : null
|
||||
)
|
||||
);
|
||||
for ( ExecutableElement getterMethod : sourceGetters ) {
|
||||
String sourcePropertyName = Executables.getPropertyName( getterMethod );
|
||||
Mapping mapping = mappings.get( sourcePropertyName );
|
||||
|
||||
for ( ExecutableElement setterMethod : targetSetters ) {
|
||||
String targetPropertyName = Executables.getPropertyName( setterMethod );
|
||||
|
||||
if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) {
|
||||
PropertyMapping property = getPropertyMapping(
|
||||
methods,
|
||||
method,
|
||||
getterMethod,
|
||||
setterMethod
|
||||
);
|
||||
|
||||
propertyMappings.add( property );
|
||||
|
||||
mappedTargetProperties.add( targetPropertyName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reportErrorForUnmappedTargetPropertiesIfRequired(
|
||||
@ -278,6 +279,41 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
);
|
||||
}
|
||||
|
||||
private PropertyMapping getPropertyMapping(List<Method> methods, Method method, ExecutableElement getterMethod,
|
||||
ExecutableElement setterMethod) {
|
||||
Type sourceType = retrieveReturnType( getterMethod );
|
||||
Type targetType = retrieveParameter( setterMethod ).getType();
|
||||
|
||||
MappingMethodReference propertyMappingMethod = getMappingMethodReference( methods, sourceType, targetType );
|
||||
Conversion conversion = conversions.getConversion(
|
||||
sourceType,
|
||||
targetType
|
||||
);
|
||||
|
||||
PropertyMapping property = new PropertyMapping(
|
||||
method.getParameterName(),
|
||||
Introspector.decapitalize( method.getTargetType().getName() ),
|
||||
Executables.getPropertyName( getterMethod ),
|
||||
getterMethod.getSimpleName().toString(),
|
||||
sourceType,
|
||||
Executables.getPropertyName( setterMethod ),
|
||||
setterMethod.getSimpleName().toString(),
|
||||
targetType,
|
||||
propertyMappingMethod,
|
||||
conversion != null ? conversion.to(
|
||||
method.getParameterName() + "." + getterMethod.getSimpleName().toString() + "()",
|
||||
targetType
|
||||
) : null
|
||||
);
|
||||
|
||||
reportErrorIfPropertyCanNotBeMapped(
|
||||
method,
|
||||
property
|
||||
);
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
private MappingMethod getIterableMappingMethod(List<Method> methods, Method method) {
|
||||
String toConversionString = getIterableConversionString(
|
||||
conversions,
|
||||
@ -319,17 +355,15 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
}
|
||||
}
|
||||
|
||||
private void reportErrorIfPropertyCanNotBeMapped(Method method, MappedProperty property,
|
||||
MappingMethodReference propertyMappingMethod,
|
||||
Conversion conversion) {
|
||||
private void reportErrorIfPropertyCanNotBeMapped(Method method, PropertyMapping property) {
|
||||
if ( property.getSourceType().equals( property.getTargetType() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//no mapping method nor conversion nor collection with default implementation
|
||||
if ( !(
|
||||
propertyMappingMethod != null ||
|
||||
conversion != null ||
|
||||
property.getMappingMethod() != null ||
|
||||
property.getConversion() != null ||
|
||||
( property.getTargetType().isCollectionType() && property.getTargetType()
|
||||
.getCollectionImplementationType() != null ) ) ) {
|
||||
|
||||
@ -510,62 +544,6 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all properties of the parameter type of the given method which
|
||||
* are mapped to a corresponding property of the return type of the given
|
||||
* method.
|
||||
*
|
||||
* @param method The method of interest
|
||||
*
|
||||
* @return All mapped properties for the given method
|
||||
*/
|
||||
private List<MappedProperty> retrieveMappedProperties(Method method) {
|
||||
Map<String, Mapping> mappings = method.getMappings();
|
||||
|
||||
TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getExecutable().getReturnType() );
|
||||
TypeElement parameterElement = (TypeElement) typeUtils.asElement(
|
||||
method.getExecutable()
|
||||
.getParameters()
|
||||
.get( 0 )
|
||||
.asType()
|
||||
);
|
||||
|
||||
List<MappedProperty> properties = new ArrayList<MappedProperty>();
|
||||
|
||||
List<ExecutableElement> sourceGetters = Filters.getterMethodsIn(
|
||||
elementUtils.getAllMembers( parameterElement )
|
||||
);
|
||||
List<ExecutableElement> targetSetters = Filters.setterMethodsIn(
|
||||
elementUtils.getAllMembers( returnTypeElement )
|
||||
);
|
||||
|
||||
reportErrorIfMappedPropertiesDontExist( method );
|
||||
|
||||
for ( ExecutableElement getterMethod : sourceGetters ) {
|
||||
String sourcePropertyName = Executables.getPropertyName( getterMethod );
|
||||
Mapping mapping = mappings.get( sourcePropertyName );
|
||||
|
||||
for ( ExecutableElement setterMethod : targetSetters ) {
|
||||
String targetPropertyName = Executables.getPropertyName( setterMethod );
|
||||
|
||||
if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) {
|
||||
properties.add(
|
||||
new MappedProperty(
|
||||
sourcePropertyName,
|
||||
getterMethod.getSimpleName().toString(),
|
||||
retrieveReturnType( getterMethod ),
|
||||
mapping != null ? mapping.getTargetName() : targetPropertyName,
|
||||
setterMethod.getSimpleName().toString(),
|
||||
retrieveParameter( setterMethod ).getType()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private void reportErrorIfMappedPropertiesDontExist(Method method) {
|
||||
for ( Mapping mappedProperty : method.getMappings().values() ) {
|
||||
if ( !method.getSourceProperties().contains( mappedProperty.getSourceName() ) ) {
|
||||
|
@ -30,23 +30,32 @@ public class PropertyMapping extends AbstractModelElement {
|
||||
|
||||
private final String sourceBeanName;
|
||||
private final String targetBeanName;
|
||||
|
||||
private final String sourceName;
|
||||
private final String sourceAccessorName;
|
||||
private final Type sourceType;
|
||||
|
||||
private final String targetName;
|
||||
private final String targetAccessorName;
|
||||
private final Type targetType;
|
||||
|
||||
private final MappingMethodReference mappingMethod;
|
||||
private final String conversion;
|
||||
|
||||
public PropertyMapping(String sourceBeanName, String targetBeanName, String sourceAccessorName, Type sourceType,
|
||||
String targetAccessorName, Type targetType, MappingMethodReference mappingMethod,
|
||||
String conversion) {
|
||||
public PropertyMapping(String sourceBeanName, String targetBeanName, String sourceName, String sourceAccessorName,
|
||||
Type sourceType, String targetName, String targetAccessorName, Type targetType,
|
||||
MappingMethodReference mappingMethod, String conversion) {
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
this.targetBeanName = targetBeanName;
|
||||
|
||||
this.sourceName = sourceName;
|
||||
this.sourceAccessorName = sourceAccessorName;
|
||||
this.sourceType = sourceType;
|
||||
|
||||
this.targetName = targetName;
|
||||
this.targetAccessorName = targetAccessorName;
|
||||
this.targetType = targetType;
|
||||
|
||||
this.mappingMethod = mappingMethod;
|
||||
this.conversion = conversion;
|
||||
}
|
||||
@ -59,6 +68,10 @@ public class PropertyMapping extends AbstractModelElement {
|
||||
return targetBeanName;
|
||||
}
|
||||
|
||||
public String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public String getSourceAccessorName() {
|
||||
return sourceAccessorName;
|
||||
}
|
||||
@ -67,6 +80,10 @@ public class PropertyMapping extends AbstractModelElement {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public String getTargetName() {
|
||||
return targetName;
|
||||
}
|
||||
|
||||
public String getTargetAccessorName() {
|
||||
return targetAccessorName;
|
||||
}
|
||||
|
@ -1,76 +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.source;
|
||||
|
||||
import org.mapstruct.ap.model.Type;
|
||||
|
||||
/**
|
||||
* Represents a property mapped from source to target with the names of its
|
||||
* accessor methods.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class MappedProperty {
|
||||
|
||||
private final String sourceName;
|
||||
private final String sourceReadAccessorName;
|
||||
private final Type sourceType;
|
||||
private final String targetName;
|
||||
private final String targetWriteAccessorName;
|
||||
private final Type targetType;
|
||||
|
||||
public MappedProperty(String sourceName, String sourceReadAccessorName, Type sourceType, String targetName,
|
||||
String targetWriteAccessorName, Type targetType) {
|
||||
this.sourceName = sourceName;
|
||||
this.sourceReadAccessorName = sourceReadAccessorName;
|
||||
this.sourceType = sourceType;
|
||||
this.targetName = targetName;
|
||||
this.targetWriteAccessorName = targetWriteAccessorName;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
public String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public String getSourceReadAccessorName() {
|
||||
return sourceReadAccessorName;
|
||||
}
|
||||
|
||||
public Type getSourceType() {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public String getTargetName() {
|
||||
return targetName;
|
||||
}
|
||||
|
||||
public String getTargetWriteAccessorName() {
|
||||
return targetWriteAccessorName;
|
||||
}
|
||||
|
||||
public Type getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return sourceType + " " + sourceName + " <=> " + targetType + " " + targetName;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user