From 4223e3ab812a496aeb31b67a63737fb648bd2ddb Mon Sep 17 00:00:00 2001 From: Tomas Poledny Date: Thu, 5 Nov 2020 14:09:30 +0100 Subject: [PATCH] #2255 Add constants for componentModel --- core/src/main/java/org/mapstruct/Mapper.java | 6 +-- .../main/java/org/mapstruct/MapperConfig.java | 2 +- .../java/org/mapstruct/MappingConstants.java | 45 +++++++++++++++++++ .../chapter-4-retrieving-a-mapper.asciidoc | 6 +-- .../chapter-5-data-type-conversions.asciidoc | 2 +- .../cdi/DecoratedSourceTargetMapper.java | 3 +- .../itest/cdi/SourceTargetMapper.java | 3 +- .../jsr330/DecoratedSourceTargetMapper.java | 3 +- .../SecondDecoratedSourceTargetMapper.java | 3 +- .../itest/jsr330/SourceTargetMapper.java | 3 +- .../spring/DecoratedSourceTargetMapper.java | 3 +- .../SecondDecoratedSourceTargetMapper.java | 3 +- .../itest/spring/SourceTargetMapper.java | 3 +- .../ap/internal/gem/MappingConstantsGem.java | 19 ++++++++ .../processor/CdiComponentProcessor.java | 3 +- .../processor/Jsr330ComponentProcessor.java | 3 +- .../processor/MapperServiceProcessor.java | 3 +- .../processor/SpringComponentProcessor.java | 3 +- .../ap/test/bugs/_1395/Issue1395Mapper.java | 4 +- .../ap/test/bugs/_880/Issue880Test.java | 5 ++- .../_880/UsesConfigFromAnnotationMapper.java | 3 +- .../test/decorator/jsr330/PersonMapper.java | 3 +- .../spring/constructor/PersonMapper.java | 3 +- .../decorator/spring/field/PersonMapper.java | 3 +- .../DestinationClassNameWithJsr330Mapper.java | 3 +- .../mapstruct/ap/test/gem/ConstantTest.java | 9 ++++ .../ap/test/imports/SourceTargetMapper.java | 3 +- ...Jsr330DefaultCompileOptionFieldMapper.java | 4 +- ...Jsr330DefaultCompileOptionFieldMapper.java | 3 +- ...rJsr330CompileOptionConstructorMapper.java | 3 +- ...rJsr330CompileOptionConstructorMapper.java | 3 +- .../constructor/ConstructorJsr330Config.java | 4 +- .../CustomerJsr330ConstructorMapper.java | 3 +- .../field/CustomerJsr330FieldMapper.java | 4 +- .../jsr330/field/FieldJsr330Config.java | 3 +- .../_default/CustomerSpringDefaultMapper.java | 3 +- .../_default/GenderSpringDefaultMapper.java | 3 +- ...dSpringCompileOptionConstructorMapper.java | 3 +- ...rSpringCompileOptionConstructorMapper.java | 3 +- ...rSpringCompileOptionConstructorMapper.java | 3 +- .../constructor/ConstructorSpringConfig.java | 4 +- ...CustomerRecordSpringConstructorMapper.java | 3 +- .../CustomerSpringConstructorMapper.java | 3 +- .../field/CustomerSpringFieldMapper.java | 4 +- .../spring/field/FieldSpringConfig.java | 3 +- .../samename/Jsr330SourceTargetMapper.java | 3 +- 46 files changed, 166 insertions(+), 48 deletions(-) diff --git a/core/src/main/java/org/mapstruct/Mapper.java b/core/src/main/java/org/mapstruct/Mapper.java index 233907621..5ed9eab17 100644 --- a/core/src/main/java/org/mapstruct/Mapper.java +++ b/core/src/main/java/org/mapstruct/Mapper.java @@ -35,7 +35,7 @@ import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; *

*

  * // we have MarkMapper (map field "mark" to field "name" to upper case)
- * @Mapper(componentModel = "spring")
+ * @Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
  * public class MarkMapper {
  *     public String mapMark(String mark) {
  *         return mark.toUpperCase();
@@ -43,7 +43,7 @@ import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION;
  * }
  * // we have CarMapper
  * @Mapper(
- *      componentModel = "spring",
+ *      componentModel = MappingConstants.ComponentModel.SPRING,
  *      uses = MarkMapper.class,
  *      injectionStrategy = InjectionStrategy.CONSTRUCTOR)
  * public interface CarMapper {
@@ -148,7 +148,7 @@ public @interface Mapper {
      *
      * @return The component model for the generated mapper.
      */
-    String componentModel() default "default";
+    String componentModel() default MappingConstants.ComponentModel.DEFAULT;
 
     /**
      * Specifies the name of the implementation class. The {@code } will be replaced by the
diff --git a/core/src/main/java/org/mapstruct/MapperConfig.java b/core/src/main/java/org/mapstruct/MapperConfig.java
index d251ff379..ecfd888ca 100644
--- a/core/src/main/java/org/mapstruct/MapperConfig.java
+++ b/core/src/main/java/org/mapstruct/MapperConfig.java
@@ -135,7 +135,7 @@ public @interface MapperConfig {
      *
      * @return The component model for the generated mapper.
      */
-    String componentModel() default "default";
+    String componentModel() default MappingConstants.ComponentModel.DEFAULT;
 
     /**
      * Specifies the name of the implementation class. The {@code } will be replaced by the
diff --git a/core/src/main/java/org/mapstruct/MappingConstants.java b/core/src/main/java/org/mapstruct/MappingConstants.java
index 2c5757038..6e30f08c2 100644
--- a/core/src/main/java/org/mapstruct/MappingConstants.java
+++ b/core/src/main/java/org/mapstruct/MappingConstants.java
@@ -66,4 +66,49 @@ public final class MappingConstants {
      */
     public static final String STRIP_PREFIX_TRANSFORMATION = "stripPrefix";
 
+    /**
+    * Specifies the component model constants to which the generated mapper should adhere.
+    * It can be used with the annotation {@link Mapper#componentModel()} or {@link MapperConfig#componentModel()}
+    *
+    * 

+ * Example: + *

+ *

+    * // Spring component model
+    * @Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+    * 
+ * + * @since 1.5.0 + */ + public static final class ComponentModel { + + private ComponentModel() { + } + + /** + * The mapper uses no component model, instances are typically retrieved + * via {@link org.mapstruct.factory.Mappers#getMapper(java.lang.Class)} + * + */ + public static final String DEFAULT = "default"; + + /** + * The generated mapper is an application-scoped CDI bean and can be retrieved via @Inject + */ + public static final String CDI = "cdi"; + + /** + * The generated mapper is a Spring bean and can be retrieved via @Autowired + * + */ + public static final String SPRING = "spring"; + + /** + * The generated mapper is annotated with @javax.inject.Named and @Singleton, and can be retrieved via @Inject + * + */ + public static final String JSR330 = "jsr330"; + + } + } diff --git a/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc b/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc index 75b5b1029..724b42fbb 100644 --- a/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc +++ b/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc @@ -69,14 +69,14 @@ Note that mappers generated by MapStruct are stateless and thread-safe and thus If you're working with a dependency injection framework such as http://jcp.org/en/jsr/detail?id=346[CDI] (Contexts and Dependency Injection for Java^TM^ EE) or the http://www.springsource.org/spring-framework[Spring Framework], it is recommended to obtain mapper objects via dependency injection and *not* via the `Mappers` class as described above. For that purpose you can specify the component model which generated mapper classes should be based on either via `@Mapper#componentModel` or using a processor option as described in <>. -Currently there is support for CDI and Spring (the latter either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: +Currently there is support for CDI and Spring (the latter either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option and constants are defined in a class `MappingConstants.ComponentModel`. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: .A mapper using the CDI component model ==== [source, java, linenums] [subs="verbatim,attributes"] ---- -@Mapper(componentModel = "cdi") +@Mapper(componentModel = MappingConstants.ComponentModel.CDI) public interface CarMapper { CarDto carToCarDto(Car car); @@ -110,7 +110,7 @@ This can be done by either providing the injection strategy via `@Mapper` or `@M [source, java, linenums] [subs="verbatim,attributes"] ---- -@Mapper(componentModel = "cdi", uses = EngineMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR) +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = EngineMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface CarMapper { CarDto carToCarDto(Car car); } diff --git a/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc b/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc index 9619d0fe2..9978cd3f2 100644 --- a/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc +++ b/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc @@ -405,7 +405,7 @@ public class ReferenceMapper { } } -@Mapper(componentModel = "cdi", uses = ReferenceMapper.class ) +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = ReferenceMapper.class ) public interface CarMapper { Car carDtoToCar(CarDto carDto); diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java index 1787fd3c9..18a57ce25 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java @@ -6,10 +6,11 @@ package org.mapstruct.itest.cdi; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.DecoratedWith; import org.mapstruct.itest.cdi.other.DateMapper; -@Mapper( componentModel = "cdi", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.CDI, uses = DateMapper.class ) public interface DecoratedSourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java index 3a46a2088..eb895f5e5 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java @@ -6,9 +6,10 @@ package org.mapstruct.itest.cdi; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.cdi.other.DateMapper; -@Mapper(componentModel = "cdi", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java index 137f234c2..77f5ec558 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java @@ -6,10 +6,11 @@ package org.mapstruct.itest.jsr330; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.DecoratedWith; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) @DecoratedWith(SourceTargetMapperDecorator.class) public interface DecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java index cdec6dc19..f088e21de 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java @@ -6,10 +6,11 @@ package org.mapstruct.itest.jsr330; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.DecoratedWith; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) @DecoratedWith(SecondSourceTargetMapperDecorator.class) public interface SecondDecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java index c5ba3670f..a96a860da 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java @@ -6,9 +6,10 @@ package org.mapstruct.itest.jsr330; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java index f1bbf87d3..a020ab2b2 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java @@ -6,10 +6,11 @@ package org.mapstruct.itest.spring; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.DecoratedWith; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper( componentModel = "spring", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class ) @DecoratedWith( SourceTargetMapperDecorator.class ) public interface DecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java index 88e290630..7c0426259 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java @@ -6,10 +6,11 @@ package org.mapstruct.itest.spring; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.DecoratedWith; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper( componentModel = "spring", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class ) @DecoratedWith( SecondSourceTargetMapperDecorator.class ) public interface SecondDecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java index 06e4be4d2..e6d6b4633 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java @@ -6,9 +6,10 @@ package org.mapstruct.itest.spring; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper(componentModel = "spring", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java index 685f5a543..5df7fd3f9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java @@ -28,4 +28,23 @@ public final class MappingConstantsGem { public static final String PREFIX_TRANSFORMATION = "prefix"; public static final String STRIP_PREFIX_TRANSFORMATION = "stripPrefix"; + + /** + * Gem for the class {@link org.mapstruct.MappingConstants.ComponentModel} + * + */ + public final class ComponentModelGem { + + private ComponentModelGem() { + } + + public static final String DEFAULT = "default"; + + public static final String CDI = "cdi"; + + public static final String SPRING = "spring"; + + public static final String JSR330 = "jsr330"; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java index a5e345868..74ff2b118 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.Annotation; import org.mapstruct.ap.internal.model.Mapper; @@ -23,7 +24,7 @@ public class CdiComponentProcessor extends AnnotationBasedComponentModelProcesso @Override protected String getComponentModelIdentifier() { - return "cdi"; + return MappingConstantsGem.ComponentModelGem.CDI; } @Override diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java index 4f7b46d64..18a6e4f69 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.Annotation; import org.mapstruct.ap.internal.model.Mapper; @@ -23,7 +24,7 @@ import org.mapstruct.ap.internal.model.Mapper; public class Jsr330ComponentProcessor extends AnnotationBasedComponentModelProcessor { @Override protected String getComponentModelIdentifier() { - return "jsr330"; + return MappingConstantsGem.ComponentModelGem.JSR330; } @Override diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java index f74a84c49..c9e37596f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java @@ -11,6 +11,7 @@ import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import javax.tools.StandardLocation; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.GeneratedType; import org.mapstruct.ap.internal.model.Mapper; import org.mapstruct.ap.internal.model.ServicesEntry; @@ -38,7 +39,7 @@ public class MapperServiceProcessor implements ModelElementProcessor