diff --git a/docs/README.md b/docs/README.md index 5743b69..5e31af0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,23 +56,21 @@ copyright: false io.github.linpeilie mapstruct-plus-spring-boot-starter - 1.2.5 + 1.3.0 ``` - gradle ```groovy -implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.2.5' +implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.0' ``` ## 更新日志 -### 1.2.5 +### 1.3.0 -- fix: 解决 MapConvertMapperAdapter 编译警告问题 -- feat: 增加 `nullValueMappingStrategy` 和 `nullValuePropertyMappingStrategy` 配置项 -- feat: 适配 solon +- fix: 解决本地开发时 IDEA 编译或者运行时报错等与预期不一致的问题 …… diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index 5092c14..8c14962 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -23,6 +23,57 @@ public class MapStructPlusConfiguration { } ``` +------------------------------------------------------------------- + +除此之外,配置属性还支持**增加编译参数**的方式,以 `-Akey=value` 的形式,传递给编译器。 + +例如,使用 Maven 时,可以在 `maven-compiler-plugin` 插件配置中,使用 `compilerArgs` 属性来配置传递,例如: + +**且使用该方式配置优先级更高**,即,当该方式和配置类同时存在时,以该方式配置的属性为准。该功能从 `1.3.0` 开始支持。 + +:::warning +**建议使用该方式来配置,因为本地开发时,修改类时,IDEA 会只对修改的类进行部分编译,无法获取到配置类,所以可能会出现与预想编译结果不同的问题,但执行 mvn clean package 又变为正常**。 +::: + +```xml + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.projectlombok + lombok + ${lombok.version} + + + io.github.linpeilie + mapstruct-plus-processor + ${mapstruct-plus.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + -Amapstruct.plus.mapperPackage=com.tutelary.mapper + -Amapstruct.plus.adapterClassName=DemoConvertMapperAdapter1 + -Amapstruct.plus.adapterPackage=io.github.linpeilie.adapter + -Amapstruct.plus.mapAdapterClassName=DemoMapConvertMapperAdapter + + + + + +``` + ## 配置项 ### mapperPackage @@ -30,6 +81,7 @@ public class MapStructPlusConfiguration { - **说明**:生成的 Mapper 转换接口的包名 - **类型**:`String` - **默认值**:默认生成在要转换的类同包名下 +- **对应编译参数**:`-Amapstruct.plus.mapperPackage` ### unmappedSourcePolicy @@ -40,6 +92,7 @@ public class MapStructPlusConfiguration { - `WARN`:打印警告日志 - `ERROR`:抛出异常 - **默认值**:`IGNORE` +- **对应编译参数**:`mapstruct.plus.unmappedSourcePolicy` ### unmappedTargetPolicy @@ -50,6 +103,7 @@ public class MapStructPlusConfiguration { - `WARN`:打印警告日志 - `ERROR`:抛出异常 - **默认值**:`IGNORE` +- **对应编译参数**:`mapstruct.plus.unmappedTargetPolicy` ### nullValueMappingStrategy @@ -59,6 +113,7 @@ public class MapStructPlusConfiguration { - `RETURN_NULL`:返回空值 - `RETURN_DEFAULT`:返回默认值 - **默认值**:`RETURN_NULL` +- **对应编译参数**:`mapstruct.plus.nullValueMappingStrategy` ### nullValuePropertyMappingStrategy @@ -69,6 +124,7 @@ public class MapStructPlusConfiguration { - `SET_TO_DEFAULT`:设置为默认值 - `IGNORE`:忽略 - **默认值**:`SET_TO_NULL` +- **对应编译参数**:`mapstruct.plus.nullValuePropertyMappingStrategy` ### builder @@ -80,6 +136,9 @@ public class MapStructPlusConfiguration { - **默认值**: - `buildMethod`:`build` - `disableBuilder`:`true` +- **分别对应的编译参数**: + - `mapstruct.plus.builder.buildMethod` + - `mapstruct.plus.builder.disableBuilder` ### adapterPackage @@ -88,6 +147,7 @@ public class MapStructPlusConfiguration { - **说明**:ConvertAdapterClass 和 MapConvertMapperAdapter 的包名 - **类型**:`String` - **默认值**:io.github.linpeilie +- **对应编译参数**:`mapstruct.plus.adapterPackage` ### adapterClassName @@ -96,6 +156,7 @@ public class MapStructPlusConfiguration { - **说明**:ConvertAdapterClass 类名 - **类型**:`String` - **默认值**:ConvertMapperAdapter +- **对应编译参数**:`mapstruct.plus.adapterClassName` ### mapAdapterClassName @@ -103,4 +164,5 @@ public class MapStructPlusConfiguration { - **说明**:MapConvertMapperAdapter 类名 - **类型**:`String` -- **默认值**:MapConvertMapperAdapter \ No newline at end of file +- **默认值**:MapConvertMapperAdapter +- **对应编译参数**:`mapstruct.plus.mapAdapterClassName` \ No newline at end of file diff --git a/docs/guide/faq.md b/docs/guide/faq.md index e84dc3f..0b10dfc 100644 --- a/docs/guide/faq.md +++ b/docs/guide/faq.md @@ -135,4 +135,8 @@ dependencies { annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version} annotationProcessor group: 'org.projectlombok', name: 'lombok-mapstruct-binding', version: '0.2.0' } -``` \ No newline at end of file +``` + +## 本地开发时,修改类后启动报错,mvn clean compile 后又恢复正常 + +该问题是由于 IDEA 部分编译导致没有找到配置类导致的,建议先更新 1.3.0,更换配置方式,详情可以查看[指南 - 配置](/guide/configuration.html) \ No newline at end of file diff --git a/docs/release/log.md b/docs/release/log.md index ad18236..93d734a 100644 --- a/docs/release/log.md +++ b/docs/release/log.md @@ -6,6 +6,10 @@ category: description: MapStructPlus release log --- +### 1.3.0 + +- fix: 解决本地开发时 IDEA 编译或者运行时报错等与预期不一致的问题 + ### 1.2.5 - fix: 解决 MapConvertMapperAdapter 编译警告问题 diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java index c636393..239026e 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java @@ -66,30 +66,27 @@ import static io.github.linpeilie.processor.Constants.COMPONENT_MODEL_CONFIG_ANN import static io.github.linpeilie.processor.Constants.MAPPER_ANNOTATION; import static io.github.linpeilie.processor.Constants.MAPPER_CONFIG_ANNOTATION; import static javax.tools.Diagnostic.Kind.ERROR; +import static io.github.linpeilie.processor.ProcessorOptions.*; @SupportedAnnotationTypes({AUTO_MAPPER_ANNOTATION, AUTO_MAPPERS_ANNOTATION, AUTO_MAP_MAPPER_ANNOTATION, AUTO_ENUM_MAPPER_ANNOTATION, MAPPER_CONFIG_ANNOTATION, COMPONENT_MODEL_CONFIG_ANNOTATION, MAPPER_ANNOTATION}) @SupportedOptions({ - AutoMapperProcessor.MAPPER_PACKAGE, - AutoMapperProcessor.ADAPTER_PACKAGE, - AutoMapperProcessor.ADAPTER_CLASS_NAME, - AutoMapperProcessor.MAP_ADAPTER_CLASS_NAME, + MAPPER_PACKAGE, + UNMAPPED_SOURCE_POLICY, + UNMAPPED_TARGET_POLICY, + NULL_VALUE_MAPPING_STRATEGY, + NULL_VALUE_PROPERTY_MAPPING_STRATEGY, + BUILDER_BUILD_METHOD, + BUILDER_DISABLE_BUILDER, + ADAPTER_PACKAGE, + ADAPTER_CLASS_NAME, + MAP_ADAPTER_CLASS_NAME, }) public class AutoMapperProcessor extends AbstractProcessor { private static final ClassName MAPPING_DEFAULT_TARGET = ClassName.get("io.github.linpeilie", "DefaultMapping"); - protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel"; - - protected static final String MAPPER_PACKAGE = "mapstruct.plus.mapperPackage"; - - protected static final String ADAPTER_PACKAGE = "mapstruct.plus.adapterPackage"; - - protected static final String ADAPTER_CLASS_NAME = "mapstruct.plus.adapterClassName"; - - protected static final String MAP_ADAPTER_CLASS_NAME = "mapstruct.plus.mapAdapterClassName"; - private final AutoMapperGenerator mapperGenerator; private AbstractAdapterMapperGenerator adapterMapperGenerator; @@ -356,30 +353,12 @@ public class AutoMapperProcessor extends AbstractProcessor { } private void loadCompilerArgs() { - String componentModel = processingEnv.getOptions().get(DEFAULT_COMPONENT_MODEL); - if (StrUtil.isNotEmpty(componentModel)) { - AutoMapperProperties.setComponentModel(componentModel); - } - final String mapperPackage = processingEnv.getOptions().get(MAPPER_PACKAGE); - if (StrUtil.isNotEmpty(mapperPackage)) { - AutoMapperProperties.setMapperPackage(mapperPackage); - } - final String adapterPackage = processingEnv.getOptions().get(ADAPTER_PACKAGE); - if (StrUtil.isNotEmpty(adapterPackage)) { - AutoMapperProperties.setAdapterPackage(adapterPackage); - } - final String adapterClassName = processingEnv.getOptions().get(ADAPTER_CLASS_NAME); - if (StrUtil.isNotEmpty(adapterClassName)) { - AutoMapperProperties.setAdapterClassName(adapterClassName); - } - final String mapAdapterClassName = processingEnv.getOptions().get(MAP_ADAPTER_CLASS_NAME); - if (StrUtil.isNotEmpty(mapAdapterClassName)) { - AutoMapperProperties.setMapAdapterClassName(mapAdapterClassName); - } - } - - private String getPackageName(Element element) { - return String.valueOf(processingEnv.getElementUtils().getPackageOf(element).getQualifiedName()); + ProcessorOptions.optionConsumers().forEach((key, consumer) -> { + final String value = processingEnv.getOptions().get(key); + if (StrUtil.isNotEmpty(value)) { + consumer.accept(value); + } + }); } private void processAutoMapperAnnotation(final RoundEnvironment roundEnv, final TypeElement annotation) { @@ -522,21 +501,6 @@ public class AutoMapperProcessor extends AbstractProcessor { return buildAutoMapperMetadata(autoMapperAnnotation, ele); } - private boolean hasReverseAutoMapping(Element ele) { - TypeElement typeElement = (TypeElement) ele; - if (!typeElement.getKind().isClass()) { - return false; - } - return typeElement.getEnclosedElements() - .stream().anyMatch(e -> { - if (e.getKind() != ElementKind.FIELD) { - return false; - } - return e.getAnnotation(ReverseAutoMapping.class) != null - || e.getAnnotation(ReverseAutoMappings.class) != null; - }); - } - private boolean isTargetFieldMapping(ClassName target, AutoMappingMetadata mappingMetadata) { if (MAPPING_DEFAULT_TARGET.reflectionName().contentEquals(mappingMetadata.getTargetClass().reflectionName())) { return true; diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java new file mode 100644 index 0000000..55e6df7 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java @@ -0,0 +1,57 @@ +package io.github.linpeilie.processor; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; + +public class ProcessorOptions { + + public static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel"; + + public static final String MAPPER_PACKAGE = "mapstruct.plus.mapperPackage"; + + public static final String UNMAPPED_SOURCE_POLICY = "mapstruct.plus.unmappedSourcePolicy"; + + public static final String UNMAPPED_TARGET_POLICY = "mapstruct.plus.unmappedTargetPolicy"; + + public static final String NULL_VALUE_MAPPING_STRATEGY = "mapstruct.plus.nullValueMappingStrategy"; + + public static final String NULL_VALUE_PROPERTY_MAPPING_STRATEGY = "mapstruct.plus.nullValuePropertyMappingStrategy"; + + public static final String BUILDER_BUILD_METHOD = "mapstruct.plus.builder.buildMethod"; + + public static final String BUILDER_DISABLE_BUILDER = "mapstruct.plus.builder.disableBuilder"; + + public static final String ADAPTER_PACKAGE = "mapstruct.plus.adapterPackage"; + + public static final String ADAPTER_CLASS_NAME = "mapstruct.plus.adapterClassName"; + + public static final String MAP_ADAPTER_CLASS_NAME = "mapstruct.plus.mapAdapterClassName"; + + public static Map> optionConsumers() { + final Map> consumerMap = new HashMap<>(); + + consumerMap.put(DEFAULT_COMPONENT_MODEL, AutoMapperProperties::setComponentModel); + + consumerMap.put(MAPPER_PACKAGE, AutoMapperProperties::setMapperPackage); + consumerMap.put(UNMAPPED_SOURCE_POLICY, value -> AutoMapperProperties.setUnmappedSourcePolicy(ReportingPolicy.valueOf(value))); + consumerMap.put(UNMAPPED_TARGET_POLICY, value -> AutoMapperProperties.setUnmappedTargetPolicy(ReportingPolicy.valueOf(value))); + consumerMap.put(NULL_VALUE_MAPPING_STRATEGY, + value -> AutoMapperProperties.setNullValueMappingStrategy(NullValueMappingStrategy.valueOf(value))); + consumerMap.put(NULL_VALUE_PROPERTY_MAPPING_STRATEGY, + value -> AutoMapperProperties.setNullValuePropertyMappingStrategy( + NullValuePropertyMappingStrategy.valueOf(value) + )); + consumerMap.put(BUILDER_BUILD_METHOD, AutoMapperProperties::setBuildMethod); + consumerMap.put(BUILDER_DISABLE_BUILDER, + value -> AutoMapperProperties.setDisableBuilder(Boolean.parseBoolean(value))); + consumerMap.put(ADAPTER_PACKAGE, AutoMapperProperties::setAdapterPackage); + consumerMap.put(ADAPTER_CLASS_NAME, AutoMapperProperties::setAdapterClassName); + consumerMap.put(MAP_ADAPTER_CLASS_NAME, AutoMapperProperties::setMapAdapterClassName); + return consumerMap; + } + +}