美文网首页java 脑洞
java脑洞 效率工程利器-代码解析maven插件 enum-e

java脑洞 效率工程利器-代码解析maven插件 enum-e

作者: 灰色调诺言 | 来源:发表于2024-08-06 17:57 被阅读0次

    前文介绍了核心组件: java脑洞 效率工程利器-代码解析工具 lp-base-export

    本文主要是介绍如何通过maven插件配合lp-base-export实现枚举的解析

    1. 先分享完整的demo :enum-export-plugin

    第一步: 引入maven插件
    <plugin>
                    <groupId>io.github.wqr503</groupId>
                    <artifactId>enum-export-plugin</artifactId>
                    <version>1.3.0.FINAL</version>
                    <configuration>
                        <taskList>
                            <task>
                                <id>enumTask</id>
                                <outPutDirection>${project.basedir}/export</outPutDirection>
                                <!--                            <classPaths>-->
                                <!--                                <classPath>${project.basedir}/target/classes</classPath>-->
                                <!--                            </classPaths>-->
                                <sourcePath>${project.basedir}/src/main/java</sourcePath>
                                <dependencyPaths>
                                    <dependencyPath>${project.basedir}/target/lib</dependencyPath>
                                </dependencyPaths>
                                <logLevel>DEBUG</logLevel>
                                <logParam>true</logParam>
                                <mvlText>
                                    <![CDATA[
    public interface CombinationEnum {
    @foreach{entity : entityList}
        // @{entity.typeName}
        String @{entity.name} = "@if{entity.desc != null}@{entity.desc} : @end{}@foreach{data : entity.valueList}@if{data.fieldList.size() > 0}@{data.fieldList[0].value}@end{}@if{data.fieldList.size() <= 0}@{data.ordinal}@end{}:@{data.name}(@if{data.desc != null}@{data.desc}@end{}),@end{}";
    @end{}
    }
      ]]>
                                </mvlText>
                            </task>
                        </taskList>
                    </configuration>
                </plugin>
    
    第二步: 启用maven插件
    image.png
    第三步:查看输出路径
    image.png

    2. 手把手教你如何做插件

    lp-export-maven-common项目(结合maven的通用向项目)

    源码地址: https://gitee.com/wqrzsy/lp-demo/tree/master/lp-export-maven-common
    引入maven插件相关的包和lp-base-export包

            <dependency>
                <groupId>io.github.wqr503</groupId>
                <artifactId>lp-base-export</artifactId>
                <version>1.3.0.FINAL</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.maven</groupId>
                <artifactId>maven-core</artifactId>
                <version>3.5.4</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.maven</groupId>
                <artifactId>maven-plugin-api</artifactId>
                <version>3.5.4</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.maven.plugin-tools</groupId>
                <artifactId>maven-plugin-annotations</artifactId>
                <version>3.5.2</version>
            </dependency>
    

    然后实现maven插件的入口AbstractMojo

    //@Mojo()
    public abstract class CommonMojo<T extends ExportTask> extends AbstractMojo {
    
        protected abstract List<T> getTaskList();
    
        protected abstract Process getProcess(T task);
    
        @Override
        public void execute() throws MojoExecutionException, MojoFailureException {
            MavenLocalLoggerFactory loggerFactory = new MavenLocalLoggerFactory(this);
            LogHandler.changeFactory(loggerFactory);
            for (T task : getTaskList()) {
                try {
                    getLog().info("执行任务 : " + task.getId());
                    Process process = getProcess(task);
                    process.execute();
                    getLog().info("执行任务 : " + task.getId() + " 完毕");
                } catch (Exception e) {
                    getLog().error(task.getId() + " 任务执行失败", e);
                }
            }
        }
    }
    

    这里注意到,为了实现多任务执行,我这里改造成列表形式

    lp-export-maven-plugin项目(maven插件项目)

    源码地址:https://gitee.com/wqrzsy/lp-demo/tree/master/lp-export-maven-plugin
    由于maven插件需要以pom形式打包,所以我们另起一个项目,然后pom文件如下

    <dependencies>
    
            <dependency>
                <groupId>io.github.wqr503</groupId>
                <artifactId>lp-export-maven-common</artifactId>
                <version>1.3.0.FINAL</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
    
    <!--            添加maven-plugin-plugin插件依赖,这个包可以使插件支持JDK1.8以上的版本-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-plugin-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <goalPrefix>lp</goalPrefix>
                        <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                    </configuration>
                </plugin>
    
    <!--            addDefaultImplementationEntries 会在生成的jar包的META-INF目录下的MANIFEST.MF文件里生成版本信息-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.3.0</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
    
            </plugins>
        </build>
    
    enum-export-plugin项目(具体实现项目,到这里就可以随意按想象力发挥了)

    源码地址: https://gitee.com/wqrzsy/lp-demo/tree/master/enum-export-plugin
    首先引入maven

        <parent>
            <groupId>io.github.wqr503</groupId>
            <artifactId>lp-export-maven-plugin</artifactId>
            <version>1.3.0.FINAL</version>
        </parent>
    

    然后定义启动名(插件列表看到的名字)

    @Mojo(name = "enumExportAll")
    public class EnumExport extends CommonMojo<CommonExportTask> {
    
        @Parameter
        private List<CommonExportTask> taskList;
    
        @Override
        protected List<CommonExportTask> getTaskList() {
            return taskList;
        }
    
        @Override
        protected Process getProcess(CommonExportTask commonExportTask) {
            getLog().info(JSONAide.toJson(commonExportTask));
            // 判断是否聚合输出
            if(commonExportTask.isCombination()) {
                return new EnumCombinationExportAll(commonExportTask);
            } else {
                return new EnumExportAll(commonExportTask);
            }
        }
    
    }
    

    具体实现

    /** 聚合输出plugin */
    public class EnumCombinationExportAll extends CommonCombinationExportAllProcess {
    
        public EnumCombinationExportAll(CommonExportTask exportTask) {
            super(exportTask.getOutPutDirection(), exportTask.getSourcePath(), exportTask.getClassPaths(),
                    exportTask.getBasePackages(), exportTask.getDependencyPaths(), exportTask.getMvlPath(),
                    exportTask.getMvlText(), exportTask.isLogParam(), exportTask.getOutPutFileName(),
                    exportTask.getLogLevel());
        }
    
        /** 显示用途 */
        @Override
        public String getProcessName() {
            return "EnumCombinationExportAll";
        }
    
        /** 构建对象转mvl的属性 */
        @Override
        protected TableAttribute createTableAttribute() {
            return new TableAttribute() {
    
                private List<EnumEntity> entityList = new ArrayList<>();
    
                public void putAttribute(ScanClassInfo classInfo, TypeFormatter typeFormatter) {
                    EnumEntity enumEntity = new EnumEntity();
                    //从枚举上提取类名
                    enumEntity.setName(classInfo.getSimpleName());
                    //从枚举上提取描述
                    enumEntity.setDesc(classInfo.getSourceClass().getDesc());
                    //从枚举上提取类名
                    enumEntity.setTypeName(classInfo.getClassName());
                    List<EnumValueEntity> valueList = new ArrayList<>();
                    //从枚举上提取枚举值
                    List<SourceEnumValue> enumValueList = classInfo.getSourceClass().getEnumValueList();
                    // 遍历枚举值
                    for (SourceEnumValue sourceEnumValue : enumValueList) {
                        EnumValueEntity enumValueEntity = new EnumValueEntity();
                        // 获取枚举值名字
                        enumValueEntity.setName(sourceEnumValue.getName());
                        // 获取枚举值描述
                        enumValueEntity.setDesc(sourceEnumValue.getDesc());
                        // 获取枚举值顺序
                        enumValueEntity.setOrdinal(sourceEnumValue.getOrdinal());
                        List<EnumValueFieldEntity> fieldList = new ArrayList<>();
                        // 获取枚举值构造列表
                        if(BlankAide.isNotBlank(sourceEnumValue.getFieldList())) {
                            for (SourceEnumValueField enumValueField : sourceEnumValue.getFieldList()) {
                                EnumValueFieldEntity fieldEntity = new EnumValueFieldEntity();
                                fieldEntity.setName(enumValueField.getName());
                                fieldEntity.setValue(enumValueField.getValue());
                                fieldList.add(fieldEntity);
                            }
                        }
                        enumValueEntity.setFieldList(fieldList);
                        valueList.add(enumValueEntity);
                    }
                    enumEntity.setValueList(valueList);
                    entityList.add(enumEntity);
                }
    
                @Override
                public Map<String, Object> getAttribute() {
                    // 按key - value 输出给mvl,在mvl就能通过该key获取到对应对象
                    Map<String, Object> map = new HashMap<>();
                    map.put("entityList", entityList);
                    return map;
                }
    
            };
        }
    
        /** 扫描过滤器 */
        @Override
        protected ClassFilter createClassFilter() {
            return ClassFilterHelper.ofInclude(new Predicate<ScanClassInfo>() {
                @Override
                public boolean test(ScanClassInfo scanClassInfo) {
                    // 判断是否枚举
                    return scanClassInfo.getSourceClass().getClassType().isEnum();
                }
            });
        }
    
    }
    

    插件字段描述

        /** 任务id */
        private String id;
    
        /** 输出路径 */
        protected String outPutDirection;
    
        /** 源文件路径 (sourcePath和classPaths二选一)*/
        protected String sourcePath;
    
        /** class文件路径(sourcePath和classPaths二选一) */
        protected String[] classPaths;
    
        /** 搜索的包路径(可空) */
        protected String[] basePackages;
    
        /** 依赖路径(可空) */
        protected String[] dependencyPaths;
    
        /** mvel文件地址(系统路径或者ClassLoader下资源名) */
        protected String mvlPath;
    
        /** mvel表达式 (mvlPath和mvlText二选一)*/
        protected String mvlText;
    
        /** 是否打印参数 */
        protected boolean logParam;
    
        /** 输出文件名 */
        protected String outPutFileName;
    
        /** 设置打印等级 ERROR,WARN,INFO,DEBUG,TRACE */
        protected String logLevel;
    
        /** 聚合输出 */
        protected boolean combination = true;
    

    结语

    有个maven插件的支持,你就会发现代码解析就是这么简单的事,那剩下的就是通过根据不同场景进行定制开发了,比如提取DO中字段的注释然后生成SQL脚本,提取接口生成描述脚本等等等

    如果这篇文章对你有帮助请给个star


    image.png

    相关文章

      网友评论

        本文标题:java脑洞 效率工程利器-代码解析maven插件 enum-e

        本文链接:https://www.haomeiwen.com/subject/dezfkjtx.html