#61 Instantiating collections/maps also if implementation type is used as target type

This commit is contained in:
Gunnar Morling 2013-08-15 20:47:19 +02:00
parent 1e280f83c9
commit 186c127ebd
4 changed files with 31 additions and 3 deletions

View File

@ -50,6 +50,7 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
private final boolean isInterface; private final boolean isInterface;
private final boolean isEnumType; private final boolean isEnumType;
private final boolean isIterableType; private final boolean isIterableType;
private final boolean isCollectionType;
private final boolean isMapType; private final boolean isMapType;
private final Type implementationType; private final Type implementationType;
private final TypeMirror typeMirror; private final TypeMirror typeMirror;
@ -57,12 +58,12 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
private final TypeElement typeElement; private final TypeElement typeElement;
public Type(TypeMirror typeMirror, List<Type> typeParameters, Type implementationType, boolean isIterableType, public Type(TypeMirror typeMirror, List<Type> typeParameters, Type implementationType, boolean isIterableType,
boolean isMapType, boolean isCollectionType, boolean isMapType, Types typeUtils, Elements elementUtils) {
Types typeUtils, Elements elementUtils) {
this.typeMirror = typeMirror; this.typeMirror = typeMirror;
this.implementationType = implementationType; this.implementationType = implementationType;
this.typeParameters = typeParameters; this.typeParameters = typeParameters;
this.isIterableType = isIterableType; this.isIterableType = isIterableType;
this.isCollectionType = isCollectionType;
this.isMapType = isMapType; this.isMapType = isMapType;
this.typeUtils = typeUtils; this.typeUtils = typeUtils;
@ -134,6 +135,10 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
return isIterableType; return isIterableType;
} }
public boolean isCollectionType() {
return isCollectionType;
}
public boolean isMapType() { public boolean isMapType() {
return isMapType; return isMapType;
} }

View File

@ -55,6 +55,7 @@ public class TypeFactory {
private final Types typeUtils; private final Types typeUtils;
private final TypeMirror iterableType; private final TypeMirror iterableType;
private final TypeMirror collectionType;
private final TypeMirror mapType; private final TypeMirror mapType;
private final Map<String, Type> implementationTypes = new HashMap<String, Type>(); private final Map<String, Type> implementationTypes = new HashMap<String, Type>();
@ -64,6 +65,10 @@ public class TypeFactory {
this.typeUtils = typeUtils; this.typeUtils = typeUtils;
iterableType = typeUtils.erasure( elementUtils.getTypeElement( Iterable.class.getCanonicalName() ).asType() ); 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() ); mapType = typeUtils.erasure( elementUtils.getTypeElement( Map.class.getCanonicalName() ).asType() );
implementationTypes.put( Iterable.class.getName(), getType( ArrayList.class ) ); implementationTypes.put( Iterable.class.getName(), getType( ArrayList.class ) );
@ -101,6 +106,10 @@ public class TypeFactory {
mirror, mirror,
iterableType iterableType
); );
boolean isCollectionType = typeUtils.isSubtype(
mirror,
collectionType
);
boolean isMapType = typeUtils.isSubtype( boolean isMapType = typeUtils.isSubtype(
mirror, mirror,
mapType mapType
@ -111,6 +120,7 @@ public class TypeFactory {
getTypeParameters( mirror ), getTypeParameters( mirror ),
implementationType, implementationType,
isIterableType, isIterableType,
isCollectionType,
isMapType, isMapType,
typeUtils, typeUtils,
elementUtils elementUtils
@ -165,6 +175,7 @@ public class TypeFactory {
getTypeParameters( mirror ), getTypeParameters( mirror ),
null, null,
implementationType.isIterableType(), implementationType.isIterableType(),
implementationType.isCollectionType(),
implementationType.isMapType(), implementationType.isMapType(),
typeUtils, typeUtils,
elementUtils elementUtils

View File

@ -32,7 +32,7 @@
</#if> </#if>
<#-- c) simply set --> <#-- c) simply set -->
<#else> <#else>
<#if targetType.implementationType??> <#if targetType.collectionType || targetType.mapType>
if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { if ( ${sourceBeanName}.${sourceAccessorName}() != null ) {
${ext.targetBeanName}.${targetAccessorName}( new <#if targetType.implementationType??><@includeModel object=targetType.implementationType/><#else><@includeModel object=targetType/></#if>( ${sourceBeanName}.${sourceAccessorName}() ) ); ${ext.targetBeanName}.${targetAccessorName}( new <#if targetType.implementationType??><@includeModel object=targetType.implementationType/><#else><@includeModel object=targetType/></#if>( ${sourceBeanName}.${sourceAccessorName}() ) );
} }

View File

@ -165,6 +165,18 @@ public class CollectionMappingTest extends MapperTestBase {
assertThat( source.getStringSet() ).containsOnly( "Bob", "Alice" ); assertThat( source.getStringSet() ).containsOnly( "Bob", "Alice" );
} }
@Test
@IssueKey("6")
public void shouldMapHashSetAsCopy() {
Source source = new Source();
source.setStringHashSet( new HashSet<String>( Arrays.asList( "Bob", "Alice" ) ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
target.getStringHashSet().add( "Bill" );
assertThat( source.getStringHashSet() ).containsOnly( "Bob", "Alice" );
}
@Test @Test
@IssueKey("6") @IssueKey("6")
public void shouldReverseMapSetAsCopy() { public void shouldReverseMapSetAsCopy() {