diff --git a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java index 962c6b1b3..968b8a3a5 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java @@ -320,7 +320,7 @@ public class PropertyMapping extends ModelElement { result = new GetterWrapperForCollectionsAndMaps( result, method.getThrownTypes(), - targetType, + ctx.getTypeFactory().asCollectionOrMap( targetType ), existingVariableNames ); } @@ -591,7 +591,7 @@ public class PropertyMapping extends ModelElement { assignment = new GetterWrapperForCollectionsAndMaps( assignment, method.getThrownTypes(), - targetType, + ctx.getTypeFactory().asCollectionOrMap( targetType ), existingVariableNames ); } @@ -643,7 +643,7 @@ public class PropertyMapping extends ModelElement { assignment = new GetterWrapperForCollectionsAndMaps( assignment, method.getThrownTypes(), - targetType, + ctx.getTypeFactory().asCollectionOrMap( targetType ), existingVariableNames ); } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/GetterWrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/GetterWrapperForCollectionsAndMaps.java index 47d9c7f64..74d3d4a02 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/assignment/GetterWrapperForCollectionsAndMaps.java +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/GetterWrapperForCollectionsAndMaps.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; + import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.util.Strings; @@ -42,16 +43,16 @@ import org.mapstruct.ap.util.Strings; public class GetterWrapperForCollectionsAndMaps extends AssignmentWrapper { private final List exceptionTypesToExclude; - private final Type targetType; + private final Type localVarType; private final String localVarName; public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, List exceptionTypesToExclude, - Type targetType, Collection existingVariableNames ) { + Type localVarType, Collection existingVariableNames) { super( decoratedAssignment ); this.exceptionTypesToExclude = exceptionTypesToExclude; - this.targetType = targetType; - this.localVarName = Strings.getSaveVariableName( "target" + targetType.getName(), existingVariableNames ); + this.localVarType = localVarType; + this.localVarName = Strings.getSaveVariableName( "target" + localVarType.getName(), existingVariableNames ); existingVariableNames.add( localVarName ); } @@ -73,10 +74,17 @@ public class GetterWrapperForCollectionsAndMaps extends AssignmentWrapper { public Set getImportTypes() { Set imported = new HashSet(); imported.addAll( super.getImportTypes() ); - imported.add( targetType ); /* is a local var */ + imported.add( localVarType ); /* is a local var */ return imported; } + /** + * @return the targetType + */ + public Type getLocalVarType() { + return localVarType; + } + public String getLocalVarName() { return localVarName; } diff --git a/processor/src/main/java/org/mapstruct/ap/model/common/TypeFactory.java b/processor/src/main/java/org/mapstruct/ap/model/common/TypeFactory.java index 3d64c942c..cdaf4ac2e 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/common/TypeFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/model/common/TypeFactory.java @@ -451,4 +451,35 @@ public class TypeFactory { return t; } } + + /** + * Converts any collection type, e.g. List to Collection and any map type, e.g. HashMap to Map. + * + * @param collectionOrMap any collection or map type + * @return the type representing Collection or Map, if the argument type is a subtype of Collection or of + * Map respectively. + */ + public Type asCollectionOrMap(Type collectionOrMap) { + List originalParameters = collectionOrMap.getTypeParameters(); + TypeMirror[] originalParameterMirrors = new TypeMirror[originalParameters.size()]; + int i = 0; + for ( Type param : originalParameters ) { + originalParameterMirrors[i++] = param.getTypeMirror(); + } + + if ( collectionOrMap.isCollectionType() + && !"java.util.Collection".equals( collectionOrMap.getFullyQualifiedName() ) ) { + return getType( typeUtils.getDeclaredType( + elementUtils.getTypeElement( "java.util.Collection" ), + originalParameterMirrors ) ); + } + else if ( collectionOrMap.isMapType() + && !"java.util.Map".equals( collectionOrMap.getFullyQualifiedName() ) ) { + return getType( typeUtils.getDeclaredType( + elementUtils.getTypeElement( "java.util.Map" ), + originalParameterMirrors ) ); + } + + return collectionOrMap; + } } diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.GetterWrapperForCollectionsAndMaps.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.GetterWrapperForCollectionsAndMaps.ftl index f96145410..fd696c66e 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.assignment.GetterWrapperForCollectionsAndMaps.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.GetterWrapperForCollectionsAndMaps.ftl @@ -36,7 +36,7 @@ if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}() != null ) { } <#macro _assignmentLine> - <@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>; + <@includeModel object=localVarType/> ${localVarName} = <@_assignment/>; if ( ${localVarName} != null ) { ${ext.targetBeanName}.${ext.targetWriteAccessorName}().<#if ext.targetType.collectionType>addAll<#else>putAll( ${localVarName} ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java index 4538b16d0..5d7f27178 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java @@ -50,6 +50,8 @@ public class Source { private List stringList2; + private Set stringSet2; + public List getStringList() { return stringList; } @@ -154,4 +156,12 @@ public class Source { this.otherStringLongMap = otherStringLongMap; } + public Set getStringSet2() { + return stringSet2; + } + + public void setStringSet2(Set stringSet2) { + this.stringSet2 = stringSet2; + } + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java index c499484d0..1249803e5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java @@ -20,11 +20,12 @@ package org.mapstruct.ap.test.collection; import java.util.Set; +import org.mapstruct.InheritConfiguration; +import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; -import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.factory.Mappers; @Mapper @@ -36,19 +37,15 @@ public interface SourceTargetMapper { @Mapping(source = "integerList", target = "integerCollection"), @Mapping(source = "integerSet", target = "set"), @Mapping(source = "anotherIntegerSet", target = "anotherStringSet"), - @Mapping(source = "stringList2", target = "stringListNoSetter") + @Mapping(source = "stringList2", target = "stringListNoSetter"), + @Mapping(source = "stringSet2", target = "stringListNoSetter2") }) Target sourceToTarget(Source source); @InheritInverseConfiguration( name = "sourceToTarget" ) Source targetToSource(Target target); - @Mappings({ - @Mapping(source = "integerList", target = "integerCollection"), - @Mapping(source = "integerSet", target = "set"), - @Mapping(source = "anotherIntegerSet", target = "anotherStringSet"), - @Mapping(source = "stringList2", target = "stringListNoSetter") - }) + @InheritConfiguration Target sourceToTargetTwoArg(Source source, @MappingTarget Target target); Set integerSetToStringSet(Set integers); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java index 224e8dc23..30c2c31cf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java @@ -50,6 +50,8 @@ public class Target { private List stringListNoSetter; + private List stringListNoSetter2; + @SuppressWarnings("rawtypes") private Set set; @@ -149,6 +151,13 @@ public class Target { return stringListNoSetter; } + public List getStringListNoSetter2() { + if ( stringListNoSetter2 == null ) { + stringListNoSetter2 = new ArrayList(); + } + return stringListNoSetter2; + } + public Map getOtherStringLongMap() { return otherStringLongMap; }