Compare commits

..

3 Commits

Author SHA1 Message Date
oppofind e10cb893ae update pom 2020-12-06 15:45:02 +08:00
oppofind 5478f2fa59 release 1.9.9.2 2020-12-06 15:44:03 +08:00
oppofind 0b6349a347 release 1.9.9.2 2020-12-06 14:55:25 +08:00
189 changed files with 5046 additions and 13275 deletions

View File

@ -1,23 +1,19 @@
### 您的使用环境(必填,不填写官方直接关闭issue)
maven和gradle版本信息根据个人使用情况填写
- maven版本号xxx
- smart-doc-maven-plugin版本号xxx
- gradle版本号xxx
- smart-doc-gradle-plugin版本号xxx
### 当前使用版本(必须填写清楚,否则不予处理)
注意请自行从maven仓库或者是[github](https://github.com/smart-doc-group/smart-doc) tag确认你当前使用的是最新版的smart-doc或者相关插件
历史版本的问题官方将拒绝处理。
### 该问题是怎么引起的(如果最新版本已经修复的,会直接关闭)
编写关于整个issue描述前注意阅读下面的注意事项尤其是萌新的同学
1. 提issue时请认真阅读官方的wiki文档及相关配置说明少给开源软件提无效的issue是一个IT从业人的专业素养。
2. 提某些简单使用问题的issue时请先思考smart-doc从18年开源以来已经有很多企业使用码云的指数也很高。 很多问题都已解决,开源玩具是走不进企业的,这已经是一个偏向成熟的软件了。请仔细阅读文档找到相关解决方法。
3. 当你提出问题时尽量思考你的描述信息能否让官方人员复现。不要随便扔个报错信息出来就把开源人当神仙了。 smart-doc是一款很依赖你本地环境和代码数据的工具。官方人员并没有你的代码数据和模拟相同环境。
因此建议你先自己debug官方的wiki也有详细的介绍怎么去debug smart-doc或smart-doc的相关插件 文档把调试步骤都写了,不要说你不懂。
2. 提某些简单使用问题的issue时请先思考smart-doc从18年开源以来已经有很多企业使用码云的指数也很高。
很多问题都已解决,开源玩具是走不进企业的,这已经是一个偏向成熟的软件了。请仔细阅读文档找到相关解决方法。
3. 当你提出问题时尽量思考你的描述信息能否让官方人员复现。不要随便扔个报错信息出来就把开源人当神仙了。
smart-doc是一款很依赖你本地环境和代码数据的工具。官方人员并没有你的代码数据和模拟相同环境。
因此建议你先自己debug官方的wiki也有详细的介绍怎么去debug smart-doc或smart-doc的相关插件
文档把调试步骤都写了,不要说你不懂。
最后、祝你使用愉快!
### 重现步骤
### 重现步骤(必填,不填写官方直接关闭issue)
### 报错信息(必填,不填写官方直接关闭issue)
### 报错信息

View File

@ -5,12 +5,6 @@ title: ''
labels: bug
assignees: ''
---
## Your Environment(您的使用环境)
<!--- Include as many relevant details about the environment you experienced the bug in -->
* smart-doc version:
* plugin version (e.g. smart-doc-maven-plugin or smart-doc-gradle-plugin):
* build tool version(maven or gradle):
## Expected Behavior(您期望的结果)
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
@ -35,5 +29,9 @@ assignees: ''
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Your Environment(您的使用环境)
<!--- Include as many relevant details about the environment you experienced the bug in -->
* smart-doc version:
* plugin version (e.g. smart-doc-maven-plugin or smart-doc-gradle-plugin):
* build tool version(maven or gradle):

View File

@ -3,15 +3,9 @@ name: Feature Request 💡
about: Suggest a new idea for the project.
labels: enhancement
---
## Summary(关于这个pr的描述)
Brief explanation of the feature.
### Basic example(pr的用例)
If the proposal involves a new or changed API, include a basic code example. Omit this section if it's not applicable.
### Motivation(提出这个pr目的)
Why are we doing this? What use cases does it support? What is the expected outcome?

View File

@ -1,313 +1,11 @@
## smart-doc版本
#### 版本号2.3.2
- 更新日期: 2021-11-21
- 更新内容:
1. 修复debug调试页搜索后目录锚点错误。
2. 修复生成openapi时List<String>等基本类型数组入参时类型转换错误。
3. 优化泛型类型显示,当泛型类型的实参类型是基本类型时直接显示为基本类型。
4. 新增对@RequestAttribute参数的忽略。
5. 修复@RequstBody使用基本类型时的请求参数示例错误
#### 版本号2.3.1
- 更新日期: 2021-11-13
- 更新内容:
1. 修复debug调试不支持请求头设置中文值的bug。
2. 修复response自定义tag设置返回未格式化换行问题。
3. 修复枚举类型字段指定mock不生效的问题。
4. 新增对@SessionAttribute参数做忽略。
5. 支持controller实现接口并使用default方法。
#### 版本号2.3.0
- 更新日期: 2021-11-07
- 更新内容:
1. 修复创建html文档丢失search.js文件问题。
2. 修复packageFilters配置多个包时只有第一个生效的问题。
3. 修复debug调试页面的curl指令错误。
4. 修复设置了下载文件接口加download标记后数据并未生效的bug。
5. 优化一些部分常见字段的随机值生成。
#### 版本号2.2.9
- 更新日期: 2021-10-31
- 更新内容:
1. 修复生成openapi文件上传错误问题。
2. 修复文件上传接口推送到torna参数被放置到query参数列表的问题。
3. 修改List<T>类型参数推送到torna错误的问题
4. 优化outPath配置只使用torna推送时可以不再要求配置outPath项。
#### 版本号2.2.8
- 更新日期: 2021-10-07
- 更新内容:
1. 修复html文档无接口注释时锚点跳转错误的问题。
2. 修复导出postman时服务端口配置成变量报错的问题。
#### 版本号2.2.7
- 更新日期: 2021-09-12
- 更新内容:
1. 修复dubbo文档css连接错误。
2. 修复分组后组归错误。
3. 修复路径常量相似度时替换错误的bug。
4. JSR303分组优化标记Null的分组字段将不再显示在文档中 。
#### 版本号2.2.6
- 更新日期: 2021-09-05
- 更新内容:
1. 修复html文档静态资源链接错误。
2. 不配置分组时不显示分组。
3. 修复分组后目录item搜索错误。
4. 优化maven插件提示 。
#### 版本号2.2.5
- 更新日期: 2021-08-08
- 更新内容:
1. 支持在html文档中不显示参数列表。
2. html文档使用的资源全部改成本地引用。
3. 修复Boolean类型字段命名为is前缀时is前缀被去除的bug。
4. 修复配置了字典码列表后枚举字段注释显示错误#139 。
5. 修复分析过程中出现的数组越界异常 。
6. 新增接口分组支持。
#### 版本号2.2.4
- 更新日期: 2021-08-08
- 更新内容:
1. 修复字典码推送torna错误 #https://gitee.com/smart-doc-team/smart-doc/issues/I43JQR。
2. 新增jsr303 @size和@length支持
3. 修改html的模板样式错误。
4. 修复postman错误#I41G2E 。
5. 新增isReplace配置 。
6. 修复当存在多个jsr注解时部分注解失效问题。
#### 版本号2.2.3
- 更新日期: 2021-07-18
- 更新内容:
1. 增加pathPrefix配置项用于配置上下文引入该配置项后serverUrl仅用于配置服务器地址。
2. 支持请求头常量设置解析。
3. 支持使用JsonIgnoreProperties和JSONType注解去忽略多字段。
4. 修改部分文档设置allInOneDocFileName无效的问题,#131 。
5. 修复dubbo rpc文档模板格式错误 #https://gitee.com/smart-doc-team/smart-doc/issues/I40ZGE .
6. 支持配置添加拦截器中设置全局请求参数,#https://github.com/smart-doc-group/smart-doc/issues/132 .
7. 修复部分类型mock未推送到torna的问题。
#### 版本号2.2.2
- 更新日期: 2021-07-04
- 更新内容:
1. 修复url中遇到正则表达解析错误问题.
2. 修复生成的json样例部分格式化后错误的bug,gitee #I3XSE5
3. 增强对文档中html特殊字符的处理防止html渲染后显示错误gitee #I3XO31
4. 请求头设置增强支持配置urlPatterns和excludePathPatterns两个属性去匹配对应的接口。
5. 优化了maven插件的提示优化后可以将加载了那些目录模块代码路径打印。
6. 提供了其它框架扩展文档解析的能力。
7. 修复doc模板错误gitee #I3Y640
8. 修复字典模板错误,#119。
9. 添加忽略HttpServlet对象。
10. 支持内置替换Jpa Pageable分页对象去除不必要的请求参数替换配置。
11. packageFilters增强可使用正则进行匹配gitee #I3YKZ4
12. 修复dubbo rpc文档推送到torna数据错误。
13. 修复customResponseFields和customRequestFields设置时不同类同名字段覆盖buggitee #I3Y6AL
14. 修复高版本gradle中使用implements添加依赖时gradle插件无法加载依赖导致返回空json的bug。
#### 版本号2.2.1
- 更新日期: 2021-06-20
- 更新内容:
1. 移除代码中System.out.print打印.
#### 版本号2.2.0
- 更新日期: 2021-06-20
- 更新内容:
1. 修复参数多行注释时注释提取错误gitee #I3TYYP.
2. 修复部分代码可能出现的空指针问题。
3. 添加@response tag。支持自己设置response example
4. 修复推送到torna请求或返回为数组时示例显示错误
5. Character类型解析支持。
6. 修复使用Quartz中JobDataMap类型解析错误。
7. 移除YapiBuilder。smart-doc不在支持其他第三方接口系统请使用torna.
#### 版本号2.1.9
- 更新日期: 2021-05-29
- 更新内容:
1. 修复inlineEnum为false时枚举展示在参数中的问题。
2. 返回Spring文件下载对象支持自动识别为文件下载减少手动标记@download tag。
3. smart-doc使用的css cdn更换默认使用国内cdn提升国内的加载速度切换英文环境使用google的cdn.
4. 添加多层泛型嵌套的解析支持。gitee #I3T6UV .
5. 修复父类是泛型时父类中LocalDateTime类型字段生成json样例错误。
6. 添加将接口排序order推送到torna中。
7. 修复类上的@ignore tag不生效bug.
8. 优化字典码推送空字典码不会像torna发起推送请求。
#### 版本号2.1.8
- 更新日期: 2021-05-22
- 更新内容:
1. 修复推送接口到torna丢失部分mock值的问题。
2. 修复在参数注释中配置类替换时将非类名解析成类名的bug 。
3. 支持父类上加@RestController注解的子类能够被识别和扫描
4. 新增将业务错误码和定义字典推送到torna。
5. 修复maven插件torna-rest和torna-rpc两个task未加编译前缀的问题。
6. 修复生成json用例中数组类型json错误的问题。
7. 修复customRequestFields中设置字段value在用例中不生效的bug。
8. 添加@JsonProperty支持,支持JsonProperty.Access控制字段。
#### 版本号2.1.7
- 更新日期: 2021-05-12
- 更新内容:
1. 添加推送接口作者信息到torna数据错误的bug。
2. 修复空参数curl命令多余号问题github 。
#### 版本号2.1.6
- 更新日期: 2021-05-10
- 更新内容:
1. 修复不允许List中放文件上传对象错误的bug。
2. 添加推送接口作者信息到torna,通过配置author设置推送人不配置默认为计算机用户名。
3. 添加推送queryParams参数到torna(需要使用torna 1.6.0+)
#### 版本号2.1.5
- 更新日期: 2021-05-05
- 更新内容:
1. 修复requestBodyAdvice请求样例丢之。
2. 添加dubbo文档到torna的推送。
#### 版本号2.1.4
- 更新日期: 2021-04-24
- 更新内容:
1. 修复Controller继承时父类的Mapping未继承的问题。
2. 修复配置responseBodyAdvice后controller中void方法返回显示错误。
3. 修复往torna推送漏掉pathParams的问题。
4. 修复非json请求集合中绑定枚举强制检查错误的问题。
5. 新增requestBodyAdvice支持可以实现请求参数包装。
6. 修复泛型为List数据时类型为object问题。
7. 修复customFiled为继承参数时配置失效问题。
#### 版本号2.1.3
- 更新日期: 2021-04-11
- 更新内容:
1. 增强对文件上传的支持。
2. 增加customRequestFields配置项#97。
3. 修复往torna推送漏掉pathParams的问题。
4. 修改debug测试页面支持post表单请求
5. 修改表单请求对象中枚举字段默认值错误的bug
#### 版本号2.1.2
- 更新日期: 2021-03-29
- 更新内容:
1. 修复Map嵌套在某些结构体中栈溢出问题gitee #I3CCLY
2. 修复Torna数据推送问题。
#### 版本号2.1.1
- 更新日期: 2021-03-24
- 更新内容:
1. 修复Map嵌套在某些结构体中栈溢出问题gitee #I3CCLY
2. 修复Torna数据推送问题。
#### 版本号2.1.0
- 更新日期: 2021-03-21
- 更新内容:
1. 导出的postman的url资源下添加缺失的protocol。
2. 增加@ignoreParams自定义tag来过滤掉不想显示在文档中参数。
3. 增加了自动生成版本记录的功能。
4. 修改torna推送的bug。
5. 支持旧的SpringMVC项目的url后缀新项目不建议加什么破玩意后缀。
#### 版本号2.0.9
- 更新日期: 2021-03-12
- 更新内容:
1. 支持UUID和ZonedDateTime字段类型#89。
2. 对map参数增加开关来兼容旧项目还是不建议使用map参数。
3. 完成和Torna的对接。
#### 版本号2.0.8
- 更新日期: 2021-02-26
- 更新内容:
1. 修复文件上传的参数丢失的注释。
2. 修复2.0.7新增忽略接口方法后解析父类字段缺失注释bug。
3. 修改byte类型的转换将过去的string转为int8。
#### 版本号2.0.7
- 更新日期: 2021-01-30
- 更新内容:
1. 修复postman的url中不附加的context-path的问题。
2. 修复带正则的path路径参数解析出现截取越界的问题。
3. 添加对默认接口实现中get方法重写忽略的能力解析。
4. 修改数组、map等字段类型的自定义mock值显示错误问题。
5. 修复对mapping中headers的处理。
#### 版本号2.0.6
- 更新日期: 2021-01-15
- 更新内容:
1. 修复带正则的path路径参数在postman中用例问题。
2. 增强对祖传不良代码的分析兼容。
#### 版本号2.0.5
- 更新日期: 2021-01-09
- 更新内容:
1. 修复集合类无泛型参数作为入参出参时的数组越界。
2. 修复新开tab访问的url拼接问题。
#### 版本号2.0.3-2.0.4
- 更新日期: 2021-01-01
- 更新内容:
1. 修改页面的错误列表标题显示。
2. 修改debug页面curl header语法错误。
3. 修改debug页面json参数输入框允许粘贴小段文本。
4. 解决使用dubbo 2.7+在provider中生成文档出错问题 github #77.
#### 版本号2.0.2
- 更新日期: 2020-12-27
- 更新内容:
1. 修改创建openapi时的空指针异常。
2. 修改debug页面时未使用mock值的问题。
3. debug页面可以根据请求动态更新curl命令。
4. 优化debug页面中的文件下载测试。
5. 优化enum入参mock错误的bug。
6. mock页面支持使用新窗口打开后端渲染的页面。
7. 修改生成一些字段值生成错误的bug。
8. 修改类中使用集合字段未指定泛型可能出错的bug。
9. 优化set等集合类在文档中的类型显示。
10. 添加对集合字段中枚举的处理。
11. 枚举序列化支持优化。
12. 调试页面新增Highlight支持。
#### 版本号2.0.1
- 更新日期: 2020-12-20
- 更新内容:
1. debug调试页面支持文件上传。
2. 修改简单请求参数mock值和类型不匹配问题。
3. debug页面完全支持文件下载测试。
4. 所有html的文档支持接口目录搜索。
5. 剔除flexmark依赖旧的非allInOne模板删除统一h5文档样式。
#### 版本号2.0.0
- 更新日期: 2020-12-13
- 更新内容:
1. 优化了文档的显示将query和path单独提出来做了展示
2. 优化openapi 3.0文档规范的支持可集成swagger ui等ui使用。
3. 优化postman collection 2.0的支持。
4. 添加分组支持group。
5. 修改mock的一些bug和增强使用
6. 支出创建debug页面
版本小于1.0都属于试用正式1.0起始发布将会等到文中提到的问题解决后才发布。
#### 版本号1.9.9.1
- 更新日期: 2020-11-23
- 更新内容:
1. 这是一个紧急修改版本。
2. 解决1.9.9版本controller中存在非路径映射方法时的错误。
#### 版本号1.9.9
- 更新日期: 2020-11-23
- 更新内容:
1. 修改1.9.8启用严格检查注释模式下的bug。
@ -317,9 +15,7 @@
5. 增加对@RequestMapping注解的path属性的解析支持
6. 修复postman中formdata表单不显示描述信息的问题
7. html5 allInOne模板支持代码高亮。
#### 版本号1.9.8
- 更新日期: 2020-11-10
- 更新内容:
1. 忽略Class对象的解析。
@ -328,9 +24,7 @@
4. 修改模拟值生成错误。
5. 支持ResponseBodyAdvice通用接口响应包装设置。
6. 修复类同时继承和基类和实现接口中可能出现字段重复的bug。
#### 版本号1.9.7
- 更新日期: 2020-10-24
- 更新内容:
1. 修复restful接口泛型中使用?时的解析错误。
@ -338,9 +32,7 @@
3. 对rest query参数自动添加描述增加可读性。
4. support ali dubbo,#I22CF7 .
5. support @RequestMapping headers.
#### 版本号1.9.6
- 更新日期: 2020-10-09
- 更新内容:
1. 修复RequestParam 解析错误。
@ -349,25 +41,19 @@
4. 增加泛型实际类型的显示开关控制。
5. 修复类继承一个泛型类时的解析错误。
6. 优化smart-doc maven插件提升用户在多模块下的使用体验。
#### 版本号1.9.5
- 更新日期: 2020-09-19
- 更新内容:
1. 接口参数无注解时将required设置为false。
2. 修改html自适应。
#### 版本号1.9.4
- 更新日期: 2020-09-06
- 更新内容:
1. 添加order tag支持对api做排序。
2. 优化一些重复的代码。
3. 修改基础url中使用常量出现空格的问题。
4. 添加生成yapi文件的功能。
#### 版本号1.9.3
- 更新日期: 2020-08-30
- 更新内容:
1. 修复Get请求用例参数值被去空格问题。
@ -375,9 +61,7 @@
3. 修复非allInOne模板使用渲染错误。
4. 修复一些泛型例子解析错误bug。
5. 优化MultipartFile文件上传参数处理不对该参数进行展开分析。
#### 版本号1.9.2
- 更新日期: 2020-08-23
- 更新内容:
1. 修改前面版本修改引发的普通jsr 303验证解析错误问题。
@ -387,18 +71,14 @@
5. 新增对Open Api 3.0的支持。
6. 修改字典表空时内部发生空指针的问题。
7. 优化curl用例增加请求头。
#### 版本号1.9.1
- 更新日期: 2020-08-02
- 更新内容:
1. 修改进去版本更新导致的泛型解析问题。
2. 修改1.8.9版本修改后带来的dubbo接口文档显示问题
2. 修改smart-doc-maven-plugin生成dubbo文档时缺乏配置文件错误问题。
3. 修改gradle插件的对多模块的支持。
#### 版本号1.9.0
- 更新日期: 2020-07-19
- 更新内容:
1. 修改dubbo html依赖部分错乱问题。
@ -406,18 +86,14 @@
3. 添加请求和响应示例的开关配置项。
4. 修改使用JSR303参数校验时默认分组验证被忽略问题。
5. 修改jackson JsonIgnore注解在参数对象中不生效的问题。
#### 版本号1.8.9
- 更新日期: 2020-07-05
- 更新内容:
1. 修改git #38
2. 修改gitee #I1LBKO
3. 修改fix #39多泛型解析顺序问题
4. 优化支持gitee #I1IQKY常量解析需求
#### 版本号1.8.8
- 更新日期: 2020-06-21
- 更新内容:
1. 修改忽略对LinkedHashMap的解析gitee #I1JI5W
@ -426,9 +102,7 @@
4. 优化枚举参数展示,支持自定义控制显示。
5. 添加Feign的支持。
6. 优化递归执行,对外提供递归次数限制。
#### 版本号1.8.7
- 更新日期: 2020-06-01
- 更新内容:
1. 增加对java接口的分析例如Jpa的分页Page类。
@ -438,20 +112,15 @@
5. maven插件和gradle插件提供includes支持方便自行配置加载第三方库。
6. fix #32.
7. 增加文档接口根据接口标题排序功能。
#### 版本号1.8.6
- 更新日期: 2020-05-09
- 更新内容:
1. 增加localTime支持[gitee #I1F7CW](https://gitee.com/sunyurepository/smart-doc/issues/I1F7CW)。
2. 优化smart-doc导入Postman
collection时的header问题[gitee #I1EX42](https://gitee.com/sunyurepository/smart-doc/issues/I1EX42)
2. 优化smart-doc导入Postman collection时的header问题[gitee #I1EX42](https://gitee.com/sunyurepository/smart-doc/issues/I1EX42)
3. 优化smart-doc-maven-plugin加载source的过滤支持使用通配符来过滤。
4. 首次发布gradle插件发布smart-doc-gradle-plugin插件
5. 修复通用泛型解析出错[git #28](https://github.com/smart-doc-group/smart-doc/issues/28)。
#### 版本号1.8.5
- 更新日期: 2020-04-19
- 更新内容:
1. maven插件错误码列表导出bug[git #I1EHXA](https://gitee.com/sunyurepository/smart-doc/issues/I1EHXA)。
@ -461,36 +130,27 @@
5. 修复分组验证空指针问题,不对返回对象做分组验证处理。
6. 优化smart-doc-maven-plugin对多级maven项目的加载。
7. 支持请求参数对象替换成另外的对象来渲染文档
#### 版本号1.8.4
- 更新日期: 2020-03-30
- 更新内容:
1. Controller新增时候@ignore
tag,可适应该tag忽略不需要生成文档的controller[git #24](https://github.com/smart-doc-group/smart-doc/issues/24)。
1. Controller新增时候@ignore tag,可适应该tag忽略不需要生成文档的controller[git #24](https://github.com/smart-doc-group/smart-doc/issues/24)。
2. 参数中包含 HttpSession时smart-doc卡主[gitee #I1CA9M](https://gitee.com/sunyurepository/smart-doc/issues/I1CA9M)
3. 解决一些复杂分组场景smart-doc报错的问题[gitee #I1CPSM](https://gitee.com/sunyurepository/smart-doc/issues/I1CPSM)。
4. 解决smart-doc-maven-plugin插件读取配置乱码问题。
#### 版本号1.8.3
- 更新日期: 2020-03-21
- 更新内容:
1. 增加从接口方法getter或者setter方法中读取注释。
2. 修改smart-doc默认编码为utf-8解决生成文档乱码问题。
3. 增加对代码中@author tag的支持支持多作者。
#### 版本号1.8.2
- 更新日期: 2020-03-13
- 更新内容:
1. 修改gitee #I19IYW
2. 修改文档模板中的title设置错误。
3. 修改gitee #I191EO
4. 支持@Validated 分组
#### 版本号1.8.1
- 更新日期: 2020-01-22
- 更新内容:
1. 增加对接口get方法的分析。
@ -500,9 +160,7 @@
5. 修改1.8.0重构后的请求示例将header放入普通参数的bug。
6. 修改参数加上@Validated注解后文档里没有该参数信息的bug。
7. 新增@Deprecated标注接口的支持(使用line through完成样式标记)
#### 版本号1.8.0
- 更新日期: 2020-01-01
- 更新内容:
1. 修改参数上多个验证注解不支持的问题。
@ -515,9 +173,7 @@
8. postman json生成支持所有参数自动回填。再也不用自己建参数了。
9. 优化对实体类中枚举字段的支持。
10. 增加对实体中静态常量常量字段的过滤。
#### 版本号1.7.9
- 更新日期: 2019-12-16
- 更新内容:
1. 修改request请求参数中嵌套对象不能解析的bug参考gitee #I16AN2.
@ -526,9 +182,7 @@
4. 修改github #9 文档错误bug.
5. 新增接口的@author展示方法从文档中查到找到接口负责人生成文档可以选择关闭显示。
6. 重点smart-doc的maven插件smart-doc-maven-plugin 1.0.0版本发布。
#### 版本号1.7.8
- 更新日期: 2019-12-02
- 更新内容:
1. 修改Spring Controller使用非Spring Web注解时生成的响应示例出错的bug。
@ -538,26 +192,20 @@
5. 修改github #4 泛型中Void类型解析死循环
6. 修改github #5 简单枚举参数解析空指针异常
7. 添加导出PostMan json数据
#### 版本号1.7.7
- 更新日期2019-11-18
- 更新内容:
1. 修改timestamp类型字段创建json示例错误bug。
2. fix #I1545A 单接口多路径bug。
3. 修改部分url生成部署空格问题。
4. 优化对java.util.concurrent.ConcurrentMap的解析。
#### 版本号1.7.6
- 更新日期2019-11-13
- 更新内容:
1. fix #I14PT5 header重复渲染到文档
2. fix #I14MV7 不设置dataDictionaries出现空指针错误
3. 增加请求参数枚举字段解析(试用功能)
#### 版本号1.7.5
- 更新日期2019-11-06
- 更新内容:
1. 优化文档中错误列表的标题,可根据语言环境变化显示中文或因为。
@ -568,9 +216,7 @@
6. 修改方法注释相同引起的html链接跳转错误。
7. 添加生成AllInOne的覆盖配置项默认自动加版本号不覆盖。
8. 新增枚举字典码导出到文档的功能。
#### 版本号1.7.4
- 更新日期2019-10-29
- 更新内容:
1. 修改gitee上bug #I1426C
@ -578,18 +224,14 @@
3. 修改gitee上bug #I13U4C
4. 修改设置中文语言环境(默认中文)下错误码列表title显示英文的问题。
5. 优化AllInOne的markdown展示生成时带上自动产生的序号。
#### 版本号1.7.3
- 更新日期2019-10-24
- 更新内容:
1. 优化html5模板左侧文档目录展示能够展开和收缩。
2. 修改gitee上bug #I13R3K
3. 修改gitee上bug #I13NR1
4. 开放的文档数据获取接口添加返回方法的唯一id和方法名称方便一些企业自己做对接。
#### 版本号1.7.2
- 更新日期2019-10-19
- 更新内容:
1. 优化注释换行\n\r问题依赖common-util 1.8.7。
@ -602,17 +244,13 @@
8. 新增对Spring ResponseEntity的解析。
9. 增加内部类返回结构解析。
10. 修改文档中显示的字段类型float、double等由原来的number直接变成具体类型。
#### 版本号1.7.1
- 更新日期:已废弃
- 更新内容:
1. 优化注释换行\n\r问题。
2. 修改bug #I135PG
3. 添加requestHeader功能
#### 版本号1.7.0
- 更新日期2019-09-30
- 更新内容:
1. 优化代码。
@ -620,78 +258,59 @@
3. 增加开放API数据接口功能。
4. 支持Callable,Future,CompletableFuture等异步接口返回的推导。
5. 支持Spring Boot Web Flux(Controller方式书写)。
#### 版本号1.6.4
- 更新日期2019-09-23
- 更新内容:
1. 优化代码
2. 增加对普通的get请求参数拼装示例的生成
3. 增加spring mvc占位符restful url请求示例生成
#### 版本号1.6.2
- 更新日期2019-09-13
- 更新内容:
1. 修改字段注释多行显示错误bug
2. 字段描述文档增加@Since tag的支持
3. 解析代码忽略WebRequest类防止生产过多信息
4. 升级基础库依赖版本
#### 版本号1.3
- 更新日期2018-09-15
- 更新内容:
1. 增加PutMapping和DeleteMapping支持
2. 添加字符串date和Date类型时间的模拟值生成
#### 版本号1.2
- 更新日期2018-09-04
- 更新内容:
1. 根据用户反馈增加controller报名过滤功能该功能为可选项
#### 版本号1.1
- 更新日期2018-08-30
- 更新内容:
1. 修改PostMapping和GetMapping value为空报错的bug
2. 增强时间字段的mock数据创建
3. 修改smart-doc解析自引用对象出错的bug
#### 版本号1.0
- 更新日期2018-08-25
- 更新内容:
1. smart-doc增加将所有文档导出归档到一个markdown中件的功能
2. 参考阿里开发手册将直接提升到1.0,之前的版本主要是个人内部测试
#### 版本号0.5
- 更新日期2018-08-23
- 更新内容:
1. 将api-doc重命名为smart-doc并发布到中央仓库
#### 版本号0.4
- 更新日期2018-07-11
- 更新内容:
1. 修改api-doc对类继承属性的支持。
#### 版本号0.3
- 更新日期2018-07-10
- 更新内容:
1. api-doc增加对jackson和fastjson注解的支持可根据注解定义来生成返回信息。
### 版本号0.2
- 更新日期2018-07-07
- 更新内容:
1. 修改api-doc泛型推导的bug.
### 版本号0.1
- 更新日期2018-06-25
- 更新内容:
1. 手册将api-doc发布到中央仓库

260
README.md
View File

@ -5,18 +5,13 @@
![number of issues closed](https://img.shields.io/github/issues-closed-raw/shalousun/smart-doc)
![closed pull requests](https://img.shields.io/github/issues-pr-closed/shalousun/smart-doc)
![java version](https://img.shields.io/badge/JAVA-1.8+-green.svg)
[![chinese](https://img.shields.io/badge/chinese-中文文档-brightgreen)](https://smart-doc-group.github.io/#/zh-cn/)
[![chinese](https://img.shields.io/badge/chinese-中文文档-brightgreen)](https://github.com/shalousun/smart-doc/blob/master/README_CN.md)
## Introduce
smart-doc is a tool that supports both JAVA REST API and Apache Dubbo RPC interface document generation. Smart-doc is
based on interface source code analysis to generate interface documents, and zero annotation intrusion. You only need to
write Javadoc comments when developing, smart-doc can help you generate Markdown or HTML5 document. smart-doc does not
need to inject annotations into the code like Swagger.
[quick start](https://smart-doc-group.github.io/#/)
smart-doc is a tool that supports both JAVA REST API and Apache Dubbo RPC interface document generation. Smart-doc is based on interface source code analysis to generate interface documents, and zero annotation intrusion.
You only need to write Javadoc comments when developing, smart-doc can help you generate Markdown or HTML5 document.
smart-doc does not need to inject annotations into the code like Swagger.
## Features
- Zero annotation, zero learning cost, only need to write standard JAVA document comments.
- Automatic derivation based on source code interface definition, powerful return structure derivation support.
- Support Spring MVC, Spring Boot, Spring Boot Web Flux (Not support endpoint), Feign.
@ -24,59 +19,242 @@ need to inject annotations into the code like Swagger.
- Support JSR-303 parameter verification specification.
- Support for automatic generation of request examples based on request parameters.
- Support for generating JSON return value examples.
- Support for loading source code from outside the project to generate field comments (including the sources jar
package).
- Support for generating multiple formats of documents: Markdown,HTML5,Asciidoctor,Postman Collection 2.0+,OpenAPI 3.0.
- Support for loading source code from outside the project to generate field comments (including the sources jar package).
- Support for generating multiple formats of documents: Markdown,HTML5,Asciidoctor,Postman Collection,OpenAPI 3.0.
- Support for exporting error codes and data dictionary codes to API documentation.
- The debug html5 page fully supports file upload and download testing.
- Support Apache Dubbo RPC.
## Getting Started
[Smart-doc Samples](https://github.com/shalousun/smart-doc-demo.git)。
```
# git clone https://github.com/shalousun/smart-doc-demo.git
```
This example already provides a static html document generated in advance. You can start the Spring Boot project and then go directly to `http://localhost:8080/doc/api.html` to view the interface documentation generated by smart-doc.
Of course, you can also browse `http://localhost:8080/doc/api.html`,
which looks a html like generated by `asciidoctor-maven-plugin` plugin.
### Add Maven Plugin
Add [smart-doc-maven-plugin](https://github.com/smart-doc-group/smart-doc-maven-plugin) in your pom.xml.
```
<plugin>
<groupId>com.github.shalousun</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>[latest]</version>
<configuration>
<!--Specify the configuration file used to generate the document-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<!--smart-doc implements automatic analysis of the dependency tree to load the source code of third-party dependencies. If some framework dependency libraries are not loaded, an error is reported, then use excludes to exclude-->
<excludes>
<!--The format is: groupId: artifactId; refer to the following-->
<exclude>com.google.guava:guava</exclude>
</excludes>
<!--Since version 1.0.8, the plugin provides includes support-->
<!--smart-doc can automatically analyze the dependency tree to load all dependent source code. In principle, it will affect the efficiency of document construction, so you can use includes to let the plugin load the components you configure.-->
<includes>
<!--The format is: groupId: artifactId; refer to the following-->
<include>com.alibaba:fastjson</include>
</includes>
</configuration>
<executions>
<execution>
<!--Comment out phase if you don't need to start smart-doc when compiling-->
<phase>compile</phase>
<goals>
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
```
### Configuration
Create a JSON configuration file in your project. The smart-doc-maven-plugin plugin will use this configuration information.
For example, create `/src/main/resources/smart-doc.json` in the project.
The configuration contents are as follows.
## Best Practice
**Minimize configuration:**
```
{
"allInOne": true, // whether to merge documents into one file, generally recommended as true
"isStrict": false,//If the strict mode is set to true, Smart-doc forces that the public method in each interface in the code has a comment.
"outPath": "/src/main/resources" //Set the api document output path.
}
```
Only the above three simple configuration items can make smart-doc-maven-plugin work.
In fact, only the outPath configuration item is necessary.
smart-doc + [Torna](http://torna.cn) form an industry-leading document generation and management solution, using
smart-doc to complete Java source code analysis and extract annotations to generate API documents without intrusion, and
automatically push the documents to the Torna enterprise-level interface document management platform.
**Detailed configuration content:**
![smart-doc+torna](https://raw.githubusercontent.com/shalousun/smart-doc/master/images/smart-doc-torna-en.png)
When you need to use smart-doc to generate more API document information, you can add detailed configuration content.
```
{
  "serverUrl": "http://127.0.0.1", // Set the server address, not required
  "isStrict": false, // whether to enable strict mode
  "allInOne": true, // whether to merge documents into one file, generally recommended as true
  "outPath": "D: // md2", // Specify the output path of the document
  "coverOld": true, // Whether to overwrite old files, mainly used for mardown file overwrite
  "packageFilters": "", // controller package filtering, multiple package names separated by commas
  "md5EncryptedHtmlName": false, // only used if each controller generates an html file
  "projectName": "smart-doc", // Configure your own project name
  "skipTransientField": true, // Not currently implemented
"style":"xt256", //set highlight
"sortByTitle":false,//Sort by interface title, the default value is false
"requestFieldToUnderline":true, //convert request field to underline
"inlineEnum":true,// Set to true to display enumeration details in the parameter table
"recursionLimit":7,// Set the number of recursive executions to avoid stack overflow, the default is 7
"responseFieldToUnderline":true,//convert response field to underline
"allInOneDocFileName":"index.html",//Customize the output document name
"displayActualType":false,//display actual type of generic,
"requestExample":"true",//Whether to display the request example in the document, the default value is true.
"responseExample":"true",//Whether to display the response example in the document, the default is true.
"ignoreRequestParams":[ //The request parameter object will be discarded when generating the document.@since 1.9.2
"org.springframework.ui.ModelMap"
],
  "dataDictionaries": [// Configure the data dictionary, no need to set
    {
      "title": "Order Status", // The name of the data dictionary
      "enumClassName": "com.power.doc.enums.OrderEnum", // Data dictionary enumeration class name
      "codeField": "code", // The field name corresponding to the data dictionary dictionary code
      "descField": "desc" // Data dictionary object description information dictionary
    }
  ],
  "errorCodeDictionaries": [{// error code list, no need to set
    "title": "title",
    "enumClassName": "com.power.doc.enums.ErrorCodeEnum", // Error code enumeration class
    "codeField": "code", // Code field name of the error code
    "descField": "desc" // Field name corresponding to the error code description
  }],
  "revisionLogs": [// Set document change records, no need to set
    {
      "version": "1.0", // Document version number
      "status": "update", // Change operation status, generally: create, update, etc.
      "author": "author", // Document change author
      "remarks": "desc" // Change description
    }
  ],
  "customResponseFields": [// Customly add fields and comments. If api-doc encounters a field with the same name later, directly add a comment to the corresponding field. It is not necessary.
    {
      "name": "code", // Override the response code field
      "desc": "Response code", // Override field comment of response code
      "ownerClassName": "org.springframework.data.domain.Pageable", // class
      "value": "00000" // Set the value of the response code
    }
  ],
"rpcApiDependencies":[{ //Your dubbo api denpendency
"artifactId":"SpringBoot2-Dubbo-Api",
"groupId":"com.demo",
"version":"1.0.0"
}],
"rpcConsumerConfig": "src/main/resources/consumer-example.conf",//dubbo consumer config example
"apiObjectReplacements": [{ // Supports replacing specified objects with custom objects to complete document rendering
"className": "org.springframework.data.domain.Pageable",
"replacementClassName": "com.power.doc.model.PageRequestDto" //Use custom PageRequestDto instead of JPA Pageable for document rendering.
}],
"apiConstants": [{//Configure your own constant class, smart-doc automatically replaces with a specific value when parsing to a constant
"constantsClassName": "com.power.doc.constants.RequestParamConstant"
}],
"responseBodyAdvice":{ //Support ResponseBodyAdvice
"className":"com.power.common.model.CommonResult" // Standard POJO for Response
},
  "requestHeaders": [// Set global request headers, no need to set
    {
      "name": "token",//header name
      "type": "string",//header type
      "desc": "description of this header.",
      "required": false,
"value":"your header value",
      "since": "-"
    }
  ]
}
```
**Note:** This JSON configuration can be converted into JSON using smart-doc's ApiConfig Object.
So the project configuration can also refer to the introduction of smart-doc.
### Generated document
#### Run Plugin with MAVEN command
```
// Generate html
mvn -Dfile.encoding=UTF-8 smart-doc: html
// Generate markdown
mvn -Dfile.encoding=UTF-8 smart-doc: markdown
// Generate adoc
mvn -Dfile.encoding=UTF-8 smart-doc: adoc
// Generate postman collection
mvn -Dfile.encoding=UTF-8 smart-doc: postman
// Apache Dubbo RPC
// Generate html
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-html
// Generate markdown
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-markdown
// Generate adoc
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-adoc
```
**Note:** Under the window system, if you use the maven command line to perform document generation,
non-English characters may be garbled, so you need to specify `-Dfile.encoding = UTF-8` during execution.
View maven's coding
```
# mvn -version
Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00)
Maven home: D:\ProgramFiles\maven\bin\..
Java version: 1.8.0_191, vendor: Oracle Corporation
Java home: D:\ProgramFiles\Java\jdk1.8.0_191\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
```
#### Run Plugin in IDEA
On Use IntelliJ IDE, if you have added smart-doc-maven-plugin to the project,
you can directly find the plugin smart-doc plugin and click to generate API documentation.
![smart-doc-maven-plugin](https://raw.githubusercontent.com/shalousun/smart-doc-maven-plugin/master/images/idea.png)
### Use Gradle Plugin
If you use gradle to build the project, you can refer to the documentation of the gradle plugin to integrate,
[smart-doc-gradle-plugin](https://github.com/smart-doc-group/smart-doc-gradle-plugin/blob/master/README.md)
### Generated document example
#### Interface header rendering
![header](https://images.gitee.com/uploads/images/2019/1231/223538_be45f8a9_144669.png "header.png")
#### Request parameter example rendering
![request-params](https://images.gitee.com/uploads/images/2019/1231/223710_88933f55_144669.png "request.png")
#### Response parameter example renderings
![response-fields](https://images.gitee.com/uploads/images/2019/1231/223817_32bea6dc_144669.png "response.png")
## Integration through unit tests
You can generate documentation by adding smart-doc dependencies directly to your project and then writing unit tests to start smart-doc.
we still recommend that you use the smart-doc-maven-plugin plugin.
[Use smart-doc by junit test](https://github.com/smart-doc-group/smart-doc/wiki/Use-smart-doc-by-junit-test)
## Building
You could build with the following commands. (Java 1.8 is required to build the master branch)
```
mvn clean install -Dmaven.test.skip=true
```
## Contributors
Thanks to the following people who have submitted major pull requests:
## TODO
- Jakarta RS-API 2.x
- [@zuonidelaowang](https://github.com/zuonidelaowang)
- [@su-qiu](https://github.com/su-qiu)
- [@qinkangdeid](https://github.com/qinkangdeid)
- [@br7roy](https://github.com/br7roy)
- [@caiqyxyx](https://gitee.com/cy-work)
- [@lichoking](https://gitee.com/lichoking)
- [@JtePromise](https://github.com/JtePromise)
- [@lizhen789](https://github.com/lizhen789)
- [@maliqiang](https://github.com/maliqiang)
## Other reference
- [Smart-doc manual](https://github.com/shalousun/smart-doc/wiki)
## Who is using
These are only part of the companies using smart-doc, for reference only. If you are using smart-doc,
please [add your company here](https://github.com/smart-doc-group/smart-doc/issues/12) to tell us your scenario to make
smart-doc better.
These are only part of the companies using smart-doc, for reference only. If you are using smart-doc, please [add your company here](https://github.com/shalousun/smart-doc/issues/12) to tell us your scenario to make smart-doc better.
![IFLYTEK](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/iflytek.png)
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/oneplus.png" title="OnePlus" width="83px" height="83px"/>
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/xiaomi.png" title="Xiaomi" width="170px" height="83px"/>
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/neusoft.png" title="东软集团" width="170px" height="83px"/>
&nbsp;&nbsp;<img src="https://www.hand-china.com/static/img/hand-logo.svg" title="上海汉得信息技术股份有限公司" width="260px" height="83px"/>
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/shunfeng.png" title="顺丰" width="83px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/zhongkezhilian.png" title="zhongkezhilian" width="272px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/yuanmengjiankang.png" title="yuanmengjiankang" width="260px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg" title="puqie" width="83px" height="83px"/>
&nbsp;&nbsp;
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/zhongkezhilian.png" title="zhongkezhilian" width="272px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg" title="puqie" width="83px" height="83px"/>&nbsp;&nbsp;
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/tianbo-tech.png" title="tianbo tech" width="127px" height="70px"/>
## Acknowledgements
Thanks to [JetBrains SoftWare](https://www.jetbrains.com) for providing free Open Source license for this open source project.
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/jetbrains-variant-3.png" width="260px" height="220px"/>
## License
Smart-doc is under the Apache 2.0 license. See the [LICENSE](https://github.com/smart-doc-group/smart-doc/blob/master/LICENSE)
file for details.
Smart-doc is under the Apache 2.0 license. See the [LICENSE](https://github.com/shalousun/smart-doc/blob/master/LICENSE) file for details.
## Contact
Email 836575280@qq.com

View File

@ -6,18 +6,12 @@
![java version](https://img.shields.io/badge/JAVA-1.8+-green.svg)
## Introduce
smart-doc是一款同时支持JAVA REST API和Apache Dubbo RPC接口文档生成的工具smart-doc在业内率先提出基于JAVA泛型定义推导的理念
完全基于接口源码来分析生成接口文档不采用任何注解侵入到业务代码中。你只需要按照java-doc标准编写注释 smart-doc就能帮你生成一个简易明了的Markdown、HTML5、Postman
Collection2.0+、OpenAPI 3.0+的文档
完全基于接口源码来分析生成接口文档不采用任何注解侵入到业务代码中。你只需要按照java-doc标准编写注释
smart-doc就能帮你生成一个简易明了的Markdown、HTML5文档甚至可以直接生成Postman Collection导入到Postman做API接口调试
$\color{red}{你给我的star胜过所有读过的诗—smart-doc}$
> 无论你是很有经验的大佬、还是刚入行的萌新。遇到使用疑惑时我们希望你能仔细阅读smart-doc官方码云的wiki文档。我们将smart-doc及其插件的 每一个配置项和可能在日常中遇到的问题都整理到了文档中。仔细阅读文档就是对开源项目最大的支持。
查看[快速开始](https://smart-doc-group.github.io/#/zh-cn/) 了解详情
## Features
- 零注解、零学习成本、只需要写标准JAVA注释。
- 基于源代码接口定义自动推导,强大的返回结构推导。
- 支持Spring MVC、Spring Boot、Spring Boot Web Flux(controller书写方式)、Feign。
@ -27,75 +21,232 @@ $\color{red}{你给我的star胜过所有读过的诗—smart-doc}$
- 对一些常用字段定义能够生成有效的模拟值。
- 支持生成JSON返回值示例。
- 支持从项目外部加载源代码来生成字段注释(包括标准规范发布的jar包)。
- 支持生成多种格式文档Markdown、HTML5、Asciidoctor、Postman Collection、OpenAPI 3.0。 Up- 开放文档数据,可自由实现接入文档管理系统。
- 支持生成多种格式文档Markdown、HTML5、Asciidoctor、Postman Collection、OpenAPI 3.0。
- 轻易实现在Spring Boot服务上在线查看静态HTML5 api文档。
- 开放文档数据,可自由实现接入文档管理系统。
- 支持导出错误码和定义在代码中的各种字典码到接口文档。
- 支持Maven、Gradle插件式轻松集成。
- 支持Apache Dubbo RPC接口文档生成。
- debug接口调试html5页面完全支持文件上传下载(@download tag标记下载方法)测试。
## Getting Started
smart-doc使用和测试可参考[smart-doc demo](https://gitee.com/sunyurepository/api-doc-test.git)。
```
# git clone https://gitee.com/sunyurepository/api-doc-test.git
```
你可以启动这个Spring Boot的项目然后访问`http://localhost:8080/doc/api.html`来浏览smart-doc生成的接口文档。
### Add Maven Plugin
smart-doc官方目前已经开发完成[Maven插件](https://gitee.com/smart-doc-team/smart-doc-maven-plugin)
和[Gradle插件](https://gitee.com/smart-doc-team/smart-doc-gradle-plugin)
你可以根据自己的构建工具来选择使用Maven插件或者是Gradle插件。
#### Add Plugin
```
<plugin>
<groupId>com.github.shalousun</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>[最新版本]</version>
<configuration>
<!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<!--指定项目名称-->
<projectName>测试</projectName>
<!--smart-doc实现自动分析依赖树加载第三方依赖的源码如果一些框架依赖库加载不到导致报错这时请使用excludes排除掉-->
<excludes>
<!--格式为groupId:artifactId;参考如下-->
<exclude>com.alibaba:fastjson</exclude>
</excludes>
<!--自1.0.8版本开始插件提供includes支持-->
<!--smart-doc能自动分析依赖树加载所有依赖源码原则上会影响文档构建效率因此你可以使用includes来让插件加载你配置的组件-->
<includes>
<!--格式为groupId:artifactId;参考如下-->
<include>com.alibaba:fastjson</include>
</includes>
</configuration>
<executions>
<execution>
<!--如果不需要在执行编译时启动smart-doc则将phase注释掉-->
<phase>compile</phase>
<goals>
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
```
#### Configuration
在项目中添加创建一个`smart-doc.json`配置文件,插件读取这个配置来生成项目的文档,
这个配置内容实际上就是以前采用单元测试编写的`ApiConfig`转成json后的结果因此关于配置项说明可以参考原来单元测试的配置。
## Best Practice
**最小配置单元:**
```
{
"outPath": "D://md2" //指定文档的输出路径,相对路径时请用./开头eg:./src/main/resources/static/doc
}
```
仅仅需要上面一行配置就能启动smart-doc-maven-plugin插件根据自己项目情况更多详细的配置参考下面。
smart-doc + [Torna](http://torna.cn) 组成行业领先的文档生成和管理解决方案使用smart-doc无侵入完成Java源代码分析和提取注释生成API文档自动将文档推送到Torna企业级接口文档管理平台。
**详细配置说明**
```
{
"serverUrl": "http://127.0.0.1", //服务器地址,非必须。导出postman建议设置成http://{{server}}方便直接在postman直接设置环境变量
"isStrict": false, //是否开启严格模式
"allInOne": true, //是否将文档合并到一个文件中一般推荐为true
"outPath": "D://md2", //指定文档的输出路径
"coverOld": true, //是否覆盖旧的文件主要用于mardown文件覆盖
"packageFilters": "",//controller包过滤多个包用英文逗号隔开
"md5EncryptedHtmlName": false,//只有每个controller生成一个html文件是才使用
"style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki喜欢配色统一简洁的同学可以不设置
"projectName": "smart-doc",//配置自己的项目名称
"skipTransientField": true,//目前未实现
"sortByTitle":false,//接口标题排序默认为false,@since 1.8.7版本开始
"showAuthor":true,//是否显示接口作者名称默认是true,不想显示可关闭
"requestFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
"responseFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
"inlineEnum":true,//设置为true会将枚举详情展示到参数表中默认关闭//@since 1.8.8版本开始
"recursionLimit":7,//设置允许递归执行的次数用于避免一些对象解析卡主默认是7正常为3次以内//@since 1.8.8版本开始
"allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0
"requestExample":"true",//是否将请求示例展示在文档中默认true@since 1.9.0
"responseExample":"true",//是否将响应示例展示在文档中默认为true@since 1.9.0
"displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名@since 1.9.6
"ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2
"org.springframework.ui.ModelMap"
],
"dataDictionaries": [ //配置数据字典,没有需求可以不设置
{
"title": "http状态码字典", //数据字典的名称
"enumClassName": "com.power.common.enums.HttpCodeEnum", //数据字典枚举类名称
"codeField": "code",//数据字典字典码对应的字段名称
"descField": "message"//数据字典对象的描述信息字典
}
],
"errorCodeDictionaries": [{ //错误码列表,没有需求可以不设置
"title": "title",
"enumClassName": "com.power.common.enums.HttpCodeEnum", //错误码枚举类
"codeField": "code",//错误码的code码字段名称
"descField": "message"//错误码的描述信息对应的字段名
}],
"revisionLogs": [ //设置文档变更记录,没有需求可以不设置
{
"version": "1.0", //文档版本号
"status": "update", //变更操作状态,一般为:创建、更新等
"author": "author", //文档变更作者
"remarks": "desc" //变更描述
}
],
"customResponseFields": [ //自定义添加字段和注释api-doc后期遇到同名字段则直接给相应字段加注释非必须
{
"name": "code",//覆盖响应码字段
"desc": "响应代码",//覆盖响应码的字段注释
"ownerClassName": "org.springframework.data.domain.Pageable", //指定你要添加注释的类名
"value": "00000"//设置响应码的值
}
],
"requestHeaders": [ //设置请求头,没有需求可以不设置
{
"name": "token",//请求头名称
"type": "string",//请求头类型
"desc": "desc",//请求头描述信息
"value":"token请求头的值",//不设置默认null
"required": false,//是否必须
"since": "-"//什么版本添加的改请求头
}
],
"rpcApiDependencies":[{ // 项目开放的dubbo api接口模块依赖配置后输出到文档方便使用者集成
"artifactId":"SpringBoot2-Dubbo-Api",
"groupId":"com.demo",
"version":"1.0.0"
}],
"rpcConsumerConfig": "src/main/resources/consumer-example.conf",//文档中添加dubbo consumer集成配置用于方便集成方可以快速集成
"apiObjectReplacements": [{ // 自smart-doc 1.8.5开始你可以使用自定义类覆盖其他类做文档渲染,非必须
"className": "org.springframework.data.domain.Pageable",
"replacementClassName": "com.power.doc.model.PageRequestDto" //自定义的PageRequestDto替换Pageable做文档渲染
}],
"apiConstants": [{//从1.8.9开始配置自己的常量类smart-doc在解析到常量时自动替换为具体的值
"constantsClassName": "com.power.doc.constants.RequestParamConstant"
}],
"responseBodyAdvice":{ //自smart-doc 1.9.8起ResponseBodyAdvice统一返回设置可用ignoreResponseBodyAdvice tag来忽略
"className":"com.power.common.model.CommonResult" //通用响应体
},
"sourceCodePaths": [ //设置代码路径, 插件已经能够自动下载发布的源码包,没必要配置
{
"path": "src/main/java",
"desc": "测试"
}
]
}
```
上面的JSON配置实例中只有"outPath"是必填项。
![smart-doc+torna](https://gitee.com/smart-doc-team/smart-doc/raw/master/images/smart-doc-torna.png)
**注意:** 对于老用户完全可以通过`Fastjson`或者是`Gson`库将`ApiConfig`转化成JSON配置。
#### Use Maven Command
添加好插件和配置文件后可以直接运行Maven命令生成文档。
```
//生成html
mvn -Dfile.encoding=UTF-8 smart-doc:html
//生成markdown
mvn -Dfile.encoding=UTF-8 smart-doc:markdown
//生成adoc
mvn -Dfile.encoding=UTF-8 smart-doc:adoc
//生成postman json数据
mvn -Dfile.encoding=UTF-8 smart-doc:postman
// 生成 Open Api 3.0+,Since smart-doc-maven-plugin 1.1.5
mvn -Dfile.encoding=UTF-8 smart-doc:openapi
[smart-doc+Torna文档自动化](https://gitee.com/smart-doc-team/smart-doc/wikis/smart-doc与torna对接?sort_id=3695028)
// Apache Dubbo RPC文档
// Generate html
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-html
// Generate markdown
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-markdown
// Generate adoc
mvn -Dfile.encoding=UTF-8 smart-doc:rpc-adoc
```
**注意:** 尤其在window系统下如果实际使用Maven命令行执行文档生成可能会出现乱码因此需要在执行时指定`-Dfile.encoding=UTF-8`。
#### Use in IDEA
![idea中smart-doc-maven插件使用](https://gitee.com/smart-doc-team/smart-doc-maven-plugin/raw/master/images/idea.png "maven_plugin_tasks.png")
> Torna是由smart-doc官方独家推动联合研发的企业级文档管理系统因此smart-doc官方不会对接其它任何的外部文档管理系统例如像showdoc、yapi 之类的对接请自定内部处理也不要再给我们提其他文档系统对接的PR。我们核心是把smart-doc+Torna的这套方案打造好。
### Use gradle plugin
如果你使用Gradle来构建项目你可以参考Gradle插件的使用文档来集成
[smart-doc-gradle-plugin](https://gitee.com/smart-doc-team/smart-doc-gradle-plugin/blob/master/README_CN.md)
### Use Junit Test
从smart-doc 1.7.9开始官方提供了Maven插件使用smart-doc的Maven插件后不再需要创建单元测试。
[单元测试生成文档](https://gitee.com/smart-doc-team/smart-doc/wikis/单元测试集成smart-doc?sort_id=1990284)
$\color{red}{注意:}$ 单元测试集成存在很多绝限性请使用插件注意市面上基于JAVA源码生成文档的工具<br/>未采用插件分析依赖加载源码的都是不成熟的工具
### Generated document example
[点击查看文档生成文档效果图](https://gitee.com/smart-doc-team/smart-doc/wikis/文档效果图?sort_id=1652819)
## Building
如果你需要自己构建smart-doc那可以使用下面命令构建需要依赖Java 1.8。
```
mvn clean install -Dmaven.test.skip=true
```
## Contributors
感谢下列提交者
## TODO
- Jakarta RS-API 2.x
- [@zuonidelaowang](https://github.com/zuonidelaowang)
- [@su-qiu](https://github.com/su-qiu)
- [@qinkangdeid](https://github.com/qinkangdeid)
- [@br7roy](https://github.com/br7roy)
- [@caiqyxyx](https://gitee.com/cy-work)
- [@lichoking](https://gitee.com/lichoking)
- [@JtePromise](https://github.com/JtePromise)
- [@lizhen789](https://github.com/lizhen789)
- [@maliqiang](https://github.com/maliqiang)
## Other reference
- [smart-doc功能使用介绍](https://my.oschina.net/u/1760791/blog/2250962)
- [smart-doc官方wiki](https://gitee.com/smart-doc-team/smart-doc/wikis/Home?sort_id=1652800)
## License
smart-doc is under the Apache 2.0 license. See
the [LICENSE](https://gitee.com/smart-doc-team/smart-doc/blob/master/LICENSE) file for details.
smart-doc is under the Apache 2.0 license. See the [LICENSE](https://gitee.com/smart-doc-team/smart-doc/blob/master/LICENSE) file for details.
**注意:** smart-doc源代码文件全部带有版权注释使用关键代码二次开源请保留原始版权否则后果自负
## Who is using
> 排名不分先后,更多接入公司,欢迎在[https://gitee.com/smart-doc-team/smart-doc/issues/I1594T](https://gitee.com/smart-doc-team/smart-doc/issues/I1594T)登记(仅供开源用户参考)
![IFLYTEK](https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/iflytek.png)
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/oneplus.png" title="一加" width="83px" height="83px"/>
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/xiaomi.png" title="小米" width="170px" height="83px"/>
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/neusoft.png" title="东软集团" width="180px" height="83px"/>
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/zhongkezhilian.png" title="中科智链" width="272px" height="83px"/>
&nbsp;&nbsp;<img src="https://www.hand-china.com/static/img/hand-logo.svg" title="上海汉得信息技术股份有限公司" width="260px" height="83px"/>
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/shunfeng.png" title="顺丰" width="83px" height="83px"/>
&nbsp;&nbsp;<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/yuanmengjiankang.png" title="远盟健康" width="260px" height="83px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/puqie_gaitubao_100x100.jpg" title="普切信息科技" width="83px" height="83px"/>
&nbsp;&nbsp;
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/tianbo-tech.png" title="杭州天铂云科" width="135px" height="83px"/>
&nbsp;&nbsp;
## Award situation
- 2020 年度 OSC 中国开源项目评选”活动中获得「最积极运营项目」
## Acknowledgements
感谢[JetBrains SoftWare](https://www.jetbrains.com) 为本开源项目提供的免费Open Source license。
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/jetbrains-variant-3.png" width="260px" height="220px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/yuanmengjiankang.png" title="远盟健康" width="260px" height="83px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/zhongkezhilian.png" title="中科智链" width="272px" height="83px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/puqie_gaitubao_100x100.jpg" title="普切信息科技" width="83px" height="83px"/>&nbsp;&nbsp;
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/known-users/tianbo-tech.png" title="杭州天铂云科" width="127px" height="70px"/>
## Contact
愿意参与构建smart-doc或者是需要交流问题可以加入qq群
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/smart-doc-qq.png" title="qq群" width="200px" height="210px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/smart-doc-qq2.jpeg" title="qq群2" width="200px" height="210px"/>
> 1群已满有问题请加2群。
## Donate
如果您觉得我们的开源软件对你有所帮助,请扫下方二维码打赏我们一杯咖啡
<img src="https://images.gitee.com/uploads/images/2020/0831/225756_9aecdd4d_144669.png" width="200px" height="210px"/>
<img src="https://gitee.com/smart-doc-team/smart-doc/raw/master/images/smart-doc-qq.png" title="qq群" width="200px" height="200px"/>

136
doc/List.md Normal file
View File

@ -0,0 +1,136 @@
关于list结构的返回json数据测试
# List<String>结构
api-doc对于List中返回基础数据类型都是支持的
```
/**
* List<String>
*
* @return
*/
@GetMapping(value = "listString")
public List<String> testList() {
return null;
}
```
api-doc生成的响应数据
```
[ "ivvqah","isrz5x"]
```
# List<Map<String,String>>结构
```
/**
*
* @return
*/
@GetMapping(value = "/map/Primitive")
public List<Map<String,String>> testMap() {
return null;
}
```
api-doc生成的响应数据
```
[{
"mapKey1": "o9mibj",
"mapKey2": "3dnnrn"
}]
```
# List<Map<String,T>>结构
```
@GetMapping(value = "/map/Primitive")
public List<Map<String,Student>> testMap() {
return null;
}
```
相应数据省略
# 测试List<T>结构
```
/**
* 测试List<T>结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public List<Teacher> testMap() {
return null;
}
```
# List<T<M,N>>结构
```
/**
* 测试List<T<M,N>>结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public List<Teacher<User,User>> testMap() {
return null;
}
```
# List<Map<M,N<P,k>>>超复杂结构
```
/**
* 测试List<Map<M,N<P,k>>>超复杂结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public List<Map<String,Teacher<User,User>>> testMap() {
return null;
}
```
api-doc自动返回的数据
```
[{
"mapKey": {
"data": {
"userName": "lxh2yi",
"userAddress": "6jfp3h",
"userAge": 741
},
"data1": {
"userName": "1wp54g",
"userAddress": "8ul6m4",
"userAge": 550
},
"age": 10
}
}]
```
# List<T<List<M>,List<M>,List<M>>>超复杂结构
```
/**
* List<T<List<M>,List<M>,List<M>>>
* @return
*/
@GetMapping(value = "listString")
public List<Teacher<List<User>,List<User>,List<User>>> testListString(){
return null;
}
```
# 其他复杂结构
```
/**
* List<T<List<M>,List<M>,List<M>>>
*
* @return
*/
@GetMapping(value = "listString")
public List<Teacher<Teacher<User,User,User>,User,User>> testListString() {
return null;
}
@GetMapping(value = "listString")
public List<Teacher<Teacher<User,User,User>,Teacher<User,User,User>,Teacher<User,User,User>>> testListString() {
return null;
}
```
**注意:** api-doc为了传入的复杂泛型结构数据做了许多情况的测试目前基本能兼容系统开发中95%以上的List返回接口
也提供了一些能够处理的很复杂的泛型结构,但是这种复杂的泛型结构在开发中是不被推荐的。

153
doc/Map.md Normal file
View File

@ -0,0 +1,153 @@
Api-doc对于api中map结构数据的json化处理多组测试用例,对于map返回的json结构
目前基本仅仅支持String类型的key。
**基础数据类型:** json支持的基本java数据类型(不包含byte,包含String)
# map使用基础数据类型
```
/**
* 测试map使用基础数据类型
* @return
*/
@GetMapping(value = "/map/Primitive")
public Map<String,Integer> testMap() {
return null;
}
```
api-doc 生成的json:
```
{
"mapKey1": 721,
"mapKey2": 280
}
```
# map使用Object
因为api-doc使用的是无侵入静态分析生成api文档因此对于直接使用Object做map value的接口api-doc无法准确的生成json。
所以api-doc返回是会在默认json中加一段警告使用者需要自己去修改返回数据或者是使用显示的类型数据结构。
```
/**
* 测试map使用基础数据类型
* @return
*/
@GetMapping(value = "/map/Primitive")
public Map<String,Object> testMap() {
return null;
}
```
api-doc 生成的json:
```
{
"mapKey": {
"waring": "You may use java.util.Object for Map value;Api-doc can't be handle."
}
}
```
# map中属于自己定义的简单数据结构
User对象的属性仅仅是基本数据类型
```
/**
* 测试map使用自定义数据结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public Map<String,User> testMap() {
return null;
}
```
api-doc 生成的json:
```
{
"mapKey": {
"userName": "7t2ccy",
"userAddress": "3ipy7g",
"userAge": 280
}
}
```
# map中属于自己定义的复杂数据结构
Student对象的属性有基本类型又有User类型和Map类型的属性。
```
/**
* 测试map使用自定义数据结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public Map<String,Student> testMap() {
return null;
}
```
api-doc 生成的json:
```
{
"mapKey": {
"stuName": "9cwzml",
"stuAge": 792,
"stuAddress": "rdfmtx",
"user": {
"userName": "fjglql",
"userAddress": "yy6vkf",
"userAge": 398
},
"userMap": {
"mapKey": {
"userName": "paw90w",
"userAddress": "mnmz42",
"userAge": 937
}
},
"user1": {
"userName": "rr3v6g",
"userAddress": "rbeorq",
"userAge": 399
}
}
}
```
# Map<M,N<P,k>>复杂结构
```
{
"mapKey":{
"data":{
"userName":"tumrit",
"userAddress":"v8fvdi",
"userAge":465
},
"data1":{
"userName":"f7wbwk",
"userAddress":"brdh8j",
"userAge":345
},
"age":194
}
}
```
# Map<String,T<List<M>,N>超复杂结构
```
/**
* Map<String,T<List<M>,N>超复杂结构
* @return
*/
@GetMapping(value = "/map/Primitive")
public Map<String,Teacher<List<User>,User>> testMap() {
return null;
}
```
# Map其他复杂结构
对于map的key采用多泛型的情况目前api-doc也是支持的。
```
/**
* Map<String,T<List<M>,N>超复杂结构
* @return
*/
public Map<String,Teacher<Map<String,User>,Map<String,User>,Map<String,User>>> testMap() {
return null;
}
```
**注意:** api-doc为了传入的复杂泛型结构数据做了许多情况的测试目前基本能兼容系统开发中95%以上的Map返回接口
也提供了一些能够处理的很复杂的泛型结构,但是这种复杂的泛型结构在开发中是不被推荐的。

31
doc/error.md Normal file
View File

@ -0,0 +1,31 @@
api-doc对Spring mvc或者SpringBoot应用的Controller接口返回做了一些强制规约一旦在代码中使用
这些被api-doc不推荐的接口返回类型api-doc将会直接报错。
# 违反规约的实例
## 直接返回Object
```
/**
* 返回object
* @return
*/
@GetMapping("/test/Object")
public Object getMe(){
return null;
}
```
报错提示Please do not return java.lang.Object directly in api interface.
## 将非String对象作为Map的key然后将map作为接口中返回
```
/**
* 测试object的作为map的key
* @return
*/
@GetMapping("/test/map")
public Map<Object,Object> objectMap(){
return null;
}
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

48
pom.xml
View File

@ -5,13 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>smart-doc</artifactId>
<packaging>jar</packaging>
<version>2.3.2</version>
<version>1.9.9.2</version>
<name>smart-doc</name>
<url>https://github.com/smart-doc-group/smart-doc.git</url>
<description>Smart-doc is a tool that supports both JAVA RESTFUL API and Apache Dubbo RPC interface document
generation.
</description>
<description>Smart-doc is a tool that supports both JAVA RESTFUL API and Apache Dubbo RPC interface document generation.</description>
<licenses>
<license>
@ -34,19 +32,19 @@
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.8.1</junit.jupiter.version>
<flexmark.version>0.62.2</flexmark.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.8.1.RELEASE</version>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.qdox</groupId>
@ -67,17 +65,33 @@
<dependency>
<groupId>com.github.shalousun</groupId>
<artifactId>common-util</artifactId>
<version>2.1.0</version>
<version>2.0.1</version>
</dependency>
<!--markdown to html-->
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark</artifactId>
<version>${flexmark.version}</version>
</dependency>
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-util</artifactId>
<version>${flexmark.version}</version>
</dependency>
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-ext-tables</artifactId>
<version>${flexmark.version}</version>
</dependency>
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-ext-gfm-strikethrough</artifactId>
<version>${flexmark.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
<version>2.8.6</version>
</dependency>
</dependencies>
<build>
@ -132,7 +146,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>

BIN
screen/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
screen/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
screen/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,10 +22,10 @@
*/
package com.power.doc.builder;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.List;
@ -61,16 +61,14 @@ public class AdocDocBuilder {
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
config.setParamsDataToTree(false);
config.setAdoc(true);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (config.isAllInOne()) {
String docName = builderTemplate.allInOneDocName(config,INDEX_DOC,".adoc");
apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_ADOC_TPL, docName);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_ADOC_TPL, INDEX_DOC);
} else {
builderTemplate.buildApiDoc(apiDocList, config, API_DOC_ADOC_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_ADOC_TPL, ERROR_CODE_LIST_ADOC);
@ -88,7 +86,7 @@ public class AdocDocBuilder {
config.setAdoc(false);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, new JavaProjectBuilder());
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
builderTemplate.buildSingleApi(configBuilder, controllerName, API_DOC_ADOC_TPL, API_EXTENSION);
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -39,7 +39,7 @@ public class ApiDataBuilder {
* @return List of ApiDoc
*/
public static ApiAllData getApiData(ApiConfig config) {
return getApiData(config, Boolean.FALSE);
return getApiData(config,false);
}
/**
@ -49,7 +49,7 @@ public class ApiDataBuilder {
* @return List of ApiDoc
*/
public static ApiAllData getApiDataTree(ApiConfig config) {
return getApiData(config, Boolean.TRUE);
return getApiData(config,true);
}
private static ApiAllData getApiData(ApiConfig config,boolean toTree) {
@ -57,7 +57,7 @@ public class ApiDataBuilder {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInitForGetApiData(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ApiAllData apiAllData = builderTemplate.getApiData(config, javaProjectBuilder);
return apiAllData;
builderTemplate.getApiData(config, javaProjectBuilder);
return builderTemplate.getApiData(config, javaProjectBuilder);
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -23,10 +23,10 @@
package com.power.doc.builder;
import com.power.common.util.DateTimeUtil;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.List;
@ -60,17 +60,15 @@ public class ApiDocBuilder {
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
config.setAdoc(false);
config.setParamsDataToTree(false);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (config.isAllInOne()) {
String version = config.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DATE_FORMAT);
String docName = builderTemplate.allInOneDocName(config,"AllInOne" + version + ".md",".md");
apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_MD_TPL, docName);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_MD_TPL, "AllInOne" + version + ".md");
} else {
builderTemplate.buildApiDoc(apiDocList, config, API_DOC_MD_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_MD_TPL, ERROR_CODE_LIST_MD);
@ -89,7 +87,7 @@ public class ApiDocBuilder {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
builderTemplate.buildSingleApi(configBuilder, controllerName, API_DOC_MD_TPL, API_EXTENSION);
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,46 +22,34 @@
*/
package com.power.doc.builder;
import com.power.common.util.DateTimeUtil;
import com.power.common.util.CollectionUtil;
import com.power.common.util.EnumUtil;
import com.power.common.util.StringUtil;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.DocLanguage;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.RevisionLog;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.Resource;
import com.power.doc.model.ApiErrorCode;
import com.power.doc.model.ApiErrorCodeDictionary;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.power.doc.constants.DocGlobalConstants.CSS_CDN;
import static com.power.doc.constants.DocGlobalConstants.CSS_CDN_CH;
/**
* @author yu 2020/5/16.
*/
public class BaseDocBuilderTemplate {
public static long NOW = System.currentTimeMillis();
/**
* check condition and init
*
* @param config Api config
* @param checkOutPath check out path
*/
public void checkAndInit(ApiConfig config,boolean checkOutPath) {
public void checkAndInit(ApiConfig config) {
this.checkAndInitForGetApiData(config);
if (StringUtil.isEmpty(config.getOutPath())&&!checkOutPath) {
if (StringUtil.isEmpty(config.getOutPath())) {
throw new RuntimeException("doc output path can't be null or empty");
}
}
@ -82,86 +70,49 @@ public class BaseDocBuilderTemplate {
config.setLanguage(DocLanguage.CHINESE);
System.setProperty(DocGlobalConstants.DOC_LANGUAGE, DocLanguage.CHINESE.getCode());
}
if (Objects.isNull(config.getRevisionLogs())) {
String strTime = DateTimeUtil.long2Str(NOW, DateTimeUtil.DATE_FORMAT_SECOND);
config.setRevisionLogs(
RevisionLog.builder()
.setRevisionTime(strTime)
.setAuthor("@" + System.getProperty("user.name"))
.setVersion("v" + strTime)
.setRemarks("Created by smart-doc")
.setStatus("auto")
);
}
if (StringUtil.isEmpty(config.getFramework())) {
config.setFramework(FrameworkEnum.SPRING.getFramework());
}
}
public Map<String, String> setDirectoryLanguageVariable(ApiConfig config, Template mapper) {
Map<String, String> titleMap = new HashMap<>();
if (Objects.nonNull(config.getLanguage())) {
public void setDirectoryLanguageVariable(ApiConfig config, Template mapper) {
if (null != config.getLanguage()) {
if (DocLanguage.CHINESE.code.equals(config.getLanguage().getCode())) {
mapper.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_CN_TITLE);
mapper.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
titleMap.put(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_CN_TITLE);
titleMap.put(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
} else {
mapper.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_EN_TITLE);
mapper.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_EN_TITLE);
titleMap.put(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_EN_TITLE);
titleMap.put(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_EN_TITLE);
}
} else {
mapper.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_CN_TITLE);
mapper.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
titleMap.put(TemplateVariable.ERROR_LIST_TITLE.getVariable(), DocGlobalConstants.ERROR_CODE_LIST_CN_TITLE);
titleMap.put(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
}
return titleMap;
}
public void setCssCDN(ApiConfig config, Template template) {
if (DocLanguage.CHINESE.equals(config.getLanguage())) {
template.binding(TemplateVariable.CSS_CND.getVariable(), CSS_CDN_CH);
} else {
template.binding(TemplateVariable.CSS_CND.getVariable(), CSS_CDN);
}
}
public String allInOneDocName(ApiConfig apiConfig, String fileName, String suffix) {
String allInOneName = apiConfig.getAllInOneDocFileName();
if (StringUtils.isNotEmpty(apiConfig.getAllInOneDocFileName())) {
if (allInOneName.endsWith(suffix)) {
return allInOneName;
public List<ApiErrorCode> errorCodeDictToList(ApiConfig config) {
if (CollectionUtil.isNotEmpty(config.getErrorCodes())) {
return config.getErrorCodes();
}
List<ApiErrorCodeDictionary> errorCodeDictionaries = config.getErrorCodeDictionaries();
if (CollectionUtil.isEmpty(errorCodeDictionaries)) {
return new ArrayList<>(0);
} else {
return allInOneName + suffix;
List<ApiErrorCode> errorCodeList = new ArrayList<>();
try {
for (ApiErrorCodeDictionary dictionary : errorCodeDictionaries) {
Class<?> clzz = dictionary.getEnumClass();
if (Objects.isNull(clzz)) {
if (StringUtil.isEmpty(dictionary.getEnumClassName())) {
throw new RuntimeException("Enum class name can't be null.");
}
} else if (StringUtil.isNotEmpty(fileName) && fileName.endsWith(suffix)) {
return fileName;
} else {
return fileName + suffix;
clzz = Class.forName(dictionary.getEnumClassName());
}
List<ApiErrorCode> enumDictionaryList = EnumUtil.getEnumInformation(clzz, dictionary.getCodeField(),
dictionary.getDescField());
errorCodeList.addAll(enumDictionaryList);
}
public static void copyJarFile(String source, String target) {
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("/template/");
Resource resource = resourceLoader.getResource(source);
try (FileWriter fileWriter = new FileWriter(target, false);
Reader reader = resource.openReader()) {
char[] c = new char[1024 * 1024];
int temp;
int len = 0;
while ((temp = reader.read()) != -1) {
c[len] = (char) temp;
len++;
}
reader.close();
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(c, 0, len);
bufferedWriter.close();
} catch (IOException e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return errorCodeList;
}
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,26 +22,23 @@
*/
package com.power.doc.builder;
import com.power.common.util.CollectionUtil;
import com.power.common.util.DateTimeUtil;
import com.power.common.util.FileUtil;
import com.power.doc.constants.DocLanguage;
import com.power.common.util.*;
import com.power.doc.constants.HighlightStyle;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.*;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.power.doc.utils.BeetlTemplateUtil;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import org.beetl.core.Template;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.power.doc.constants.DocGlobalConstants.*;
import static com.power.doc.constants.DocGlobalConstants.FILE_SEPARATOR;
/**
* @author yu 2019/9/26.
@ -63,9 +60,9 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
apiAllData.setProjectId(DocUtil.generateId(config.getProjectName()));
apiAllData.setLanguage(config.getLanguage().getCode());
apiAllData.setApiDocList(listOfApiData(config, javaProjectBuilder));
apiAllData.setErrorCodeList(DocUtil.errorCodeDictToList(config));
apiAllData.setErrorCodeList(errorCodeDictToList(config));
apiAllData.setRevisionLogs(config.getRevisionLogs());
apiAllData.setApiDocDictList(DocUtil.buildDictionary(config, javaProjectBuilder));
apiAllData.setApiDocDictList(buildDictionary(config, javaProjectBuilder));
return apiAllData;
}
@ -99,116 +96,35 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
* @param template template
* @param outPutFileName output file
*/
public void buildAllInOne(List<ApiDoc> apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder,
String template, String outPutFileName) {
buildDoc(apiDocList, config, javaProjectBuilder, template, outPutFileName, null, null);
}
/**
* Merge all api doc into one document
*
* @param apiDocList list data of Api doc
* @param config api config
* @param javaProjectBuilder JavaProjectBuilder
* @param template template
* @param outPutFileName output file
* @param apiDoc apiDoc
* @param index index html
*/
public void buildDoc(List<ApiDoc> apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder,
String template, String outPutFileName, ApiDoc apiDoc, String index) {
public void buildAllInOne(List<ApiDoc> apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder, String template, String outPutFileName) {
String outPath = config.getOutPath();
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
FileUtil.mkdirs(outPath);
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
List<ApiErrorCode> errorCodeList = errorCodeDictToList(config);
Template tpl = BeetlTemplateUtil.getByName(template);
String style = config.getStyle();
tpl.binding(TemplateVariable.STYLE.getVariable(),style);
tpl.binding(TemplateVariable.HIGH_LIGHT_CSS_LINK.getVariable(), config.getHighlightStyleLink());
tpl.binding(TemplateVariable.BACKGROUND.getVariable(), HighlightStyle.getBackgroundColor(style));
tpl.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
tpl.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), errorCodeList);
tpl.binding(TemplateVariable.VERSION_LIST.getVariable(), config.getRevisionLogs());
tpl.binding(TemplateVariable.VERSION.getVariable(), now);
tpl.binding(TemplateVariable.INDEX_ALIAS.getVariable(), index);
tpl.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
tpl.binding(TemplateVariable.PROJECT_NAME.getVariable(), config.getProjectName());
tpl.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample());
tpl.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample());
tpl.binding(TemplateVariable.DISPLAY_REQUEST_PARAMS.getVariable(), config.isRequestParamsTable());
tpl.binding(TemplateVariable.DISPLAY_RESPONSE_PARAMS.getVariable(), config.isResponseParamsTable());
setCssCDN(config, tpl);
if (CollectionUtil.isEmpty(errorCodeList)) {
tpl.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 1);
} else {
tpl.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 2);
}
if (Objects.nonNull(apiDoc)) {
tpl.binding(TemplateVariable.DESC.getVariable(), apiDoc.getDesc());
tpl.binding(TemplateVariable.ORDER.getVariable(), apiDoc.order);
tpl.binding(TemplateVariable.LIST.getVariable(), apiDoc.getList());//类名
}
setDirectoryLanguageVariable(config, tpl);
List<ApiDocDict> apiDocDictList = DocUtil.buildDictionary(config, javaProjectBuilder);
List<ApiDocDict> apiDocDictList = buildDictionary(config, javaProjectBuilder);
tpl.binding(TemplateVariable.DICT_LIST.getVariable(), apiDocDictList);
FileUtil.nioWriteFile(tpl.render(), outPath + FILE_SEPARATOR + outPutFileName);
}
public void buildSearchJs(ApiConfig config, JavaProjectBuilder javaProjectBuilder, List<ApiDoc> apiDocList, String template) {
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
Template tpl = BeetlTemplateUtil.getByName(template);
// directory tree
List<ApiDoc> apiDocs = new ArrayList<>();
for (ApiDoc apiDoc1 : apiDocList) {
apiDoc1.setOrder(apiDocs.size() + 1);
apiDocs.add(apiDoc1);
}
boolean isOnlyDefaultGroup = apiDocList.size() == 1;
Map<String, String> titleMap = setDirectoryLanguageVariable(config, tpl);
// set error code
if (CollectionUtil.isNotEmpty(errorCodeList)) {
ApiDoc apiDoc1 = new ApiDoc();
apiDoc1.setOrder((isOnlyDefaultGroup ? apiDocs.get(0).getChildrenApiDocs().size() : apiDocs.size()) + 1);
apiDoc1.setDesc(titleMap.get(TemplateVariable.ERROR_LIST_TITLE.getVariable()));
apiDoc1.setList(new ArrayList<>(0));
apiDoc1.setLink("error_code_list");
apiDoc1.setAlias("error");
apiDoc1.setGroup(apiDoc1.getDesc());
if (isOnlyDefaultGroup) {
apiDocs.get(0).getChildrenApiDocs().add(apiDoc1);
} else {
apiDocs.add(apiDoc1);
}
}
// set dict list
List<ApiDocDict> apiDocDictList = DocUtil.buildDictionary(config, javaProjectBuilder);
if (CollectionUtil.isNotEmpty(apiDocDictList)) {
ApiDoc apiDoc1 = new ApiDoc();
apiDoc1.setOrder((isOnlyDefaultGroup ? apiDocs.get(0).getChildrenApiDocs().size() : apiDocs.size()) + 1);
apiDoc1.setLink("dict_list");
apiDoc1.setAlias("dict");
apiDoc1.setDesc(titleMap.get(TemplateVariable.DICT_LIST_TITLE.getVariable()));
apiDoc1.setGroup(apiDoc1.getDesc());
List<ApiMethodDoc> methodDocs = new ArrayList<>();
for (ApiDocDict apiDocDict : apiDocDictList) {
ApiMethodDoc methodDoc = new ApiMethodDoc();
methodDoc.setOrder(apiDocDict.getOrder());
methodDoc.setDesc(apiDocDict.getTitle());
methodDocs.add(methodDoc);
}
apiDoc1.setList(methodDocs);
if (isOnlyDefaultGroup) {
apiDocs.get(0).getChildrenApiDocs().add(apiDoc1);
} else {
apiDocs.add(apiDoc1);
}
}
tpl.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocs);
FileUtil.nioWriteFile(tpl.render(), config.getOutPath() + FILE_SEPARATOR + SEARCH_JS_OUT);
}
/**
* build error_code adoc
@ -218,95 +134,9 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
* @param outPutFileName output file
*/
public void buildErrorCodeDoc(ApiConfig config, String template, String outPutFileName) {
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
Template tpl = BeetlTemplateUtil.getByName(template);
setCssCDN(config, tpl);
tpl.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
tpl.binding(TemplateVariable.LIST.getVariable(), errorCodeList);
FileUtil.nioWriteFile(tpl.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
}
/**
* build error_code html
*
* @param config api config
* @param javaProjectBuilder javaProjectBuilder
* @param apiDocList list data of Api doc
* @param template template
* @param outPutFileName output file
* @param indexAlias index alias
*/
public void buildErrorCodeDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder,
List<ApiDoc> apiDocList, String template, String outPutFileName, String indexAlias) {
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
Template errorTemplate = BeetlTemplateUtil.getByName(template);
errorTemplate.binding(TemplateVariable.PROJECT_NAME.getVariable(), config.getProjectName());
String style = config.getStyle();
errorTemplate.binding(TemplateVariable.HIGH_LIGHT_CSS_LINK.getVariable(), config.getHighlightStyleLink());
errorTemplate.binding(TemplateVariable.STYLE.getVariable(), style);
if (CollectionUtil.isEmpty(errorCodeList)) {
errorTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 1);
} else {
errorTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 2);
}
// set css cdn
setCssCDN(config, errorTemplate);
List<ApiDocDict> apiDocDictList = DocUtil.buildDictionary(config, javaProjectBuilder);
errorTemplate.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
errorTemplate.binding(TemplateVariable.VERSION.getVariable(), now);
errorTemplate.binding(TemplateVariable.DICT_LIST.getVariable(), apiDocDictList);
errorTemplate.binding(TemplateVariable.INDEX_ALIAS.getVariable(), indexAlias);
errorTemplate.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
errorTemplate.binding(TemplateVariable.BACKGROUND.getVariable(), HighlightStyle.getBackgroundColor(style));
errorTemplate.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), errorCodeList);
setDirectoryLanguageVariable(config, errorTemplate);
FileUtil.nioWriteFile(errorTemplate.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
}
/**
* build common_data doc
*
* @param config api config
* @param javaProjectBuilder JavaProjectBuilder
* @param apiDocList list data of Api doc
* @param template template
* @param outPutFileName output file
* @param indexAlias index alias
*/
public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder, List<ApiDoc> apiDocList,
String template, String outPutFileName, String indexAlias) {
List<ApiDocDict> directoryList = DocUtil.buildDictionary(config, javaProjectBuilder);
List<ApiErrorCode> errorCodeList = errorCodeDictToList(config);
Template mapper = BeetlTemplateUtil.getByName(template);
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
mapper.binding(TemplateVariable.PROJECT_NAME.getVariable(), config.getProjectName());
String style = config.getStyle();
mapper.binding(TemplateVariable.HIGH_LIGHT_CSS_LINK.getVariable(), config.getHighlightStyleLink());
mapper.binding(TemplateVariable.STYLE.getVariable(), style);
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
// set css cdn
setCssCDN(config, mapper);
if (DocLanguage.CHINESE.equals(config.getLanguage())) {
mapper.binding(TemplateVariable.CSS_CND.getVariable(), CSS_CDN_CH);
} else {
mapper.binding(TemplateVariable.CSS_CND.getVariable(), CSS_CDN);
}
if (CollectionUtil.isNotEmpty(errorCodeList)) {
mapper.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 2);
} else {
mapper.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 1);
}
mapper.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
mapper.binding(TemplateVariable.VERSION.getVariable(), now);
mapper.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
mapper.binding(TemplateVariable.INDEX_ALIAS.getVariable(), indexAlias);
mapper.binding(TemplateVariable.BACKGROUND.getVariable(), HighlightStyle.getBackgroundColor(style));
mapper.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), errorCodeList);
setDirectoryLanguageVariable(config, mapper);
mapper.binding(TemplateVariable.DICT_LIST.getVariable(), directoryList);
mapper.binding(TemplateVariable.LIST.getVariable(), errorCodeList);
FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
}
@ -319,13 +149,9 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
* @param outPutFileName output file
*/
public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder, String template, String outPutFileName) {
List<ApiDocDict> directoryList = DocUtil.buildDictionary(config, javaProjectBuilder);
List<ApiDocDict> directoryList = buildDictionary(config, javaProjectBuilder);
Template mapper = BeetlTemplateUtil.getByName(template);
setDirectoryLanguageVariable(config, mapper);
// set css cdn
setCssCDN(config, mapper);
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
mapper.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
mapper.binding(TemplateVariable.DICT_LIST.getVariable(), directoryList);
FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
}
@ -342,7 +168,7 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
public void buildSingleApi(ProjectDocConfigBuilder projectBuilder, String controllerName, String template, String fileExtension) {
ApiConfig config = projectBuilder.getApiConfig();
FileUtil.mkdirs(config.getOutPath());
IDocBuildTemplate<ApiDoc> docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate<ApiDoc> docBuildTemplate = new SpringBootDocBuildTemplate();
ApiDoc doc = docBuildTemplate.getSingleApiData(projectBuilder, controllerName);
Template mapper = BeetlTemplateUtil.getByName(template);
mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
@ -351,13 +177,56 @@ public class DocBuilderTemplate extends BaseDocBuilderTemplate {
FileUtil.writeFileNotAppend(mapper.render(), config.getOutPath() + FILE_SEPARATOR + doc.getName() + fileExtension);
}
/**
* Build dictionary
*
* @param config api config
* @param javaProjectBuilder JavaProjectBuilder
* @return list of ApiDocDict
*/
public List<ApiDocDict> buildDictionary(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
List<ApiDataDictionary> apiDataDictionaryList = config.getDataDictionaries();
if (CollectionUtil.isEmpty(apiDataDictionaryList)) {
return new ArrayList<>(0);
}
List<ApiDocDict> apiDocDictList = new ArrayList<>();
try {
int order = 0;
for (ApiDataDictionary apiDataDictionary : apiDataDictionaryList) {
order++;
Class<?> clazz = apiDataDictionary.getEnumClass();
if (Objects.isNull(clazz)) {
if (StringUtil.isEmpty(apiDataDictionary.getEnumClassName())) {
throw new RuntimeException("Enum class name can't be null.");
}
clazz = Class.forName(apiDataDictionary.getEnumClassName());
}
ApiDocDict apiDocDict = new ApiDocDict();
apiDocDict.setOrder(order);
apiDocDict.setTitle(apiDataDictionary.getTitle());
JavaClass javaClass = javaProjectBuilder.getClassByName(clazz.getCanonicalName());
if (apiDataDictionary.getTitle() == null) {
apiDocDict.setTitle(javaClass.getComment());
}
List<DataDict> enumDictionaryList = EnumUtil.getEnumInformation(clazz, apiDataDictionary.getCodeField(),
apiDataDictionary.getDescField());
if (!clazz.isEnum()) {
throw new RuntimeException(clazz.getCanonicalName() + " is not an enum class.");
}
apiDocDict.setDataDictList(enumDictionaryList);
apiDocDictList.add(apiDocDict);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return apiDocDictList;
}
private List<ApiDoc> listOfApiData(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
this.checkAndInitForGetApiData(config);
config.setMd5EncryptedHtmlName(true);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
return docBuildTemplate.getApiData(configBuilder);
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,17 +22,27 @@
*/
package com.power.doc.builder;
import com.power.common.util.CollectionUtil;
import com.power.common.util.DateTimeUtil;
import com.power.common.util.FileUtil;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.DocLanguage;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.model.ApiDocDict;
import com.power.doc.model.ApiErrorCode;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.power.doc.utils.BeetlTemplateUtil;
import com.power.doc.utils.MarkDownUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.Template;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.power.doc.constants.DocGlobalConstants.*;
@ -42,11 +52,13 @@ import static com.power.doc.constants.DocGlobalConstants.*;
*/
public class HtmlApiDocBuilder {
private static final String ERROR_CODE_HTML = "error.html";
private static final String DICT_HTML = "dict.html";
private static long now = System.currentTimeMillis();
private static final String STR_TIME = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
private static String INDEX_HTML = "index.html";
/**
* build controller api
*
@ -65,76 +77,138 @@ public class HtmlApiDocBuilder {
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
config.setParamsDataToTree(false);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
Template indexCssTemplate = BeetlTemplateUtil.getByName(ALL_IN_ONE_CSS);
FileUtil.nioWriteFile(indexCssTemplate.render(), config.getOutPath() + FILE_SEPARATOR + ALL_IN_ONE_CSS_OUT);
builderTemplate.copyJarFile("js/" + HIGH_LIGHT_JS, config.getOutPath() + FILE_SEPARATOR + HIGH_LIGHT_JS);
builderTemplate.copyJarFile("css/" + FONT_STYLE, config.getOutPath() + FILE_SEPARATOR + FONT_STYLE);
builderTemplate.copyJarFile("js/" + JQUERY, config.getOutPath() + FILE_SEPARATOR + JQUERY);
builderTemplate.copyJarFile("css/" + HIGH_LIGHT_STYLE, config.getOutPath() + FILE_SEPARATOR + HIGH_LIGHT_STYLE);
if (config.isAllInOne()) {
apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
if (config.isCreateDebugPage()) {
INDEX_HTML = DEBUG_PAGE_ALL_TPL;
if (StringUtils.isNotEmpty(config.getAllInOneDocFileName())) {
INDEX_HTML = config.getAllInOneDocFileName();
}
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, DEBUG_PAGE_ALL_TPL, INDEX_HTML);
Template mockJs = BeetlTemplateUtil.getByName(DEBUG_JS_TPL);
FileUtil.nioWriteFile(mockJs.render(), config.getOutPath() + FILE_SEPARATOR + DEBUG_JS_OUT);
} else {
Template indexCssTemplate = BeetlTemplateUtil.getByName(ALL_IN_ONE_CSS);
FileUtil.nioWriteFile(indexCssTemplate.render(), config.getOutPath() + FILE_SEPARATOR + ALL_IN_ONE_CSS);
if (StringUtils.isNotEmpty(config.getAllInOneDocFileName())) {
INDEX_HTML = config.getAllInOneDocFileName();
}
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_HTML_TPL, INDEX_HTML);
}
builderTemplate.buildSearchJs(config, javaProjectBuilder, apiDocList, SEARCH_ALL_JS_TPL);
} else {
String indexAlias;
if (config.isCreateDebugPage()) {
indexAlias = "debug";
buildDoc(builderTemplate, apiDocList, config, javaProjectBuilder, DEBUG_PAGE_SINGLE_TPL, indexAlias);
Template mockJs = BeetlTemplateUtil.getByName(DEBUG_JS_TPL);
FileUtil.nioWriteFile(mockJs.render(), config.getOutPath() + FILE_SEPARATOR + DEBUG_JS_OUT);
} else {
indexAlias = "api";
buildDoc(builderTemplate, apiDocList, config, javaProjectBuilder, SINGLE_INDEX_HTML_TPL, indexAlias);
List<ApiDocDict> apiDocDictList = builderTemplate.buildDictionary(config, javaProjectBuilder);
buildIndex(apiDocList, config);
copyCss(config.getOutPath());
buildDoc(apiDocList, config);
buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath());
buildDictionary(apiDocDictList, config.getOutPath());
}
builderTemplate.buildErrorCodeDoc(config, javaProjectBuilder, apiDocList, SINGLE_ERROR_HTML_TPL,
ERROR_CODE_HTML, indexAlias);
builderTemplate.buildDirectoryDataDoc(config, javaProjectBuilder, apiDocList,
SINGLE_DICT_HTML_TPL, DICT_HTML, indexAlias);
builderTemplate.buildSearchJs(config, javaProjectBuilder, apiDocList, SEARCH_JS_TPL);
}
private static void copyCss(String outPath) {
Template indexCssTemplate = BeetlTemplateUtil.getByName(INDEX_CSS_TPL);
Template mdCssTemplate = BeetlTemplateUtil.getByName(MARKDOWN_CSS_TPL);
FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + INDEX_CSS_TPL);
FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + MARKDOWN_CSS_TPL);
}
/**
* build api.html
*
* @param apiDocList list of api doc
* @param config ApiConfig
*/
private static void buildIndex(List<ApiDoc> apiDocList, ApiConfig config) {
FileUtil.mkdirs(config.getOutPath());
Template indexTemplate = BeetlTemplateUtil.getByName(INDEX_TPL);
if (CollectionUtil.isEmpty(apiDocList)) {
return;
}
ApiDoc doc = apiDocList.get(0);
String homePage = doc.getAlias();
indexTemplate.binding(TemplateVariable.HOME_PAGE.getVariable(), homePage);
indexTemplate.binding(TemplateVariable.VERSION.getVariable(), now);
indexTemplate.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
indexTemplate.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), config.getErrorCodes());
indexTemplate.binding(TemplateVariable.DICT_LIST.getVariable(), config.getDataDictionaries());
if (CollectionUtil.isEmpty(config.getErrorCodes())) {
indexTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 1);
} else {
indexTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 2);
}
if (null != config.getLanguage()) {
if (DocLanguage.CHINESE.code.equals(config.getLanguage().getCode())) {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_CN_TITLE);
indexTemplate.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
} else {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_EN_TITLE);
indexTemplate.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_EN_TITLE);
}
} else {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_CN_TITLE);
indexTemplate.binding(TemplateVariable.DICT_LIST_TITLE.getVariable(), DocGlobalConstants.DICT_CN_TITLE);
}
FileUtil.nioWriteFile(indexTemplate.render(), config.getOutPath() + FILE_SEPARATOR + "api.html");
}
/**
* build ever controller api
*
* @param builderTemplate DocBuilderTemplate
* @param apiDocList list of api doc
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
* @param template template
* @param indexHtml indexHtml
*/
private static void buildDoc(DocBuilderTemplate builderTemplate, List<ApiDoc> apiDocList,
ApiConfig config, JavaProjectBuilder javaProjectBuilder,
String template, String indexHtml) {
private static void buildDoc(List<ApiDoc> apiDocList, ApiConfig config) {
FileUtil.mkdirs(config.getOutPath());
int index = 0;
Template htmlApiDoc;
for (ApiDoc doc : apiDocList) {
if (index == 0) {
doc.setAlias(indexHtml);
}
builderTemplate.buildDoc(apiDocList, config, javaProjectBuilder, template,
doc.getAlias() + ".html", doc, indexHtml);
index++;
Template apiTemplate = BeetlTemplateUtil.getByName(API_DOC_MD_TPL);
apiTemplate.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample());
apiTemplate.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample());
apiTemplate.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
apiTemplate.binding(TemplateVariable.NAME.getVariable(), doc.getName());
apiTemplate.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名
Map<String, Object> templateVariables = new HashMap<>();
templateVariables.put(TemplateVariable.TITLE.getVariable(), doc.getDesc());
htmlApiDoc = initTemplate(apiTemplate, HTML_API_DOC_TPL, templateVariables);
FileUtil.nioWriteFile(htmlApiDoc.render(), config.getOutPath() + FILE_SEPARATOR + doc.getAlias() + ".html");
}
}
/**
* build error_code html
*
* @param errorCodeList list of error code
* @param outPath
*/
private static void buildErrorCodeDoc(List<ApiErrorCode> errorCodeList, String outPath) {
if (CollectionUtil.isNotEmpty(errorCodeList)) {
Template errorTemplate = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_MD_TPL);
errorTemplate.binding(TemplateVariable.LIST.getVariable(), errorCodeList);
Map<String, Object> templateVariables = new HashMap<>();
templateVariables.put(TemplateVariable.TITLE.getVariable(), ERROR_CODE_LIST_EN_TITLE);
Template errorCodeDoc = initTemplate(errorTemplate, HTML_API_DOC_TPL, templateVariables);
FileUtil.nioWriteFile(errorCodeDoc.render(), outPath + FILE_SEPARATOR + "error_code.html");
}
}
/**
* build dictionary
*
* @param apiDocDictList dictionary list
* @param outPath
*/
private static void buildDictionary(List<ApiDocDict> apiDocDictList, String outPath) {
if (CollectionUtil.isNotEmpty(apiDocDictList)) {
Template template = BeetlTemplateUtil.getByName(DICT_LIST_MD_TPL);
template.binding(TemplateVariable.DICT_LIST.getVariable(), apiDocDictList);
Map<String, Object> templateVariables = new HashMap<>();
templateVariables.put(TemplateVariable.TITLE.getVariable(), DICT_EN_TITLE);
Template dictTpl = initTemplate(template, HTML_API_DOC_TPL, templateVariables);
FileUtil.nioWriteFile(dictTpl.render(), outPath + FILE_SEPARATOR + "dict.html");
}
}
private static Template initTemplate(Template template, String templateName, Map<String, Object> templateVariables) {
String errorHtml = MarkDownUtil.toHtml(template.render());
Template template1 = BeetlTemplateUtil.getByName(templateName);
template1.binding(TemplateVariable.VERSION.getVariable(), now);
template1.binding(TemplateVariable.HTML.getVariable(), errorHtml);
template1.binding(TemplateVariable.CREATE_TIME.getVariable(), STR_TIME);
template1.binding(templateVariables);
return template1;
}
}

View File

@ -1,37 +1,15 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.builder;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.power.common.util.CollectionUtil;
import com.power.common.util.FileUtil;
import com.power.common.util.StringUtil;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.Methods;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.*;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.power.doc.utils.DocUtil;
import com.power.doc.utils.JsonUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.*;
@ -41,17 +19,16 @@ import java.util.*;
*/
public class OpenApiBuilder {
//过滤url中的特殊字符
private static final String PATH_REGEX ="[/{};\\t+]";
/**
* Build OpenApi json
* 构建postman json
*
* @param config ApiConfig
* @param config 配置文件
*/
public static void buildOpenApi(ApiConfig config) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config, false);
builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
openApiCreate(config, configBuilder);
@ -61,27 +38,26 @@ public class OpenApiBuilder {
* Only for smart-doc maven plugin and gradle plugin.
*
* @param config ApiConfig Object
* @param projectBuilder QDOX JavaProjectBuilder
* @param projectBuilder QDOX avaProjectBuilder
*/
public static void buildOpenApi(ApiConfig config, JavaProjectBuilder projectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config, false);
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, projectBuilder);
openApiCreate(config, configBuilder);
}
/**
* Build OpenApi
*
* @param config ApiConfig
* 构建openApi 文件
* @param config 配置文件
* @param configBuilder
*/
private static void openApiCreate(ApiConfig config, ProjectDocConfigBuilder configBuilder) {
config.setParamsDataToTree(true);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
SpringBootDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
Map<String, Object> json = new HashMap<>(8);
json.put("openapi", "3.0.3");
json.put("openapi", "3.0.0");
json.put("info", buildInfo(config));
json.put("servers", buildServers(config));
json.put("paths", buildPaths(apiDocList));
@ -89,41 +65,39 @@ public class OpenApiBuilder {
String filePath = config.getOutPath();
filePath = filePath + DocGlobalConstants.OPEN_API_JSON;
String data = JsonUtil.toPrettyJson(json);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String data = gson.toJson(json);
FileUtil.nioWriteFile(data, filePath);
}
/**
* Build openapi info
*
* @param apiConfig ApiConfig
* info 信息
* @param apiConfig 文档配置信息
* @return
*/
private static Map<String, Object> buildInfo(ApiConfig apiConfig) {
Map<String, Object> infoMap = new HashMap<>(8);
infoMap.put("title", apiConfig.getProjectName() == null ? "Project Name is Null." : apiConfig.getProjectName());
infoMap.put("title", apiConfig.getProjectName() == null ? "未设置项目名称" : apiConfig.getProjectName());
infoMap.put("version", "1.0.0");
return infoMap;
}
/**
* Build Servers
*
* @param config ApiConfig
* server 信息
* @param config 文档配置信息
* @return
*/
private static List<Map<String, Object>> buildServers(ApiConfig config) {
List<Map<String, Object>> serverList = new ArrayList<>();
Map<String, Object> serverMap = new HashMap<>(8);
serverMap.put("url", config.getServerUrl() == null ? "" : config.getServerUrl());
serverMap.put("url", config.getServerUrl() == null ? "http://127.0.0.1" : config.getServerUrl());
serverList.add(serverMap);
return serverList;
}
/**
* Build openapi paths
*
* @param apiDocList List of api
* 构建path数据 url请求
* @param apiDocList api列表
* @return
*/
private static Map<String, Object> buildPaths(List<ApiDoc> apiDocList) {
@ -133,7 +107,7 @@ public class OpenApiBuilder {
List<ApiMethodDoc> apiMethodDocs = a.getList();
apiMethodDocs.forEach(
method -> {
//replace '//' to '/'
//设置paths的请求url 将双斜杠替换成单斜杠
String url = method.getPath().replace("//", "/");
Map<String, Object> request = buildPathUrls(method, a);
//pathMap.put(method.getPath().replace("//", "/"), buildPathUrls(method, a));
@ -149,12 +123,10 @@ public class OpenApiBuilder {
);
return pathMap;
}
/**
* Build path urls
*
* @param apiMethodDoc Method
* @param apiDoc ApiDoc
* paths 设置url请求方式
* @param apiMethodDoc 方法参数
* @param apiDoc 类参数
* @return
*/
private static Map<String, Object> buildPathUrls(ApiMethodDoc apiMethodDoc, ApiDoc apiDoc) {
@ -162,10 +134,8 @@ public class OpenApiBuilder {
request.put(apiMethodDoc.getType().toLowerCase(), buildPathUrlsRequest(apiMethodDoc, apiDoc));
return request;
}
/**
* url的基本信息 信息简介summary 详情description 所属分类tags 请求参数parameter 请求体request 返回值responses
*
* @param apiMethodDoc 方法参数
* @param apiDoc 类参数
* @return
@ -174,31 +144,30 @@ public class OpenApiBuilder {
Map<String, Object> request = new HashMap<>(20);
request.put("summary", apiMethodDoc.getDesc());
request.put("description", apiMethodDoc.getDetail());
if (StringUtil.isNotEmpty(apiMethodDoc.getGroup())) {
request.put("tags", new String[]{apiMethodDoc.getGroup()});
} else {
request.put("tags", new String[]{apiDoc.getDesc()});
}
request.put("requestBody", buildRequestBody(apiMethodDoc));
request.put("parameters", buildParameters(apiMethodDoc));
request.put("responses", buildResponses(apiMethodDoc));
request.put("deprecated", apiMethodDoc.isDeprecated());
request.put("operationId", apiMethodDoc.getMethodId());
return request;
}
/**
* Build request body
*
* @param apiMethodDoc ApiMethodDoc
* 请求体构建 只针对post请求 并且请求体不为null
* @param apiMethodDoc 方法参数
* @return
*/
private static Map<String, Object> buildRequestBody(ApiMethodDoc apiMethodDoc) {
int size = 0;
Map<String, Object> requestBody = new HashMap<>(8);
boolean isPost = (apiMethodDoc.getType().equals(Methods.POST.getValue())
|| apiMethodDoc.getType().equals(Methods.PUT.getValue()) ||
apiMethodDoc.getType().equals(Methods.PATCH.getValue()));
//add content of post method
//判断请求体去除pathVariable参数后是否为null
if(!CollectionUtil.isEmpty(apiMethodDoc.getRequestParams())) {
List<ApiParam> apiParams = apiMethodDoc.getRequestParams();
//去除pathVariable参数
size = (int) apiParams.stream()
.filter(apiParam -> !apiParam.isPathParam()).count();
}
boolean isPost = (apiMethodDoc.getType().equals(Methods.POST.getValue()) || apiMethodDoc.getType().equals(Methods.PUT.getValue()) ||
apiMethodDoc.getType().equals(Methods.PATCH.getValue())) && size > 0;
//如果是post请求 且包含请求体
if (isPost) {
requestBody.put("content", buildContent(apiMethodDoc, false));
return requestBody;
@ -206,114 +175,49 @@ public class OpenApiBuilder {
return null;
}
/**
* 构建content信息 responses requestBody 都需要content信息
*
* @param apiMethodDoc 方法参数
* @param isRep 是否是返回数据
* @return
*/
private static Map<String, Object> buildContent(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map<String, Object> content = new HashMap<>(8);
String contentType = apiMethodDoc.getContentType();
if (isRep) {
contentType = "*/*";
}
content.put(contentType, buildContentBody(apiMethodDoc, isRep));
content.put(apiMethodDoc.getContentType(), buildContentBody(apiMethodDoc, isRep));
return content;
}
/**
* 构建content的数据内容
*
* @param apiMethodDoc 方法参数
* @param isRep 是否是返回数据
* @return
*/
private static Map<String, Object> buildContentBody(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map<String, Object> content = new HashMap<>(8);
if (Objects.nonNull(apiMethodDoc.getReturnSchema()) && isRep) {
content.put("schema", apiMethodDoc.getReturnSchema());
} else {
if (!isRep && apiMethodDoc.getContentType().equals(DocGlobalConstants.MULTIPART_TYPE)) {
// formdata
Map<String, Object> map = new LinkedHashMap<>();
map.put("type", "object");
Map<String, Object> properties = new LinkedHashMap<>();
Map<String, Object> detail;
for (ApiParam apiParam : apiMethodDoc.getQueryParams()) {
detail = new HashMap<>();
detail.put("type", apiParam.getType());
detail.put("description", apiParam.getDesc());
detail.put("example", DocUtil.handleJsonStr(apiParam.getValue()));
if ("file".equals(apiParam.getType())) {
detail.remove("example");
if (apiParam.isHasItems()) {
detail.put("type", "array");
Map<String, Object> items = new HashMap<>();
items.put("type", "string");
items.put("format", "binary");
detail.put("items", items);
} else {
detail.put("format", "binary");
detail.put("type", "string");
}
}
properties.put(apiParam.getField(), detail);
}
map.put("properties", properties);
content.put("schema", map);
} else if (!isRep && Objects.nonNull(apiMethodDoc.getRequestSchema())) {
content.put("schema", apiMethodDoc.getRequestSchema());
} else {
content.put("schema", buildBodySchema(apiMethodDoc, isRep));
}
}
content.put("schema", buildBodySchema(apiMethodDoc.getPath(), isRep));
content.put("examples", buildBodyExample(apiMethodDoc, isRep));
return content;
}
/**
* content body 的schema 信息
*
* @param apiMethodDoc 请求方法参数 去除server
* @param url 请求的url 去除server
* @param isRep 是否是返回数据
* @return
*/
private static Map<String, Object> buildBodySchema(ApiMethodDoc apiMethodDoc, boolean isRep) {
private static Map<String, Object> buildBodySchema(String url, boolean isRep) {
Map<String, Object> schema = new HashMap<>(10);
//当类型为数组时使用
Map<String, Object> innerScheme = new HashMap<>(10);
//去除url中的特殊字符
String responseRef = "#/components/schemas/" + apiMethodDoc.getPath().replaceAll(PATH_REGEX, "_") + "response";
String requestRef = "#/components/schemas/" + apiMethodDoc.getPath().replaceAll(PATH_REGEX, "_") + "request";
//如果是数组类型
if (apiMethodDoc.isListParam()) {
schema.put("type", DocGlobalConstants.ARRAY);
if (isRep) {
innerScheme.put("$ref", responseRef);
schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "response");
} else {
innerScheme.put("$ref", requestRef);
schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "request");
}
schema.put("items", innerScheme);
} else {
if (isRep) {
schema.put("$ref", responseRef);
} else {
schema.put("$ref", requestRef);
}
}
return schema;
}
/**
* 信息样例 请求和返回的信息样例
*
* @param apiMethodDoc 方法参数
* @param isRep 是否是返回数据
* @return
@ -324,10 +228,8 @@ public class OpenApiBuilder {
return content;
}
/**
* 信息样例数据构建 此处请求体requestBody构建完成
*
* @param apiMethodDoc 方法参数
* @param isRep 是否为返回数据
* @return
@ -348,40 +250,38 @@ public class OpenApiBuilder {
/**
* 构建请求参数 用于get请求 @PathVariable Header 参数构建
*
* @param apiMethodDoc 方法体
* @return
*/
private static List<Map<String, Object>> buildParameters(ApiMethodDoc apiMethodDoc) {
Map<String, Object> parameters;
List<Map<String, Object>> parametersList = new ArrayList<>();
for (ApiParam apiParam : apiMethodDoc.getPathParams()) {
parameters = getStringParams(apiParam);
//如果是get请求 包含@pathvariable
if (apiMethodDoc.getType().equals(Methods.GET.getValue()) || apiMethodDoc.getPath().contains("{")) {
if (apiMethodDoc.getRequestParams() == null) {
return null;
}
for (ApiParam apiParam : apiMethodDoc.getRequestParams()) {
parameters = new HashMap<>(20);
parameters.put("name", apiParam.getField());
parameters.put("description", apiParam.getDesc());
parameters.put("required", apiParam.isRequired());
parameters.put("schema", buildParametersSchema(apiParam));
if (apiParam.isPathParam()) {
parameters.put("in", "path");
List<ApiParam> children = apiParam.getChildren();
if (CollectionUtil.isEmpty(children)) {
parametersList.add(parameters);
}
}
// not handle form data
if (!apiMethodDoc.getContentType().equals(DocGlobalConstants.MULTIPART_TYPE)) {
for (ApiParam apiParam : apiMethodDoc.getQueryParams()) {
parameters = getStringParams(apiParam);
} else {
parameters.put("in", "query");
List<ApiParam> children = apiParam.getChildren();
if (CollectionUtil.isEmpty(children)) {
parametersList.add(parameters);
}
parametersList.add(parameters);
}
}
//如果包含请求头
if (!CollectionUtil.isEmpty(apiMethodDoc.getRequestHeaders())) {
for (ApiReqParam header : apiMethodDoc.getRequestHeaders()) {
for (ApiReqHeader header : apiMethodDoc.getRequestHeaders()) {
parameters = new HashMap<>(20);
parameters.put("name", header.getName());
parameters.put("description", header.getDesc());
parameters.put("required", header.isRequired());
parameters.put("example", header.getValue());
parameters.put("schema", buildParametersSchema(header));
parameters.put("in", "header");
parametersList.add(parameters);
@ -389,21 +289,8 @@ public class OpenApiBuilder {
}
return parametersList;
}
private static Map<String, Object> getStringParams(ApiParam apiParam) {
Map<String, Object> parameters;
parameters = new HashMap<>(20);
parameters.put("name", apiParam.getField());
parameters.put("description", apiParam.getDesc());
parameters.put("required", apiParam.isRequired());
parameters.put("example", StringUtil.removeQuotes(apiParam.getValue()));
parameters.put("schema", buildParametersSchema(apiParam));
return parameters;
}
/**
* 如果是get请求或者是@PathVariable 设置请求参数
*
* @param apiParam 参数信息
* @return
*/
@ -414,36 +301,27 @@ public class OpenApiBuilder {
if ("object".equals(openApiType) || "string".equals(openApiType)) {
if ("file".equals(apiParam.getType())) {
schema.put("format", "binary");
} else if ("enum".equals(apiParam.getType())) {
schema.put("enum", apiParam.getEnumValues());
}else if("array".equals(apiParam.getType())) {
schema.put("type","array");
schema.put("items",new HashMap<>());
}
} else {
schema.put("format", "int16".equals(apiParam.getType())?"int32":apiParam.getType());
}
return schema;
}
/**
* 如果包含header 设置请求参数
*
* @param header 参数信息
* @return
*/
private static Map<String, Object> buildParametersSchema(ApiReqParam header) {
private static Map<String, Object> buildParametersSchema(ApiReqHeader header) {
Map<String, Object> schema = new HashMap<>(10);
String openApiType = DocUtil.javaTypeToOpenApiTypeConvert(header.getType());
schema.put("type", openApiType);
schema.put("format", "int16".equals(header.getType())?"int32":header.getType());
return schema;
}
/**
* build response
*
* @param apiMethodDoc ApiMethodDoc
* 构建返回信息
* @param apiMethodDoc 方法参数
* @return
*/
private static Map<String, Object> buildResponses(ApiMethodDoc apiMethodDoc) {
@ -451,24 +329,23 @@ public class OpenApiBuilder {
response.put("200", buildResponsesBody(apiMethodDoc));
return response;
}
/**
* response body
*
* @param apiMethodDoc ApiMethodDoc
* 构建返回信息实体
* @param apiMethodDoc 方法参数
* @return
*/
private static Map<String, Object> buildResponsesBody(ApiMethodDoc apiMethodDoc) {
Map<String, Object> responseBody = new HashMap<>(10);
responseBody.put("description", "OK");
responseBody.put("description", "a pet to be returned");
if (!CollectionUtil.isEmpty(apiMethodDoc.getResponseParams())) {
responseBody.put("content", buildContent(apiMethodDoc, true));
}
return responseBody;
}
/**
* component schema
*
* @param apiDocs List of ApiDoc
* 构建component
* @param apiDocs 请求列表
* @return
*/
private static Map<String, Object> buildComponentsSchema(List<ApiDoc> apiDocs) {
@ -481,14 +358,7 @@ public class OpenApiBuilder {
method -> {
//request components
List<ApiParam> requestParams = method.getRequestParams();
if (CollectionUtil.isNotEmpty(requestParams)) {
Map<String, Object> prop = buildProperties(requestParams);
if (Objects.nonNull(prop) && prop.size() > 0) {
component.put(method.getPath().replaceAll(PATH_REGEX, "_") + "request", buildProperties(requestParams));
}
} else {
component.put(method.getPath().replaceAll(PATH_REGEX, "_") + "request", new HashMap<>(0));
}
//response components
List<ApiParam> responseParams = method.getResponseParams();
component.put(method.getPath().replaceAll(PATH_REGEX, "_") + "response", buildProperties(responseParams));
@ -501,33 +371,25 @@ public class OpenApiBuilder {
}
/**
* component schema properties
*
* @param apiParam list of ApiParam
* component schema properties 信息
* @param apiParam 参数列表
* @return
*/
private static Map<String, Object> buildProperties(List<ApiParam> apiParam) {
Map<String, Object> component = new HashMap<>();
Map<String, Object> propertiesData = new LinkedHashMap<>();
Map<String, Object> propertiesData = new HashMap<>();
List<String> requiredList = new ArrayList<>();
if (apiParam != null) {
int paramsSize = apiParam.size();
for (ApiParam param : apiParam) {
if (param.isRequired()) {
requiredList.add(param.getField());
}
if (param.getType().equals("map") && paramsSize == 1) {
continue;
}
if (param.isQueryParam() || param.isPathParam()) {
continue;
}
String field = param.getField();
propertiesData.put(field, buildPropertiesData(param));
}
if (!propertiesData.isEmpty()) {
component.put("properties", propertiesData);
}
if (!CollectionUtil.isEmpty(requiredList)) {
component.put("required", requiredList);
}
@ -537,11 +399,9 @@ public class OpenApiBuilder {
}
}
/**
* component schema properties data
*
* @param apiParam ApiParam
* component schema properties 实体信息构建
* @param apiParam 参数基本信息
* @return
*/
private static Map<String, Object> buildPropertiesData(ApiParam apiParam) {

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,29 +22,28 @@
*/
package com.power.doc.builder;
import com.power.common.util.CollectionUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.power.common.util.FileUtil;
import com.power.common.util.StringUtil;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.*;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.model.ApiMethodDoc;
import com.power.doc.model.ApiReqHeader;
import com.power.doc.model.postman.InfoBean;
import com.power.doc.model.postman.ItemBean;
import com.power.doc.model.postman.RequestItem;
import com.power.doc.model.postman.UrlBean;
import com.power.doc.model.postman.request.ParamBean;
import com.power.doc.model.postman.request.RequestBean;
import com.power.doc.model.postman.request.body.BodyBean;
import com.power.doc.model.postman.request.header.HeaderBean;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.utils.DocPathUtil;
import com.power.doc.utils.JsonUtil;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
@ -55,13 +54,13 @@ public class PostmanJsonBuilder {
private static final String MSG = "Interface name is not set.";
/**
* build postman json
* 构建postman json
*
* @param config Smart-doc ApiConfig
* @param config 配置文件
*/
public static void buildPostmanCollection(ApiConfig config) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
postManCreate(config, configBuilder);
@ -75,17 +74,17 @@ public class PostmanJsonBuilder {
*/
public static void buildPostmanCollection(ApiConfig config, JavaProjectBuilder projectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,false);
builderTemplate.checkAndInit(config);
config.setParamsDataToTree(false);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, projectBuilder);
postManCreate(config, configBuilder);
}
/**
* Build the first layer of Postman Item
* 第一层的Item
*
* @param apiDoc Documentation for each Controller
* @return First layer of Postman Item
* @param apiDoc
* @return
*/
private static ItemBean buildItemBean(ApiDoc apiDoc) {
ItemBean itemBean = new ItemBean();
@ -103,10 +102,10 @@ public class PostmanJsonBuilder {
}
/**
* Build the second layer of Postman item
* 构建第二层的item
*
* @param apiMethodDoc Documentation for each method
* @return The second layer of Postman item
* @param apiMethodDoc
* @return
*/
private static ItemBean buildItem(ApiMethodDoc apiMethodDoc) {
ItemBean item = new ItemBean();
@ -120,73 +119,29 @@ public class PostmanJsonBuilder {
requestBean.setHeader(buildHeaderBeanList(apiMethodDoc));
requestBean.setBody(buildBodyBean(apiMethodDoc));
requestBean.setUrl(buildUrlBean(apiMethodDoc));
requestBean.setUrl(apiMethodDoc.getRequestExample().getUrl() == null ? apiMethodDoc.getUrl() : apiMethodDoc.getRequestExample().getUrl());
item.setRequest(requestBean);
return item;
}
private static UrlBean buildUrlBean(ApiMethodDoc apiMethodDoc) {
UrlBean urlBean = new UrlBean(apiMethodDoc.getServerUrl());
String url = Optional.ofNullable(apiMethodDoc.getRequestExample().getUrl()).orElse(apiMethodDoc.getUrl());
urlBean.setRaw(DocPathUtil.toPostmanPath(url));
String shortUrl = DocPathUtil.toPostmanPath(apiMethodDoc.getPath());
String[] paths = shortUrl.split("/");
List<String> pathList = new ArrayList<>();
String serverPath = CollectionUtil.isNotEmpty(urlBean.getPath()) ? urlBean.getPath().get(0) : "";
// Add server path
if (CollectionUtil.isNotEmpty(urlBean.getPath()) && !shortUrl.contains(serverPath)) {
String[] serverPaths = serverPath.split("/");
pathList.addAll(Arrays.asList(serverPaths));
}
// Add mapping path
for (String str : paths) {
if (StringUtil.isNotEmpty(str)) {
pathList.add(str);
}
}
if (shortUrl.endsWith("/")) {
pathList.add("");
}
urlBean.setPath(pathList);
List<ParamBean> queryParams = new ArrayList<>();
for (ApiParam apiParam : apiMethodDoc.getQueryParams()) {
ParamBean queryParam = new ParamBean();
queryParam.setDescription(apiParam.getDesc());
queryParam.setKey(apiParam.getField());
queryParam.setValue(apiParam.getValue());
queryParams.add(queryParam);
}
List<ParamBean> variables = new ArrayList<>();
for (ApiParam apiParam : apiMethodDoc.getPathParams()) {
ParamBean queryParam = new ParamBean();
queryParam.setDescription(apiParam.getDesc());
queryParam.setKey(apiParam.getField());
queryParam.setValue(apiParam.getValue());
variables.add(queryParam);
}
urlBean.setVariable(variables);
urlBean.setQuery(queryParams);
return urlBean;
}
/**
* Build payload
* 构造请求体
*
* @return Body payload
* @param apiMethodDoc
* @return
*/
private static BodyBean buildBodyBean(ApiMethodDoc apiMethodDoc) {
BodyBean bodyBean;
if (apiMethodDoc.getContentType().contains(DocGlobalConstants.JSON_CONTENT_TYPE)) {
bodyBean = new BodyBean(Boolean.FALSE);// Json request
bodyBean = new BodyBean(false);
bodyBean.setMode(DocGlobalConstants.POSTMAN_MODE_RAW);
if (apiMethodDoc.getRequestExample() != null) {
bodyBean.setRaw(apiMethodDoc.getRequestExample().getJsonBody());
}
} else {
bodyBean = new BodyBean(Boolean.TRUE); //Formdata
bodyBean = new BodyBean(true);
bodyBean.setMode(DocGlobalConstants.POSTMAN_MODE_FORMDATA);
bodyBean.setFormdata(apiMethodDoc.getRequestExample().getFormDataList());
}
@ -195,13 +150,15 @@ public class PostmanJsonBuilder {
}
/**
* Build header
* 构造请求头
*
* @return List of header
* @param apiMethodDoc
* @return
*/
private static List<HeaderBean> buildHeaderBeanList(ApiMethodDoc apiMethodDoc) {
List<HeaderBean> headerBeans = new ArrayList<>();
List<ApiReqParam> headers = apiMethodDoc.getRequestHeaders();
List<ApiReqHeader> headers = apiMethodDoc.getRequestHeaders();
headers.forEach(
apiReqHeader -> {
HeaderBean headerBean = new HeaderBean();
@ -218,7 +175,7 @@ public class PostmanJsonBuilder {
}
private static void postManCreate(ApiConfig config, ProjectDocConfigBuilder configBuilder) {
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
RequestItem requestItem = new RequestItem();
requestItem.setInfo(new InfoBean(config.getProjectName()));
@ -232,7 +189,8 @@ public class PostmanJsonBuilder {
requestItem.setItem(itemBeans);
String filePath = config.getOutPath();
filePath = filePath + DocGlobalConstants.POSTMAN_JSON;
String data = JsonUtil.toPrettyJson(requestItem);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String data = gson.toJson(requestItem);
FileUtil.nioWriteFile(data, filePath);
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -35,7 +35,6 @@ import com.thoughtworks.qdox.model.JavaClass;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import static com.power.doc.constants.DocGlobalConstants.DEFAULT_SERVER_URL;
@ -44,15 +43,11 @@ import static com.power.doc.constants.DocGlobalConstants.DEFAULT_SERVER_URL;
*/
public class ProjectDocConfigBuilder {
private static Logger log = Logger.getLogger(ProjectDocConfigBuilder.class.getName());
private JavaProjectBuilder javaProjectBuilder;
private Map<String, JavaClass> classFilesMap = new ConcurrentHashMap<>();
private Map<String, CustomField> customRespFieldMap = new ConcurrentHashMap<>();
private Map<String, CustomField> customReqFieldMap = new ConcurrentHashMap<>();
private Map<String, CustomRespField> customRespFieldMap = new ConcurrentHashMap<>();
private Map<String, String> replaceClassMap = new ConcurrentHashMap<>();
@ -80,23 +75,17 @@ public class ProjectDocConfigBuilder {
this.setHighlightStyle();
javaProjectBuilder.setEncoding(Charset.DEFAULT_CHARSET);
this.javaProjectBuilder = javaProjectBuilder;
try {
this.loadJavaSource(apiConfig.getSourceCodePaths(), this.javaProjectBuilder);
} catch (Exception e) {
log.warning(e.getMessage());
}
this.initClassFilesMap();
this.initCustomResponseFieldsMap(apiConfig);
this.initCustomRequestFieldsMap(apiConfig);
this.initReplaceClassMap(apiConfig);
this.initConstants(apiConfig);
this.checkBodyAdvice(apiConfig.getRequestBodyAdvice());
this.checkBodyAdvice(apiConfig.getResponseBodyAdvice());
this.checkResponseBodyAdvice(apiConfig);
}
public JavaClass getClassByName(String simpleName) {
JavaClass cls = javaProjectBuilder.getClassByName(simpleName);
List<DocJavaField> fieldList = JavaClassUtil.getFields(cls, 0, new LinkedHashMap<>());
List<DocJavaField> fieldList = JavaClassUtil.getFields(cls, 0, new HashSet<>());
// handle inner class
if (Objects.isNull(cls.getFields()) || fieldList.isEmpty()) {
cls = classFilesMap.get(simpleName);
@ -135,16 +124,8 @@ public class ProjectDocConfigBuilder {
private void initCustomResponseFieldsMap(ApiConfig config) {
if (CollectionUtil.isNotEmpty(config.getCustomResponseFields())) {
for (CustomField field : config.getCustomResponseFields()) {
customRespFieldMap.put(field.getOwnerClassName() + "." + field.getName(), field);
}
}
}
private void initCustomRequestFieldsMap(ApiConfig config) {
if (CollectionUtil.isNotEmpty(config.getCustomRequestFields())) {
for (CustomField field : config.getCustomRequestFields()) {
customReqFieldMap.put(field.getOwnerClassName() + "." + field.getName(), field);
for (CustomRespField field : config.getCustomResponseFields()) {
customRespFieldMap.put(field.getName(), field);
}
}
}
@ -180,54 +161,43 @@ public class ProjectDocConfigBuilder {
}
}
private void checkBodyAdvice(BodyAdvice bodyAdvice) {
if (Objects.nonNull(bodyAdvice) && StringUtil.isNotEmpty(bodyAdvice.getClassName())) {
if (Objects.nonNull(bodyAdvice.getWrapperClass())) {
return;
}
private void checkResponseBodyAdvice(ApiConfig config) {
ResponseBodyAdvice responseBodyAdvice = config.getResponseBodyAdvice();
if (Objects.nonNull(responseBodyAdvice) && StringUtil.isNotEmpty(responseBodyAdvice.getClassName())) {
try {
Class.forName(bodyAdvice.getClassName());
Class.forName(responseBodyAdvice.getClassName());
} catch (ClassNotFoundException e) {
throw new RuntimeException("Can't find class " + bodyAdvice.getClassName() + " for ResponseBodyAdvice.");
throw new RuntimeException("Can't find class " + responseBodyAdvice.getClassName() + " for ResponseBodyAdvice.");
}
}
}
/**
* 设置高亮样式
*/
private void setHighlightStyle() {
String style = apiConfig.getStyle();
if (DocGlobalConstants.HIGH_LIGHT_DEFAULT_STYLE.equals(style)) {
// use local css file
apiConfig.setHighlightStyleLink(DocGlobalConstants.HIGH_LIGHT_CSS_DEFAULT);
return;
}
if (HighlightStyle.containsStyle(style)) {
apiConfig.setHighlightStyleLink(String.format(DocGlobalConstants.HIGH_LIGHT_CSS_URL_FORMAT, style));
return;
}
Random random = new Random();
if (DocGlobalConstants.HIGH_LIGHT_CSS_RANDOM_LIGHT.equals(style)) {
if ("randomLight".equals(style)) {
// Eliminate styles that do not match the template
style = HighlightStyle.randomLight(random);
if(HighlightStyle.containsStyle(style)){
apiConfig.setStyle(style);
apiConfig.setHighlightStyleLink(String.format(DocGlobalConstants.HIGH_LIGHT_CSS_URL_FORMAT, style));
} else {
apiConfig.setStyle(null);
apiConfig.setStyle("null");
}
} else if (DocGlobalConstants.HIGH_LIGHT_CSS_RANDOM_DARK.equals(style)) {
style = HighlightStyle.randomDark(random);
if (DocGlobalConstants.HIGH_LIGHT_DEFAULT_STYLE.equals(style)) {
apiConfig.setHighlightStyleLink(DocGlobalConstants.HIGH_LIGHT_CSS_DEFAULT);
} else {
apiConfig.setHighlightStyleLink(String.format(DocGlobalConstants.HIGH_LIGHT_CSS_URL_FORMAT, style));
}
apiConfig.setStyle(style);
} else if ("randomDark".equals(style)) {
apiConfig.setStyle(HighlightStyle.randomDark(random));
} else {
// Eliminate styles that do not match the template
apiConfig.setStyle(null);
apiConfig.setStyle("null");
}
}
}
}
public JavaProjectBuilder getJavaProjectBuilder() {
return javaProjectBuilder;
}
@ -237,14 +207,10 @@ public class ProjectDocConfigBuilder {
return classFilesMap;
}
public Map<String, CustomField> getCustomRespFieldMap() {
public Map<String, CustomRespField> getCustomRespFieldMap() {
return customRespFieldMap;
}
public Map<String, CustomField> getCustomReqFieldMap() {
return customReqFieldMap;
}
public String getServerUrl() {
return serverUrl;
}

View File

@ -1,143 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.builder;
import com.google.gson.Gson;
import com.power.common.util.CollectionUtil;
import com.power.common.util.OkHttp3Util;
import com.power.common.util.StringUtil;
import com.power.doc.constants.TornaConstants;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.model.torna.Apis;
import com.power.doc.model.torna.TornaApi;
import com.power.doc.model.torna.TornaDic;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.utils.DocUtil;
import com.power.doc.utils.TornaUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.power.doc.constants.TornaConstants.ENUM_PUSH;
import static com.power.doc.constants.TornaConstants.PUSH;
import static com.power.doc.utils.TornaUtil.buildApis;
import static com.power.doc.utils.TornaUtil.buildErrorCode;
/**
* @author xingzi 2021/2/2 18:05
**/
public class TornaBuilder {
/**
* build controller api
*
* @param config config
*/
public static void buildApiDoc(ApiConfig config) {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
buildApiDoc(config, javaProjectBuilder);
}
/**
* Only for smart-doc maven plugin and gradle plugin.
*
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
config.setParamsDataToTree(true);
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config,true);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
buildTorna(apiDocList, config, javaProjectBuilder);
}
/**
* build torna Data
*
* @param apiDocs apiData
* @param apiConfig ApiConfig
* @param builder JavaProjectBuilder
*/
public static void buildTorna(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
TornaApi tornaApi = new TornaApi();
tornaApi.setAuthor(StringUtil.isEmpty(apiConfig.getAuthor()) ? System.getProperty("user.name") : apiConfig.getAuthor());
tornaApi.setIsReplace((apiConfig.getReplace() == null || apiConfig.getReplace()) ? 1 : 0);
Apis api;
List<Apis> groupApiList = new ArrayList<>();
//Convert ApiDoc to Apis
for (ApiDoc groupApi : apiDocs) {
List<Apis> apisList = new ArrayList<>();
List<ApiDoc> childrenApiDocs = groupApi.getChildrenApiDocs();
for (ApiDoc a : childrenApiDocs) {
api = new Apis();
api.setName(StringUtils.isBlank(a.getDesc()) ? a.getName() : a.getDesc());
api.setItems(buildApis(a.getList(), TornaUtil.setDebugEnv(apiConfig, tornaApi)));
api.setIsFolder(TornaConstants.YES);
api.setAuthor(a.getAuthor());
api.setOrderIndex(a.getOrder());
apisList.add(api);
}
api = new Apis();
api.setName(StringUtils.isBlank(groupApi.getDesc()) ? groupApi.getName() : groupApi.getDesc());
api.setAuthor(tornaApi.getAuthor());
api.setOrderIndex(groupApi.getOrder());
api.setIsFolder(TornaConstants.YES);
api.setItems(apisList);
groupApiList.add(api);
}
tornaApi.setCommonErrorCodes(buildErrorCode(apiConfig));
// delete default group when only default group
tornaApi.setApis(groupApiList.size() == 1 ? groupApiList.get(0).getItems() : groupApiList);
//Build push document information
Map<String, String> requestJson = TornaConstants.buildParams(PUSH, new Gson().toJson(tornaApi), apiConfig);
//Push dictionary information
Map<String, Object> dicMap = new HashMap<>(2);
List<TornaDic> docDicts = TornaUtil.buildTornaDic(DocUtil.buildDictionary(apiConfig, builder));
if (CollectionUtil.isNotEmpty(docDicts)) {
dicMap.put("enums", docDicts);
Map<String, String> dicRequestJson = TornaConstants.buildParams(ENUM_PUSH, new Gson().toJson(dicMap), apiConfig);
String dicResponseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(dicRequestJson));
TornaUtil.printDebugInfo(apiConfig, dicResponseMsg, dicRequestJson, ENUM_PUSH);
}
//Get the response result
String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(requestJson));
//Print the log of pushing documents to Torna
TornaUtil.printDebugInfo(apiConfig, responseMsg, requestJson, PUSH);
}
}

View File

@ -0,0 +1,264 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2019-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.builder;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.power.common.util.FileUtil;
import com.power.common.util.StringUtil;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.model.ApiParam;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.power.doc.utils.BeetlTemplateUtil;
import com.power.doc.utils.Iterables;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.beetl.core.Template;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.power.doc.constants.DocGlobalConstants.YAPI_RESULT_TPL;
/**
* generate yapi's yapi json
*
* @author dai19470 2020/08/20.
*/
public class YapiJsonBuilder {
/**
* 构建yapi json
*
* @param config 配置文件
*/
public static void buildYapiCollection(ApiConfig config) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
yapiJsonCreate(config, configBuilder);
}
/**
* Only for smart-doc maven plugin and gradle plugin.
*
* @param config ApiConfig Object
* @param projectBuilder QDOX avaProjectBuilder
*/
public static void buildYapiCollection(ApiConfig config, JavaProjectBuilder projectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, projectBuilder);
yapiJsonCreate(config, configBuilder);
}
private static Set<String> getUrl(String url, String patter) {
Pattern pattern = Pattern.compile(patter);
Matcher matcher = pattern.matcher(url);
Set<String> result = new HashSet<>();
while (matcher.find()) {
result.add(matcher.group());
}
return result;
}
private static void yapiJsonCreate(ApiConfig config, ProjectDocConfigBuilder configBuilder) {
config.setParamsDataToTree(true);
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
List<Map<String, Object>> requestItem = new ArrayList<>();
Iterables.forEach(apiDocList, (index, apiDoc) -> {
Map<String, Object> module = new HashMap<>();
module.put("index", index);
module.put("name", apiDoc.getDesc());
module.put("parent_id", -1);
module.put("desc", apiDoc.getDesc());
module.put("add_time", System.currentTimeMillis() / 1000);
module.put("up_time", System.currentTimeMillis() / 1000);
List<Map<String, Object>> methods = new ArrayList();
Iterables.forEach(apiDoc.getList(), (idx, apiMethodDoc) -> {
Map<String, Object> method = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("path", apiMethodDoc.getPath());
map.put("params", new Object[]{});
method.put("query_path", map);
// method.put("owners",new String[]{apiMethodDoc.getAuthor()});
method.put("owners", new String[]{});
method.put("edit_uid", 0);
method.put("status", "done");
method.put("type", "static");
method.put("req_body_is_json_schema", true);
method.put("res_body_is_json_schema", true);
method.put("api_opened", false);
method.put("index", idx);
method.put("tag", new Object[]{});
method.put("method", apiMethodDoc.getType());
method.put("title", apiMethodDoc.getDesc());
method.put("desc", apiMethodDoc.getDetail());
method.put("name", apiMethodDoc.getName());
method.put("path", apiMethodDoc.getPath().replace("//", "/"));
method.put("req_body_form", Arrays.asList());
List<Map<String, Object>> req_params = new ArrayList();
Set<String> req_param = getUrl(apiMethodDoc.getPath(), "(?<=\\{)(.+?)(?=\\})");
Iterables.forEach(req_param, (j, param) -> {
ApiParam temp = apiMethodDoc.getRequestParams().stream().filter(apiParam -> apiParam.getField().equals(param)).findFirst().orElse(null);
if (temp != null) {
Map<String, Object> h = new HashMap<>();
h.put("example", "");
h.put("name", temp.getField());
h.put("type", temp.getType());
h.put("desc", temp.getDesc());
req_params.add(j, h);
}
});
method.put("req_params", req_params);
method.put("res_body_type", "json");
List<Map<String, Object>> querys = new ArrayList();
Iterables.forEach(apiMethodDoc.getRequestParams(), (j, res) -> {
Map<String, Object> h = new HashMap<>();
h.put("required", res.isRequired() ? "1" : "0");
h.put("desc", res.getDesc());
h.put("name", res.getField());
h.put("example", "");
h.put("type", res.getType());
querys.add(j, h);
});
method.put("req_query", querys);
List<Map<String, Object>> headers = new ArrayList();
Iterables.forEach(apiMethodDoc.getRequestHeaders(), (j, res) -> {
Map<String, Object> h = new HashMap<>();
h.put("required", res.isRequired() ? "1" : "0");
h.put("value", res.getValue());
h.put("name", res.getName());
h.put("desc", res.getDesc());
headers.add(j, h);
});
method.put("req_headers", headers);
Template apiTemplate = BeetlTemplateUtil.getByName(YAPI_RESULT_TPL);
apiTemplate.binding(TemplateVariable.RESPONSE_LIST.getVariable(), generateJson(apiMethodDoc.getResponseParams()));
String json = apiTemplate.render();
method.put("res_body", json);
if (StringUtil.isNotEmpty(apiMethodDoc.getResponseUsage())) {
method.put("desc", "<pre><code>\n" + apiMethodDoc.getResponseUsage() + "\n</code></pre>\n");
}
methods.add(idx, method);
});
module.put("list", methods);
requestItem.add(module);
});
String filePath = config.getOutPath();
filePath = filePath + DocGlobalConstants.YAPI_JSON;
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String data = gson.toJson(requestItem);
FileUtil.nioWriteFile(data, filePath);
}
private static String generateJson(List<ApiParam> responseParams) {
StringBuffer re = new StringBuffer("\"type\":\"object\",\n\"properties\":{\n");
HashSet<String> required = new HashSet<>();
responseParams.stream().forEach(apiParam -> {
re.append(getTypeAndPropertiesJson(apiParam));
if (apiParam.isRequired()) {
required.add(apiParam.getField());
}
});
Gson gs = new Gson();
re.append("\"required\":\"" + gs.toJson(required.toArray()) + "\"");
re.append("\t}");
return re.toString();
}
/**
* 将字段类型转换为yapi的字段类型
*
* @param type java type
* @return String
*/
private static String changeType(String type) {
switch (type) {
case "boolean":
return "boolean";
case "int32":
return "integer";
case "int64":
return "number";
default:
return type;
}
}
/**
* 单个参数拼接字符串
*
* @param param ApiParam
* @return String
*/
private static String getTypeAndPropertiesJson(ApiParam param) {
StringBuffer resultJson = new StringBuffer();
resultJson.append("\"" + param.getField() + "\":{");
resultJson.append("\"type\":\"" + changeType(param.getType()) + "\", ");
if (param.getChildren() != null && param.getChildren().size() > 0) {
if (param.getType().equals("object")) {
resultJson.append(" \"properties\":{");
param.getChildren().forEach(child -> {
resultJson.append(getTypeAndPropertiesJson(child));
});
} else if (param.getType().equals("array")) {
resultJson.append(" \"items\":{");
resultJson.append("\"type\":\"object\",\n\"properties\":{\n");
param.getChildren().forEach(child -> {
resultJson.append(getTypeAndPropertiesJson(child));
});
resultJson.append("\t},");
}
resultJson.append("},");
}
resultJson.append("},");
return resultJson.toString();
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -23,11 +23,9 @@
package com.power.doc.builder.rpc;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.rpc.RpcApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.RpcDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.List;
@ -60,17 +58,15 @@ public class RpcAdocBuilder {
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
config.setFramework(FrameworkEnum.DUBBO.getFramework());
config.setAdoc(true);
config.setShowJavaType(true);
RpcDocBuilderTemplate builderTemplate = new RpcDocBuilderTemplate();
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
RpcDocBuildTemplate docBuildTemplate = new RpcDocBuildTemplate();
List<RpcApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (config.isAllInOne()) {
String docName = builderTemplate.allInOneDocName(config, INDEX_DOC, ".adoc");
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_ADOC_TPL, docName);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_ADOC_TPL, INDEX_DOC);
} else {
builderTemplate.buildApiDoc(apiDocList, config, RPC_API_DOC_ADOC_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_ADOC_TPL, ERROR_CODE_LIST_ADOC);

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,8 +22,6 @@
*/
package com.power.doc.builder.rpc;
import com.power.common.util.StringUtil;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.rpc.RpcApiAllData;
import com.thoughtworks.qdox.JavaProjectBuilder;
@ -41,9 +39,6 @@ public class RpcApiDataBuilder {
*/
public static RpcApiAllData getApiData(ApiConfig config) {
config.setShowJavaType(true);
if (StringUtil.isEmpty(config.getFramework())) {
config.setFramework(FrameworkEnum.DUBBO.getFramework());
}
RpcDocBuilderTemplate builderTemplate = new RpcDocBuilderTemplate();
builderTemplate.checkAndInitForGetApiData(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,49 +22,34 @@
*/
package com.power.doc.builder.rpc;
import com.power.common.util.CollectionUtil;
import com.power.common.util.DateTimeUtil;
import com.power.common.util.FileUtil;
import com.power.common.util.StringUtil;
import com.power.doc.builder.BaseDocBuilderTemplate;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiErrorCode;
import com.power.doc.model.rpc.RpcApiAllData;
import com.power.doc.model.rpc.RpcApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.RpcDocBuildTemplate;
import com.power.doc.utils.BeetlTemplateUtil;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.beetl.core.Template;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.power.doc.constants.DocGlobalConstants.FILE_SEPARATOR;
import static com.power.doc.constants.DocGlobalConstants.RPC_OUT_DIR;
/**
* @author yu 2020/5/16.
*/
public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
private static final String DEPENDENCY_TITLE = "Add dependency";
private static long now = System.currentTimeMillis();
public void checkAndInit(ApiConfig config) {
if (StringUtil.isEmpty(config.getFramework())) {
config.setFramework(FrameworkEnum.DUBBO.getFramework());
}
super.checkAndInit(config,false);
config.setOutPath(config.getOutPath() + FILE_SEPARATOR + RPC_OUT_DIR);
}
/**
* Generate api documentation for all controllers.
*
@ -106,7 +91,7 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
rpcConfigConfigContent = FileUtil.getFileContent(rpcConfig);
}
FileUtil.mkdirs(outPath);
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
List<ApiErrorCode> errorCodeList = errorCodeDictToList(config);
Template tpl = BeetlTemplateUtil.getByName(template);
tpl.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
tpl.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), errorCodeList);
@ -117,46 +102,9 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
tpl.binding(TemplateVariable.PROJECT_NAME.getVariable(), config.getProjectName());
tpl.binding(TemplateVariable.RPC_CONSUMER_CONFIG.getVariable(), rpcConfigConfigContent);
setDirectoryLanguageVariable(config, tpl);
setCssCDN(config, tpl);
FileUtil.nioWriteFile(tpl.render(), outPath + FILE_SEPARATOR + outPutFileName);
}
/**
* Build search js
*
* @param apiDocList list data of Api doc
* @param config api config
* @param template template
* @param outPutFileName output file
*/
public void buildSearchJs(List<RpcApiDoc> apiDocList, ApiConfig config, String template, String outPutFileName) {
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
Template tpl = BeetlTemplateUtil.getByName(template);
// directory tree
List<RpcApiDoc> apiDocs = new ArrayList<>();
RpcApiDoc apiDoc = new RpcApiDoc();
apiDoc.setAlias(DEPENDENCY_TITLE);
apiDoc.setOrder(1);
apiDoc.setDesc(DEPENDENCY_TITLE);
apiDoc.setList(new ArrayList<>(0));
apiDocs.add(apiDoc);
List<RpcApiDoc> apiDocs1 = apiDocList;
for (RpcApiDoc apiDoc1 : apiDocs1) {
apiDoc1.setOrder(apiDocs.size() + 1);
apiDocs.add(apiDoc1);
}
Map<String, String> titleMap = setDirectoryLanguageVariable(config, tpl);
if (CollectionUtil.isNotEmpty(errorCodeList)) {
RpcApiDoc apiDoc1 = new RpcApiDoc();
apiDoc1.setOrder(apiDocs.size() + 1);
apiDoc1.setDesc(titleMap.get(TemplateVariable.ERROR_LIST_TITLE.getVariable()));
apiDoc1.setList(new ArrayList<>(0));
apiDocs.add(apiDoc1);
}
tpl.binding(TemplateVariable.DIRECTORY_TREE.getVariable(), apiDocs);
FileUtil.nioWriteFile(tpl.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
}
/**
* build error_code adoc
*
@ -165,7 +113,7 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
* @param outPutFileName output file
*/
public void buildErrorCodeDoc(ApiConfig config, String template, String outPutFileName) {
List<ApiErrorCode> errorCodeList = DocUtil.errorCodeDictToList(config);
List<ApiErrorCode> errorCodeList = errorCodeDictToList(config);
Template mapper = BeetlTemplateUtil.getByName(template);
mapper.binding(TemplateVariable.LIST.getVariable(), errorCodeList);
FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + FILE_SEPARATOR + outPutFileName);
@ -184,7 +132,7 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
apiAllData.setProjectName(config.getProjectName());
apiAllData.setProjectId(DocUtil.generateId(config.getProjectName()));
apiAllData.setApiDocList(listOfApiData(config, javaProjectBuilder));
apiAllData.setErrorCodeList(DocUtil.errorCodeDictToList(config));
apiAllData.setErrorCodeList(errorCodeDictToList(config));
apiAllData.setRevisionLogs(config.getRevisionLogs());
apiAllData.setDependencyList(config.getRpcApiDependencies());
return apiAllData;
@ -194,7 +142,7 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate {
this.checkAndInitForGetApiData(config);
config.setMd5EncryptedHtmlName(true);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
IDocBuildTemplate docBuildTemplate = new RpcDocBuildTemplate();
return docBuildTemplate.getApiData(configBuilder);
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,19 +22,24 @@
*/
package com.power.doc.builder.rpc;
import com.power.common.util.CollectionUtil;
import com.power.common.util.DateTimeUtil;
import com.power.common.util.FileUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.constants.DocLanguage;
import com.power.doc.constants.TemplateVariable;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiErrorCode;
import com.power.doc.model.rpc.RpcApiDependency;
import com.power.doc.model.rpc.RpcApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.RpcDocBuildTemplate;
import com.power.doc.utils.BeetlTemplateUtil;
import com.power.doc.utils.MarkDownUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.beetl.core.Template;
import java.util.List;
import java.util.Objects;
import static com.power.doc.constants.DocGlobalConstants.*;
@ -47,8 +52,6 @@ public class RpcHtmlBuilder {
private static String INDEX_HTML = "rpc-index.html";
private static String SEARCH_JS = "search.js";
/**
* build controller api
@ -70,14 +73,143 @@ public class RpcHtmlBuilder {
config.setShowJavaType(true);
RpcDocBuilderTemplate builderTemplate = new RpcDocBuilderTemplate();
builderTemplate.checkAndInit(config);
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
RpcDocBuildTemplate docBuildTemplate = new RpcDocBuildTemplate();
List<RpcApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (config.isAllInOne()) {
Template indexCssTemplate = BeetlTemplateUtil.getByName(ALL_IN_ONE_CSS);
FileUtil.nioWriteFile(indexCssTemplate.render(), config.getOutPath() + FILE_SEPARATOR + ALL_IN_ONE_CSS_OUT);
builderTemplate.copyJarFile("css/" + FONT_STYLE, config.getOutPath() + FILE_SEPARATOR + FONT_STYLE);
builderTemplate.copyJarFile("js/" + JQUERY, config.getOutPath() + FILE_SEPARATOR + JQUERY);
FileUtil.nioWriteFile(indexCssTemplate.render(), config.getOutPath() + FILE_SEPARATOR + ALL_IN_ONE_CSS);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_HTML_TPL, INDEX_HTML);
builderTemplate.buildSearchJs(apiDocList, config, RPC_ALL_IN_ONE_SEARCH_TPL, SEARCH_JS);
} else {
buildIndex(apiDocList, config);
copyCss(config.getOutPath());
buildDoc(apiDocList, config.getOutPath());
buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath());
buildDependency(config);
}
}
private static void copyCss(String outPath) {
Template indexCssTemplate = BeetlTemplateUtil.getByName(INDEX_CSS_TPL);
Template mdCssTemplate = BeetlTemplateUtil.getByName(MARKDOWN_CSS_TPL);
FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + INDEX_CSS_TPL);
FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + MARKDOWN_CSS_TPL);
}
/**
* build api.html
*
* @param apiDocList list of api doc
* @param config ApiConfig
*/
private static void buildIndex(List<RpcApiDoc> apiDocList, ApiConfig config) {
FileUtil.mkdirs(config.getOutPath());
Template indexTemplate = BeetlTemplateUtil.getByName(RPC_INDEX_TPL);
if (CollectionUtil.isEmpty(apiDocList)) {
return;
}
RpcApiDoc doc = apiDocList.get(0);
String homePage = doc.getAlias();
indexTemplate.binding(TemplateVariable.HOME_PAGE.getVariable(), homePage);
indexTemplate.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
indexTemplate.binding(TemplateVariable.VERSION.getVariable(), now);
indexTemplate.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), config.getErrorCodes());
indexTemplate.binding(TemplateVariable.DICT_LIST.getVariable(), config.getDataDictionaries());
if (CollectionUtil.isEmpty(config.getErrorCodes())) {
indexTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 2);
} else {
indexTemplate.binding(TemplateVariable.DICT_ORDER.getVariable(), apiDocList.size() + 3);
}
if (null != config.getLanguage()) {
if (DocLanguage.CHINESE.code.equals(config.getLanguage().getCode())) {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_CN_TITLE);
} else {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_EN_TITLE);
}
} else {
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), ERROR_CODE_LIST_CN_TITLE);
}
FileUtil.nioWriteFile(indexTemplate.render(), config.getOutPath() + FILE_SEPARATOR + "rpc-api.html");
}
/**
* build ever controller api
*
* @param apiDocList list of api doc
* @param outPath output path
*/
private static void buildDoc(List<RpcApiDoc> apiDocList, String outPath) {
FileUtil.mkdirs(outPath);
Template htmlApiDoc;
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);
for (RpcApiDoc rpcDoc : apiDocList) {
Template apiTemplate = BeetlTemplateUtil.getByName(RPC_API_DOC_MD_TPL);
apiTemplate.binding(TemplateVariable.DESC.getVariable(), rpcDoc.getDesc());
apiTemplate.binding(TemplateVariable.NAME.getVariable(), rpcDoc.getName());
apiTemplate.binding(TemplateVariable.LIST.getVariable(), rpcDoc.getList());
apiTemplate.binding(TemplateVariable.PROTOCOL.getVariable(), rpcDoc.getProtocol());
apiTemplate.binding(TemplateVariable.AUTHOR.getVariable(), rpcDoc.getAuthor());
apiTemplate.binding(TemplateVariable.VERSION.getVariable(), rpcDoc.getVersion());
apiTemplate.binding(TemplateVariable.URI.getVariable(), rpcDoc.getUri());
String html = MarkDownUtil.toHtml(apiTemplate.render());
htmlApiDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL);
htmlApiDoc.binding(TemplateVariable.HTML.getVariable(), html);
htmlApiDoc.binding(TemplateVariable.TITLE.getVariable(), rpcDoc.getDesc());
htmlApiDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime);
htmlApiDoc.binding(TemplateVariable.VERSION.getVariable(), now);
FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + rpcDoc.getShortName() + ".html");
}
}
/**
* build error_code html
*
* @param errorCodeList list of error code
* @param outPath
*/
private static void buildErrorCodeDoc(List<ApiErrorCode> errorCodeList, String outPath) {
if (CollectionUtil.isNotEmpty(errorCodeList)) {
Template error = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_MD_TPL);
error.binding(TemplateVariable.LIST.getVariable(), errorCodeList);
String errorHtml = MarkDownUtil.toHtml(error.render());
Template errorCodeDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL);
errorCodeDoc.binding(TemplateVariable.VERSION.getVariable(), now);
errorCodeDoc.binding(TemplateVariable.HTML.getVariable(), errorHtml);
errorCodeDoc.binding(TemplateVariable.TITLE.getVariable(), ERROR_CODE_LIST_EN_TITLE);
errorCodeDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND));
FileUtil.nioWriteFile(errorCodeDoc.render(), outPath + FILE_SEPARATOR + "error_code.html");
}
}
/**
* build dictionary
*
* @param apiDocDictList dictionary list
* @param outPath
*/
private static void buildDependency(ApiConfig config) {
List<RpcApiDependency> apiDependencies = config.getRpcApiDependencies();
Template template;
if (CollectionUtil.isNotEmpty(config.getRpcApiDependencies())) {
String rpcConfig = config.getRpcConsumerConfig();
String rpcConfigConfigContent = null;
if (Objects.nonNull(rpcConfig)) {
rpcConfigConfigContent = FileUtil.getFileContent(rpcConfig);
}
template = BeetlTemplateUtil.getByName(RPC_DEPENDENCY_MD_TPL);
template.binding(TemplateVariable.RPC_CONSUMER_CONFIG.getVariable(), rpcConfigConfigContent);
template.binding(TemplateVariable.DEPENDENCY_LIST.getVariable(), apiDependencies);
} else {
template = BeetlTemplateUtil.getByName(RPC_DEPENDENCY_EMPTY_MD_TPL);
}
String dictHtml = MarkDownUtil.toHtml(template.render());
Template dictTpl = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL);
dictTpl.binding(TemplateVariable.VERSION.getVariable(), now);
dictTpl.binding(TemplateVariable.TITLE.getVariable(), DICT_EN_TITLE);
dictTpl.binding(TemplateVariable.HTML.getVariable(), dictHtml);
dictTpl.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND));
FileUtil.nioWriteFile(dictTpl.render(), config.getOutPath() + FILE_SEPARATOR + "dependency.html");
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -24,10 +24,10 @@ package com.power.doc.builder.rpc;
import com.power.common.util.DateTimeUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.rpc.RpcApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.RpcDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.List;
@ -54,24 +54,23 @@ public class RpcMarkdownBuilder {
/**
*Only for smart-doc maven plugin and gradle plugin.
*
* @param apiConfig ApiConfig
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig apiConfig, JavaProjectBuilder javaProjectBuilder) {
apiConfig.setAdoc(false);
apiConfig.setShowJavaType(true);
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
config.setAdoc(false);
config.setShowJavaType(true);
RpcDocBuilderTemplate builderTemplate = new RpcDocBuilderTemplate();
builderTemplate.checkAndInit(apiConfig);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(apiConfig, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(apiConfig.getFramework());
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = new RpcDocBuildTemplate();
List<RpcApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (apiConfig.isAllInOne()) {
String version = apiConfig.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DATE_FORMAT);
String docName = builderTemplate.allInOneDocName(apiConfig, "rpc-all" + version, ".md");
builderTemplate.buildAllInOne(apiDocList, apiConfig, javaProjectBuilder, RPC_ALL_IN_ONE_MD_TPL, docName);
if (config.isAllInOne()) {
String version = config.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DATE_FORMAT);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_MD_TPL, "rpc-all" + version + ".md");
} else {
builderTemplate.buildApiDoc(apiDocList, apiConfig, RPC_API_DOC_MD_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(apiConfig, ERROR_CODE_LIST_MD_TPL, ERROR_CODE_LIST_MD);
builderTemplate.buildApiDoc(apiDocList, config, RPC_API_DOC_MD_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_MD_TPL, ERROR_CODE_LIST_MD);
}
}
}

View File

@ -1,131 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.builder.rpc;
import com.google.gson.Gson;
import com.power.common.util.CollectionUtil;
import com.power.common.util.OkHttp3Util;
import com.power.common.util.StringUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.TornaConstants;
import com.power.doc.factory.BuildTemplateFactory;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.rpc.RpcApiDoc;
import com.power.doc.model.torna.Apis;
import com.power.doc.model.torna.DubboInfo;
import com.power.doc.model.torna.TornaApi;
import com.power.doc.model.torna.TornaDic;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.RpcDocBuildTemplate;
import com.power.doc.utils.DocUtil;
import com.power.doc.utils.TornaUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.power.doc.constants.TornaConstants.ENUM_PUSH;
import static com.power.doc.constants.TornaConstants.PUSH;
import static com.power.doc.utils.TornaUtil.buildDubboApis;
import static com.power.doc.utils.TornaUtil.buildErrorCode;
/**
* @author xingzi 2021/4/28 16:14
**/
public class RpcTornaBuilder {
/**
* build controller api
*
* @param config config
*/
public static void buildApiDoc(ApiConfig config) {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
buildApiDoc(config, javaProjectBuilder);
}
/**
* Only for smart-doc maven plugin and gradle plugin.
*
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
config.setParamsDataToTree(true);
RpcDocBuilderTemplate builderTemplate = new RpcDocBuilderTemplate();
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
List<RpcApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
buildTorna(apiDocList, config, javaProjectBuilder);
}
public static void buildTorna(List<RpcApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
TornaApi tornaApi = new TornaApi();
tornaApi.setAuthor(StringUtil.isEmpty(apiConfig.getAuthor()) ? System.getProperty("user.name") : apiConfig.getAuthor());
tornaApi.setIsReplace((apiConfig.getReplace() == null || apiConfig.getReplace()) ? 1 : 0);
Apis api;
List<Apis> apisList = new ArrayList<>();
//添加接口数据
for (RpcApiDoc a : apiDocs) {
api = new Apis();
api.setName(StringUtils.isBlank(a.getDesc()) ? a.getName() : a.getDesc());
TornaUtil.setDebugEnv(apiConfig, tornaApi);
api.setItems(buildDubboApis(a.getList()));
api.setIsFolder(TornaConstants.YES);
api.setAuthor(a.getAuthor());
api.setDubboInfo(new DubboInfo().builder()
.setAuthor(a.getAuthor())
.setProtocol(a.getProtocol())
.setVersion(a.getVersion())
.setDependency(TornaUtil.buildDependencies(apiConfig.getRpcApiDependencies()))
.setInterfaceName(a.getName()));
api.setOrderIndex(a.getOrder());
apisList.add(api);
}
tornaApi.setCommonErrorCodes(buildErrorCode(apiConfig));
tornaApi.setApis(apisList);
//Build push document information
Map<String, String> requestJson = TornaConstants.buildParams(PUSH, new Gson().toJson(tornaApi), apiConfig);
//Push dictionary information
Map<String, Object> dicMap = new HashMap<>(2);
List<TornaDic> docDicts = TornaUtil.buildTornaDic(DocUtil.buildDictionary(apiConfig, builder));
if (CollectionUtil.isNotEmpty(docDicts)) {
dicMap.put("enums", docDicts);
Map<String, String> dicRequestJson = TornaConstants.buildParams(ENUM_PUSH, new Gson().toJson(dicMap), apiConfig);
String dicResponseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(dicRequestJson));
TornaUtil.printDebugInfo(apiConfig, dicResponseMsg, dicRequestJson, ENUM_PUSH);
}
Map<String, String> dicRequestJson = TornaConstants.buildParams(ENUM_PUSH, new Gson().toJson(dicMap), apiConfig);
//Get the response result
String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(requestJson));
//Print the log of pushing documents to Torna
TornaUtil.printDebugInfo(apiConfig, responseMsg, requestJson, PUSH);
}
}

View File

@ -1,32 +0,0 @@
package com.power.doc.constants;
/**
* @author chen qi 2021-07-15 10:55
**/
public enum ApiReqParamInTypeEnum {
/**
* header param
*/
HEADER("header"),
/**
* query param
*/
QUERY("query"),
/**
* path param
*/
PATH("path");
private final String value;
ApiReqParamInTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**
@ -39,11 +17,6 @@ public interface DocAnnotationConstants {
String SHORT_JSON_IGNORE = "JsonIgnore";
/**
* jackson JsonIgnoreProperties annotation
*/
String SHORT_JSON_IGNORE_PROPERTIES = "JsonIgnoreProperties";
String SHORT_JSON_PROPERTY = "JsonProperty";
String SHORT_JSON_FIELD = "JSONField";
@ -65,26 +38,4 @@ public interface DocAnnotationConstants {
String REQUEST_MAPPING = "RequestMapping";
String DEPRECATED = "Deprecated";
String JSON_VALUE = "JsonValue";
String JSON_CREATOR = "JsonCreator";
String MAX = "max";
String SIZE = "size";
String LENGTH = "length";
String JSON_PROPERTY = "JsonProperty";
/**
* Fastjson JSONType annotation
*/
String SHORT_JSON_TYPE = "JSONType";
/**
* Fastjson JSONType annotation ignores prop
*/
String IGNORE_PROP = "ignores";
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**
@ -27,8 +5,6 @@ package com.power.doc.constants;
*/
public interface DocGlobalConstants {
int API_ORDER = 0;
String FILE_SEPARATOR = System.getProperty("file.separator");
String HTML_DOC_OUT_PATH = "src/main/resources/static/doc";
@ -69,41 +45,13 @@ public interface DocGlobalConstants {
String DICT_LIST_ADOC_TPL = "Dictionary.btl";
String SEARCH_ALL_JS_TPL = "js/search_all.js.btl";
String INDEX_TPL = "Index.btl";
String SEARCH_JS_TPL = "js/search.js.btl";
String INDEX_CSS_TPL = "index.css";
String SEARCH_JS_OUT = "search.js";
String MARKDOWN_CSS_TPL = "markdown.css";
String DEBUG_JS_TPL = "js/debug.js";
String DEBUG_JS_OUT = "debug.js";
String DEBUG_PAGE_TPL = "mock.html";
String DEBUG_PAGE_ALL_TPL = "debug-all.html";
String DEBUG_PAGE_SINGLE_TPL = "html/debug.html";
String SINGLE_INDEX_HTML_TPL = "html/index.html";
String SINGLE_ERROR_HTML_TPL = "html/error.html";
String SINGLE_DICT_HTML_TPL = "html/dict.html";
String ALL_IN_ONE_CSS = "css/AllInOne.css";
String ALL_IN_ONE_CSS_OUT = "AllInOne.css";
String FONT_STYLE = "font.css";
String HIGH_LIGHT_JS = "highlight.min.js";
String JQUERY = "jquery.min.js";
String HIGH_LIGHT_STYLE = "xt256.min.css";
String RPC_OUT_DIR = "rpc";
String ALL_IN_ONE_CSS = "AllInOne.css";
String RPC_API_DOC_ADOC_TPL = "dubbo/Dubbo.adoc";
@ -111,8 +59,6 @@ public interface DocGlobalConstants {
String RPC_ALL_IN_ONE_HTML_TPL = "dubbo/DubboAllInOne.html";
String RPC_ALL_IN_ONE_SEARCH_TPL = "dubbo/DubboSearch.btl";
String RPC_DEPENDENCY_MD_TPL = "dubbo/DubboApiDependency.md";
String RPC_DEPENDENCY_EMPTY_MD_TPL = "dubbo/DubboApiDependencyEmpty.md";
@ -125,7 +71,7 @@ public interface DocGlobalConstants {
String POSTMAN_JSON = "/postman.json";
String OPEN_API_JSON = "/openapi.json";
String OPEN_API_JSON = "/openApi3.0.json";
String CONTROLLER_FULLY = "org.springframework.stereotype.Controller";
@ -147,16 +93,10 @@ public interface DocGlobalConstants {
String MODE_AND_VIEW_FULLY = "org.springframework.web.servlet.ModelAndView";
String FEIGN_CLIENT_FULLY = "org.springframework.cloud.netflix.feign.FeignClient";
String FEIGN_CLIENT = "FeignClient";
String MULTIPART_FILE_FULLY = "org.springframework.web.multipart.MultipartFile";
String JAVA_OBJECT_FULLY = "java.lang.Object";
String JAVA_BOOLEAN = "java.lang.Boolean";
String JAVA_STRING_FULLY = "java.lang.String";
String JAVA_MAP_FULLY = "java.util.Map";
@ -189,8 +129,6 @@ public interface DocGlobalConstants {
String JSON_CONTENT_TYPE = "application/json; charset=utf-8";
String URL_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=utf-8";
String POSTMAN_MODE_FORMDATA = "formdata";
String POSTMAN_MODE_RAW = "raw";
@ -210,67 +148,6 @@ public interface DocGlobalConstants {
String EMPTY = "";
String ENUM = "enum";
String YAPI_RESULT_TPL = "yapiJson.btl";
String YAPI_JSON="/yapi.json";
String DUBBO_SWAGGER = "org.apache.dubbo.rpc.protocol.rest.integration.swagger.DubboSwaggerApiListingResource";
String ARRAY = "array";
String OBJECT = "object";
String JSON_PROPERTY_READ_WRITE = "JsonProperty.Access.READ_WRITE";
String JSON_PROPERTY_READ_ONLY = "JsonProperty.Access.READ_ONLY";
String JSON_PROPERTY_WRITE_ONLY = "JsonProperty.Access.WRITE_ONLY";
String CSS_CDN_CH = "https://fonts.googleapis.cnpmjs.org";
String CSS_CDN = "https://fonts.googleapis.com";
String PATH_DELIMITER = "/";
/**
* JAX-RS@PATH
*/
String JAX_PATH_FULLY = "javax.ws.rs.Path";
/**
* JAX-RS@Produces
*/
String JAX_PRODUCES_FULLY = "javax.ws.rs.Produces";
/**
* JAX-RS@Produces
*/
String JAX_CONSUMES_FULLY = "javax.ws.rs.Consumes";
/**
* JAX-RS@GET
*/
String JAX_GET_FULLY = "javax.ws.rs.GET";
/**
* JAX-RS@POST
*/
String JAX_POST_FULLY = "javax.ws.rs.POST";
/**
* JAX-RS@PUT
*/
String JAX_PUT_FULLY = "javax.ws.rs.PUT";
/**
* JAX-RS@DELETE
*/
String JAXB_DELETE_FULLY = "javax.ws.rs.DELETE";
String HIGH_LIGHT_CSS_URL_FORMAT = "https://cdn.bootcdn.net/ajax/libs/highlight.js/10.3.2/styles/%s.min.css";
String HIGH_LIGHT_DEFAULT_STYLE = "xt256";
String HIGH_LIGHT_CSS_DEFAULT = "xt256.min.css";
String HIGH_LIGHT_CSS_RANDOM_LIGHT = "randomLight";
String HIGH_LIGHT_CSS_RANDOM_DARK = "randomDark";
}

View File

@ -1,25 +1,4 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**
@ -53,15 +31,10 @@ public interface DocTags {
String AUTHOR = "author";
/**
* java version tag
* java verion tag
*/
String VERSION = "version";
/**
* java deprecated tag
*/
String DEPRECATED = "deprecated";
/**
* custom ignore tag
*/
@ -87,46 +60,8 @@ public interface DocTags {
*/
String ORDER = "order";
/**
* custom @group tag
*/
String GROUP = "group";
/**
* custom @download tag
*/
String DOWNLOAD = "download";
/**
* custom @page tag
*/
String PAGE = "page";
/**
* custom @ignoreParams tag
*/
String IGNORE_PARAMS = "ignoreParams";
/**
* Ignore ResponseBodyAdvice
*/
String IGNORE_RESPONSE_BODY_ADVICE = "ignoreResponseBodyAdvice";
String IGNORE_REQUEST_BODY_ADVICE = "ignoreRequestBodyAdvice";
/**
* response tag @since 2.2.0
*/
String API_RESPONSE = "response";
/**
* custom @tag
*/
String TAG = "tag";
/**
* custom @dubboRest tag
*/
String DUBBO_REST = "dubboRest";
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -69,7 +69,8 @@ public enum DocValidatorAnnotationEnum {
RANGE("Range"),
VALIDATED("Validated");
VALIDATED("Validated")
;
private String value;

View File

@ -1,30 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**
* dubbo annotation
*
* @author yu 2020/1/29.
*/
public interface DubboAnnotationConstants {

View File

@ -1,87 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
import com.power.common.util.StringUtil;
/**
* Smart-doc Supported Framework
*
* @author yu 2021/6/27.
*/
public enum FrameworkEnum {
/**
* Apache Dubbo
*/
DUBBO("dubbo", "com.power.doc.template.RpcDocBuildTemplate"),
/**
* Spring Framework
*/
SPRING("spring", "com.power.doc.template.SpringBootDocBuildTemplate"),
/**
* JAX-RS
*/
JAX_RS("JAX-RS", "com.power.doc.template.JaxrsDocBuildTemplate");
/**
* Framework name
*/
private String framework;
/**
* Framework IDocBuildTemplate implement
*/
private String className;
FrameworkEnum(String framework, String className) {
this.framework = framework;
this.className = className;
}
public static String getClassNameByFramework(String framework) {
String className = "";
if (StringUtil.isEmpty(framework)) {
return className;
}
for (FrameworkEnum e : FrameworkEnum.values()) {
if (e.framework.equalsIgnoreCase(framework)) {
className = e.className;
break;
}
}
return className;
}
public String getFramework() {
return framework;
}
public String getClassName() {
return className;
}
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
import com.power.common.util.StringUtil;
@ -229,7 +207,7 @@ public class HighlightStyle {
/**
* Randomly select a light style
* 随机一个 light style
*
* @param random Random
* @return String of random
@ -239,7 +217,7 @@ public class HighlightStyle {
}
/**
* Randomly select a dark style
* 随机一个 dark style
*
* @param random Random
* @return String of random
@ -249,7 +227,7 @@ public class HighlightStyle {
}
/**
* Randomly select a style
* 随机一个 style
*
* @param random Random
* @return String of random
@ -271,9 +249,10 @@ public class HighlightStyle {
}
/**
* Does the highlight style exist?
* |
* 高亮样式是否存在
*
* @param style Highlight style
* @param style 高亮样式
* @return boolean
*/
public static boolean containsStyle(String style) {

View File

@ -1,54 +0,0 @@
package com.power.doc.constants;
/**
* JAX-RS Annotations
*
* @author Zxq
*/
public interface JAXRSAnnotations {
/**
* JAX-RS@PATH
*/
String JAX_PATH = "Path";
/**
* JAX-RS@Produces
*/
String JAX_PRODUCES = "Produces";
/**
* JAX-RS@HeaderParam
*/
String JAX_HEADER_PARAM = "HeaderParam";
/**
* JAX-RS@PathParam
*/
String JAX_PATH_PARAM = "PathParam";
/**
* JAX-RS@QueryParam
*/
String JAX_QUERY_PARAM = "QueryParam";
/**
* JAX-RS@FormParam
*/
String JAX_FORM_PARAM = "FormParam";
/**
* JAX-RS@Consumes
*/
String JAX_CONSUMES = "Consumes";
/**
* JAX-RS@GET
*/
String GET = "GET";
/**
* JAX-RS@POST
*/
String POST = "POST";
/**
* JAX-RS@PUT
*/
String PUT = "PUT";
/**
* JAX-RS@DELETE
*/
String DELETE = "DELETE";
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
/**

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -50,8 +50,4 @@ public interface SpringMvcAnnotations {
String REST_CONTROLLER = "RestController";
String PATH_VARIABLE = "PathVariable";
String SESSION_ATTRIBUTE = "SessionAttribute";
String REQUEST_ATTRIBUTE="RequestAttribute";
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -37,8 +37,7 @@ public enum SpringMvcRequestAnnotationsEnum {
REQUEST_BODY("RequestBody"),
REQUEST_BODY_FULLY("org.springframework.web.bind.annotation.RequestBody"),
REQUEST_HERDER("RequestHeader"),
REQUEST_HERDER_FULLY("org.springframework.web.bind.annotation.RequestHeader"),
;
REQUEST_HERDER_FULLY("org.springframework.web.bind.annotation.RequestHeader"),;
private String value;
SpringMvcRequestAnnotationsEnum(String value) {

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -51,14 +51,7 @@ public enum TemplateVariable {
RPC_CONSUMER_CONFIG("consumerConfigExample"),
REQUEST_EXAMPLE("isRequestExample"),
RESPONSE_EXAMPLE("isResponseExample"),
DISPLAY_REQUEST_PARAMS("displayRequestParams"),
DISPLAY_RESPONSE_PARAMS("displayResponseParams"),
RESPONSE_LIST("respList"),
ORDER("order"),
INDEX_ALIAS("alias"),
DIRECTORY_TREE("directoryTree"),
HIGH_LIGHT_CSS_LINK("highlightCssLink"),
CSS_CND("css_cdn");
RESPONSE_LIST("respList");
private String variable;

View File

@ -1,151 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.constants;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.power.doc.model.ApiConfig;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author xingzi 2020/2/2
*/
public class TornaConstants {
public static final String ID = "id";
public static final String CODE = "code";
public static final String MESSAGE = "msg";
public static final String DATA = "data";
public static final String SUCCESS_CODE = "0";
public static final String YES = "1";
public static final String NO = "0";
public static final String ARRAY = "array";
public static final String CATEGORY_CREATE = "doc.category.create";
public static final String PUSH = "doc.push";
public static final String ENUM_PUSH = "enum.batch.push";
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
/**
* build torna params
*
* @param name interface name
* @param data json
* @param config ApiConfig
* @return Map
*/
public static Map<String, String> buildParams(String name, String data, ApiConfig config) {
Map<String, String> param = new HashMap<>(8);
try {
if (StringUtils.isNotBlank(data)) {
data = URLEncoder.encode(data, "utf-8");
}
// Public request parameters for pushing documents to Torna
param.put("name", name);
param.put("app_key", config.getAppKey());
param.put("data", data);
param.put("timestamp", getTime());
param.put("version", "1.0");
param.put("access_token", config.getAppToken());
String sign = buildSign(param, config.getSecret());
param.put("sign", sign);
return param;
} catch (IOException e) {
e.printStackTrace();
}
return param;
}
/**
* 构建签名
*
* @param paramsMap 参数
* @param secret 密钥
* @return String
*/
public static String buildSign(Map<String, ?> paramsMap, String secret) {
Set<String> keySet = paramsMap.keySet();
List<String> paramNames = new ArrayList<>(keySet);
Collections.sort(paramNames);
StringBuilder paramNameValue = new StringBuilder();
for (String paramName : paramNames) {
Object value = paramsMap.get(paramName);
if (value != null) {
paramNameValue.append(paramName).append(value);
}
}
String source = secret + paramNameValue.toString() + secret;
return md5(source);
}
/**
* Generate md5 and convert to uppercase
*
* @param message message
* @return String
*/
public static String md5(String message) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] input = message.getBytes();
byte[] buff = md.digest(input);
return byte2hex(buff);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Convert byte array to hex
* @param bytes byte array
* @return String
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
public static String getTime() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,53 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.factory;
import com.power.doc.constants.FrameworkEnum;
import com.power.doc.template.IDocBuildTemplate;
/**
* @author yu 2021/6/27.
*/
public class BuildTemplateFactory {
/**
* Get Doc build template
*
* @param framework framework name
* @param <T> API doc type
* @return Implements of IDocBuildTemplate
*/
public static <T> IDocBuildTemplate<T> getDocBuildTemplate(String framework) {
String className = FrameworkEnum.getClassNameByFramework(framework);
try {
return (IDocBuildTemplate) Class.forName(className).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
throw new RuntimeException("The class=>" + className + " is not found , smart-doc currently supported framework name can only be set in [dubbo, spring].");
}
return null;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -26,7 +26,6 @@ import com.power.doc.model.ApiReturn;
/**
* must be put last
*
* @author yu 2020/4/17.
*/
public class DefaultReturnFilter implements ReturnTypeFilter {

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -26,14 +26,12 @@ import com.power.doc.model.ApiReturn;
/**
* Chain Of Responsibility Pattern
*
* @author yu 2020/4/17.
*/
public interface ReturnTypeFilter {
/**
* filter return Type
*
* @param fullyName full type name
* @return ApiReturn
*/

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,39 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.function;
import org.beetl.core.Context;
import org.beetl.core.Function;
/**
* @author yu 2021/6/26.
*/
public class HtmlEscape implements Function {
@Override
public String call(Object[] paras, Context ctx) {
String str = String.valueOf(paras[0]).replaceAll("&", "&amp;")
.replaceAll("\"","&quot;");
return str;
}
}

View File

@ -1,18 +0,0 @@
package com.power.doc.function;
import org.beetl.core.Context;
import org.beetl.core.Function;
/**
* @author yu 2021/7/24.
*/
public class RemoveLineBreaks implements Function {
@Override
public String call(Object[] paras, Context ctx) {
String str = String.valueOf(paras[0])
.replaceAll("\n", " ")
.replaceAll("\r"," ");
return str;
}
}

View File

@ -1,65 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.handler;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.JAXRSAnnotations;
import com.power.doc.model.ApiReqParam;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaMethod;
import java.util.ArrayList;
import java.util.List;
/**
*
*
* @author Zxq
*/
public class JaxrsHeaderHandler {
/**
* Handle JAX RS Header
* @param method method
* @param projectBuilder ProjectDocConfigBuilder
* @return list of ApiReqParam
*/
public List<ApiReqParam> handle(JavaMethod method, ProjectDocConfigBuilder projectBuilder) {
List<JavaAnnotation> annotations = method.getAnnotations();
List<ApiReqParam> ApiReqParams = new ArrayList<>();
for (JavaAnnotation annotation : annotations) {
// hit target head annotation
if (JAXRSAnnotations.JAX_HEADER_PARAM.equals(annotation.getType().getName())) {
ApiReqParam ApiReqParam = new ApiReqParam();
// Obtain header value
ApiReqParam.setValue(DocUtil.getRequestHeaderValue(annotation).replaceAll("\"", ""));
ApiReqParam.setName(DocUtil.getRequestHeaderValue(annotation).replaceAll("\"", ""));
ApiReqParam.setType("string");
ApiReqParam.setDesc("desc");
ApiReqParams.add(ApiReqParam);
}
}
return ApiReqParams;
}
}

View File

@ -1,144 +0,0 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.handler;
import com.power.common.util.StringUtil;
import com.power.common.util.UrlUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.*;
import com.power.doc.model.request.JaxrsPathMapping;
import com.power.doc.utils.DocUrlUtil;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaMethod;
import java.util.*;
import static com.power.doc.constants.DocTags.DEPRECATED;
import static com.power.doc.constants.DocTags.IGNORE;
/**
* dubbo Rest 注解处理器
*
* @author Zxq
*/
public class JaxrsPathHandler {
/**
* ANNOTATION_NAMES
*/
private static final Set<String> ANNOTATION_NAMES = Collections.unmodifiableSet(new HashSet<>(
Arrays.asList(JAXRSAnnotations.DELETE,
DocGlobalConstants.JAXB_DELETE_FULLY,
JAXRSAnnotations.PUT, DocGlobalConstants.JAX_PUT_FULLY,
JAXRSAnnotations.GET, DocGlobalConstants.JAX_GET_FULLY,
JAXRSAnnotations.POST, DocGlobalConstants.JAX_POST_FULLY
)));
Map<String, String> constantsMap;
public JaxrsPathMapping handle(ProjectDocConfigBuilder projectBuilder, String baseUrl, JavaMethod method) {
List<JavaAnnotation> annotations = method.getAnnotations();
this.constantsMap = projectBuilder.getConstantsMap();
String url;
String methodType = null;
String shortUrl = null;
String mediaType = null;
String serverUrl = projectBuilder.getServerUrl();
String contextPath = projectBuilder.getApiConfig().getPathPrefix();
boolean deprecated = false;
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getName();
if (JAXRSAnnotations.JAX_PRODUCES.equals(annotationName)) {
mediaType = DocUtil.getRequestHeaderValue(annotation);
}
// Deprecated annotation on method
if (DocAnnotationConstants.DEPRECATED.equals(annotationName)) {
deprecated = true;
}
if (JAXRSAnnotations.JAX_PATH.equals(annotationName) ||
JAXRSAnnotations.JAX_PATH_PARAM.equals(annotationName) ||
DocGlobalConstants.JAX_PATH_FULLY
.equals(annotationName)) {
shortUrl = DocUtil.handleMappingValue(annotation);
}
if (ANNOTATION_NAMES.contains(annotationName)) {
methodType = annotationName;
}
}
// @deprecated tag on method
if (Objects.nonNull(method.getTagByName(DEPRECATED))) {
deprecated = true;
}
JaxrsPathMapping jaxrsPathMapping = getJaxbPathMapping(projectBuilder, baseUrl, method, shortUrl, serverUrl, contextPath);
if (jaxrsPathMapping != null) {
return jaxrsPathMapping.setDeprecated(deprecated)
.setMethodType(methodType)
.setMediaType(mediaType);
}
return null;
}
private JaxrsPathMapping getJaxbPathMapping(ProjectDocConfigBuilder projectBuilder,
String baseUrl, JavaMethod method,
String shortUrl,
String serverUrl,
String contextPath) {
String url;
if (Objects.nonNull(shortUrl)) {
if (Objects.nonNull(method.getTagByName(IGNORE))) {
return null;
}
shortUrl = StringUtil.removeQuotes(shortUrl);
List<String> urls = DocUtil.split(shortUrl);
url = String.join(DocGlobalConstants.PATH_DELIMITER, serverUrl, contextPath, baseUrl, shortUrl);
shortUrl = String.join(DocGlobalConstants.PATH_DELIMITER, DocGlobalConstants.PATH_DELIMITER, contextPath, baseUrl, shortUrl);
if (urls.size() > 1) {
url = DocUrlUtil.getMvcUrls(serverUrl, contextPath + "/" + baseUrl, urls);
shortUrl = DocUrlUtil.getMvcUrls(DocGlobalConstants.EMPTY, contextPath + "/" + baseUrl, urls);
}
for (Map.Entry<String, String> entry : constantsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (url.contains(key)) {
url = url.replace(key, value).replace("+", "");
}
if (shortUrl.contains(key)) {
shortUrl = shortUrl.replace(key, value).replace("+", "");
}
}
String urlSuffix = projectBuilder.getApiConfig().getUrlSuffix();
url = UrlUtil.simplifyUrl(url);
shortUrl = UrlUtil.simplifyUrl(shortUrl);
if (StringUtil.isNotEmpty(urlSuffix)) {
url += urlSuffix;
shortUrl += urlSuffix;
}
return JaxrsPathMapping.builder()
.setUrl(StringUtil.trim(url))
.setShortUrl(StringUtil.trim(shortUrl));
}
return null;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -23,11 +23,10 @@
package com.power.doc.handler;
import com.power.common.util.StringUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.DocAnnotationConstants;
import com.power.doc.constants.DocTags;
import com.power.doc.constants.SpringMvcAnnotations;
import com.power.doc.model.ApiReqParam;
import com.power.doc.model.ApiReqHeader;
import com.power.doc.utils.DocClassUtil;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
@ -47,12 +46,10 @@ public class SpringMVCRequestHeaderHandler {
* handle Spring MVC Request Header
*
* @param method JavaMethod
* @param projectBuilder projectBuilder
* @return list of ApiReqHeader
*/
public List<ApiReqParam> handle(JavaMethod method, ProjectDocConfigBuilder projectBuilder) {
Map<String, String> constantsMap = projectBuilder.getConstantsMap();
List<ApiReqParam> mappingHeaders = new ArrayList<>();
public List<ApiReqHeader> handle(JavaMethod method) {
List<ApiReqHeader> mappingHeaders = new ArrayList<>();
List<JavaAnnotation> annotations = method.getAnnotations();
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getValue();
@ -60,45 +57,47 @@ public class SpringMVCRequestHeaderHandler {
if (!isMapping(annotationName) || Objects.isNull(headersObject)) {
continue;
}
String mappingHeader = StringUtil.removeQuotes(headersObject.toString());
if (!mappingHeader.startsWith("[")) {
processMappingHeaders(mappingHeader, mappingHeaders);
continue;
}
List<String> headers = (LinkedList) headersObject;
for (String str : headers) {
String header = StringUtil.removeQuotes(str);
if (header.startsWith("!")) {
continue;
}
processMappingHeaders(header, mappingHeaders);
if (header.contains("!=")) {
String headerName = header.substring(0, header.indexOf("!"));
ApiReqHeader apiReqHeader = ApiReqHeader.builder().setName(headerName)
.setRequired(true).setValue(null).setDesc(header).setType("string");
mappingHeaders.add(apiReqHeader);
} else {
String headerName;
String headerValue = null;
if (header.contains("=")) {
int index = header.indexOf("=");
headerName = header.substring(0, header.indexOf("="));
headerValue = header.substring(index + 1);
} else {
headerName = header;
}
ApiReqHeader apiReqHeader = ApiReqHeader.builder().setName(headerName)
.setRequired(true).setValue(headerValue).setDesc(header).setType("string");
mappingHeaders.add(apiReqHeader);
}
}
List<ApiReqParam> reqHeaders = new ArrayList<>();
}
List<ApiReqHeader> reqHeaders = new ArrayList<>();
for (JavaParameter javaParameter : method.getParameters()) {
List<JavaAnnotation> javaAnnotations = javaParameter.getAnnotations();
String className = method.getDeclaringClass().getCanonicalName();
Map<String, String> paramMap = DocUtil.getParamsComments(method, DocTags.PARAM, className);
String paramName = javaParameter.getName();
ApiReqParam apiReqHeader;
ApiReqHeader apiReqHeader;
for (JavaAnnotation annotation : javaAnnotations) {
String annotationName = annotation.getType().getValue();
if (SpringMvcAnnotations.REQUEST_HERDER.equals(annotationName)) {
apiReqHeader = new ApiReqParam();
apiReqHeader = new ApiReqHeader();
Map<String, Object> requestHeaderMap = annotation.getNamedParameterMap();
if (requestHeaderMap.get(DocAnnotationConstants.VALUE_PROP) != null) {
String attribute = DocUtil.handleRequestHeaderValue(annotation);
String constValue = ((String) requestHeaderMap.get(DocAnnotationConstants.VALUE_PROP)).replaceAll("\"", "");
if (StringUtil.isEmpty(attribute)) {
apiReqHeader.setName(constValue);
} else {
Object value = constantsMap.get(attribute);
if (value == null) {
apiReqHeader.setName(constValue);
} else {
apiReqHeader.setName((String) value);
}
}
apiReqHeader.setName(StringUtil.removeQuotes((String) requestHeaderMap.get(DocAnnotationConstants.VALUE_PROP)));
} else {
apiReqHeader.setName(paramName);
}
@ -114,8 +113,7 @@ public class SpringMVCRequestHeaderHandler {
}
apiReqHeader.setDesc(desc.toString());
if (requestHeaderMap.get(DocAnnotationConstants.REQUIRED_PROP) != null) {
apiReqHeader.setRequired(!Boolean.FALSE.toString()
.equals(requestHeaderMap.get(DocAnnotationConstants.REQUIRED_PROP)));
apiReqHeader.setRequired(!Boolean.FALSE.toString().equals(requestHeaderMap.get(DocAnnotationConstants.REQUIRED_PROP)));
} else {
apiReqHeader.setRequired(true);
}
@ -126,10 +124,8 @@ public class SpringMVCRequestHeaderHandler {
}
}
}
List<ApiReqParam> allApiReqHeaders = Stream.of(mappingHeaders, reqHeaders)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
List<ApiReqHeader> allApiReqHeaders = Stream.of(mappingHeaders, reqHeaders)
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
return allApiReqHeaders;
}
@ -146,34 +142,4 @@ public class SpringMVCRequestHeaderHandler {
return false;
}
}
public void processMappingHeaders(String header, List<ApiReqParam> mappingHeaders) {
if (header.contains("!=")) {
String headerName = header.substring(0, header.indexOf("!"));
ApiReqParam apiReqHeader = ApiReqParam.builder()
.setName(headerName)
.setRequired(true)
.setValue(null)
.setDesc("header condition")
.setType("string");
mappingHeaders.add(apiReqHeader);
} else {
String headerName;
String headerValue = null;
if (header.contains("=")) {
int index = header.indexOf("=");
headerName = header.substring(0, index);
headerValue = header.substring(index + 1);
} else {
headerName = header;
}
ApiReqParam apiReqHeader = ApiReqParam.builder()
.setName(headerName)
.setRequired(true)
.setValue(headerValue)
.setDesc("header condition")
.setType("string");
mappingHeaders.add(apiReqHeader);
}
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -24,7 +24,6 @@ package com.power.doc.handler;
import com.power.common.util.StringUtil;
import com.power.common.util.UrlUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.DocAnnotationConstants;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.Methods;
@ -35,11 +34,10 @@ import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaMethod;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.power.doc.constants.DocTags.DEPRECATED;
import static com.power.doc.constants.DocTags.IGNORE;
/**
@ -50,25 +48,24 @@ public class SpringMVCRequestMappingHandler {
/**
* handle spring request mapping
*
* @param projectBuilder projectBuilder
* @param serverUrl server url
* @param controllerBaseUrl spring mvc controller base url
* @param method JavaMethod
* @param constantsMap project constant container
* @return RequestMapping
*/
public RequestMapping handle(ProjectDocConfigBuilder projectBuilder, String controllerBaseUrl, JavaMethod method, Map<String, String> constantsMap) {
public RequestMapping handle(String serverUrl, String controllerBaseUrl, JavaMethod method, Map<String, String> constantsMap) {
List<JavaAnnotation> annotations = method.getAnnotations();
String url;
String methodType = null;
String shortUrl = null;
String mediaType = null;
String serverUrl = projectBuilder.getServerUrl();
String contextPath = projectBuilder.getApiConfig().getPathPrefix();
boolean deprecated = false;
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getName();
Object produces = annotation.getNamedParameter("produces");
if (Objects.nonNull(produces)) {
if (produces != null) {
mediaType = produces.toString();
}
if (DocAnnotationConstants.DEPRECATED.equals(annotationName)) {
@ -77,7 +74,7 @@ public class SpringMVCRequestMappingHandler {
if (SpringMvcAnnotations.REQUEST_MAPPING.equals(annotationName) || DocGlobalConstants.REQUEST_MAPPING_FULLY.equals(annotationName)) {
shortUrl = DocUtil.handleMappingValue(annotation);
Object nameParam = annotation.getNamedParameter("method");
if (Objects.nonNull(nameParam)) {
if (null != nameParam) {
methodType = nameParam.toString();
methodType = DocUtil.handleHttpMethod(methodType);
} else {
@ -100,53 +97,34 @@ public class SpringMVCRequestMappingHandler {
methodType = Methods.DELETE.getValue();
}
}
if (Objects.nonNull(method.getTagByName(DEPRECATED))) {
deprecated = true;
}
if (Objects.nonNull(shortUrl)) {
if (Objects.nonNull(method.getTagByName(IGNORE))) {
if (shortUrl != null) {
if (null != method.getTagByName(IGNORE)) {
return null;
}
shortUrl = StringUtil.removeQuotes(shortUrl);
List<String> urls = DocUtil.split(shortUrl);
if (urls.size() > 1) {
url = DocUrlUtil.getMvcUrls(serverUrl, contextPath + "/" + controllerBaseUrl, urls);
shortUrl = DocUrlUtil.getMvcUrls(DocGlobalConstants.EMPTY, contextPath + "/" + controllerBaseUrl, urls);
String[] urls = shortUrl.split(",");
if (urls.length > 1) {
url = DocUrlUtil.getMvcUrls(serverUrl, controllerBaseUrl, Arrays.asList(urls));
shortUrl = DocUrlUtil.getMvcUrls("", controllerBaseUrl, Arrays.asList(urls));
} else {
url = String.join(DocGlobalConstants.PATH_DELIMITER, serverUrl, contextPath, controllerBaseUrl, shortUrl);
shortUrl = String.join(DocGlobalConstants.PATH_DELIMITER, DocGlobalConstants.PATH_DELIMITER, contextPath, controllerBaseUrl, shortUrl);
url = UrlUtil.simplifyUrl(serverUrl + "/" + controllerBaseUrl + "/" + shortUrl);
shortUrl = UrlUtil.simplifyUrl("/" + controllerBaseUrl + "/" + shortUrl);
}
for (Map.Entry<String, String> entry : constantsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
url = delConstantsUrl(url, key, value);
shortUrl = delConstantsUrl(shortUrl, key, value);
if (url.contains(key)) {
url = url.replace(key, value);
url = url.replace("+", "");
}
if (shortUrl.contains(key)) {
shortUrl = shortUrl.replace(key, value);
shortUrl = shortUrl.replace("+", "");
}
String urlSuffix = projectBuilder.getApiConfig().getUrlSuffix();
if (StringUtil.isNotEmpty(urlSuffix)) {
url = UrlUtil.simplifyUrl(StringUtil.trim(url)) + urlSuffix;
shortUrl = UrlUtil.simplifyUrl(StringUtil.trim(shortUrl)) + urlSuffix;
} else {
url = UrlUtil.simplifyUrl(StringUtil.trim(url));
shortUrl = UrlUtil.simplifyUrl(StringUtil.trim(shortUrl));
}
return RequestMapping.builder().setMediaType(mediaType).setMethodType(methodType)
.setUrl(url).setShortUrl(shortUrl).setDeprecated(deprecated);
.setUrl(StringUtil.trim(url)).setShortUrl(StringUtil.trim(shortUrl)).setDeprecated(deprecated);
}
return null;
}
public static String delConstantsUrl(String url, String replaceKey, String replaceValue) {
url = StringUtil.trim(url);
url = url.replace("+", "");
url = UrlUtil.simplifyUrl(url);
String[] pathWords = url.split("/");
for (String word : pathWords) {
if (word.equals(replaceKey)) {
url = url.replace(replaceKey, replaceValue);
return url;
}
}
return url;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -28,7 +28,6 @@ import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.DocTags;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.CustomField;
import com.power.doc.model.DocJavaField;
import com.power.doc.model.FormData;
import com.power.doc.utils.DocClassUtil;
@ -38,7 +37,10 @@ import com.power.doc.utils.JavaClassValidateUtil;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
/**
* @author yu 2019/12/25.
@ -77,7 +79,7 @@ public class FormDataBuildHelper {
String simpleName = DocClassUtil.getSimpleName(className);
String[] globGicName = DocClassUtil.getSimpleGicName(className);
JavaClass cls = builder.getJavaProjectBuilder().getClassByName(simpleName);
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new LinkedHashMap<>());
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new HashSet<>());
if (JavaClassValidateUtil.isPrimitive(simpleName)) {
FormData formData = new FormData();
@ -92,9 +94,6 @@ public class FormDataBuildHelper {
if (JavaClassValidateUtil.isArray(gicName)) {
gicName = gicName.substring(0, gicName.indexOf("["));
}
if (JavaClassValidateUtil.isPrimitive(gicName)) {
pre = pre.substring(0, pre.lastIndexOf("."));
}
formDataList.addAll(getFormData(gicName, registryClasses, counter, builder, pre + "[]"));
}
int n = 0;
@ -104,7 +103,7 @@ public class FormDataBuildHelper {
String fieldName = field.getName();
String subTypeName = docField.getFullyQualifiedName();
String fieldGicName = docField.getGenericCanonicalName();
JavaClass javaClass = field.getType();
JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(subTypeName);
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
@ -127,7 +126,7 @@ public class FormDataBuildHelper {
if (StringUtil.isNotEmpty(comment)) {
comment = DocUtil.replaceNewLineToHtmlBr(comment);
}
if (JavaClassValidateUtil.isFile(fieldGicName)) {
if (fieldGicName.contains(DocGlobalConstants.MULTIPART_FILE_FULLY)) {
FormData formData = new FormData();
formData.setKey(pre + fieldName);
formData.setType("file");
@ -141,12 +140,6 @@ public class FormDataBuildHelper {
} else {
fieldValue = DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName());
}
CustomField customRequestField = builder.getCustomReqFieldMap().get(fieldName);
// cover request value
if (Objects.nonNull(customRequestField) && Objects.nonNull(customRequestField.getValue())
&& JavaClassUtil.isTargetChildClass(simpleName, customRequestField.getOwnerClassName())) {
fieldValue = String.valueOf(customRequestField.getValue());
}
FormData formData = new FormData();
formData.setKey(pre + fieldName);
formData.setType("text");
@ -155,9 +148,6 @@ public class FormDataBuildHelper {
formDataList.add(formData);
} else if (javaClass.isEnum()) {
Object value = JavaClassUtil.getEnumValue(javaClass, Boolean.TRUE);
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
value = tagsMap.get(DocTags.MOCK);
}
FormData formData = new FormData();
formData.setKey(pre + fieldName);
formData.setType("text");

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,21 +22,18 @@
*/
package com.power.doc.helper;
import com.power.common.util.JsonFormatUtil;
import com.power.common.util.StringUtil;
import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.DocAnnotationConstants;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.DocTags;
import com.power.doc.constants.ValidatorAnnotations;
import com.power.doc.model.*;
import com.power.doc.utils.*;
import com.thoughtworks.qdox.model.*;
import com.thoughtworks.qdox.model.expression.AnnotationValue;
import java.util.*;
import static com.power.doc.constants.DocGlobalConstants.JSON_PROPERTY_READ_ONLY;
import static com.power.doc.constants.DocGlobalConstants.JSON_PROPERTY_WRITE_ONLY;
import static com.power.doc.constants.DocTags.IGNORE_RESPONSE_BODY_ADVICE;
@ -54,45 +51,21 @@ public class JsonBuildHelper {
*/
public static String buildReturnJson(DocJavaMethod docJavaMethod, ProjectDocConfigBuilder builder) {
JavaMethod method = docJavaMethod.getJavaMethod();
String responseBodyAdvice = null;
if (Objects.nonNull(builder.getApiConfig().getResponseBodyAdvice())) {
responseBodyAdvice = builder.getApiConfig().getResponseBodyAdvice().getClassName();
}
if (method.getReturns().isVoid() && Objects.isNull(responseBodyAdvice)) {
return "Return void.";
}
DocletTag downloadTag = method.getTagByName(DocTags.DOWNLOAD);
if (Objects.nonNull(downloadTag)) {
return "File download.";
}
if (method.getReturns().isEnum() && Objects.isNull(responseBodyAdvice)) {
return StringUtil.removeQuotes(String.valueOf(JavaClassUtil.getEnumValue(method.getReturns(), Boolean.FALSE)));
}
if (method.getReturns().isPrimitive() && Objects.isNull(responseBodyAdvice)) {
String typeName = method.getReturnType().getCanonicalName();
return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName));
}
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(method.getReturnType().getGenericCanonicalName())
&& Objects.isNull(responseBodyAdvice)) {
return "string";
if (method.getReturns().isVoid()) {
return "This api return nothing.";
}
String returnTypeGenericCanonicalName = method.getReturnType().getGenericCanonicalName();
if (Objects.nonNull(responseBodyAdvice)
if (Objects.nonNull(builder.getApiConfig().getResponseBodyAdvice())
&& Objects.isNull(method.getTagByName(IGNORE_RESPONSE_BODY_ADVICE))) {
if (!returnTypeGenericCanonicalName.startsWith(responseBodyAdvice)) {
String responseBodyAdvice = builder.getApiConfig().getResponseBodyAdvice().getClassName();
StringBuilder sb = new StringBuilder();
sb.append(responseBodyAdvice)
.append("<")
.append(returnTypeGenericCanonicalName).append(">");
returnTypeGenericCanonicalName = sb.toString();
}
}
ApiReturn apiReturn = DocClassUtil.processReturnType(returnTypeGenericCanonicalName);
String typeName = apiReturn.getSimpleName();
if (JavaClassValidateUtil.isFileDownloadResource(typeName)) {
docJavaMethod.setDownload(true);
return "File download.";
}
Map<String, JavaType> actualTypesMap = docJavaMethod.getActualTypesMap();
String returnType = apiReturn.getGenericCanonicalName();
if (Objects.nonNull(actualTypesMap)) {
@ -101,16 +74,7 @@ public class JsonBuildHelper {
returnType = returnType.replace(entry.getKey(), entry.getValue().getCanonicalName());
}
}
if (JavaClassValidateUtil.isPrimitive(typeName)) {
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(typeName)) {
return "string";
}
return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName));
}
return JsonUtil.toPrettyFormat(buildJson(typeName, returnType, Boolean.TRUE, 0,
new HashMap<>(), new ArrayList<>(0), builder));
return JsonFormatUtil.formatJson(buildJson(typeName, returnType, Boolean.TRUE, 0, new HashMap<>(), builder));
}
/**
@ -119,13 +83,13 @@ public class JsonBuildHelper {
* @param isResp Response flag
* @param counter Recursive counter
* @param registryClasses class container
* @param groupClasses valid group class
* @param builder project config builder
* @return String
*/
public static String buildJson(String typeName, String genericCanonicalName,
boolean isResp, int counter, Map<String, String> registryClasses, List<String> groupClasses, ProjectDocConfigBuilder builder) {
boolean isResp, int counter, Map<String, String> registryClasses, ProjectDocConfigBuilder builder) {
//存储泛型所对应的实体类
Map<String, String> genericMap = new HashMap<>(10);
JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(typeName);
ApiConfig apiConfig = builder.getApiConfig();
@ -148,21 +112,16 @@ public class JsonBuildHelper {
return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName));
}
if (javaClass.isEnum()) {
return StringUtil.removeQuotes(String.valueOf(JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE)));
return String.valueOf(JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE));
}
boolean skipTransientField = apiConfig.isSkipTransientField();
StringBuilder data0 = new StringBuilder();
JavaClass cls = builder.getClassByName(typeName);
data0.append("{");
String[] globGicName = DocClassUtil.getSimpleGicName(genericCanonicalName);
if (Objects.isNull(globGicName) || globGicName.length < 1) {
// obtain generics from parent class
JavaClass superJavaClass = cls != null ? cls.getSuperJavaClass() : null;
if (Objects.nonNull(superJavaClass) && !"Object".equals(superJavaClass.getSimpleName())) {
globGicName = DocClassUtil.getSimpleGicName(superJavaClass.getGenericFullyQualifiedName());
}
}
//添加泛型对应关系
JavaClassUtil.genericParamMap(genericMap, cls, globGicName);
StringBuilder data = new StringBuilder();
if (JavaClassValidateUtil.isCollection(typeName) || JavaClassValidateUtil.isArray(typeName)) {
@ -181,12 +140,12 @@ public class JsonBuildHelper {
data.append(DocUtil.jsonValueByType(gName));
} else if (gName.contains("<")) {
String simple = DocClassUtil.getSimpleName(gName);
String json = buildJson(simple, gName, isResp, nextLevel, registryClasses, groupClasses, builder);
String json = buildJson(simple, gName, isResp, nextLevel, registryClasses, builder);
data.append(json);
} else if (JavaClassValidateUtil.isCollection(gName)) {
data.append("\"any object\"");
} else {
String json = buildJson(gName, gName, isResp, nextLevel, registryClasses, groupClasses, builder);
String json = buildJson(gName, gName, isResp, nextLevel, registryClasses, builder);
data.append(json);
}
data.append("]");
@ -198,46 +157,43 @@ public class JsonBuildHelper {
data.append("{\"mapKey\":{}}");
return data.toString();
}
if ((!DocGlobalConstants.JAVA_STRING_FULLY.equals(getKeyValType[0])) && apiConfig.isStrict()) {
if (!DocGlobalConstants.JAVA_STRING_FULLY.equals(getKeyValType[0])) {
throw new RuntimeException("Map's key can only use String for json,but you use " + getKeyValType[0]);
}
String gicName = gNameTemp.substring(gNameTemp.indexOf(",") + 1, gNameTemp.lastIndexOf(">"));
if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(gicName)) {
data.append("{").append("\"mapKey\":").append("{\"waring\":\"You may use java.util.Object for Map value; smart-doc can't be handle.\"}")
.append("}");
data.append("{").append("\"mapKey\":").append("{\"waring\":\"You may use java.util.Object for Map value; smart-doc can't be handle.\"}").append("}");
} else if (JavaClassValidateUtil.isPrimitive(gicName)) {
data.append("{").append("\"mapKey1\":").append(DocUtil.jsonValueByType(gicName)).append(",");
data.append("\"mapKey2\":").append(DocUtil.jsonValueByType(gicName)).append("}");
} else if (gicName.contains("<")) {
String simple = DocClassUtil.getSimpleName(gicName);
String json = buildJson(simple, gicName, isResp, nextLevel, registryClasses, groupClasses, builder);
String json = buildJson(simple, gicName, isResp, nextLevel, registryClasses, builder);
data.append("{").append("\"mapKey\":").append(json).append("}");
} else {
data.append("{").append("\"mapKey\":").append(buildJson(gicName, gNameTemp, isResp, counter + 1, registryClasses, groupClasses, builder)).append("}");
data.append("{").append("\"mapKey\":").append(buildJson(gicName, gNameTemp, isResp, counter + 1, registryClasses, builder)).append("}");
}
return data.toString();
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(typeName)) {
data.append("{\"object\":\" any object\"},");
// throw new RuntimeException("Please do not return java.lang.Object directly in api interface.");
} else if (JavaClassValidateUtil.isReactor(typeName)) {
data.append(buildJson(globGicName[0], typeName, isResp, nextLevel, registryClasses, groupClasses, builder));
return data.toString();
} else {
boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline();
boolean responseFieldToUnderline = builder.getApiConfig().isResponseFieldToUnderline();
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new LinkedHashMap<>());
Map<String, String> ignoreFields = JavaClassUtil.getClassJsonIgnoreFields(cls);
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new HashSet<>());
boolean isGenerics = JavaFieldUtil.checkGenerics(fields);
out:
for (DocJavaField docField : fields) {
JavaField field = docField.getJavaField();
String subTypeName = docField.getFullyQualifiedName();
String fieldName = field.getName();
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
}
if (field.isTransient() && skipTransientField) {
continue;
}
String fieldName = docField.getFieldName();
if (ignoreFields.containsKey(fieldName)) {
continue;
}
String subTypeName = docField.getFullyQualifiedName();
if ((responseFieldToUnderline && isResp) || (requestFieldToUnderline && !isResp)) {
fieldName = StringUtil.camelToUnderline(fieldName);
}
@ -250,25 +206,6 @@ public class JsonBuildHelper {
List<JavaAnnotation> annotations = docField.getAnnotations();
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getValue();
if (ValidatorAnnotations.NULL.equals(annotationName) && !isResp) {
List<String> groupClassList = JavaClassUtil.getParamGroupJavaClass(annotation);
for (String groupClass : groupClassList) {
if (groupClasses.contains(groupClass)) {
continue out;
}
}
}
if (DocAnnotationConstants.JSON_PROPERTY.equalsIgnoreCase(annotationName)) {
AnnotationValue value = annotation.getProperty("access");
if (Objects.nonNull(value)) {
if (JSON_PROPERTY_READ_ONLY.equals(value.getParameterValue()) && !isResp) {
continue out;
}
if (JSON_PROPERTY_WRITE_ONLY.equals(value.getParameterValue()) && isResp) {
continue out;
}
}
}
if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(annotationName)) {
continue out;
} else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName)) {
@ -286,71 +223,62 @@ public class JsonBuildHelper {
}
}
String typeSimpleName = field.getType().getSimpleName();
String fieldGicName = docField.getGenericCanonicalName();
CustomField customResponseField = builder.getCustomRespFieldMap().get(typeName + "." + fieldName);
CustomField customRequestField = builder.getCustomReqFieldMap().get(typeName + "." + fieldName);
if (customRequestField != null && JavaClassUtil.isTargetChildClass(typeName, customRequestField.getOwnerClassName()) && (customRequestField.isIgnore()) && !isResp) {
continue;
}
if (customResponseField != null && JavaClassUtil.isTargetChildClass(typeName, customResponseField.getOwnerClassName()) && (customResponseField.isIgnore()) && isResp) {
continue;
}
String fieldGicName = docField.getGenericCanonicalName();
data0.append("\"").append(fieldName).append("\":");
if (JavaClassValidateUtil.isPrimitive(subTypeName)) {
String fieldValue = "";
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
fieldValue = tagsMap.get(DocTags.MOCK);
if (!DocUtil.javaPrimaryType(typeSimpleName)
&& !JavaClassValidateUtil.isCollection(subTypeName)
&& !JavaClassValidateUtil.isMap(subTypeName)
&& !JavaClassValidateUtil.isArray(subTypeName)) {
if ("String".equals(typeSimpleName)) {
fieldValue = DocUtil.handleJsonStr(fieldValue);
}
}
if (JavaClassValidateUtil.isPrimitive(subTypeName)) {
int data0Length = data0.length();
if (StringUtil.isEmpty(fieldValue)) {
} else {
fieldValue = DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName());
}
if (Objects.nonNull(customRequestField) && !isResp && typeName.equals(customRequestField.getOwnerClassName())) {
JavaFieldUtil.buildCustomField(data0, typeSimpleName, customRequestField);
CustomRespField customResponseField = builder.getCustomRespFieldMap().get(fieldName);
if (null != customResponseField) {
Object val = customResponseField.getValue();
if (null != val) {
if ("String".equals(typeSimpleName)) {
data0.append(DocUtil.handleJsonStr(String.valueOf(val))).append(",");
} else {
data0.append(val).append(",");
}
if (Objects.nonNull(customResponseField) && isResp && typeName.equals(customResponseField.getOwnerClassName())) {
JavaFieldUtil.buildCustomField(data0, typeSimpleName, customResponseField);
} else {
data0.append(fieldValue).append(",");
}
if (data0.length() == data0Length) {
} else {
data0.append(fieldValue).append(",");
}
} else {
if (JavaClassValidateUtil.isCollection(subTypeName) || JavaClassValidateUtil.isArray(subTypeName)) {
if (StringUtil.isNotEmpty(fieldValue)) {
data0.append(fieldValue).append(",");
continue out;
}
if (globGicName.length > 0 && "java.util.List".equals(fieldGicName)) {
fieldGicName = fieldGicName + "<T>";
}
if (JavaClassValidateUtil.isArray(subTypeName)) {
fieldGicName = fieldGicName.substring(0, fieldGicName.lastIndexOf("["));
fieldGicName = "java.util.List<" + fieldGicName + ">";
fieldGicName = JavaClassValidateUtil.isArray(subTypeName) ? fieldGicName.substring(0, fieldGicName.indexOf("[")) : fieldGicName;
if (DocClassUtil.getSimpleGicName(fieldGicName).length == 0) {
data0.append("{\"object\":\"any object\"},");
continue out;
}
String gicName = DocClassUtil.getSimpleGicName(fieldGicName)[0];
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName)) {
data0.append("[").append(DocUtil.jsonValueByType(gicName)).append("]").append(",");
data0.append("[").append("\"").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("\"]").append(",");
} else if (DocGlobalConstants.JAVA_LIST_FULLY.equals(gicName)) {
data0.append("[{\"object\":\"any object\"}],");
data0.append("{\"object\":\"any object\"},");
} else if (gicName.length() == 1) {
if (globGicName.length == 0) {
data0.append("[{\"object\":\"any object\"}],");
data0.append("{\"object\":\"any object\"},");
continue out;
}
String gicName1 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName);
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
data0.append("[").append(DocUtil.jsonValueByType(gicName1)).append("]").append(",");
data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"]").append(",");
} else {
if (!typeName.equals(gicName1)) {
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, groupClasses, builder))
.append("]").append(",");
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
@ -361,49 +289,30 @@ public class JsonBuildHelper {
data0.append("[{\"mapKey\":{}}],");
continue out;
}
JavaClass arraySubClass = builder.getJavaProjectBuilder().getClassByName(gicName);
if (arraySubClass.isEnum()) {
Object value = JavaClassUtil.getEnumValue(arraySubClass, Boolean.FALSE);
data0.append("[").append(value).append("],");
continue out;
}
data0.append("[").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, groupClasses, builder)).append("]").append(",");
data0.append("[").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
}
} else if (JavaClassValidateUtil.isMap(subTypeName)) {
if (StringUtil.isNotEmpty(fieldValue)) {
data0.append(fieldValue).append(",");
continue out;
}
if (JavaClassValidateUtil.isMap(fieldGicName)) {
data0.append("{").append("\"mapKey\":{}},");
continue out;
}
String gicName = fieldGicName.substring(fieldGicName.indexOf(",") + 1, fieldGicName.indexOf(">"));
if (gicName.length() == 1) {
String gicName1 = "";
if (Objects.nonNull(genericMap.get(gicName))) {
gicName1 = genericMap.get(gicName);
} else {
if (globGicName.length > 0) {
gicName1 = globGicName[0];
}
}
String gicName1 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName);
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
data0.append("{").append("\"mapKey\":").append(DocUtil.jsonValueByType(gicName1)).append("},");
data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"},");
} else {
if (!typeName.equals(gicName1)) {
data0.append("{").append("\"mapKey\":")
.append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, groupClasses, builder)).append("},");
data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("},");
} else {
data0.append("{\"mapKey\":{}},");
}
}
} else {
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, groupClasses, builder))
.append("},");
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("},");
}
} else if (subTypeName.length() == 1) {
if (!typeName.equals(genericCanonicalName)) {
@ -412,45 +321,38 @@ public class JsonBuildHelper {
data0.append(DocUtil.jsonValueByType(gicName)).append(",");
} else {
String simple = DocClassUtil.getSimpleName(gicName);
data0.append(buildJson(simple, gicName, isResp, nextLevel, registryClasses, groupClasses, builder)).append(",");
data0.append(buildJson(simple, gicName, isResp, nextLevel, registryClasses, builder)).append(",");
}
} else {
data0.append("{},");
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
if (StringUtil.isNotEmpty(field.getComment())) {
// from source code
if (isGenerics) {
data0.append("{\"object\":\"any object\"},");
} else if (globGicName.length > 0) {
String gicName = genericMap.get(subTypeName) == null ? globGicName[0] : genericMap.get(subTypeName);
if (!typeName.equals(genericCanonicalName)) {
if (JavaClassValidateUtil.isPrimitive(gicName)) {
data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, nextLevel, registryClasses, groupClasses, builder)).append("\",");
data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, nextLevel, registryClasses, builder)).append("\",");
} else {
String simpleName = DocClassUtil.getSimpleName(gicName);
data0.append(buildJson(simpleName, gicName, isResp, nextLevel, registryClasses, groupClasses, builder)).append(",");
data0.append(buildJson(simpleName, gicName, isResp, nextLevel, registryClasses, builder)).append(",");
}
} else {
data0.append("{},");
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
} else {
data0.append("{},");
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
} else if (typeName.equals(subTypeName)) {
data0.append("{\"$ref\":\"...\"}").append(",");
} else {
javaClass = field.getType();
if (javaClass.isEnum()) {
// Override old value
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
data0.append(tagsMap.get(DocTags.MOCK)).append(",");
} else {
javaClass = builder.getJavaProjectBuilder().getClassByName(subTypeName);
if (!isResp && javaClass.isEnum()) {
Object value = JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE);
data0.append(value).append(",");
}
} else {
fieldGicName = DocUtil.formatFieldTypeGicName(genericMap, globGicName, fieldGicName);
data0.append(buildJson(subTypeName, fieldGicName, isResp, nextLevel, registryClasses, groupClasses, builder)).append(",");
data0.append(buildJson(subTypeName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append(",");
}
}
}
@ -462,4 +364,6 @@ public class JsonBuildHelper {
data0.append("}");
return data0.toString();
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -31,31 +31,28 @@ import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.DocTags;
import com.power.doc.constants.ValidatorAnnotations;
import com.power.doc.model.*;
import com.power.doc.utils.DocClassUtil;
import com.power.doc.utils.DocUtil;
import com.power.doc.utils.JavaClassUtil;
import com.power.doc.utils.JavaClassValidateUtil;
import com.power.doc.utils.*;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.expression.AnnotationValue;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
import static com.power.doc.constants.DocGlobalConstants.*;
import static com.power.doc.constants.DocGlobalConstants.JAVA_LIST_FULLY;
import static com.power.doc.constants.DocGlobalConstants.NO_COMMENTS_FOUND;
/**
* @author yu 2019/12/21.
*/
public class ParamsBuildHelper {
public static List<ApiParam> buildParams(String className, String pre, int level, String isRequired, boolean isResp,
public static List<ApiParam> buildParams(String className, String pre, int level, String isRequired,
Map<String, CustomRespField> responseFieldMap, boolean isResp,
Map<String, String> registryClasses, ProjectDocConfigBuilder projectBuilder,
List<String> groupClasses, int pid, boolean jsonRequest) {
List<String> groupClasses, int pid) {
//存储泛型所对应的实体类
Map<String, String> genericMap = new HashMap<>(10);
if (StringUtil.isEmpty(className)) {
@ -71,7 +68,6 @@ public class ParamsBuildHelper {
if (registryClasses.containsKey(className) && level > registryClasses.size()) {
return paramList;
}
Map<String, CustomField> responseFieldMap = projectBuilder.getCustomRespFieldMap();
boolean skipTransientField = apiConfig.isSkipTransientField();
boolean isShowJavaType = projectBuilder.getApiConfig().getShowJavaType();
boolean requestFieldToUnderline = projectBuilder.getApiConfig().isRequestFieldToUnderline();
@ -82,16 +78,9 @@ public class ParamsBuildHelper {
String simpleName = DocClassUtil.getSimpleName(className);
String[] globGicName = DocClassUtil.getSimpleGicName(className);
JavaClass cls = projectBuilder.getClassByName(simpleName);
if (Objects.isNull(globGicName) || globGicName.length < 1) {
// obtain generics from parent class
JavaClass superJavaClass = cls != null ? cls.getSuperJavaClass() : null;
if (superJavaClass != null && !"Object".equals(superJavaClass.getSimpleName())) {
globGicName = DocClassUtil.getSimpleGicName(superJavaClass.getGenericFullyQualifiedName());
}
}
//如果存在泛型 则将泛型与类名的对应关系存起来
JavaClassUtil.genericParamMap(genericMap, cls, globGicName);
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new LinkedHashMap<>());
List<DocJavaField> fields = JavaClassUtil.getFields(cls, 0, new HashSet<>());
if (JavaClassValidateUtil.isPrimitive(simpleName)) {
String processedType = isShowJavaType ? simpleName : DocClassUtil.processTypeNameForParams(simpleName.toLowerCase());
paramList.addAll(primitiveReturnRespComment(processedType));
@ -101,42 +90,37 @@ public class ParamsBuildHelper {
if (JavaClassValidateUtil.isArray(gicName)) {
gicName = gicName.substring(0, gicName.indexOf("["));
}
paramList.addAll(buildParams(gicName, pre, nextLevel, isRequired, isResp,
registryClasses, projectBuilder, groupClasses, pid, jsonRequest));
paramList.addAll(buildParams(gicName, pre, nextLevel, isRequired, responseFieldMap, isResp,
registryClasses, projectBuilder, groupClasses, pid));
}
} else if (JavaClassValidateUtil.isMap(simpleName)) {
if (globGicName.length == 2) {
paramList.addAll(buildParams(globGicName[1], pre, nextLevel, isRequired, isResp,
registryClasses, projectBuilder, groupClasses, pid, jsonRequest));
paramList.addAll(buildParams(globGicName[1], pre, nextLevel, isRequired, responseFieldMap, isResp,
registryClasses, projectBuilder, groupClasses, pid));
}
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(className)) {
ApiParam param = ApiParam.of().setId(pid + 1).setField(pre + "any object").setType("object").setPid(pid);
ApiParam param = ApiParam.of().setField(pre + "any object").setType("object").setPid(pid);
if (StringUtil.isEmpty(isRequired)) {
param.setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
} else {
param.setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setRequired(false).setVersion(DocGlobalConstants.DEFAULT_VERSION);
}
paramList.add(param);
} else if (JavaClassValidateUtil.isReactor(simpleName)) {
if (globGicName.length > 0) {
paramList.addAll(buildParams(globGicName[0], pre, nextLevel, isRequired, isResp,
registryClasses, projectBuilder, groupClasses, pid, jsonRequest));
}
} else {
Map<String, String> ignoreFields = JavaClassUtil.getClassJsonIgnoreFields(cls);
boolean isGenerics = JavaFieldUtil.checkGenerics(fields);
out:
for (DocJavaField docField : fields) {
String maxLength = null;
JavaField field = docField.getJavaField();
String fieldName = field.getName();
String subTypeName = docField.getFullyQualifiedName();
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
}
if (field.isTransient() && skipTransientField) {
continue;
}
String fieldName = docField.getFieldName();
if (ignoreFields.containsKey(fieldName)) {
continue;
}
String subTypeName = docField.getFullyQualifiedName();
if ((responseFieldToUnderline && isResp) || (requestFieldToUnderline && !isResp)) {
fieldName = StringUtil.camelToUnderline(fieldName);
}
@ -158,46 +142,13 @@ public class ParamsBuildHelper {
since = tagsMap.get(DocTags.SINCE);
}
}
boolean strRequired = false;
int annotationCounter = 0;
CustomField customResponseField = responseFieldMap.get(simpleName + "." + fieldName);
if (customResponseField != null && JavaClassUtil.isTargetChildClass(simpleName, customResponseField.getOwnerClassName())
&& (customResponseField.isIgnore()) && isResp) {
continue;
}
CustomField customRequestField = projectBuilder.getCustomReqFieldMap().get(simpleName + "." + fieldName);
if (customRequestField != null && JavaClassUtil.isTargetChildClass(simpleName, customRequestField.getOwnerClassName())
&& (customRequestField.isIgnore()) && !isResp) {
continue;
}
an:
for (JavaAnnotation annotation : javaAnnotations) {
String simpleAnnotationName = annotation.getType().getValue();
AnnotationValue annotationValue = null;
if (DocAnnotationConstants.MAX.equalsIgnoreCase(simpleAnnotationName)) {
annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
}
if (DocAnnotationConstants.SIZE.equalsIgnoreCase(simpleAnnotationName)) {
annotationValue = annotation.getProperty(DocAnnotationConstants.MAX);
}
if (DocAnnotationConstants.LENGTH.equalsIgnoreCase(simpleAnnotationName)) {
annotationValue = annotation.getProperty(DocAnnotationConstants.MAX);
}
if (!Objects.isNull(annotationValue)) {
maxLength = annotationValue.toString();
}
if (DocAnnotationConstants.JSON_PROPERTY.equalsIgnoreCase(simpleAnnotationName)) {
AnnotationValue value = annotation.getProperty("access");
if (Objects.nonNull(value)) {
if (JSON_PROPERTY_READ_ONLY.equals(value.getParameterValue()) && !isResp) {
continue out;
}
if (JSON_PROPERTY_WRITE_ONLY.equals(value.getParameterValue()) && isResp) {
continue out;
}
}
}
if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(simpleAnnotationName)) {
continue out;
} else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(simpleAnnotationName)) {
@ -217,7 +168,7 @@ public class ParamsBuildHelper {
for (String javaClass : groupClassList) {
if (groupClasses.contains(javaClass)) {
strRequired = false;
continue out;
break an;
}
}
} else if (JavaClassValidateUtil.isJSR303Required(simpleAnnotationName) && !isResp) {
@ -237,16 +188,6 @@ public class ParamsBuildHelper {
break an;
}
}
String fieldValue = "";
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
fieldValue = tagsMap.get(DocTags.MOCK);
if (!DocUtil.javaPrimaryType(typeSimpleName)
&& !JavaClassValidateUtil.isCollection(subTypeName)
&& !JavaClassValidateUtil.isMap(subTypeName)
&& !JavaClassValidateUtil.isArray(subTypeName)) {
fieldValue = DocUtil.handleJsonStr(fieldValue);
}
}
if (annotationCounter < 1) {
doc:
if (tagsMap.containsKey(DocTags.REQUIRED)) {
@ -254,52 +195,29 @@ public class ParamsBuildHelper {
break doc;
}
}
// cover response value
if (Objects.nonNull(customResponseField) && isResp && Objects.nonNull(customResponseField.getValue())
&& JavaClassUtil.isTargetChildClass(simpleName, customResponseField.getOwnerClassName())) {
fieldValue = String.valueOf(customResponseField.getValue());
}
// cover request value
if (Objects.nonNull(customRequestField) && !isResp && Objects.nonNull(customRequestField.getValue())
&& JavaClassUtil.isTargetChildClass(simpleName, customRequestField.getOwnerClassName())) {
fieldValue = String.valueOf(customRequestField.getValue());
}
//cover required
if (customRequestField != null && !isResp && JavaClassUtil.isTargetChildClass(simpleName, customRequestField.getOwnerClassName())
&& customRequestField.isRequire()) {
strRequired = true;
}
//cover comment
String comment = "";
if (null != customRequestField && StringUtil.isNotEmpty(customRequestField.getDesc())
&& JavaClassUtil.isTargetChildClass(simpleName, customRequestField.getOwnerClassName()) && !isResp) {
comment = customRequestField.getDesc();
}
CustomRespField customResponseField = responseFieldMap.get(field.getName());
String comment;
if (null != customResponseField && StringUtil.isNotEmpty(customResponseField.getDesc())
&& JavaClassUtil.isTargetChildClass(simpleName, customResponseField.getOwnerClassName()) && isResp) {
&& simpleName.equals(customResponseField.getOwnerClassName())) {
comment = customResponseField.getDesc();
}
if (StringUtils.isBlank(comment)) {
} else {
comment = docField.getComment();
}
if (StringUtil.isNotEmpty(comment)) {
comment = DocUtil.replaceNewLineToHtmlBr(comment);
}
// file
if (JavaClassValidateUtil.isFile(fieldGicName)) {
if (fieldGicName.contains(DocGlobalConstants.MULTIPART_FILE_FULLY)) {
ApiParam param = ApiParam.of().setField(pre + fieldName).setType("file")
.setPid(pid).setId(paramList.size() + pid + 1)
.setMaxLength(maxLength)
.setDesc(comment).setRequired(Boolean.valueOf(isRequired)).setVersion(since);
paramList.add(param);
continue;
}
if (JavaClassValidateUtil.isPrimitive(subTypeName)) {
if (StringUtil.isEmpty(fieldValue)) {
fieldValue = DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName());
}
ApiParam param = ApiParam.of().setField(pre + fieldName);
param.setPid(pid).setMaxLength(maxLength).setValue(fieldValue);
param.setPid(pid);
String processedType = isShowJavaType ? typeSimpleName : DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase());
param.setType(processedType);
if (StringUtil.isNotEmpty(comment)) {
@ -308,6 +226,28 @@ public class ParamsBuildHelper {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND, since, strRequired);
}
} else {
ApiParam param = ApiParam.of().setField(pre + fieldName).setPid(pid);
JavaClass javaClass = projectBuilder.getJavaProjectBuilder().getClassByName(subTypeName);
String enumComments = javaClass.getComment();
if (javaClass.isEnum()) {
if (projectBuilder.getApiConfig().getInlineEnum()) {
ApiDataDictionary dataDictionary = projectBuilder.getApiConfig().getDataDictionary(javaClass.getSimpleName());
if (dataDictionary == null) {
comment = comment + JavaClassUtil.getEnumParams(javaClass);
} else {
comment = comment + "(enum:" + dictionaryListComment(dataDictionary) + ")";
}
} else {
enumComments = DocUtil.replaceNewLineToHtmlBr(enumComments);
comment = comment + "<br/>" + JavaClassUtil.getEnumParams(javaClass) + "<br/>";
if (enumComments != null) {
comment = comment + "(See: " + enumComments + ")";
}
comment = StringUtil.removeQuotes(comment);
}
param.setType(DocGlobalConstants.ENUM);
}
String appendComment = "";
if (displayActualType) {
if (globGicName.length > 0) {
@ -320,41 +260,20 @@ public class ParamsBuildHelper {
appendComment = " (ActualType: " + JavaClassUtil.getClassSimpleName(docField.getActualJavaType()) + ")";
}
}
StringBuilder preBuilder = new StringBuilder();
for (int j = 0; j < level; j++) {
preBuilder.append(DocGlobalConstants.FIELD_SPACE);
}
preBuilder.append("└─");
int fieldPid;
ApiParam param = ApiParam.of().setField(pre + fieldName).setPid(pid).setMaxLength(maxLength);
//如果已经设置返回类型 不需要再次设置
if (param.getType() == null) {
String processedType;
if (typeSimpleName.length() == 1) {
String gicName = JAVA_OBJECT_FULLY;
if (Objects.nonNull(genericMap.get(typeSimpleName))) {
gicName = genericMap.get(subTypeName);
} else {
if (globGicName.length > 0) {
gicName = globGicName[0];
}
}
if (JavaClassValidateUtil.isPrimitive(gicName)) {
processedType = DocClassUtil.processTypeNameForParams(gicName);
} else {
processedType = DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase());
}
} else {
processedType = isShowJavaType ? typeSimpleName : DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase());
}
param.setType(processedType);
JavaClass javaClass = field.getType();
if (javaClass.isEnum()) {
comment = comment + handleEnumComment(javaClass, projectBuilder);
param.setType(DocGlobalConstants.ENUM);
if (!isResp) {
}
if (!isResp && javaClass.isEnum()) {
List<JavaMethod> methods = javaClass.getMethods();
int index = 0;
enumOut:
for (JavaMethod method : methods) {
List<JavaAnnotation> javaAnnotationList = method.getAnnotations();
@ -368,93 +287,7 @@ public class ParamsBuildHelper {
}
index++;
}
Object value = JavaClassUtil.getEnumValue(javaClass, !jsonRequest);
param.setValue(String.valueOf(value));
param.setEnumValues(JavaClassUtil.getEnumValues(javaClass));
}
// Override old value
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
param.setValue(tagsMap.get(DocTags.MOCK));
}
if (StringUtil.isNotEmpty(comment)) {
commonHandleParam(paramList, param, isRequired, comment + appendComment, since, strRequired);
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
} else if (JavaClassValidateUtil.isCollection(subTypeName) || JavaClassValidateUtil.isArray(subTypeName)) {
param.setType("array");
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
param.setValue(fieldValue);
}
if (globGicName.length > 0 && "java.util.List".equals(fieldGicName)) {
fieldGicName = fieldGicName + "<T>";
}
if (JavaClassValidateUtil.isArray(subTypeName)) {
fieldGicName = fieldGicName.substring(0, fieldGicName.lastIndexOf("["));
fieldGicName = "java.util.List<" + fieldGicName + ">";
}
String[] gNameArr = DocClassUtil.getSimpleGicName(fieldGicName);
if (gNameArr.length == 0) {
continue out;
}
if (gNameArr.length > 0) {
String gName = DocClassUtil.getSimpleGicName(fieldGicName)[0];
JavaClass javaClass1 = projectBuilder.getJavaProjectBuilder().getClassByName(gName);
comment = comment + handleEnumComment(javaClass1, projectBuilder);
}
String gName = gNameArr[0];
if (JavaClassValidateUtil.isPrimitive(gName)) {
String builder = DocUtil.jsonValueByType(gName) +
"," +
DocUtil.jsonValueByType(gName);
if (StringUtil.isEmpty(fieldValue)) {
param.setValue(DocUtil.handleJsonStr(builder));
} else {
param.setValue(fieldValue);
}
if (StringUtil.isNotEmpty(comment)) {
commonHandleParam(paramList, param, isRequired, comment + appendComment, since, strRequired);
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
} else {
if (StringUtil.isNotEmpty(comment)) {
commonHandleParam(paramList, param, isRequired, comment + appendComment, since, strRequired);
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
fieldPid = paramList.size() + pid;
if (!simpleName.equals(gName) && !gName.equals(simpleName)) {
JavaClass arraySubClass = projectBuilder.getJavaProjectBuilder().getClassByName(gName);
if (arraySubClass.isEnum()) {
Object value = JavaClassUtil.getEnumValue(arraySubClass, Boolean.FALSE);
StringBuilder sb = new StringBuilder();
sb.append("[\"").append(value).append("\"]");
param.setValue(sb.toString());
} else if (gName.length() == 1) {
// handle generic
int len = globGicName.length;
if (len < 1) {
continue out;
}
String gicName = genericMap.get(gName) != null ? genericMap.get(gName) : globGicName[0];
if (!JavaClassValidateUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
paramList.addAll(buildParams(gicName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
}
} else {
paramList.addAll(buildParams(gName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
}
}
}
} else if (JavaClassValidateUtil.isMap(subTypeName)) {
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
param.setType("map");
param.setValue(fieldValue);
param.setType(DocGlobalConstants.ENUM);
}
if (StringUtil.isNotEmpty(comment)) {
@ -462,41 +295,67 @@ public class ParamsBuildHelper {
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
fieldPid = paramList.size() + pid;
StringBuilder preBuilder = new StringBuilder();
for (int j = 0; j < level; j++) {
preBuilder.append(DocGlobalConstants.FIELD_SPACE);
}
preBuilder.append("└─");
int fieldPid = paramList.size() + pid;
if (JavaClassValidateUtil.isMap(subTypeName)) {
String gNameTemp = fieldGicName;
String valType = DocClassUtil.getMapKeyValueType(gNameTemp).length == 0 ? gNameTemp : DocClassUtil.getMapKeyValueType(gNameTemp)[1];
if (JavaClassValidateUtil.isMap(gNameTemp) || JAVA_OBJECT_FULLY.equals(valType)) {
if (JavaClassValidateUtil.isMap(gNameTemp)) {
ApiParam param1 = ApiParam.of().setField(preBuilder.toString() + "any object")
.setId(fieldPid + 1).setPid(fieldPid)
.setMaxLength(maxLength)
.setId(paramList.size() + 1).setPid(fieldPid)
.setType("object").setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
paramList.add(param1);
continue;
}
String valType = DocClassUtil.getMapKeyValueType(gNameTemp)[1];
if (!JavaClassValidateUtil.isPrimitive(valType)) {
if (valType.length() == 1) {
String gicName = genericMap.get(valType);
if (!JavaClassValidateUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
paramList.addAll(buildParams(gicName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else {
paramList.addAll(buildParams(valType, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
}
} else if (JavaClassValidateUtil.isCollection(subTypeName)) {
String gNameTemp = fieldGicName;
if (globGicName.length > 0 && JAVA_LIST_FULLY.equals(gNameTemp)) {
gNameTemp = gNameTemp + "<T>";
}
String[] gNameArr = DocClassUtil.getSimpleGicName(gNameTemp);
if (gNameArr.length == 0) {
continue out;
}
String gName = DocClassUtil.getSimpleGicName(gNameTemp)[0];
if (!JavaClassValidateUtil.isPrimitive(gName)) {
if (!simpleName.equals(gName) && !gName.equals(simpleName)) {
if (gName.length() == 1) {
// handle generic
int len = globGicName.length;
if (len > 0) {
String gicName = genericMap.get(gName) != null ? genericMap.get(gName) : globGicName[0];
if (!JavaClassValidateUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
paramList.addAll(buildParams(gicName, preBuilder.toString(), nextLevel, isRequired,
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
}
} else {
paramList.addAll(buildParams(gName, preBuilder.toString(), nextLevel, isRequired,
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
}
}
} else if (subTypeName.length() == 1 || DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
if (StringUtil.isNotEmpty(comment)) {
commonHandleParam(paramList, param, isRequired, comment + appendComment, since, strRequired);
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
fieldPid = paramList.size() + pid;
// handle java generic or object
if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName) && StringUtil.isNotEmpty(field.getComment())) {
if (isGenerics && DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
ApiParam param1 = ApiParam.of().setField(preBuilder.toString() + "any object")
.setId(paramList.size())
.setMaxLength(maxLength)
.setType("object").setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
paramList.add(param1);
} else if (!simpleName.equals(className)) {
@ -507,47 +366,48 @@ public class ParamsBuildHelper {
//do nothing
} else if (gicName.contains("<")) {
if (JavaClassValidateUtil.isCollection(simple)) {
param.setType(ARRAY);
String gName = DocClassUtil.getSimpleGicName(gicName)[0];
if (!JavaClassValidateUtil.isPrimitive(gName)) {
paramList.addAll(buildParams(gName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else if (JavaClassValidateUtil.isMap(simple)) {
String valType = DocClassUtil.getMapKeyValueType(gicName)[1];
if (!JavaClassValidateUtil.isPrimitive(valType)) {
paramList.addAll(buildParams(valType, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else {
paramList.addAll(buildParams(gicName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else {
paramList.addAll(buildParams(gicName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else {
paramList.addAll(buildParams(subTypeName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
}
} else if (JavaClassValidateUtil.isArray(subTypeName)) {
fieldGicName = fieldGicName.substring(0, fieldGicName.indexOf("["));
if (className.equals(fieldGicName)) {
//do nothing
} else if (!JavaClassValidateUtil.isPrimitive(fieldGicName)) {
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), nextLevel, isRequired,
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
} else if (simpleName.equals(subTypeName)) {
//do nothing
} else {
if (StringUtil.isNotEmpty(comment)) {
commonHandleParam(paramList, param, isRequired, comment + appendComment, since, strRequired);
} else {
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND + appendComment, since, strRequired);
}
fieldGicName = DocUtil.formatFieldTypeGicName(genericMap, globGicName, fieldGicName);
fieldPid = paramList.size() + pid;
if (!javaClass.isEnum()) {
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), nextLevel, isRequired,
isResp, registryClasses, projectBuilder, groupClasses, fieldPid, jsonRequest));
responseFieldMap, isResp, registryClasses, projectBuilder, groupClasses, fieldPid));
}
}
}
}
}//end field
}
return paramList;
}
@ -555,8 +415,7 @@ public class ParamsBuildHelper {
public static String dictionaryListComment(ApiDataDictionary dictionary) {
List<EnumDictionary> enumDataDict = dictionary.getEnumDataDict();
return enumDataDict.stream().map(apiDataDictionary ->
apiDataDictionary.getName() + "-(\"" + apiDataDictionary.getValue() + "\",\""
+ apiDataDictionary.getDesc() + "\")"
apiDataDictionary.getValue() + ":" + apiDataDictionary.getDesc()
).collect(Collectors.joining(","));
}
@ -580,27 +439,4 @@ public class ParamsBuildHelper {
param.setId(paramList.size() + param.getPid() + 1);
paramList.add(param);
}
private static String handleEnumComment(JavaClass javaClass, ProjectDocConfigBuilder projectBuilder) {
String comment = "";
if (!javaClass.isEnum()) {
return comment;
}
String enumComments = javaClass.getComment();
if (projectBuilder.getApiConfig().getInlineEnum()) {
ApiDataDictionary dataDictionary = projectBuilder.getApiConfig().getDataDictionary(javaClass.getCanonicalName());
if (Objects.isNull(dataDictionary)) {
comment = comment + "<br/>" + JavaClassUtil.getEnumParams(javaClass);
} else {
comment = comment + "[enum:" + dictionaryListComment(dataDictionary) + "]";
}
} else {
enumComments = DocUtil.replaceNewLineToHtmlBr(enumComments);
if (StringUtil.isNotEmpty(enumComments)) {
comment = comment + "(See: " + enumComments + ")";
}
comment = StringUtil.removeQuotes(comment);
}
return comment;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -26,7 +26,6 @@ import com.power.common.util.CollectionUtil;
import com.power.doc.constants.DocLanguage;
import com.power.doc.model.rpc.RpcApiDependency;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -44,11 +43,6 @@ public class ApiConfig {
*/
private String serverUrl;
/**
* Path Prefix, eg: Servlet ContextPath
*/
private String pathPrefix = "";
/**
* Set comments check mode
*/
@ -73,13 +67,7 @@ public class ApiConfig {
/**
* list of Request headers
*/
private List<ApiReqParam> requestHeaders;
/**
* @since 2.2.2
* list of Request params
*/
private List<ApiReqParam> requestParams;
private List<ApiReqHeader> requestHeaders;
/**
* @since 1.7.5
@ -90,11 +78,7 @@ public class ApiConfig {
/**
* list of custom response filed
*/
private List<CustomField> customResponseFields;
/**
* list of custom request field
*/
private List<CustomField> customRequestFields;
private List<CustomRespField> customResponseFields;
/**
* List of error code
@ -158,22 +142,11 @@ public class ApiConfig {
*/
private List<ApiConstant> apiConstants;
/**
* @since 2.0.7
* project group
*/
private String group;
/**
* @since 1.7.5
* project name
*/
private String projectName;
/**
* @since 2.0.7
* project cn name
*/
private String projectCName;
/**
* Skip Transient Field
@ -263,175 +236,25 @@ public class ApiConfig {
/**
* request ignore param
*
* @return
* @since 1.9.2
* @return
*/
private List<String> ignoreRequestParams;
/**
* display actual type of generic
*
* @since 1.9.6
*/
private boolean displayActualType;
/**
* Support Spring MVC ResponseBodyAdvice
*
* @since 1.9.8
*/
private BodyAdvice responseBodyAdvice;
/**
* @since 2.1.4
*/
private BodyAdvice requestBodyAdvice;
private ResponseBodyAdvice responseBodyAdvice;
private String style;
private String highlightStyleLink;
/**
* create debug page
*/
private boolean createDebugPage;
/**
* Spring MVC url suffix
*
* @since 2.1.0
*/
private String urlSuffix;
/**
* public static final String APP_KEY = "20201216788835306945118208";
* public static final String SECRET = "W.ZyGMOB9Q0UqujVxnfi@.I#V&tUUYZR";
* public static final String APP_TOKEN = "2f9a7d3858a147b7845ebb48785d4dc7";
* public static final String OPEN_URL = "http://torna.opensphere.cn/api/";
* @return
*/
/**
* Torna appKey
*/
private String appKey;
/**
* Torna Secret
*/
private String secret;
/**
* Torna appToken
*/
private String appToken;
/**
* Torna openUrl
*/
private String openUrl;
/**
* Debugging environment name
*/
private String debugEnvName;
/**
* Url of the debugging environment
*/
private String debugEnvUrl;
/**
* Show log when pushing document to torna
*/
private boolean tornaDebug = true;
/**
* The operator who pushes the document to Torna
*/
private String author;
/**
* smart-doc supported framework, if not set default is spring,
*/
private String framework;
private List<ApiGroup> groups;
/**
* replace old document while push to torna
* @since 2.2.4
*/
private Boolean replace;
/**
* @since 2.2.5
*/
private boolean requestParamsTable = Boolean.TRUE;
/**
* @since 2.2.5
*/
private boolean responseParamsTable = Boolean.TRUE;
public String getPathPrefix() {
return pathPrefix;
}
public void setPathPrefix(String pathPrefix) {
this.pathPrefix = pathPrefix;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public boolean isTornaDebug() {
return tornaDebug;
}
public void setTornaDebug(boolean tornaDebug) {
this.tornaDebug = tornaDebug;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getAppToken() {
return appToken;
}
public void setAppToken(String appToken) {
this.appToken = appToken;
}
public String getOpenUrl() {
return openUrl;
}
public void setOpenUrl(String openUrl) {
this.openUrl = openUrl;
}
public String getServerUrl() {
return serverUrl;
}
@ -456,60 +279,25 @@ public class ApiConfig {
this.outPath = outPath;
}
public List<ApiReqParam> getRequestHeaders() {
public List<ApiReqHeader> getRequestHeaders() {
return requestHeaders;
}
public void setRequestHeaders(List<ApiReqParam> requestHeaders) {
this.requestHeaders = requestHeaders;
}
public void setRequestHeaders(ApiReqParam... requestHeaders) {
public void setRequestHeaders(ApiReqHeader... requestHeaders) {
this.requestHeaders = CollectionUtil.asList(requestHeaders);
this.requestHeaders.forEach(header -> header.setDesc(header.getDesc() + "(Global)"));
this.requestHeaders.stream().map(header -> header.setDesc(header.getDesc() + "(Global)"))
.collect(Collectors.toList());
}
public List<ApiGroup> getGroups() {
return groups;
}
public ApiConfig setGroups(List<ApiGroup> groups) {
this.groups = groups;
return this;
}
public ApiConfig setGroups(ApiGroup... groups) {
this.groups = CollectionUtil.asList(groups);
return this;
}
public List<ApiReqParam> getRequestParams() {
return requestParams;
}
public ApiConfig setRequestParams(List<ApiReqParam> requestParams) {
this.requestParams = requestParams;
return this;
}
public void setRequestParams(ApiReqParam... requestParams) {
this.requestParams = CollectionUtil.asList(requestParams);
this.requestParams.forEach(param -> param.setDesc(param.getDesc() + "(Global)"));
}
public List<CustomField> getCustomResponseFields() {
public List<CustomRespField> getCustomResponseFields() {
return customResponseFields;
}
public void setCustomResponseFields(List<CustomField> customResponseFields) {
this.customResponseFields = customResponseFields;
}
public void setCustomResponseFields(CustomField... customResponseFields) {
public void setCustomResponseFields(CustomRespField... customResponseFields) {
this.customResponseFields = CollectionUtil.asList(customResponseFields);
}
public List<ApiErrorCode> getErrorCodes() {
return errorCodes;
}
@ -522,10 +310,6 @@ public class ApiConfig {
return sourceCodePaths;
}
public void setSourceCodePaths(List<SourceCodePath> sourceCodePaths) {
this.sourceCodePaths = sourceCodePaths;
}
public void setSourceCodePaths(SourceCodePath... sourcePaths) {
this.sourceCodePaths = CollectionUtil.asList(sourcePaths);
}
@ -550,14 +334,11 @@ public class ApiConfig {
return revisionLogs;
}
public void setRevisionLogs(List<RevisionLog> revisionLogs) {
this.revisionLogs = revisionLogs;
}
public void setRevisionLogs(RevisionLog... revisionLogs) {
this.revisionLogs = CollectionUtil.asList(revisionLogs);
}
public boolean isMd5EncryptedHtmlName() {
return md5EncryptedHtmlName;
}
@ -586,31 +367,23 @@ public class ApiConfig {
return dataDictionaries;
}
public void setDataDictionaries(List<ApiDataDictionary> dataDictionaries) {
this.dataDictionaries = dataDictionaries;
}
public void setDataDictionaries(ApiDataDictionary... dataDictConfigs) {
this.dataDictionaries = CollectionUtil.asList(dataDictConfigs);
}
public ApiDataDictionary getDataDictionary(String enumClassName) {
public ApiDataDictionary getDataDictionary(String enumClassSimpleName) {
if (Objects.isNull(this.dataDictionaries)) {
return null;
}
return this.dataDictionaries.stream().filter((apiDataDictionary ->
enumClassName.equalsIgnoreCase(apiDataDictionary.getEnumClassName())))
.findFirst().orElse(null);
enumClassSimpleName.equalsIgnoreCase(apiDataDictionary.getEnumClassName())))
.findFirst().orElse(new ApiDataDictionary());
}
public List<ApiErrorCodeDictionary> getErrorCodeDictionaries() {
return errorCodeDictionaries;
}
public void setErrorCodeDictionaries(List<ApiErrorCodeDictionary> errorCodeDictionaries) {
this.errorCodeDictionaries = errorCodeDictionaries;
}
public void setErrorCodeDictionaries(ApiErrorCodeDictionary... errorCodeDictConfigs) {
this.errorCodeDictionaries = CollectionUtil.asList(errorCodeDictConfigs);
}
@ -619,10 +392,6 @@ public class ApiConfig {
return apiObjectReplacements;
}
public void setApiObjectReplacements(List<ApiObjectReplacement> apiObjectReplacements) {
this.apiObjectReplacements = apiObjectReplacements;
}
public void setApiObjectReplacements(ApiObjectReplacement... apiObjectReplaces) {
this.apiObjectReplacements = CollectionUtil.asList(apiObjectReplaces);
}
@ -631,10 +400,6 @@ public class ApiConfig {
return rpcApiDependencies;
}
public void setRpcApiDependencies(List<RpcApiDependency> rpcApiDependencies) {
this.rpcApiDependencies = rpcApiDependencies;
}
public void setRpcApiDependencies(RpcApiDependency... rpcApiDependencies) {
this.rpcApiDependencies = CollectionUtil.asList(rpcApiDependencies);
}
@ -643,10 +408,6 @@ public class ApiConfig {
return apiConstants;
}
public void setApiConstants(List<ApiConstant> apiConstants) {
this.apiConstants = apiConstants;
}
public void setApiConstants(ApiConstant... apiConstants) {
this.apiConstants = CollectionUtil.asList(apiConstants);
}
@ -667,22 +428,6 @@ public class ApiConfig {
this.projectName = projectName;
}
public String getProjectCName() {
return projectCName;
}
public void setProjectCName(String projectCName) {
this.projectCName = projectCName;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public boolean isSkipTransientField() {
return skipTransientField;
}
@ -803,22 +548,14 @@ public class ApiConfig {
this.displayActualType = displayActualType;
}
public BodyAdvice getResponseBodyAdvice() {
public ResponseBodyAdvice getResponseBodyAdvice() {
return responseBodyAdvice;
}
public void setResponseBodyAdvice(BodyAdvice responseBodyAdvice) {
public void setResponseBodyAdvice(ResponseBodyAdvice responseBodyAdvice) {
this.responseBodyAdvice = responseBodyAdvice;
}
public BodyAdvice getRequestBodyAdvice() {
return requestBodyAdvice;
}
public void setRequestBodyAdvice(BodyAdvice requestBodyAdvice) {
this.requestBodyAdvice = requestBodyAdvice;
}
public String getStyle() {
return style;
}
@ -827,88 +564,84 @@ public class ApiConfig {
this.style = style;
}
public boolean isCreateDebugPage() {
return createDebugPage;
}
public void setCreateDebugPage(boolean createDebugPage) {
this.createDebugPage = createDebugPage;
}
public String getDebugEnvName() {
return debugEnvName;
}
public void setDebugEnvName(String debugEnvName) {
this.debugEnvName = debugEnvName;
}
public String getDebugEnvUrl() {
return debugEnvUrl;
}
public void setDebugEnvUrl(String debugEnvUrl) {
this.debugEnvUrl = debugEnvUrl;
}
public String getUrlSuffix() {
return urlSuffix;
}
public void setUrlSuffix(String urlSuffix) {
this.urlSuffix = urlSuffix;
}
public List<CustomField> getCustomRequestFields() {
return customRequestFields;
}
public ApiConfig setCustomRequestFields(List<CustomField> customRequestFields) {
this.customRequestFields = customRequestFields;
return this;
}
public void setCustomRequestFields(CustomField... customRequestFields) {
this.customRequestFields = CollectionUtil.asList(customRequestFields);
}
public String getFramework() {
return framework;
}
public void setFramework(String framework) {
this.framework = framework;
}
public Boolean getReplace() {
return replace;
}
public void setReplace(Boolean replace) {
this.replace = replace;
}
public boolean isRequestParamsTable() {
return requestParamsTable;
}
public void setRequestParamsTable(boolean requestParamsTable) {
this.requestParamsTable = requestParamsTable;
}
public boolean isResponseParamsTable() {
return responseParamsTable;
}
public void setResponseParamsTable(boolean responseParamsTable) {
this.responseParamsTable = responseParamsTable;
}
public String getHighlightStyleLink() {
return highlightStyleLink;
}
public void setHighlightStyleLink(String highlightStyleLink) {
this.highlightStyleLink = highlightStyleLink;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"serverUrl\":\"")
.append(serverUrl).append('\"');
sb.append(",\"isStrict\":")
.append(isStrict);
sb.append(",\"allInOne\":")
.append(allInOne);
sb.append(",\"outPath\":\"")
.append(outPath).append('\"');
sb.append(",\"sourceCodePaths\":")
.append(sourceCodePaths);
sb.append(",\"requestHeaders\":")
.append(requestHeaders);
sb.append(",\"coverOld\":")
.append(coverOld);
sb.append(",\"customResponseFields\":")
.append(customResponseFields);
sb.append(",\"errorCodes\":")
.append(errorCodes);
sb.append(",\"packageFilters\":\"")
.append(packageFilters).append('\"');
sb.append(",\"revisionLogs\":")
.append(revisionLogs);
sb.append(",\"md5EncryptedHtmlName\":")
.append(md5EncryptedHtmlName);
sb.append(",\"language\":")
.append(language);
sb.append(",\"adoc\":")
.append(adoc);
sb.append(",\"dataDictionaries\":")
.append(dataDictionaries);
sb.append(",\"errorCodeDictionaries\":")
.append(errorCodeDictionaries);
sb.append(",\"apiObjectReplacements\":")
.append(apiObjectReplacements);
sb.append(",\"rpcApiDependencies\":")
.append(rpcApiDependencies);
sb.append(",\"apiConstants\":")
.append(apiConstants);
sb.append(",\"projectName\":\"")
.append(projectName).append('\"');
sb.append(",\"skipTransientField\":")
.append(skipTransientField);
sb.append(",\"showAuthor\":")
.append(showAuthor);
sb.append(",\"requestFieldToUnderline\":")
.append(requestFieldToUnderline);
sb.append(",\"responseFieldToUnderline\":")
.append(responseFieldToUnderline);
sb.append(",\"sortByTitle\":")
.append(sortByTitle);
sb.append(",\"showJavaType\":")
.append(showJavaType);
sb.append(",\"inlineEnum\":")
.append(inlineEnum);
sb.append(",\"rpcConsumerConfig\":\"")
.append(rpcConsumerConfig).append('\"');
sb.append(",\"recursionLimit\":")
.append(recursionLimit);
sb.append(",\"requestExample\":")
.append(requestExample);
sb.append(",\"responseExample\":")
.append(responseExample);
sb.append(",\"allInOneDocFileName\":\"")
.append(allInOneDocFileName).append('\"');
sb.append(",\"paramsDataToTree\":")
.append(paramsDataToTree);
sb.append(",\"ignoreRequestParams\":")
.append(ignoreRequestParams);
sb.append(",\"displayActualType\":")
.append(displayActualType);
sb.append(",\"responseBodyAdvice\":")
.append(responseBodyAdvice);
sb.append(",\"style\":")
.append(style);
sb.append('}');
return sb.toString();
}
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
/**

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -59,6 +59,12 @@ public class ApiDataDictionary {
*/
private String descField;
@Deprecated
public static ApiDataDictionary dict() {
return new ApiDataDictionary();
}
public static ApiDataDictionary builder() {
return new ApiDataDictionary();
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,10 +22,8 @@
*/
package com.power.doc.model;
import org.jetbrains.annotations.NotNull;
import com.power.common.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -36,7 +34,7 @@ public class ApiDoc implements Comparable<ApiDoc> {
*
* @since 1.7+
*/
public Integer order;
public int order;
/**
* controller name
@ -50,26 +48,6 @@ public class ApiDoc implements Comparable<ApiDoc> {
*/
private String alias;
/**
* tags
*
* @author cqmike
*/
private String[] tags;
/**
* group
*
* @author cqmike
*/
private String group;
/**
* class in package name
*
*/
private String packageName;
/**
* List of method doc
*/
@ -80,31 +58,6 @@ public class ApiDoc implements Comparable<ApiDoc> {
*/
private String desc;
/**
* link
*/
private String link;
private String author;
/**
* if this is group, then is true
*/
private boolean isFolder;
/**
* children
*/
private List<ApiDoc> childrenApiDocs = new ArrayList<>();
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getName() {
return name;
}
@ -129,11 +82,11 @@ public class ApiDoc implements Comparable<ApiDoc> {
this.desc = desc;
}
public Integer getOrder() {
public int getOrder() {
return order;
}
public void setOrder(Integer order) {
public void setOrder(int order) {
this.order = order;
}
@ -145,91 +98,14 @@ public class ApiDoc implements Comparable<ApiDoc> {
this.alias = alias;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
public String getLink() {
if (StringUtil.isNotEmpty(link)) {
return link;
}
return desc.replace(" ", "_").toLowerCase();
}
public void setLink(String link) {
this.link = link;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public boolean isFolder() {
return isFolder;
}
public void setFolder(boolean folder) {
isFolder = folder;
}
public List<ApiDoc> getChildrenApiDocs() {
return childrenApiDocs;
}
public void setChildrenApiDocs(List<ApiDoc> childrenApiDocs) {
this.childrenApiDocs = childrenApiDocs;
}
@Override
public int compareTo(ApiDoc o) {
public int compareTo(@NotNull ApiDoc o) {
if (Objects.nonNull(o.getDesc())) {
return desc.compareTo(o.getDesc());
}
return name.compareTo(o.getName());
}
public static ApiDoc buildTagApiDoc(ApiDoc source, String tag, ApiMethodDoc methodDoc) {
ApiDoc apiDoc = new ApiDoc();
apiDoc.setAlias(source.getAlias());
apiDoc.setLink(source.getLink());
apiDoc.setDesc(tag);
apiDoc.setAuthor(source.getAuthor());
apiDoc.setPackageName(source.getPackageName());
apiDoc.setName(tag);
apiDoc.setList(new ArrayList<>());
ApiMethodDoc clone = methodDoc.clone();
clone.setOrder(apiDoc.getList().size() + 1);
apiDoc.getList().add(clone);
return apiDoc;
}
public static ApiDoc buildGroupApiDoc(String group) {
ApiDoc apiDoc = new ApiDoc();
apiDoc.setFolder(true);
apiDoc.setGroup(group);
apiDoc.setName(group);
apiDoc.setDesc(group);
apiDoc.setChildrenApiDocs(new ArrayList<>());
return apiDoc;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -82,4 +82,3 @@ public class ApiDocDict {
return sb.toString();
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,55 +0,0 @@
package com.power.doc.model;
/**
* api group
*
* @author cqmike
* @version 1.0.0
* @since 2021年07月31日 16:39:00
*/
public class ApiGroup {
/**
* group name
*/
private String name;
/**
* package name
* support patten
*/
private String apis;
/**
* url path
* support patten
*/
private String paths;
public String getName() {
return name;
}
public ApiGroup setName(String name) {
this.name = name;
return this;
}
public String getApis() {
return apis;
}
public ApiGroup setApis(String apis) {
this.apis = apis;
return this;
}
public String getPaths() {
return paths;
}
public ApiGroup setPaths(String paths) {
this.paths = paths;
return this;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,18 +22,15 @@
*/
package com.power.doc.model;
import com.power.common.util.StringUtil;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.model.request.ApiRequestExample;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* java api method info model.
*/
public class ApiMethodDoc implements Serializable, Cloneable {
public class ApiMethodDoc implements Serializable {
private static final long serialVersionUID = 7211922919532562867L;
@ -104,12 +101,12 @@ public class ApiMethodDoc implements Serializable, Cloneable {
/**
* http contentType
*/
private String contentType = DocGlobalConstants.URL_CONTENT_TYPE;
private String contentType = "application/x-www-form-urlencoded;charset=utf-8";
/**
* http request headers
*/
private List<ApiReqParam> requestHeaders;
private List<ApiReqHeader> requestHeaders;
/**
* path params
@ -152,100 +149,6 @@ public class ApiMethodDoc implements Serializable, Cloneable {
*/
private boolean deprecated;
/**
* return schema
*/
private Map<String, Object> returnSchema;
/**
* request schema
*/
private Map<String, Object> requestSchema;
/**
* api group
*/
private String group;
/**
* marking download
*/
private boolean download;
/**
* link
*/
private String link;
/**
* mark page
*/
private String page = "";
/**
* torna request is array
*/
private Integer isRequestArray;
/**
* torna request is array-type
*/
private String requestArrayType;
/**
* torna response is array
*/
private Integer isResponseArray;
/**
* torna request is array
*/
private String responseArrayType;
/**
* 是否为List数据 openApi
*/
private boolean listParam = false;
/**
* tags
*/
private String[] tags;
public Integer getIsRequestArray() {
return isRequestArray;
}
public void setIsRequestArray(Integer isRequestArray) {
this.isRequestArray = isRequestArray;
}
public String getRequestArrayType() {
return requestArrayType;
}
public void setRequestArrayType(String requestArrayType) {
this.requestArrayType = requestArrayType;
}
public Integer getIsResponseArray() {
return isResponseArray;
}
public void setIsResponseArray(Integer isResponseArray) {
this.isResponseArray = isResponseArray;
}
public String getResponseArrayType() {
return responseArrayType;
}
public void setResponseArrayType(String responseArrayType) {
this.responseArrayType = responseArrayType;
}
public boolean isListParam() {
return listParam;
}
public void setListParam(boolean listParam) {
this.listParam = listParam;
}
public String getMethodId() {
return methodId;
@ -343,11 +246,11 @@ public class ApiMethodDoc implements Serializable, Cloneable {
this.responseParams = responseParams;
}
public List<ApiReqParam> getRequestHeaders() {
public List<ApiReqHeader> getRequestHeaders() {
return requestHeaders;
}
public void setRequestHeaders(List<ApiReqParam> requestHeaders) {
public void setRequestHeaders(List<ApiReqHeader> requestHeaders) {
this.requestHeaders = requestHeaders;
}
@ -415,67 +318,6 @@ public class ApiMethodDoc implements Serializable, Cloneable {
this.queryParams = queryParams;
}
public Map<String, Object> getReturnSchema() {
return returnSchema;
}
public void setReturnSchema(Map<String, Object> returnSchema) {
this.returnSchema = returnSchema;
}
public Map<String, Object> getRequestSchema() {
return requestSchema;
}
public void setRequestSchema(Map<String, Object> requestSchema) {
this.requestSchema = requestSchema;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public boolean isDownload() {
return download;
}
public void setDownload(boolean download) {
this.download = download;
}
public String getLink() {
if (StringUtil.isNotEmpty(link)) {
return link;
}
return desc.replace(" ", "_").toLowerCase();
}
public void setLink(String link) {
this.link = link;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public String[] getTags() {
return tags;
}
public ApiMethodDoc setTags(String[] tags) {
this.tags = tags;
return this;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
@ -524,13 +366,4 @@ public class ApiMethodDoc implements Serializable, Cloneable {
sb.append('}');
return sb.toString();
}
@Override
public ApiMethodDoc clone() {
try {
return (ApiMethodDoc) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("clone apiMethodDoc is error", e);
}
}
}

View File

@ -1,77 +0,0 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
import java.util.List;
/**
* @author yu 2020/11/26.
*/
public class ApiMethodReqParam {
/**
* path params
*/
private List<ApiParam> pathParams;
/**
* query params
*/
private List<ApiParam> queryParams;
/**
* http request params
*/
private List<ApiParam> requestParams;
public static ApiMethodReqParam builder() {
return new ApiMethodReqParam();
}
public List<ApiParam> getPathParams() {
return pathParams;
}
public ApiMethodReqParam setPathParams(List<ApiParam> pathParams) {
this.pathParams = pathParams;
return this;
}
public List<ApiParam> getQueryParams() {
return queryParams;
}
public ApiMethodReqParam setQueryParams(List<ApiParam> queryParams) {
this.queryParams = queryParams;
return this;
}
public List<ApiParam> getRequestParams() {
return requestParams;
}
public ApiMethodReqParam setRequestParams(List<ApiParam> requestParams) {
this.requestParams = requestParams;
return this;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,8 +22,6 @@
*/
package com.power.doc.model;
import com.power.doc.model.torna.EnumInfo;
import java.util.List;
/**
@ -77,7 +75,7 @@ public class ApiParam {
private boolean queryParam;
/**
* param mock value
*
*/
private String value;
@ -86,43 +84,10 @@ public class ApiParam {
*/
private List<ApiParam> children;
/**
* openapi items
*/
private boolean hasItems;
/**
* enum values
*/
private List<String> enumValues;
/**
* enum
*/
private List<EnumInfo> enumInfo;
/**
* Valid @Max
*/
private String maxLength;
/**
* is config.json config param
* default false
*/
private boolean configParam;
public static ApiParam of(){
return new ApiParam();
}
public List<EnumInfo> getEnumInfo() {
return enumInfo;
}
public ApiParam setEnumInfo(List<EnumInfo> enumInfo) {
this.enumInfo = enumInfo;
return this;
}
public String getField() {
return field;
}
@ -190,11 +155,6 @@ public class ApiParam {
return children;
}
public ApiParam setChildren(List<ApiParam> children) {
this.children = children;
return this;
}
public boolean isPathParam() {
return pathParam;
}
@ -213,6 +173,11 @@ public class ApiParam {
return this;
}
public ApiParam setChildren(List<ApiParam> children) {
this.children = children;
return this;
}
public String getValue() {
return value;
}
@ -222,42 +187,6 @@ public class ApiParam {
return this;
}
public boolean isHasItems() {
return hasItems;
}
public ApiParam setHasItems(boolean hasItems) {
this.hasItems = hasItems;
return this;
}
public List<String> getEnumValues() {
return enumValues;
}
public ApiParam setEnumValues(List<String> enumValues) {
this.enumValues = enumValues;
return this;
}
public String getMaxLength() {
return maxLength;
}
public ApiParam setMaxLength(String maxLength) {
this.maxLength = maxLength;
return this;
}
public boolean isConfigParam() {
return configParam;
}
public ApiParam setConfigParam(boolean configParam) {
this.configParam = configParam;
return this;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -22,48 +22,36 @@
*/
package com.power.doc.model;
import com.power.doc.constants.ApiReqParamInTypeEnum;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
/**
* Description:
* http request param info model
* http request header info model
*
* @author yu 2018/06/18.
* @author chenqi 2021/07/15
*/
public class ApiReqParam {
public class ApiReqHeader {
/**
* Request param name
* Request header name
*/
private String name;
/**
* Request param type
* Request header type
*/
private String type;
/**
* request param defaultValue
* request header defaultValue
*/
private String value;
/**
* Request param description
* Request header description
*/
private String desc;
/**
* where is param location
* default header
*
* @see ApiReqParamInTypeEnum value
*/
private String paramIn;
/**
* required flag
*
@ -78,27 +66,20 @@ public class ApiReqParam {
*/
private String since = "-";
/**
* @since 2.2.2
* Regular expression match request param
*/
private String pathPatterns;
@Deprecated
public static ApiReqHeader header() {
return new ApiReqHeader();
}
/**
* @since 2.2.2
* Regular expression ignore request param
*/
private String excludePathPatterns;
public static ApiReqParam builder() {
return new ApiReqParam();
public static ApiReqHeader builder() {
return new ApiReqHeader();
}
public String getName() {
return name;
}
public ApiReqParam setName(String name) {
public ApiReqHeader setName(String name) {
this.name = name;
return this;
}
@ -107,7 +88,7 @@ public class ApiReqParam {
return type;
}
public ApiReqParam setType(String type) {
public ApiReqHeader setType(String type) {
this.type = type;
return this;
}
@ -116,7 +97,7 @@ public class ApiReqParam {
return desc;
}
public ApiReqParam setDesc(String desc) {
public ApiReqHeader setDesc(String desc) {
this.desc = desc;
return this;
}
@ -125,7 +106,7 @@ public class ApiReqParam {
return required;
}
public ApiReqParam setRequired(boolean required) {
public ApiReqHeader setRequired(boolean required) {
this.required = required;
return this;
}
@ -134,7 +115,7 @@ public class ApiReqParam {
return since;
}
public ApiReqParam setSince(String since) {
public ApiReqHeader setSince(String since) {
this.since = since;
return this;
}
@ -143,46 +124,16 @@ public class ApiReqParam {
return value;
}
public ApiReqParam setValue(String value) {
public ApiReqHeader setValue(String value) {
this.value = value;
return this;
}
public String getPathPatterns() {
return pathPatterns;
}
public ApiReqParam setPathPatterns(String pathPatterns) {
this.pathPatterns = pathPatterns;
return this;
}
public String getExcludePathPatterns() {
return excludePathPatterns;
}
public ApiReqParam setExcludePathPatterns(String excludePathPatterns) {
this.excludePathPatterns = excludePathPatterns;
return this;
}
public String getParamIn() {
if (StringUtils.isEmpty(paramIn)) {
return ApiReqParamInTypeEnum.HEADER.getValue();
}
return paramIn;
}
public ApiReqParam setParamIn(String paramIn) {
this.paramIn = paramIn;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApiReqParam that = (ApiReqParam) o;
ApiReqHeader that = (ApiReqHeader) o;
return Objects.equals(name, that.name);
}
@ -202,23 +153,11 @@ public class ApiReqParam {
.append(value).append('\"');
sb.append(",\"desc\":\"")
.append(desc).append('\"');
sb.append(",\"paramIn\":")
.append(paramIn);
sb.append(",\"required\":")
.append(required);
sb.append(",\"since\":\"")
.append(since).append('\"');
sb.append(",\"pathPatterns\":\"")
.append(pathPatterns).append('\"');
sb.append(",\"excludePathPatterns\":\"")
.append(excludePathPatterns).append('\"');
sb.append('}');
return sb.toString();
}
public static ApiParam convertToApiParam(ApiReqParam param) {
return ApiParam.of().setField(param.getName()).setValue(param.getValue())
.setRequired(param.isRequired()).setDesc(param.getDesc()).setConfigParam(true)
.setVersion("-").setType(param.getType());
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc https://github.com/shalousun/smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -23,50 +23,48 @@
package com.power.doc.model;
/**
* @author xingzi
**/
public class CustomField {
* Description:
* This can be used to customize the comments for setting java fields.
* You can reference README.md
*
* @author yu 2018/06/18.
*/
public class CustomRespField {
/**
* field name
*/
private String name;
/**
* field description
*/
private String desc;
/**
* owner class
*/
private String ownerClassName;
/**
* default value
*/
private Object value;
/**
* required
*/
private boolean require;
private boolean ignore;
public static CustomField builder() {
return new CustomField();
@Deprecated
public static CustomRespField field() {
return new CustomRespField();
}
public boolean isRequire() {
return require;
}
public CustomField setRequire(boolean require) {
this.require = require;
return this;
public static CustomRespField builder() {
return new CustomRespField();
}
public String getName() {
return name;
}
public CustomField setName(String name) {
public CustomRespField setName(String name) {
this.name = name;
return this;
}
@ -75,7 +73,7 @@ public class CustomField {
return desc;
}
public CustomField setDesc(String desc) {
public CustomRespField setDesc(String desc) {
this.desc = desc;
return this;
}
@ -84,7 +82,7 @@ public class CustomField {
return ownerClassName;
}
public CustomField setOwnerClassName(String ownerClassName) {
public CustomRespField setOwnerClassName(String ownerClassName) {
this.ownerClassName = ownerClassName;
return this;
}
@ -93,17 +91,23 @@ public class CustomField {
return value;
}
public CustomField setValue(Object value) {
public CustomRespField setValue(Object value) {
this.value = value;
return this;
}
public boolean isIgnore() {
return ignore;
}
public CustomField setIgnore(boolean ignore) {
this.ignore = ignore;
return this;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"name\":\"")
.append(name).append('\"');
sb.append(",\"desc\":\"")
.append(desc).append('\"');
sb.append(",\"ownerClassName\":\"")
.append(ownerClassName).append('\"');
sb.append(",\"value\":")
.append(value);
sb.append('}');
return sb.toString();
}
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
import com.power.common.model.EnumDictionary;

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -69,11 +69,6 @@ public class DocJavaField {
*/
private String actualJavaType;
/**
* field name
*/
private String fieldName;
private boolean array;
private boolean primitive;
@ -204,13 +199,4 @@ public class DocJavaField {
public void setEnum(boolean anEnum) {
isEnum = anEnum;
}
public String getFieldName() {
return fieldName;
}
public DocJavaField setFieldName(String fieldName) {
this.fieldName = fieldName;
return this;
}
}

View File

@ -1,25 +1,3 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
import com.thoughtworks.qdox.model.JavaMethod;
@ -28,21 +6,15 @@ import com.thoughtworks.qdox.model.JavaType;
import java.util.Map;
/**
* @author yu 2020/10/30.
* @since 1.9.8
* @author yu 2020/10/30.
*/
public class DocJavaMethod {
private JavaMethod javaMethod;
private Map<String, Object> returnSchema;
private Map<String, Object> requestSchema;
private Map<String, JavaType> actualTypesMap;
private boolean download;
public static DocJavaMethod builder(){
return new DocJavaMethod();
}
@ -64,31 +36,4 @@ public class DocJavaMethod {
this.actualTypesMap = actualTypesMap;
return this;
}
public Map<String, Object> getReturnSchema() {
return returnSchema;
}
public DocJavaMethod setReturnSchema(Map<String, Object> returnSchema) {
this.returnSchema = returnSchema;
return this;
}
public Map<String, Object> getRequestSchema() {
return requestSchema;
}
public DocJavaMethod setRequestSchema(Map<String, Object> requestSchema) {
this.requestSchema = requestSchema;
return this;
}
public boolean isDownload() {
return download;
}
public DocJavaMethod setDownload(boolean download) {
this.download = download;
return this;
}
}

View File

@ -1,7 +1,7 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
* Copyright (C) 2018-2020 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,25 +1,3 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
import java.util.List;

View File

@ -1,25 +1,3 @@
/*
* smart-doc
*
* Copyright (C) 2018-2021 smart-doc
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.power.doc.model;
import java.util.List;
@ -31,16 +9,19 @@ public class JavaMethodDoc {
/**
* methodId handled by md5
*
*/
private String methodId;
/**
* method name
*
*/
private String name;
/**
* method order
*
*/
private int order;

Some files were not shown because too many files have changed in this diff Show More