String getDocComment(T doc) {
221 | String comment = doc.commentText().trim();
222 | comment = comment.replaceAll("", " ");
223 | //将多个连续的空白字符替换成一个空格
224 | comment = comment.replaceAll("\\s+", " ");
225 | //转义xml字符
226 | return StringEscapeUtils.escapeXml10(comment);
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/src/main/java/top/naccl/reader/JavaDocReader.java:
--------------------------------------------------------------------------------
1 | package top.naccl.reader;
2 |
3 | import com.sun.javadoc.RootDoc;
4 | import top.naccl.MainConfig;
5 |
6 | import java.io.OutputStream;
7 | import java.io.PrintWriter;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * JavaDocReader
13 | *
14 | * @author: Naccl
15 | * @date: 2022-04-18
16 | */
17 | public class JavaDocReader {
18 | /**
19 | * 解析出的JavaDoc结果
20 | */
21 | private static RootDoc root;
22 |
23 | public static class Doclet {
24 | /**
25 | * The main entry point of the doclet.
26 | *
27 | * @param root the root of the documentation tree
28 | * @return true if the doclet processed the documentation
29 | */
30 | @SuppressWarnings("unused")
31 | public static boolean start(RootDoc root) {
32 | JavaDocReader.root = root;
33 | return true;
34 | }
35 | }
36 |
37 | /**
38 | * 读取JavaDoc
39 | *
40 | * @param javaFilePath java文件路径
41 | * @param config 主配置
42 | * @return 读取结果
43 | */
44 | public static RootDoc read(String javaFilePath, MainConfig config) {
45 | return read(javaFilePath, config.isIncludePrivate(), config.isIgnoreJavaDocError());
46 | }
47 |
48 | /**
49 | * 读取JavaDoc
50 | *
51 | * @param javaFilePath java文件路径
52 | * @param readAll 是否读取所有的类和成员(包括private)
53 | * @param ignoreError 是否忽略错误(未设置"-classpath",待解析的Java类中的依赖包将找不到,会产生很多错误输出,但不影响文档生成,完全可以忽略)
54 | * @return 读取结果
55 | */
56 | public static RootDoc read(String javaFilePath, boolean readAll, boolean ignoreError) {
57 | List args = new ArrayList<>();
58 | args.add("-encoding");
59 | args.add("utf-8");
60 | args.add(javaFilePath);
61 | if (readAll) {
62 | args.add("-private");
63 | }
64 |
65 | PrintWriter out;
66 | if (ignoreError) {
67 | //忽略错误,将输出流设置为无操作
68 | out = new PrintWriter(new OutputStream() {
69 | @Override
70 | public void write(int b) {
71 | }
72 | });
73 | } else {
74 | out = new PrintWriter(System.err);
75 | }
76 |
77 | com.sun.tools.javadoc.Main.execute("Java2Doc", out, out, out, Doclet.class.getName(), args.toArray(new String[0]));
78 | return root;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/top/naccl/util/CollectionUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.util;
2 |
3 | import java.util.Collection;
4 |
5 | /**
6 | * 集合工具类
7 | *
8 | * @author: Naccl
9 | * @date: 2022-04-19
10 | */
11 | public class CollectionUtils {
12 | /**
13 | * 集合是否为空
14 | *
15 | * @param collection 集合
16 | * @return 是否为空
17 | */
18 | public static boolean isEmpty(Collection> collection) {
19 | return collection == null || collection.isEmpty();
20 | }
21 |
22 | /**
23 | * 集合是否为非空
24 | *
25 | * @param collection 集合
26 | * @return 是否为非空
27 | */
28 | public static boolean isNotEmpty(Collection> collection) {
29 | return !isEmpty(collection);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/top/naccl/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.util;
2 |
3 | import lombok.SneakyThrows;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.nio.file.Files;
8 | import java.nio.file.Path;
9 | import java.nio.file.Paths;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.stream.Stream;
13 |
14 | /**
15 | * 文件工具类
16 | *
17 | * @author: Naccl
18 | * @date: 2022-04-18
19 | */
20 | public class FileUtils {
21 | /**
22 | * 获取当前路径
23 | *
24 | * @return 当前路径
25 | */
26 | public static String getCurrentPath() {
27 | return System.getProperty("user.dir");
28 | }
29 |
30 | /**
31 | * 检查文件或目录是否存在
32 | *
33 | * @param path 文件或目录路径
34 | * @return 存在返回true,否则返回false
35 | */
36 | public static boolean isFileExists(String path) {
37 | return Files.exists(Paths.get(path));
38 | }
39 |
40 | /**
41 | * 获取绝对路径
42 | *
43 | * @param path 路径
44 | * @return 绝对路径
45 | */
46 | @SneakyThrows
47 | public static String getCanonicalPath(String path) {
48 | File file = new File(path);
49 | return file.getCanonicalPath();
50 | }
51 |
52 | /**
53 | * 创建文件
54 | *
55 | * @param path 文件路径
56 | * @param fileName 文件名
57 | * @return File Object
58 | */
59 | public static File touchFile(String path, String fileName) {
60 | File folder = new File(path);
61 | folder.mkdirs();
62 | return new File(folder, fileName);
63 | }
64 |
65 | /**
66 | * 遍历给定根目录下的所有指定拓展名文件
67 | *
68 | * @param rootPath 根目录
69 | * @param maxDepth 最大深度
70 | * @param fileExtension 文件拓展名
71 | * @return 指定拓展名文件列表
72 | * @throws IOException 出现IO异常则抛出
73 | */
74 | public static List walkFile(String rootPath, int maxDepth, String fileExtension) throws IOException {
75 | List javaFiles = new ArrayList<>();
76 | Stream paths = Files.walk(Paths.get(rootPath), maxDepth);
77 | paths.map(Path::toString).filter(f -> f.endsWith(fileExtension)).forEach(javaFiles::add);
78 | return javaFiles;
79 | }
80 |
81 | /**
82 | * 遍历给定根目录下的所有.java文件
83 | *
84 | * @param rootPath 根目录
85 | * @param maxDepth 最大深度
86 | * @return java文件列表
87 | * @throws IOException 出现IO异常则抛出
88 | */
89 | public static List walkJavaFile(String rootPath, int maxDepth) throws IOException {
90 | return walkFile(rootPath, maxDepth, ".java");
91 | }
92 |
93 | /**
94 | * 遍历给定根目录下的所有.java文件
95 | *
96 | * @param rootPath 根目录
97 | * @return java文件列表
98 | * @throws IOException 出现IO异常则抛出
99 | */
100 | public static List walkJavaFile(String rootPath) throws IOException {
101 | return walkJavaFile(rootPath, Integer.MAX_VALUE);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/top/naccl/util/PropertiesUtils.java:
--------------------------------------------------------------------------------
1 | package top.naccl.util;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.util.Properties;
8 |
9 | /**
10 | * 配置文件工具类
11 | *
12 | * @author: Naccl
13 | * @date: 2022-04-21
14 | */
15 | @Slf4j
16 | public class PropertiesUtils {
17 | /**
18 | * 配置文件
19 | */
20 | private static Properties properties;
21 |
22 | /**
23 | * 加载配置文件
24 | */
25 | static {
26 | properties = new Properties();
27 | try (InputStream inputStream = PropertiesUtils.class.getClassLoader().getResourceAsStream("app.properties")) {
28 | properties.load(inputStream);
29 | } catch (IOException e) {
30 | log.error("An exception occurred during the loading of app.properties", e);
31 | }
32 | }
33 |
34 | /**
35 | * 获取配置文件中的值
36 | *
37 | * @param key 配置文件中的key
38 | * @return 配置文件中的value
39 | */
40 | public static String getProperty(String key) {
41 | return properties.getProperty(key);
42 | }
43 |
44 | /**
45 | * 获取版本号
46 | *
47 | * @return 版本号
48 | */
49 | public static String getVersion() {
50 | return properties.getProperty("java2doc.version");
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/resources/app.properties:
--------------------------------------------------------------------------------
1 | java2doc.version=1.0.0
2 |
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Naccl/Java2Doc/a928088c86aab9459f989b0a50d0de6270e547fd/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.jar
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.jar.md5:
--------------------------------------------------------------------------------
1 | 2900dd94c85ab07fb0c977bc3f918c60
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.jar.sha1:
--------------------------------------------------------------------------------
1 | 81a753eb87560f9f734cf3b33d6154d638cddf15
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.pom:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.sun
6 | tools
7 | 1.8
8 | POM was created from install:install-file
9 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.pom.md5:
--------------------------------------------------------------------------------
1 | 1b4991223deec9771c82b50d7dc219ce
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/1.8/tools-1.8.pom.sha1:
--------------------------------------------------------------------------------
1 | 656a05f70988c494c934ab15f00d345866d0f0bf
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.sun
4 | tools
5 |
6 | 1.8
7 |
8 | 1.8
9 |
10 | 20220422001826
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/maven-metadata-local.xml.md5:
--------------------------------------------------------------------------------
1 | 36b1bd779f77e1e2347264e82a25547d
--------------------------------------------------------------------------------
/src/main/resources/lib/com/sun/tools/maven-metadata-local.xml.sha1:
--------------------------------------------------------------------------------
1 | 608ee709c975b64a7600c6cc24cc23e723bdce05
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ${log.pattern}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/resources/template/freemarker/document_html.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
126 | ${projectName!'Java2Doc'}
127 |
128 |
129 | Java Class描述文档
130 | 项目名称:${projectName!'Java2Doc'}
131 | 文档版本:${version!'1.0.0'}
132 | 文档描述:${description!'Java项目Class描述文档生成'}
133 | <#list packageList as package>
134 | ${package.name}包中类的描述
135 |
136 |
137 |
138 |
139 | 类名 |
140 | 属性/方法 |
141 | 描述 |
142 |
143 |
144 |
145 | <#list package.classList as class>
146 | <#if class.fieldList?size == 0 && class.methodList?size == 0>
147 | <#--如果字段和方法都没有,就保留个类名-->
148 |
149 | ${class.name} |
150 | |
151 | |
152 |
153 | #if>
154 | <#list class.fieldList as field>
155 | <#if field_index == 0>
156 | <#--第一行-->
157 |
158 | ${class.name} |
159 | <#if field.accessModifier!=''>${field.accessModifier} #if>${field.type} ${field.name}; |
160 | ${field.comment} |
161 |
162 | <#else>
163 | <#--第一行之后-->
164 |
165 | <#if field.accessModifier!=''>${field.accessModifier} #if>${field.type} ${field.name}; |
166 | ${field.comment} |
167 |
168 | #if>
169 | #list>
170 | <#list class.methodList as method>
171 | <#if class.fieldList?size == 0 && method_index == 0>
172 | <#--第一行-->
173 |
174 | ${class.name} |
175 | <#if method.accessModifier!=''>${method.accessModifier} #if>${method.returnType} ${method.name}(<#list method.paramList as param>${param.type} ${param.name}<#if param_has_next>, #if>#list>); |
176 | ${method.comment} |
177 |
178 | <#else>
179 | <#--第一行之后-->
180 |
181 | <#if method.accessModifier!=''>${method.accessModifier} #if>${method.returnType} ${method.name}(<#list method.paramList as param>${param.type} ${param.name}<#if param_has_next>, #if>#list>); |
182 | ${method.comment} |
183 |
184 | #if>
185 | #list>
186 | #list>
187 |
188 |
189 |
190 | #list>
191 |
192 |
--------------------------------------------------------------------------------
/src/main/resources/template/freemarker/document_md.ftl:
--------------------------------------------------------------------------------
1 | # Java Class描述文档
2 |
3 | **项目名称**:${projectName!'Java2Doc'}
4 |
5 | **文档版本**:${version!'1.0.0'}
6 |
7 | **文档描述**:${description!'Java项目Class描述文档生成'}
8 | <#list packageList as package>
9 |
10 | #### ${package.name}包中类的描述
11 |
12 | | 类名 | 属性/方法 | 描述 |
13 | |:---:|---|---|
14 | <#list package.classList as class>
15 | <#if class.fieldList?size == 0 && class.methodList?size == 0>
16 | <#--如果字段和方法都没有,就保留个类名-->
17 | | ${class.name} | | |
18 | #if>
19 | <#list class.fieldList as field>
20 | <#if field_index == 0>
21 | <#--第一行-->
22 | | ${class.name} | <#if field.accessModifier!=''>${field.accessModifier} #if>${field.type} ${field.name}; | ${field.comment} |
23 | <#else>
24 | <#--第一行之后-->
25 | | | <#if field.accessModifier!=''>${field.accessModifier} #if>${field.type} ${field.name}; | ${field.comment} |
26 | #if>
27 | #list>
28 | <#list class.methodList as method>
29 | <#if class.fieldList?size == 0 && method_index == 0>
30 | <#--第一行-->
31 | | ${class.name} | <#if method.accessModifier!=''>${method.accessModifier} #if>${method.returnType} ${method.name}(<#list method.paramList as param>${param.type} ${param.name}<#if param_has_next>, #if>#list>); | ${method.comment} |
32 | <#else>
33 | <#--第一行之后-->
34 | | | <#if method.accessModifier!=''>${method.accessModifier} #if>${method.returnType} ${method.name}(<#list method.paramList as param>${param.type} ${param.name}<#if param_has_next>, #if>#list>); | ${method.comment} |
35 | #if>
36 | #list>
37 | #list>
38 | #list>
--------------------------------------------------------------------------------
/src/main/resources/template/freemarker/document_word.ftl:
--------------------------------------------------------------------------------
1 | <#--标题-->Java Class描述文档<#--项目名称-->项目名称:${projectName!'Java2Doc'}<#--文档版本-->文档版本:${version!'1.0.0'}<#--文档描述-->文档描述:${description!'Java项目Class描述文档生成'}<#--循环从这里开始--><#list packageList as package><#--小标题-->${package.name}包中类的描述<#--表格描述-->表${package_index + 1} ${package.name}包中类的描述<#--表格--><#--表头--><#--类名-->类名<#--属性/方法-->属性/方法<#--描述-->描述<#--表格行--><#list package.classList as class><#if class.fieldList?size == 0 && class.methodList?size == 0><#--如果字段和方法都没有,就保留个类名--><#--单元格1,第一行用这个w:tc-->${class.name}<#--单元格2--><#--留空--><#--单元格3--><#--留空-->#if><#list class.fieldList as field><#if field_index == 0><#--单元格1,第一行用这个w:tc-->${class.name}<#else><#--单元格1,第一行之后用这个w:tc-->#if><#--单元格2--><#if field.accessModifier!=''>${field.accessModifier} #if>${field.type} ${field.name};<#--单元格3-->${field.comment}#list><#list class.methodList as method><#if class.fieldList?size == 0 && method_index == 0><#--单元格1,第一行用这个w:tc-->${class.name}<#else><#--单元格1,第一行之后用这个w:tc-->#if><#--单元格2--><#if method.accessModifier!=''>${method.accessModifier} #if>${method.returnType} ${method.name}(<#list method.paramList as param>${param.type} ${param.name}<#if param_has_next>, #if>#list>);<#--单元格3-->${method.comment}#list>#list>#list><#--循环到这里结束-->${projectName!'Java2Doc'}NacclNaccl1Normal.dotm0111Microsoft Office Word011falsefalse0falsefalse16.0000
--------------------------------------------------------------------------------