diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Direct.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Direct.java index e7f2efb5a..d71b2980f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Direct.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Direct.java @@ -69,4 +69,8 @@ public class Direct extends ModelElement implements Assignment { return false; } + @Override + public String toString() { + return sourceReference; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java index e18c3efe9..13bd32418 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java @@ -35,6 +35,7 @@ import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.internal.model.assignment.AdderWrapper; import org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper; import org.mapstruct.ap.internal.model.assignment.Assignment; +import org.mapstruct.ap.internal.model.assignment.EnumSetCopyWrapper; import org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps; import org.mapstruct.ap.internal.model.assignment.NewCollectionOrMapWrapper; import org.mapstruct.ap.internal.model.assignment.NullCheckWrapper; @@ -347,7 +348,14 @@ public class PropertyMapping extends ModelElement { else { implementationTypes = targetType.getImportTypes(); } - newCollectionOrMap = new NewCollectionOrMapWrapper( result, implementationTypes ); + + if ( "java.util.EnumSet".equals( targetType.getFullyQualifiedName() ) ) { + newCollectionOrMap = new EnumSetCopyWrapper( ctx.getTypeFactory(), result ); + } + else { + newCollectionOrMap = new NewCollectionOrMapWrapper( result, implementationTypes ); + } + newCollectionOrMap = new SetterWrapper( newCollectionOrMap, method.getThrownTypes() ); } if ( result.isUpdateMethod() ) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.java new file mode 100644 index 000000000..11fa41fb8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.java @@ -0,0 +1,55 @@ +/** + * Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.internal.model.assignment; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; + +/** + * Invokes the copy method for enum sets. + * + * @author Gunnar Morling + */ +public class EnumSetCopyWrapper extends AssignmentWrapper { + + private Type enumSetType; + + public EnumSetCopyWrapper(TypeFactory typeFactory, Assignment decoratedAssignment) { + super( decoratedAssignment ); + enumSetType = typeFactory.getType( EnumSet.class ); + } + + @Override + public Set getImportTypes() { + Set imported = new HashSet( getAssignment().getImportTypes().size() + 1 ); + imported.addAll( getAssignment().getImportTypes() ); + imported.add( enumSetType ); + + return imported; + } + + @Override + public String toString() { + return "EnumSet.copyOf( " + getAssignment() + " )"; + } +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.ftl new file mode 100644 index 000000000..4f692c7b7 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumSetCopyWrapper.ftl @@ -0,0 +1,21 @@ +<#-- + + Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/) + and/or other contributors as indicated by the @authors tag. See the + copyright.txt file in the distribution for a full listing of all + contributors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +EnumSet.copyOf( <@includeModel object=assignment targetBeanName=ext.targetBeanName targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName targetType=ext.targetType/> ) 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 ad1039313..fc4ac4e03 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 @@ -376,4 +376,17 @@ public class CollectionMappingTest { assertThat( numbers ).isNotNull(); assertThat( numbers ).containsOnly( 123, 456 ); } + + @Test + @IssueKey("732") + public void shouldEnumSetAsCopy() { + Source source = new Source(); + source.setEnumSet( EnumSet.of( Colour.BLUE, Colour.GREEN ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + source.getEnumSet().add( Colour.RED ); + + assertThat( source.getEnumSet() ).containsOnly( Colour.BLUE, Colour.GREEN, Colour.RED ); + assertThat( target.getEnumSet() ).containsOnly( Colour.BLUE, Colour.GREEN ); + } } 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 74b0d992f..9cf974134 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 @@ -20,6 +20,7 @@ package org.mapstruct.ap.test.collection; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -52,6 +53,8 @@ public class Source { private Set stringSet2; + private EnumSet enumSet; + public List getStringList() { return stringList; } @@ -164,4 +167,11 @@ public class Source { this.stringSet2 = stringSet2; } + public EnumSet getEnumSet() { + return enumSet; + } + + public void setEnumSet(EnumSet enumSet) { + this.enumSet = enumSet; + } } 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 94af29fec..8ddd9d210 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 @@ -20,6 +20,7 @@ package org.mapstruct.ap.test.collection; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -55,6 +56,8 @@ public class Target { @SuppressWarnings("rawtypes") private Set set; + private EnumSet enumSet; + public Target() { otherStringLongMap = Maps.newHashMap(); otherStringLongMap.put( "not-present-after-mapping", 42L ); @@ -174,4 +177,11 @@ public class Target { this.otherStringList = otherStringList; } + public EnumSet getEnumSet() { + return enumSet; + } + + public void setEnumSet(EnumSet enumSet) { + this.enumSet = enumSet; + } }