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.ReportingPolicy;
|
||||||
import org.mapstruct.ap.model.SimpleMappingMethod;
|
import org.mapstruct.ap.model.SimpleMappingMethod;
|
||||||
import org.mapstruct.ap.model.Type;
|
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.Mapping;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.model.source.Parameter;
|
import org.mapstruct.ap.model.source.Parameter;
|
||||||
@ -224,43 +223,45 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>();
|
List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>();
|
||||||
Set<String> mappedTargetProperties = new HashSet<String>();
|
Set<String> mappedTargetProperties = new HashSet<String>();
|
||||||
|
|
||||||
List<MappedProperty> mappedProperties = retrieveMappedProperties( method );
|
Map<String, Mapping> mappings = method.getMappings();
|
||||||
|
|
||||||
for ( MappedProperty property : mappedProperties ) {
|
TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getExecutable().getReturnType() );
|
||||||
mappedTargetProperties.add( property.getTargetName() );
|
TypeElement parameterElement = (TypeElement) typeUtils.asElement(
|
||||||
|
method.getExecutable()
|
||||||
|
.getParameters()
|
||||||
|
.get( 0 )
|
||||||
|
.asType()
|
||||||
|
);
|
||||||
|
|
||||||
MappingMethodReference propertyMappingMethod = getMappingMethodReference(
|
List<ExecutableElement> sourceGetters = Filters.getterMethodsIn(
|
||||||
methods,
|
elementUtils.getAllMembers( parameterElement )
|
||||||
property.getSourceType(),
|
);
|
||||||
property.getTargetType()
|
List<ExecutableElement> targetSetters = Filters.setterMethodsIn(
|
||||||
);
|
elementUtils.getAllMembers( returnTypeElement )
|
||||||
Conversion conversion = conversions.getConversion(
|
);
|
||||||
property.getSourceType(),
|
|
||||||
property.getTargetType()
|
|
||||||
);
|
|
||||||
|
|
||||||
reportErrorIfPropertyCanNotBeMapped(
|
reportErrorIfMappedPropertiesDontExist( method );
|
||||||
method,
|
|
||||||
property,
|
|
||||||
propertyMappingMethod,
|
|
||||||
conversion
|
|
||||||
);
|
|
||||||
|
|
||||||
propertyMappings.add(
|
for ( ExecutableElement getterMethod : sourceGetters ) {
|
||||||
new PropertyMapping(
|
String sourcePropertyName = Executables.getPropertyName( getterMethod );
|
||||||
method.getParameterName(),
|
Mapping mapping = mappings.get( sourcePropertyName );
|
||||||
Introspector.decapitalize( method.getTargetType().getName() ),
|
|
||||||
property.getSourceReadAccessorName(),
|
for ( ExecutableElement setterMethod : targetSetters ) {
|
||||||
property.getSourceType(),
|
String targetPropertyName = Executables.getPropertyName( setterMethod );
|
||||||
property.getTargetWriteAccessorName(),
|
|
||||||
property.getTargetType(),
|
if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) {
|
||||||
propertyMappingMethod,
|
PropertyMapping property = getPropertyMapping(
|
||||||
conversion != null ? conversion.to(
|
methods,
|
||||||
method.getParameterName() + "." + property.getSourceReadAccessorName() + "()",
|
method,
|
||||||
property.getTargetType()
|
getterMethod,
|
||||||
) : null
|
setterMethod
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
propertyMappings.add( property );
|
||||||
|
|
||||||
|
mappedTargetProperties.add( targetPropertyName );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reportErrorForUnmappedTargetPropertiesIfRequired(
|
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) {
|
private MappingMethod getIterableMappingMethod(List<Method> methods, Method method) {
|
||||||
String toConversionString = getIterableConversionString(
|
String toConversionString = getIterableConversionString(
|
||||||
conversions,
|
conversions,
|
||||||
@ -319,17 +355,15 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportErrorIfPropertyCanNotBeMapped(Method method, MappedProperty property,
|
private void reportErrorIfPropertyCanNotBeMapped(Method method, PropertyMapping property) {
|
||||||
MappingMethodReference propertyMappingMethod,
|
|
||||||
Conversion conversion) {
|
|
||||||
if ( property.getSourceType().equals( property.getTargetType() ) ) {
|
if ( property.getSourceType().equals( property.getTargetType() ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//no mapping method nor conversion nor collection with default implementation
|
//no mapping method nor conversion nor collection with default implementation
|
||||||
if ( !(
|
if ( !(
|
||||||
propertyMappingMethod != null ||
|
property.getMappingMethod() != null ||
|
||||||
conversion != null ||
|
property.getConversion() != null ||
|
||||||
( property.getTargetType().isCollectionType() && property.getTargetType()
|
( property.getTargetType().isCollectionType() && property.getTargetType()
|
||||||
.getCollectionImplementationType() != null ) ) ) {
|
.getCollectionImplementationType() != null ) ) ) {
|
||||||
|
|
||||||
@ -510,62 +544,6 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
return methods;
|
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) {
|
private void reportErrorIfMappedPropertiesDontExist(Method method) {
|
||||||
for ( Mapping mappedProperty : method.getMappings().values() ) {
|
for ( Mapping mappedProperty : method.getMappings().values() ) {
|
||||||
if ( !method.getSourceProperties().contains( mappedProperty.getSourceName() ) ) {
|
if ( !method.getSourceProperties().contains( mappedProperty.getSourceName() ) ) {
|
||||||
|
@ -30,23 +30,32 @@ public class PropertyMapping extends AbstractModelElement {
|
|||||||
|
|
||||||
private final String sourceBeanName;
|
private final String sourceBeanName;
|
||||||
private final String targetBeanName;
|
private final String targetBeanName;
|
||||||
|
|
||||||
|
private final String sourceName;
|
||||||
private final String sourceAccessorName;
|
private final String sourceAccessorName;
|
||||||
private final Type sourceType;
|
private final Type sourceType;
|
||||||
|
|
||||||
|
private final String targetName;
|
||||||
private final String targetAccessorName;
|
private final String targetAccessorName;
|
||||||
private final Type targetType;
|
private final Type targetType;
|
||||||
|
|
||||||
private final MappingMethodReference mappingMethod;
|
private final MappingMethodReference mappingMethod;
|
||||||
private final String conversion;
|
private final String conversion;
|
||||||
|
|
||||||
public PropertyMapping(String sourceBeanName, String targetBeanName, String sourceAccessorName, Type sourceType,
|
public PropertyMapping(String sourceBeanName, String targetBeanName, String sourceName, String sourceAccessorName,
|
||||||
String targetAccessorName, Type targetType, MappingMethodReference mappingMethod,
|
Type sourceType, String targetName, String targetAccessorName, Type targetType,
|
||||||
String conversion) {
|
MappingMethodReference mappingMethod, String conversion) {
|
||||||
this.sourceBeanName = sourceBeanName;
|
this.sourceBeanName = sourceBeanName;
|
||||||
this.targetBeanName = targetBeanName;
|
this.targetBeanName = targetBeanName;
|
||||||
|
|
||||||
|
this.sourceName = sourceName;
|
||||||
this.sourceAccessorName = sourceAccessorName;
|
this.sourceAccessorName = sourceAccessorName;
|
||||||
this.sourceType = sourceType;
|
this.sourceType = sourceType;
|
||||||
|
|
||||||
|
this.targetName = targetName;
|
||||||
this.targetAccessorName = targetAccessorName;
|
this.targetAccessorName = targetAccessorName;
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
|
|
||||||
this.mappingMethod = mappingMethod;
|
this.mappingMethod = mappingMethod;
|
||||||
this.conversion = conversion;
|
this.conversion = conversion;
|
||||||
}
|
}
|
||||||
@ -59,6 +68,10 @@ public class PropertyMapping extends AbstractModelElement {
|
|||||||
return targetBeanName;
|
return targetBeanName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSourceName() {
|
||||||
|
return sourceName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSourceAccessorName() {
|
public String getSourceAccessorName() {
|
||||||
return sourceAccessorName;
|
return sourceAccessorName;
|
||||||
}
|
}
|
||||||
@ -67,6 +80,10 @@ public class PropertyMapping extends AbstractModelElement {
|
|||||||
return sourceType;
|
return sourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTargetName() {
|
||||||
|
return targetName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTargetAccessorName() {
|
public String getTargetAccessorName() {
|
||||||
return targetAccessorName;
|
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