From ebad18447ccac64dc2929ad97205a199bc169630 Mon Sep 17 00:00:00 2001 From: linpeilie Date: Sat, 25 Feb 2023 23:57:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0map=E8=BD=AC=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/pom.xml | 7 +- example/quick-start/pom.xml | 5 + .../StringToListStringConverter.java | 12 ++ .../java/io/github/linpeilie/model/Goods.java | 32 ++++++ .../io/github/linpeilie/model/GoodsDto.java | 39 +++++++ .../io/github/linpeilie/model/MapModelA.java | 54 +++++++++ .../io/github/linpeilie/model/MapModelB.java | 25 +++++ .../java/io/github/linpeilie/model/User.java | 51 ++++++--- .../io/github/linpeilie/model/UserDto.java | 50 ++++++--- .../io/github/linpeilie/QuickStartTest.java | 94 ++++++++++++++++ .../io/github/linpeilie/model/MapModelA.java | 54 +++++++++ .../io/github/linpeilie/model/MapModelB.java | 25 +++++ .../io/github/linpeilie/QuickStartTest.java | 31 +++-- .../AbstractAdapterMapperGenerator.java | 15 +-- .../processor/AutoMapperProcessor.java | 106 +++++++++++++++--- .../processor/AutoMapperProperties.java | 8 ++ .../github/linpeilie/processor/Constants.java | 7 ++ .../DefaultAdapterMapperGenerator.java | 85 -------------- .../{ => generator}/AutoMapperGenerator.java | 11 +- .../DefaultAdapterMapperGenerator.java | 42 +++++++ .../MapperConfigGenerator.java | 19 ++-- .../SpringAdapterMapperGenerator.java | 40 ++++--- .../AbstractAdapterMethodMetadata.java | 30 +++++ .../metadata/AbstractMapperMetadata.java | 30 +++++ .../metadata/AdapterMapMethodMetadata.java | 50 +++++++++ .../{ => metadata}/AdapterMethodMetadata.java | 26 ++--- .../metadata/AutoMapMapperMetadata.java | 13 +++ .../{ => metadata}/AutoMapperMetadata.java | 49 +++++--- .../{ => metadata}/AutoMappingMetadata.java | 2 +- .../mapstruct/SpringConverterFactory.java | 12 ++ mapstruct-plus/pom.xml | 4 + .../AbstractCachedConverterFactory.java | 18 +++ .../io/github/linpeilie/BaseMapMapper.java | 19 ++++ .../java/io/github/linpeilie/Converter.java | 17 +++ .../io/github/linpeilie/ConverterFactory.java | 2 + .../linpeilie/DefaultConverterFactory.java | 14 +++ .../linpeilie/annotations/AutoMapMapper.java | 18 +++ .../linpeilie/map/MapObjectConvert.java | 81 +++++++++++++ pom.xml | 11 +- 39 files changed, 980 insertions(+), 228 deletions(-) create mode 100644 example/quick-start/src/main/java/io/github/linpeilie/StringToListStringConverter.java create mode 100644 example/quick-start/src/main/java/io/github/linpeilie/model/Goods.java create mode 100644 example/quick-start/src/main/java/io/github/linpeilie/model/GoodsDto.java create mode 100644 example/quick-start/src/main/java/io/github/linpeilie/model/MapModelA.java create mode 100644 example/quick-start/src/main/java/io/github/linpeilie/model/MapModelB.java create mode 100644 example/quick-start/src/test/java/io/github/linpeilie/QuickStartTest.java create mode 100644 example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelA.java create mode 100644 example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelB.java delete mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/DefaultAdapterMapperGenerator.java rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => generator}/AutoMapperGenerator.java (92%) create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/DefaultAdapterMapperGenerator.java rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => generator}/MapperConfigGenerator.java (68%) rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => generator}/SpringAdapterMapperGenerator.java (57%) create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractAdapterMethodMetadata.java create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractMapperMetadata.java create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMapMethodMetadata.java rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => metadata}/AdapterMethodMetadata.java (67%) create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => metadata}/AutoMapperMetadata.java (58%) rename mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/{ => metadata}/AutoMappingMetadata.java (96%) create mode 100644 mapstruct-plus/src/main/java/io/github/linpeilie/BaseMapMapper.java create mode 100644 mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapMapper.java create mode 100644 mapstruct-plus/src/main/java/io/github/linpeilie/map/MapObjectConvert.java diff --git a/example/pom.xml b/example/pom.xml index a45ff15..5de3449 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -18,7 +18,7 @@ 8 UTF-8 1.5.1.Final - 1.0.0 + 1.1.0 2.7.0 @@ -39,11 +39,6 @@ mapstruct-plus ${mapstruct-plus.version} - - org.mapstruct - mapstruct - ${mapstruct.version} - org.springframework.boot spring-boot-dependencies diff --git a/example/quick-start/pom.xml b/example/quick-start/pom.xml index d6d1d58..80600f3 100644 --- a/example/quick-start/pom.xml +++ b/example/quick-start/pom.xml @@ -22,6 +22,11 @@ io.github.linpeilie mapstruct-plus + + org.junit.jupiter + junit-jupiter + test + \ No newline at end of file diff --git a/example/quick-start/src/main/java/io/github/linpeilie/StringToListStringConverter.java b/example/quick-start/src/main/java/io/github/linpeilie/StringToListStringConverter.java new file mode 100644 index 0000000..faafac9 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/StringToListStringConverter.java @@ -0,0 +1,12 @@ +package io.github.linpeilie; + +import java.util.Arrays; +import java.util.List; + +public class StringToListStringConverter { + + public static List stringToListString(String str) { + return Arrays.asList(str.split(",")); + } + +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/Goods.java b/example/quick-start/src/main/java/io/github/linpeilie/model/Goods.java new file mode 100644 index 0000000..40901e1 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/Goods.java @@ -0,0 +1,32 @@ +package io.github.linpeilie.model; + +public class Goods { + + private String price; + + private String takeDownTime; + + public String getPrice() { + return price; + } + + public void setPrice(final String price) { + this.price = price; + } + + public String getTakeDownTime() { + return takeDownTime; + } + + public void setTakeDownTime(final String takeDownTime) { + this.takeDownTime = takeDownTime; + } + + @Override + public String toString() { + return "Goods{" + + "price='" + price + '\'' + + ", takeDownTime='" + takeDownTime + '\'' + + '}'; + } +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/GoodsDto.java b/example/quick-start/src/main/java/io/github/linpeilie/model/GoodsDto.java new file mode 100644 index 0000000..7777056 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/GoodsDto.java @@ -0,0 +1,39 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.Date; + +@AutoMapper(target = Goods.class) +public class GoodsDto { + + @AutoMapping(target = "takeDownTime", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date takeDownTime; + + @AutoMapping(target = "price", numberFormat = "$#.00") + private int price; + + public int getPrice() { + return price; + } + + public void setPrice(final int price) { + this.price = price; + } + + public Date getTakeDownTime() { + return takeDownTime; + } + + public void setTakeDownTime(final Date takeDownTime) { + this.takeDownTime = takeDownTime; + } + + @Override + public String toString() { + return "GoodsDto{" + + "takeDownTime=" + takeDownTime + + ", price=" + price + + '}'; + } +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelA.java b/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelA.java new file mode 100644 index 0000000..65b3968 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelA.java @@ -0,0 +1,54 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapMapper; + +@AutoMapMapper +public class MapModelA { + + private String str; + private int i1; + private Long l2; + private MapModelB mapModelB; + + public String getStr() { + return str; + } + + public void setStr(final String str) { + this.str = str; + } + + public int getI1() { + return i1; + } + + public void setI1(final int i1) { + this.i1 = i1; + } + + public Long getL2() { + return l2; + } + + public void setL2(final Long l2) { + this.l2 = l2; + } + + public MapModelB getMapModelB() { + return mapModelB; + } + + @Override + public String toString() { + return "MapModelA{" + + "str='" + str + '\'' + + ", i1=" + i1 + + ", l2=" + l2 + + ", mapModelB=" + mapModelB + + '}'; + } + + public void setMapModelB(final MapModelB mapModelB) { + this.mapModelB = mapModelB; + } +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelB.java b/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelB.java new file mode 100644 index 0000000..a181c5c --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/MapModelB.java @@ -0,0 +1,25 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapMapper; +import java.util.Date; + +@AutoMapMapper +public class MapModelB { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(final Date date) { + this.date = date; + } + + @Override + public String toString() { + return "MapModelB{" + + "date=" + date + + '}'; + } +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/User.java b/example/quick-start/src/main/java/io/github/linpeilie/model/User.java index 6430977..9b3510a 100644 --- a/example/quick-start/src/main/java/io/github/linpeilie/model/User.java +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/User.java @@ -1,15 +1,27 @@ package io.github.linpeilie.model; import io.github.linpeilie.annotations.AutoMapper; -import java.util.Objects; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.Date; +import java.util.List; @AutoMapper(target = UserDto.class) public class User { private String username; + private int age; private boolean young; + @AutoMapping(target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))") + private List educationList; + + @AutoMapping(target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date birthday; + + @AutoMapping(target = "assets", numberFormat = "$0.00") + private double assets; + public String getUsername() { return username; } @@ -34,22 +46,28 @@ public class User { this.young = young; } - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final User user = (User) o; - return getAge() == user.getAge() && isYoung() == user.isYoung() && - Objects.equals(getUsername(), user.getUsername()); + public List getEducationList() { + return educationList; } - @Override - public int hashCode() { - return Objects.hash(getUsername(), getAge(), isYoung()); + public void setEducationList(final List educationList) { + this.educationList = educationList; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(final Date birthday) { + this.birthday = birthday; + } + + public double getAssets() { + return assets; + } + + public void setAssets(final double assets) { + this.assets = assets; } @Override @@ -58,6 +76,9 @@ public class User { "username='" + username + '\'' + ", age=" + age + ", young=" + young + + ", educationList=" + educationList + + ", birthday=" + birthday + + ", assets=" + assets + '}'; } } diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java b/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java index 8731e18..c6167e4 100644 --- a/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java @@ -1,13 +1,23 @@ package io.github.linpeilie.model; -import java.util.Objects; +import io.github.linpeilie.StringToListStringConverter; +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +@AutoMapper(target = User.class, uses = StringToListStringConverter.class) public class UserDto { private String username; private int age; private boolean young; + @AutoMapping(target = "educationList") + private String educations; + + private String birthday; + + private String assets; + public String getUsername() { return username; } @@ -32,22 +42,28 @@ public class UserDto { this.young = young; } - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final UserDto user = (UserDto) o; - return getAge() == user.getAge() && isYoung() == user.isYoung() && - Objects.equals(getUsername(), user.getUsername()); + public String getEducations() { + return educations; } - @Override - public int hashCode() { - return Objects.hash(getUsername(), getAge(), isYoung()); + public void setEducations(final String educations) { + this.educations = educations; + } + + public String getBirthday() { + return birthday; + } + + public void setBirthday(final String birthday) { + this.birthday = birthday; + } + + public String getAssets() { + return assets; + } + + public void setAssets(final String assets) { + this.assets = assets; } @Override @@ -56,7 +72,9 @@ public class UserDto { "username='" + username + '\'' + ", age=" + age + ", young=" + young + + ", educations='" + educations + '\'' + + ", birthday='" + birthday + '\'' + + ", assets='" + assets + '\'' + '}'; } - } diff --git a/example/quick-start/src/test/java/io/github/linpeilie/QuickStartTest.java b/example/quick-start/src/test/java/io/github/linpeilie/QuickStartTest.java new file mode 100644 index 0000000..607cd6b --- /dev/null +++ b/example/quick-start/src/test/java/io/github/linpeilie/QuickStartTest.java @@ -0,0 +1,94 @@ +package io.github.linpeilie; + +import cn.hutool.core.date.DateUtil; +import io.github.linpeilie.model.Goods; +import io.github.linpeilie.model.GoodsDto; +import io.github.linpeilie.model.MapModelA; +import io.github.linpeilie.model.User; +import io.github.linpeilie.model.UserDto; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +public class QuickStartTest { + + private Converter converter = new Converter(); + + @Test + public void test() { + Map mapModel1 = new HashMap<>(); + mapModel1.put("str", "1jkf1ijkj3f"); + mapModel1.put("i1", 111); + mapModel1.put("l2", 11231); + + Map mapModel2 = new HashMap<>(); + mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23")); + + mapModel1.put("mapModelB", mapModel2); + + final MapModelA mapModelA = converter.convert(mapModel1, MapModelA.class); + System.out.println(mapModelA); + } + + + @Test + public void ueseTest() { + UserDto userDto = new UserDto(); + userDto.setEducations("1,2,3"); + + final User user = converter.convert(userDto, User.class); + System.out.println(user.getEducationList()); // [1, 2, 3] + + assert user.getEducationList().size() == 3; + } + + @Test + public void numberFormatTest() { + GoodsDto goodsDto = new GoodsDto(); + goodsDto.setPrice(9); + + final Goods goods = converter.convert(goodsDto, Goods.class); + + System.out.println(goods.getPrice()); // $9.00 + + assert "$9.00".equals(goods.getPrice()); + } + + @Test + public void dateFormatTest() throws ParseException { + final GoodsDto goodsDto = new GoodsDto(); + + final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + final String dateString = "2023-02-23 23:27:37"; + final Date date = simpleDateFormat.parse(dateString); + + goodsDto.setTakeDownTime(date); + + final Goods goods = converter.convert(goodsDto, Goods.class); + + System.out.println(goods.getTakeDownTime()); // 2023-02-23 23:27:37 + + assert dateString.equals(goods.getTakeDownTime()); + } + + @Test + public void expressionFormatTest() { + User user = new User(); + List list = new ArrayList<>(); + list.add("1"); + list.add("2"); + list.add("3"); + user.setEducationList(list); + + final UserDto userDto = converter.convert(user, UserDto.class); + System.out.println(userDto.getEducations()); + + assert "1,2,3".equals(userDto.getEducations()); + } + +} diff --git a/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelA.java b/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelA.java new file mode 100644 index 0000000..65b3968 --- /dev/null +++ b/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelA.java @@ -0,0 +1,54 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapMapper; + +@AutoMapMapper +public class MapModelA { + + private String str; + private int i1; + private Long l2; + private MapModelB mapModelB; + + public String getStr() { + return str; + } + + public void setStr(final String str) { + this.str = str; + } + + public int getI1() { + return i1; + } + + public void setI1(final int i1) { + this.i1 = i1; + } + + public Long getL2() { + return l2; + } + + public void setL2(final Long l2) { + this.l2 = l2; + } + + public MapModelB getMapModelB() { + return mapModelB; + } + + @Override + public String toString() { + return "MapModelA{" + + "str='" + str + '\'' + + ", i1=" + i1 + + ", l2=" + l2 + + ", mapModelB=" + mapModelB + + '}'; + } + + public void setMapModelB(final MapModelB mapModelB) { + this.mapModelB = mapModelB; + } +} diff --git a/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelB.java b/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelB.java new file mode 100644 index 0000000..a181c5c --- /dev/null +++ b/example/spring-boot/src/main/java/io/github/linpeilie/model/MapModelB.java @@ -0,0 +1,25 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapMapper; +import java.util.Date; + +@AutoMapMapper +public class MapModelB { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(final Date date) { + this.date = date; + } + + @Override + public String toString() { + return "MapModelB{" + + "date=" + date + + '}'; + } +} diff --git a/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java b/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java index 3536eab..6fb5633 100644 --- a/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java +++ b/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java @@ -1,14 +1,19 @@ package io.github.linpeilie; +import cn.hutool.core.date.DateUtil; import io.github.linpeilie.model.Goods; import io.github.linpeilie.model.GoodsDto; +import io.github.linpeilie.model.MapModelA; import io.github.linpeilie.model.User; import io.github.linpeilie.model.UserDto; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -22,27 +27,21 @@ public class QuickStartTest { @Test public void test() { - User user = new User(); - user.setUsername("jack"); - user.setAge(23); - user.setYoung(false); + Map mapModel1 = new HashMap<>(); + mapModel1.put("str", "1jkf1ijkj3f"); + mapModel1.put("i1", 111); + mapModel1.put("l2", 11231); - UserDto userDto = converter.convert(user, UserDto.class); - System.out.println(userDto); // UserDto{username='jack', age=23, young=false} + Map mapModel2 = new HashMap<>(); + mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23")); - assert user.getUsername().equals(userDto.getUsername()); - assert user.getAge() == userDto.getAge(); - assert user.isYoung() == userDto.isYoung(); + mapModel1.put("mapModelB", mapModel2); - User newUser = converter.convert(userDto, User.class); - - System.out.println(newUser); // User{username='jack', age=23, young=false} - - assert user.getUsername().equals(newUser.getUsername()); - assert user.getAge() == newUser.getAge(); - assert user.isYoung() == newUser.isYoung(); + final MapModelA mapModelA = converter.convert(mapModel1, MapModelA.class); + System.out.println(mapModelA); } + @Test public void ueseTest() { UserDto userDto = new UserDto(); diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java index 793ccce..422c51f 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java @@ -2,6 +2,7 @@ package io.github.linpeilie.processor; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata; import java.io.IOException; import java.io.Writer; import java.util.Collection; @@ -11,26 +12,22 @@ import static javax.tools.Diagnostic.Kind.ERROR; public abstract class AbstractAdapterMapperGenerator { - public void write(ProcessingEnvironment processingEnv, Collection adapterMethods) { + public void write(ProcessingEnvironment processingEnv, Collection adapterMethods, String adapterClassName) { // write Adapter try (final Writer writer = processingEnv.getFiler() - .createSourceFile(adapterPackage() + "." + adapterClassName()) + .createSourceFile(adapterPackage() + "." + adapterClassName) .openWriter()) { - JavaFile.builder(adapterPackage(), createTypeSpec(adapterMethods)).build().writeTo(writer); + JavaFile.builder(adapterPackage(), createTypeSpec(adapterMethods, adapterClassName)).build().writeTo(writer); } catch (IOException e) { processingEnv.getMessager() - .printMessage(ERROR, "Error while opening " + adapterClassName() + " output file: " + e.getMessage()); + .printMessage(ERROR, "Error while opening " + adapterClassName + " output file: " + e.getMessage()); } } - protected abstract TypeSpec createTypeSpec(Collection adapterMethods); + protected abstract TypeSpec createTypeSpec(Collection adapterMethods, String adapterClassName); protected String adapterPackage() { return AutoMapperProperties.getAdapterPackage(); } - protected String adapterClassName() { - return AutoMapperProperties.getAdapterClassName(); - } - } 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 b5e3649..f0959ca 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 @@ -1,14 +1,25 @@ package io.github.linpeilie.processor; import com.squareup.javapoet.ClassName; +import io.github.linpeilie.annotations.AutoMapMapper; import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapping; import io.github.linpeilie.annotations.ComponentModelConfig; import io.github.linpeilie.annotations.MapperConfig; -import java.awt.Component; +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.SpringAdapterMapperGenerator; +import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata; +import io.github.linpeilie.processor.metadata.AdapterMapMethodMetadata; +import io.github.linpeilie.processor.metadata.AdapterMethodMetadata; +import io.github.linpeilie.processor.metadata.AutoMapMapperMetadata; +import io.github.linpeilie.processor.metadata.AutoMapperMetadata; +import io.github.linpeilie.processor.metadata.AutoMappingMetadata; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -31,11 +42,13 @@ import org.apache.commons.lang3.StringUtils; import org.mapstruct.MappingConstants; import static io.github.linpeilie.processor.Constants.AUTO_MAPPER_ANNOTATION; +import static io.github.linpeilie.processor.Constants.AUTO_MAP_MAPPER_ANNOTATION; import static io.github.linpeilie.processor.Constants.COMPONENT_MODEL_CONFIG_ANNOTATION; import static io.github.linpeilie.processor.Constants.MAPPER_CONFIG_ANNOTATION; import static javax.tools.Diagnostic.Kind.ERROR; -@SupportedAnnotationTypes({AUTO_MAPPER_ANNOTATION, MAPPER_CONFIG_ANNOTATION, COMPONENT_MODEL_CONFIG_ANNOTATION}) +@SupportedAnnotationTypes({AUTO_MAPPER_ANNOTATION, AUTO_MAP_MAPPER_ANNOTATION, MAPPER_CONFIG_ANNOTATION, + COMPONENT_MODEL_CONFIG_ANNOTATION}) public class AutoMapperProcessor extends AbstractProcessor { private final AutoMapperGenerator mapperGenerator; @@ -44,7 +57,9 @@ public class AutoMapperProcessor extends AbstractProcessor { private final MapperConfigGenerator mapperConfigGenerator; - private final Map methodMap = new HashMap<>(); + private final Map methodMap = new HashMap<>(); + + private final Map mapMethodMap = new HashMap<>(); private final Set mapperSet = new HashSet<>(); @@ -57,6 +72,10 @@ public class AutoMapperProcessor extends AbstractProcessor { return AUTO_MAPPER_ANNOTATION.contentEquals(annotation.getQualifiedName()); } + private boolean isAutoMapMapperAnnotation(TypeElement annotation) { + return AUTO_MAP_MAPPER_ANNOTATION.contentEquals(annotation.getQualifiedName()); + } + private boolean isMapperConfigAnnotation(TypeElement annotation) { return MAPPER_CONFIG_ANNOTATION.contentEquals(annotation.getQualifiedName()); } @@ -71,22 +90,62 @@ public class AutoMapperProcessor extends AbstractProcessor { if (!hasAutoMapper) { return false; } - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "start refresh properties"); + // 刷新配置 refreshProperties(annotations, roundEnv); + // 根据配置生成注解类 this.adapterMapperGenerator = AutoMapperProperties.getComponentModel() .contentEquals( MappingConstants.ComponentModel.SPRING) ? new SpringAdapterMapperGenerator() : new DefaultAdapterMapperGenerator(); - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "start write config class"); - writeConfigClass(); - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "start generate mapper class"); + // 获取 MapMapper + annotations.stream() + .filter(this::isAutoMapMapperAnnotation) + .findFirst() + .ifPresent(annotation -> processAutoMapMapperAnnotation(roundEnv, annotation)); + + // 生成类 annotations.stream() .filter(this::isAutoMapperAnnotation) - .forEach(annotation -> processAutoMapperAnnotation(roundEnv, annotation)); + .findFirst() + .ifPresent(annotation -> processAutoMapperAnnotation(roundEnv, annotation)); return false; } + private void processAutoMapMapperAnnotation(final RoundEnvironment roundEnv, final TypeElement annotation) { + final List autoMapMapperMetadataList = + roundEnv.getElementsAnnotatedWith(annotation).stream().map(ele -> { + if (ele.getAnnotation(AutoMapMapper.class) == null) { + return null; + } + ClassName source = ClassName.get("java.util", "Map"); + ClassName target = ClassName.get((TypeElement) ele); + List uses = Arrays.asList(ClassName.get("io.github.linpeilie.map", "MapObjectConvert")); + + final AutoMapperMetadata autoMapperMetadata = new AutoMapMapperMetadata(); + autoMapperMetadata.setTargetClassName(target); + autoMapperMetadata.setSourceClassName(source); + autoMapperMetadata.setUsesClassNameList(uses); + autoMapperMetadata.setSuperClass(ClassName.get("io.github.linpeilie", "BaseMapMapper")); + autoMapperMetadata.setSuperGenerics(new ClassName[] {target}); + autoMapperMetadata.setMapstructConfigClass(ClassName.get(AutoMapperProperties.getConfigPackage(), + AutoMapperProperties.getMapConfigClassName())); + return autoMapperMetadata; + }).filter(Objects::nonNull).collect(Collectors.toList()); + autoMapMapperMetadataList.forEach(metadata -> { + this.writeAutoMapperClassFile(metadata); + addAdapterMapMethod(metadata.getSourceClassName(), metadata.getTargetClassName(), metadata.mapperClass(), + false); + addAdapterMapMethod(ClassName.get("java.lang", "Object"), metadata.getTargetClassName(), + metadata.mapperClass(), true); + }); + adapterMapperGenerator.write(processingEnv, mapMethodMap.values(), + AutoMapperProperties.getMapAdapterClassName()); + + mapperConfigGenerator.write(processingEnv, AutoMapperProperties.getMapConfigClassName(), + AutoMapperProperties.getMapAdapterClassName()); + } + private void refreshProperties(final Set annotations, final RoundEnvironment roundEnv) { annotations.stream() .filter(this::isMapperConfigAnnotation) @@ -116,10 +175,6 @@ public class AutoMapperProcessor extends AbstractProcessor { return String.valueOf(processingEnv.getElementUtils().getPackageOf(element).getQualifiedName()); } - private void writeConfigClass() { - mapperConfigGenerator.write(processingEnv); - } - private void processAutoMapperAnnotation(final RoundEnvironment roundEnv, final TypeElement annotation) { final List autoMapperMetadataList = roundEnv.getElementsAnnotatedWith(annotation) .stream() @@ -141,15 +196,26 @@ public class AutoMapperProcessor extends AbstractProcessor { autoMapperMetadataList.addAll(reverseMapperMetadataList); - autoMapperMetadataList.forEach(this::writeAutoMapperClassFile); + autoMapperMetadataList.forEach(metadata -> { + this.writeAutoMapperClassFile(metadata); + addAdapterMethod(metadata.getSourceClassName(), metadata.getTargetClassName(), metadata.mapperClass()); + }); - adapterMapperGenerator.write(processingEnv, methodMap.values()); + adapterMapperGenerator.write(processingEnv, methodMap.values(), AutoMapperProperties.getAdapterClassName()); + + mapperConfigGenerator.write(processingEnv, AutoMapperProperties.getConfigClassName(), + AutoMapperProperties.getAdapterClassName()); } private AutoMapperMetadata reverseMapper(AutoMapperMetadata autoMapperMetadata) { AutoMapperMetadata reverseMapperMetadata = new AutoMapperMetadata(); reverseMapperMetadata.setSourceClassName(autoMapperMetadata.getTargetClassName()); reverseMapperMetadata.setTargetClassName(autoMapperMetadata.getSourceClassName()); + reverseMapperMetadata.setSuperClass(autoMapperMetadata.getSuperClass()); + reverseMapperMetadata.setSuperGenerics( + new ClassName[] {reverseMapperMetadata.getSourceClassName(), reverseMapperMetadata.getTargetClassName()}); + reverseMapperMetadata.setMapstructConfigClass( + ClassName.get(AutoMapperProperties.getConfigPackage(), AutoMapperProperties.getConfigClassName())); // 需要继承的属性 final List fieldMetadataList = autoMapperMetadata.getFieldMappingList().stream().map(fieldMapping -> { @@ -169,8 +235,6 @@ public class AutoMapperProcessor extends AbstractProcessor { .createSourceFile(mapperPackage + "." + mapperClassName) .openWriter()) { mapperGenerator.write(metadata, writer); - addAdapterMethod(metadata.getSourceClassName(), metadata.getTargetClassName(), - ClassName.get(mapperPackage, mapperClassName)); } catch (IOException e) { processingEnv.getMessager() .printMessage(ERROR, @@ -183,6 +247,12 @@ public class AutoMapperProcessor extends AbstractProcessor { methodMap.put(adapterMethodMetadata.getMethodName(), adapterMethodMetadata); } + private void addAdapterMapMethod(ClassName source, ClassName target, ClassName mapper, boolean objectConverter) { + final AdapterMapMethodMetadata adapterMapMethodMetadata = + new AdapterMapMethodMetadata(source, target, mapper, objectConverter); + mapMethodMap.put(adapterMapMethodMetadata.getMethodName(), adapterMapMethodMetadata); + } + private AutoMapperMetadata buildAutoMapperMetadata(final Element ele) { AutoMapper autoMapperAnnotation = ele.getAnnotation(AutoMapper.class); if (autoMapperAnnotation == null) { @@ -203,6 +273,10 @@ public class AutoMapperProcessor extends AbstractProcessor { metadata.setTargetClassName(target); metadata.setUsesClassNameList(uses); metadata.setFieldMappingList(autoMappingMetadataList); + metadata.setSuperClass(ClassName.get("io.github.linpeilie", "BaseMapper")); + metadata.setSuperGenerics(new ClassName[] {source, target}); + metadata.setMapstructConfigClass( + ClassName.get(AutoMapperProperties.getConfigPackage(), AutoMapperProperties.getConfigClassName())); return metadata; } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java index ebe5315..2721cd4 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java @@ -20,6 +20,10 @@ public class AutoMapperProperties { return DEFAULT_ADAPTER_CLASS_NAME; } + public static String getMapAdapterClassName() { + return DEFAULT_MAP_ADAPTER_CLASS_NAME; + } + public static String getConfigPackage() { return DEFAULT_BASE_PACKAGE; } @@ -28,6 +32,10 @@ public class AutoMapperProperties { return AUTO_MAPPER_CONFIG_CLASS_NAME; } + public static String getMapConfigClassName() { + return AUTO_MAP_MAPPER_CONFIG_CLASS_NAME; + } + public static String getComponentModel() { return componentModel; } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/Constants.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/Constants.java index 4b78d2d..da1c525 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/Constants.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/Constants.java @@ -10,11 +10,16 @@ public class Constants { public static final String DEFAULT_ADAPTER_CLASS_NAME = "ConvertMapperAdapter"; + public static final String DEFAULT_MAP_ADAPTER_CLASS_NAME = "MapConvertMapperAdapter"; public static final String AUTO_MAPPER_CONFIG_CLASS_NAME = "AutoMapperConfig"; + public static final String AUTO_MAP_MAPPER_CONFIG_CLASS_NAME = "AutoMapMapperConfig"; + public static final String AUTO_MAPPER_ANNOTATION = "io.github.linpeilie.annotations.AutoMapper"; + public static final String AUTO_MAP_MAPPER_ANNOTATION = "io.github.linpeilie.annotations.AutoMapMapper"; + public static final String MAPPER_CONFIG_ANNOTATION = "io.github.linpeilie.annotations.MapperConfig"; public static final String COMPONENT_MODEL_CONFIG_ANNOTATION = "io.github.linpeilie.annotations.ComponentModelConfig"; @@ -23,6 +28,8 @@ public class Constants { public static final String BASE_MAPPER_CLASS_NAME = "BaseMapper"; + public static final String BASE_MAP_MAPPER_CLASS_NAME = "BaseMapMapper"; + public static final String MAPSTRUCT_MAPPER_PACKAGE = "org.mapstruct"; public static final String MAPSTRUCT_MAPPER_CLASS_NAME = "Mapper"; diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/DefaultAdapterMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/DefaultAdapterMapperGenerator.java deleted file mode 100644 index 21fb29e..0000000 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/DefaultAdapterMapperGenerator.java +++ /dev/null @@ -1,85 +0,0 @@ -package io.github.linpeilie.processor; - -import com.squareup.javapoet.AnnotationSpec; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeSpec; -import java.io.IOException; -import java.io.Writer; -import java.util.Collection; -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Modifier; -import org.mapstruct.MappingConstants; - -import static javax.tools.Diagnostic.Kind.ERROR; - -public class DefaultAdapterMapperGenerator extends AbstractAdapterMapperGenerator { - - public TypeSpec createTypeSpec(Collection adapterMethods) { - TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder( - ClassName.get(AutoMapperProperties.getAdapterPackage(), AutoMapperProperties.getAdapterClassName())) - .addModifiers(Modifier.PUBLIC); - - if (AutoMapperProperties.getComponentModel().contentEquals(MappingConstants.ComponentModel.SPRING)) { - adapterMethods.forEach(adapterMethod -> adapterBuilder.addField(buildMapperField(adapterMethod.getMapper())) - .addMethod(buildMapperSetterMethod(adapterMethod.getMapper())) - .addMethod(buildSpringProxyMethod(adapterMethod))); - } else { - adapterMethods.forEach(adapterMethod -> adapterBuilder.addMethod(buildDefaultProxyMethod(adapterMethod))); - } - - return adapterBuilder.build(); - } - - private MethodSpec buildSpringProxyMethod(final AdapterMethodMetadata adapterMethodMetadata) { - ParameterSpec parameterSpec = ParameterSpec.builder(adapterMethodMetadata.getSource(), - firstWordToLower(adapterMethodMetadata.getSource().simpleName())).build(); - return MethodSpec.methodBuilder(firstWordToLower(adapterMethodMetadata.getSource().simpleName()) + "To" + - adapterMethodMetadata.getTarget().simpleName()) - .addModifiers(Modifier.PUBLIC) - .addParameter(parameterSpec) - .returns(adapterMethodMetadata.getTarget()) - .addStatement("return $N.convert($N)", firstWordToLower(adapterMethodMetadata.getMapper().simpleName())) - .build(); - } - - private FieldSpec buildMapperField(ClassName mapper) { - return FieldSpec.builder(mapper, firstWordToLower(mapper.simpleName()), Modifier.PRIVATE).build(); - } - - private String firstWordToLower(String str) { - return str.substring(0, 1).toLowerCase() + str.substring(1); - } - - private MethodSpec buildDefaultProxyMethod(AdapterMethodMetadata adapterMethodMetadata) { - ParameterSpec parameterSpec = ParameterSpec.builder(adapterMethodMetadata.getSource(), - firstWordToLower(adapterMethodMetadata.getSource().simpleName())).build(); - return MethodSpec.methodBuilder(firstWordToLower(adapterMethodMetadata.getSource().simpleName()) + "To" + - adapterMethodMetadata.getTarget().simpleName()) - .addModifiers(Modifier.PUBLIC) - .addParameter(parameterSpec) - .returns(adapterMethodMetadata.getTarget()) - .addStatement("return ($T.getMapper($T.class)).convert($N)", - ClassName.get("org.mapstruct.factory", "Mappers"), adapterMethodMetadata.getMapper(), - firstWordToLower(adapterMethodMetadata.getSource().simpleName())) - .build(); - } - - private MethodSpec buildMapperSetterMethod(ClassName mapper) { - ParameterSpec parameterSpec = buildMapperSetterParameter(mapper); - return MethodSpec.methodBuilder("set" + mapper.simpleName()) - .addModifiers(Modifier.PUBLIC) - .addParameter(parameterSpec) - .addStatement("this.$N = $N", buildMapperField(mapper), parameterSpec) - .build(); - } - - private ParameterSpec buildMapperSetterParameter(ClassName mapper) { - return ParameterSpec.builder(mapper, firstWordToLower(mapper.simpleName())).build(); - } - -} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java similarity index 92% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperGenerator.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java index b8b98e4..afb1c66 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java @@ -1,4 +1,4 @@ -package io.github.linpeilie.processor; +package io.github.linpeilie.processor.generator; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; @@ -8,6 +8,9 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.processor.AutoMapperProperties; +import io.github.linpeilie.processor.metadata.AutoMapperMetadata; +import io.github.linpeilie.processor.metadata.AutoMappingMetadata; import java.io.IOException; import java.io.UncheckedIOException; import java.io.Writer; @@ -36,8 +39,7 @@ public class AutoMapperGenerator { private TypeSpec createTypeSpec(AutoMapperMetadata metadata) { ParameterizedTypeName converterName = - ParameterizedTypeName.get(ClassName.get(BASE_MAPPER_PACKAGE, BASE_MAPPER_CLASS_NAME), - metadata.getSourceClassName(), metadata.getTargetClassName()); + ParameterizedTypeName.get(metadata.getSuperClass(), metadata.getSuperGenerics()); TypeSpec.Builder builder = TypeSpec.interfaceBuilder(metadata.mapperName()) .addSuperinterface(converterName) @@ -91,8 +93,7 @@ public class AutoMapperGenerator { // config CodeBlock configCodeBlock = CodeBlock.builder() - .add("$T.class", - ClassName.get(AutoMapperProperties.getConfigPackage(), AutoMapperProperties.getConfigClassName())) + .add("$T.class", metadata.getMapstructConfigClass()) .build(); // uses diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/DefaultAdapterMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/DefaultAdapterMapperGenerator.java new file mode 100644 index 0000000..e5db8b5 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/DefaultAdapterMapperGenerator.java @@ -0,0 +1,42 @@ +package io.github.linpeilie.processor.generator; + +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.processor.AbstractAdapterMapperGenerator; +import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata; +import java.util.Collection; +import javax.lang.model.element.Modifier; + +public class DefaultAdapterMapperGenerator extends AbstractAdapterMapperGenerator { + + public TypeSpec createTypeSpec(Collection adapterMethods, String adapterClassName) { + TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder( + ClassName.get(adapterPackage(), adapterClassName)) + .addModifiers(Modifier.PUBLIC); + + adapterMethods.forEach(adapterMethod -> adapterBuilder.addMethod(buildDefaultProxyMethod(adapterMethod))); + + return adapterBuilder.build(); + } + + private String firstWordToLower(String str) { + return str.substring(0, 1).toLowerCase() + str.substring(1); + } + + private MethodSpec buildDefaultProxyMethod(AbstractAdapterMethodMetadata adapterMethodMetadata) { + ParameterSpec parameterSpec = ParameterSpec.builder(adapterMethodMetadata.getSource(), + firstWordToLower(adapterMethodMetadata.getSource().simpleName())).build(); + return MethodSpec.methodBuilder(adapterMethodMetadata.getMethodName()) + .addModifiers(Modifier.PUBLIC) + .addParameter(parameterSpec) + .returns(adapterMethodMetadata.getReturn()) + .addStatement("return ($T.getMapper($T.class)).$N($N)", + ClassName.get("org.mapstruct.factory", "Mappers"), adapterMethodMetadata.getMapper(), + adapterMethodMetadata.getMapperMethodName(), + firstWordToLower(adapterMethodMetadata.getSource().simpleName())) + .build(); + } + +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/MapperConfigGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java similarity index 68% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/MapperConfigGenerator.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java index 5c9a541..ad0ad5b 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/MapperConfigGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java @@ -1,10 +1,11 @@ -package io.github.linpeilie.processor; +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.JavaFile; import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.processor.AutoMapperProperties; import java.io.IOException; import java.io.Writer; import javax.annotation.processing.ProcessingEnvironment; @@ -14,11 +15,11 @@ import static javax.tools.Diagnostic.Kind.ERROR; public class MapperConfigGenerator { - public void write(ProcessingEnvironment processingEnv) { + public void write(ProcessingEnvironment processingEnv, String mapstructConfigName, String adapterClassName) { try (final Writer writer = processingEnv.getFiler() - .createSourceFile(AutoMapperProperties.getConfigPackage() + "." + AutoMapperProperties.getConfigClassName()) + .createSourceFile(AutoMapperProperties.getConfigPackage() + "." + mapstructConfigName) .openWriter()) { - JavaFile.builder(AutoMapperProperties.getConfigPackage(), createConfigTypeSpec()).build().writeTo(writer); + JavaFile.builder(AutoMapperProperties.getConfigPackage(), createConfigTypeSpec(mapstructConfigName, adapterClassName)).build().writeTo(writer); } catch (IOException e) { processingEnv.getMessager() .printMessage(ERROR, @@ -27,17 +28,17 @@ public class MapperConfigGenerator { } } - private TypeSpec createConfigTypeSpec() { - return TypeSpec.interfaceBuilder(AutoMapperProperties.getConfigClassName()) + private TypeSpec createConfigTypeSpec(final String mapstructConfigName, final String adapterClassName) { + return TypeSpec.interfaceBuilder(mapstructConfigName) .addModifiers(Modifier.PUBLIC) - .addAnnotation(buildMapperConfigAnnotationSpec()) + .addAnnotation(buildMapperConfigAnnotationSpec(adapterClassName)) .build(); } - private AnnotationSpec buildMapperConfigAnnotationSpec() { + private AnnotationSpec buildMapperConfigAnnotationSpec(final String adapterClassName) { CodeBlock.Builder usesCodeBuilder = CodeBlock.builder().add("{"); usesCodeBuilder.add("$T.class", - ClassName.get(AutoMapperProperties.getAdapterPackage(), AutoMapperProperties.getAdapterClassName())); + ClassName.get(AutoMapperProperties.getAdapterPackage(), adapterClassName)); CodeBlock usesCodeBlock = usesCodeBuilder.add("}").build(); return AnnotationSpec.builder(ClassName.get("org.mapstruct", "MapperConfig")) .addMember("componentModel", diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/SpringAdapterMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/SpringAdapterMapperGenerator.java similarity index 57% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/SpringAdapterMapperGenerator.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/SpringAdapterMapperGenerator.java index 1124a30..139e932 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/SpringAdapterMapperGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/SpringAdapterMapperGenerator.java @@ -1,4 +1,4 @@ -package io.github.linpeilie.processor; +package io.github.linpeilie.processor.generator; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; @@ -6,43 +6,47 @@ import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.processor.AbstractAdapterMapperGenerator; +import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata; import java.util.Collection; import javax.lang.model.element.Modifier; public class SpringAdapterMapperGenerator extends AbstractAdapterMapperGenerator { @Override - protected TypeSpec createTypeSpec(Collection adapterMethods) { - TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder( - ClassName.get(AutoMapperProperties.getAdapterPackage(), AutoMapperProperties.getAdapterClassName())) + protected TypeSpec createTypeSpec(Collection adapterMethods, String adapterClassName) { + TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder(ClassName.get(adapterPackage(), adapterClassName)) .addModifiers(Modifier.PUBLIC) .addAnnotation(ClassName.get("org.springframework.stereotype", "Component")); - adapterMethods.forEach(adapterMethod -> adapterBuilder.addField(buildMapperField(adapterMethod.getMapper())) - .addMethod(buildMapperSetterMethod(adapterMethod.getMapper())) + adapterMethods.stream().map(AbstractAdapterMethodMetadata::getMapper) + .distinct() + .forEach(mapper -> adapterBuilder.addField(buildMapperField(mapper)) + .addMethod(buildMapperSetterMethod(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).build(); + return FieldSpec.builder(mapper, firstWordToLower(mapper.simpleName()), Modifier.PRIVATE).build(); } private String firstWordToLower(String str) { return str.substring(0, 1).toLowerCase() + str.substring(1); } - private MethodSpec buildProxyMethod(AdapterMethodMetadata adapterMethodMetadata) { + private MethodSpec buildProxyMethod(AbstractAdapterMethodMetadata adapterMethodMetadata) { ParameterSpec parameterSpec = ParameterSpec.builder(adapterMethodMetadata.getSource(), firstWordToLower(adapterMethodMetadata.getSource().simpleName())).build(); - return MethodSpec.methodBuilder(firstWordToLower(adapterMethodMetadata.getSource().simpleName()) + "To" + - adapterMethodMetadata.getTarget().simpleName()) + return MethodSpec.methodBuilder(adapterMethodMetadata.getMethodName()) .addModifiers(Modifier.PUBLIC) .addParameter(parameterSpec) - .returns(adapterMethodMetadata.getTarget()) - .addStatement("return $N.convert($N)", firstWordToLower(adapterMethodMetadata.getMapper().simpleName()), + .returns(adapterMethodMetadata.getReturn()) + .addStatement("return $N.$N($N)", firstWordToLower(adapterMethodMetadata.getMapper().simpleName()), + adapterMethodMetadata.getMapperMethodName(), firstWordToLower(adapterMethodMetadata.getSource().simpleName())) .build(); } @@ -52,18 +56,18 @@ public class SpringAdapterMapperGenerator extends AbstractAdapterMapperGenerator return MethodSpec.methodBuilder("set" + mapper.simpleName()) .addModifiers(Modifier.PUBLIC) .addParameter(parameterSpec) - .addAnnotation(AnnotationSpec.builder( - ClassName.get("org.springframework.beans.factory.annotation", "Autowired")) - .build()) + .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())) + return ParameterSpec.builder(mapper, firstWordToLower(mapper.simpleName())) .addAnnotation( AnnotationSpec.builder(ClassName.get("org.springframework.context.annotation", "Lazy")).build()) .build(); } + } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractAdapterMethodMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractAdapterMethodMetadata.java new file mode 100644 index 0000000..44bd832 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractAdapterMethodMetadata.java @@ -0,0 +1,30 @@ +package io.github.linpeilie.processor.metadata; + +import com.squareup.javapoet.ClassName; + +public abstract class AbstractAdapterMethodMetadata { + + public AbstractAdapterMethodMetadata(final ClassName source, ClassName mapper) { + this.source = source; + this.mapper = mapper; + } + + protected final ClassName source; + + protected final ClassName mapper; + + public abstract String getMethodName(); + + public abstract ClassName getReturn(); + + public abstract String getMapperMethodName(); + + public ClassName getSource() { + return source; + } + + public ClassName getMapper() { + return mapper; + } + +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractMapperMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractMapperMetadata.java new file mode 100644 index 0000000..4225adb --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AbstractMapperMetadata.java @@ -0,0 +1,30 @@ +package io.github.linpeilie.processor.metadata; + +import com.squareup.javapoet.ClassName; +import io.github.linpeilie.processor.AutoMapperProperties; +import org.apache.commons.lang3.StringUtils; + +public abstract class AbstractMapperMetadata { + + protected ClassName sourceClassName; + + public String mapperPackage() { + return StringUtils.isNotEmpty(AutoMapperProperties.getMapperPackage()) + ? AutoMapperProperties.getMapperPackage() : sourceClassName.packageName(); + } + + public abstract String mapperName(); + + public ClassName mapperClass() { + return ClassName.get(mapperPackage(), mapperName()); + } + + public ClassName getSourceClassName() { + return sourceClassName; + } + + public void setSourceClassName(final ClassName sourceClassName) { + this.sourceClassName = sourceClassName; + } + +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMapMethodMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMapMethodMetadata.java new file mode 100644 index 0000000..1a87981 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMapMethodMetadata.java @@ -0,0 +1,50 @@ +package io.github.linpeilie.processor.metadata; + +import com.squareup.javapoet.ClassName; +import java.lang.annotation.Target; + +public class AdapterMapMethodMetadata extends AbstractAdapterMethodMetadata { + + private final ClassName target; + + private final String methodName; + + private final String mapperMethodName; + + public AdapterMapMethodMetadata(final ClassName source, + final ClassName target, + final ClassName mapper, + boolean objectConverter) { + super(source, mapper); + this.target = target; + if (objectConverter) { + methodName = "objectTo" + source.simpleName(); + mapperMethodName = "convertByObj"; + } else { + methodName = "mapTo" + source.simpleName(); + mapperMethodName = "convert"; + } + } + + public static AdapterMapMethodMetadata newInstance(final ClassName source, + final ClassName target, + final ClassName mapper, + boolean objectConverter) { + return new AdapterMapMethodMetadata(source, target, mapper, objectConverter); + } + + @Override + public String getMethodName() { + return methodName; + } + + @Override + public ClassName getReturn() { + return target; + } + + @Override + public String getMapperMethodName() { + return mapperMethodName; + } +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AdapterMethodMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java similarity index 67% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AdapterMethodMetadata.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java index 33e67c8..f312423 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AdapterMethodMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java @@ -1,39 +1,37 @@ -package io.github.linpeilie.processor; +package io.github.linpeilie.processor.metadata; import com.squareup.javapoet.ClassName; -public class AdapterMethodMetadata { +public class AdapterMethodMetadata extends AbstractAdapterMethodMetadata { private AdapterMethodMetadata(final ClassName source, final ClassName target, ClassName mapper) { - this.source = source; + super(source, mapper); this.target = target; - this.mapper = mapper; } - private final ClassName source; - private final ClassName target; - private final ClassName mapper; - public static AdapterMethodMetadata newInstance(ClassName source, ClassName target, ClassName mapper) { return new AdapterMethodMetadata(source, target, mapper); } + @Override public String getMethodName() { return source.simpleName().substring(0, 1).toLowerCase() + source.simpleName().substring(1) + "To" + target.simpleName(); } - public ClassName getSource() { - return source; - } - public ClassName getTarget() { return target; } - public ClassName getMapper() { - return mapper; + @Override + public ClassName getReturn() { + return target; + } + + @Override + public String getMapperMethodName() { + return "convert"; } } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java new file mode 100644 index 0000000..b22e27c --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.processor.metadata; + +import io.github.linpeilie.processor.AutoMapperProperties; +import org.apache.commons.lang3.StringUtils; + +public class AutoMapMapperMetadata extends AutoMapperMetadata { + + @Override + public String mapperPackage() { + return StringUtils.isNotEmpty(AutoMapperProperties.getMapperPackage()) + ? AutoMapperProperties.getMapperPackage() : getTargetClassName().packageName(); + } +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java similarity index 58% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperMetadata.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java index 8ce2892..56fb324 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java @@ -1,12 +1,11 @@ -package io.github.linpeilie.processor; +package io.github.linpeilie.processor.metadata; import com.squareup.javapoet.ClassName; import java.util.List; -import org.apache.commons.lang3.StringUtils; -public class AutoMapperMetadata { +public class AutoMapperMetadata extends AbstractMapperMetadata { + - private ClassName sourceClassName; private ClassName targetClassName; @@ -14,24 +13,16 @@ public class AutoMapperMetadata { private List fieldMappingList; - public String mapperPackage() { - return StringUtils.isNotEmpty(AutoMapperProperties.getMapperPackage()) - ? AutoMapperProperties.getMapperPackage() : sourceClassName.packageName(); - } + private ClassName superClass; + + private ClassName[] superGenerics; + + private ClassName mapstructConfigClass; public String mapperName() { return sourceClassName.simpleName() + "To" + targetClassName.simpleName() + "Mapper"; } - public ClassName getSourceClassName() { - return sourceClassName; - } - - public AutoMapperMetadata setSourceClassName(final ClassName sourceClassName) { - this.sourceClassName = sourceClassName; - return this; - } - public ClassName getTargetClassName() { return targetClassName; } @@ -58,4 +49,28 @@ public class AutoMapperMetadata { this.fieldMappingList = fieldMappingList; return this; } + + public ClassName getSuperClass() { + return superClass; + } + + public ClassName[] getSuperGenerics() { + return superGenerics; + } + + public void setSuperGenerics(final ClassName[] superGenerics) { + this.superGenerics = superGenerics; + } + + public void setSuperClass(final ClassName superClass) { + this.superClass = superClass; + } + + public ClassName getMapstructConfigClass() { + return mapstructConfigClass; + } + + public void setMapstructConfigClass(final ClassName mapstructConfigClass) { + this.mapstructConfigClass = mapstructConfigClass; + } } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMappingMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java similarity index 96% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMappingMetadata.java rename to mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java index fae7a12..86e91c7 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMappingMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java @@ -1,4 +1,4 @@ -package io.github.linpeilie.processor; +package io.github.linpeilie.processor.metadata; public class AutoMappingMetadata { diff --git a/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringConverterFactory.java b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringConverterFactory.java index 97cc6b6..e3e91e7 100644 --- a/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringConverterFactory.java +++ b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringConverterFactory.java @@ -1,6 +1,7 @@ package io.github.linpeilie.mapstruct; import io.github.linpeilie.AbstractCachedConverterFactory; +import io.github.linpeilie.BaseMapMapper; import io.github.linpeilie.BaseMapper; import org.springframework.context.ApplicationContext; import org.springframework.core.ResolvableType; @@ -23,4 +24,15 @@ public class SpringConverterFactory extends AbstractCachedConverterFactory { } return (BaseMapper) applicationContext.getBean(beanNames[0]); } + + @Override + protected BaseMapMapper findMapMapper(final Class source) { + ResolvableType type = ResolvableType.forClassWithGenerics( + BaseMapMapper.class, source); + String[] beanNames = applicationContext.getBeanNamesForType(type); + if (beanNames.length == 0) { + return null; + } + return (BaseMapMapper) applicationContext.getBean(beanNames[0]); + } } diff --git a/mapstruct-plus/pom.xml b/mapstruct-plus/pom.xml index 9a46123..cca4476 100644 --- a/mapstruct-plus/pom.xml +++ b/mapstruct-plus/pom.xml @@ -23,6 +23,10 @@ org.mapstruct mapstruct + + cn.hutool + hutool-core + \ No newline at end of file diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/AbstractCachedConverterFactory.java b/mapstruct-plus/src/main/java/io/github/linpeilie/AbstractCachedConverterFactory.java index 834b580..79af169 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/AbstractCachedConverterFactory.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/AbstractCachedConverterFactory.java @@ -6,6 +6,8 @@ public abstract class AbstractCachedConverterFactory implements ConverterFactory private final ConcurrentHashMap mapperMap = new ConcurrentHashMap<>(); + private final ConcurrentHashMap mapMapperMap = new ConcurrentHashMap<>(); + @Override @SuppressWarnings("unchecked") public BaseMapper getMapper(final Class sourceType, final Class targetType) { @@ -21,8 +23,24 @@ public abstract class AbstractCachedConverterFactory implements ConverterFactory return null; } + @Override + public BaseMapMapper getMapMapper(final Class sourceType) { + final String key = sourceType.getName(); + if (mapMapperMap.contains(key)) { + return mapMapperMap.get(key); + } + final BaseMapMapper mapper = findMapMapper(sourceType); + if (mapper != null) { + mapMapperMap.put(key, mapper); + return mapper; + } + return null; + } + protected abstract BaseMapper findMapper(final Class source, final Class target); + protected abstract BaseMapMapper findMapMapper(final Class source); + private String key(Class source, Class target) { return source.getName() + "__" + target.getName(); } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/BaseMapMapper.java b/mapstruct-plus/src/main/java/io/github/linpeilie/BaseMapMapper.java new file mode 100644 index 0000000..b40b064 --- /dev/null +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/BaseMapMapper.java @@ -0,0 +1,19 @@ +package io.github.linpeilie; + +import java.util.Map; + +public interface BaseMapMapper { + + T convert(Map map); + + default T convertByObj(Object obj) { + if (obj == null) { + return null; + } + if (obj instanceof Map) { + return convert((Map) obj); + } + return null; + } + +} diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java b/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java index 6c03c5a..e3e0dbf 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java @@ -2,6 +2,8 @@ package io.github.linpeilie; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; public class Converter { @@ -52,4 +54,19 @@ public class Converter { return source.stream().map(item -> convert(item, targetType)).collect(Collectors.toList()); } + public T convert(Map map, Class target) { + if (map == null || map.isEmpty()) { + return null; + } + if (map.values().stream().allMatch(Objects::isNull)) { + return null; + } + final BaseMapMapper mapper = converterFactory.getMapMapper(target); + if (mapper != null) { + return mapper.convert(map); + } + throw new ConvertException("cannot find converter from " + map.getClass().getName() + " to " + + target.getClass().getSimpleName()); + } + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/ConverterFactory.java b/mapstruct-plus/src/main/java/io/github/linpeilie/ConverterFactory.java index 3447414..852559c 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/ConverterFactory.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/ConverterFactory.java @@ -4,4 +4,6 @@ public interface ConverterFactory { BaseMapper getMapper(Class sourceType, Class targetType); + BaseMapMapper getMapMapper(Class sourceType); + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java index ea5417c..bf2d043 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java @@ -83,6 +83,10 @@ public class DefaultConverterFactory extends AbstractCachedConverterFactory { return source.getSimpleName() + "To" + target.getSimpleName() + "Mapper"; } + private String getMapMapperClassName(Class source) { + return "MapTo" + source.getSimpleName() + "Mapper"; + } + private String getMapperPackage(Class sourceType) { return basePackage != null && !basePackage.isEmpty() ? basePackage : sourceType.getPackage().getName(); @@ -100,4 +104,14 @@ public class DefaultConverterFactory extends AbstractCachedConverterFactory { } } + @Override + protected BaseMapMapper findMapMapper(final Class source) { + final String mapperClassName = getMapMapperClassName(source); + try { + final Class mapperClass = Class.forName(getMapperPackage(source) + "." + mapperClassName); + return (BaseMapMapper) Mappers.getMapper(mapperClass); + } catch (ClassNotFoundException e) { + return null; + } + } } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapMapper.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapMapper.java new file mode 100644 index 0000000..12d4cf7 --- /dev/null +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapMapper.java @@ -0,0 +1,18 @@ +package io.github.linpeilie.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 为添加当前注解的类生成 Map 转为当前类的转换接口 + * + * @author linpl + * @since 1.1.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface AutoMapMapper { + +} diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/map/MapObjectConvert.java b/mapstruct-plus/src/main/java/io/github/linpeilie/map/MapObjectConvert.java new file mode 100644 index 0000000..1e1a653 --- /dev/null +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/map/MapObjectConvert.java @@ -0,0 +1,81 @@ +package io.github.linpeilie.map; + +import cn.hutool.core.convert.Convert; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Calendar; +import java.util.Currency; +import java.util.Date; + +public class MapObjectConvert { + + public static String objToString(Object obj) { + return Convert.toStr(obj); + } + + public static BigDecimal objToBigDecimal(Object obj) { + return Convert.toBigDecimal(obj); + } + + public static BigInteger objToBigInteger(Object obj) { + return Convert.toBigInteger(obj); + } + + public static Integer objToInteger(Object obj) { + return Convert.toInt(obj); + } + + public static Long objToLong(Object obj) { + return Convert.toLong(obj); + } + + public static Double objToDouble(Object obj) { + return Convert.toDouble(obj); + } + + public static Number objToNumber(Object obj) { + return Convert.toNumber(obj); + } + + public static Boolean objToBoolean(Object obj) { + return Convert.toBool(obj); + } + + public static Date objToDate(Object obj) { + return Convert.toDate(obj); + } + + public static LocalDateTime objToLocalDateTime(Object obj) { + return Convert.toLocalDateTime(obj); + } + + public static LocalDate objToLocalDate(Object obj) { + return Convert.convert(LocalDate.class, obj); + } + + public static LocalTime objToLocalTime(Object obj) { + return Convert.convert(LocalTime.class, obj); + } + + public static URI objToUri(Object obj) { + return Convert.convert(URI.class, obj); + } + + public static URL objToUrl(Object obj) { + return Convert.convert(URL.class, obj); + } + + public static Calendar objToCalendar(Object obj) { + return Convert.convert(Calendar.class, obj); + } + + public static Currency objToCurrency(Object obj) { + return Convert.convert(Currency.class, obj); + } + +} diff --git a/pom.xml b/pom.xml index 9c957d2..99d4c98 100644 --- a/pom.xml +++ b/pom.xml @@ -17,11 +17,12 @@ - 1.0.0 + 1.1.0 8 8 UTF-8 1.5.1.Final + 5.8.9 https://github.com/linpeilie/mapstruct-plus.git @@ -62,6 +63,11 @@ spring-core 5.3.23 + + cn.hutool + hutool-core + ${hutool.version} + @@ -110,6 +116,9 @@ org.apache.maven.plugins maven-javadoc-plugin 2.9.1 + + ${java.home}/../bin/javadoc + attach-javadocs