├── .gitignore ├── LICENSE ├── README.md ├── pom.xml ├── super-java-doc-core ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── uifuture │ │ └── supercore │ │ ├── SuperJavaDoc.java │ │ ├── format │ │ └── Format.java │ │ ├── framework │ │ └── AbstractFramework.java │ │ ├── model │ │ ├── ApiAction.java │ │ ├── ApiDoc.java │ │ ├── ApiModule.java │ │ ├── DocTags.java │ │ ├── FieldInfo.java │ │ └── ObjectInfo.java │ │ ├── resolver │ │ ├── DocTagResolver.java │ │ ├── IgnoreApi.java │ │ └── parser │ │ │ ├── JavaParserDocTagResolver.java │ │ │ └── converter │ │ │ ├── JavaParserTagConverter.java │ │ │ ├── JavaParserTagConverterManager.java │ │ │ ├── ParamTagConverter.java │ │ │ ├── RespTagConverter.java │ │ │ ├── SeeTagConverter.java │ │ │ └── impl │ │ │ └── DefaultJavaParserTagConverterImpl.java │ │ ├── tag │ │ ├── AbstractDocTag.java │ │ └── impl │ │ │ ├── DocTagImpl.java │ │ │ ├── ParamTagImpl.java │ │ │ ├── RespTagImpl.java │ │ │ └── SeeTagImpl.java │ │ └── utils │ │ ├── ClassMapperUtils.java │ │ ├── ClassUtils.java │ │ ├── CommentUtils.java │ │ ├── Constant.java │ │ ├── FileUtils.java │ │ ├── JsonFormatUtils.java │ │ └── JsonUtils.java │ └── resources │ └── logback.xml ├── super-java-doc-spring ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── uifuture │ │ └── superspring │ │ ├── format │ │ ├── HtmlForamt.java │ │ ├── MarkdownFormat.java │ │ ├── VelocityTemplater.java │ │ ├── api.vm │ │ └── html.vm │ │ └── framework │ │ ├── ParamInfo.java │ │ ├── SpringApiAction.java │ │ ├── SpringApiModule.java │ │ └── SpringWebFramework.java │ └── resources │ └── logback.xml ├── super-java-doc-starter ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── uifuture │ │ └── superstarter │ │ └── boot │ │ ├── DocConfiguration.java │ │ ├── DocController.java │ │ ├── DocProperties.java │ │ └── EnableDoc.java │ └── resources │ └── static │ └── superJavaDoc │ ├── element-ui.css │ ├── element-ui.js │ ├── fonts │ └── element-icons.woff │ ├── index.html │ └── vue.min.js └── super-java-doc-test ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── uifuture │ │ └── test │ │ ├── TestApplication.java │ │ ├── controller │ │ ├── AccountController.java │ │ ├── CommController.java │ │ └── UserController.java │ │ └── vo │ │ ├── Account.java │ │ ├── AccountEx.java │ │ └── User.java └── resources │ ├── application.yml │ └── logback.xml └── test └── java └── com └── uifuture └── test └── SuperJavaDocTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | ### IntelliJ IDEA ### 23 | .idea 24 | *.iws 25 | *.iml 26 | *.ipr 27 | */target 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # superJavaDoc 快速文档构建框架 3 | 4 | - **基于Java注释生成接口文档** 5 | - **注释支持扩展** 6 | - **接口框架支持扩展** 7 | - **默认支持markdown和离线/在线html等格式的文档** 8 | - **默认支持spring mvc规范** 9 | - **默认支持spring-boot直接内嵌启动** 10 | 11 | ## 基于SpringBoot在线直接使用 12 | 13 | ### 1.引入Maven依赖 14 | ```xml 15 | 16 | 17 | com.uifuture 18 | super-java-doc-starter 19 | 1.0.0 20 | 21 | ``` 22 | 23 | ### 2.增加EnableDoc注解 24 | 在Application类上加上EnableDoc注解 25 | ```java 26 | @EnableDoc //<--- 加上此注解以便启用XDOC在线HTML文档 27 | @SpringBootApplication 28 | public class TestApplication { 29 | 30 | public static void main(String[] args) { 31 | SpringApplication.run(TestApplication.class, args); 32 | } 33 | } 34 | ``` 35 | 36 | ### 3.1 properties配置文件 37 | ``` 38 | #在application.properties配置项目源码的位置,直接在项目里启动时,如果是单模块的maven项目,默认可以不配置 39 | #是否启动XDoc,默认是true,因为可以不填 40 | doc.enable=true 41 | #源码路径,多个时用英文逗号隔开,super-java-doc-test为项目模块名称。单模块项目可以将super-java-doc-test/去掉,直接使用src/main/java 42 | doc.sourcePath=super-java-doc-test/src/main/java 43 | #用于配置文档页面标题 44 | doc.title=在线接口文档 45 | #标识接口文档的版本号 46 | doc.version=1.0 47 | ``` 48 | ### 3.2 yml配置文件 49 | ```yml 50 | doc: 51 | enable: true #是否启动superJavaDoc,默认是true,因为可以不填 52 | title: 在线接口文档 #用于配置文档页面标题 53 | sourcePath: super-java-doc-test/src/main/java #源码路径,多个时用英文逗号隔开 54 | version: 1.0 #标识接口文档的版本号 55 | ``` 56 | 57 | ### 4 使用 58 | **以上配置就都写好了** 59 | 60 | **跟着随便写几个Controller作为Demo接口,便于直接浏览生成效果:** 61 | ```java 62 | 63 | /** 64 | * BlogsController 65 | * 66 | * @author chenhaoxiang 67 | * @date 2018-09-12 18:23:40 68 | */ 69 | @Controller 70 | @RequestMapping("admin/blogs") 71 | public class BlogsController { 72 | @Resource 73 | private BlogsService blogsService; 74 | 75 | /** 76 | * 添加Blogs 77 | * 78 | * @param blogs 对象 79 | * @return ResultModel统一响应结果 80 | */ 81 | @PostMapping("add") 82 | @ResponseBody 83 | public ResultModel add(Blogs blogs) { 84 | blogsService.insert(blogs); 85 | return ResultModel.success(); 86 | } 87 | 88 | /** 89 | * 根据ID进行删除 90 | * 91 | * @param id 主键 92 | * @return ResultModel统一响应结果 93 | */ 94 | @PostMapping("delete") 95 | @ResponseBody 96 | public ResultModel delete(@RequestParam Integer id) { 97 | blogsService.deleteById(id); 98 | return ResultModel.success(); 99 | } 100 | 101 | /** 102 | * 根据ID进行修改Blogs对象 103 | * 104 | * @param blogs 对象中必须有ID主键 105 | * @return ResultModel统一响应结果 106 | */ 107 | @PostMapping("update") 108 | @ResponseBody 109 | public ResultModel update(Blogs blogs) { 110 | blogsService.updateById(blogs); 111 | return ResultModel.success(); 112 | } 113 | 114 | /** 115 | * 查询详情 116 | * 117 | * @param id 主键 118 | * @return ResultModel统一响应结果 119 | */ 120 | @PostMapping("detail") 121 | @ResponseBody 122 | public ResultModel detail(@RequestParam Integer id) { 123 | Blogs blogs = blogsService.selectById(id); 124 | return ResultModel.success(blogs); 125 | } 126 | 127 | /** 128 | * 分页查询 129 | * 130 | * @param page 当前页 默认0 不分页 131 | * @param size 每页的条数 默认为0 查询所有 132 | * @return ResultModel统一响应结果 133 | */ 134 | @PostMapping("list") 135 | @ResponseBody 136 | public ResultModel list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) { 137 | PageHelper.startPage(page, size); 138 | List list = blogsService.selectAll(); 139 | PageInfo pageInfo = new PageInfo(list); 140 | return ResultModel.success(pageInfo); 141 | } 142 | 143 | } 144 | 145 | ``` 146 | 147 | **直接启动项目, 敲入地址: http://localhost:8080/superJavaDoc/index.html** 148 | 149 | 如下两个图,为部分展示内容。 150 | ![http://blogimg.chenhaoxiang.cn/18-11-26/76692396.jpg](http://blogimg.chenhaoxiang.cn/18-11-26/76692396.jpg) 151 | 152 | ![http://blogimg.chenhaoxiang.cn/18-11-26/6863840.jpg](http://blogimg.chenhaoxiang.cn/18-11-26/6863840.jpg) 153 | 154 | ### 2.生成离线文档 155 | **支持html:** 156 | ```java 157 | @Test 158 | public void buildMarkdown() { 159 | //生成离线的Markdown格式的接口文档 160 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 161 | String rootDir = System.getProperty("user.dir"); 162 | SuperJavaDoc xDoc = new SuperJavaDoc(rootDir + "/src/main/java/com/uifuture", new SpringWebFramework()); 163 | xDoc.build(out, new MarkdownFormat()); 164 | 165 | System.out.println(out.toString()); 166 | } 167 | ``` 168 | 169 | **支持markdown:** 170 | ```java 171 | @Test 172 | public void buildHtml() throws Exception { 173 | //生成离线的HTML格式的接口文档 174 | String userDir = System.getProperty("user.dir"); 175 | FileOutputStream out = new FileOutputStream(new File(userDir, "api.html")); 176 | SuperJavaDoc xDoc = new SuperJavaDoc(userDir + "/src/main/java/com/uifuture", new SpringWebFramework()); 177 | xDoc.build(out, new HtmlForamt()); 178 | } 179 | ``` 180 | 181 | **注意:生产环境不推荐开启此文,可能会消耗性能,所以在生成环境下,配置文件中配置如下即可:** 182 | ```txt 183 | doc.enable=false 184 | ``` 185 | 186 | 187 | 欢迎有志之士一起开发。提Issues。 188 | 189 | 190 | 参考项目:https://gitee.com/treeleaf/xDoc 191 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.uifuture 8 | super-java-doc 9 | pom 10 | 1.0.0 11 | 12 | super-java-doc-core 13 | super-java-doc-spring 14 | super-java-doc-starter 15 | 16 | super-java-doc 17 | https://github.com/chenhaoxiang/super-java-doc 18 | super-java-doc,基于Java doc注释,自动构建文档,项目地址:https://github.com/chenhaoxiang/super-java-doc 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-dependencies 25 | 2.0.3.RELEASE 26 | pom 27 | import 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.slf4j 37 | slf4j-api 38 | 1.7.25 39 | 40 | 41 | 42 | 43 | com.fasterxml.jackson.core 44 | jackson-databind 45 | 46 | 47 | 48 | commons-beanutils 49 | commons-beanutils 50 | 1.9.3 51 | 52 | 53 | 54 | commons-io 55 | commons-io 56 | 2.5 57 | 58 | 59 | 60 | junit 61 | junit 62 | test 63 | 64 | 65 | 66 | 67 | org.apache.commons 68 | commons-lang3 69 | 3.4 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.sonatype.oss 78 | oss-parent 79 | 7 80 | 81 | 82 | 83 | 84 | The Apache License, Version 2.0 85 | http://www.apache.org/licenses/LICENSE-2.0.txt 86 | 87 | 88 | 89 | 90 | master 91 | git@github.com:chenhaoxiang/super-java-doc.git 92 | scm:git:git@github.com:chenhaoxiang/super-java-doc.git 93 | scm:git:git@github.com:chenhaoxiang/super-java-doc.git 94 | 95 | 96 | 97 | 98 | chenhaoxiang 99 | uifuture@uifuture.com 100 | uifuture 101 | http://chenhaoxiang.cn 102 | 103 | 104 | 105 | 106 | 107 | sonatype-oss-release 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-gpg-plugin 113 | 114 | 1.5 115 | 116 | 117 | sign-artifacts 118 | verify 119 | 120 | sign 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-javadoc-plugin 129 | 2.7 130 | 131 | 132 | attach-javadocs 133 | 134 | jar 135 | 136 | 137 | -Xdoclint:none 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | src/main/java 151 | 152 | **/*.vm 153 | 154 | false 155 | 156 | 157 | src/main/resources 158 | 159 | **/*.* 160 | 161 | false 162 | 163 | 164 | 165 | 166 | 167 | org.apache.maven.plugins 168 | maven-compiler-plugin 169 | 3.7.0 170 | 171 | 8 172 | 8 173 | UTF-8 174 | 175 | 176 | 177 | 178 | org.apache.maven.plugins 179 | maven-source-plugin 180 | 3.0.1 181 | 182 | 183 | attach-sources 184 | 185 | jar-no-fork 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /super-java-doc-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | super-java-doc 7 | com.uifuture 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | super-java-doc-core 13 | 14 | 15 | 16 | 17 | 18 | com.github.javaparser 19 | javaparser-core 20 | 3.6.10 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/SuperJavaDoc.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore; 6 | 7 | import com.uifuture.supercore.format.Format; 8 | import com.uifuture.supercore.framework.AbstractFramework; 9 | import com.uifuture.supercore.model.ApiDoc; 10 | import com.uifuture.supercore.model.ApiModule; 11 | import com.uifuture.supercore.resolver.DocTagResolver; 12 | import com.uifuture.supercore.resolver.parser.JavaParserDocTagResolver; 13 | import com.uifuture.supercore.utils.FileUtils; 14 | import org.apache.commons.io.IOUtils; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * 主入口,核心处理从这里开始 28 | * 29 | * @author chenhx 30 | * @version SuperMain.java, v 0.1 2018-09-26 下午 5:27 31 | */ 32 | public class SuperJavaDoc { 33 | 34 | private static final String CHARSET = "utf-8"; 35 | 36 | private Logger log = LoggerFactory.getLogger(getClass()); 37 | 38 | /** 39 | * 源码路径 40 | */ 41 | private List srcPaths; 42 | 43 | /** 44 | * api框架类型 45 | */ 46 | private AbstractFramework abstractFramework; 47 | 48 | /** 49 | * 默认的java注释解析器实现 50 | *

51 | * 备注:基于sun doc的解析方式已经废弃,若需要请参考v1.0之前的版本 52 | * 53 | * @see JavaParserDocTagResolver 54 | */ 55 | private DocTagResolver docTagResolver = new JavaParserDocTagResolver(); 56 | 57 | /** 58 | * 构建doc对象 59 | * @param srcPath 源码路径 60 | * @param abstractFramework 61 | */ 62 | public SuperJavaDoc(String srcPath, AbstractFramework abstractFramework) { 63 | this(Arrays.asList(srcPath), abstractFramework); 64 | } 65 | 66 | /** 67 | * 构建SuperJavaDoc对象 68 | * @param srcPaths 源码路径,支持多个 69 | * @param abstractFramework 70 | */ 71 | public SuperJavaDoc(List srcPaths, AbstractFramework abstractFramework) { 72 | this.srcPaths = srcPaths; 73 | this.abstractFramework = abstractFramework; 74 | } 75 | 76 | /** 77 | * 解析源码并返回对应的接口数据 78 | * 79 | * @return API接口数据 80 | */ 81 | public ApiDoc resolve() { 82 | List files = new ArrayList<>(); 83 | for (String srcPath : this.srcPaths) { 84 | files.addAll(FileUtils.getAllJavaFiles(new File(srcPath))); 85 | } 86 | 87 | List apiModules = this.docTagResolver.resolve(files, abstractFramework); 88 | 89 | if (abstractFramework != null) { 90 | apiModules = abstractFramework.extend(apiModules); 91 | } 92 | return new ApiDoc(apiModules); 93 | } 94 | 95 | /** 96 | * 构建接口文档 97 | * 98 | * @param out 输出位置 99 | * @param format 文档格式 100 | */ 101 | public void build(OutputStream out, Format format) { 102 | this.build(out, format, null); 103 | } 104 | 105 | /** 106 | * 构建接口文档 107 | * 108 | * @param out 输出位置 109 | * @param format 文档格式 110 | * @param properties 文档属性 111 | */ 112 | public void build(OutputStream out, Format format, Map properties) { 113 | ApiDoc apiDoc = this.resolve(); 114 | if (properties != null) { 115 | apiDoc.getProperties().putAll(properties); 116 | } 117 | 118 | if (apiDoc.getApiModules() != null && out != null && format != null) { 119 | String s = format.format(apiDoc); 120 | try { 121 | IOUtils.write(s, out, CHARSET); 122 | } catch (IOException e) { 123 | log.error("接口文档写入文件失败", e); 124 | } finally { 125 | IOUtils.closeQuietly(out); 126 | } 127 | } 128 | } 129 | 130 | /** 131 | * Setter method for property srcPaths. 132 | * 133 | * @param srcPaths value to be assigned to property srcPaths 134 | */ 135 | public void setSrcPaths(List srcPaths) { 136 | this.srcPaths = srcPaths; 137 | } 138 | 139 | /** 140 | * Setter method for property framework. 141 | * 142 | * @param abstractFramework value to be assigned to property framework 143 | */ 144 | public void setAbstractFramework(AbstractFramework abstractFramework) { 145 | this.abstractFramework = abstractFramework; 146 | } 147 | 148 | /** 149 | * Setter method for property docTagResolver. 150 | * 151 | * @param docTagResolver value to be assigned to property docTagResolver 152 | */ 153 | public void setDocTagResolver(DocTagResolver docTagResolver) { 154 | this.docTagResolver = docTagResolver; 155 | } 156 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/format/Format.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.format; 6 | 7 | import com.uifuture.supercore.model.ApiDoc; 8 | 9 | /** 10 | * 文档输出格式 11 | * 12 | * @author chenhx 13 | * @version Format.java, v 0.1 2018-09-26 下午 4:31 14 | */ 15 | public interface Format { 16 | String format(ApiDoc apiDoc); 17 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/framework/AbstractFramework.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.framework; 6 | 7 | import com.uifuture.supercore.model.ApiModule; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * 抽象各种API框架的特性,用于在基于SuperJavaDoc-core渲染出来的ApiModule基础中,进行再度包装 13 | * 14 | * @author chenhx 15 | * @version Framework.java, v 0.1 2018-09-26 下午 4:45 16 | */ 17 | public abstract class AbstractFramework { 18 | 19 | /** 20 | * 扩展API数据 21 | * 22 | * @param apiModules 原始基本的Api数据 23 | * @return 扩展后的api数据 24 | */ 25 | public abstract List extend(List apiModules); 26 | 27 | /** 28 | * 判断该类是否适合该框架 29 | * 30 | * @param classz 扫描到的类 31 | * @return 是支持 32 | */ 33 | public abstract boolean support(Class classz); 34 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/ApiAction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import com.fasterxml.jackson.annotation.JsonIgnore; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 接口信息,一个接口类里面会有多个接口,每个接口都抽象成ApiAction 13 | * 14 | * @author chenhx 15 | * @version ApiAction.java, v 0.1 2018-09-26 下午 4:32 16 | */ 17 | public class ApiAction { 18 | /** 19 | * 展示用的标题 20 | */ 21 | private String title; 22 | 23 | /** 24 | * 接口方法名称 25 | */ 26 | private String name; 27 | 28 | /** 29 | * 接口方法 30 | */ 31 | @JsonIgnore 32 | private transient Method method; 33 | 34 | /** 35 | * 接口的描述 36 | */ 37 | private String comment; 38 | 39 | /** 40 | * 方法上标注的注解 41 | */ 42 | private com.uifuture.supercore.model.DocTags docTags; 43 | 44 | /** 45 | * Getter method for property title. 46 | * 47 | * @return property value of title 48 | */ 49 | public String getTitle() { 50 | return title; 51 | } 52 | 53 | /** 54 | * Setter method for property title. 55 | * 56 | * @param title value to be assigned to property title 57 | */ 58 | public void setTitle(String title) { 59 | this.title = title; 60 | } 61 | 62 | /** 63 | * Getter method for property name. 64 | * 65 | * @return property value of name 66 | */ 67 | public String getName() { 68 | return name; 69 | } 70 | 71 | /** 72 | * Setter method for property name. 73 | * 74 | * @param name value to be assigned to property name 75 | */ 76 | public void setName(String name) { 77 | this.name = name; 78 | } 79 | 80 | /** 81 | * Getter method for property method. 82 | * 83 | * @return property value of method 84 | */ 85 | public Method getMethod() { 86 | return method; 87 | } 88 | 89 | /** 90 | * Setter method for property method. 91 | * 92 | * @param method value to be assigned to property method 93 | */ 94 | public void setMethod(Method method) { 95 | this.method = method; 96 | } 97 | 98 | /** 99 | * Getter method for property comment. 100 | * 101 | * @return property value of comment 102 | */ 103 | public String getComment() { 104 | return comment; 105 | } 106 | 107 | /** 108 | * Setter method for property comment. 109 | * 110 | * @param comment value to be assigned to property comment 111 | */ 112 | public void setComment(String comment) { 113 | this.comment = comment; 114 | } 115 | 116 | /** 117 | * Getter method for property docTags. 118 | * 119 | * @return property value of docTags 120 | */ 121 | public com.uifuture.supercore.model.DocTags getDocTags() { 122 | return docTags; 123 | } 124 | 125 | /** 126 | * Setter method for property docTags. 127 | * 128 | * @param docTags value to be assigned to property docTags 129 | */ 130 | public void setDocTags(com.uifuture.supercore.model.DocTags docTags) { 131 | this.docTags = docTags; 132 | } 133 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/ApiDoc.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author chenhx 13 | * @version ApiDoc.java, v 0.1 2018-09-26 下午 4:31 14 | */ 15 | public class ApiDoc { 16 | 17 | /** 18 | * 附带的属性 19 | */ 20 | private Map properties = new HashMap<>(); 21 | 22 | /** 23 | * 所有API模块 24 | */ 25 | private List apiModules; 26 | 27 | public ApiDoc(List apiModules) { 28 | this.apiModules = apiModules; 29 | } 30 | 31 | public ApiDoc(Map properties, List apiModules) { 32 | this.properties = properties; 33 | this.apiModules = apiModules; 34 | } 35 | 36 | /** 37 | * Getter method for property properties. 38 | * 39 | * @return property value of properties 40 | */ 41 | public Map getProperties() { 42 | return properties; 43 | } 44 | 45 | /** 46 | * Setter method for property properties. 47 | * 48 | * @param properties value to be assigned to property properties 49 | */ 50 | public void setProperties(Map properties) { 51 | this.properties = properties; 52 | } 53 | 54 | /** 55 | * Getter method for property apiModules. 56 | * 57 | * @return property value of apiModules 58 | */ 59 | public List getApiModules() { 60 | return apiModules; 61 | } 62 | 63 | /** 64 | * Setter method for property apiModules. 65 | * 66 | * @param apiModules value to be assigned to property apiModules 67 | */ 68 | public void setApiModules(List apiModules) { 69 | this.apiModules = apiModules; 70 | } 71 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/ApiModule.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import com.fasterxml.jackson.annotation.JsonIgnore; 8 | 9 | import java.util.LinkedList; 10 | import java.util.List; 11 | 12 | /** 13 | * 接口业务模块,一个接口类为一个模块 14 | * 15 | * @author chenhx 16 | * @version ApiModule.java, v 0.1 2018-09-26 下午 4:32 17 | */ 18 | public class ApiModule { 19 | /** 20 | * 源码在哪个类 21 | */ 22 | @JsonIgnore 23 | private transient Class type; 24 | 25 | /** 26 | * 业务模块的描述 27 | */ 28 | private String comment; 29 | 30 | /** 31 | * 此业务模块下有哪些接口 32 | */ 33 | private List apiActions = new LinkedList<>(); 34 | 35 | /** 36 | * Getter method for property type. 37 | * 38 | * @return property value of type 39 | */ 40 | public Class getType() { 41 | return type; 42 | } 43 | 44 | /** 45 | * Setter method for property type. 46 | * 47 | * @param type value to be assigned to property type 48 | */ 49 | public void setType(Class type) { 50 | this.type = type; 51 | } 52 | 53 | /** 54 | * Getter method for property comment. 55 | * 56 | * @return property value of comment 57 | */ 58 | public String getComment() { 59 | return comment; 60 | } 61 | 62 | /** 63 | * Setter method for property comment. 64 | * 65 | * @param comment value to be assigned to property comment 66 | */ 67 | public void setComment(String comment) { 68 | this.comment = comment; 69 | } 70 | 71 | /** 72 | * Getter method for property apiActions. 73 | * 74 | * @return property value of apiActions 75 | */ 76 | public List getApiActions() { 77 | return apiActions; 78 | } 79 | 80 | /** 81 | * Setter method for property apiActions. 82 | * 83 | * @param apiActions value to be assigned to property apiActions 84 | */ 85 | public void setApiActions(List apiActions) { 86 | this.apiActions = apiActions; 87 | } 88 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/DocTags.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * @author chenhx 14 | * @version DocTags.java, v 0.1 2018-09-26 下午 4:37 15 | */ 16 | public class DocTags { 17 | 18 | private List list; 19 | 20 | public DocTags() { 21 | } 22 | 23 | public DocTags(List list) { 24 | this.list = list; 25 | } 26 | 27 | public AbstractDocTag getTag(String name) { 28 | for (int i = 0; i < list.size(); i++) { 29 | AbstractDocTag abstractDocTag = list.get(i); 30 | if (abstractDocTag.getTagName().equals(name)) { 31 | return abstractDocTag; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | public List getTags(String name) { 38 | List abstractDocTags = new ArrayList(); 39 | for (int i = 0; i < list.size(); i++) { 40 | AbstractDocTag abstractDocTag = list.get(i); 41 | if (abstractDocTag.getTagName().equals(name)) { 42 | abstractDocTags.add(abstractDocTag); 43 | } 44 | } 45 | return abstractDocTags; 46 | } 47 | 48 | /** 49 | * Getter method for property list. 50 | * 51 | * @return property value of list 52 | */ 53 | public List getList() { 54 | return list; 55 | } 56 | 57 | /** 58 | * Setter method for property list. 59 | * 60 | * @param list value to be assigned to property list 61 | */ 62 | public void setList(List list) { 63 | this.list = list; 64 | } 65 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/FieldInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author chenhx 11 | * @version FieldInfo.java, v 0.1 2018-09-26 下午 4:37 12 | */ 13 | public class FieldInfo { 14 | 15 | private String name; 16 | 17 | private Class type; 18 | 19 | private String simpleTypeName; 20 | 21 | private String comment; 22 | 23 | /** 24 | * 是否必填,默认false 25 | */ 26 | private boolean require; 27 | 28 | private List fieldInfos; 29 | 30 | /** 31 | * Getter method for property name. 32 | * 33 | * @return property value of name 34 | */ 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | /** 40 | * Setter method for property name. 41 | * 42 | * @param name value to be assigned to property name 43 | */ 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | /** 49 | * Getter method for property type. 50 | * 51 | * @return property value of type 52 | */ 53 | public Class getType() { 54 | return type; 55 | } 56 | 57 | /** 58 | * Setter method for property type. 59 | * 60 | * @param type value to be assigned to property type 61 | */ 62 | public void setType(Class type) { 63 | this.type = type; 64 | } 65 | 66 | /** 67 | * Getter method for property simpleTypeName. 68 | * 69 | * @return property value of simpleTypeName 70 | */ 71 | public String getSimpleTypeName() { 72 | return simpleTypeName; 73 | } 74 | 75 | /** 76 | * Setter method for property simpleTypeName. 77 | * 78 | * @param simpleTypeName value to be assigned to property simpleTypeName 79 | */ 80 | public void setSimpleTypeName(String simpleTypeName) { 81 | this.simpleTypeName = simpleTypeName; 82 | } 83 | 84 | /** 85 | * Getter method for property comment. 86 | * 87 | * @return property value of comment 88 | */ 89 | public String getComment() { 90 | return comment; 91 | } 92 | 93 | /** 94 | * Setter method for property comment. 95 | * 96 | * @param comment value to be assigned to property comment 97 | */ 98 | public void setComment(String comment) { 99 | this.comment = comment; 100 | } 101 | 102 | /** 103 | * Getter method for property require. 104 | * 105 | * @return property value of require 106 | */ 107 | public boolean isRequire() { 108 | return require; 109 | } 110 | 111 | /** 112 | * Setter method for property require. 113 | * 114 | * @param require value to be assigned to property require 115 | */ 116 | public void setRequire(boolean require) { 117 | this.require = require; 118 | } 119 | 120 | /** 121 | * Getter method for property fieldInfos. 122 | * 123 | * @return property value of fieldInfos 124 | */ 125 | public List getFieldInfos() { 126 | return fieldInfos; 127 | } 128 | 129 | /** 130 | * Setter method for property fieldInfos. 131 | * 132 | * @param fieldInfos value to be assigned to property fieldInfos 133 | */ 134 | public void setFieldInfos(List fieldInfos) { 135 | this.fieldInfos = fieldInfos; 136 | } 137 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/model/ObjectInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.model; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author chenhx 12 | * @version ObjectInfo.java, v 0.1 2018-09-26 下午 4:40 13 | */ 14 | public class ObjectInfo { 15 | 16 | private String name; 17 | 18 | /** 19 | * 源码在哪个类 20 | */ 21 | private Class type; 22 | 23 | private String comment; 24 | 25 | private List fieldInfos = new ArrayList<>(); 26 | 27 | /** 28 | * Getter method for property name. 29 | * 30 | * @return property value of name 31 | */ 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | /** 37 | * Setter method for property name. 38 | * 39 | * @param name value to be assigned to property name 40 | */ 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | 45 | /** 46 | * Getter method for property type. 47 | * 48 | * @return property value of type 49 | */ 50 | public Class getType() { 51 | return type; 52 | } 53 | 54 | /** 55 | * Setter method for property type. 56 | * 57 | * @param type value to be assigned to property type 58 | */ 59 | public void setType(Class type) { 60 | this.type = type; 61 | } 62 | 63 | /** 64 | * Getter method for property comment. 65 | * 66 | * @return property value of comment 67 | */ 68 | public String getComment() { 69 | return comment; 70 | } 71 | 72 | /** 73 | * Setter method for property comment. 74 | * 75 | * @param comment value to be assigned to property comment 76 | */ 77 | public void setComment(String comment) { 78 | this.comment = comment; 79 | } 80 | 81 | /** 82 | * Getter method for property fieldInfos. 83 | * 84 | * @return property value of fieldInfos 85 | */ 86 | public List getFieldInfos() { 87 | return fieldInfos; 88 | } 89 | 90 | /** 91 | * Setter method for property fieldInfos. 92 | * 93 | * @param fieldInfos value to be assigned to property fieldInfos 94 | */ 95 | public void setFieldInfos(List fieldInfos) { 96 | this.fieldInfos = fieldInfos; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/DocTagResolver.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver; 6 | 7 | import com.uifuture.supercore.framework.AbstractFramework; 8 | import com.uifuture.supercore.model.ApiModule; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 注释解析器接口,所有的解析器实现都要继承此接口 14 | *

15 | * 现有的实现有基于sun javadoc, 也有基于开源的javaparser 16 | * 17 | * @author chenhx 18 | * @version DocTagResolver.java, v 0.1 2018-09-26 下午 4:45 19 | */ 20 | public interface DocTagResolver { 21 | 22 | /** 23 | * 执行解析 24 | * @param files 要解析的所有java源代码文件的绝对路径 25 | * @param abstractFramework api文档所属框架 26 | * @return 27 | */ 28 | List resolve(List files, AbstractFramework abstractFramework); 29 | } 30 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/IgnoreApi.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | /** 13 | * 忽略生成接口文档 14 | * 15 | * @author chenhx 16 | * @version IgnoreApi.java, v 0.1 2018-09-26 下午 4:46 17 | */ 18 | @Target({ElementType.TYPE, ElementType.METHOD}) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | public @interface IgnoreApi { 21 | } 22 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/JavaParserDocTagResolver.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser; 6 | 7 | 8 | import com.github.javaparser.JavaParser; 9 | import com.github.javaparser.ast.CompilationUnit; 10 | import com.github.javaparser.ast.body.MethodDeclaration; 11 | import com.github.javaparser.ast.body.Parameter; 12 | import com.github.javaparser.ast.body.TypeDeclaration; 13 | import com.github.javaparser.ast.visitor.VoidVisitorAdapter; 14 | import com.uifuture.supercore.framework.AbstractFramework; 15 | import com.uifuture.supercore.model.ApiAction; 16 | import com.uifuture.supercore.model.ApiModule; 17 | import com.uifuture.supercore.model.DocTags; 18 | import com.uifuture.supercore.resolver.DocTagResolver; 19 | import com.uifuture.supercore.resolver.IgnoreApi; 20 | import com.uifuture.supercore.resolver.parser.converter.JavaParserTagConverter; 21 | import com.uifuture.supercore.resolver.parser.converter.JavaParserTagConverterManager; 22 | import com.uifuture.supercore.tag.AbstractDocTag; 23 | import com.uifuture.supercore.utils.ClassMapperUtils; 24 | import com.uifuture.supercore.utils.CommentUtils; 25 | import org.apache.commons.lang3.StringUtils; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.io.FileInputStream; 30 | import java.lang.reflect.Method; 31 | import java.util.ArrayList; 32 | import java.util.LinkedList; 33 | import java.util.List; 34 | 35 | /** 36 | * 基于开源JavaParser实现的解析 37 | * 38 | * @author chenhx 39 | * @version JavaParserDocTagResolver.java, v 0.1 2018-09-26 下午 4:58 40 | */ 41 | 42 | public class JavaParserDocTagResolver implements DocTagResolver { 43 | 44 | private Logger log = LoggerFactory.getLogger(JavaParserDocTagResolver.class); 45 | 46 | /** 47 | * 获取指定方法的所有入参类型,便于反射 48 | * 49 | * @param declaration 50 | * @return 51 | */ 52 | private static Method parseToMenthod(Class type, MethodDeclaration declaration) { 53 | List parameters = declaration.getParameters(); 54 | parameters = parameters == null ? new ArrayList(0) : parameters; 55 | Method[] methods = type.getDeclaredMethods(); 56 | for (Method m : methods) { 57 | if (!m.getName().equals(declaration.getNameAsString())) { 58 | continue; 59 | } 60 | if (m.getParameterTypes().length != parameters.size()) { 61 | continue; 62 | } 63 | 64 | boolean b = true; 65 | 66 | for (int j = 0; j < m.getParameterTypes().length; j++) { 67 | Class paramClass = m.getParameterTypes()[j]; 68 | com.github.javaparser.ast.type.Type ptype = parameters.get(j).getType(); 69 | if (ptype == null) { 70 | continue; 71 | } 72 | String paranTypeName = ptype.toString(); 73 | int index = paranTypeName.lastIndexOf("."); 74 | if (index > 0) { 75 | paranTypeName = paranTypeName.substring(index + 1); 76 | } 77 | //处理泛型 78 | index = paranTypeName.indexOf("<"); 79 | if (index > 0) { 80 | paranTypeName = paranTypeName.substring(0, index); 81 | } 82 | 83 | if (!paramClass.getSimpleName().equals(paranTypeName)) { 84 | b = false; 85 | break; 86 | } 87 | } 88 | if (b) { 89 | return m; 90 | } 91 | } 92 | return null; 93 | } 94 | 95 | @Override 96 | public List resolve(List files, AbstractFramework abstractFramework) { 97 | //缓存文件 98 | for (String file : files) { 99 | try (FileInputStream in = new FileInputStream(file)) { 100 | CompilationUnit cu = JavaParser.parse(in); 101 | if (cu.getTypes().size() <= 0) { 102 | continue; 103 | } 104 | 105 | TypeDeclaration typeDeclaration = cu.getTypes().get(0); 106 | final Class moduleType = Class.forName(cu.getPackageDeclaration().get().getNameAsString() + "." + typeDeclaration.getNameAsString()); 107 | IgnoreApi ignoreApi = moduleType.getAnnotation(IgnoreApi.class); 108 | if (ignoreApi == null) { 109 | //缓存路径 110 | ClassMapperUtils.put(moduleType.getName(), file); 111 | //缓存路径 112 | ClassMapperUtils.put(moduleType.getSimpleName(), file); 113 | } 114 | } catch (Exception e) { 115 | log.warn("读取文件失败:{}, {}", file, e.getMessage()); 116 | } 117 | } 118 | 119 | List apiModules = new LinkedList<>(); 120 | 121 | for (String file : files) { 122 | try (FileInputStream in = new FileInputStream(file)) { 123 | 124 | CompilationUnit cu = JavaParser.parse(in); 125 | if (cu.getTypes().size() <= 0) { 126 | continue; 127 | } 128 | 129 | TypeDeclaration typeDeclaration = cu.getTypes().get(0); 130 | //获取到类对象 131 | final Class moduleType = Class.forName(cu.getPackageDeclaration().get().getNameAsString() + "." + typeDeclaration.getNameAsString()); 132 | 133 | 134 | if (!abstractFramework.support(moduleType)) { 135 | continue; 136 | } 137 | 138 | //跳过生成文档注解 139 | IgnoreApi ignoreApi = moduleType.getAnnotation(IgnoreApi.class); 140 | if (ignoreApi != null) { 141 | continue; 142 | } 143 | 144 | final ApiModule apiModule = new ApiModule(); 145 | apiModule.setType(moduleType); 146 | if (typeDeclaration.getComment().isPresent()) { 147 | String commentText = CommentUtils.parseCommentText(typeDeclaration.getComment().get().getContent()); 148 | commentText = commentText.split("\n")[0].split("\r")[0]; 149 | apiModule.setComment(commentText); 150 | } 151 | 152 | new VoidVisitorAdapter() { 153 | @Override 154 | public void visit(MethodDeclaration m, Void arg) { 155 | Method method = parseToMenthod(moduleType, m); 156 | if (method == null) { 157 | log.warn("查找不到方法:{}.{}", moduleType.getSimpleName(), m.getNameAsString()); 158 | return; 159 | } 160 | 161 | IgnoreApi ignoreApi = method.getAnnotation(IgnoreApi.class); 162 | if (ignoreApi != null || !m.getComment().isPresent()) { 163 | return; 164 | } 165 | 166 | List comments = CommentUtils.asCommentList(StringUtils.defaultIfBlank(m.getComment().get().getContent(), "")); 167 | List abstractDocTagList = new ArrayList<>(comments.size()); 168 | 169 | for (int i = 0; i < comments.size(); i++) { 170 | String c = comments.get(i); 171 | String tagType = CommentUtils.getTagType(c); 172 | if (StringUtils.isBlank(tagType)) { 173 | continue; 174 | } 175 | JavaParserTagConverter converter = JavaParserTagConverterManager.getConverter(tagType); 176 | AbstractDocTag abstractDocTag = converter.converter(c); 177 | if (abstractDocTag != null) { 178 | abstractDocTagList.add(abstractDocTag); 179 | } else { 180 | log.warn("识别不了:{}", c); 181 | } 182 | } 183 | 184 | DocTags docTags = new DocTags(abstractDocTagList); 185 | ApiAction apiAction = new ApiAction(); 186 | if (m.getComment().isPresent()) { 187 | apiAction.setComment(CommentUtils.parseCommentText(m.getComment().get().getContent())); 188 | } 189 | apiAction.setName(m.getNameAsString()); 190 | apiAction.setDocTags(docTags); 191 | apiAction.setMethod(method); 192 | apiModule.getApiActions().add(apiAction); 193 | 194 | super.visit(m, arg); 195 | } 196 | }.visit(cu, null); 197 | 198 | apiModules.add(apiModule); 199 | 200 | } catch (Exception e) { 201 | log.warn("解析{}失败:{}", file, e.getMessage()); 202 | continue; 203 | } 204 | } 205 | return apiModules; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/JavaParserTagConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | 9 | /** 10 | * @author chenhx 11 | * @version JavaParserTagConverter.java, v 0.1 2018-09-26 下午 5:23 12 | */ 13 | public interface JavaParserTagConverter { 14 | AbstractDocTag converter(T o); 15 | } 16 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/JavaParserTagConverterManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter; 6 | 7 | import com.uifuture.supercore.resolver.parser.converter.impl.DefaultJavaParserTagConverterImpl; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author chenhx 14 | * @version JavaParserTagConverterManager.java, v 0.1 2018-09-26 下午 5:23 15 | */ 16 | 17 | public class JavaParserTagConverterManager { 18 | 19 | private static Map registrator = new HashMap<>(); 20 | 21 | private static JavaParserTagConverter defaultTagConverter = new DefaultJavaParserTagConverterImpl(); 22 | 23 | static { 24 | registerConverter("@param", new ParamTagConverter()); 25 | registerConverter("@see", new SeeTagConverter()); 26 | registerConverter("@resp", new RespTagConverter()); 27 | } 28 | 29 | public static void registerConverter(String tagName, JavaParserTagConverter tagConverter) { 30 | registrator.put(tagName, tagConverter); 31 | } 32 | 33 | /** 34 | * 获取标签转换器,如果没有特殊定制的,则返回默认的转换器DefaultJavaParserTagConverterImpl 35 | * 36 | * @param tagName 要转换的标签名称 37 | * @return 匹配到的标签转换器 38 | */ 39 | public static JavaParserTagConverter getConverter(String tagName) { 40 | for (Map.Entry entry : registrator.entrySet()) { 41 | if (entry.getKey().equalsIgnoreCase(tagName)) { 42 | return entry.getValue(); 43 | } 44 | } 45 | return defaultTagConverter; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/ParamTagConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter; 6 | 7 | import com.uifuture.supercore.resolver.parser.converter.impl.DefaultJavaParserTagConverterImpl; 8 | import com.uifuture.supercore.tag.AbstractDocTag; 9 | import com.uifuture.supercore.tag.impl.ParamTagImpl; 10 | import com.uifuture.supercore.utils.Constant; 11 | 12 | /** 13 | * @author chenhx 14 | * @version ParamTagConverter.java, v 0.1 2018-09-26 下午 5:24 15 | */ 16 | 17 | public class ParamTagConverter extends DefaultJavaParserTagConverterImpl { 18 | 19 | @Override 20 | public AbstractDocTag converter(String comment) { 21 | AbstractDocTag abstractDocTag = super.converter(comment); 22 | String values = (String) abstractDocTag.getValues(); 23 | String[] array = values.split("[ \t]+"); 24 | String paramName = null; 25 | String paramDesc = ""; 26 | String paramType = "String"; 27 | boolean require = false; 28 | //解析 "user :username 用户名|必填" 这种注释内容 29 | //或者 "username 用户名|必填" 这种注释内容 30 | //或者 "username 用户名|String|必填" 这种注释内容 31 | //上面的"必填"两个字也可以换成英文的"Y" 32 | 33 | if (array.length > 0) { 34 | //先将第一个认为是参数名称 35 | paramName = array[0]; 36 | if (array.length > 1) { 37 | 38 | int start = 1; 39 | if (array[1].startsWith(":") && array[1].length() > 1) { 40 | //获取 :username这种类型的参数名称 41 | paramName = array[1].substring(1); 42 | start = 2; 43 | } 44 | 45 | StringBuilder sb = new StringBuilder(); 46 | for (int i = start; i < array.length; i++) { 47 | sb.append(array[i]).append(' '); 48 | } 49 | paramDesc = sb.toString(); 50 | } 51 | } 52 | 53 | String[] descs = paramDesc.split("\\|"); 54 | if (descs.length > 0) { 55 | paramDesc = descs[0]; 56 | if (descs.length > 2) { 57 | paramType = descs[1]; 58 | String requireString = descs[descs.length - 1].trim(); 59 | require = Constant.YES_ZH.equals(requireString) || Constant.YES_EN.equalsIgnoreCase(requireString); 60 | } else if (descs.length == 2) { 61 | String requireString = descs[1].trim(); 62 | require = Constant.YES_ZH.equals(requireString) || Constant.YES_EN.equalsIgnoreCase(requireString); 63 | 64 | //如果最后一个不是是否必填的描述,则认为是类型描述 65 | boolean notRequired = !require && !(Constant.NOT_EN.equalsIgnoreCase(requireString) || Constant.NOT_ZH.equals(requireString)); 66 | if (notRequired) { 67 | paramType = requireString; 68 | } 69 | } 70 | } 71 | 72 | return new ParamTagImpl(abstractDocTag.getTagName(), paramName, paramDesc, paramType, require); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/RespTagConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | import com.uifuture.supercore.tag.impl.ParamTagImpl; 9 | import com.uifuture.supercore.tag.impl.RespTagImpl; 10 | 11 | /** 12 | * @author chenhx 13 | * @version RespTagConverter.java, v 0.1 2018-09-26 下午 5:24 14 | */ 15 | 16 | public class RespTagConverter extends ParamTagConverter { 17 | 18 | @Override 19 | public AbstractDocTag converter(String comment) { 20 | ParamTagImpl paramTag = (ParamTagImpl) super.converter(comment); 21 | RespTagImpl respTag = new RespTagImpl(paramTag.getTagName(), paramTag.getParamName(), paramTag.getParamDesc(), 22 | paramTag.getParamType(), paramTag.isRequire()); 23 | return respTag; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/SeeTagConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter; 6 | 7 | import com.github.javaparser.JavaParser; 8 | import com.github.javaparser.ast.CompilationUnit; 9 | import com.github.javaparser.ast.body.FieldDeclaration; 10 | import com.github.javaparser.ast.visitor.VoidVisitorAdapter; 11 | import com.uifuture.supercore.model.FieldInfo; 12 | import com.uifuture.supercore.model.ObjectInfo; 13 | import com.uifuture.supercore.resolver.parser.converter.impl.DefaultJavaParserTagConverterImpl; 14 | import com.uifuture.supercore.tag.AbstractDocTag; 15 | import com.uifuture.supercore.tag.impl.SeeTagImpl; 16 | import com.uifuture.supercore.utils.ClassMapperUtils; 17 | import com.uifuture.supercore.utils.CommentUtils; 18 | import com.uifuture.supercore.utils.Constant; 19 | import org.apache.commons.beanutils.PropertyUtils; 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import java.beans.PropertyDescriptor; 25 | import java.io.FileInputStream; 26 | import java.util.ArrayList; 27 | import java.util.HashMap; 28 | import java.util.LinkedList; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | /** 33 | * @author chenhx 34 | * @version SeeTagConverter.java, v 0.1 2018-09-26 下午 5:24 35 | */ 36 | 37 | public class SeeTagConverter extends DefaultJavaParserTagConverterImpl { 38 | 39 | private Logger log = LoggerFactory.getLogger(SeeTagConverter.class); 40 | 41 | @Override 42 | public AbstractDocTag converter(String comment) { 43 | AbstractDocTag abstractDocTag = super.converter(comment); 44 | 45 | String path = ClassMapperUtils.getPath((String) abstractDocTag.getValues()); 46 | if (StringUtils.isBlank(path)) { 47 | return null; 48 | } 49 | 50 | Class returnClassz; 51 | CompilationUnit cu; 52 | try (FileInputStream in = new FileInputStream(path)) { 53 | cu = JavaParser.parse(in); 54 | if (cu.getTypes().size() <= 0) { 55 | return null; 56 | } 57 | returnClassz = Class.forName(cu.getPackageDeclaration().get().getNameAsString() 58 | + "." + cu.getTypes().get(0).getNameAsString()); 59 | 60 | } catch (Exception e) { 61 | log.warn("读取java原文件失败:{}", path, e.getMessage()); 62 | return null; 63 | } 64 | 65 | String text = cu.getComment().isPresent() ? CommentUtils.parseCommentText(cu.getComment().get().getContent()) : ""; 66 | 67 | Map commentMap = this.analysisFieldComments(returnClassz); 68 | List fields = this.analysisFields(returnClassz, commentMap); 69 | 70 | ObjectInfo objectInfo = new ObjectInfo(); 71 | objectInfo.setType(returnClassz); 72 | objectInfo.setFieldInfos(fields); 73 | objectInfo.setComment(text); 74 | return new SeeTagImpl(abstractDocTag.getTagName(), objectInfo); 75 | } 76 | 77 | private Map analysisFieldComments(Class classz) { 78 | 79 | final Map commentMap = new HashMap(16); 80 | 81 | List classes = new LinkedList<>(); 82 | 83 | Class nowClass = classz; 84 | 85 | //获取所有的属性注释(包括父类的) 86 | while (true) { 87 | classes.add(0, nowClass); 88 | if (Object.class.equals(nowClass) || Object.class.equals(nowClass.getSuperclass())) { 89 | break; 90 | } 91 | nowClass = nowClass.getSuperclass(); 92 | } 93 | 94 | //反方向循环,子类属性注释覆盖父类属性 95 | for (Class clz : classes) { 96 | String path = ClassMapperUtils.getPath(clz.getSimpleName()); 97 | if (StringUtils.isBlank(path)) { 98 | continue; 99 | } 100 | try (FileInputStream in = new FileInputStream(path)) { 101 | CompilationUnit cu = JavaParser.parse(in); 102 | 103 | new VoidVisitorAdapter() { 104 | @Override 105 | public void visit(FieldDeclaration n, Void arg) { 106 | String name = n.getVariable(0).getName().asString(); 107 | 108 | String comment = ""; 109 | if (n.getComment().isPresent()) { 110 | comment = n.getComment().get().getContent(); 111 | } 112 | 113 | if (name.contains("=")) { 114 | name = name.substring(0, name.indexOf("=")).trim(); 115 | } 116 | 117 | commentMap.put(name, CommentUtils.parseCommentText(comment)); 118 | } 119 | }.visit(cu, null); 120 | 121 | } catch (Exception e) { 122 | log.warn("读取java原文件失败:{}", path, e.getMessage(), e); 123 | } 124 | } 125 | 126 | return commentMap; 127 | } 128 | 129 | private List analysisFields(Class classz, Map commentMap) { 130 | PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(classz); 131 | 132 | 133 | List fields = new ArrayList<>(); 134 | 135 | for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { 136 | //排除掉class属性 137 | if ("class".equals(propertyDescriptor.getName())) { 138 | continue; 139 | } 140 | 141 | FieldInfo field = new FieldInfo(); 142 | field.setType(propertyDescriptor.getPropertyType()); 143 | field.setSimpleTypeName(propertyDescriptor.getPropertyType().getSimpleName()); 144 | field.setName(propertyDescriptor.getName()); 145 | String comment = commentMap.get(propertyDescriptor.getName()); 146 | if (StringUtils.isBlank(comment)) { 147 | field.setComment(""); 148 | field.setRequire(false); 149 | fields.add(field); 150 | } else { 151 | boolean require = false; 152 | if (comment.contains("|")) { 153 | int endIndex = comment.lastIndexOf("|" + Constant.YES_ZH); 154 | if (endIndex < 0) { 155 | endIndex = comment.lastIndexOf("|" + Constant.YES_EN); 156 | } 157 | require = endIndex > 0; 158 | 159 | if (require) { 160 | comment = comment.substring(0, endIndex); 161 | } 162 | } 163 | 164 | field.setComment(comment); 165 | field.setRequire(require); 166 | fields.add(field); 167 | } 168 | } 169 | return fields; 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/resolver/parser/converter/impl/DefaultJavaParserTagConverterImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.resolver.parser.converter.impl; 6 | 7 | import com.uifuture.supercore.resolver.parser.converter.JavaParserTagConverter; 8 | import com.uifuture.supercore.tag.AbstractDocTag; 9 | import com.uifuture.supercore.tag.impl.DocTagImpl; 10 | import com.uifuture.supercore.utils.CommentUtils; 11 | 12 | /** 13 | * @author chenhx 14 | * @version DefaultJavaParserTagConverterImpl.java, v 0.1 2018-09-26 下午 5:22 15 | */ 16 | public class DefaultJavaParserTagConverterImpl implements JavaParserTagConverter { 17 | 18 | @Override 19 | public AbstractDocTag converter(String comment) { 20 | String tagType = CommentUtils.getTagType(comment); 21 | String coment = comment.substring(tagType.length()).trim(); 22 | return new DocTagImpl(tagType, coment); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/tag/AbstractDocTag.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.tag; 6 | 7 | /** 8 | * 针对注释标签 9 | * 10 | * @author chenhx 11 | * @version DocTag.java, v 0.1 2018-09-26 下午 4:38 12 | */ 13 | public abstract class AbstractDocTag { 14 | 15 | /** 16 | * 标签名称 17 | */ 18 | private String tagName; 19 | 20 | public AbstractDocTag(String tagName) { 21 | this.tagName = tagName; 22 | } 23 | 24 | public abstract T getValues(); 25 | 26 | /** 27 | * Getter method for property tagName. 28 | * 29 | * @return property value of tagName 30 | */ 31 | public String getTagName() { 32 | return tagName; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/tag/impl/DocTagImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.tag.impl; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | 9 | /** 10 | * 简单文本型注释标签实现 11 | * 12 | * @author chenhx 13 | * @version DocTagImpl.java, v 0.1 2018-09-26 下午 4:39 14 | */ 15 | public class DocTagImpl extends AbstractDocTag { 16 | 17 | private String value; 18 | 19 | public DocTagImpl(String tagName, String value) { 20 | super(tagName); 21 | this.value = value; 22 | } 23 | 24 | @Override 25 | public String getValues() { 26 | return value; 27 | } 28 | 29 | /** 30 | * Getter method for property value. 31 | * 32 | * @return property value of value 33 | */ 34 | public String getValue() { 35 | return value; 36 | } 37 | 38 | /** 39 | * Setter method for property value. 40 | * 41 | * @param value value to be assigned to property value 42 | */ 43 | public void setValue(String value) { 44 | this.value = value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/tag/impl/ParamTagImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.tag.impl; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | 9 | /** 10 | * 对@Param注释的封装 11 | * 12 | * @author chenhx 13 | * @version ParamTagImpl.java, v 0.1 2018-09-26 下午 4:39 14 | */ 15 | public class ParamTagImpl extends AbstractDocTag { 16 | 17 | /** 18 | * 参数名 19 | */ 20 | private String paramName; 21 | 22 | /** 23 | * 参数描述 24 | */ 25 | private String paramDesc; 26 | 27 | /** 28 | * 是否必填,默认false 29 | */ 30 | private boolean require; 31 | 32 | /** 33 | * 参数类型 34 | */ 35 | private String paramType; 36 | 37 | 38 | public ParamTagImpl(String tagName, String paramName, String paramDesc, String paramType, boolean require) { 39 | super(tagName); 40 | this.paramName = paramName; 41 | this.paramDesc = paramDesc; 42 | this.paramType = paramType; 43 | this.require = require; 44 | } 45 | 46 | @Override 47 | public String getValues() { 48 | return paramName + " " + this.paramDesc; 49 | } 50 | 51 | /** 52 | * Getter method for property paramName. 53 | * 54 | * @return property value of paramName 55 | */ 56 | public String getParamName() { 57 | return paramName; 58 | } 59 | 60 | /** 61 | * Setter method for property paramName. 62 | * 63 | * @param paramName value to be assigned to property paramName 64 | */ 65 | public void setParamName(String paramName) { 66 | this.paramName = paramName; 67 | } 68 | 69 | /** 70 | * Getter method for property paramDesc. 71 | * 72 | * @return property value of paramDesc 73 | */ 74 | public String getParamDesc() { 75 | return paramDesc; 76 | } 77 | 78 | /** 79 | * Setter method for property paramDesc. 80 | * 81 | * @param paramDesc value to be assigned to property paramDesc 82 | */ 83 | public void setParamDesc(String paramDesc) { 84 | this.paramDesc = paramDesc; 85 | } 86 | 87 | /** 88 | * Getter method for property require. 89 | * 90 | * @return property value of require 91 | */ 92 | public boolean isRequire() { 93 | return require; 94 | } 95 | 96 | /** 97 | * Setter method for property require. 98 | * 99 | * @param require value to be assigned to property require 100 | */ 101 | public void setRequire(boolean require) { 102 | this.require = require; 103 | } 104 | 105 | /** 106 | * Getter method for property paramType. 107 | * 108 | * @return property value of paramType 109 | */ 110 | public String getParamType() { 111 | return paramType; 112 | } 113 | 114 | /** 115 | * Setter method for property paramType. 116 | * 117 | * @param paramType value to be assigned to property paramType 118 | */ 119 | public void setParamType(String paramType) { 120 | this.paramType = paramType; 121 | } 122 | } -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/tag/impl/RespTagImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.tag.impl; 6 | 7 | import com.uifuture.supercore.tag.AbstractDocTag; 8 | import com.uifuture.supercore.utils.Constant; 9 | import org.apache.commons.lang3.StringUtils; 10 | 11 | /** 12 | * 针对@Resp注释的内容封装 13 | * 14 | * @author chenhx 15 | * @version RespTagImpl.java, v 0.1 2018-09-26 下午 4:40 16 | */ 17 | public class RespTagImpl extends AbstractDocTag { 18 | 19 | /** 20 | * 参数名 21 | */ 22 | private String paramName; 23 | 24 | /** 25 | * 参数描述 26 | */ 27 | private String paramDesc; 28 | 29 | /** 30 | * 是否必填,默认false 31 | */ 32 | private boolean require; 33 | 34 | /** 35 | * 类型 36 | */ 37 | private String paramType; 38 | 39 | 40 | public RespTagImpl(String tagName, String paramName, String paramDesc, String paramType, boolean require) { 41 | super(tagName); 42 | this.paramName = paramName; 43 | this.paramDesc = paramDesc; 44 | this.paramType = paramType; 45 | this.require = require; 46 | } 47 | 48 | @Override 49 | public String getValues() { 50 | String s = paramName + " " + paramDesc; 51 | if (StringUtils.isNotBlank(paramType)) { 52 | s += " " + paramType; 53 | } 54 | s += " " + (require ? Constant.YES_ZH : Constant.NOT_ZH); 55 | return s; 56 | } 57 | 58 | 59 | /** 60 | * Getter method for property paramName. 61 | * 62 | * @return property value of paramName 63 | */ 64 | public String getParamName() { 65 | return paramName; 66 | } 67 | 68 | /** 69 | * Setter method for property paramName. 70 | * 71 | * @param paramName value to be assigned to property paramName 72 | */ 73 | public void setParamName(String paramName) { 74 | this.paramName = paramName; 75 | } 76 | 77 | /** 78 | * Getter method for property paramDesc. 79 | * 80 | * @return property value of paramDesc 81 | */ 82 | public String getParamDesc() { 83 | return paramDesc; 84 | } 85 | 86 | /** 87 | * Setter method for property paramDesc. 88 | * 89 | * @param paramDesc value to be assigned to property paramDesc 90 | */ 91 | public void setParamDesc(String paramDesc) { 92 | this.paramDesc = paramDesc; 93 | } 94 | 95 | /** 96 | * Getter method for property require. 97 | * 98 | * @return property value of require 99 | */ 100 | public boolean isRequire() { 101 | return require; 102 | } 103 | 104 | /** 105 | * Setter method for property require. 106 | * 107 | * @param require value to be assigned to property require 108 | */ 109 | public void setRequire(boolean require) { 110 | this.require = require; 111 | } 112 | 113 | /** 114 | * Getter method for property paramType. 115 | * 116 | * @return property value of paramType 117 | */ 118 | public String getParamType() { 119 | return paramType; 120 | } 121 | 122 | /** 123 | * Setter method for property paramType. 124 | * 125 | * @param paramType value to be assigned to property paramType 126 | */ 127 | public void setParamType(String paramType) { 128 | this.paramType = paramType; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/tag/impl/SeeTagImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.tag.impl; 6 | 7 | import com.uifuture.supercore.model.ObjectInfo; 8 | import com.uifuture.supercore.tag.AbstractDocTag; 9 | 10 | /** 11 | * 针对@see注释标签进行封装,返回@see上注释的类信息 12 | * 13 | * @author chenhx 14 | * @version SeeTagImpl.java, v 0.1 2018-09-26 下午 4:40 15 | */ 16 | public class SeeTagImpl extends AbstractDocTag { 17 | 18 | private ObjectInfo objectInfo; 19 | 20 | public SeeTagImpl(String tagName, ObjectInfo objectInfo) { 21 | super(tagName); 22 | this.objectInfo = objectInfo; 23 | } 24 | 25 | @Override 26 | public ObjectInfo getValues() { 27 | return objectInfo; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/ClassMapperUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author chenhx 12 | * @version ClassMapperUtils.java, v 0.1 2018-09-26 下午 4:41 13 | */ 14 | public class ClassMapperUtils { 15 | 16 | private static Map classPath = new HashMap<>(); 17 | 18 | public static void put(String name, String path) { 19 | classPath.put(name, path); 20 | } 21 | 22 | public static String getPath(String name) { 23 | return classPath.get(name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/ClassUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | /** 8 | * @author chenhx 9 | * @version ClassUtils.java, v 0.1 2018-09-26 下午 4:42 10 | */ 11 | public class ClassUtils { 12 | /** 13 | * 将基本类型的转为class类型 14 | * @param className 15 | * @return 16 | */ 17 | public static Class toBae(String className) { 18 | if ("byte".equals(className)) { 19 | return byte.class; 20 | } else if ("short".equals(className)) { 21 | return short.class; 22 | } else if ("int".equals(className)) { 23 | return int.class; 24 | } else if ("long".equals(className)) { 25 | return long.class; 26 | } else if ("float".equals(className)) { 27 | return float.class; 28 | } else if ("double".equals(className)) { 29 | return double.class; 30 | } else if ("boolean".equals(className)) { 31 | return boolean.class; 32 | } else if ("char".equals(className)) { 33 | return char.class; 34 | } else { 35 | return null; 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/CommentUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | import org.apache.commons.lang3.StringUtils; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | /** 15 | * @author chenhx 16 | * @version CommentUtils.java, v 0.1 2018-09-26 下午 4:42 17 | */ 18 | public class CommentUtils { 19 | private final static Pattern COMPILE = Pattern.compile("^@[\\w]+[\\t ]"); 20 | 21 | /** 22 | * 获取注释的类型 23 | * 24 | * @param coment 25 | * @return @see @param @resp @return等 26 | */ 27 | public static String getTagType(String coment) { 28 | Matcher m = COMPILE.matcher(coment); 29 | if (m.find()) { 30 | return m.group().trim(); 31 | } else { 32 | return null; 33 | } 34 | } 35 | 36 | /** 37 | * 解析基本的文本注释 38 | * 39 | * @param coment 40 | * @return 41 | */ 42 | public static String parseCommentText(String coment) { 43 | List coments = asCommentList(coment); 44 | for (String s : coments) { 45 | if (!s.startsWith("@")) { 46 | return s; 47 | } 48 | } 49 | return ""; 50 | } 51 | 52 | /** 53 | * 将注释转为多行文本 54 | * 55 | * @param coment 56 | * @return 57 | */ 58 | public static List asCommentList(String coment) { 59 | coment = coment.replaceAll("\\*", "").trim(); 60 | String[] array = coment.split("\n"); 61 | List comments = new ArrayList(array.length); 62 | int index = 0; 63 | StringBuilder sb = new StringBuilder(); 64 | for (; index < array.length; index++) { 65 | String c = array[index].trim(); 66 | 67 | if (StringUtils.isBlank(c)) { 68 | continue; 69 | } 70 | 71 | String tagType = CommentUtils.getTagType(c); 72 | if (StringUtils.isBlank(tagType)) { 73 | sb.append(c); 74 | sb.append("\n"); 75 | } else { 76 | break; 77 | } 78 | } 79 | 80 | if (sb.length() > 0) { 81 | sb.deleteCharAt(sb.length() - 1); 82 | comments.add(sb.toString()); 83 | } 84 | 85 | for (int i = index; i < array.length; i++) { 86 | String c = array[i].trim(); 87 | if (StringUtils.isNotBlank(c)) { 88 | comments.add(c); 89 | } 90 | } 91 | return comments; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/Constant.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | /** 8 | * @author chenhx 9 | * @version Constant.java, v 0.1 2018-09-26 下午 4:43 10 | */ 11 | public class Constant { 12 | 13 | public static final String NOT_EN = "N"; 14 | public static final String NOT_ZH = "非必填"; 15 | public static final String YES_EN = "Y"; 16 | public static final String YES_ZH = "必填"; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | import java.io.File; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author chenhx 13 | * @version FileUtils.java, v 0.1 2018-09-26 下午 4:43 14 | */ 15 | public class FileUtils { 16 | 17 | /** 18 | * 递归获取指定目录下面所有的Java文件,包括子目录中的 19 | * 20 | * @param file 文件目录 21 | * @return 所有java文件 22 | */ 23 | public static List getAllJavaFiles(File file) { 24 | if (!file.exists()) { 25 | return new ArrayList(0); 26 | } 27 | 28 | if (file.isFile()) { 29 | if (file.getName().lastIndexOf(".java") > 0) { 30 | List list = new ArrayList(); 31 | list.add(file.getAbsolutePath()); 32 | return list; 33 | } else { 34 | return new ArrayList(0); 35 | } 36 | } 37 | 38 | List list = new ArrayList(); 39 | if (file.isDirectory()) { 40 | File[] files = file.listFiles(); 41 | if (files != null) { 42 | for (File f : files) { 43 | list.addAll(getAllJavaFiles(f)); 44 | } 45 | } 46 | } 47 | return list; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/JsonFormatUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | /** 8 | * @author chenhx 9 | * @version JsonFormatUtils.java, v 0.1 2018-09-26 下午 4:44 10 | */ 11 | public class JsonFormatUtils { 12 | 13 | /** 14 | * 格式化json字符串 15 | * 16 | * @param jsonStr 17 | * @return 18 | */ 19 | public static String formatJson(String jsonStr) { 20 | if (null == jsonStr || "".equals(jsonStr)) { 21 | return ""; 22 | } 23 | StringBuilder sb = new StringBuilder(); 24 | char last; 25 | char current = '\0'; 26 | int indent = 0; 27 | for (int i = 0; i < jsonStr.length(); i++) { 28 | last = current; 29 | current = jsonStr.charAt(i); 30 | switch (current) { 31 | case '{': 32 | case '[': 33 | sb.append(current); 34 | sb.append('\n'); 35 | indent++; 36 | addIndentBlank(sb, indent); 37 | break; 38 | case '}': 39 | case ']': 40 | sb.append('\n'); 41 | indent--; 42 | addIndentBlank(sb, indent); 43 | sb.append(current); 44 | break; 45 | case ',': 46 | sb.append(current); 47 | if (last != '\\') { 48 | sb.append('\n'); 49 | addIndentBlank(sb, indent); 50 | } 51 | break; 52 | default: 53 | sb.append(current); 54 | } 55 | } 56 | 57 | return sb.toString(); 58 | } 59 | 60 | /** 61 | * 添加space 62 | * 63 | * @param sb 64 | * @param indent 65 | */ 66 | private static void addIndentBlank(StringBuilder sb, int indent) { 67 | for (int i = 0; i < indent; i++) { 68 | sb.append('\t'); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/java/com/uifuture/supercore/utils/JsonUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.supercore.utils; 6 | 7 | import com.fasterxml.jackson.annotation.JsonInclude; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | 11 | import java.text.SimpleDateFormat; 12 | 13 | /** 14 | * @author chenhx 15 | * @version JsonUtils.java, v 0.1 2018-09-26 下午 4:44 16 | */ 17 | public class JsonUtils { 18 | 19 | private static ObjectMapper objectMapper = new ObjectMapper(); 20 | 21 | static { 22 | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 23 | objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); 24 | } 25 | 26 | /** 27 | * 将一个对象转为json字符窜 28 | */ 29 | public static String toJson(Object obj) { 30 | try { 31 | return objectMapper.writeValueAsString(obj); 32 | } catch (JsonProcessingException e) { 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /super-java-doc-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36}:%L - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /super-java-doc-spring/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | super-java-doc 7 | com.uifuture 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | super-java-doc-spring 13 | 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter-web 19 | 20 | 21 | 22 | com.uifuture 23 | super-java-doc-core 24 | 1.0.0 25 | 26 | 27 | 28 | 29 | org.apache.velocity 30 | velocity 31 | 1.7 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/format/HtmlForamt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.format; 6 | 7 | import com.uifuture.supercore.format.Format; 8 | import com.uifuture.supercore.model.ApiDoc; 9 | import com.uifuture.supercore.utils.JsonUtils; 10 | import org.apache.commons.io.IOUtils; 11 | import org.apache.commons.lang3.StringUtils; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * @author chenhx 20 | * @version HtmlForamt.java, v 0.1 2018-09-26 下午 5:32 21 | */ 22 | 23 | public class HtmlForamt implements Format { 24 | 25 | @Override 26 | public String format(ApiDoc apiDoc) { 27 | InputStream in = HtmlForamt.class.getResourceAsStream("html.vm"); 28 | if (in != null) { 29 | try { 30 | String s = IOUtils.toString(in, "utf-8"); 31 | 32 | Map model = new HashMap<>(4); 33 | model.put("title", StringUtils.defaultString((String) apiDoc.getProperties().get("title"), "接口文档")); 34 | model.put("apiModules", apiDoc.getApiModules()); 35 | //生成json数据 36 | return s.replace("_apis_json", JsonUtils.toJson(model)); 37 | } catch (IOException e) { 38 | throw new RuntimeException(e); 39 | } finally { 40 | IOUtils.closeQuietly(in); 41 | } 42 | } 43 | return ""; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/format/MarkdownFormat.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.format; 6 | 7 | import com.uifuture.supercore.format.Format; 8 | import com.uifuture.supercore.model.ApiAction; 9 | import com.uifuture.supercore.model.ApiDoc; 10 | import com.uifuture.supercore.model.ApiModule; 11 | import com.uifuture.supercore.utils.JsonFormatUtils; 12 | import com.uifuture.superspring.framework.SpringApiAction; 13 | import org.apache.commons.beanutils.PropertyUtils; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.util.Map; 19 | 20 | /** 21 | * @author chenhx 22 | * @version MarkdownFormat.java, v 0.1 2018-09-26 下午 5:32 23 | */ 24 | 25 | public class MarkdownFormat implements Format { 26 | 27 | private Logger log = LoggerFactory.getLogger(getClass()); 28 | 29 | private VelocityTemplater templater = new VelocityTemplater("com/uifuture/superspring/format/api.vm"); 30 | 31 | @Override 32 | public String format(ApiDoc apiDoc) { 33 | StringBuilder sb = new StringBuilder(); 34 | for (ApiModule apiModule : apiDoc.getApiModules()) { 35 | sb.append(format(apiModule)).append("\n\n"); 36 | } 37 | return sb.toString(); 38 | } 39 | 40 | private String format(ApiModule apiModule) { 41 | 42 | for (ApiAction apiAction : apiModule.getApiActions()) { 43 | SpringApiAction saa = (SpringApiAction) apiAction; 44 | if (saa.isJson() && StringUtils.isNotBlank(saa.getRespbody())) { 45 | saa.setRespbody(JsonFormatUtils.formatJson(saa.getRespbody())); 46 | } 47 | } 48 | 49 | try { 50 | Map map = PropertyUtils.describe(apiModule); 51 | return templater.parse(map); 52 | } catch (Exception e) { 53 | log.error("输出markdown文档格式失败", e); 54 | } 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/format/VelocityTemplater.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.format; 6 | 7 | import org.apache.velocity.Template; 8 | import org.apache.velocity.VelocityContext; 9 | import org.apache.velocity.app.Velocity; 10 | import org.apache.velocity.app.VelocityEngine; 11 | 12 | import java.io.StringWriter; 13 | import java.util.Map; 14 | 15 | /** 16 | * @author chenhx 17 | * @version VelocityTemplater.java, v 0.1 2018-09-26 下午 5:32 18 | */ 19 | 20 | public class VelocityTemplater { 21 | 22 | public static final String ENCODING = "UTF-8"; 23 | 24 | private static VelocityEngine ve = new VelocityEngine(); 25 | 26 | static { 27 | //设置模板加载路径,这里设置的是class下 28 | ve.setProperty(Velocity.RESOURCE_LOADER, "class"); 29 | ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 30 | ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogChute"); 31 | ve.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_CACHE, false); 32 | // ve.setProperty("file.resource.loader.modificationCheckInterval", 10); 33 | ve.init(); 34 | } 35 | 36 | private String path; 37 | 38 | public VelocityTemplater(String path) { 39 | this.path = path; 40 | } 41 | 42 | public String parse(Map param) { 43 | 44 | // Template template = ve.getTemplate("com/jleaf/test/netty/template/" + name + ".vm", ENCODING); 45 | Template template = ve.getTemplate(path, ENCODING); 46 | 47 | VelocityContext velocityContext = new VelocityContext(); 48 | 49 | for (Map.Entry entry : param.entrySet()) { 50 | velocityContext.put(entry.getKey(), entry.getValue()); 51 | } 52 | 53 | StringWriter sw = new StringWriter(); 54 | template.merge(velocityContext, sw); 55 | 56 | return sw.toString(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/format/api.vm: -------------------------------------------------------------------------------- 1 | # $comment 2 | 3 | #foreach( $apiAction in $apiActions) 4 | 5 | --- 6 | # $apiAction.title 7 | > $apiAction.comment 8 | 9 | 地址: $uris.get(0)/$apiAction.uris.get(0) 10 | #if($apiAction.methods.size() > 0) 11 | 支持方式: $apiAction.methods 12 | #else 13 | 支持方式: 所有 14 | #end 15 | 16 | **参数:** 17 | 18 | 参数名|描述|是否必填 19 | -----|------|------ 20 | #foreach($p in $apiAction.param) 21 | $p.paramName|$p.paramDesc|$p.require 22 | #end 23 | 24 | **返回:** 25 | $apiAction.returnDesc 26 | 27 | 参数名|类型|描述 28 | -----|------|------ 29 | #foreach($field in $apiAction.returnObj.fieldInfos) 30 | $field.name|$field.simpleTypeName|$field.comment 31 | #end 32 | #if($apiAction.respbody) 33 | 返回: 34 | ```json 35 | $apiAction.respbody 36 | ``` 37 | #end 38 | #end -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/format/html.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 离线接口文档 6 | 7 | 8 | 9 | 10 | 11 |

12 |
13 | 14 |

{{title}}

15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 24 | 25 |
26 | 28 |
29 |
30 |

{{currentApiAction.title}}

31 |

描述: {{currentApiAction.comment}}

32 |

只支持: 33 | {{m}} 34 |

35 |

接口地址: {{(currentApiModule.uris[0] ? currentApiModule.uris[0] 36 | : '') + uri}}

37 |

接口返回: {{currentApiAction.returnDesc}}

38 | 39 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 72 |
{{reverseRespbody}}
73 |
74 |
75 |
76 | 77 |
78 |

测试

79 |
80 |
81 | 82 | 83 | 84 | 85 | {{m}} 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 测试 95 | 重置 96 | 97 | 98 | 99 |

返回内容

100 |
101 |
102 | 104 |
105 |
106 |
107 |
108 | 109 | 112 | 181 | 414 | 415 | 416 | 521 | 522 | 523 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/framework/ParamInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.framework; 6 | 7 | /** 8 | * @author chenhx 9 | * @version ParamInfo.java, v 0.1 2018-09-26 下午 5:30 10 | */ 11 | 12 | public class ParamInfo { 13 | 14 | /** 15 | * 参数名 16 | */ 17 | private String paramName; 18 | 19 | /** 20 | * 参数描述 21 | */ 22 | private String paramDesc; 23 | 24 | /** 25 | * 是否必填,默认false 26 | */ 27 | private boolean require; 28 | 29 | /** 30 | * 类型 31 | */ 32 | private String paramType; 33 | 34 | /** 35 | * Getter method for property paramName. 36 | * 37 | * @return property value of paramName 38 | */ 39 | public String getParamName() { 40 | return paramName; 41 | } 42 | 43 | /** 44 | * Setter method for property paramName. 45 | * 46 | * @param paramName value to be assigned to property paramName 47 | */ 48 | public void setParamName(String paramName) { 49 | this.paramName = paramName; 50 | } 51 | 52 | /** 53 | * Getter method for property paramDesc. 54 | * 55 | * @return property value of paramDesc 56 | */ 57 | public String getParamDesc() { 58 | return paramDesc; 59 | } 60 | 61 | /** 62 | * Setter method for property paramDesc. 63 | * 64 | * @param paramDesc value to be assigned to property paramDesc 65 | */ 66 | public void setParamDesc(String paramDesc) { 67 | this.paramDesc = paramDesc; 68 | } 69 | 70 | /** 71 | * Getter method for property require. 72 | * 73 | * @return property value of require 74 | */ 75 | public boolean isRequire() { 76 | return require; 77 | } 78 | 79 | /** 80 | * Setter method for property require. 81 | * 82 | * @param require value to be assigned to property require 83 | */ 84 | public void setRequire(boolean require) { 85 | this.require = require; 86 | } 87 | 88 | /** 89 | * Getter method for property paramType. 90 | * 91 | * @return property value of paramType 92 | */ 93 | public String getParamType() { 94 | return paramType; 95 | } 96 | 97 | /** 98 | * Setter method for property paramType. 99 | * 100 | * @param paramType value to be assigned to property paramType 101 | */ 102 | public void setParamType(String paramType) { 103 | this.paramType = paramType; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/framework/SpringApiAction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.framework; 6 | 7 | 8 | import com.uifuture.supercore.model.ApiAction; 9 | import com.uifuture.supercore.model.ObjectInfo; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * @author chenhx 16 | * @version SpringApiAction.java, v 0.1 2018-09-26 下午 5:31 17 | */ 18 | 19 | public class SpringApiAction extends ApiAction { 20 | 21 | /** 22 | * 访问的uri地址 23 | */ 24 | private List uris; 25 | 26 | /** 27 | * 允许的访问方法:POST,GET,DELETE,PUT等, 如果没有,则无限制 28 | */ 29 | private List methods; 30 | 31 | /** 32 | * 入参 33 | */ 34 | private List param = new ArrayList<>(0); 35 | 36 | /** 37 | * 返回对象 38 | */ 39 | private ObjectInfo returnObj; 40 | 41 | /** 42 | * 出参 43 | */ 44 | private List respParam = new ArrayList<>(0); 45 | 46 | /** 47 | * 返回描述 48 | */ 49 | private String returnDesc; 50 | 51 | /** 52 | * 返回的数据 53 | */ 54 | private String respbody; 55 | 56 | /** 57 | * 是否返回json 58 | */ 59 | private boolean json; 60 | 61 | 62 | /** 63 | * Getter method for property uris. 64 | * 65 | * @return property value of uris 66 | */ 67 | public List getUris() { 68 | return uris; 69 | } 70 | 71 | /** 72 | * Setter method for property uris. 73 | * 74 | * @param uris value to be assigned to property uris 75 | */ 76 | public void setUris(List uris) { 77 | this.uris = uris; 78 | } 79 | 80 | /** 81 | * Getter method for property methods. 82 | * 83 | * @return property value of methods 84 | */ 85 | public List getMethods() { 86 | return methods; 87 | } 88 | 89 | /** 90 | * Setter method for property methods. 91 | * 92 | * @param methods value to be assigned to property methods 93 | */ 94 | public void setMethods(List methods) { 95 | this.methods = methods; 96 | } 97 | 98 | /** 99 | * Getter method for property param. 100 | * 101 | * @return property value of param 102 | */ 103 | public List getParam() { 104 | return param; 105 | } 106 | 107 | /** 108 | * Setter method for property param. 109 | * 110 | * @param param value to be assigned to property param 111 | */ 112 | public void setParam(List param) { 113 | this.param = param; 114 | } 115 | 116 | /** 117 | * Getter method for property returnObj. 118 | * 119 | * @return property value of returnObj 120 | */ 121 | public ObjectInfo getReturnObj() { 122 | return returnObj; 123 | } 124 | 125 | /** 126 | * Setter method for property returnObj. 127 | * 128 | * @param returnObj value to be assigned to property returnObj 129 | */ 130 | public void setReturnObj(ObjectInfo returnObj) { 131 | this.returnObj = returnObj; 132 | } 133 | 134 | /** 135 | * Getter method for property respParam. 136 | * 137 | * @return property value of respParam 138 | */ 139 | public List getRespParam() { 140 | return respParam; 141 | } 142 | 143 | /** 144 | * Setter method for property respParam. 145 | * 146 | * @param respParam value to be assigned to property respParam 147 | */ 148 | public void setRespParam(List respParam) { 149 | this.respParam = respParam; 150 | } 151 | 152 | /** 153 | * Getter method for property returnDesc. 154 | * 155 | * @return property value of returnDesc 156 | */ 157 | public String getReturnDesc() { 158 | return returnDesc; 159 | } 160 | 161 | /** 162 | * Setter method for property returnDesc. 163 | * 164 | * @param returnDesc value to be assigned to property returnDesc 165 | */ 166 | public void setReturnDesc(String returnDesc) { 167 | this.returnDesc = returnDesc; 168 | } 169 | 170 | /** 171 | * Getter method for property respbody. 172 | * 173 | * @return property value of respbody 174 | */ 175 | public String getRespbody() { 176 | return respbody; 177 | } 178 | 179 | /** 180 | * Setter method for property respbody. 181 | * 182 | * @param respbody value to be assigned to property respbody 183 | */ 184 | public void setRespbody(String respbody) { 185 | this.respbody = respbody; 186 | } 187 | 188 | /** 189 | * Getter method for property json. 190 | * 191 | * @return property value of json 192 | */ 193 | public boolean isJson() { 194 | return json; 195 | } 196 | 197 | /** 198 | * Setter method for property json. 199 | * 200 | * @param json value to be assigned to property json 201 | */ 202 | public void setJson(boolean json) { 203 | this.json = json; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/framework/SpringApiModule.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.framework; 6 | 7 | import com.uifuture.supercore.model.ApiModule; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author chenhx 13 | * @version SpringApiModule.java, v 0.1 2018-09-26 下午 5:31 14 | */ 15 | 16 | public class SpringApiModule extends ApiModule { 17 | 18 | /** 19 | * 业务模块首地址 20 | */ 21 | private List uris; 22 | 23 | /** 24 | * 接口限制必须采用访问方式 25 | */ 26 | private List methods; 27 | 28 | /** 29 | * 是否返回json 30 | */ 31 | private boolean json; 32 | 33 | /** 34 | * Getter method for property uris. 35 | * 36 | * @return property value of uris 37 | */ 38 | public List getUris() { 39 | return uris; 40 | } 41 | 42 | /** 43 | * Setter method for property uris. 44 | * 45 | * @param uris value to be assigned to property uris 46 | */ 47 | public void setUris(List uris) { 48 | this.uris = uris; 49 | } 50 | 51 | /** 52 | * Getter method for property methods. 53 | * 54 | * @return property value of methods 55 | */ 56 | public List getMethods() { 57 | return methods; 58 | } 59 | 60 | /** 61 | * Setter method for property methods. 62 | * 63 | * @param methods value to be assigned to property methods 64 | */ 65 | public void setMethods(List methods) { 66 | this.methods = methods; 67 | } 68 | 69 | /** 70 | * Getter method for property json. 71 | * 72 | * @return property value of json 73 | */ 74 | public boolean isJson() { 75 | return json; 76 | } 77 | 78 | /** 79 | * Setter method for property json. 80 | * 81 | * @param json value to be assigned to property json 82 | */ 83 | public void setJson(boolean json) { 84 | this.json = json; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/java/com/uifuture/superspring/framework/SpringWebFramework.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superspring.framework; 6 | 7 | import com.uifuture.supercore.framework.AbstractFramework; 8 | import com.uifuture.supercore.model.ApiAction; 9 | import com.uifuture.supercore.model.ApiModule; 10 | import com.uifuture.supercore.model.ObjectInfo; 11 | import com.uifuture.supercore.tag.AbstractDocTag; 12 | import com.uifuture.supercore.tag.impl.ParamTagImpl; 13 | import com.uifuture.supercore.tag.impl.RespTagImpl; 14 | import com.uifuture.supercore.tag.impl.SeeTagImpl; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.web.bind.annotation.DeleteMapping; 17 | import org.springframework.web.bind.annotation.GetMapping; 18 | import org.springframework.web.bind.annotation.PatchMapping; 19 | import org.springframework.web.bind.annotation.PostMapping; 20 | import org.springframework.web.bind.annotation.PutMapping; 21 | import org.springframework.web.bind.annotation.RequestMapping; 22 | import org.springframework.web.bind.annotation.RequestMethod; 23 | import org.springframework.web.bind.annotation.ResponseBody; 24 | import org.springframework.web.bind.annotation.RestController; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * 基于spirng web框架,扩展api数据 31 | * 32 | * @author chenhx 33 | * @version SpringWebFramework.java, v 0.1 2018-09-26 下午 5:31 34 | */ 35 | 36 | public class SpringWebFramework extends AbstractFramework { 37 | 38 | @Override 39 | public boolean support(Class classz) { 40 | if (classz.getAnnotation(Controller.class) != null 41 | || classz.getAnnotation(RestController.class) != null) { 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | @Override 48 | public List extend(List apiModules) { 49 | if (apiModules == null) { 50 | return new ArrayList<>(0); 51 | } 52 | List list = new ArrayList<>(apiModules.size()); 53 | for (ApiModule apiModule : apiModules) { 54 | SpringApiModule sam = new SpringApiModule(); 55 | 56 | sam.setComment(apiModule.getComment()); 57 | sam.setType(apiModule.getType()); 58 | boolean isjson = this.isJson(apiModule.getType()); 59 | sam.setJson(isjson); 60 | 61 | RequestMapping classRequestMappingAnno = apiModule.getType().getAnnotation(RequestMapping.class); 62 | //接口地址 63 | if (classRequestMappingAnno != null) { 64 | String[] urls = classRequestMappingAnno.value(); 65 | addSprit(urls); 66 | sam.setUris(this.getUris(urls)); 67 | sam.setMethods(this.getMethods(classRequestMappingAnno.method())); 68 | } else { 69 | sam.setUris(new ArrayList<>(0)); 70 | sam.setMethods(new ArrayList<>(0)); 71 | } 72 | 73 | for (ApiAction apiAction : apiModule.getApiActions()) { 74 | SpringApiAction saa = this.buildSpringApiAction(apiAction, isjson); 75 | if (saa != null) { 76 | sam.getApiActions().add(saa); 77 | } 78 | } 79 | 80 | list.add(sam); 81 | } 82 | return list; 83 | } 84 | 85 | /** 86 | * 兼容链接开始没有添加斜杠的情况 87 | * 88 | * @param urls 89 | */ 90 | private void addSprit(String[] urls) { 91 | for (int i = 0; i < urls.length; i++) { 92 | if (urls[i].length() > 0) { 93 | if (urls[i].charAt(0) != '/') { 94 | urls[i] = "/" + urls[i]; 95 | } 96 | } else { 97 | urls[i] = "/"; 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * 构建基于spring web的接口 104 | * 105 | * @param apiAction 106 | * @param isjson 是否json 107 | * @return 108 | */ 109 | private SpringApiAction buildSpringApiAction(ApiAction apiAction, boolean isjson) { 110 | SpringApiAction saa = new SpringApiAction(); 111 | saa.setName(apiAction.getName()); 112 | saa.setComment(apiAction.getComment()); 113 | saa.setMethod(apiAction.getMethod()); 114 | saa.setDocTags(apiAction.getDocTags()); 115 | 116 | if (isjson || apiAction.getMethod().getAnnotation(ResponseBody.class) != null) { 117 | saa.setJson(true); 118 | } 119 | 120 | saa.setTitle(getTitile(saa)); 121 | saa.setRespbody(getRespbody(saa)); 122 | 123 | boolean isMappingMethod = this.setUrisAndMethods(apiAction, saa); 124 | 125 | if (!isMappingMethod) { 126 | return null; 127 | } 128 | 129 | saa.setParam(this.getParams(saa)); 130 | saa.setRespParam(this.getRespParam(saa)); 131 | saa.setReturnObj(this.getReturnObj(saa)); 132 | saa.setReturnDesc(this.getReturnDesc(saa)); 133 | 134 | return saa; 135 | } 136 | 137 | private boolean setUrisAndMethods(ApiAction apiAction, SpringApiAction saa) { 138 | RequestMapping methodRequestMappingAnno = apiAction.getMethod().getAnnotation(RequestMapping.class); 139 | if (methodRequestMappingAnno != null) { 140 | String[] urls = methodRequestMappingAnno.value(); 141 | addSprit(urls); 142 | 143 | saa.setUris(this.getUris(urls)); 144 | saa.setMethods(this.getMethods(methodRequestMappingAnno.method())); 145 | return true; 146 | } 147 | 148 | PostMapping postMapping = apiAction.getMethod().getAnnotation(PostMapping.class); 149 | if (postMapping != null) { 150 | String[] urls = postMapping.value(); 151 | addSprit(urls); 152 | 153 | saa.setUris(this.getUris(urls)); 154 | saa.setMethods(this.getMethods(RequestMethod.POST)); 155 | return true; 156 | } 157 | 158 | GetMapping getMapping = apiAction.getMethod().getAnnotation(GetMapping.class); 159 | if (getMapping != null) { 160 | String[] urls = getMapping.value(); 161 | addSprit(urls); 162 | 163 | saa.setUris(this.getUris(urls)); 164 | saa.setMethods(this.getMethods(RequestMethod.GET)); 165 | return true; 166 | } 167 | 168 | PutMapping putMapping = apiAction.getMethod().getAnnotation(PutMapping.class); 169 | if (putMapping != null) { 170 | String[] urls = putMapping.value(); 171 | addSprit(urls); 172 | 173 | saa.setUris(this.getUris(urls)); 174 | saa.setMethods(this.getMethods(RequestMethod.PUT)); 175 | return true; 176 | } 177 | 178 | DeleteMapping deleteMapping = apiAction.getMethod().getAnnotation(DeleteMapping.class); 179 | if (deleteMapping != null) { 180 | String[] urls = deleteMapping.value(); 181 | addSprit(urls); 182 | 183 | saa.setUris(this.getUris(urls)); 184 | saa.setMethods(this.getMethods(RequestMethod.DELETE)); 185 | return true; 186 | } 187 | 188 | PatchMapping patchMapping = apiAction.getMethod().getAnnotation(PatchMapping.class); 189 | if (patchMapping != null) { 190 | String[] urls = patchMapping.value(); 191 | addSprit(urls); 192 | 193 | saa.setUris(this.getUris(urls)); 194 | saa.setMethods(this.getMethods(RequestMethod.PATCH)); 195 | return true; 196 | } 197 | return false; 198 | } 199 | 200 | protected String getReturnDesc(SpringApiAction saa) { 201 | AbstractDocTag tag = saa.getDocTags().getTag("@return"); 202 | return tag != null ? tag.getValues().toString() : null; 203 | } 204 | 205 | protected ObjectInfo getReturnObj(SpringApiAction saa) { 206 | SeeTagImpl tag = (SeeTagImpl) saa.getDocTags().getTag("@see"); 207 | return tag != null ? tag.getValues() : null; 208 | } 209 | 210 | protected List getParams(SpringApiAction saa) { 211 | List tags = saa.getDocTags().getTags("@param"); 212 | List paramInfos = new ArrayList<>(tags.size()); 213 | for (Object tag : tags) { 214 | ParamTagImpl paramTag = (ParamTagImpl) tag; 215 | ParamInfo paramInfo = new ParamInfo(); 216 | paramInfo.setParamName(paramTag.getParamName()); 217 | paramInfo.setParamDesc(paramTag.getParamDesc()); 218 | paramInfo.setParamType(paramTag.getParamType()); 219 | paramInfo.setRequire(paramTag.isRequire()); 220 | paramInfos.add(paramInfo); 221 | } 222 | return paramInfos; 223 | } 224 | 225 | protected List getRespParam(SpringApiAction saa) { 226 | List tags = saa.getDocTags().getTags("@resp"); 227 | List list = new ArrayList(tags.size()); 228 | for (AbstractDocTag tag : tags) { 229 | RespTagImpl respTag = (RespTagImpl) tag; 230 | ParamInfo paramInfo = new ParamInfo(); 231 | paramInfo.setParamName(respTag.getParamName()); 232 | paramInfo.setRequire(respTag.isRequire()); 233 | paramInfo.setParamDesc(respTag.getParamDesc()); 234 | paramInfo.setParamType(respTag.getParamType()); 235 | list.add(paramInfo); 236 | } 237 | return list; 238 | } 239 | 240 | protected String getRespbody(SpringApiAction saa) { 241 | AbstractDocTag respbodyTag = saa.getDocTags().getTag("@respbody"); 242 | if (respbodyTag != null) { 243 | return (String) respbodyTag.getValues(); 244 | } 245 | return null; 246 | } 247 | 248 | protected String getTitile(SpringApiAction saa) { 249 | AbstractDocTag titleTag = saa.getDocTags().getTag("@title"); 250 | if (titleTag != null) { 251 | return (String) titleTag.getValues(); 252 | } else { 253 | return saa.getComment(); 254 | } 255 | } 256 | 257 | /** 258 | * 获取接口的uri 259 | * 260 | * @return 261 | */ 262 | protected List getUris(String[] values) { 263 | List uris = new ArrayList<>(); 264 | for (String value : values) { 265 | uris.add(value); 266 | } 267 | return uris; 268 | } 269 | 270 | /** 271 | * 获取接口上允许的访问方式 272 | * 273 | * @return 274 | */ 275 | protected List getMethods(RequestMethod... methods) { 276 | List methodStrs = new ArrayList<>(); 277 | for (RequestMethod requestMethod : methods) { 278 | methodStrs.add(requestMethod.name()); 279 | } 280 | return methodStrs; 281 | } 282 | 283 | /** 284 | * 判断整个类里的所有接口是否都返回json 285 | * 286 | * @param classz 287 | * @return 288 | */ 289 | protected boolean isJson(Class classz) { 290 | Controller controllerAnno = classz.getAnnotation(Controller.class); 291 | RestController restControllerAnno = classz.getAnnotation(RestController.class); 292 | ResponseBody responseBody = classz.getAnnotation(ResponseBody.class); 293 | 294 | if (responseBody != null) { 295 | return true; 296 | } else if (controllerAnno != null) { 297 | return false; 298 | } else if (restControllerAnno != null) { 299 | return true; 300 | } 301 | return false; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /super-java-doc-spring/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36}:%L - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /super-java-doc-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | super-java-doc 7 | com.uifuture 8 | 1.0.0 9 | 10 | 1.0.1 11 | super-java-doc-starter 12 | 4.0.0 13 | super-java-doc,基于Java doc注释,自动构建文档,项目地址:https://github.com/chenhaoxiang/super-java-doc 14 | 15 | 16 | 17 | com.uifuture 18 | super-java-doc-spring 19 | 1.0.0 20 | 21 | 22 | com.uifuture 23 | super-java-doc-core 24 | 1.0.0 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/java/com/uifuture/superstarter/boot/DocConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superstarter.boot; 6 | 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.context.annotation.Bean; 9 | 10 | /** 11 | * @author chenhx 12 | * @version DocConfiguration.java, v 0.1 2018-09-26 下午 6:10 13 | */ 14 | public class DocConfiguration { 15 | 16 | public DocConfiguration() { 17 | } 18 | 19 | @Bean 20 | @ConditionalOnProperty(prefix = "doc", name = "enable", matchIfMissing = true) 21 | public DocController docController() { 22 | return new DocController(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/java/com/uifuture/superstarter/boot/DocController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superstarter.boot; 6 | 7 | import com.uifuture.supercore.SuperJavaDoc; 8 | import com.uifuture.supercore.model.ApiDoc; 9 | import com.uifuture.supercore.utils.JsonUtils; 10 | import com.uifuture.superspring.framework.SpringWebFramework; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.Logger; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.GetMapping; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.ResponseBody; 17 | 18 | import javax.annotation.PostConstruct; 19 | import java.util.Arrays; 20 | import java.util.HashMap; 21 | import java.util.List; 22 | 23 | import static org.slf4j.LoggerFactory.getLogger; 24 | 25 | /** 26 | * @author chenhx 27 | * @version docController.java, v 0.1 2018-09-26 下午 6:11 28 | */ 29 | @RequestMapping("superJavaDoc") 30 | public class DocController { 31 | private static final Logger LOGGER = getLogger(DocController.class); 32 | private static ApiDoc apiDoc; 33 | @Autowired 34 | private DocProperties docProperties; 35 | 36 | @PostConstruct 37 | public void init() { 38 | if (!docProperties.isEnable()) { 39 | return; 40 | } 41 | 42 | String path = docProperties.getSourcePath(); 43 | 44 | if (StringUtils.isBlank(path)) { 45 | //默认为当前目录 46 | path = "."; 47 | } 48 | 49 | List paths = Arrays.asList(path.split(",")); 50 | 51 | LOGGER.debug("starting SuperJavaDoc, source path:{}", paths); 52 | 53 | try { 54 | SuperJavaDoc superJavaDoc = new SuperJavaDoc(paths, new SpringWebFramework()); 55 | 56 | Thread thread = new Thread(() -> { 57 | try { 58 | apiDoc = superJavaDoc.resolve(); 59 | HashMap properties = new HashMap<>(4); 60 | properties.put("version", docProperties.getVersion()); 61 | properties.put("title", docProperties.getTitle()); 62 | apiDoc.setProperties(properties); 63 | 64 | LOGGER.info("start up SuperJavaDoc"); 65 | } catch (Exception e) { 66 | LOGGER.error("start up SuperJavaDoc error", e); 67 | } 68 | }); 69 | thread.start(); 70 | } catch (Exception e) { 71 | LOGGER.error("start up SuperJavaDoc error", e); 72 | } 73 | } 74 | 75 | /** 76 | * 跳转到SuperJavaDoc接口文档首页 77 | */ 78 | @GetMapping 79 | public String index() { 80 | return "redirect:index.html"; 81 | } 82 | 83 | /** 84 | * 获取所有文档api 85 | * 86 | * @return 系统所有文档接口的数据(json格式) 87 | */ 88 | @ResponseBody 89 | @RequestMapping("apis") 90 | public Object apis() { 91 | return JsonUtils.toJson(apiDoc); 92 | } 93 | 94 | /** 95 | * 重新构建文档 96 | * 97 | * @return 文档页面 98 | */ 99 | @GetMapping("rebuild") 100 | public String rebuild() { 101 | init(); 102 | return "redirect:index.html"; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/java/com/uifuture/superstarter/boot/DocProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superstarter.boot; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | 9 | /** 10 | * @author chenhx 11 | * @version DocProperties.java, v 0.1 2018-09-26 下午 6:11 12 | */ 13 | @ConfigurationProperties("doc") 14 | public class DocProperties { 15 | 16 | /** 17 | * 是否启动SuperJavaDoc,此值便于在生产等环境启动程序时增加参数进行控制 18 | */ 19 | private boolean enable = true; 20 | /** 21 | * 界面标题描述 22 | */ 23 | private String title = "SuperJavaDoc 接口文档"; 24 | /** 25 | * 源码相对路径(支持多个,用英文逗号隔开) 26 | */ 27 | private String sourcePath; 28 | /** 29 | * 文档版本号 30 | */ 31 | private String version; 32 | 33 | public DocProperties() { 34 | } 35 | 36 | /** 37 | * Getter method for property enable. 38 | * 39 | * @return property value of enable 40 | */ 41 | public boolean isEnable() { 42 | return enable; 43 | } 44 | 45 | /** 46 | * Setter method for property enable. 47 | * 48 | * @param enable value to be assigned to property enable 49 | */ 50 | public void setEnable(boolean enable) { 51 | this.enable = enable; 52 | } 53 | 54 | /** 55 | * Getter method for property title. 56 | * 57 | * @return property value of title 58 | */ 59 | public String getTitle() { 60 | return title; 61 | } 62 | 63 | /** 64 | * Setter method for property title. 65 | * 66 | * @param title value to be assigned to property title 67 | */ 68 | public void setTitle(String title) { 69 | this.title = title; 70 | } 71 | 72 | /** 73 | * Getter method for property sourcePath. 74 | * 75 | * @return property value of sourcePath 76 | */ 77 | public String getSourcePath() { 78 | return sourcePath; 79 | } 80 | 81 | /** 82 | * Setter method for property sourcePath. 83 | * 84 | * @param sourcePath value to be assigned to property sourcePath 85 | */ 86 | public void setSourcePath(String sourcePath) { 87 | this.sourcePath = sourcePath; 88 | } 89 | 90 | /** 91 | * Getter method for property version. 92 | * 93 | * @return property value of version 94 | */ 95 | public String getVersion() { 96 | return version; 97 | } 98 | 99 | /** 100 | * Setter method for property version. 101 | * 102 | * @param version value to be assigned to property version 103 | */ 104 | public void setVersion(String version) { 105 | this.version = version; 106 | } 107 | } -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/java/com/uifuture/superstarter/boot/EnableDoc.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.superstarter.boot; 6 | 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 8 | import org.springframework.context.annotation.Import; 9 | 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | /** 16 | * 开启注解 17 | * 18 | * @author chenhx 19 | * @version EnableDoc.java, v 0.1 2018-09-26 下午 6:10 20 | */ 21 | @Target({ElementType.TYPE}) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Import(DocConfiguration.class) 24 | @EnableConfigurationProperties(DocProperties.class) 25 | public @interface EnableDoc { 26 | } -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/resources/static/superJavaDoc/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenhaoxiang/super-java-doc/293c8ad32730a791fc607b56d37daa1a1e853ed5/super-java-doc-starter/src/main/resources/static/superJavaDoc/fonts/element-icons.woff -------------------------------------------------------------------------------- /super-java-doc-starter/src/main/resources/static/superJavaDoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 在线接口文档 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 |

{{title}}

18 | 19 | 20 | 21 | 22 | 重新生成文档 23 | 24 | 25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 | 34 |
35 |
36 |

{{currentApiAction.title}}

37 |

描述: {{currentApiAction.comment}}

38 |

仅支持: 39 | {{m}} 40 |

41 |

接口地址: {{(currentApiModule.uris[0] ? currentApiModule.uris[0] 42 | : '') + uri}}

43 |

接口返回: {{currentApiAction.returnDesc}}

44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 78 |
{{reverseRespbody}}
79 |
80 |
81 |
82 | 83 |
84 |

测试

85 |
86 |
87 | 88 | 89 | 90 | 91 | {{m}} 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 请求 101 | 重置 102 | 103 | 104 | 105 |

返回内容

106 |
107 |
108 | 110 |
111 |
112 |
113 |
114 | 115 | 184 | 417 | 418 | 419 | 525 | 526 | 527 | -------------------------------------------------------------------------------- /super-java-doc-test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | super-java-doc-test 7 | com.uifuture 8 | 1.0.0 9 | 10 | 11 | 1.8 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.0.4.RELEASE 17 | 18 | 4.0.0 19 | 20 | 21 | 22 | com.uifuture 23 | super-java-doc-starter 24 | 1.0.0 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | junit 34 | junit 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | maven-compiler-plugin 47 | 48 | ${java.version} 49 | ${java.version} 50 | UTF-8 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/TestApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test; 6 | 7 | import com.uifuture.superstarter.boot.EnableDoc; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | /** 12 | * 测试启动类 13 | * 14 | * @author chenhx 15 | * @version TestApplication.java, v 0.1 2018-09-26 下午 6:27 16 | */ 17 | @EnableDoc 18 | @SpringBootApplication 19 | public class TestApplication { 20 | public static void main(String[] args) { 21 | SpringApplication.run(TestApplication.class, args); 22 | } 23 | } -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.controller; 6 | 7 | import com.uifuture.test.vo.Account; 8 | import com.uifuture.test.vo.AccountEx; 9 | import org.apache.commons.io.IOUtils; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.http.HttpHeaders; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.web.bind.annotation.RequestHeader; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RequestMethod; 18 | import org.springframework.web.bind.annotation.ResponseBody; 19 | 20 | import javax.servlet.ServletOutputStream; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.io.File; 23 | import java.io.FileInputStream; 24 | import java.io.IOException; 25 | import java.util.Date; 26 | import java.util.UUID; 27 | import java.util.concurrent.Callable; 28 | 29 | /** 30 | * 用户账户模块 31 | * 32 | * @author chenhx 33 | * @version AccountController.java, v 0.1 2018-09-26 下午 6:24 34 | */ 35 | @Controller 36 | @RequestMapping("api/account") 37 | public class AccountController { 38 | 39 | private Logger log = LoggerFactory.getLogger(AccountController.class); 40 | 41 | /** 42 | * 获取当前登录用户的账户资产信息,用户不存在会返回code为9999的错误信息,见: 43 | * 44 | * @return 用户的资产 45 | * @title 查询用户资产 46 | * @see AccountEx 47 | */ 48 | @ResponseBody 49 | @RequestMapping(value = "info", method = RequestMethod.POST) 50 | Account info() { 51 | Account account = new Account(); 52 | account.setId(UUID.randomUUID().toString()); 53 | account.setBalance(100D); 54 | account.setScore(666666); 55 | return account; 56 | } 57 | 58 | /** 59 | * 文件/图片获取 60 | * 61 | * @param id 文件Id|必填 62 | * @param type 业务类型,1-用户头像,2-绘画完成的作品,3-心情,4-图案,5-关于我们logo|必填 63 | * @return 文件(如果文件不存在, http response status会返回404) 64 | * @throws IOException 65 | */ 66 | @RequestMapping("get") 67 | public Callable get(String id, String type, HttpServletResponse resp, @RequestHeader HttpHeaders httpHeaders) { 68 | 69 | if (id.contains("..") || StringUtils.isBlank(id)) { 70 | log.warn("文件ID非法:" + id); 71 | resp.setStatus(404); 72 | return null; 73 | } 74 | 75 | //实现304缓存 76 | String ifModifiedSince = httpHeaders.getFirst("If-Modified-Since"); 77 | if (StringUtils.isNotBlank(ifModifiedSince)) { 78 | resp.setStatus(304); 79 | return null; 80 | } 81 | 82 | resp.setHeader("Last-Modified", new Date().toString()); 83 | 84 | String path = "/"; 85 | File file = new File(path + "/" + type + "/" + id); 86 | if (!file.exists()) { 87 | resp.setStatus(404); 88 | return null; 89 | } 90 | 91 | Callable callback = () -> { 92 | ServletOutputStream out = null; 93 | FileInputStream in = null; 94 | try { 95 | out = resp.getOutputStream(); 96 | in = new FileInputStream(file); 97 | IOUtils.copy(in, out); 98 | } catch (IOException e) { 99 | log.info("输出文件错误:{}", id, e); 100 | } finally { 101 | IOUtils.closeQuietly(out); 102 | IOUtils.closeQuietly(in); 103 | } 104 | return ""; 105 | }; 106 | return callback; 107 | } 108 | } -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/controller/CommController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.controller; 6 | 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | /** 11 | * 通用接口 12 | * 13 | * @author chenhx 14 | * @version CommController.java, v 0.1 2018-09-26 下午 6:28 15 | */ 16 | @RestController 17 | public class CommController { 18 | /** 19 | * 首页 20 | * 21 | * @return 首页页面 22 | */ 23 | @RequestMapping("index") 24 | public String index() { 25 | return "index"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/controller/UserController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.controller; 6 | 7 | import com.uifuture.test.vo.User; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import org.springframework.web.multipart.MultipartFile; 15 | 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 用户模块 23 | * 24 | * @author chenhx 25 | * @version UserController.java, v 0.1 2018-09-26 下午 6:28 26 | */ 27 | @Controller 28 | @RequestMapping("/user") 29 | public class UserController { 30 | 31 | /** 32 | * 登录 33 | * 34 | * @param username 用户名|必填 35 | * @param password 密码 36 | * @return 当前登录用户的基本信息 37 | * @resp code 返回码(0000表示登录成功,其它表示失败)|string|必填 38 | * @resp msg 登录信息|string 39 | * @resp username 登录成功后返回的用户名|string 40 | */ 41 | @ResponseBody 42 | @PostMapping("/login") 43 | public Map login(String username, String password) { 44 | Map model = new HashMap<>(4); 45 | model.put("code", "0000"); 46 | model.put("msg", "登录成功"); 47 | model.put("username", username); 48 | return model; 49 | } 50 | 51 | 52 | /** 53 | * 用户注册 54 | * 55 | * @param user :username 用户名|必填 56 | * @param user :password 密码 57 | * @return 注册后生成的用户的基本信息 58 | * @respbody {"id":"123","password":"123456","username":"admin"} 59 | * @title 注册 60 | * @resp score 分数 61 | * @see User 62 | */ 63 | @ResponseBody 64 | @RequestMapping(value = "register", method = {RequestMethod.POST, RequestMethod.PUT}) 65 | User register(User user, @RequestParam(value = "abc", required = false) List list) { 66 | user.setId(UUID.randomUUID().toString()); 67 | return user; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/vo/Account.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.vo; 6 | 7 | /** 8 | * 用户账户 9 | * 10 | * @author chenhx 11 | * @version Account.java, v 0.1 2018-09-26 下午 6:24 12 | */ 13 | 14 | public class Account { 15 | 16 | /** 17 | * 账户ID,跟用户ID一致 18 | */ 19 | private String id; 20 | 21 | /** 22 | * 用户余额 23 | */ 24 | private Double balance; 25 | 26 | /** 27 | * 用户积分 28 | */ 29 | private Integer score; 30 | 31 | /** 32 | * Getter method for property id. 33 | * 34 | * @return property value of id 35 | */ 36 | public String getId() { 37 | return id; 38 | } 39 | 40 | /** 41 | * Setter method for property id. 42 | * 43 | * @param id value to be assigned to property id 44 | */ 45 | public void setId(String id) { 46 | this.id = id; 47 | } 48 | 49 | /** 50 | * Getter method for property balance. 51 | * 52 | * @return property value of balance 53 | */ 54 | public Double getBalance() { 55 | return balance; 56 | } 57 | 58 | /** 59 | * Setter method for property balance. 60 | * 61 | * @param balance value to be assigned to property balance 62 | */ 63 | public void setBalance(Double balance) { 64 | this.balance = balance; 65 | } 66 | 67 | /** 68 | * Getter method for property score. 69 | * 70 | * @return property value of score 71 | */ 72 | public Integer getScore() { 73 | return score; 74 | } 75 | 76 | /** 77 | * Setter method for property score. 78 | * 79 | * @param score value to be assigned to property score 80 | */ 81 | public void setScore(Integer score) { 82 | this.score = score; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | final StringBuilder sb = new StringBuilder("Account{"); 88 | sb.append(super.toString()); 89 | sb.append(","); 90 | sb.append("id='").append(id).append('\''); 91 | sb.append(", balance=").append(balance); 92 | sb.append(", score=").append(score); 93 | sb.append('}'); 94 | return sb.toString(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/vo/AccountEx.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.vo; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @author chenhx 11 | * @version AccountEx.java, v 0.1 2018-09-26 下午 6:25 12 | */ 13 | 14 | public class AccountEx extends Account { 15 | 16 | /** 17 | * 创建时间 18 | */ 19 | private Date createdtime; 20 | 21 | 22 | /** 23 | * 等级,数字越高级别越大 24 | */ 25 | private Integer level; 26 | 27 | /** 28 | * 重写父类的注释,新的含义是:已消费的积分 29 | */ 30 | private Integer score; 31 | 32 | /** 33 | * Getter method for property createdtime. 34 | * 35 | * @return property value of createdtime 36 | */ 37 | public Date getCreatedtime() { 38 | return createdtime; 39 | } 40 | 41 | /** 42 | * Setter method for property createdtime. 43 | * 44 | * @param createdtime value to be assigned to property createdtime 45 | */ 46 | public void setCreatedtime(Date createdtime) { 47 | this.createdtime = createdtime; 48 | } 49 | 50 | /** 51 | * Getter method for property level. 52 | * 53 | * @return property value of level 54 | */ 55 | public Integer getLevel() { 56 | return level; 57 | } 58 | 59 | /** 60 | * Setter method for property level. 61 | * 62 | * @param level value to be assigned to property level 63 | */ 64 | public void setLevel(Integer level) { 65 | this.level = level; 66 | } 67 | 68 | /** 69 | * Getter method for property score. 70 | * 71 | * @return property value of score 72 | */ 73 | @Override 74 | public Integer getScore() { 75 | return score; 76 | } 77 | 78 | /** 79 | * Setter method for property score. 80 | * 81 | * @param score value to be assigned to property score 82 | */ 83 | @Override 84 | public void setScore(Integer score) { 85 | this.score = score; 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | final StringBuilder sb = new StringBuilder("AccountEx{"); 91 | sb.append(super.toString()); 92 | sb.append(","); 93 | sb.append("createdtime=").append(createdtime); 94 | sb.append(", level=").append(level); 95 | sb.append(", score=").append(score); 96 | sb.append('}'); 97 | return sb.toString(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /super-java-doc-test/src/main/java/com/uifuture/test/vo/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test.vo; 6 | 7 | /** 8 | * @author chenhx 9 | * @version User.java, v 0.1 2018-09-26 下午 6:25 10 | */ 11 | public class User { 12 | 13 | /** 14 | * 用户ID 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 用户名 20 | */ 21 | private String username; 22 | 23 | /** 24 | * 密码 25 | */ 26 | private String password; 27 | 28 | /** 29 | * Getter method for property id. 30 | * 31 | * @return property value of id 32 | */ 33 | public String getId() { 34 | return id; 35 | } 36 | 37 | /** 38 | * Setter method for property id. 39 | * 40 | * @param id value to be assigned to property id 41 | */ 42 | public void setId(String id) { 43 | this.id = id; 44 | } 45 | 46 | /** 47 | * Getter method for property username. 48 | * 49 | * @return property value of username 50 | */ 51 | public String getUsername() { 52 | return username; 53 | } 54 | 55 | /** 56 | * Setter method for property username. 57 | * 58 | * @param username value to be assigned to property username 59 | */ 60 | public void setUsername(String username) { 61 | this.username = username; 62 | } 63 | 64 | /** 65 | * Getter method for property password. 66 | * 67 | * @return property value of password 68 | */ 69 | public String getPassword() { 70 | return password; 71 | } 72 | 73 | /** 74 | * Setter method for property password. 75 | * 76 | * @param password value to be assigned to property password 77 | */ 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | final StringBuilder sb = new StringBuilder("User{"); 85 | sb.append(super.toString()); 86 | sb.append(","); 87 | sb.append("id='").append(id).append('\''); 88 | sb.append(", username='").append(username).append('\''); 89 | sb.append(", password='").append(password).append('\''); 90 | sb.append('}'); 91 | return sb.toString(); 92 | } 93 | } -------------------------------------------------------------------------------- /super-java-doc-test/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | doc: 2 | enable: true 3 | title: 测试文档 4 | sourcePath: super-java-doc-test/src/main/java -------------------------------------------------------------------------------- /super-java-doc-test/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36}:%L - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /super-java-doc-test/src/test/java/com/uifuture/test/SuperJavaDocTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * uifuture.com 3 | * Copyright (C) 2013-2018 All Rights Reserved. 4 | */ 5 | package com.uifuture.test; 6 | 7 | import com.uifuture.supercore.SuperJavaDoc; 8 | import com.uifuture.superspring.format.HtmlForamt; 9 | import com.uifuture.superspring.format.MarkdownFormat; 10 | import com.uifuture.superspring.framework.SpringWebFramework; 11 | import org.junit.Test; 12 | 13 | import java.io.ByteArrayOutputStream; 14 | import java.io.File; 15 | import java.io.FileOutputStream; 16 | 17 | /** 18 | * @author chenhx 19 | * @version SuperJavaDocTest.java, v 0.1 2018-09-26 下午 6:41 20 | */ 21 | public class SuperJavaDocTest { 22 | 23 | @Test 24 | public void buildMarkdown() { 25 | //生成离线的Markdown格式的接口文档 26 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 27 | String rootDir = System.getProperty("user.dir"); 28 | SuperJavaDoc xDoc = new SuperJavaDoc(rootDir + "/src/main/java/com/uifuture", new SpringWebFramework()); 29 | xDoc.build(out, new MarkdownFormat()); 30 | 31 | System.out.println(out.toString()); 32 | } 33 | 34 | @Test 35 | public void buildHtml() throws Exception { 36 | //生成离线的HTML格式的接口文档 37 | String userDir = System.getProperty("user.dir"); 38 | FileOutputStream out = new FileOutputStream(new File(userDir, "api.html")); 39 | SuperJavaDoc xDoc = new SuperJavaDoc(userDir + "/src/main/java/com/uifuture", new SpringWebFramework()); 40 | xDoc.build(out, new HtmlForamt()); 41 | } 42 | 43 | } --------------------------------------------------------------------------------