mirror of
https://gitee.com/easii/mapstruct-plus.git
synced 2025-12-06 17:18:43 +08:00
1.2.5
解决 MapAdapterConvert 告警问题; feature: 适配 solon
This commit is contained in:
parent
957d139d6b
commit
899636e41d
@ -56,7 +56,7 @@ public class User {
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<mapstruct-plus.version>1.2.4</mapstruct-plus.version>
|
||||
<mapstruct-plus.version>1.2.5</mapstruct-plus.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@ -52,14 +52,14 @@ copyright: false
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>1.2.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
- gradle
|
||||
|
||||
```groovy
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.2.4'
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.2.5'
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
@ -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.2.3</mapstruct-plus.version>
|
||||
<mapstruct-plus.version>1.2.5</mapstruct-plus.version>
|
||||
<lombok.version>1.18.22</lombok.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package io.github.linpeilie.processor;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata;
|
||||
import java.io.IOException;
|
||||
@ -39,11 +42,24 @@ public abstract class AbstractAdapterMapperGenerator {
|
||||
return AutoMapperProperties.getAdapterPackage();
|
||||
}
|
||||
|
||||
private TypeName wrapperTypeName(TypeName source) {
|
||||
if (source.isPrimitive() || source.isBoxedPrimitive()) {
|
||||
return source;
|
||||
}
|
||||
if ("java.util.Map".contentEquals(source.toString())) {
|
||||
return ParameterizedTypeName.get((ClassName) source,
|
||||
ClassName.get("java.lang", "String"),
|
||||
ClassName.get("java.lang", "Object"));
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
protected MethodSpec buildProxyMethod(AbstractAdapterMethodMetadata adapterMethodMetadata) {
|
||||
CodeBlock targetCode = adapterMethodMetadata.isStatic() ? CodeBlock.of("return $T.$N($N);",
|
||||
adapterMethodMetadata.getMapper(), adapterMethodMetadata.getMapperMethodName(),
|
||||
"param") : proxyMethodTarget(adapterMethodMetadata);
|
||||
ParameterSpec parameterSpec = ParameterSpec.builder(adapterMethodMetadata.getSource(), "param").build();
|
||||
ParameterSpec parameterSpec = ParameterSpec.builder(
|
||||
wrapperTypeName(adapterMethodMetadata.getSource()), "param").build();
|
||||
return MethodSpec.methodBuilder(adapterMethodMetadata.getMethodName())
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addParameter(parameterSpec)
|
||||
|
||||
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import io.github.linpeilie.ComponentModelConstant;
|
||||
import io.github.linpeilie.annotations.AutoEnumMapper;
|
||||
import io.github.linpeilie.annotations.AutoMapMapper;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
@ -18,6 +19,7 @@ import io.github.linpeilie.processor.generator.AutoEnumMapperGenerator;
|
||||
import io.github.linpeilie.processor.generator.AutoMapperGenerator;
|
||||
import io.github.linpeilie.processor.generator.DefaultAdapterMapperGenerator;
|
||||
import io.github.linpeilie.processor.generator.MapperConfigGenerator;
|
||||
import io.github.linpeilie.processor.generator.SolonAdapterMapperGenerator;
|
||||
import io.github.linpeilie.processor.generator.SpringAdapterMapperGenerator;
|
||||
import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata;
|
||||
import io.github.linpeilie.processor.metadata.AdapterEnumMethodMetadata;
|
||||
@ -71,6 +73,8 @@ 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";
|
||||
|
||||
private final AutoMapperGenerator mapperGenerator;
|
||||
|
||||
private AbstractAdapterMapperGenerator adapterMapperGenerator;
|
||||
@ -133,9 +137,16 @@ public class AutoMapperProcessor extends AbstractProcessor {
|
||||
refreshProperties(annotations, roundEnv);
|
||||
|
||||
// 根据配置生成适配类生成器
|
||||
this.adapterMapperGenerator = AutoMapperProperties.getComponentModel()
|
||||
.contentEquals(
|
||||
MappingConstants.ComponentModel.SPRING) ? new SpringAdapterMapperGenerator() : new DefaultAdapterMapperGenerator();
|
||||
switch (AutoMapperProperties.getComponentModel()) {
|
||||
case MappingConstants.ComponentModel.SPRING:
|
||||
this.adapterMapperGenerator = new SpringAdapterMapperGenerator();
|
||||
break;
|
||||
case ComponentModelConstant.SOLON:
|
||||
this.adapterMapperGenerator = new SolonAdapterMapperGenerator();
|
||||
break;
|
||||
default:
|
||||
this.adapterMapperGenerator = new DefaultAdapterMapperGenerator();
|
||||
}
|
||||
|
||||
// AutoMapMapper
|
||||
annotations.stream()
|
||||
@ -301,7 +312,8 @@ public class AutoMapperProcessor extends AbstractProcessor {
|
||||
AutoMapperProperties.setUnmappedSourcePolicy(mapperConfig.unmappedSourcePolicy());
|
||||
AutoMapperProperties.setUnmappedTargetPolicy(mapperConfig.unmappedTargetPolicy());
|
||||
AutoMapperProperties.setNullValueMappingStrategy(mapperConfig.nullValueMappingStrategy());
|
||||
AutoMapperProperties.setNullValuePropertyMappingStrategy(mapperConfig.nullValuePropertyMappingStrategy());
|
||||
AutoMapperProperties.setNullValuePropertyMappingStrategy(
|
||||
mapperConfig.nullValuePropertyMappingStrategy());
|
||||
AutoMapperProperties.setBuildMethod(mapperConfig.builder().buildMethod());
|
||||
AutoMapperProperties.setDisableBuilder(mapperConfig.builder().disableBuilder());
|
||||
if (StrUtil.isNotEmpty(mapperConfig.adapterPackage())) {
|
||||
@ -314,16 +326,20 @@ public class AutoMapperProcessor extends AbstractProcessor {
|
||||
AutoMapperProperties.setMapAdapterClassName(mapperConfig.mapAdapterClassName());
|
||||
}
|
||||
});
|
||||
// 构建参数
|
||||
String componentModel = processingEnv.getOptions().get(DEFAULT_COMPONENT_MODEL);
|
||||
AutoMapperProperties.setComponentModel(componentModel);
|
||||
|
||||
annotations.stream()
|
||||
.filter(this::isComponentModelConfigAnnotation)
|
||||
.findFirst()
|
||||
.flatMap(annotation -> roundEnv.getElementsAnnotatedWith(annotation).stream().findFirst())
|
||||
.ifPresent(element -> {
|
||||
if (StrUtil.isEmpty(componentModel)) {
|
||||
final ComponentModelConfig componentModelConfig = element.getAnnotation(ComponentModelConfig.class);
|
||||
String componentModel = StringUtils.isEmpty(
|
||||
componentModelConfig.componentModel()) ? "default" : componentModelConfig.componentModel();
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "component model " + componentModel);
|
||||
AutoMapperProperties.setComponentModel(componentModel);
|
||||
String componentModelByAnnotation = componentModelConfig.componentModel();
|
||||
AutoMapperProperties.setComponentModel(componentModelByAnnotation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
package io.github.linpeilie.processor.generator;
|
||||
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.github.linpeilie.processor.AbstractAdapterMapperGenerator;
|
||||
import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
public abstract class IocAdapterMapperGenerator extends AbstractAdapterMapperGenerator {
|
||||
|
||||
protected abstract AnnotationSpec componentAnnotation();
|
||||
|
||||
protected abstract List<AnnotationSpec> injectAnnotations();
|
||||
|
||||
@Override
|
||||
protected TypeSpec createTypeSpec(final Collection<AbstractAdapterMethodMetadata> adapterMethods,
|
||||
final String adapterClassName) {
|
||||
TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder(ClassName.get(adapterPackage(), adapterClassName))
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addAnnotation(componentAnnotation());
|
||||
|
||||
adapterMethods.stream()
|
||||
.filter(adapterMethodMetadata -> !adapterMethodMetadata.isStatic())
|
||||
.map(AbstractAdapterMethodMetadata::getMapper)
|
||||
.distinct()
|
||||
.forEach(mapper -> adapterBuilder.addField(buildMapperField(mapper)));
|
||||
|
||||
adapterMethods.forEach(adapterMethod -> adapterBuilder
|
||||
.addMethod(buildProxyMethod(adapterMethod)));
|
||||
|
||||
return adapterBuilder.build();
|
||||
}
|
||||
|
||||
private FieldSpec buildMapperField(ClassName mapper) {
|
||||
return FieldSpec.builder(mapper, firstWordToLower(mapper.simpleName()), Modifier.PRIVATE)
|
||||
.addAnnotations(injectAnnotations())
|
||||
.build();
|
||||
}
|
||||
|
||||
private String firstWordToLower(String str) {
|
||||
return str.substring(0, 1).toLowerCase() + str.substring(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CodeBlock proxyMethodTarget(AbstractAdapterMethodMetadata adapterMethodMetadata) {
|
||||
return CodeBlock.builder()
|
||||
.add("return $N.$N($N);", firstWordToLower(adapterMethodMetadata.getMapper().simpleName()),
|
||||
adapterMethodMetadata.getMapperMethodName(),
|
||||
"param")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package io.github.linpeilie.processor.generator;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class SolonAdapterMapperGenerator extends IocAdapterMapperGenerator {
|
||||
|
||||
private AnnotationSpec component() {
|
||||
return AnnotationSpec.builder(ClassName.get("org.noear.solon.annotation", "Component"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private AnnotationSpec inject() {
|
||||
return AnnotationSpec.builder(ClassName.get("org.noear.solon.annotation", "Inject"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnnotationSpec componentAnnotation() {
|
||||
return component();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AnnotationSpec> injectAnnotations() {
|
||||
return CollectionUtil.newArrayList(inject());
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package io.github.linpeilie.processor.generator;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
@ -10,63 +11,37 @@ import com.squareup.javapoet.TypeSpec;
|
||||
import io.github.linpeilie.processor.AbstractAdapterMapperGenerator;
|
||||
import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
public class SpringAdapterMapperGenerator extends AbstractAdapterMapperGenerator {
|
||||
public class SpringAdapterMapperGenerator extends IocAdapterMapperGenerator {
|
||||
|
||||
@Override
|
||||
protected TypeSpec createTypeSpec(Collection<AbstractAdapterMethodMetadata> adapterMethods, String adapterClassName) {
|
||||
TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder(ClassName.get(adapterPackage(), adapterClassName))
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addAnnotation(ClassName.get("org.springframework.stereotype", "Component"));
|
||||
|
||||
adapterMethods.stream()
|
||||
.filter(adapterMethodMetadata -> !adapterMethodMetadata.isStatic())
|
||||
.map(AbstractAdapterMethodMetadata::getMapper)
|
||||
.distinct()
|
||||
.forEach(mapper -> adapterBuilder.addField(buildMapperField(mapper))
|
||||
.addMethod(buildMapperSetterMethod(mapper)));
|
||||
|
||||
adapterMethods.forEach(adapterMethod -> adapterBuilder
|
||||
.addMethod(buildProxyMethod(adapterMethod)));
|
||||
|
||||
return adapterBuilder.build();
|
||||
private AnnotationSpec component() {
|
||||
return AnnotationSpec
|
||||
.builder(ClassName.get("org.springframework.stereotype", "Component"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private FieldSpec buildMapperField(ClassName mapper) {
|
||||
return FieldSpec.builder(mapper, firstWordToLower(mapper.simpleName()), Modifier.PRIVATE).build();
|
||||
private AnnotationSpec autowired() {
|
||||
return AnnotationSpec
|
||||
.builder(ClassName.get("org.springframework.beans", "Autowired"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String firstWordToLower(String str) {
|
||||
return str.substring(0, 1).toLowerCase() + str.substring(1);
|
||||
private AnnotationSpec lazy() {
|
||||
return AnnotationSpec
|
||||
.builder(ClassName.get("org.springframework.context.annotation", "Lazy"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CodeBlock proxyMethodTarget(AbstractAdapterMethodMetadata adapterMethodMetadata) {
|
||||
return CodeBlock.builder()
|
||||
.add("return $N.$N($N);", firstWordToLower(adapterMethodMetadata.getMapper().simpleName()),
|
||||
adapterMethodMetadata.getMapperMethodName(),
|
||||
"param")
|
||||
.build();
|
||||
protected AnnotationSpec componentAnnotation() {
|
||||
return component();
|
||||
}
|
||||
|
||||
private MethodSpec buildMapperSetterMethod(ClassName mapper) {
|
||||
ParameterSpec parameterSpec = buildMapperSetterParameter(mapper);
|
||||
return MethodSpec.methodBuilder("set" + mapper.simpleName())
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addParameter(parameterSpec)
|
||||
.addAnnotation(
|
||||
AnnotationSpec.builder(ClassName.get("org.springframework.beans.factory.annotation", "Autowired"))
|
||||
.build())
|
||||
.addStatement("this.$N = $N", buildMapperField(mapper), parameterSpec)
|
||||
.build();
|
||||
}
|
||||
|
||||
private ParameterSpec buildMapperSetterParameter(ClassName mapper) {
|
||||
return ParameterSpec.builder(mapper, firstWordToLower(mapper.simpleName()))
|
||||
.addAnnotation(
|
||||
AnnotationSpec.builder(ClassName.get("org.springframework.context.annotation", "Lazy")).build())
|
||||
.build();
|
||||
@Override
|
||||
protected List<AnnotationSpec> injectAnnotations() {
|
||||
return CollectionUtil.newArrayList(autowired(), lazy());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package io.github.linpeilie.processor.solon;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import io.github.linpeilie.ComponentModelConstant;
|
||||
import java.util.List;
|
||||
import org.mapstruct.ap.internal.model.Annotation;
|
||||
import org.mapstruct.ap.internal.model.Mapper;
|
||||
import org.mapstruct.ap.internal.processor.AnnotationBasedComponentModelProcessor;
|
||||
|
||||
public class SolonComponentProcessor extends AnnotationBasedComponentModelProcessor {
|
||||
@Override
|
||||
protected String getComponentModelIdentifier() {
|
||||
return ComponentModelConstant.SOLON;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Annotation> getTypeAnnotations(final Mapper mapper) {
|
||||
return CollectionUtil.newArrayList(component());
|
||||
}
|
||||
|
||||
private Annotation component() {
|
||||
return new Annotation(getTypeFactory().getType("org.noear.solon.annotation.Component"));
|
||||
}
|
||||
|
||||
private Annotation inject() {
|
||||
return new Annotation(getTypeFactory().getType("org.noear.solon.annotation.Inject"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Annotation> getMapperReferenceAnnotations() {
|
||||
return CollectionUtil.newArrayList(inject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean requiresGenerationOfDecoratorClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
# Copyright MapStruct Authors.
|
||||
#
|
||||
# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
org.mapstruct.ap.internal.processor.CdiComponentProcessor
|
||||
org.mapstruct.ap.internal.processor.JakartaCdiComponentProcessor
|
||||
org.mapstruct.ap.internal.processor.Jsr330ComponentProcessor
|
||||
org.mapstruct.ap.internal.processor.JakartaComponentProcessor
|
||||
org.mapstruct.ap.internal.processor.MapperCreationProcessor
|
||||
org.mapstruct.ap.internal.processor.MapperRenderingProcessor
|
||||
org.mapstruct.ap.internal.processor.MethodRetrievalProcessor
|
||||
org.mapstruct.ap.internal.processor.SpringComponentProcessor
|
||||
org.mapstruct.ap.internal.processor.MapperServiceProcessor
|
||||
io.github.linpeilie.processor.solon.SolonComponentProcessor
|
||||
@ -0,0 +1,7 @@
|
||||
package io.github.linpeilie;
|
||||
|
||||
public interface ComponentModelConstant {
|
||||
|
||||
String SOLON = "solon";
|
||||
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@ -17,7 +17,7 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<mapstruct-plus.version>1.2.4</mapstruct-plus.version>
|
||||
<mapstruct-plus.version>1.2.5</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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user