mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#160 Refactoring into targetReadAccessor and targetWriteAccessor and making them available to ftl templates
This commit is contained in:
parent
bcf28c1cc1
commit
776bc3d157
@ -90,7 +90,7 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
public Builder souceMethod(SourceMethod sourceMethod) {
|
||||
this.method = sourceMethod;
|
||||
CollectionMappingStrategyPrism cms = sourceMethod.getMapperConfiguration().getCollectionMappingStrategy();
|
||||
Map<String, ExecutableElement> accessors = method.getResultType().getTargetAccessors( cms );
|
||||
Map<String, ExecutableElement> accessors = method.getResultType().getPropertyWriteAccessors( cms );
|
||||
this.targetProperties = accessors.keySet();
|
||||
this.unprocessedTargetProperties = new HashMap<String, ExecutableElement>( accessors );
|
||||
for ( Parameter sourceParameter : method.getSourceParameters() ) {
|
||||
@ -237,8 +237,8 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
PropertyMapping propertyMapping = null;
|
||||
|
||||
// fetch the target property
|
||||
ExecutableElement targetProperty = unprocessedTargetProperties.get( mapping.getTargetName() );
|
||||
if ( targetProperty == null ) {
|
||||
ExecutableElement targetWriteAccessor = unprocessedTargetProperties.get( mapping.getTargetName() );
|
||||
if ( targetWriteAccessor == null ) {
|
||||
ctx.getMessager().printMessage(
|
||||
method.getExecutable(),
|
||||
mapping.getMirror(),
|
||||
@ -277,14 +277,15 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
SourceReference sourceRef = mapping.getSourceReference();
|
||||
if ( sourceRef.isValid() ) {
|
||||
|
||||
if ( targetProperty != null ) {
|
||||
if ( targetWriteAccessor != null ) {
|
||||
|
||||
// targetProperty == null can occur: we arrived here because we want as many errors
|
||||
// as possible before we stop analysing
|
||||
propertyMapping = new PropertyMappingBuilder()
|
||||
.mappingContext( ctx )
|
||||
.souceMethod( method )
|
||||
.targetAccessor( targetProperty )
|
||||
.targetWriteAccessor( targetWriteAccessor )
|
||||
.targetReadAccessor( getTargetPropertyReadAccessor( mapping.getTargetName() ) )
|
||||
.targetPropertyName( mapping.getTargetName() )
|
||||
.sourceReference( sourceRef )
|
||||
.qualifiers( mapping.getQualifiers() )
|
||||
@ -303,13 +304,14 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
}
|
||||
|
||||
// its a constant
|
||||
else if ( mapping.getConstant() != null && targetProperty != null ) {
|
||||
else if ( mapping.getConstant() != null && targetWriteAccessor != null ) {
|
||||
|
||||
propertyMapping = new ConstantMappingBuilder()
|
||||
.mappingContext( ctx )
|
||||
.sourceMethod( method )
|
||||
.constantExpression( "\"" + mapping.getConstant() + "\"" )
|
||||
.targetAccessor( targetProperty )
|
||||
.targetWriteAccessor( targetWriteAccessor )
|
||||
.targetReadAccessor( getTargetPropertyReadAccessor( mapping.getTargetName() ) )
|
||||
.targetPropertyName( mapping.getTargetName() )
|
||||
.dateFormat( mapping.getDateFormat() )
|
||||
.qualifiers( mapping.getQualifiers() )
|
||||
@ -321,14 +323,15 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
}
|
||||
|
||||
// its an expression
|
||||
else if ( mapping.getJavaExpression() != null && targetProperty != null ) {
|
||||
else if ( mapping.getJavaExpression() != null && targetWriteAccessor != null ) {
|
||||
|
||||
propertyMapping = new JavaExpressionMappingBuilder()
|
||||
.mappingContext( ctx )
|
||||
.souceMethod( method )
|
||||
.javaExpression( mapping.getJavaExpression() )
|
||||
.targetAccessor( targetProperty )
|
||||
.existingVariableNames( existingVariableNames )
|
||||
.targetWriteAccessor( targetWriteAccessor )
|
||||
.targetReadAccessor( targetWriteAccessor )
|
||||
.targetPropertyName( mapping.getTargetName() )
|
||||
.dependsOn( mapping.getDependsOn() )
|
||||
.build();
|
||||
@ -378,11 +381,13 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( ExecutableElement sourceAccessor : sourceParameter.getType().getGetters() ) {
|
||||
String sourcePropertyName = Executables.getPropertyName( sourceAccessor );
|
||||
Collection<ExecutableElement> sourceReadAccessors =
|
||||
sourceParameter.getType().getPropertyReadAccessors().values();
|
||||
for ( ExecutableElement sourceReadAccessor : sourceReadAccessors ) {
|
||||
String sourcePropertyName = Executables.getPropertyName( sourceReadAccessor );
|
||||
|
||||
if ( sourcePropertyName.equals( targetProperty.getKey() ) ) {
|
||||
candidates.add( sourceAccessor );
|
||||
candidates.add( sourceReadAccessor );
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,7 +406,8 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
newPropertyMapping = new PropertyMappingBuilder()
|
||||
.mappingContext( ctx )
|
||||
.souceMethod( method )
|
||||
.targetAccessor( targetProperty.getValue() )
|
||||
.targetWriteAccessor( targetProperty.getValue() )
|
||||
.targetReadAccessor( getTargetPropertyReadAccessor( targetProperty.getKey() ) )
|
||||
.targetPropertyName( targetProperty.getKey() )
|
||||
.sourceReference( sourceRef )
|
||||
.qualifiers( mapping != null ? mapping.getQualifiers() : null )
|
||||
@ -464,7 +470,8 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
PropertyMapping propertyMapping = new PropertyMappingBuilder()
|
||||
.mappingContext( ctx )
|
||||
.souceMethod( method )
|
||||
.targetAccessor( targetProperty.getValue() )
|
||||
.targetWriteAccessor( targetProperty.getValue() )
|
||||
.targetReadAccessor( getTargetPropertyReadAccessor( targetProperty.getKey() ) )
|
||||
.targetPropertyName( targetProperty.getKey() )
|
||||
.sourceReference( sourceRef )
|
||||
.qualifiers( mapping != null ? mapping.getQualifiers() : null )
|
||||
@ -510,6 +517,10 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
}
|
||||
}
|
||||
|
||||
private ExecutableElement getTargetPropertyReadAccessor( String propertyName ) {
|
||||
return method.getResultType().getPropertyReadAccessors().get( propertyName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective policy for reporting unmapped getReturnType properties. If explicitly set via
|
||||
* {@code Mapper}, this value will be returned. Otherwise the value from the corresponding processor option will
|
||||
|
@ -61,7 +61,8 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
private final String name;
|
||||
private final String sourceBeanName;
|
||||
private final String targetAccessorName;
|
||||
private final String targetWriteAccessorName;
|
||||
private final String targetReadAccessorName;
|
||||
private final Type targetType;
|
||||
private final Assignment assignment;
|
||||
private final List<String> dependsOn;
|
||||
@ -71,7 +72,8 @@ public class PropertyMapping extends ModelElement {
|
||||
// initial properties
|
||||
private MappingBuilderContext ctx;
|
||||
private SourceMethod method;
|
||||
private ExecutableElement targetAccessor;
|
||||
private ExecutableElement targetWriteAccessor;
|
||||
private ExecutableElement targetReadAccessor;
|
||||
private String targetPropertyName;
|
||||
private String dateFormat;
|
||||
private List<TypeMirror> qualifiers;
|
||||
@ -90,8 +92,13 @@ public class PropertyMapping extends ModelElement {
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyMappingBuilder targetAccessor(ExecutableElement targetAccessor) {
|
||||
this.targetAccessor = targetAccessor;
|
||||
public PropertyMappingBuilder targetReadAccessor(ExecutableElement targetReadAccessor) {
|
||||
this.targetReadAccessor = targetReadAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyMappingBuilder targetWriteAccessor(ExecutableElement targetWriteAccessor) {
|
||||
this.targetWriteAccessor = targetWriteAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -130,8 +137,7 @@ public class PropertyMapping extends ModelElement {
|
||||
return this;
|
||||
}
|
||||
|
||||
private enum TargetAccessorType {
|
||||
|
||||
private enum TargetWriteAccessorType {
|
||||
GETTER,
|
||||
SETTER,
|
||||
ADDER
|
||||
@ -140,18 +146,18 @@ public class PropertyMapping extends ModelElement {
|
||||
public PropertyMapping build() {
|
||||
|
||||
// handle target
|
||||
TargetAccessorType targetAccessorType = getTargetAcccessorType();
|
||||
TargetWriteAccessorType targetAccessorType = getTargetAcccessorType();
|
||||
Type targetType = getTargetType( targetAccessorType );
|
||||
|
||||
// handle source
|
||||
String sourceElement = getSourceElement();
|
||||
Type sourceType = getSourceType();
|
||||
String sourceRefStr;
|
||||
if ( targetAccessorType == TargetAccessorType.ADDER && sourceType.isCollectionType() ) {
|
||||
if ( targetAccessorType == TargetWriteAccessorType.ADDER && sourceType.isCollectionType() ) {
|
||||
// handle adder, if source is collection then use iterator element type as source type.
|
||||
// sourceRef becomes a local variable in the itereation.
|
||||
sourceType = sourceType.getTypeParameters().get( 0 );
|
||||
sourceRefStr = Executables.getElementNameForAdder( targetAccessor );
|
||||
sourceRefStr = Executables.getElementNameForAdder( targetWriteAccessor );
|
||||
}
|
||||
else {
|
||||
sourceRefStr = getSourceRef();
|
||||
@ -208,19 +214,21 @@ public class PropertyMapping extends ModelElement {
|
||||
return new PropertyMapping(
|
||||
targetPropertyName,
|
||||
sourceReference.getParameter().getName(),
|
||||
targetAccessor.getSimpleName().toString(),
|
||||
targetWriteAccessor.getSimpleName().toString(),
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
);
|
||||
}
|
||||
|
||||
private Assignment assignObject(Type sourceType, Type targetType, TargetAccessorType targetAccessorType,
|
||||
private Assignment assignObject(Type sourceType, Type targetType, TargetWriteAccessorType targetAccessorType,
|
||||
Assignment rhs) {
|
||||
|
||||
Assignment result = rhs;
|
||||
|
||||
if ( targetAccessorType == TargetAccessorType.SETTER ) {
|
||||
if ( targetAccessorType == TargetWriteAccessorType.SETTER ) {
|
||||
|
||||
result = new SetterWrapper( result, method.getThrownTypes() );
|
||||
if ( !sourceType.isPrimitive()
|
||||
&& !sourceReference.getPropertyEntries().isEmpty() /* parameter null taken care of by beanmapper */
|
||||
@ -252,12 +260,14 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
}
|
||||
|
||||
private Assignment assignCollection(Type targetType, TargetAccessorType targetAccessorType, Assignment rhs) {
|
||||
private Assignment assignCollection(Type targetType,
|
||||
TargetWriteAccessorType targetAccessorType,
|
||||
Assignment rhs) {
|
||||
|
||||
Assignment result = rhs;
|
||||
|
||||
// wrap the setter in the collection / map initializers
|
||||
if ( targetAccessorType == TargetAccessorType.SETTER ) {
|
||||
if ( targetAccessorType == TargetWriteAccessorType.SETTER ) {
|
||||
|
||||
// wrap the assignment in a new Map or Collection implementation if this is not done in a
|
||||
// mapping method. Note, typeconversons do not apply to collections or maps
|
||||
@ -273,7 +283,7 @@ public class PropertyMapping extends ModelElement {
|
||||
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
||||
result = new SetterWrapperForCollectionsAndMaps(
|
||||
result,
|
||||
targetAccessor.getSimpleName().toString(),
|
||||
targetWriteAccessor.getSimpleName().toString(),
|
||||
newCollectionOrMap
|
||||
);
|
||||
}
|
||||
@ -379,26 +389,26 @@ public class PropertyMapping extends ModelElement {
|
||||
}
|
||||
}
|
||||
|
||||
private TargetAccessorType getTargetAcccessorType() {
|
||||
if ( Executables.isSetterMethod( targetAccessor ) ) {
|
||||
return TargetAccessorType.SETTER;
|
||||
private TargetWriteAccessorType getTargetAcccessorType() {
|
||||
if ( Executables.isSetterMethod( targetWriteAccessor ) ) {
|
||||
return TargetWriteAccessorType.SETTER;
|
||||
}
|
||||
else if ( Executables.isAdderMethod( targetAccessor ) ) {
|
||||
return TargetAccessorType.ADDER;
|
||||
else if ( Executables.isAdderMethod( targetWriteAccessor ) ) {
|
||||
return TargetWriteAccessorType.ADDER;
|
||||
}
|
||||
else {
|
||||
return TargetAccessorType.GETTER;
|
||||
return TargetWriteAccessorType.GETTER;
|
||||
}
|
||||
}
|
||||
|
||||
private Type getTargetType(TargetAccessorType targetAccessorType) {
|
||||
private Type getTargetType(TargetWriteAccessorType targetAccessorType) {
|
||||
switch ( targetAccessorType ) {
|
||||
case ADDER:
|
||||
case SETTER:
|
||||
return ctx.getTypeFactory().getSingleParameter( targetAccessor ).getType();
|
||||
return ctx.getTypeFactory().getSingleParameter( targetWriteAccessor ).getType();
|
||||
case GETTER:
|
||||
default:
|
||||
return ctx.getTypeFactory().getReturnType( targetAccessor );
|
||||
return ctx.getTypeFactory().getReturnType( targetWriteAccessor );
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,8 +487,9 @@ public class PropertyMapping extends ModelElement {
|
||||
private MappingBuilderContext ctx;
|
||||
private SourceMethod method;
|
||||
private String constantExpression;
|
||||
private ExecutableElement targetAccessor;
|
||||
private String targetPropertyName;
|
||||
private ExecutableElement targetWriteAccessor;
|
||||
private ExecutableElement targetReadAccessor;
|
||||
private String dateFormat;
|
||||
private List<TypeMirror> qualifiers;
|
||||
private TypeMirror resultType;
|
||||
@ -500,8 +511,13 @@ public class PropertyMapping extends ModelElement {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstantMappingBuilder targetAccessor(ExecutableElement targetAccessor) {
|
||||
this.targetAccessor = targetAccessor;
|
||||
public ConstantMappingBuilder targetWriteAccessor(ExecutableElement targetAccessor) {
|
||||
this.targetWriteAccessor = targetAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstantMappingBuilder targetReadAccessor(ExecutableElement targetReadAccessor) {
|
||||
this.targetReadAccessor = targetReadAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -543,11 +559,11 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
// target
|
||||
Type targetType;
|
||||
if ( Executables.isSetterMethod( targetAccessor ) ) {
|
||||
targetType = ctx.getTypeFactory().getSingleParameter( targetAccessor ).getType();
|
||||
if ( Executables.isSetterMethod( targetWriteAccessor ) ) {
|
||||
targetType = ctx.getTypeFactory().getSingleParameter( targetWriteAccessor ).getType();
|
||||
}
|
||||
else {
|
||||
targetType = ctx.getTypeFactory().getReturnType( targetAccessor );
|
||||
targetType = ctx.getTypeFactory().getReturnType( targetWriteAccessor );
|
||||
}
|
||||
|
||||
Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
|
||||
@ -564,7 +580,7 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
if ( assignment != null ) {
|
||||
|
||||
if ( Executables.isSetterMethod( targetAccessor ) ) {
|
||||
if ( Executables.isSetterMethod( targetWriteAccessor ) ) {
|
||||
// target accessor is setter, so decorate assignment as setter
|
||||
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
||||
}
|
||||
@ -591,7 +607,8 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
return new PropertyMapping(
|
||||
targetPropertyName,
|
||||
targetAccessor.getSimpleName().toString(),
|
||||
targetWriteAccessor.getSimpleName().toString(),
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
@ -604,10 +621,11 @@ public class PropertyMapping extends ModelElement {
|
||||
private MappingBuilderContext ctx;
|
||||
private SourceMethod method;
|
||||
private String javaExpression;
|
||||
private ExecutableElement targetAccessor;
|
||||
private Collection<String> existingVariableNames;
|
||||
private String targetPropertyName;
|
||||
private List<String> dependsOn;
|
||||
private ExecutableElement targetWriteAccessor;
|
||||
private ExecutableElement targetReadAccessor;
|
||||
|
||||
public JavaExpressionMappingBuilder mappingContext(MappingBuilderContext mappingContext) {
|
||||
this.ctx = mappingContext;
|
||||
@ -624,8 +642,13 @@ public class PropertyMapping extends ModelElement {
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaExpressionMappingBuilder targetAccessor(ExecutableElement targetAccessor) {
|
||||
this.targetAccessor = targetAccessor;
|
||||
public JavaExpressionMappingBuilder targetWriteAccessor(ExecutableElement targetWriteAccessor) {
|
||||
this.targetWriteAccessor = targetWriteAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaExpressionMappingBuilder targetReadAccessor(ExecutableElement targetReadAccessor) {
|
||||
this.targetReadAccessor = targetReadAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -649,13 +672,13 @@ public class PropertyMapping extends ModelElement {
|
||||
Assignment assignment = AssignmentFactory.createDirect( javaExpression );
|
||||
|
||||
Type targetType;
|
||||
if ( Executables.isSetterMethod( targetAccessor ) ) {
|
||||
if ( Executables.isSetterMethod( targetWriteAccessor ) ) {
|
||||
// setter, so wrap in setter
|
||||
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
||||
targetType = ctx.getTypeFactory().getSingleParameter( targetAccessor ).getType();
|
||||
targetType = ctx.getTypeFactory().getSingleParameter( targetWriteAccessor ).getType();
|
||||
}
|
||||
else {
|
||||
targetType = ctx.getTypeFactory().getReturnType( targetAccessor );
|
||||
targetType = ctx.getTypeFactory().getReturnType( targetWriteAccessor );
|
||||
// target accessor is getter, so wrap the setter in getter map/ collection handling
|
||||
assignment = new GetterWrapperForCollectionsAndMaps(
|
||||
assignment,
|
||||
@ -667,7 +690,8 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
return new PropertyMapping(
|
||||
targetPropertyName,
|
||||
targetAccessor.getSimpleName().toString(),
|
||||
targetWriteAccessor.getSimpleName().toString(),
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
@ -677,16 +701,18 @@ public class PropertyMapping extends ModelElement {
|
||||
}
|
||||
|
||||
// Constructor for creating mappings of constant expressions.
|
||||
private PropertyMapping(String name, String targetAccessorName, Type targetType, Assignment propertyAssignment,
|
||||
List<String> dependsOn) {
|
||||
this( name, null, targetAccessorName, targetType, propertyAssignment, dependsOn );
|
||||
private PropertyMapping(String name, String targetWriteAccessorName, String targetReadAccessorName, Type targetType,
|
||||
Assignment propertyAssignment, List<String> dependsOn) {
|
||||
this( name, null, targetWriteAccessorName, targetReadAccessorName, targetType, propertyAssignment, dependsOn );
|
||||
}
|
||||
|
||||
private PropertyMapping(String name, String sourceBeanName, String targetAccessorName, Type targetType,
|
||||
Assignment assignment, List<String> dependsOn) {
|
||||
private PropertyMapping(String name, String sourceBeanName, String targetWriteAccessorName,
|
||||
String targetReadAccessorName, Type targetType, Assignment assignment,
|
||||
List<String> dependsOn) {
|
||||
this.name = name;
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
this.targetAccessorName = targetAccessorName;
|
||||
this.targetWriteAccessorName = targetWriteAccessorName;
|
||||
this.targetReadAccessorName = targetReadAccessorName;
|
||||
this.targetType = targetType;
|
||||
this.assignment = assignment;
|
||||
this.dependsOn = dependsOn != null ? dependsOn : Collections.<String>emptyList();
|
||||
@ -703,8 +729,12 @@ public class PropertyMapping extends ModelElement {
|
||||
return sourceBeanName;
|
||||
}
|
||||
|
||||
public String getTargetAccessorName() {
|
||||
return targetAccessorName;
|
||||
public String getTargetWriteAccessorName() {
|
||||
return targetWriteAccessorName;
|
||||
}
|
||||
|
||||
public String getTargetReadAccessorName() {
|
||||
return targetReadAccessorName;
|
||||
}
|
||||
|
||||
public Type getTargetType() {
|
||||
@ -728,6 +758,8 @@ public class PropertyMapping extends ModelElement {
|
||||
public String toString() {
|
||||
return "PropertyMapping {"
|
||||
+ "\n name='" + name + "\',"
|
||||
+ "\n targetWriteAccessorName='" + targetWriteAccessorName + "\',"
|
||||
+ "\n targetReadAccessorName='" + targetReadAccessorName + "\',"
|
||||
+ "\n targetType=" + targetType + ","
|
||||
+ "\n propertyAssignment=" + assignment + ","
|
||||
+ "\n dependsOn=" + dependsOn
|
||||
|
@ -92,13 +92,13 @@ public class TypeConversion extends ModelElement implements Assignment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssignmentType getType() {
|
||||
public Assignment.AssignmentType getType() {
|
||||
|
||||
switch ( assignment.getType() ) {
|
||||
case DIRECT:
|
||||
return AssignmentType.TYPE_CONVERTED;
|
||||
return Assignment.AssignmentType.TYPE_CONVERTED;
|
||||
case MAPPED:
|
||||
return AssignmentType.MAPPED_TYPE_CONVERTED;
|
||||
return Assignment.AssignmentType.MAPPED_TYPE_CONVERTED;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -81,8 +82,9 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
|
||||
private final List<String> enumConstants;
|
||||
|
||||
private Map<String, ExecutableElement> getters = null;
|
||||
|
||||
private List<ExecutableElement> allExecutables = null;
|
||||
private List<ExecutableElement> getters = null;
|
||||
private List<ExecutableElement> setters = null;
|
||||
private List<ExecutableElement> adders = null;
|
||||
private List<ExecutableElement> alternativeTargetAccessors = null;
|
||||
@ -312,32 +314,38 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
}
|
||||
|
||||
/**
|
||||
* getGetters
|
||||
* getPropertyReadAccessors
|
||||
*
|
||||
* @return an unmodifiable list of all getters (including 'is' for booleans).
|
||||
* @return an unmodifiable map of all read accessors (including 'is' for booleans), indexed by property name
|
||||
*/
|
||||
public List<ExecutableElement> getGetters() {
|
||||
public Map<String, ExecutableElement> getPropertyReadAccessors() {
|
||||
if ( getters == null ) {
|
||||
getters = Collections.unmodifiableList( Filters.getterMethodsIn( getAllExecutables() ) );
|
||||
List<ExecutableElement> getterList = Filters.getterMethodsIn( getAllExecutables() );
|
||||
Map<String, ExecutableElement> modifiableGetters = new LinkedHashMap<String, ExecutableElement>();
|
||||
for (ExecutableElement getter : getterList) {
|
||||
modifiableGetters.put( Executables.getPropertyName( getter ), getter );
|
||||
}
|
||||
getters = Collections.unmodifiableMap( modifiableGetters );
|
||||
}
|
||||
return getters;
|
||||
}
|
||||
|
||||
/**
|
||||
* getTargetAccessors returns a list of the target accessors according to the CollectionMappingStrategy. These
|
||||
* accessors include:
|
||||
* getPropertyWriteAccessors returns a map of the write accessors according to the CollectionMappingStrategy.
|
||||
*
|
||||
* These accessors include:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>setters, the obvious candidate :-), {@link #getSetters() }</li>
|
||||
* <li>getters, for collections that do not have a setter, e.g. for JAXB generated collection attributes
|
||||
* {@link #getGetters() }</li>
|
||||
* {@link #getPropertyReadAccessors() }</li>
|
||||
* <li>adders, typically for from table generated entities, {@link #getAdders() }</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* @param cmStrategy
|
||||
* @return an unmodifiable list of all getters (including 'is' for booleans).
|
||||
* @return an unmodifiable map of all write accessors indexed by property name
|
||||
*/
|
||||
public Map<String, ExecutableElement> getTargetAccessors( CollectionMappingStrategyPrism cmStrategy ) {
|
||||
public Map<String, ExecutableElement> getPropertyWriteAccessors( CollectionMappingStrategyPrism cmStrategy ) {
|
||||
|
||||
// collect all candidate target accessors
|
||||
List<ExecutableElement> candidates = new ArrayList<ExecutableElement>();
|
||||
@ -482,11 +490,12 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
* @return an unmodifiable list of alternative target accessors.
|
||||
*/
|
||||
private List<ExecutableElement> getAlternativeTargetAccessors() {
|
||||
|
||||
if ( alternativeTargetAccessors == null ) {
|
||||
|
||||
List<ExecutableElement> result = new ArrayList<ExecutableElement>();
|
||||
List<ExecutableElement> setterMethods = getSetters();
|
||||
List<ExecutableElement> getterMethods = getGetters();
|
||||
List<ExecutableElement> getterMethods = new ArrayList( getPropertyReadAccessors().values() );
|
||||
|
||||
// there could be a getter method for a list/map that is not present as setter.
|
||||
// a getter could substitute the setter in that case and act as setter.
|
||||
|
@ -266,7 +266,7 @@ public class Mapping {
|
||||
|
||||
private boolean hasPropertyInReverseMethod(String name, SourceMethod method) {
|
||||
CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy();
|
||||
return method.getResultType().getTargetAccessors( cms ).containsKey( name );
|
||||
return method.getResultType().getPropertyWriteAccessors( cms ).containsKey( name );
|
||||
}
|
||||
|
||||
public Mapping reverse(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory) {
|
||||
|
@ -21,13 +21,13 @@ package org.mapstruct.ap.model.source;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
|
||||
import org.mapstruct.ap.model.common.Parameter;
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.common.TypeFactory;
|
||||
import org.mapstruct.ap.util.Executables;
|
||||
import org.mapstruct.ap.util.FormattingMessager;
|
||||
import org.mapstruct.ap.util.Message;
|
||||
import org.mapstruct.ap.util.Strings;
|
||||
@ -173,11 +173,11 @@ public class SourceReference {
|
||||
Type newType = type;
|
||||
for ( String entryName : entryNames ) {
|
||||
boolean matchFound = false;
|
||||
List<ExecutableElement> getters = newType.getGetters();
|
||||
for ( ExecutableElement getter : getters ) {
|
||||
if ( Executables.getPropertyName( getter ).equals( entryName ) ) {
|
||||
newType = typeFactory.getType( getter.getReturnType() );
|
||||
sourceEntries.add( new PropertyEntry( entryName, getter, newType ) );
|
||||
Map<String, ExecutableElement> sourceReadAccessors = newType.getPropertyReadAccessors();
|
||||
for ( Map.Entry<String, ExecutableElement> getter : sourceReadAccessors.entrySet() ) {
|
||||
if ( getter.getKey().equals( entryName ) ) {
|
||||
newType = typeFactory.getType( getter.getValue().getReturnType() );
|
||||
sourceEntries.add( new PropertyEntry( entryName, getter.getValue(), newType ) );
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@
|
||||
break;
|
||||
}
|
||||
</#if>
|
||||
<@includeModel object=elementAssignment targetAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>
|
||||
<@includeModel object=elementAssignment targetWriteAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>
|
||||
${index1Name}++;
|
||||
}
|
||||
<#else>
|
||||
@ -69,7 +69,7 @@
|
||||
</#if>
|
||||
|
||||
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
||||
<@includeModel object=elementAssignment targetBeanName=resultName targetAccessorName="add" targetType=resultElementType/>
|
||||
<@includeModel object=elementAssignment targetBeanName=resultName targetWriteAccessorName="add" targetType=resultElementType/>
|
||||
}
|
||||
</#if>
|
||||
|
||||
|
@ -43,11 +43,11 @@
|
||||
for ( java.util.Map.Entry<<#list sourceParameter.type.typeParameters as typeParameter><@includeModel object=typeParameter /><#if typeParameter_has_next>, </#if></#list>> ${entryVariableName} : ${sourceParameter.name}.entrySet() ) {
|
||||
<#-- key -->
|
||||
<@includeModel object=keyAssignment
|
||||
targetAccessorName=keyVariableName
|
||||
targetWriteAccessorName=keyVariableName
|
||||
targetType=resultType.typeParameters[0]/>
|
||||
<#-- value -->
|
||||
<@includeModel object=valueAssignment
|
||||
targetAccessorName=valueVariableName
|
||||
targetWriteAccessorName=valueVariableName
|
||||
targetType=resultType.typeParameters[1]/>
|
||||
${resultName}.put( ${keyVariableName}, ${valueVariableName} );
|
||||
}
|
||||
|
@ -26,12 +26,23 @@
|
||||
<#if param.targetType>
|
||||
<#-- a class is passed on for casting, see @TargetType -->
|
||||
<@includeModel object=ext.targetType raw=true/>.class
|
||||
<#elseif param.mappingTarget>
|
||||
${ext.targetBeanName}.${ext.targetReadAccessorName}()
|
||||
<#else>
|
||||
<@includeModel object=assignment targetType=singleSourceParameterType raw=ext.raw/>
|
||||
<@_assignment/>
|
||||
</#if>
|
||||
<#if param_has_next>, </#if>
|
||||
</#list>
|
||||
<#-- context parameter, e.g. for builtin methods concerning date conversion -->
|
||||
<#if contextParam??>, ${contextParam}</#if>
|
||||
</#macro>
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=singleSourceParameterType/>
|
||||
</#macro>
|
||||
</@compress>
|
||||
|
@ -22,5 +22,6 @@
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=targetAccessorName
|
||||
targetReadAccessorName=targetReadAccessorName
|
||||
targetWriteAccessorName=targetWriteAccessorName
|
||||
targetType=targetType/>
|
||||
|
@ -18,4 +18,15 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
${openExpression}<@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>${closeExpression}
|
||||
<@compress single_line=true>
|
||||
${openExpression}<@_assignment/>${closeExpression}
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
||||
</@compress>
|
||||
|
@ -20,21 +20,23 @@
|
||||
-->
|
||||
<#if (exceptionTypes?size == 0) >
|
||||
for ( <@includeModel object=sourceType/> ${iteratorReference} : ${sourceReference} ) {
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( <@includeModel object=assignment
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=ext.targetAccessorName
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/> );
|
||||
}
|
||||
<#else>
|
||||
try {
|
||||
for ( <@includeModel object=sourceType/> ${iteratorReference} : ${sourceReference} ) {
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( <@includeModel object=assignment
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=ext.targetAccessorName
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/> );
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,11 @@
|
||||
-->
|
||||
<#if (exceptionTypes?size == 0) >
|
||||
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||
<#else>
|
||||
try {
|
||||
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||
}
|
||||
<#list exceptionTypes as exceptionType>
|
||||
catch ( <@includeModel object=exceptionType/> e ) {
|
||||
@ -33,5 +33,11 @@
|
||||
</#list>
|
||||
</#if>
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment raw=ext.raw targetType=ext.targetType/>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
@ -18,9 +18,9 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
if ( ${ext.targetBeanName}.${ext.targetAccessorName}() != null ) {
|
||||
if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}() != null ) {
|
||||
<#if ext.existingInstanceMapping>
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}().clear();
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}().clear();
|
||||
</#if>
|
||||
<#if (exceptionTypes?size == 0) >
|
||||
<@_assignmentLine/>
|
||||
@ -38,7 +38,7 @@ if ( ${ext.targetBeanName}.${ext.targetAccessorName}() != null ) {
|
||||
<#macro _assignmentLine>
|
||||
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||
if ( ${localVarName} != null ) {
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}().<#if ext.targetType.collectionType>addAll<#else>putAll</#if>( ${localVarName} );
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}().<#if ext.targetType.collectionType>addAll<#else>putAll</#if>( ${localVarName} );
|
||||
}
|
||||
</#macro>
|
||||
<#macro _assignment>
|
||||
@ -49,4 +49,4 @@ if ( ${ext.targetBeanName}.${ext.targetAccessorName}() != null ) {
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
||||
</#macro>
|
||||
|
@ -19,11 +19,11 @@
|
||||
|
||||
-->
|
||||
<#if (exceptionTypes?size == 0) >
|
||||
<#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/></#if> ${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
||||
<#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/></#if> ${ext.targetWriteAccessorName} = <@_assignment/>;
|
||||
<#else>
|
||||
<#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/> ${ext.targetAccessorName};</#if>
|
||||
<#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/> ${ext.targetWriteAccessorName};</#if>
|
||||
try {
|
||||
${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
||||
${ext.targetWriteAccessorName} = <@_assignment/>;
|
||||
}
|
||||
<#list exceptionTypes as exceptionType>
|
||||
catch ( <@includeModel object=exceptionType/> e ) {
|
||||
@ -31,3 +31,12 @@
|
||||
}
|
||||
</#list>
|
||||
</#if>
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
@ -24,5 +24,5 @@ new <#if ext.targetType.implementationType??>
|
||||
<#else>
|
||||
<@includeModel object=ext.targetType/>
|
||||
</#if>
|
||||
( <@includeModel object=assignment targetBeanName=ext.targetBeanName targetAccessorName=ext.targetAccessorName targetType=ext.targetType raw=ext.raw/> )
|
||||
( <@includeModel object=assignment targetBeanName=ext.targetBeanName targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName targetType=ext.targetType raw=ext.raw/> )
|
||||
</@compress>
|
@ -23,6 +23,7 @@ if ( ${sourceReference} != null ) {
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=ext.targetAccessorName
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
}
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
-->
|
||||
<#if (exceptionTypes?size == 0) >
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( <@_assignment/> );
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_assignment/> );
|
||||
<#else>
|
||||
try {
|
||||
${ext.targetBeanName}.${ext.targetAccessorName}( <@_assignment/> );
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_assignment/> );
|
||||
}
|
||||
<#list exceptionTypes as exceptionType>
|
||||
catch ( <@includeModel object=exceptionType/> e ) {
|
||||
@ -31,5 +31,11 @@
|
||||
</#list>
|
||||
</#if>
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment raw=ext.raw targetType=ext.targetType/>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
@ -26,14 +26,16 @@
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName="${targetGetterName}().addAll"
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName="${targetGetterName}().addAll"
|
||||
targetType=ext.targetType/>
|
||||
<#else>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName="${targetGetterName}().putAll"
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName="${targetGetterName}().putAll"
|
||||
targetType=ext.targetType/>
|
||||
</#if>
|
||||
}
|
||||
@ -56,7 +58,8 @@
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=ext.targetAccessorName
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
||||
<#macro _newCollectionOrMapAssignment>
|
||||
@ -64,6 +67,7 @@
|
||||
targetBeanName=ext.targetBeanName
|
||||
raw=ext.raw
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetAccessorName=ext.targetAccessorName
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
Loading…
x
Reference in New Issue
Block a user