liuyanming6 3 years ago
parent
commit
64ba16cb66

+ 58 - 0
pom.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.shoulder.plugins</groupId>
+    <!--插件命名遵守${prefix}-maven-plugin-->
+    <artifactId>error-code-generator-maven-plugin</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>maven-plugin</packaging>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>3.3.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.5.2</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <version>3.5.2</version>
+                <configuration>
+                    <!-- 或者在类的注视上添加一个descriptor -->
+                    <!-- Needed for Java 5 annotation based configuration, for some reason. -->
+                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 139 - 0
src/main/java/org/shoulder/maven/plugins/mojo/ClassUtil.java

@@ -0,0 +1,139 @@
+package org.shoulder.maven.plugins.mojo;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author lym
+ */
+public class ClassUtil {
+
+    public static void main(String[] args) {
+        getAllSonOfClass(ClassUtil.class.getPackage().getName(), ErrorCode.class);
+        System.out.println();
+    }
+
+    public static <T> List<Class<? extends T>> getAllSonOfClass(String packageName, Class<T> clazz) {
+        return filterSonOfClass(getAllClass(packageName), clazz);
+    }
+
+    @SuppressWarnings({"unchecked"})
+    private static <T> List<Class<? extends T>> filterSonOfClass(Collection<Class<?>> allClass, Class<T> clazz) {
+        List<Class<? extends T>> list = new LinkedList<>();
+        try {
+            for (Class aClass : allClass) {
+                if (clazz.isAssignableFrom(aClass)) {
+                    // 自身并不加进去
+                    if (!clazz.equals(aClass)) {
+                        list.add(aClass);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("error when scan package");
+        }
+        return list;
+    }
+
+    /**
+     * 从一个指定路径下查找所有的类
+     */
+    @SuppressWarnings("rawtypes")
+    private static List<Class<?>> getAllClass(String packageName) {
+        ArrayList<Class<?>> classes = new ArrayList<>();
+        //先把包名转换为路径,首先得到项目的classpath
+        String classpath = ClassUtil.class.getResource("/").getPath();
+        //然后把我们的包名basPach转换为路径名
+        packageName = packageName.replace(".", File.separator);
+        //然后把classpath和basePack合并
+        String searchPath = classpath + packageName;
+        List<String> classPaths = new LinkedList<>();
+        doPath(new File(searchPath), classPaths);
+        //这个时候我们已经得到了指定包下所有的类的绝对路径了。我们现在利用这些绝对路径和java的反射机制得到他们的类对象
+        for (String s : classPaths) {
+            //把 D:\work\code\20170401\search-class\target\classes\com\baibin\search\a\A.class 这样的绝对路径转换为全类名com.baibin.search.a.A
+            s = s.replace(classpath.replace("/","\\").replaceFirst("\\\\",""),"").replace("\\",".").replace(".class","");
+            Class cls = null;
+            try {
+                cls = Class.forName(s);
+            } catch (ClassNotFoundException e) {
+                //log.error("class not found " + s, e);
+            }
+            classes.add(cls);
+        }
+        return classes;
+    }
+
+    private static void doPath(File file, List<String> allFile) {
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            if (files != null) {
+                for (File f : files) {
+                    doPath(f, allFile);
+                }
+            }
+        } else {
+            if (file.getName().endsWith(".class")) {
+                //如果是class文件我们就放入我们的集合中。
+                allFile.add(file.getPath());
+            }
+        }
+    }
+
+
+
+    @FunctionalInterface
+    interface FileScanFilter {
+        boolean include(File file);
+    }
+
+    abstract class AbstractFileScanFilter implements FileScanFilter {
+
+        protected FileScanFilter delegate;
+
+        AbstractFileScanFilter(FileScanFilter delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public boolean include(File file) {
+            return delegate == null ? isWanted(file) :
+                    delegate.include(file) && isWanted(file);
+        }
+
+        protected abstract boolean isWanted(File file);
+
+
+    }
+
+    class ClassFileFilter extends AbstractFileScanFilter {
+
+        public ClassFileFilter(FileScanFilter delegate) {
+            super(delegate);
+        }
+
+        @Override
+        public boolean isWanted(File file) {
+            return file.getName().endsWith(".class");
+        }
+    }
+
+    class SpecialTypeFilter extends ClassFileFilter {
+
+        private Class<?> type;
+
+        public SpecialTypeFilter(FileScanFilter delegate, Class<?> type) {
+            super(delegate);
+            this.type = type;
+        }
+
+        @Override
+        public boolean isWanted(File file) {
+            return super.isWanted(file) && type.getTypeName().equals(file.getName().substring(0,
+                    file.getName().length() - ".class".length()));
+        }
+    }
+}

+ 146 - 0
src/main/java/org/shoulder/maven/plugins/mojo/CodeLineCounter.java

@@ -0,0 +1,146 @@
+package org.shoulder.maven.plugins.mojo;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 统计代码行数(用于测试)
+ *
+ * @author lym
+ * @goal 统计代码行数
+ */
+@Mojo(name = "countLine")
+public class CodeLineCounter extends AbstractMojo {
+
+    private static final String[] INCLUDES_DEFAULT = {"properties", "xml", "java", "yml"};
+
+    @Parameter(defaultValue = "${basedir}")
+    private File baseDir;
+
+    @Parameter(defaultValue = "${project.build.resources}", readonly = true, required = true)
+    private List<Resource> resources;
+
+    @Parameter(defaultValue = "${project.build.sourceDirectory}", required = true, readonly = true)
+    private File sourceDir;
+
+    @Parameter(defaultValue = "${project.build.testResources}", readonly = true, required = true)
+    private List<Resource> testResources;
+
+    @Parameter(defaultValue = "${project.build.testSourceDirectory}", readonly = true, required = true)
+    private File testSourceDir;
+
+    @Parameter(property = "count.include")
+    private String[] includes;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+        getLog().info("baseDir目录" + baseDir);
+        if (includes == null || includes.length == 0) {
+            includes = INCLUDES_DEFAULT;
+        }
+
+        try {
+            countDir(sourceDir);
+
+            countDir(testSourceDir);
+
+            for (Resource resource : resources) {
+                countDir(new File(resource.getDirectory()));
+            }
+
+            for (Resource testResource : testResources) {
+                countDir(new File(testResource.getDirectory()));
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException(e.getMessage());
+        }
+    }
+
+    private void showInclude() {
+        getLog().info("include包括" + Arrays.asList(includes));
+    }
+
+    public void countDir(File file) throws IOException {
+
+        for (String fileType : includes) {
+            int fileNum = countFileNum(file, fileType);
+            int codeLineNum = countLineNum(file, fileType);
+            if(fileNum == 0 || codeLineNum == 0) {
+                continue;
+            }
+            getLog().info(file.getAbsolutePath().substring(baseDir.getName().length() + "de\\javaCode\\".length()) +
+                    " 共 " + fileNum + " 个 " + fileType + " 文件. " + codeLineNum + " 行代码:");
+        }
+    }
+
+    /**
+     * 统计文件多少个
+     */
+    public int countFileNum(File file, String fileType) {
+        int num = 0;
+        if (file.isFile() && file.getName().endsWith("." + fileType)) {
+            return 1;
+        }
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            if(files != null){
+                for (File f : files) {
+                    num += countFileNum(f, fileType);
+                }
+            }
+        }
+        return num;
+    }
+
+    /**
+     * 统计文件多少行
+     */
+    public int countLineNum(File file, String fileType) throws IOException {
+        int lineNum = 0;
+        if (file.isFile() && file.getName().endsWith("." + fileType)) {
+            BufferedReader br = new BufferedReader(new FileReader(file));
+            String line = "";
+            while ((line = br.readLine()) != null) {
+                if(!isBlank(line)){
+                    lineNum++;
+                }
+            }
+            return lineNum;
+        }
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            if(files != null){
+                for (File f : files) {
+                    lineNum += countLineNum(f, fileType);
+                }
+            }
+        }
+        return lineNum;
+    }
+
+    public static boolean isBlank(final CharSequence cs) {
+        int strLen;
+        if (cs == null || (strLen = cs.length()) == 0) {
+            return true;
+        }
+        for (int i = 0; i < strLen; i++) {
+            if (!Character.isWhitespace(cs.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

+ 4 - 0
src/main/java/org/shoulder/maven/plugins/mojo/ErrorCode.java

@@ -0,0 +1,4 @@
+package org.shoulder.maven.plugins.mojo;
+
+public interface ErrorCode {
+}

+ 36 - 0
src/main/java/org/shoulder/maven/plugins/mojo/ErrorCodeInfoGenerator.java

@@ -0,0 +1,36 @@
+package org.shoulder.maven.plugins.mojo;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+import java.io.File;
+
+/**
+ * 生成错误码文档
+ *
+ * @author lym
+ * @goal 生成错误码文档
+ */
+@Mojo(name = "generateErrorCodeInfo")
+public class ErrorCodeInfoGenerator extends AbstractMojo implements ErrorCode {
+
+    @Parameter(defaultValue = "${basedir}")
+    private File baseDir;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+        getLog().info("baseDir目录" + baseDir);
+
+
+        try {
+
+        } catch (Exception e) {
+            throw new MojoExecutionException(e.getMessage());
+        }
+    }
+
+}