From 2ee265c21386e6616b45b8976353e91f56b5d57a Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Fri, 19 Jul 2024 18:09:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20apt=20=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github/yulichang/annotation/Table.java | 32 +++- .../com/github/yulichang/apt/OgnlRoot.java | 4 +- .../yulichang/processor/EntityProcessor.java | 38 ++-- .../yulichang/processor/matedata/Conf.java | 162 ++++++++++++++++++ .../processor/matedata/TableInfo.java | 38 +++- 5 files changed, 244 insertions(+), 30 deletions(-) create mode 100644 plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/Conf.java diff --git a/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/Table.java b/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/Table.java index 89c6ce4..a29c5a2 100644 --- a/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/Table.java +++ b/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/Table.java @@ -8,25 +8,33 @@ import java.lang.annotation.Target; /** * apt注解 *

+ * 默认为String.format + *

+ * 举例: + *

+ *

* 支持Ognl语法字段说明
* Ognl上下文 *

- *

* 指定开头 Ognl# 这不是ognl语法,这是MPJ规定的 用于区分 ognl还是String.format *

* 举例: *

*

* 支持 三元运算 String所有方法 如lastIndexOf subString toUpperCase等 Ognl语法

- * 若想扩展stringHelper可在github交流 * * @author yulichang * @since 1.5.0 @@ -49,6 +57,18 @@ public @interface Table { */ String packageName() default "%s.apt"; + /** + * 是否在Tables中生成对应的类字段 + */ + boolean genTables() default true; + + /** + * Tables中的字段名 默认大写的类名 + *

+ * 支持Ognl 默认使用String.format() + */ + String tablesPackageName() default "%s.tables"; + /** * Tables中的字段名 默认大写的类名 *

diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/apt/OgnlRoot.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/apt/OgnlRoot.java index 69bdcda..1560e91 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/apt/OgnlRoot.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/apt/OgnlRoot.java @@ -27,11 +27,11 @@ public class OgnlRoot { /** * 类名 */ - private final String className; + public final String className; /** * 包名 */ - private final String packageName; + public final String packageName; public ClassInfo(String className, String packageName) { diff --git a/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/EntityProcessor.java b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/EntityProcessor.java index 7c99160..2544685 100644 --- a/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/EntityProcessor.java +++ b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/EntityProcessor.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.github.yulichang.annotation.Table; import com.github.yulichang.apt.BaseColumn; import com.github.yulichang.apt.Column; +import com.github.yulichang.processor.matedata.Conf; import com.github.yulichang.processor.matedata.FieldInfo; import com.github.yulichang.processor.matedata.TableInfo; import com.github.yulichang.processor.utils.StringUtil; @@ -13,19 +14,13 @@ import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; import java.io.Writer; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -38,6 +33,7 @@ public class EntityProcessor extends AbstractProcessor { private Elements elementUtils; private Types typeUtils; private Messager messager; + private Conf globalConf; @Override public synchronized void init(ProcessingEnvironment processingEnv) { @@ -45,6 +41,11 @@ public class EntityProcessor extends AbstractProcessor { this.elementUtils = processingEnv.getElementUtils(); this.typeUtils = processingEnv.getTypeUtils(); this.messager = processingEnv.getMessager(); + this.globalConf = new Conf(processingEnv.getFiler(), this::note); + } + + private void note(String msg) { + messager.printMessage(Diagnostic.Kind.NOTE, msg + " - " + UUID.randomUUID()); } @@ -53,10 +54,12 @@ public class EntityProcessor extends AbstractProcessor { if (!roundEnv.processingOver()) { TypeElement table = annotations.stream().filter(i -> i.toString().equals(Table.class.getName())).findFirst().orElse(null); if (table != null) { + note("mybatis plus join processor start"); Set tables = roundEnv.getElementsAnnotatedWith(table); tables.stream().filter(f -> f instanceof TypeElement) .map(f -> (TypeElement) f).map(this::createColumn) - .collect(Collectors.groupingBy(TableInfo::getClassPackage)) + .filter(Objects::nonNull).filter(TableInfo::isGenTables) + .collect(Collectors.groupingBy(TableInfo::getTagTablesPackageName)) .forEach(this::createTables); } } @@ -80,7 +83,16 @@ public class EntityProcessor extends AbstractProcessor { * 生成Column类 */ private TableInfo createColumn(TypeElement element) { - TableInfo tableInfo = new TableInfo(element.getAnnotation(Table.class), element.toString(), element.getSimpleName().toString()); + AnnotationMirror tb = element.getAnnotationMirrors().stream().filter(a -> + a.getAnnotationType().asElement().toString().equals(Table.class.getName())).findFirst().orElse(null); + Table table = element.getAnnotation(Table.class); + if (tb == null) { + return null; + } + Set keySet = tb.getElementValues().keySet().stream().map(k -> + k.getSimpleName().toString()).collect(Collectors.toSet()); + Conf conf = Conf.getConf(globalConf, table, keySet); + TableInfo tableInfo = new TableInfo(conf, element.toString(), element.getSimpleName().toString()); tableInfo.setClassPackage(elementUtils.getPackageOf(element).getQualifiedName().toString()); tableInfo.setClassComment(elementUtils.getDocComment(element)); @@ -127,7 +139,7 @@ public class EntityProcessor extends AbstractProcessor { private void createTables(String tagPackage, List tableInfos) { StringBuilderHelper content = new StringBuilderHelper(); // package - content.addPackage(tagPackage + ".tables"); + content.addPackage(tagPackage); content.newLine(); // import tableInfos.forEach(tableInfo -> content.addImport(tableInfo.getTagPackage() + "." + tableInfo.getTagClassName())); @@ -141,7 +153,7 @@ public class EntityProcessor extends AbstractProcessor { // 添加table字段 .addTablesFields(tableInfos)); - writerFile(tagPackage + ".tables.Tables", content.getContent()); + writerFile(tagPackage + ".Tables", content.getContent()); } private void writerFile(String fullClassName, String content) { @@ -220,7 +232,7 @@ public class EntityProcessor extends AbstractProcessor { addComment("\t", tableInfo.getClassComment()); sb.append(String.format("\tpublic static final %s %s = new %s();\n", tableInfo.getTagClassName(), - String.format(tableInfo.getTableAnnotation().tablesName(), tableInfo.getSimpleClassName()), + String.format(tableInfo.getTagTablesName(), tableInfo.getSimpleClassName()), tableInfo.getTagClassName())); newLine(); }); diff --git a/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/Conf.java b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/Conf.java new file mode 100644 index 0000000..da5adee --- /dev/null +++ b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/Conf.java @@ -0,0 +1,162 @@ +package com.github.yulichang.processor.matedata; + +import com.github.yulichang.annotation.Table; + +import javax.annotation.processing.Filer; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.Properties; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +public class Conf { + + private String className = "%sCol"; + private String packageName = "%s.apt"; + private boolean genTables = true; + private String tablasPackageName = "%s.tables"; + private String tablesName = "%S"; + + private boolean initFlag = false; + + private Conf(Conf conf) { + this.className = conf.className; + this.packageName = conf.packageName; + this.genTables = conf.genTables; + this.tablasPackageName = conf.tablasPackageName; + this.tablesName = conf.tablesName; + this.initFlag = conf.initFlag; + } + + + public Conf(Filer filer, Consumer log) { + try { + FileObject confPath = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "mybatis-plus-join"); + File file = new File(confPath.toUri()).getParentFile(); + int loop = 0; + while (file != null && file.exists() && file.isDirectory()) { + loop++; + File[] files = file.listFiles(); + if (files != null && files.length > 0) { + File confFile = Arrays.stream(files).filter(f -> f.getName().equals("mybatis-plus-join.properties")).findFirst().orElse(null); + if (confFile != null && confFile.exists()) { + log.accept(String.format("use mybatis-plus-join.properties %s", confFile.getAbsolutePath())); + this.init(confFile); + break; + } + } + file = file.getParentFile(); + if (loop > 50) { + break; + } + } + if (!this.initFlag) { + log.accept("not find mybatis-plus-join.properties use default setting"); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void init(File confFile) throws IOException { + this.initFlag = true; + Properties properties = new Properties(); + properties.load(Files.newInputStream(confFile.toPath())); + this.className = properties.getOrDefault("className", this.className).toString(); + this.packageName = properties.getOrDefault("packageName", this.packageName).toString(); + this.genTables = Boolean.parseBoolean(properties.getOrDefault("genTables", Boolean.toString(this.genTables)).toString()); + this.tablasPackageName = properties.getOrDefault("tablasPackageName", this.tablasPackageName).toString(); + this.tablesName = properties.getOrDefault("tablesName", this.tablesName).toString(); + } + + public static Conf getConf(Conf globalConf, Table table, Collection keys) { + if (keys == null || keys.isEmpty()) { + return globalConf; + } + Conf conf = new Conf(globalConf); + keys.forEach(key -> ConfItem.doIt(conf, key, table)); + return conf; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public boolean isGenTables() { + return genTables; + } + + public void setGenTables(boolean genTables) { + this.genTables = genTables; + } + + public String getTablasPackageName() { + return tablasPackageName; + } + + public void setTablasPackageName(String tablasPackageName) { + this.tablasPackageName = tablasPackageName; + } + + public String getTablesName() { + return tablesName; + } + + public void setTablesName(String tablesName) { + this.tablesName = tablesName; + } + + public enum ConfItem { + className("value", Table::value, (c, v) -> c.setClassName(v.toString())), + packageName("packageName", Table::packageName, (c, v) -> c.setPackageName(v.toString())), + genTables("genTables", Table::genTables, (c, v) -> c.setGenTables((boolean) v)), + tablasPackageName("tablasPackageName", Table::tablesPackageName, (c, v) -> c.setTablasPackageName(v.toString())), + tablesName("tablesName", Table::tablesName, (c, v) -> c.setTablesName(v.toString())); + + private final String action; + + private final Function annoVal; + + private final BiConsumer doIt; + + ConfItem(String action, Function annoVal, BiConsumer doIt) { + this.action = action; + this.annoVal = annoVal; + this.doIt = doIt; + } + + public static void doIt(Conf tableConf, String act, Table anno) { + Arrays.stream(ConfItem.values()).filter(f -> f.action.equals(act)).findFirst() + .ifPresent(item -> item.doIt.accept(tableConf, item.annoVal.apply(anno))); + } + } + + @Override + public String toString() { + return "Conf{" + + "className='" + className + '\'' + + ", packageName='" + packageName + '\'' + + ", genTables=" + genTables + + ", tablasPackageName='" + tablasPackageName + '\'' + + ", tablesName='" + tablesName + '\'' + + '}'; + } +} diff --git a/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/TableInfo.java b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/TableInfo.java index c6d7a93..1232879 100644 --- a/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/TableInfo.java +++ b/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/matedata/TableInfo.java @@ -1,6 +1,5 @@ package com.github.yulichang.processor.matedata; -import com.github.yulichang.annotation.Table; import com.github.yulichang.apt.OgnlRoot; import org.apache.ibatis.builder.BuilderException; import org.apache.ibatis.ognl.Ognl; @@ -27,15 +26,17 @@ public class TableInfo { private String classPackage; - private final Table tableAnnotation; + private final Conf conf; private Set fields; private String tagClassName; private String tagPackageName; + private String tagTablesName; + private String tagTablesPackageName; - public TableInfo(Table tableAnnotation, String className, String simpleClassName) { - this.tableAnnotation = tableAnnotation; + public TableInfo(Conf conf, String className, String simpleClassName) { + this.conf = conf; this.className = className; this.simpleClassName = simpleClassName; } @@ -45,7 +46,7 @@ public class TableInfo { */ public String getTagClassName() { if (tagClassName == null) { - tagClassName = parse(tableAnnotation.value(), this.simpleClassName); + tagClassName = parse(conf.getClassName(), this.simpleClassName); } return tagClassName; } @@ -55,11 +56,30 @@ public class TableInfo { */ public String getTagPackage() { if (tagPackageName == null) { - tagPackageName = parse(tableAnnotation.packageName(), this.classPackage); + tagPackageName = parse(conf.getPackageName(), this.classPackage); } return tagPackageName; } + /** + * 获取Tables的字段名 + */ + public String getTagTablesName() { + if (tagTablesName == null) { + tagTablesName = parse(conf.getTablesName(), this.simpleClassName); + } + return tagTablesName; + } + + /** + * 获取Tables的路径 + */ + public String getTagTablesPackageName() { + if (tagTablesPackageName == null) { + tagTablesPackageName = parse(conf.getTablasPackageName(), this.classPackage); + } + return tagTablesPackageName; + } private String parse(String expression, String source) { String tag; @@ -94,7 +114,7 @@ public class TableInfo { this.classComment = classComment; } - public String getClassPackage() { + public String getClassPackage1() { return classPackage; } @@ -102,8 +122,8 @@ public class TableInfo { this.classPackage = classPackage; } - public Table getTableAnnotation() { - return tableAnnotation; + public boolean isGenTables() { + return this.conf.isGenTables(); } public Set getFields() {