Merge pull request #56 from linpeilie/1.3.6

1.3.6
This commit is contained in:
easii 2024-01-07 17:14:55 +08:00 committed by GitHub
commit ede43b83ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 334 additions and 41 deletions

View File

@ -0,0 +1,22 @@
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 30
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -62,36 +62,31 @@ footer:
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
<version>1.3.5</version>
<version>1.3.6</version>
</dependency>
```
- gradle
```groovy
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.5'
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.6'
```
## 更新日志
### 1.3.6
- 兼容内部类转换
- feature : AutoMapping 注解中的 targetClass 支持配置父类
- [issue#I8QPRO](https://gitee.com/easii/mapstruct-plus/issues/I8QPRO) : 框架自动生成的 AutoMapperConfig 和 AutoMapMapper 包和类名支持配置
- [issue#I8T7EF](https://gitee.com/easii/mapstruct-plus/issues/I8T7EF) : 支持在父类中配置的 AutoMapping 注解
### 1.3.5
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;
- AutoMapping、ReverseAutoMapping 支持 defaultExpression 和 conditionExpression 属性
### 1.3.4
……什么都没更新腾讯云maven源同步的jar有问题只能重新发个新包
### 1.3.3
- fixbug: 修复 win JDK8 编译报错问题
### 1.3.2
- 不可变对象支持,可以使用任意包下的 `Immutable` 标注类型为不可变类
- 全面适配 IDEA 部分编译问题,使用更加流畅丝滑
……
## 代码仓库

View File

@ -58,32 +58,30 @@ fotter:
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
<version>1.3.5</version>
<version>1.3.6</version>
</dependency>
```
- gradle
```groovy
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.5'
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.6'
```
## Change Log
### 1.3.6
- Compatible with internal class conversion.
- The targetClass in the AutoMapping annotation supports configuring the parent class.
- AutoMapperConfig and AutoMapMapperConfig package and class name generated automatically by the framework support configuration.
- Supports AutoMapping annotations configured in the parent class.
### 1.3.5
- `@AutoMapping``@ReversedAutoMapping` support is configured on top of methods.
- `@AutoMapping``@ReverseAutoMapping` support the defaultExpression and conditionExpression properties
### 1.3.3
- fixbug: fixed compilation error on win jdk8
### 1.3.2
- Support Immutable object, you can use the `@Immutable` annotation type under any package as an immutable class
- fully adapt the IDEA part of the compilation problem, use more smooth silky
……
## Code Warehouse

View File

@ -163,4 +163,31 @@ eg:
- **Description**the class name of MapConvertMapperAdapter
- **Type**`String`
- **Default**MapConvertMapperAdapter
- **Compile Parameter**`-Amapstruct.plus.mapAdapterClassName`
- **Compile Parameter**`-Amapstruct.plus.mapAdapterClassName`
### autoConfigPackage
> since `1.3.6`
- **Description**The package path of the automatically generated configuration class --- `AutoMapperConfig`/`AutoMapMapperConfig` --- from the MapStructPlus framework.
- **Type**`String`
- **Default**io.github.linpeilie
- **Compile Parameter**`-Amapstruct.plus.autoConfigPackage`
### autoMapperConfigClassName
> since `1.3.6`
- **Description**MapStructPlus framework automatically generates the name of the configuration class(transformation between configuration objects)
- **Type**`String`
- **Default**AutoMapperConfig
- **Compile Parameter**`-Amapstruct.plus.autoMapperConfigClassName`
### autoMapMapperConfigClassName
> since `1.3.6`
- **Description**MapStructPlus framework automatically generates the name of the configuration class(which configures the transformation between the Map and the object)
- **Type**`String`
- **Default**AutoMapMapperConfig
- **Compile Parameter**`-Amapstruct.plus.autoMapMapperConfigClassName`

View File

@ -34,6 +34,12 @@ when using the `@AutoMapping` annotation, configure the `targetClass` attribute
If `targetClass` is not specified when the `@AutoMapping` annotation is configured, the current rule applies to all class conversions.
:::info
`targetClass` also supports the configuration parent class, which applies to this rule when the target class is a subclass of the configured `targetClass`.
> This feature is supported from 1.3.6
:::
eg
```java

View File

@ -6,6 +6,13 @@ category:
description: MapStructPlus release log
---
### 1.3.6
- Compatible with internal class conversion.
- The targetClass in the AutoMapping annotation supports configuring the parent class.
- AutoMapperConfig and AutoMapMapperConfig package and class name generated automatically by the framework support configuration.
- Supports AutoMapping annotations configured in the parent class.
### 1.3.5
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;

View File

@ -160,4 +160,31 @@ public class MapStructPlusConfiguration {
- **说明**MapConvertMapperAdapter 类名
- **类型**`String`
- **默认值**MapConvertMapperAdapter
- **对应编译参数**`-Amapstruct.plus.mapAdapterClassName`
- **对应编译参数**`-Amapstruct.plus.mapAdapterClassName`
### autoConfigPackage
> since `1.3.6`
- **说明**MapStructPlus 框架自动生成的配置类 --- `AutoMapperConfig`/`AutoMapMapperConfig` 所在的包路径
- **类型**`String`
- **默认值**io.github.linpeilie
- **对应编译参数**`-Amapstruct.plus.autoConfigPackage`
### autoMapperConfigClassName
> since `1.3.6`
- **说明**MapStructPlus 框架自动生成的的配置类(配置对象之间的转换)类名
- **类型**`String`
- **默认值**AutoMapperConfig
- **对应编译参数**`-Amapstruct.plus.autoMapperConfigClassName`
### autoMapMapperConfigClassName
> since `1.3.6`
- **说明**MapStructPlus 框架自动生成的配置类配置Map与对象之间的转换类名
- **类型**`String`
- **默认值**AutoMapMapperConfig
- **对应编译参数**`-Amapstruct.plus.autoMapMapperConfigClassName`

View File

@ -33,6 +33,13 @@ public class User {
如果在配置 `@AutoMapping` 注解时,没有指定 `targetClass` 时,则当前规则,会应用于与所有类转换。
:::info
`targetClass` 同时支持配置父类,当目标类是所配置的 `targetClass` 的子类时,即可应用于该规则。
> 该特性从 1.3.6 开始支持
:::
例如:
```java

View File

@ -6,6 +6,13 @@ category:
description: MapStructPlus release log
---
### 1.3.6
- 兼容内部类转换
- feature : AutoMapping 注解中的 targetClass 支持配置父类
- [issue#I8QPRO](https://gitee.com/easii/mapstruct-plus/issues/I8QPRO) : 框架自动生成的 AutoMapperConfig 和 AutoMapMapper 包和类名支持配置
- [issue#I8T7EF](https://gitee.com/easii/mapstruct-plus/issues/I8T7EF) : 支持在父类中配置的 AutoMapping 注解
### 1.3.5
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;

View File

@ -18,7 +18,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mapstruct.version>1.5.1.Final</mapstruct.version>
<mapstruct-plus.version>1.3.5</mapstruct-plus.version>
<mapstruct-plus.version>1.3.6</mapstruct-plus.version>
<lombok.version>1.18.22</lombok.version>
</properties>

View File

@ -4,6 +4,9 @@ import io.github.linpeilie.annotations.MapperConfig;
@MapperConfig(adapterClassName = "DemoConvertMapperAdapter",
adapterPackage = "io.github.linpeilie.adapter",
mapAdapterClassName = "DemoMapConvertMapperAdapter")
mapAdapterClassName = "DemoMapConvertMapperAdapter",
autoConfigPackage = "cn.easii",
autoMapperConfigClassName = "EasiiAutoMapperConfig",
autoMapMapperConfigClassName = "EasiiAutoMapMapperConfig")
public class MapStructPlusConfiguration {
}

View File

@ -0,0 +1,12 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapping;
import lombok.Data;
@Data
public class A {
@AutoMapping(target = "createBy.id")
private Long createBy;
}

View File

@ -0,0 +1,13 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMapping;
import lombok.Data;
@AutoMapper(target = BB.class)
@Data
public class AA extends A {
private String name;
}

View File

@ -0,0 +1,10 @@
package io.github.linpeilie.model;
import lombok.Data;
@Data
public class B {
private C createBy;
}

View File

@ -0,0 +1,10 @@
package io.github.linpeilie.model;
import lombok.Data;
@Data
public class BB extends B {
private String name;
}

View File

@ -0,0 +1,12 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapping;
import lombok.Data;
@Data
public class BaseDTO {
@AutoMapping(target = "success", targetClass = BaseVO.class, ignore = true)
private Boolean success;
}

View File

@ -0,0 +1,12 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapping;
import lombok.Data;
@Data
public class BaseVO {
@AutoMapping(target = "success", targetClass = BaseDTO.class, ignore = true)
private Integer success;
}

View File

@ -0,0 +1,10 @@
package io.github.linpeilie.model;
import lombok.Data;
@Data
public class C {
private Long id;
}

View File

@ -17,4 +17,9 @@ public class Car {
@AutoMapping(target = "wheels", ignore = true)
private Wheels wheels;
@Data
public static class InnerClass {
private String f;
}
}

View File

@ -1,18 +1,22 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import io.github.linpeilie.annotations.AutoMapping;
import java.util.Date;
import lombok.Data;
@Data
@AutoMapper(target = Goods.class)
public class GoodsDto {
@AutoMappers({
@AutoMapper(target = Goods.class),
@AutoMapper(target = GoodsVo.class)
})
public class GoodsDto extends BaseDTO {
@AutoMapping(target = "takeDownTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@AutoMapping(targetClass = Goods.class, target = "takeDownTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date takeDownTime;
@AutoMapping(target = "price", numberFormat = "$#.00")
@AutoMapping(targetClass = Goods.class, target = "price", numberFormat = "$#.00")
private int price;
private Integer state;

View File

@ -1,9 +1,11 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
@Data
public class GoodsVo {
@AutoMapper(target = GoodsDto.class)
public class GoodsVo extends BaseVO {
private Integer price;

View File

@ -0,0 +1,12 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
@Data
@AutoMapper(target = Car.InnerClass.class)
public class InnerClassTarget {
private String f;
}

View File

@ -399,6 +399,15 @@ public class AutoMapperProcessor extends AbstractProcessor {
if (StrUtil.isNotEmpty(mapperConfig.mapAdapterClassName())) {
AutoMapperProperties.setMapAdapterClassName(mapperConfig.mapAdapterClassName());
}
if (StrUtil.isNotEmpty(mapperConfig.autoConfigPackage())) {
AutoMapperProperties.setAutoConfigPackage(mapperConfig.autoConfigPackage());
}
if (StrUtil.isNotEmpty(mapperConfig.autoMapperConfigClassName())) {
AutoMapperProperties.setAutoMapperConfigClassName(mapperConfig.autoMapperConfigClassName());
}
if (StrUtil.isNotEmpty(mapperConfig.autoMapMapperConfigClassName())) {
AutoMapperProperties.setAutoMapMapperConfigClassName(mapperConfig.autoMapMapperConfigClassName());
}
}
private void refreshProperties(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
@ -621,7 +630,24 @@ public class AutoMapperProcessor extends AbstractProcessor {
if (target.reflectionName().contentEquals(mappingMetadata.getTargetClass().reflectionName())) {
return true;
}
return false;
TypeElement targetTypeElement = classNameToTypeElement(target);
Optional<TypeElement> superClass = getSuperClass(targetTypeElement);
return superClass.filter(typeElement -> isTargetFieldMapping(ClassName.get(typeElement), mappingMetadata))
.isPresent();
}
private Optional<TypeElement> getSuperClass(TypeElement ele) {
TypeMirror superclass = ele.getSuperclass();
if (superclass == null) {
return Optional.empty();
}
if ("java.lang.Object".equals(superclass.toString())) {
return Optional.empty();
}
if (ele.getQualifiedName().contentEquals(superclass.toString())) {
return Optional.empty();
}
return Optional.of((TypeElement) processingEnv.getTypeUtils().asElement(superclass));
}
private AutoMapperMetadata buildAutoMapperMetadata(final AutoMapper autoMapper, final Element ele) {
@ -672,6 +698,11 @@ public class AutoMapperProcessor extends AbstractProcessor {
}
}
}
// super class
getSuperClass(ele)
.ifPresent(superClass -> list.addAll(buildFieldReverseMappingMetadata(superClass)));
list.removeIf(Objects::isNull);
return list;
}
@ -738,6 +769,10 @@ public class AutoMapperProcessor extends AbstractProcessor {
}
}
// add super class AutoMappings
getSuperClass(autoMapperEle)
.ifPresent(superClass -> list.addAll(buildFieldMappingMetadata(superClass)));
list.removeIf(Objects::isNull);
return list;
}
@ -801,6 +836,11 @@ public class AutoMapperProcessor extends AbstractProcessor {
.collect(Collectors.toList());
}
private TypeElement classNameToTypeElement(ClassName className) {
String classNameString = className.toString();
return processingEnv.getElementUtils().getTypeElement(classNameString);
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();

View File

@ -31,6 +31,12 @@ public class AutoMapperProperties {
private static String mapAdapterClassName = DEFAULT_MAP_ADAPTER_CLASS_NAME;
private static String autoConfigPackage = DEFAULT_BASE_PACKAGE;
private static String autoMapperConfigClassName = AUTO_MAPPER_CONFIG_CLASS_NAME;
private static String autoMapMapperConfigClassName = AUTO_MAP_MAPPER_CONFIG_CLASS_NAME;
public static String getMapperPackage() {
return mapperPackage;
}
@ -60,15 +66,27 @@ public class AutoMapperProperties {
}
public static String getConfigPackage() {
return DEFAULT_BASE_PACKAGE;
return autoConfigPackage;
}
public static void setAutoConfigPackage(String autoConfigPackage) {
AutoMapperProperties.autoConfigPackage = autoConfigPackage;
}
public static String getConfigClassName() {
return AUTO_MAPPER_CONFIG_CLASS_NAME;
return autoMapperConfigClassName;
}
public static void setAutoMapperConfigClassName(String autoMapperConfigClassName) {
AutoMapperProperties.autoMapperConfigClassName = autoMapperConfigClassName;
}
public static String getMapConfigClassName() {
return AUTO_MAP_MAPPER_CONFIG_CLASS_NAME;
return autoMapMapperConfigClassName;
}
public static void setAutoMapMapperConfigClassName(String autoMapMapperConfigClassName) {
AutoMapperProperties.autoMapMapperConfigClassName = autoMapMapperConfigClassName;
}
public static String getComponentModel() {

View File

@ -33,6 +33,12 @@ public class ProcessorOptions {
public static final String MAP_ADAPTER_CLASS_NAME = "mapstruct.plus.mapAdapterClassName";
public static final String AUTO_CONFIG_PACKAGE = "mapstruct.plus.autoConfigPackage";
public static final String AUTO_MAPPER_CONFIG_CLASS_NAME = "mapstruct.plus.autoMapperConfigClassName";
public static final String AUTO_MAP_MAPPER_CONFIG_CLASS_NAME = "mapstruct.plus.autoMapMapperConfigClassName";
public static Map<String, Consumer<String>> optionConsumers() {
final Map<String, Consumer<String>> consumerMap = new HashMap<>();
@ -53,6 +59,9 @@ public class ProcessorOptions {
consumerMap.put(ADAPTER_PACKAGE, AutoMapperProperties::setAdapterPackage);
consumerMap.put(ADAPTER_CLASS_NAME, AutoMapperProperties::setAdapterClassName);
consumerMap.put(MAP_ADAPTER_CLASS_NAME, AutoMapperProperties::setMapAdapterClassName);
consumerMap.put(AUTO_CONFIG_PACKAGE, AutoMapperProperties::setAutoConfigPackage);
consumerMap.put(AUTO_MAPPER_CONFIG_CLASS_NAME, AutoMapperProperties::setAutoMapperConfigClassName);
consumerMap.put(AUTO_MAP_MAPPER_CONFIG_CLASS_NAME, AutoMapperProperties::setAutoMapMapperConfigClassName);
return consumerMap;
}

View File

@ -26,6 +26,7 @@ import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import org.apache.commons.lang3.StringUtils;
import static io.github.linpeilie.processor.Constants.*;
@ -90,7 +91,7 @@ public class AutoMapperGenerator {
private boolean classIsImmutable(ProcessingEnvironment processingEnv, ClassName className) {
final TypeElement targetElement = processingEnv.getElementUtils()
.getTypeElement(className.packageName() + "." + className.simpleName());
.getTypeElement(className.reflectionName().replaceAll("\\$", "."));
final List<? extends AnnotationMirror> annotationMirrors = targetElement.getAnnotationMirrors();
for (AnnotationMirror annotationMirror : annotationMirrors) {
if (annotationMirror.getAnnotationType().asElement().getSimpleName().contentEquals("Immutable")) {

View File

@ -74,4 +74,28 @@ public @interface MapperConfig {
*/
String mapAdapterClassName() default "";
/**
* MapStructPlus 所生成的配置类(AutoMapperConfig/AutoMapMapperConfig)包路径
* <br>
* 默认包路径为 io.github.linpeilie
* @return AutoMapperConfig / AutoMapMapperConfig 包路径
*/
String autoConfigPackage() default "";
/**
* MapStructPlus 所生成的配置类转换的配置类名
* <br>
* 默认类名为 AutoMapperConfig
* @return AutoMapperConfig 类名
*/
String autoMapperConfigClassName() default "";
/**
* MapStructPlus 所生成的配置 Map 与对象转换的配置类名
* <br>
* 默认类名为 AutoMapMapperConfig
* @return AutoMapMapperConfig 类名
*/
String autoMapMapperConfigClassName() default "";
}

View File

@ -17,7 +17,7 @@
</modules>
<properties>
<mapstruct-plus.version>1.3.5</mapstruct-plus.version>
<mapstruct-plus.version>1.3.6</mapstruct-plus.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>