From 8f56d8dd6723550cb4d28febbefa5c0d5a52c230 Mon Sep 17 00:00:00 2001 From: sjaakd Date: Tue, 19 Aug 2014 19:42:25 +0200 Subject: [PATCH] #265 adding imports to the Mapper to make expressions more easy. --- .../src/main/java/org/mapstruct/Mapper.java | 9 ++++++++ .../org/mapstruct/ap/model/Decorator.java | 7 +++--- .../org/mapstruct/ap/model/GeneratedType.java | 10 ++++++++- .../java/org/mapstruct/ap/model/Mapper.java | 22 ++++++++++++++----- .../ap/processor/MapperCreationProcessor.java | 19 +++++++++++++++- .../org/mapstruct/ap/util/MapperConfig.java | 4 ++++ .../expressions/java/JavaExpressionTest.java | 1 + .../expressions/java/SourceTargetMapper.java | 11 +++++----- .../SourceTargetMapperSeveralSources.java | 9 ++++---- .../test/source/expressions/java/Target.java | 2 ++ .../java/{ => mapper}/TimeAndFormat.java | 2 +- 11 files changed, 73 insertions(+), 23 deletions(-) rename processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/{ => mapper}/TimeAndFormat.java (95%) diff --git a/core-common/src/main/java/org/mapstruct/Mapper.java b/core-common/src/main/java/org/mapstruct/Mapper.java index cc03b1f4c..031126752 100644 --- a/core-common/src/main/java/org/mapstruct/Mapper.java +++ b/core-common/src/main/java/org/mapstruct/Mapper.java @@ -42,6 +42,15 @@ public @interface Mapper { */ Class[] uses() default { }; + /** + * Additional types for which an import statement is to be added to the generated mapper implementation class. + * This allows to refer to those types from within mapping expressions given via {@link #expression()} using + * their simple name rather than their fully-qualified name. + * + * @return classes to add in the imports of the generated implementation. + */ + Class[] imports() default { }; + /** * How unmapped properties of the target type of a mapping should be * reported. The method overrides an unmappedTargetPolicy set in a central diff --git a/processor/src/main/java/org/mapstruct/ap/model/Decorator.java b/processor/src/main/java/org/mapstruct/ap/model/Decorator.java index 57f43ab5c..4be7d75ea 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/Decorator.java +++ b/processor/src/main/java/org/mapstruct/ap/model/Decorator.java @@ -20,10 +20,10 @@ package org.mapstruct.ap.model; import java.util.Arrays; import java.util.List; +import java.util.TreeSet; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; - import org.mapstruct.ap.model.common.Accessibility; import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.Type; @@ -41,7 +41,7 @@ public class Decorator extends GeneratedType { private Decorator(TypeFactory typeFactory, String packageName, String name, String superClassName, String interfaceName, List methods, List fields, - boolean suppressGeneratorTimestamp, Accessibility accessibility) { + boolean suppressGeneratorTimestamp, Accessibility accessibility ) { super( typeFactory, packageName, @@ -51,7 +51,8 @@ public class Decorator extends GeneratedType { methods, fields, suppressGeneratorTimestamp, - accessibility + accessibility, + new TreeSet() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/model/GeneratedType.java b/processor/src/main/java/org/mapstruct/ap/model/GeneratedType.java index dce5aeda8..20fea924e 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/GeneratedType.java +++ b/processor/src/main/java/org/mapstruct/ap/model/GeneratedType.java @@ -45,6 +45,7 @@ public abstract class GeneratedType extends ModelElement { private final List annotations; private final List methods; private final List fields; + private final SortedSet extraImportedTypes; private final boolean suppressGeneratorTimestamp; private final Accessibility accessibility; @@ -58,11 +59,14 @@ public abstract class GeneratedType extends ModelElement { String interfaceName, List methods, List fields, - boolean suppressGeneratorTimestamp, Accessibility accessibility) { + boolean suppressGeneratorTimestamp, + Accessibility accessibility, + SortedSet extraImportedTypes) { this.packageName = packageName; this.name = name; this.superClassName = superClassName; this.interfaceName = interfaceName; + this.extraImportedTypes = extraImportedTypes; this.annotations = new ArrayList(); this.methods = methods; @@ -135,6 +139,10 @@ public abstract class GeneratedType extends ModelElement { addWithDependents( importedTypes, annotation.getType() ); } + for ( Type extraImport : extraImportedTypes ) { + addWithDependents( importedTypes, extraImport ); + } + return importedTypes; } diff --git a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java index 9f7e95f87..94a3102d9 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java @@ -19,11 +19,12 @@ package org.mapstruct.ap.model; import java.util.List; +import java.util.SortedSet; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; - import org.mapstruct.ap.model.common.Accessibility; +import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.TypeFactory; /** @@ -40,10 +41,11 @@ public class Mapper extends GeneratedType { private final List referencedMappers; private final Decorator decorator; + //CHECKSTYLE:OFF private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName, - String interfaceName, - List methods, boolean suppressGeneratorTimestamp, Accessibility accessibility, - List referencedMappers, Decorator decorator) { + String interfaceName, List methods, boolean suppressGeneratorTimestamp, + Accessibility accessibility, List referencedMappers, Decorator decorator, + SortedSet extraImportedTypes ) { super( typeFactory, @@ -54,7 +56,8 @@ public class Mapper extends GeneratedType { methods, referencedMappers, suppressGeneratorTimestamp, - accessibility + accessibility, + extraImportedTypes ); this.referencedMappers = referencedMappers; @@ -67,6 +70,7 @@ public class Mapper extends GeneratedType { private TypeElement element; private List mappingMethods; private List mapperReferences; + private SortedSet extraImportedTypes; private Elements elementUtils; private boolean suppressGeneratorTimestamp; @@ -107,6 +111,11 @@ public class Mapper extends GeneratedType { return this; } + public Builder extraImports(SortedSet extraImportedTypes) { + this.extraImportedTypes = extraImportedTypes; + return this; + } + public Mapper build() { String implementationName = element.getSimpleName() + ( decorator == null ? IMPLEMENTATION_SUFFIX : DECORATED_IMPLEMENTATION_SUFFIX ); @@ -121,7 +130,8 @@ public class Mapper extends GeneratedType { suppressGeneratorTimestamp, Accessibility.fromModifiers( element.getModifiers() ), mapperReferences, - decorator + decorator, + extraImportedTypes ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java index 3bd102c5a..be3bc68f1 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java @@ -26,6 +26,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import javax.annotation.processing.Messager; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -132,6 +134,7 @@ public class MapperCreationProcessor implements ModelElementProcessor getReferencedMappers(TypeElement element) { + private List getReferencedMappers(TypeElement element) { List mapperReferences = new LinkedList(); List variableNames = new LinkedList(); @@ -263,6 +266,20 @@ public class MapperCreationProcessor implements ModelElementProcessor getExtraImports(TypeElement element) { + + SortedSet extraImports = new TreeSet(); + + MapperConfig mapperPrism = MapperConfig.getInstanceOn( element ); + + for ( TypeMirror extraImport : mapperPrism.imports() ) { + Type type = typeFactory.getType( extraImport ); + extraImports.add( type ); + } + + return extraImports; + } + private List getMappingMethods(List mapperReferences, List methods, TypeElement element) { List mappingMethods = new ArrayList(); diff --git a/processor/src/main/java/org/mapstruct/ap/util/MapperConfig.java b/processor/src/main/java/org/mapstruct/ap/util/MapperConfig.java index 14a0c5320..d486886bc 100644 --- a/processor/src/main/java/org/mapstruct/ap/util/MapperConfig.java +++ b/processor/src/main/java/org/mapstruct/ap/util/MapperConfig.java @@ -78,6 +78,10 @@ public class MapperConfig { return new ArrayList( uses ); } + public List imports() { + return mapperPrism.imports(); + } + public String unmappedTargetPolicy() { if ( !ReportingPolicy.valueOf( mapperPrism.unmappedTargetPolicy() ).equals( ReportingPolicy.DEFAULT ) ) { // it is not the default configuration diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/JavaExpressionTest.java b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/JavaExpressionTest.java index f3f50d84e..0e62454f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/JavaExpressionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/JavaExpressionTest.java @@ -18,6 +18,7 @@ */ package org.mapstruct.ap.test.source.expressions.java; +import org.mapstruct.ap.test.source.expressions.java.mapper.TimeAndFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapper.java index 50e56d600..0439f2769 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapper.java @@ -18,6 +18,7 @@ */ package org.mapstruct.ap.test.source.expressions.java; +import org.mapstruct.ap.test.source.expressions.java.mapper.TimeAndFormat; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; @@ -27,22 +28,20 @@ import org.mapstruct.factory.Mappers; /** * @author Sjaak Derksen */ -@Mapper +@Mapper( imports = TimeAndFormat.class ) public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings( { - @Mapping( target = "timeAndFormat", expression = "java( new org.mapstruct.ap.test.source.expressions.java." - + "TimeAndFormat( s.getTime(), s.getFormat() ))" ), + @Mapping( target = "timeAndFormat", expression = "java( new TimeAndFormat( s.getTime(), s.getFormat() ))" ), @Mapping( target = "anotherProp", ignore = true ) } ) - Target sourceToTarget(Source s); + Target sourceToTarget( Source s ); @Mappings( { - @Mapping( target = "timeAndFormat", expression = "java( new org.mapstruct.ap.test.source.expressions.java." - + "TimeAndFormat( s.getTime(), s.getFormat() ))" ), + @Mapping( target = "timeAndFormat", expression = "java( new TimeAndFormat( s.getTime(), s.getFormat() ))"), @Mapping( target = "anotherProp", ignore = true ) } ) Target sourceToTargetWithMappingTarget(Source s, @MappingTarget Target t); diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapperSeveralSources.java b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapperSeveralSources.java index ed71ba7f0..c589e9568 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapperSeveralSources.java +++ b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/SourceTargetMapperSeveralSources.java @@ -21,21 +21,20 @@ package org.mapstruct.ap.test.source.expressions.java; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; +import org.mapstruct.ap.test.source.expressions.java.mapper.TimeAndFormat; import org.mapstruct.factory.Mappers; /** * @author Sjaak Derksen */ -@Mapper +@Mapper( imports = TimeAndFormat.class ) public interface SourceTargetMapperSeveralSources { - SourceTargetMapperSeveralSources INSTANCE = Mappers.getMapper( SourceTargetMapperSeveralSources.class ); @Mappings( { - @Mapping( target = "timeAndFormat", expression = "java( new org.mapstruct.ap.test.source.expressions.java." - + "TimeAndFormat( s.getTime(), s.getFormat() ))" ), + @Mapping( target = "timeAndFormat", expression = "java( new TimeAndFormat( s.getTime(), s.getFormat() ))" ), @Mapping( source = "anotherProp", target = "anotherProp" ) } ) - Target sourceToTarget(Source s, Source2 s1); + Target sourceToTarget( Source s, Source2 s1 ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/Target.java b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/Target.java index 639c6dae4..1c1951503 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/Target.java @@ -18,6 +18,8 @@ */ package org.mapstruct.ap.test.source.expressions.java; +import org.mapstruct.ap.test.source.expressions.java.mapper.TimeAndFormat; + /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/TimeAndFormat.java b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/mapper/TimeAndFormat.java similarity index 95% rename from processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/TimeAndFormat.java rename to processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/mapper/TimeAndFormat.java index d5c9f5a5d..3c6288076 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/TimeAndFormat.java +++ b/processor/src/test/java/org/mapstruct/ap/test/source/expressions/java/mapper/TimeAndFormat.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.mapstruct.ap.test.source.expressions.java; +package org.mapstruct.ap.test.source.expressions.java.mapper; import java.util.Date;