From 186c127ebda46e0a95d7bca913a64048e4ece5ad Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 15 Aug 2013 20:47:19 +0200 Subject: [PATCH] #61 Instantiating collections/maps also if implementation type is used as target type --- .../src/main/java/org/mapstruct/ap/model/Type.java | 9 +++++++-- .../main/java/org/mapstruct/ap/util/TypeFactory.java | 11 +++++++++++ .../org.mapstruct.ap.model.PropertyMapping.ftl | 2 +- .../ap/test/collection/CollectionMappingTest.java | 12 ++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/processor/src/main/java/org/mapstruct/ap/model/Type.java b/processor/src/main/java/org/mapstruct/ap/model/Type.java index bcc2bd769..6f9d6fc22 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/Type.java +++ b/processor/src/main/java/org/mapstruct/ap/model/Type.java @@ -50,6 +50,7 @@ public class Type extends AbstractModelElement implements Comparable { private final boolean isInterface; private final boolean isEnumType; private final boolean isIterableType; + private final boolean isCollectionType; private final boolean isMapType; private final Type implementationType; private final TypeMirror typeMirror; @@ -57,12 +58,12 @@ public class Type extends AbstractModelElement implements Comparable { private final TypeElement typeElement; public Type(TypeMirror typeMirror, List typeParameters, Type implementationType, boolean isIterableType, - boolean isMapType, - Types typeUtils, Elements elementUtils) { + boolean isCollectionType, boolean isMapType, Types typeUtils, Elements elementUtils) { this.typeMirror = typeMirror; this.implementationType = implementationType; this.typeParameters = typeParameters; this.isIterableType = isIterableType; + this.isCollectionType = isCollectionType; this.isMapType = isMapType; this.typeUtils = typeUtils; @@ -134,6 +135,10 @@ public class Type extends AbstractModelElement implements Comparable { return isIterableType; } + public boolean isCollectionType() { + return isCollectionType; + } + public boolean isMapType() { return isMapType; } diff --git a/processor/src/main/java/org/mapstruct/ap/util/TypeFactory.java b/processor/src/main/java/org/mapstruct/ap/util/TypeFactory.java index d800b4265..36f0e852a 100644 --- a/processor/src/main/java/org/mapstruct/ap/util/TypeFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/util/TypeFactory.java @@ -55,6 +55,7 @@ public class TypeFactory { private final Types typeUtils; private final TypeMirror iterableType; + private final TypeMirror collectionType; private final TypeMirror mapType; private final Map implementationTypes = new HashMap(); @@ -64,6 +65,10 @@ public class TypeFactory { this.typeUtils = typeUtils; iterableType = typeUtils.erasure( elementUtils.getTypeElement( Iterable.class.getCanonicalName() ).asType() ); + collectionType = typeUtils.erasure( + elementUtils.getTypeElement( Collection.class.getCanonicalName() ) + .asType() + ); mapType = typeUtils.erasure( elementUtils.getTypeElement( Map.class.getCanonicalName() ).asType() ); implementationTypes.put( Iterable.class.getName(), getType( ArrayList.class ) ); @@ -101,6 +106,10 @@ public class TypeFactory { mirror, iterableType ); + boolean isCollectionType = typeUtils.isSubtype( + mirror, + collectionType + ); boolean isMapType = typeUtils.isSubtype( mirror, mapType @@ -111,6 +120,7 @@ public class TypeFactory { getTypeParameters( mirror ), implementationType, isIterableType, + isCollectionType, isMapType, typeUtils, elementUtils @@ -165,6 +175,7 @@ public class TypeFactory { getTypeParameters( mirror ), null, implementationType.isIterableType(), + implementationType.isCollectionType(), implementationType.isMapType(), typeUtils, elementUtils diff --git a/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl b/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl index 0424237ef..60a487619 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl @@ -32,7 +32,7 @@ <#-- c) simply set --> <#else> - <#if targetType.implementationType??> + <#if targetType.collectionType || targetType.mapType> if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { ${ext.targetBeanName}.${targetAccessorName}( new <#if targetType.implementationType??><@includeModel object=targetType.implementationType/><#else><@includeModel object=targetType/>( ${sourceBeanName}.${sourceAccessorName}() ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java index 532c7b1ea..19fc8d444 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java @@ -165,6 +165,18 @@ public class CollectionMappingTest extends MapperTestBase { assertThat( source.getStringSet() ).containsOnly( "Bob", "Alice" ); } + @Test + @IssueKey("6") + public void shouldMapHashSetAsCopy() { + Source source = new Source(); + source.setStringHashSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + target.getStringHashSet().add( "Bill" ); + + assertThat( source.getStringHashSet() ).containsOnly( "Bob", "Alice" ); + } + @Test @IssueKey("6") public void shouldReverseMapSetAsCopy() {