mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#6 Mapping collections of with same element type in source and target as copy
This commit is contained in:
parent
b11fa30200
commit
07c1009c6b
@ -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 ) {
|
||||
|
@ -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 ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user