#227 removing the new collection / map implementation from the addAll methods

This commit is contained in:
sjaakd 2014-06-22 22:54:20 +02:00
parent 6eed953fdf
commit cd1037a663
5 changed files with 78 additions and 35 deletions

View File

@ -18,13 +18,11 @@
*/
package org.mapstruct.ap.model;
import java.util.HashSet;
import java.util.Set;
import org.mapstruct.ap.model.common.ModelElement;
import org.mapstruct.ap.model.common.Type;
import static org.mapstruct.ap.model.Assignment.AssignmentType.DIRECT;
/**
* Represents the mapping between a source and target property, e.g. from
@ -76,16 +74,7 @@ public class PropertyMapping extends ModelElement {
@Override
public Set<Type> getImportTypes() {
Set<Type> importTypes = new HashSet<Type>();
if ( assignment.getType() == DIRECT ) {
if ( targetType.isCollectionOrMapType() ) {
importTypes.addAll( targetType.getImportTypes() );
}
}
else {
importTypes.addAll( assignment.getImportTypes() );
}
return importTypes;
return assignment.getImportTypes();
}
@Override

View File

@ -18,7 +18,10 @@
*/
package org.mapstruct.ap.model.assignment;
import java.util.HashSet;
import java.util.Set;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.common.Type;
/**
* Decorates the assignment as a Map or Collection constructor
@ -27,7 +30,18 @@ import org.mapstruct.ap.model.Assignment;
*/
public class NewCollectionOrMapWrapper extends AssignmentWrapper {
public NewCollectionOrMapWrapper( Assignment decoratedAssignment ) {
private final Set<Type> implementationTypes;
public NewCollectionOrMapWrapper( Assignment decoratedAssignment, Set<Type> implementationTypes ) {
super( decoratedAssignment );
this.implementationTypes = implementationTypes;
}
@Override
public Set<Type> getImportTypes() {
Set<Type> imported = new HashSet<Type>();
imported.addAll( getAssignment().getImportTypes() );
imported.addAll( implementationTypes );
return imported;
}
}

View File

@ -18,7 +18,10 @@
*/
package org.mapstruct.ap.model.assignment;
import java.util.HashSet;
import java.util.Set;
import org.mapstruct.ap.model.Assignment;
import org.mapstruct.ap.model.common.Type;
/**
* This wrapper handles the situation were an assignment is done via the setter.
@ -35,14 +38,31 @@ import org.mapstruct.ap.model.Assignment;
public class SetterCollectionOrMapWrapper extends AssignmentWrapper {
private final String targetGetterName;
private final Assignment newCollectionOrMapAssignment;
public SetterCollectionOrMapWrapper( Assignment decoratedAssignment, String targetSetterName ) {
public SetterCollectionOrMapWrapper( Assignment decoratedAssignment,
String targetSetterName,
Assignment newCollectionOrMapAssignment ) {
super( decoratedAssignment );
this.targetGetterName = "get" + targetSetterName.substring( 3 );
this.newCollectionOrMapAssignment = newCollectionOrMapAssignment;
}
public String getTargetGetterName() {
return targetGetterName;
}
public Assignment getNewCollectionOrMapAssignment() {
return newCollectionOrMapAssignment;
}
@Override
public Set<Type> getImportTypes() {
Set<Type> imported = new HashSet<Type>();
imported.addAll( getAssignment().getImportTypes() );
if ( newCollectionOrMapAssignment != null ) {
imported.addAll( newCollectionOrMapAssignment.getImportTypes() );
}
return imported;
}
}

View File

@ -759,26 +759,32 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
if ( targetType.isCollectionOrMapType() ) {
// 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
if ( assignment.getType() == DIRECT ) {
assignment = new NewCollectionOrMapWrapper( assignment );
}
// wrap the assignment in the setter method
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
// wrap the setter in the collection / map initializers
if ( targetAccessorType == TargetAccessorType.SETTER ) {
// target accessor is setter, so decorate assignment as 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
Assignment newCollectionOrMap = null;
if ( assignment.getType() == DIRECT ) {
newCollectionOrMap = new NewCollectionOrMapWrapper( assignment, targetType.getImportTypes() );
newCollectionOrMap = new SetterWrapper( newCollectionOrMap, method.getThrownTypes() );
}
// wrap the assignment in the setter method
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
// target accessor is setter, so wrap the setter in setter map/ collection handling
assignment = new SetterCollectionOrMapWrapper(
assignment,
targetAccessor.getSimpleName().toString()
targetAccessor.getSimpleName().toString(),
newCollectionOrMap
);
}
else {
// target accessor is getter, so decorate assignment as getter
// wrap the assignment in the setter method
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
// target accessor is getter, so wrap the setter in getter map/ collection handling
assignment = new GetterCollectionOrMapWrapper( assignment );
}
@ -869,7 +875,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
// create a new Map or Collection implementation if no method or type conversion
if ( targetType != null && ( targetType.isCollectionType() || targetType.isMapType() ) ) {
if ( assignment.getType() == DIRECT ) {
assignment = new NewCollectionOrMapWrapper( assignment );
assignment = new NewCollectionOrMapWrapper( assignment, targetType.getImportTypes() );
}
}

View File

@ -38,18 +38,32 @@
</#if>
}
else {
<@includeModel object=assignment
targetBeanName=ext.targetBeanName
raw=ext.raw
existingInstanceMapping=ext.existingInstanceMapping
targetAccessorName=ext.targetAccessorName
targetType=ext.targetType/>
<#if newCollectionOrMapAssignment??>
<@_newCollectionOrMapAssignment/>
<#else>
<@_assignment/>
</#if>
}
<#else>
<#if newCollectionOrMapAssignment??>
<@_newCollectionOrMapAssignment/>
<#else>
<@_assignment/>
</#if>
</#if>
<#macro _assignment>
<@includeModel object=assignment
targetBeanName=ext.targetBeanName
raw=ext.raw
existingInstanceMapping=ext.existingInstanceMapping
targetAccessorName=ext.targetAccessorName
targetType=ext.targetType/>
</#if>
</#macro>
<#macro _newCollectionOrMapAssignment>
<@includeModel object=newCollectionOrMapAssignment
targetBeanName=ext.targetBeanName
raw=ext.raw
existingInstanceMapping=ext.existingInstanceMapping
targetAccessorName=ext.targetAccessorName
targetType=ext.targetType/>
</#macro>