All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.doc.DocHelp Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
package shz.doc;

import com.sun.javadoc.*;
import com.sun.tools.javadoc.Main;
import org.slf4j.LoggerFactory;
import shz.core.NullHelp;
import shz.core.ToMap;
import shz.core.tools.compile.CompileHelp;

import java.io.File;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 用法: javadoc [options] [packagenames] [sourcefiles] [@files]
 * -overview                  从 HTML 文件读取概览文档
 * -public                          仅显示 public 类和成员
 * -protected                       显示 protected/public 类和成员 (默认值)
 * -package                         显示 package/protected/public 类和成员
 * -private                         显示所有类和成员
 * -help                            显示命令行选项并退出
 * -doclet                   通过替代 doclet 生成输出
 * -docletpath                指定查找 doclet 类文件的位置
 * -sourcepath            指定查找源文件的位置
 * -classpath             指定查找用户类文件的位置
 * -cp                    指定查找用户类文件的位置
 * -exclude                指定要排除的程序包列表
 * -subpackages         指定要递归加载的子程序包
 * -breakiterator                   计算带有 BreakIterator 的第一个语句
 * -bootclasspath         覆盖由引导类加载器所加载的
 * 类文件的位置
 * -source                 提供与指定发行版的源兼容性
 * -extdirs                覆盖所安装扩展的位置
 * -verbose                         输出有关 Javadoc 正在执行的操作的信息
 * -locale                    要使用的区域设置, 例如 en_US 或 en_US_WIN
 * -encoding                  源文件编码名称
 * -quiet                           不显示状态消息
 * -J                         直接将  传递到运行时系统
 * -X                               输出非标准选项的提要
 */
public final class DocHelp {
    private static RootDoc rootDoc;

    public static boolean start(RootDoc root) {
        rootDoc = root;
        return true;
    }

    public static boolean execute(Class cls, boolean cp, Consumer consumer) {
        File file = CompileHelp.findFile(cls);
        if (file == null) return false;

        List ps = new ArrayList<>();
        ps.add("-doclet");
        ps.add(DocHelp.class.getName());
        ps.add("-encoding");
        ps.add("utf-8");

        if (cp) {
            String lib = CompileHelp.libToCp(file);
            if (lib != null) {
                ps.add("-cp");
                ps.add(lib);
            }
        }

        ps.add(file.getAbsolutePath());

        int execute = Main.execute(ps.toArray(new String[0]));
        ClassDoc[] classes;
        if (execute != 0 || rootDoc == null || NullHelp.isEmpty(classes = rootDoc.classes())) return false;
        consumer.accept(classes);
        return true;
    }

    public static boolean execute(Class cls, boolean cp, Consumer cConsumer, Consumer mConsumer, Consumer fConsumer) {
        return execute(cls, cp, classes -> {
            for (ClassDoc classDoc : classes) {
                if (cConsumer != null) cConsumer.accept(classDoc);
                if (mConsumer != null) {
                    MethodDoc[] methods = classDoc.methods(false);
                    if (NullHelp.nonEmpty(methods)) for (MethodDoc methodDoc : methods) mConsumer.accept(methodDoc);
                }
                if (fConsumer != null) {
                    FieldDoc[] fields = classDoc.fields(false);
                    if (NullHelp.nonEmpty(fields)) for (FieldDoc fieldDoc : fields) fConsumer.accept(fieldDoc);
                }
            }
        });
    }

    private static Map, DocDto> DOC_CACHE;

    /**
     * 不支持并发
     */
    public static DocDto execute(Class cls, boolean cp) {
        if (DOC_CACHE == null) DOC_CACHE = new HashMap<>(128);
        return DOC_CACHE.computeIfAbsent(cls, k -> {
            DocDto docDto = new DocDto();
            boolean execute = execute(
                    cls, cp,
                    classDoc -> docDto.classDoc = classDoc,
                    methodDoc -> docDto.methodDocs.put(key(methodDoc), methodDoc),
                    fieldDoc -> docDto.fieldDocs.put(fieldDoc.name(), fieldDoc)
            );
            return execute ? docDto : DocDto.NULL;
        });
    }

    public static void clear() {
        DOC_CACHE = null;
        LoggerFactory.getLogger(DocHelp.class).info("构造 Javadoc 完成!");
    }

    private static String key(MethodDoc methodDoc) {
        StringBuilder sb = new StringBuilder();
        sb.append(methodDoc.name());
        Parameter[] parameters = methodDoc.parameters();
        if (NullHelp.nonEmpty(parameters)) for (Parameter parameter : parameters)
            sb.append(":").append(parameter.name());
        return sb.toString();
    }

    public static String key(Method method, String[] parameterNames) {
        StringBuilder sb = new StringBuilder();
        sb.append(method.getName());
        if (NullHelp.nonEmpty(parameterNames)) for (String parameterName : parameterNames)
            sb.append(":").append(parameterName);
        return sb.toString();
    }

    public static Map getParams(MethodDoc methodDoc) {
        if (methodDoc == null) return Collections.emptyMap();
        String rawCommentText = methodDoc.getRawCommentText();
        if (NullHelp.isBlank(rawCommentText)) return Collections.emptyMap();
        Map result = ToMap.get().build();
        Matcher matcher = Pattern.compile("(?<=@param)\\s*(\\w+)\\s*([^@]*)\\s*(?!@)").matcher(rawCommentText);
        while (matcher.find()) {
            String g2 = matcher.group(2);
            if (g2 != null) result.put(matcher.group(1), g2.trim());
        }
        return result.isEmpty() ? Collections.emptyMap() : result;
    }

    public static String getReturn(MethodDoc methodDoc) {
        if (methodDoc == null) return null;
        String rawCommentText = methodDoc.getRawCommentText();
        if (NullHelp.isBlank(rawCommentText)) return null;
        Matcher matcher = Pattern.compile("(?<=@return)\\s*([^@]*)\\s*").matcher(rawCommentText);
        if (matcher.find()) {
            String g1 = matcher.group(1);
            if (g1 != null) return g1.trim();
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy