mirror of
https://gitee.com/easii/mapstruct-plus.git
synced 2025-12-07 01:28:31 +08:00
不可变对象支持
This commit is contained in:
parent
13dad0a31b
commit
48bc0b863c
@ -459,7 +459,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
|
|||||||
try (final Writer writer = processingEnv.getFiler()
|
try (final Writer writer = processingEnv.getFiler()
|
||||||
.createSourceFile(mapperPackage + "." + mapperClassName)
|
.createSourceFile(mapperPackage + "." + mapperClassName)
|
||||||
.openWriter()) {
|
.openWriter()) {
|
||||||
mapperGenerator.write(metadata, writer);
|
mapperGenerator.write(metadata, processingEnv, writer);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
processingEnv.getMessager()
|
processingEnv.getMessager()
|
||||||
.printMessage(ERROR,
|
.printMessage(ERROR,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package io.github.linpeilie.processor.generator;
|
package io.github.linpeilie.processor.generator;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.squareup.javapoet.AnnotationSpec;
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
@ -9,7 +10,7 @@ import com.squareup.javapoet.MethodSpec;
|
|||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import io.github.linpeilie.processor.AutoMapperProperties;
|
import io.github.linpeilie.annotations.ImmutableEntity;
|
||||||
import io.github.linpeilie.processor.metadata.AutoMapperMetadata;
|
import io.github.linpeilie.processor.metadata.AutoMapperMetadata;
|
||||||
import io.github.linpeilie.processor.metadata.AutoMappingMetadata;
|
import io.github.linpeilie.processor.metadata.AutoMappingMetadata;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -21,17 +22,20 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.mapstruct.ReportingPolicy;
|
|
||||||
|
|
||||||
import static io.github.linpeilie.processor.Constants.*;
|
import static io.github.linpeilie.processor.Constants.*;
|
||||||
|
|
||||||
public class AutoMapperGenerator {
|
public class AutoMapperGenerator {
|
||||||
|
|
||||||
public void write(AutoMapperMetadata metadata, Writer writer) {
|
public static final String CONVERT_METHOD_NAME = "convert";
|
||||||
|
|
||||||
|
public void write(AutoMapperMetadata metadata, final ProcessingEnvironment processingEnv, Writer writer) {
|
||||||
try {
|
try {
|
||||||
JavaFile.builder(metadata.mapperPackage(), createTypeSpec(metadata)).build().writeTo(writer);
|
JavaFile.builder(metadata.mapperPackage(), createTypeSpec(processingEnv, metadata)).build().writeTo(writer);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UncheckedIOException(e);
|
throw new UncheckedIOException(e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -39,36 +43,70 @@ public class AutoMapperGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeSpec createTypeSpec(AutoMapperMetadata metadata) {
|
private TypeSpec createTypeSpec(ProcessingEnvironment processingEnv, AutoMapperMetadata metadata) {
|
||||||
ParameterizedTypeName converterName =
|
ParameterizedTypeName converterName =
|
||||||
ParameterizedTypeName.get(metadata.getSuperClass(), metadata.getSuperGenerics());
|
ParameterizedTypeName.get(metadata.getSuperClass(), metadata.getSuperGenerics());
|
||||||
|
|
||||||
|
final ClassName targetClassName = metadata.getTargetClassName();
|
||||||
|
|
||||||
|
|
||||||
TypeSpec.Builder builder = TypeSpec.interfaceBuilder(metadata.mapperName())
|
TypeSpec.Builder builder = TypeSpec.interfaceBuilder(metadata.mapperName())
|
||||||
.addSuperinterface(converterName)
|
.addSuperinterface(converterName)
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addAnnotation(buildGeneratedMapperAnnotationSpec(metadata));
|
.addAnnotation(buildGeneratedMapperAnnotationSpec(metadata));
|
||||||
if (metadata.getFieldMappingList() != null && !metadata.getFieldMappingList().isEmpty()) {
|
|
||||||
final ParameterSpec source = ParameterSpec.builder(metadata.getSourceClassName(), "source").build();
|
final ParameterSpec source = ParameterSpec.builder(metadata.getSourceClassName(), "source").build();
|
||||||
final ParameterSpec target = ParameterSpec.builder(metadata.getTargetClassName(), "target")
|
final ParameterSpec target = ParameterSpec.builder(targetClassName, "target")
|
||||||
.addAnnotation(AnnotationSpec.builder(ClassName.get("org.mapstruct", "MappingTarget")).build())
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("org.mapstruct", "MappingTarget")).build())
|
||||||
.build();
|
.build();
|
||||||
|
if (metadata.getFieldMappingList() != null && !metadata.getFieldMappingList().isEmpty()) {
|
||||||
builder.addMethod(addConvertMethodSpec(Collections.singletonList(source), metadata.getFieldMappingList(),
|
builder.addMethod(addConvertMethodSpec(Collections.singletonList(source), metadata.getFieldMappingList(),
|
||||||
metadata.getTargetClassName()));
|
targetClassName));
|
||||||
builder.addMethod(addConvertMethodSpec(Arrays.asList(source, target), metadata.getFieldMappingList(),
|
|
||||||
metadata.getTargetClassName()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean targetIsImmutable = classIsImmutable(processingEnv, targetClassName);
|
||||||
|
if (targetIsImmutable) {
|
||||||
|
builder.addMethod(addEmptyConvertMethodForImmutableEntity(source, target, targetClassName));
|
||||||
|
} else {
|
||||||
|
builder.addMethod(addConvertMethodSpec(Arrays.asList(source, target), metadata.getFieldMappingList(),
|
||||||
|
targetClassName));
|
||||||
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MethodSpec addEmptyConvertMethodForImmutableEntity(ParameterSpec source,
|
||||||
|
ParameterSpec target,
|
||||||
|
ClassName targetClassName) {
|
||||||
|
return MethodSpec.methodBuilder(CONVERT_METHOD_NAME)
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||||
|
.addParameter(source)
|
||||||
|
.addParameter(target)
|
||||||
|
.returns(targetClassName)
|
||||||
|
.addCode("return target;")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean classIsImmutable(ProcessingEnvironment processingEnv, ClassName className) {
|
||||||
|
final TypeElement targetElement = processingEnv.getElementUtils()
|
||||||
|
.getTypeElement(className.packageName() + "." + className.simpleName());
|
||||||
|
if (targetElement != null) {
|
||||||
|
return targetElement.getAnnotation(ImmutableEntity.class) != null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private MethodSpec addConvertMethodSpec(List<ParameterSpec> parameterSpecs,
|
private MethodSpec addConvertMethodSpec(List<ParameterSpec> parameterSpecs,
|
||||||
List<AutoMappingMetadata> autoMappingMetadataList,
|
List<AutoMappingMetadata> autoMappingMetadataList,
|
||||||
ClassName target) {
|
ClassName target) {
|
||||||
return MethodSpec.methodBuilder("convert")
|
final MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(CONVERT_METHOD_NAME)
|
||||||
.addParameters(parameterSpecs)
|
.addParameters(parameterSpecs)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
.addAnnotations(buildMappingAnnotations(autoMappingMetadataList))
|
.returns(target);
|
||||||
.returns(target)
|
if (CollectionUtil.isNotEmpty(autoMappingMetadataList)) {
|
||||||
.build();
|
methodSpecBuilder.addAnnotations(buildMappingAnnotations(autoMappingMetadataList));
|
||||||
|
}
|
||||||
|
return methodSpecBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AnnotationSpec> buildMappingAnnotations(final List<AutoMappingMetadata> autoMappingMetadataList) {
|
private List<AnnotationSpec> buildMappingAnnotations(final List<AutoMappingMetadata> autoMappingMetadataList) {
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
package io.github.linpeilie.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
public @interface ImmutableEntity {
|
||||||
|
}
|
||||||
2
pom.xml
2
pom.xml
@ -17,7 +17,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<mapstruct-plus.version>1.3.1</mapstruct-plus.version>
|
<mapstruct-plus.version>1.3.2-SNAPSHOT</mapstruct-plus.version>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user