#6 Mapping collections of with same element type in source and target as copy

This commit is contained in:
Gunnar Morling 2013-05-02 23:30:27 +02:00
parent b11fa30200
commit 07c1009c6b
7 changed files with 305 additions and 6 deletions

View File

@ -48,12 +48,19 @@ public class Type {
private final Type elementType;
private final boolean isEnumType;
private final Type implementingType;
private final boolean isCollectionType;
public static Type forClass(Class<?> clazz) {
Package pakkage = clazz.getPackage();
if ( pakkage != null ) {
return new Type( pakkage.getName(), clazz.getSimpleName(), null, clazz.isEnum() );
return new Type(
pakkage.getName(),
clazz.getSimpleName(),
null,
clazz.isEnum(),
Collection.class.isAssignableFrom( clazz )
);
}
else {
return new Type( clazz.getSimpleName() );
@ -61,15 +68,16 @@ public class Type {
}
public Type(String name) {
this( null, name, null, false );
this( null, name, null, false, false );
}
public Type(String packageName, String name, Type elementType, boolean isEnumType) {
public Type(String packageName, String name, Type elementType, boolean isEnumType, boolean isCollectionType) {
this.packageName = packageName;
this.name = name;
this.elementType = elementType;
this.isEnumType = isEnumType;
implementingType = defaultCollectionImplementationTypes.get( packageName + "." + name );
this.isCollectionType = isCollectionType;
}
public String getPackageName() {
@ -96,6 +104,10 @@ public class Type {
return implementingType;
}
public boolean isCollectionType() {
return isCollectionType;
}
@Override
public String toString() {
if ( packageName == null ) {

View File

@ -15,6 +15,7 @@
*/
package org.mapstruct.ap.util;
import java.util.Collection;
import javax.lang.model.element.ElementKind;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
@ -28,20 +29,27 @@ public class TypeUtil {
private final Elements elementUtils;
private final Types typeUtils;
private TypeMirror collectionType;
public TypeUtil(Elements elementUtils, Types typeUtils) {
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
collectionType = elementUtils.getTypeElement( Collection.class.getCanonicalName() ).asType();
}
public Type getType(DeclaredType type) {
Type elementType = isIterableType( type ) ? retrieveType( type.getTypeArguments().iterator().next() ) : null;
Type elementType = null;
if ( isIterableType( type ) && !type.getTypeArguments().isEmpty() ) {
elementType = retrieveType( type.getTypeArguments().iterator().next() );
}
return new Type(
elementUtils.getPackageOf( type.asElement() ).toString(),
type.asElement().getSimpleName().toString(),
elementType,
type.asElement().getKind() == ElementKind.ENUM
type.asElement().getKind() == ElementKind.ENUM,
typeUtils.isAssignable( typeUtils.erasure( type ), typeUtils.erasure( collectionType ) )
);
}

View File

@ -75,7 +75,13 @@ public class ${implementationName} implements ${interfaceName} {
<#elseif propertyMapping.mappingMethod??>
${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( <#if propertyMapping.mappingMethod.declaringMapper??>${propertyMapping.mappingMethod.declaringMapper.name?uncap_first}.</#if>${propertyMapping.mappingMethod.name}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) );
<#else>
<#if propertyMapping.targetType.collectionType == true>
if ( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() != null ) {
${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( new <#if propertyMapping.targetType.implementingType??>${propertyMapping.targetType.implementingType.name}<#else>${propertyMapping.targetType.name}</#if><#if propertyMapping.targetType.elementType??><${propertyMapping.targetType.elementType.name}></#if>( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) );
}
<#else>
${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() );
</#if>
</#if>
</#list>
@ -124,7 +130,13 @@ public class ${implementationName} implements ${interfaceName} {
<#elseif propertyMapping.reverseMappingMethod??>
${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( <#if propertyMapping.reverseMappingMethod.declaringMapper??>${propertyMapping.reverseMappingMethod.declaringMapper.name?uncap_first}.</#if>${propertyMapping.reverseMappingMethod.name}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) );
<#else>
<#if propertyMapping.sourceType.collectionType == true>
if ( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() != null ) {
${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( new <#if propertyMapping.sourceType.implementingType??>${propertyMapping.sourceType.implementingType.name}<#else>${propertyMapping.sourceType.name}</#if><#if propertyMapping.sourceType.elementType??><${propertyMapping.sourceType.elementType.name}></#if>( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) );
}
<#else>
${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() );
</#if>
</#if>
</#list>

View File

@ -15,7 +15,9 @@
*/
package org.mapstruct.ap.test.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.mapstruct.ap.testutil.IssueKey;
@ -45,4 +47,159 @@ public class CollectionMappingTest extends MapperTestBase {
assertThat( target ).isNotNull();
assertThat( target.getStringList() ).isNull();
}
@Test
@IssueKey("6")
public void shouldReverseMapNullList() {
Target target = new Target();
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getStringList() ).isNull();
}
@Test
@IssueKey("6")
public void shouldMapList() {
Source source = new Source();
source.setStringList( Arrays.asList( "Bob", "Alice" ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getStringList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldReverseMapList() {
Target target = new Target();
target.setStringList( Arrays.asList( "Bob", "Alice" ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getStringList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldMapListAsCopy() {
Source source = new Source();
source.setStringList( Arrays.asList( "Bob", "Alice" ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
target.getStringList().add( "Bill" );
assertThat( source.getStringList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldReverseMapListAsCopy() {
Target target = new Target();
target.setStringList( Arrays.asList( "Bob", "Alice" ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
source.getStringList().add( "Bill" );
assertThat( target.getStringList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldMapArrayList() {
Source source = new Source();
source.setStringArrayList( new ArrayList<String>( Arrays.asList( "Bob", "Alice" ) ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getStringArrayList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldReverseMapArrayList() {
Target target = new Target();
target.setStringArrayList( new ArrayList<String>( Arrays.asList( "Bob", "Alice" ) ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getStringArrayList() ).containsExactly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldMapSet() {
Source source = new Source();
source.setStringSet( new HashSet<String>( Arrays.asList( "Bob", "Alice" ) ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getStringSet() ).contains( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldReverseMapSet() {
Target target = new Target();
target.setStringSet( new HashSet<String>( Arrays.asList( "Bob", "Alice" ) ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getStringSet() ).contains( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldMapSetAsCopy() {
Source source = new Source();
source.setStringSet( new HashSet<String>( Arrays.asList( "Bob", "Alice" ) ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
target.getStringSet().add( "Bill" );
assertThat( source.getStringSet() ).containsOnly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldReverseMapSetAsCopy() {
Target target = new Target();
target.setStringSet( new HashSet<String>( Arrays.asList( "Bob", "Alice" ) ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
source.getStringSet().add( "Bill" );
assertThat( target.getStringSet() ).containsOnly( "Bob", "Alice" );
}
@Test
@IssueKey("6")
public void shouldMapListToCollection() {
Source source = new Source();
source.setIntegerList( Arrays.asList( 1, 2 ) );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getIntegerCollection() ).containsOnly( 1, 2 );
}
@Test
@IssueKey("6")
public void shouldReverseMapListToCollection() {
Target target = new Target();
target.setIntegerCollection( Arrays.asList( 1, 2 ) );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getIntegerList() ).containsOnly( 1, 2 );
}
}

View File

@ -15,11 +15,23 @@
*/
package org.mapstruct.ap.test.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Source {
private List<String> stringList;
private ArrayList<String> stringArrayList;
private Set<String> stringSet;
private HashSet<String> stringHashSet;
private Collection<String> stringCollection;
private List<Integer> integerList;
public List<String> getStringList() {
return stringList;
@ -28,4 +40,44 @@ public class Source {
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public ArrayList<String> getStringArrayList() {
return stringArrayList;
}
public void setStringArrayList(ArrayList<String> stringArrayList) {
this.stringArrayList = stringArrayList;
}
public Set<String> getStringSet() {
return stringSet;
}
public void setStringSet(Set<String> stringSet) {
this.stringSet = stringSet;
}
public HashSet<String> getStringHashSet() {
return stringHashSet;
}
public void setStringHashSet(HashSet<String> stringHashSet) {
this.stringHashSet = stringHashSet;
}
public Collection<String> getStringCollection() {
return stringCollection;
}
public void setStringCollection(Collection<String> stringCollection) {
this.stringCollection = stringCollection;
}
public List<Integer> getIntegerList() {
return integerList;
}
public void setIntegerList(List<Integer> integerList) {
this.integerList = integerList;
}
}

View File

@ -15,14 +15,20 @@
*/
package org.mapstruct.ap.test.collection;
import org.mapstruct.Mapper;
import org.mapstruct.Mappers;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@Mapper
public interface SourceTargetMapper {
public static SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
@Mappings({
@Mapping(source = "integerList", target = "integerCollection")
})
Target sourceToTarget(Source source);
Source targetToSource(Target target);
}

View File

@ -15,11 +15,23 @@
*/
package org.mapstruct.ap.test.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Target {
private List<String> stringList;
private ArrayList<String> stringArrayList;
private Set<String> stringSet;
private HashSet<String> stringHashSet;
private Collection<String> stringCollection;
private Collection<Integer> integerCollection;
public List<String> getStringList() {
return stringList;
@ -28,4 +40,44 @@ public class Target {
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public ArrayList<String> getStringArrayList() {
return stringArrayList;
}
public void setStringArrayList(ArrayList<String> stringArrayList) {
this.stringArrayList = stringArrayList;
}
public Set<String> getStringSet() {
return stringSet;
}
public void setStringSet(Set<String> stringSet) {
this.stringSet = stringSet;
}
public HashSet<String> getStringHashSet() {
return stringHashSet;
}
public void setStringHashSet(HashSet<String> stringHashSet) {
this.stringHashSet = stringHashSet;
}
public Collection<String> getStringCollection() {
return stringCollection;
}
public void setStringCollection(Collection<String> stringCollection) {
this.stringCollection = stringCollection;
}
public Collection<Integer> getIntegerCollection() {
return integerCollection;
}
public void setIntegerCollection(Collection<Integer> integerCollection) {
this.integerCollection = integerCollection;
}
}