From da1f2e6e57525a60bf9f1269722f536c16f0bac6 Mon Sep 17 00:00:00 2001 From: zhangdd <86431843@qq.com> Date: Fri, 17 Jun 2022 10:42:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=E5=A4=84=E7=90=86=E5=BD=93=E5=89=8Dpar?= =?UTF-8?q?ameter=E5=8F=AA=E5=8C=B9=E9=85=8D@param=20&=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=AD=A3=E5=88=99=E5=8C=B9=E9=85=8D=E9=81=BF=E5=85=8D?= =?UTF-8?q?@param=E5=90=8E=E9=9D=A2=E5=A4=9A=E4=B8=AA=E7=A9=BA=E6=A0=BC?= =?UTF-8?q?=E5=AF=BC=E8=87=B4StringIndexOutOfBoundsException?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangdd <86431843@qq.com> --- .../doc/view/utils/CustomPsiCommentUtils.java | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java b/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java index 2d5bfb9..184f6c2 100644 --- a/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java +++ b/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java @@ -16,6 +16,8 @@ import java.util.Iterator; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * 从注释中解析注解的工具类 @@ -28,10 +30,6 @@ public class CustomPsiCommentUtils { /** * 获取注释, 如果指定 tagName 则直接从 tagName 里面获取 - * - * @param docComment - * @param tagName - * @return */ @NotNull public static String getDocComment(PsiDocComment docComment, String tagName) { @@ -55,10 +53,6 @@ public static String getDocComment(PsiDocComment docComment, String tagName) { /** * 获取方法字段的注释 - * - * @param docComment - * @param parameter - * @return */ @NotNull public static String getMethodParam(PsiDocComment docComment, @NotNull PsiParameter parameter) { @@ -69,11 +63,31 @@ public static String getMethodParam(PsiDocComment docComment, @NotNull PsiParame if (!("PsiDocTag:@param").equalsIgnoreCase(element.toString())) { continue; } - - if (element.getText().startsWith("@param " + parameter.getName())) { - return element.getText().substring(("@param " + parameter.getName()).length(), element.getText().indexOf("\n")); + String parameterName = parameter.getName(); + + boolean matchDocLine = false; + PsiElement[] children = element.getChildren(); + for (PsiElement child : children) { + if (parameterName.equals(child.getText())) { + matchDocLine = true; + break; + } + } + //当前行的 @param 是否是 当前parameter 的描述 + if (!matchDocLine) { + continue; } + //如果element.getText()最后包含换行或者空格则去掉 + String text = StringUtils.trim(element.getText()); + + //用于匹配"@param"开头,方法参数结尾 + Pattern docCommentTagCompile = Pattern.compile("@param\\s+" + parameterName); + Matcher matcher = docCommentTagCompile.matcher(text); + if (matcher.find()) { + int startPoint = matcher.group(0).length(); + return text.substring(startPoint); + } } } From 1fc5c6ba6eb05a0780a02ec4e9a42e36546b685a Mon Sep 17 00:00:00 2001 From: liuzhihang Date: Fri, 17 Jun 2022 18:58:58 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=94=9F=E6=88=90=20http?= =?UTF-8?q?=20client,=20=E4=BF=AE=E5=A4=8D=E8=A7=A3=E6=9E=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=B3=A8=E9=87=8A=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +- parts/changeNotes.html | 12 +- parts/pluginDescription.html | 12 +- .../window/catalog/CatalogClearAction.java | 2 +- .../catalog/CatalogHttpClientAction.java | 43 ++++ .../window/catalog/CatalogOpenAction.java | 3 +- .../doc/view/constant/Constant.java | 7 + .../doc/view/constant/MethodConstant.java | 24 ++ .../doc/view/constant/SpringConstant.java | 27 ++- .../com/liuzhihang/doc/view/dto/DocView.java | 25 +- .../liuzhihang/doc/view/dto/DocViewData.java | 111 ++++++--- .../doc/view/enums/ContentTypeEnum.java | 28 +++ .../doc/view/enums/FrameworkEnum.java | 20 ++ .../ShowDocFacadeService.java | 6 +- .../YApiFacadeService.java | 6 +- .../YuQueFacadeService.java | 8 +- .../dto/ShowDocUpdateRequest.java | 2 +- .../dto/ShowDocUpdateResponse.java | 2 +- .../dto/YApiBodyForm.java | 2 +- .../{facade => integration}/dto/YApiCat.java | 2 +- .../dto/YApiHeader.java | 2 +- .../dto/YApiModified.java | 2 +- .../dto/YApiParam.java | 2 +- .../dto/YApiQuery.java | 2 +- .../dto/YApiResponse.java | 2 +- .../{facade => integration}/dto/YapiSave.java | 2 +- .../dto/YuQueCreate.java | 2 +- .../dto/YuQueResponse.java | 2 +- .../dto/YuQueUpdate.java | 2 +- .../impl/ShowDocFacadeServiceImpl.java | 8 +- .../impl/YApiFacadeServiceImpl.java | 10 +- .../impl/YuQueFacadeServiceImpl.java | 10 +- .../service/impl/DubboDocViewServiceImpl.java | 12 +- .../view/service/impl/ShowDocServiceImpl.java | 8 +- .../impl/SpringDocViewServiceImpl.java | 60 +++-- .../view/service/impl/YApiServiceImpl.java | 40 ++-- .../view/service/impl/YuQueServiceImpl.java | 10 +- .../doc/view/ui/window/ClassNode.java | 12 +- .../doc/view/ui/window/DocViewNode.java | 16 +- .../doc/view/ui/window/MethodNode.java | 16 +- .../doc/view/ui/window/ModuleNode.java | 15 +- .../doc/view/ui/window/RootNode.java | 6 +- .../doc/view/utils/CustomFileUtils.java | 98 +++++++- .../doc/view/utils/CustomPsiCommentUtils.java | 152 ++++++------- .../doc/view/utils/DocViewUtils.java | 52 +++-- .../doc/view/utils/SpringPsiUtils.java | 215 ++++++++++++------ src/main/resources/META-INF/plugin.xml | 12 +- .../com/liuzhihang/doc/view/MainTest.java | 7 +- 48 files changed, 746 insertions(+), 376 deletions(-) create mode 100644 src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogHttpClientAction.java create mode 100644 src/main/java/com/liuzhihang/doc/view/constant/MethodConstant.java create mode 100644 src/main/java/com/liuzhihang/doc/view/enums/ContentTypeEnum.java create mode 100644 src/main/java/com/liuzhihang/doc/view/enums/FrameworkEnum.java rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/ShowDocFacadeService.java (65%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/YApiFacadeService.java (81%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/YuQueFacadeService.java (82%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/ShowDocUpdateRequest.java (96%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/ShowDocUpdateResponse.java (95%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiBodyForm.java (85%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiCat.java (89%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiHeader.java (85%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiModified.java (78%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiParam.java (79%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiQuery.java (85%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YApiResponse.java (83%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YapiSave.java (98%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YuQueCreate.java (87%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YuQueResponse.java (98%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/dto/YuQueUpdate.java (87%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/impl/ShowDocFacadeServiceImpl.java (82%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/impl/YApiFacadeServiceImpl.java (88%) rename src/main/java/com/liuzhihang/doc/view/{facade => integration}/impl/YuQueFacadeServiceImpl.java (87%) diff --git a/build.gradle b/build.gradle index 93fa27f..9a7c658 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'com.liuzhihang' -version '1.2.9' +version '1.3.0' JavaVersion.VERSION_11 @@ -24,6 +24,7 @@ dependencies { // See https://github.com/JetBrains/gradle-intellij-plugin/ intellij { version = '2022.1' +// type = "IU" plugins = ['com.intellij.java', 'markdown'] pluginName = 'Doc View' updateSinceUntilBuild = false diff --git a/parts/changeNotes.html b/parts/changeNotes.html index 6fffa4a..cb57f76 100644 --- a/parts/changeNotes.html +++ b/parts/changeNotes.html @@ -3,20 +3,20 @@

English introduction

中文介绍


@@ -33,7 +32,7 @@

Generate Markdown documents based on the interface



-基于接口生成 Markdown 文档, 支持预览、编辑以及上传到YApi、ShowDoc。 +基于接口生成 Markdown 文档, 支持预览、编辑以及上传到YApi、ShowDoc、语雀。


diff --git a/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogClearAction.java b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogClearAction.java index d64fff2..d7a4f6c 100644 --- a/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogClearAction.java +++ b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogClearAction.java @@ -32,7 +32,7 @@ public void actionPerformed(@NotNull AnActionEvent e) { if (selectedNode instanceof DocViewNode) { DocViewNode docViewNode = (DocViewNode) selectedNode; - CustomFileUtils.delete(project, docViewNode.cachePath(project)); + CustomFileUtils.delete(project, docViewNode.docPath(project)); } diff --git a/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogHttpClientAction.java b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogHttpClientAction.java new file mode 100644 index 0000000..58c2cc3 --- /dev/null +++ b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogHttpClientAction.java @@ -0,0 +1,43 @@ +package com.liuzhihang.doc.view.action.toolbar.window.catalog; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.ui.TreeExpandCollapse; +import com.intellij.ui.treeStructure.SimpleNode; +import com.intellij.ui.treeStructure.SimpleTree; +import com.liuzhihang.doc.view.data.DocViewDataKeys; +import com.liuzhihang.doc.view.ui.window.MethodNode; +import com.liuzhihang.doc.view.utils.CustomFileUtils; + +/** + * window 窗口目录树, 右键生成 HttpClient 功能 + * + * @author liuzhihang + * @version CatalogHttpClientAction.java, v 0.1 2022/6/16 17:53 liuzhihang + */ +public class CatalogHttpClientAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + + // 获取当前project对象 + Project project = e.getData(PlatformDataKeys.PROJECT); + SimpleTree simpleTree = e.getData(DocViewDataKeys.WINDOW_CATALOG_TREE); + + if (simpleTree == null || project == null) { + return; + } + + SimpleNode selectedNode = simpleTree.getSelectedNode(); + + if (selectedNode instanceof MethodNode) { + MethodNode methodNode = (MethodNode) selectedNode; + CustomFileUtils.openHttp(project, methodNode); + } else { + TreeExpandCollapse.expandAll(simpleTree); + } + + } +} diff --git a/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogOpenAction.java b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogOpenAction.java index b629636..75c9ccf 100644 --- a/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogOpenAction.java +++ b/src/main/java/com/liuzhihang/doc/view/action/toolbar/window/catalog/CatalogOpenAction.java @@ -33,12 +33,11 @@ public void actionPerformed(@NotNull AnActionEvent e) { if (selectedNode instanceof MethodNode) { MethodNode methodNode = (MethodNode) selectedNode; - CustomFileUtils.open(methodNode, project); + CustomFileUtils.openMd(project, methodNode); } else { TreeExpandCollapse.expandAll(simpleTree); } } - } diff --git a/src/main/java/com/liuzhihang/doc/view/constant/Constant.java b/src/main/java/com/liuzhihang/doc/view/constant/Constant.java index f7c2a63..5eab5f4 100644 --- a/src/main/java/com/liuzhihang/doc/view/constant/Constant.java +++ b/src/main/java/com/liuzhihang/doc/view/constant/Constant.java @@ -1,6 +1,8 @@ package com.liuzhihang.doc.view.constant; /** + * 常量 + * * @author liuzhihang * @date 2021/8/5 18:12 */ @@ -9,4 +11,9 @@ private Constant() { } public static final String DOC_VIEW = "DocView"; + + /** + * 返回 void + */ + public static final String RETURN_VOID = "void"; } diff --git a/src/main/java/com/liuzhihang/doc/view/constant/MethodConstant.java b/src/main/java/com/liuzhihang/doc/view/constant/MethodConstant.java new file mode 100644 index 0000000..257720f --- /dev/null +++ b/src/main/java/com/liuzhihang/doc/view/constant/MethodConstant.java @@ -0,0 +1,24 @@ +/* + * Ant Group + * Copyright (c) 2004-2022 All Rights Reserved. + */ +package com.liuzhihang.doc.view.constant; + +/** + * 方法常量 + * + * @author liuzhihang + * @version MethodConstant.java, v 0.1 2022年06月17日 11:55 AM zijun.lzh + */ +public final class MethodConstant { + + public static final String GET = "GET"; + public static final String POST = "POST"; + public static final String PUT = "PUT"; + public static final String DELETE = "DELETE"; + public static final String HEAD = "HEAD"; + public static final String OPTIONS = "OPTIONS"; + public static final String PATCH = "PATCH"; + public static final String DUBBO = "DUBBO"; + +} \ No newline at end of file diff --git a/src/main/java/com/liuzhihang/doc/view/constant/SpringConstant.java b/src/main/java/com/liuzhihang/doc/view/constant/SpringConstant.java index 3cc5d06..c745eab 100644 --- a/src/main/java/com/liuzhihang/doc/view/constant/SpringConstant.java +++ b/src/main/java/com/liuzhihang/doc/view/constant/SpringConstant.java @@ -1,5 +1,8 @@ package com.liuzhihang.doc.view.constant; +import java.util.ArrayList; +import java.util.List; + /** * @author liuzhihang * @date 2020/3/4 13:44 @@ -55,15 +58,27 @@ private SpringConstant() { /** * other */ - public static final String CONTROLLER_ADVICE = "org.springframework.web.bind.annotation.ControllerAdvice"; + public static final String CONTROLLER_ADVICE = "org.springframework.web.bind.annotation.ControllerAdvice"; public static final String REST_CONTROLLER_ADVICE = "org.springframework.web.bind.annotation.RestControllerAdvice"; - public static final String COOKIE_VALUE = "org.springframework.web.bind.annotation.CookieValue"; - public static final String CROSS_ORIGIN = "org.springframework.web.bind.annotation.CrossOrigin"; + public static final String COOKIE_VALUE = "org.springframework.web.bind.annotation.CookieValue"; + public static final String CROSS_ORIGIN = "org.springframework.web.bind.annotation.CrossOrigin"; public static final String EXCEPTION_HANDLER = "org.springframework.web.bind.annotation.ExceptionHandler"; - public static final String INIT_BINDER = "org.springframework.web.bind.annotation.InitBinder"; - public static final String MATRIX_VARIABLE = "org.springframework.web.bind.annotation.MatrixVariable"; - public static final String MODEL_ATTRIBUTE = "org.springframework.web.bind.annotation.ModelAttribute"; + public static final String INIT_BINDER = "org.springframework.web.bind.annotation.InitBinder"; + public static final String MATRIX_VARIABLE = "org.springframework.web.bind.annotation.MatrixVariable"; + public static final String MODEL_ATTRIBUTE = "org.springframework.web.bind.annotation.ModelAttribute"; + + /** + * Spring Mapping 注解列表 + */ + public static final List MAPPING_ANNOTATIONS = new ArrayList<>() {{ + add(GET_MAPPING); + add(POST_MAPPING); + add(PUT_MAPPING); + add(DELETE_MAPPING); + add(PATCH_MAPPING); + add(REQUEST_MAPPING); + }}; } diff --git a/src/main/java/com/liuzhihang/doc/view/dto/DocView.java b/src/main/java/com/liuzhihang/doc/view/dto/DocView.java index ba5556d..eb8c99c 100644 --- a/src/main/java/com/liuzhihang/doc/view/dto/DocView.java +++ b/src/main/java/com/liuzhihang/doc/view/dto/DocView.java @@ -2,6 +2,8 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; +import com.liuzhihang.doc.view.enums.ContentTypeEnum; +import com.liuzhihang.doc.view.enums.FrameworkEnum; import lombok.Data; import java.util.List; @@ -76,23 +78,20 @@ public class DocView { */ private String changeLog; - /** * headers */ private List
headerList; - /** * 请求参数 */ - private Body reqRootBody = new Body(); + private Body reqBody = new Body(); /** * 返回参数 */ - private Body respRootBody = new Body(); - + private Body respBody = new Body(); /** * 请求参数 @@ -100,14 +99,19 @@ public class DocView { private List reqParamList; /** - * 参数时Json时举例 + * body 参数 */ - private String reqExample; + private String reqBodyExample; /** - * reqExampleType 类型 + * form 参数 */ - private String reqExampleType; + private String reqFormExample; + + /** + * 请求参数类型 json/form + */ + private ContentTypeEnum contentType; /** * 返回参数 @@ -119,7 +123,7 @@ public class DocView { */ private String remark; - private String type; + private FrameworkEnum type; public DocView(String name) { this.name = name; @@ -128,5 +132,4 @@ public DocView(String name) { public DocView() { } - } diff --git a/src/main/java/com/liuzhihang/doc/view/dto/DocViewData.java b/src/main/java/com/liuzhihang/doc/view/dto/DocViewData.java index 8b26467..4b1b0a6 100644 --- a/src/main/java/com/liuzhihang/doc/view/dto/DocViewData.java +++ b/src/main/java/com/liuzhihang/doc/view/dto/DocViewData.java @@ -3,6 +3,7 @@ import com.intellij.openapi.project.Project; import com.liuzhihang.doc.view.config.Settings; import com.liuzhihang.doc.view.config.TemplateSettings; +import com.liuzhihang.doc.view.enums.FrameworkEnum; import com.liuzhihang.doc.view.utils.VelocityUtils; import lombok.Data; import org.apache.commons.collections.CollectionUtils; @@ -50,7 +51,6 @@ public class DocViewData { */ private final String method; - /** * headers */ @@ -65,12 +65,14 @@ public class DocViewData { private final String requestParam; - /** * 请求参数 */ private final List requestBodyDataList; + /** + * 请求中 body 参数 + */ private final String requestBody; /** @@ -82,8 +84,7 @@ public class DocViewData { * 返回参数 */ private final List responseParamDataList; - private final String responseParam; - + private final String responseParam; /** * 返回示例 @@ -98,7 +99,7 @@ public DocViewData(DocView docView) { this.desc = docView.getDesc(); this.path = docView.getPath(); this.method = docView.getMethod(); - this.type = docView.getType(); + this.type = docView.getType().toString(); this.requestHeaderDataList = headerDataList(docView.getHeaderList()); this.requestHeader = headerMarkdown(requestHeaderDataList); @@ -106,13 +107,13 @@ public DocViewData(DocView docView) { this.requestParamDataList = paramDataList(docView.getReqParamList()); this.requestParam = paramMarkdown(requestParamDataList); - this.requestBodyDataList = buildBodyDataList(docView.getReqRootBody().getChildList()); + this.requestBodyDataList = buildBodyDataList(docView.getReqBody().getChildList()); this.requestBody = paramMarkdown(requestBodyDataList); - this.requestExample = buildReqExample(docView.getReqExampleType(), docView.getReqExample()); + this.requestExample = requestExample(docView); - this.responseParamDataList = buildBodyDataList(docView.getRespRootBody().getChildList()); + this.responseParamDataList = buildBodyDataList(docView.getRespBody().getChildList()); this.responseParam = paramMarkdown(responseParamDataList); - this.responseExample = buildRespExample(docView.getReqExampleType(), docView.getRespExample()); + this.responseExample = respBodyExample(docView.getRespExample()); } @@ -126,7 +127,7 @@ public static String markdownText(Project project, DocView docView) { DocViewData docViewData = new DocViewData(docView); - if (docView.getType().equalsIgnoreCase("Dubbo")) { + if (docView.getType() == FrameworkEnum.DUBBO) { return VelocityUtils.convert(TemplateSettings.getInstance(project).getDubboTemplate(), docViewData); } else { // 按照 Spring 模版 @@ -147,9 +148,9 @@ private static String paramMarkdown(List dataList) { return ""; } - return "|参数名|类型|必选|描述|\n" + - "|:-----|:-----|:-----|:-----|\n" + - paramMarkdownContent(dataList); + return "|参数名|类型|必选|描述|\n" + + "|:-----|:-----|:-----|:-----|\n" + + paramMarkdownContent(dataList); } /** @@ -173,11 +174,9 @@ private static StringBuilder paramMarkdownContent(List dataLis return builder; } - @NotNull private static String headerMarkdown(List dataList) { - if (CollectionUtils.isEmpty(dataList)) { return ""; } @@ -192,13 +191,11 @@ private static String headerMarkdown(List dataList) { .append("|").append("\n"); } - - return "|参数名|参数值|必填|描述|\n" + - "|:-----|:-----|:-----|:-----|\n" + - builder; + return "|参数名|参数值|必填|描述|\n" + + "|:-----|:-----|:-----|:-----|\n" + + builder; } - private List headerDataList(List
headerList) { if (CollectionUtils.isEmpty(headerList)) { @@ -253,7 +250,6 @@ public static List buildBodyDataList(List bodyList) { return buildBodyDataList(bodyList, "", ""); } - /** * 递归 body 生成 List * @@ -283,29 +279,84 @@ private static List buildBodyDataList(@NotNull List body Settings settings = Settings.getInstance(body.getPsiElement().getProject()); - data.setChildList(buildBodyDataList(body.getChildList(), settings.getPrefixSymbol1(), prefixSymbol2 + settings.getPrefixSymbol2())); + data.setChildList( + buildBodyDataList(body.getChildList(), settings.getPrefixSymbol1(), prefixSymbol2 + settings.getPrefixSymbol2())); } dataList.add(data); } return dataList; } + @NotNull + private String requestExample(DocView docView) { + + String reqFormExample = reqFormExample(docView.getReqFormExample()); + + String reqBodyExample = reqBodyExample(docView.getReqBodyExample()); + + if (StringUtils.isBlank(reqFormExample)) { + return reqBodyExample; + } + + if (StringUtils.isBlank(reqBodyExample)) { + return reqFormExample; + } + return reqFormExample + "\n\n" + reqBodyExample; + } + + /** + * 请求参数中的 Form 示例 + * + * @param reqFormExample + * @return + */ + private String reqFormExample(String reqFormExample) { + if (StringUtils.isBlank(reqFormExample)) { + return ""; + } + + return "```Form\n" + + reqFormExample + "\n" + + "```"; + } + + /** + * 请求参数中的 Body 示例 + * + * @param reqBodyExample Body + * @return 组装结果 + */ @NotNull @Contract(pure = true) - private String buildReqExample(String reqExampleType, String reqExample) { + private String reqBodyExample(String reqBodyExample) { - return "```" + reqExampleType + "\n" + - (reqExample == null ? "" : reqExample) + "\n" + - "```"; + if (StringUtils.isBlank(reqBodyExample)) { + return ""; + } + + return "```JSON\n" + + reqBodyExample + "\n" + + "```"; } + /** + * 构建返回 body + * + * @param respExample 返回示例 + * @return 返回body + */ @NotNull @Contract(pure = true) - private String buildRespExample(String respExampleType, String respExample) { - return "```json\n" + - (respExampleType == null ? "" : respExample) + "\n" + - "```\n\n"; + private String respBodyExample(String respExample) { + + if (StringUtils.isBlank(respExample)) { + return ""; + } + + return "```JSON\n" + + respExample + "\n" + + "```\n\n"; } } diff --git a/src/main/java/com/liuzhihang/doc/view/enums/ContentTypeEnum.java b/src/main/java/com/liuzhihang/doc/view/enums/ContentTypeEnum.java new file mode 100644 index 0000000..43c8913 --- /dev/null +++ b/src/main/java/com/liuzhihang/doc/view/enums/ContentTypeEnum.java @@ -0,0 +1,28 @@ +package com.liuzhihang.doc.view.enums; + +import lombok.Getter; + +/** + * http 请求 content-type 枚举 + * + * @author liuzhihang + * @version ContentTypeEnum.java, v 0.1 2022年06月16日 8:38 PM liuzhihang + */ +@Getter +public enum ContentTypeEnum { + + JSON("Content-Type", "application/json"), + FORM("Content-Type", "application/x-www-form-urlencoded"), + + ; + + ContentTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + private String key; + + private String value; + +} \ No newline at end of file diff --git a/src/main/java/com/liuzhihang/doc/view/enums/FrameworkEnum.java b/src/main/java/com/liuzhihang/doc/view/enums/FrameworkEnum.java new file mode 100644 index 0000000..7e2617c --- /dev/null +++ b/src/main/java/com/liuzhihang/doc/view/enums/FrameworkEnum.java @@ -0,0 +1,20 @@ +package com.liuzhihang.doc.view.enums; + +/** + * 框架类型 Spring Dubbo + * + * @author liuzhihang + * @version FrameworkEnum.java, v 0.1 2022年06月17日 10:28 AM liuzhihang + */ +public enum FrameworkEnum { + /** + * Spring + */ + SPRING, + + /** + * Dubbo + */ + DUBBO; + +} \ No newline at end of file diff --git a/src/main/java/com/liuzhihang/doc/view/facade/ShowDocFacadeService.java b/src/main/java/com/liuzhihang/doc/view/integration/ShowDocFacadeService.java similarity index 65% rename from src/main/java/com/liuzhihang/doc/view/facade/ShowDocFacadeService.java rename to src/main/java/com/liuzhihang/doc/view/integration/ShowDocFacadeService.java index 1fe2a64..a5d113f 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/ShowDocFacadeService.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/ShowDocFacadeService.java @@ -1,7 +1,7 @@ -package com.liuzhihang.doc.view.facade; +package com.liuzhihang.doc.view.integration; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateRequest; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateResponse; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateRequest; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateResponse; /** * ShowDoc 文档对接 diff --git a/src/main/java/com/liuzhihang/doc/view/facade/YApiFacadeService.java b/src/main/java/com/liuzhihang/doc/view/integration/YApiFacadeService.java similarity index 81% rename from src/main/java/com/liuzhihang/doc/view/facade/YApiFacadeService.java rename to src/main/java/com/liuzhihang/doc/view/integration/YApiFacadeService.java index f63cc3d..c27e412 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/YApiFacadeService.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/YApiFacadeService.java @@ -1,7 +1,7 @@ -package com.liuzhihang.doc.view.facade; +package com.liuzhihang.doc.view.integration; -import com.liuzhihang.doc.view.facade.dto.YApiCat; -import com.liuzhihang.doc.view.facade.dto.YapiSave; +import com.liuzhihang.doc.view.integration.dto.YApiCat; +import com.liuzhihang.doc.view.integration.dto.YapiSave; import java.util.List; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/YuQueFacadeService.java b/src/main/java/com/liuzhihang/doc/view/integration/YuQueFacadeService.java similarity index 82% rename from src/main/java/com/liuzhihang/doc/view/facade/YuQueFacadeService.java rename to src/main/java/com/liuzhihang/doc/view/integration/YuQueFacadeService.java index 2929187..2d8c1dc 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/YuQueFacadeService.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/YuQueFacadeService.java @@ -1,8 +1,8 @@ -package com.liuzhihang.doc.view.facade; +package com.liuzhihang.doc.view.integration; -import com.liuzhihang.doc.view.facade.dto.YuQueCreate; -import com.liuzhihang.doc.view.facade.dto.YuQueResponse; -import com.liuzhihang.doc.view.facade.dto.YuQueUpdate; +import com.liuzhihang.doc.view.integration.dto.YuQueCreate; +import com.liuzhihang.doc.view.integration.dto.YuQueResponse; +import com.liuzhihang.doc.view.integration.dto.YuQueUpdate; /** * 语雀包装 service diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateRequest.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateRequest.java similarity index 96% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateRequest.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateRequest.java index b7f8919..2097bbd 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateRequest.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateRequest.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import com.google.gson.annotations.SerializedName; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateResponse.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateResponse.java similarity index 95% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateResponse.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateResponse.java index c9f8469..650af2d 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/ShowDocUpdateResponse.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/ShowDocUpdateResponse.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import com.google.gson.annotations.SerializedName; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiBodyForm.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiBodyForm.java similarity index 85% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiBodyForm.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiBodyForm.java index 7c47109..bfc8752 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiBodyForm.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiBodyForm.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiCat.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiCat.java similarity index 89% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiCat.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiCat.java index 0b17719..53255a3 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiCat.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiCat.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import com.google.gson.annotations.SerializedName; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiHeader.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiHeader.java similarity index 85% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiHeader.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiHeader.java index 7b090ce..c4fb532 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiHeader.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiHeader.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiModified.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiModified.java similarity index 78% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiModified.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiModified.java index 2883b08..860c74e 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiModified.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiModified.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiParam.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiParam.java similarity index 79% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiParam.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiParam.java index da58a83..fb13f0b 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiParam.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiParam.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiQuery.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiQuery.java similarity index 85% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiQuery.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiQuery.java index f033ff7..345b92d 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiQuery.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiQuery.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiResponse.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiResponse.java similarity index 83% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YApiResponse.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YApiResponse.java index 274f3b0..268fa70 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YApiResponse.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YApiResponse.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YapiSave.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YapiSave.java similarity index 98% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YapiSave.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YapiSave.java index a3240ac..d22c2a5 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YapiSave.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YapiSave.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import com.google.gson.annotations.SerializedName; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueCreate.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueCreate.java similarity index 87% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueCreate.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueCreate.java index 4250672..c473479 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueCreate.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueCreate.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueResponse.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueResponse.java similarity index 98% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueResponse.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueResponse.java index 88e3aad..f15a28c 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueResponse.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueResponse.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueUpdate.java b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueUpdate.java similarity index 87% rename from src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueUpdate.java rename to src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueUpdate.java index 39e65b7..36e8dae 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/dto/YuQueUpdate.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/dto/YuQueUpdate.java @@ -1,4 +1,4 @@ -package com.liuzhihang.doc.view.facade.dto; +package com.liuzhihang.doc.view.integration.dto; import lombok.Data; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/impl/ShowDocFacadeServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/integration/impl/ShowDocFacadeServiceImpl.java similarity index 82% rename from src/main/java/com/liuzhihang/doc/view/facade/impl/ShowDocFacadeServiceImpl.java rename to src/main/java/com/liuzhihang/doc/view/integration/impl/ShowDocFacadeServiceImpl.java index 00cbb01..8949335 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/impl/ShowDocFacadeServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/impl/ShowDocFacadeServiceImpl.java @@ -1,12 +1,12 @@ -package com.liuzhihang.doc.view.facade.impl; +package com.liuzhihang.doc.view.integration.impl; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.intellij.openapi.diagnostic.Logger; -import com.liuzhihang.doc.view.facade.ShowDocFacadeService; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateRequest; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateResponse; +import com.liuzhihang.doc.view.integration.ShowDocFacadeService; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateRequest; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateResponse; import com.liuzhihang.doc.view.utils.HttpUtils; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/impl/YApiFacadeServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/integration/impl/YApiFacadeServiceImpl.java similarity index 88% rename from src/main/java/com/liuzhihang/doc/view/facade/impl/YApiFacadeServiceImpl.java rename to src/main/java/com/liuzhihang/doc/view/integration/impl/YApiFacadeServiceImpl.java index c5ad597..c6f6b5d 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/impl/YApiFacadeServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/impl/YApiFacadeServiceImpl.java @@ -1,13 +1,13 @@ -package com.liuzhihang.doc.view.facade.impl; +package com.liuzhihang.doc.view.integration.impl; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; -import com.liuzhihang.doc.view.facade.YApiFacadeService; -import com.liuzhihang.doc.view.facade.dto.YApiCat; -import com.liuzhihang.doc.view.facade.dto.YApiResponse; -import com.liuzhihang.doc.view.facade.dto.YapiSave; +import com.liuzhihang.doc.view.integration.YApiFacadeService; +import com.liuzhihang.doc.view.integration.dto.YApiCat; +import com.liuzhihang.doc.view.integration.dto.YApiResponse; +import com.liuzhihang.doc.view.integration.dto.YapiSave; import com.liuzhihang.doc.view.utils.HttpUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/liuzhihang/doc/view/facade/impl/YuQueFacadeServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/integration/impl/YuQueFacadeServiceImpl.java similarity index 87% rename from src/main/java/com/liuzhihang/doc/view/facade/impl/YuQueFacadeServiceImpl.java rename to src/main/java/com/liuzhihang/doc/view/integration/impl/YuQueFacadeServiceImpl.java index 3191748..4edf978 100644 --- a/src/main/java/com/liuzhihang/doc/view/facade/impl/YuQueFacadeServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/integration/impl/YuQueFacadeServiceImpl.java @@ -1,11 +1,11 @@ -package com.liuzhihang.doc.view.facade.impl; +package com.liuzhihang.doc.view.integration.impl; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.liuzhihang.doc.view.facade.YuQueFacadeService; -import com.liuzhihang.doc.view.facade.dto.YuQueCreate; -import com.liuzhihang.doc.view.facade.dto.YuQueResponse; -import com.liuzhihang.doc.view.facade.dto.YuQueUpdate; +import com.liuzhihang.doc.view.integration.YuQueFacadeService; +import com.liuzhihang.doc.view.integration.dto.YuQueCreate; +import com.liuzhihang.doc.view.integration.dto.YuQueResponse; +import com.liuzhihang.doc.view.integration.dto.YuQueUpdate; import com.liuzhihang.doc.view.utils.HttpUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; diff --git a/src/main/java/com/liuzhihang/doc/view/service/impl/DubboDocViewServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/service/impl/DubboDocViewServiceImpl.java index 4768742..8f89284 100644 --- a/src/main/java/com/liuzhihang/doc/view/service/impl/DubboDocViewServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/service/impl/DubboDocViewServiceImpl.java @@ -6,6 +6,8 @@ import com.intellij.psi.PsiType; import com.liuzhihang.doc.view.config.Settings; import com.liuzhihang.doc.view.dto.DocView; +import com.liuzhihang.doc.view.enums.ContentTypeEnum; +import com.liuzhihang.doc.view.enums.FrameworkEnum; import com.liuzhihang.doc.view.service.DocViewService; import com.liuzhihang.doc.view.utils.DocViewUtils; import com.liuzhihang.doc.view.utils.DubboPsiUtils; @@ -61,19 +63,19 @@ public DocView buildClassMethodDoc(@NotNull Project project, @NotNull PsiClass p docView.setPath(psiClass.getName() + "#" + psiMethod.getName()); docView.setMethod("Dubbo"); // docView.setDomain(); - docView.setType("Dubbo"); + docView.setType(FrameworkEnum.DUBBO); // 有参数 if (psiMethod.hasParameters()) { - docView.setReqRootBody(DubboPsiUtils.buildBody(psiMethod)); - docView.setReqExampleType("json"); - docView.setReqExample(DubboPsiUtils.getReqBodyJson(psiMethod)); + docView.setReqBody(DubboPsiUtils.buildBody(psiMethod)); + docView.setContentType(ContentTypeEnum.JSON); + docView.setReqBodyExample(DubboPsiUtils.getReqBodyJson(psiMethod)); } PsiType returnType = psiMethod.getReturnType(); // 返回代码相同 if (returnType != null && returnType.isValid() && !returnType.equalsToText("void")) { - docView.setRespRootBody(ParamPsiUtils.buildRespBody(returnType)); + docView.setRespBody(ParamPsiUtils.buildRespBody(returnType)); docView.setRespExample(ParamPsiUtils.getRespBodyJson(returnType)); } return docView; diff --git a/src/main/java/com/liuzhihang/doc/view/service/impl/ShowDocServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/service/impl/ShowDocServiceImpl.java index 7ab884b..9e4bde8 100644 --- a/src/main/java/com/liuzhihang/doc/view/service/impl/ShowDocServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/service/impl/ShowDocServiceImpl.java @@ -9,10 +9,10 @@ import com.liuzhihang.doc.view.config.ShowDocSettingsConfigurable; import com.liuzhihang.doc.view.dto.DocView; import com.liuzhihang.doc.view.dto.DocViewData; -import com.liuzhihang.doc.view.facade.ShowDocFacadeService; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateRequest; -import com.liuzhihang.doc.view.facade.dto.ShowDocUpdateResponse; -import com.liuzhihang.doc.view.facade.impl.ShowDocFacadeServiceImpl; +import com.liuzhihang.doc.view.integration.ShowDocFacadeService; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateRequest; +import com.liuzhihang.doc.view.integration.dto.ShowDocUpdateResponse; +import com.liuzhihang.doc.view.integration.impl.ShowDocFacadeServiceImpl; import com.liuzhihang.doc.view.notification.DocViewNotification; import com.liuzhihang.doc.view.service.DocViewUploadService; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/liuzhihang/doc/view/service/impl/SpringDocViewServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/service/impl/SpringDocViewServiceImpl.java index b2bf6ab..3d7b7c9 100644 --- a/src/main/java/com/liuzhihang/doc/view/service/impl/SpringDocViewServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/service/impl/SpringDocViewServiceImpl.java @@ -7,18 +7,20 @@ import com.intellij.psi.PsiType; import com.liuzhihang.doc.view.config.Settings; import com.liuzhihang.doc.view.dto.DocView; -import com.liuzhihang.doc.view.dto.Header; +import com.liuzhihang.doc.view.enums.ContentTypeEnum; +import com.liuzhihang.doc.view.enums.FrameworkEnum; import com.liuzhihang.doc.view.service.DocViewService; import com.liuzhihang.doc.view.utils.DocViewUtils; import com.liuzhihang.doc.view.utils.ParamPsiUtils; -import com.liuzhihang.doc.view.utils.SpringHeaderUtils; import com.liuzhihang.doc.view.utils.SpringPsiUtils; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedList; import java.util.List; +import static com.intellij.psi.PsiKeyword.VOID; + /** * @author liuzhihang * @date 2020/3/3 13:32 @@ -61,49 +63,41 @@ public DocView buildClassMethodDoc(@NotNull Project project, PsiClass psiClass, docView.setDocTitle(DocViewUtils.getTitle(psiClass)); docView.setName(DocViewUtils.getName(psiMethod)); docView.setDesc(DocViewUtils.getMethodDesc(psiMethod)); - docView.setPath(SpringPsiUtils.getPath(psiClass, psiMethod)); - docView.setMethod(SpringPsiUtils.getMethod(psiMethod)); - // docView.setDomain(); - docView.setType("Spring"); - - List
headerList = new ArrayList<>(); + docView.setPath(SpringPsiUtils.path(psiClass, psiMethod)); + docView.setMethod(SpringPsiUtils.method(psiMethod)); + docView.setDomain(Collections.emptyList()); + docView.setType(FrameworkEnum.SPRING); // 有参数 if (psiMethod.hasParameters()) { - // 获取 - PsiParameter requestBodyParam = SpringPsiUtils.getRequestBodyParam(psiMethod); - docView.setReqParamList(SpringPsiUtils.buildFormParam(psiMethod)); + ContentTypeEnum contentType = SpringPsiUtils.contentType(psiMethod); + docView.setContentType(contentType); - if (requestBodyParam != null) { - // 有requestBody, 则 Content-Type: application/json - headerList.add(SpringHeaderUtils.buildJsonHeader()); - docView.setReqExampleType("json"); - docView.setReqRootBody(SpringPsiUtils.buildBody(requestBodyParam)); - docView.setReqExample(SpringPsiUtils.getReqBodyJson(requestBodyParam, settings)); - - } else { - headerList.add(SpringHeaderUtils.buildFormHeader()); - docView.setReqExampleType("form"); - docView.setReqExample(SpringPsiUtils.getReqParamKV(docView.getReqParamList())); + // 请求中的 form 参数, url 后面拼接的 kv + docView.setReqParamList(SpringPsiUtils.buildFormParam(psiMethod)); + docView.setReqFormExample(SpringPsiUtils.reqParamKV(docView.getReqParamList())); + + if (contentType == ContentTypeEnum.JSON) { + // JSON 请求可能会有 body + PsiParameter requestBodyParam = SpringPsiUtils.requestBodyParam(psiMethod); + if (requestBodyParam != null) { + docView.setReqBody(SpringPsiUtils.buildBody(requestBodyParam)); + docView.setReqBodyExample(SpringPsiUtils.reqBodyJson(requestBodyParam, settings)); + } } - - // 处理 header - List
headers = SpringPsiUtils.buildHeader(psiMethod); - headerList.addAll(headers); } else { - docView.setReqExampleType("form"); - headerList.add(SpringHeaderUtils.buildFormHeader()); + docView.setContentType(ContentTypeEnum.FORM); } - docView.setHeaderList(headerList); + + docView.setHeaderList(SpringPsiUtils.buildHeader(psiMethod)); PsiType returnType = psiMethod.getReturnType(); - if (returnType != null && returnType.isValid() && !returnType.equalsToText("void")) { - docView.setRespRootBody(ParamPsiUtils.buildRespBody(returnType)); + if (returnType != null && returnType.isValid() && !returnType.equalsToText(VOID)) { + docView.setRespBody(ParamPsiUtils.buildRespBody(returnType)); docView.setRespExample(ParamPsiUtils.getRespBodyJson(returnType)); } return docView; } - } diff --git a/src/main/java/com/liuzhihang/doc/view/service/impl/YApiServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/service/impl/YApiServiceImpl.java index 0e1ccd9..fc6de58 100644 --- a/src/main/java/com/liuzhihang/doc/view/service/impl/YApiServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/service/impl/YApiServiceImpl.java @@ -5,7 +5,11 @@ import com.intellij.openapi.components.Service; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiPrimitiveType; +import com.intellij.psi.PsiType; import com.intellij.psi.util.InheritanceUtil; import com.liuzhihang.doc.view.DocViewBundle; import com.liuzhihang.doc.view.config.YApiSettings; @@ -15,12 +19,13 @@ import com.liuzhihang.doc.view.dto.DocView; import com.liuzhihang.doc.view.dto.Header; import com.liuzhihang.doc.view.dto.Param; -import com.liuzhihang.doc.view.facade.YApiFacadeService; -import com.liuzhihang.doc.view.facade.dto.YApiCat; -import com.liuzhihang.doc.view.facade.dto.YApiHeader; -import com.liuzhihang.doc.view.facade.dto.YApiQuery; -import com.liuzhihang.doc.view.facade.dto.YapiSave; -import com.liuzhihang.doc.view.facade.impl.YApiFacadeServiceImpl; +import com.liuzhihang.doc.view.enums.ContentTypeEnum; +import com.liuzhihang.doc.view.integration.YApiFacadeService; +import com.liuzhihang.doc.view.integration.dto.YApiCat; +import com.liuzhihang.doc.view.integration.dto.YApiHeader; +import com.liuzhihang.doc.view.integration.dto.YApiQuery; +import com.liuzhihang.doc.view.integration.dto.YapiSave; +import com.liuzhihang.doc.view.integration.impl.YApiFacadeServiceImpl; import com.liuzhihang.doc.view.notification.DocViewNotification; import com.liuzhihang.doc.view.service.DocViewUploadService; import lombok.extern.slf4j.Slf4j; @@ -28,7 +33,12 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -76,7 +86,7 @@ public void doUpload(@NotNull Project project, @NotNull DocView docView) { save.setProjectId(settings.getProjectId()); save.setCatId(cat.getId()); - if (docView.getMethod().equals("Dubbo")) { + if ("Dubbo".equals(docView.getMethod())) { // dubbo 接口处理 save.setPath("/Dubbo/" + docView.getPsiMethod().getName()); save.setMethod("POST"); @@ -85,19 +95,19 @@ public void doUpload(@NotNull Project project, @NotNull DocView docView) { save.setPath(docView.getPath()); } // 枚举: raw,form,json - save.setReqBodyType(docView.getReqExampleType()); + save.setReqBodyType(docView.getContentType().toString()); save.setReqBodyForm(new ArrayList<>()); save.setReqParams(new ArrayList<>()); save.setReqHeaders(buildReqHeaders(docView.getHeaderList())); save.setReqQuery(buildReqQuery(docView.getReqParamList())); save.setResBodyType("json"); - save.setResBody(buildJsonSchema(docView.getRespRootBody().getChildList())); + save.setResBody(buildJsonSchema(docView.getRespBody().getChildList())); save.setMarkdown(buildDesc(docView)); save.setTitle(docView.getName()); - if (docView.getReqExampleType().equals("json")) { + if (docView.getContentType().equals(ContentTypeEnum.JSON)) { save.setReqBodyIsJsonSchema(true); - save.setReqBodyOther(buildJsonSchema(docView.getReqRootBody().getChildList())); + save.setReqBodyOther(buildJsonSchema(docView.getReqBody().getChildList())); } facadeService.save(save); @@ -127,8 +137,8 @@ private String buildDesc(DocView docView) { + "**接口描述:**\n\n" + docView.getDesc() + "\n\n" + "**请求示例:**\n\n" - + "```" + docView.getReqExampleType() + "\n" + - (docView.getReqExample() == null ? "" : docView.getReqExample()) + "\n" + + + "```" + docView.getContentType() + "\n" + + (docView.getReqBodyExample() == null ? "" : docView.getReqBodyExample()) + "\n" + "```" + "\n\n" + "**返回示例:**\n\n" + "```json\n" + diff --git a/src/main/java/com/liuzhihang/doc/view/service/impl/YuQueServiceImpl.java b/src/main/java/com/liuzhihang/doc/view/service/impl/YuQueServiceImpl.java index e005a92..353331d 100644 --- a/src/main/java/com/liuzhihang/doc/view/service/impl/YuQueServiceImpl.java +++ b/src/main/java/com/liuzhihang/doc/view/service/impl/YuQueServiceImpl.java @@ -9,11 +9,11 @@ import com.liuzhihang.doc.view.config.YuQueSettings; import com.liuzhihang.doc.view.dto.DocView; import com.liuzhihang.doc.view.dto.DocViewData; -import com.liuzhihang.doc.view.facade.YuQueFacadeService; -import com.liuzhihang.doc.view.facade.dto.YuQueCreate; -import com.liuzhihang.doc.view.facade.dto.YuQueResponse; -import com.liuzhihang.doc.view.facade.dto.YuQueUpdate; -import com.liuzhihang.doc.view.facade.impl.YuQueFacadeServiceImpl; +import com.liuzhihang.doc.view.integration.YuQueFacadeService; +import com.liuzhihang.doc.view.integration.dto.YuQueCreate; +import com.liuzhihang.doc.view.integration.dto.YuQueResponse; +import com.liuzhihang.doc.view.integration.dto.YuQueUpdate; +import com.liuzhihang.doc.view.integration.impl.YuQueFacadeServiceImpl; import com.liuzhihang.doc.view.notification.DocViewNotification; import com.liuzhihang.doc.view.service.DocViewUploadService; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/liuzhihang/doc/view/ui/window/ClassNode.java b/src/main/java/com/liuzhihang/doc/view/ui/window/ClassNode.java index baf2364..098a97c 100644 --- a/src/main/java/com/liuzhihang/doc/view/ui/window/ClassNode.java +++ b/src/main/java/com/liuzhihang/doc/view/ui/window/ClassNode.java @@ -49,11 +49,19 @@ public void updateNode(Project project) { } @Override - public String cachePath(Project project) { + public String docPath(Project project) { ModuleNode moduleNode = (ModuleNode) getParent(); - return moduleNode.cachePath(project) + "/" + DocViewUtils.getTitle(psiClass); + return moduleNode.docPath(project) + "/" + DocViewUtils.getTitle(psiClass); + } + + @Override + public String httpPath(Project project) { + + ModuleNode moduleNode = (ModuleNode) getParent(); + + return moduleNode.httpPath(project) + "/" + DocViewUtils.getTitle(psiClass); } @Override diff --git a/src/main/java/com/liuzhihang/doc/view/ui/window/DocViewNode.java b/src/main/java/com/liuzhihang/doc/view/ui/window/DocViewNode.java index 676be05..a790095 100644 --- a/src/main/java/com/liuzhihang/doc/view/ui/window/DocViewNode.java +++ b/src/main/java/com/liuzhihang/doc/view/ui/window/DocViewNode.java @@ -30,6 +30,20 @@ public String getName() { public abstract void updateNode(Project project); - public abstract String cachePath(Project project); + /** + * 生成的文档保存路径 + * + * @param project project + * @return path + */ + public abstract String docPath(Project project); + + /** + * 生成的 .http 文件路径 + * + * @param project project + * @return path + */ + public abstract String httpPath(Project project); } diff --git a/src/main/java/com/liuzhihang/doc/view/ui/window/MethodNode.java b/src/main/java/com/liuzhihang/doc/view/ui/window/MethodNode.java index 5b7f9d9..76a1b87 100644 --- a/src/main/java/com/liuzhihang/doc/view/ui/window/MethodNode.java +++ b/src/main/java/com/liuzhihang/doc/view/ui/window/MethodNode.java @@ -54,7 +54,7 @@ protected MethodNode(SimpleNode aParent, PsiClass psiClass, PsiMethod psiMethod) private Icon methodIcon() { if (SpringPsiUtils.isSpringClass(psiClass) && SpringPsiUtils.isSpringMethod(psiMethod)) { - return ICON_MAP.get(SpringPsiUtils.getMethod(psiMethod)); + return ICON_MAP.get(SpringPsiUtils.method(psiMethod)); } if (DubboPsiUtils.isDubboClass(psiClass) && DubboPsiUtils.isDubboMethod(psiMethod)) { return ICON_MAP.get("DUBBO"); @@ -90,14 +90,22 @@ public void updateNode(Project project) { } @Override - public String cachePath(Project project) { + public String docPath(Project project) { ClassNode classNode = (ClassNode) getParent(); - return classNode.cachePath(project) + "/" + DocViewUtils.getName(psiMethod) + ".md"; + return classNode.docPath(project) + "/" + DocViewUtils.getName(psiMethod) + ".md"; } + @Override + public String httpPath(Project project) { + + ClassNode classNode = (ClassNode) getParent(); + + return classNode.httpPath(project) + "/" + DocViewUtils.getName(psiMethod) + ".http"; + } + @Override public void handleSelection(SimpleTree tree) { super.handleSelection(tree); @@ -111,7 +119,7 @@ public void handleSelection(SimpleTree tree) { */ @Override public void handleDoubleClickOrEnter(SimpleTree tree, InputEvent inputEvent) { - CustomFileUtils.open(this, psiClass.getProject()); + CustomFileUtils.openMd(psiClass.getProject(), this); } public PsiMethod getPsiMethod() { diff --git a/src/main/java/com/liuzhihang/doc/view/ui/window/ModuleNode.java b/src/main/java/com/liuzhihang/doc/view/ui/window/ModuleNode.java index 9470217..9cdbb88 100644 --- a/src/main/java/com/liuzhihang/doc/view/ui/window/ModuleNode.java +++ b/src/main/java/com/liuzhihang/doc/view/ui/window/ModuleNode.java @@ -27,7 +27,7 @@ public class ModuleNode extends DocViewNode { private final List classNodes = new ArrayList<>(); - private final Module module; + private final Module module; protected ModuleNode(SimpleNode aParent, Module module) { super(aParent); @@ -58,7 +58,6 @@ public void updateNode(Project project) { psiClasses.addAll(SpringPsiUtils.findDocViewFromModule(module)); - for (PsiClass psiClass : psiClasses) { ClassNode classNode = new ClassNode(this, psiClass); classNodes.add(classNode); @@ -67,11 +66,19 @@ public void updateNode(Project project) { } @Override - public String cachePath(Project project) { + public String docPath(Project project) { + + RootNode rootNode = (RootNode) getParent(); + + return rootNode.docPath(project) + "/" + module.getName(); + } + + @Override + public String httpPath(Project project) { RootNode rootNode = (RootNode) getParent(); - return rootNode.cachePath(project) + "/" + module.getName(); + return rootNode.httpPath(project) + "/" + module.getName(); } @Override diff --git a/src/main/java/com/liuzhihang/doc/view/ui/window/RootNode.java b/src/main/java/com/liuzhihang/doc/view/ui/window/RootNode.java index db839b7..564eb22 100644 --- a/src/main/java/com/liuzhihang/doc/view/ui/window/RootNode.java +++ b/src/main/java/com/liuzhihang/doc/view/ui/window/RootNode.java @@ -44,10 +44,14 @@ public void updateNode(Project project) { } @Override - public String cachePath(Project project) { + public String docPath(Project project) { return "Doc View"; } + @Override + public String httpPath(Project project) { + return "Http"; + } @Override protected SimpleNode[] buildChildren() { diff --git a/src/main/java/com/liuzhihang/doc/view/utils/CustomFileUtils.java b/src/main/java/com/liuzhihang/doc/view/utils/CustomFileUtils.java index 08dd02d..b990f5a 100644 --- a/src/main/java/com/liuzhihang/doc/view/utils/CustomFileUtils.java +++ b/src/main/java/com/liuzhihang/doc/view/utils/CustomFileUtils.java @@ -14,28 +14,71 @@ import com.liuzhihang.doc.view.DocViewBundle; import com.liuzhihang.doc.view.dto.DocView; import com.liuzhihang.doc.view.dto.DocViewData; +import com.liuzhihang.doc.view.enums.ContentTypeEnum; import com.liuzhihang.doc.view.notification.DocViewNotification; import com.liuzhihang.doc.view.service.DocViewService; import com.liuzhihang.doc.view.ui.window.MethodNode; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; /** + * 自定义文件操作, 文件保存在 "Scratches and Consoles" 下面 + * + * Scratch files + * * @author liuzhihang * @date 2021/12/16 */ public class CustomFileUtils { + /** + * 生成接口文档 md 文件, 并打开 + * + * @param project 项目 + * @param node 右侧目录树节点 + */ + public static void openMd(Project project, MethodNode node) { + + if (node == null) { + return; + } + + DocViewService service = DocViewService.getInstance(project, node.getPsiClass()); + + if (service == null) { + return; + } + + // 生成接口对应的 markdown 文本 + String markdownText = ApplicationManager.getApplication().runReadAction((Computable) () -> { + DocView docView = service.buildClassMethodDoc(project, node.getPsiClass(), node.getPsiMethod()); + return DocViewData.markdownText(project, docView); + }); + + open(project, node.docPath(project), markdownText); + + } + + /** + * 删除生成的文件 + * + * @param project 项目 + * @param path 删除的路径 + */ public static void delete(Project project, String path) { try { + // 获取在文件系统中的虚拟文件 VirtualFile file = ExtensionsRootType.getInstance().findFile(project, path, Option.create_if_missing); + // 在删除之前要先关闭 if (FileEditorManager.getInstance(project).isFileOpen(file)) { FileEditorManager.getInstance(project).closeFile(file); } + // 删除文件 WriteAction.runAndWait(() -> file.delete(project)); } catch (IOException e) { @@ -43,7 +86,13 @@ public static void delete(Project project, String path) { } } - public static void open(MethodNode node, Project project) { + /** + * 生成打开 .http 文件 + * + * @param project 项目 + * @param node 节点 + */ + public static void openHttp(Project project, MethodNode node) { if (node == null) { return; @@ -55,29 +104,60 @@ public static void open(MethodNode node, Project project) { return; } - String markdownText = ApplicationManager.getApplication().runReadAction((Computable) () -> { - DocView docView = service.buildClassMethodDoc(project, node.getPsiClass(), node.getPsiMethod()); - return DocViewData.markdownText(project, docView); - }); + // 解析获取 DocView, 从而可以获取接口信息 + DocView docView = ApplicationManager.getApplication().runReadAction( + (Computable) () -> service.buildClassMethodDoc(project, node.getPsiClass(), node.getPsiMethod())); + + StringBuilder builder = new StringBuilder(); + builder.append("### Doc View: ").append(docView.getName()).append("\n"); + builder.append(docView.getMethod()).append(" {{host}}").append(docView.getPath()); + + if (StringUtils.isNotBlank(docView.getReqFormExample())) { + builder.append("?").append(docView.getReqFormExample()); + } + + builder.append("\n"); + + if (docView.getContentType() == ContentTypeEnum.JSON) { + builder.append(ContentTypeEnum.JSON.getKey()).append(": ").append(ContentTypeEnum.JSON.getValue()).append("\n"); + builder.append("\n"); + builder.append(docView.getReqBodyExample()); + } else { + builder.append(ContentTypeEnum.FORM.getKey()).append(": ").append(ContentTypeEnum.JSON.getValue()).append("\n"); + } + open(project, node.httpPath(project), builder.toString()); + + } + + /** + * 打开文件 + * + * @param project 项目 + * @param pathName 文件路径 + * @param text 文本内容 + */ + private static void open(Project project, String pathName, String text) { try { + // 打开虚拟文件 VirtualFile virtualFile = WriteCommandAction.writeCommandAction(project) .withName(DocViewBundle.message("notify.extensions.file.creating")) .withGlobalUndo().shouldRecordActionForActiveDocument(false) .withUndoConfirmationPolicy(UndoConfirmationPolicy.REQUEST_CONFIRMATION).compute(() -> { + // 使用 ExtensionsRootType 可以打开 Extensions 目录 ExtensionsRootType fileService = ExtensionsRootType.getInstance(); - VirtualFile scratchFile = fileService.findFile(project, node.cachePath(project), Option.create_if_missing); - VfsUtil.saveText(scratchFile, markdownText); + VirtualFile scratchFile = fileService.findFile(project, pathName, Option.create_new_always); + VfsUtil.saveText(scratchFile, text); return scratchFile; }); + // 打开文件, 并聚焦在该文件 if (virtualFile != null) { FileEditorManager.getInstance(project).openFile(virtualFile, true); } } catch (IOException e) { - DocViewNotification.notifyError(project, DocViewBundle.message("notify.extensions.file.create.file", node.getName())); + DocViewNotification.notifyError(project, DocViewBundle.message("notify.extensions.file.create.file", pathName)); } - } } diff --git a/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java b/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java index 184f6c2..1279744 100644 --- a/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java +++ b/src/main/java/com/liuzhihang/doc/view/utils/CustomPsiCommentUtils.java @@ -16,8 +16,6 @@ import java.util.Iterator; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * 从注释中解析注解的工具类 @@ -27,82 +25,87 @@ */ public class CustomPsiCommentUtils { - /** - * 获取注释, 如果指定 tagName 则直接从 tagName 里面获取 + * 获取注释中 tagName 对应的注释, 如果指定 tagName 则直接从 tagName 里面获取 + * + * @param docComment 注释 PsiDocComment + * @param tagName 注释中的 @xxx 标签 + * @return 注释 */ @NotNull - public static String getDocComment(PsiDocComment docComment, String tagName) { + public static String tagDocComment(PsiDocComment docComment, String tagName) { - if (docComment != null) { - for (PsiElement element : docComment.getChildren()) { + String comment = ""; - if (!("PsiDocTag:@" + tagName).equalsIgnoreCase(element.toString())) { - continue; - } + if (docComment == null) { + return comment; + } - return element.getText() - .replace(("@" + tagName), StringUtils.EMPTY) - .trim(); + for (PsiElement element : docComment.getChildren()) { + // 不是 tagName 则继续查找 + if (!("PsiDocTag:@" + tagName).equalsIgnoreCase(element.toString())) { + continue; } + + return element.getText() + .replace(("@" + tagName), StringUtils.EMPTY) + .trim(); + } return ""; } /** - * 获取方法字段的注释 + * 获取方法中字段的注释, 一般会用 @param 标注出来 + * + * @param docComment 方法的注释 Psi + * @param parameter 参数 + * @return 字段注释 */ @NotNull - public static String getMethodParam(PsiDocComment docComment, @NotNull PsiParameter parameter) { + public static String paramDocComment(PsiDocComment docComment, @NotNull PsiParameter parameter) { - if (docComment != null) { - for (PsiElement element : docComment.getChildren()) { + String comment = ""; - if (!("PsiDocTag:@param").equalsIgnoreCase(element.toString())) { - continue; - } - String parameterName = parameter.getName(); - - boolean matchDocLine = false; - PsiElement[] children = element.getChildren(); - for (PsiElement child : children) { - if (parameterName.equals(child.getText())) { - matchDocLine = true; - break; - } - } - //当前行的 @param 是否是 当前parameter 的描述 - if (!matchDocLine) { - continue; - } + if (docComment == null) { + return comment; + } + + for (PsiElement element : docComment.getChildren()) { + + // 不是当前字段则继续循环 + if (!("PsiDocTag:@param").equalsIgnoreCase(element.toString())) { + continue; + } + + // 在注释中定位到该参数 + if (element.getText().startsWith("@param " + parameter.getName())) { - //如果element.getText()最后包含换行或者空格则去掉 - String text = StringUtils.trim(element.getText()); + String paramWithComment = element.getText(); - //用于匹配"@param"开头,方法参数结尾 - Pattern docCommentTagCompile = Pattern.compile("@param\\s+" + parameterName); - Matcher matcher = docCommentTagCompile.matcher(text); - if (matcher.find()) { - int startPoint = matcher.group(0).length(); - return text.substring(startPoint); + if (paramWithComment.contains("\n")) { + // 该字段后面还有注释 + comment = paramWithComment.substring(("@param " + parameter.getName()).length(), element.getText().indexOf("\n")); + } else { + // 该字段后面没有其他注释, 只有 */ + comment = paramWithComment.substring(("@param " + parameter.getName()).length()); } } } - - return ""; + // 移除前后的空格 + return comment.trim(); } - /** - * 获取注释, 没有 tag 的注释 + * 获取注释, 没有 tag 的注释, 一般是卸载注释开头的位置 * - * @param docComment - * @return + * @param docComment 注释 PSI + * @return 注释 */ @NotNull - public static String getDocComment(PsiDocComment docComment) { + public static String tagDocComment(PsiDocComment docComment) { return ApplicationManager.getApplication().runReadAction((Computable) () -> { @@ -127,17 +130,16 @@ public static String getDocComment(PsiDocComment docComment) { /** * 获取注释, 没有 tag 的注释 * - * @param docComment + * @param docComment 注释 PSI * @param oneLine 只获取一行 - * @return + * @return 注释 */ @NotNull - public static String getDocComment(PsiDocComment docComment, Boolean oneLine) { - + public static String tagDocComment(PsiDocComment docComment, Boolean oneLine) { return ApplicationManager.getApplication().runReadAction((Computable) () -> { if (!oneLine) { - return getDocComment(docComment); + return tagDocComment(docComment); } if (docComment != null) { for (PsiElement element : docComment.getChildren()) { @@ -153,10 +155,16 @@ public static String getDocComment(PsiDocComment docComment, Boolean oneLine) { } - + /** + * 获取字段的注释 + * + * 举例 // xxx + * + * @param psiComment 字段的注释 PSI + * @return 注释 + */ @NotNull - public static String getComment(PsiComment psiComment) { - + public static String fieldComment(PsiComment psiComment) { if (psiComment != null && StringUtils.isNotBlank(psiComment.getText())) { // 原注释中的换行符移除 @@ -166,35 +174,6 @@ public static String getComment(PsiComment psiComment) { return ""; } - - /** - * 保留换行 - * - * @param docComment - * @return - */ - @NotNull - public static String getMethodComment(PsiDocComment docComment) { - StringBuilder sb = new StringBuilder(); - - if (docComment != null) { - for (PsiElement element : docComment.getChildren()) { - - if (!"PsiDocToken:DOC_COMMENT_DATA".equalsIgnoreCase(element.toString())) { - continue; - } - if (sb.length() > 0) { - // 保留换行符 - sb.append(element.getText().replaceAll("[/* ]+", StringUtils.EMPTY)).append("\n"); - } else { - sb.append(element.getText().replaceAll("[/* ]+", StringUtils.EMPTY)); - } - - } - } - return sb.toString(); - } - /** * 构建参数 * @@ -237,7 +216,6 @@ public static List buildParams(@NotNull List elements, List< return paramDocList; } - /** * 构建返回 * diff --git a/src/main/java/com/liuzhihang/doc/view/utils/DocViewUtils.java b/src/main/java/com/liuzhihang/doc/view/utils/DocViewUtils.java index d8c1259..ccb0120 100644 --- a/src/main/java/com/liuzhihang/doc/view/utils/DocViewUtils.java +++ b/src/main/java/com/liuzhihang/doc/view/utils/DocViewUtils.java @@ -4,7 +4,19 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiAnnotationMemberValue; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiNameValuePair; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.PsiType; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.util.InheritanceUtil; @@ -52,7 +64,6 @@ public static boolean isDocViewClass(@Nullable PsiClass psiClass) { return true; } - if (psiClass.isInterface()) { return Settings.getInstance(psiClass.getProject()).getIncludeNormalInterface() || DubboPsiUtils.isDubboClass(psiClass) @@ -89,7 +100,6 @@ public static boolean isDocViewMethod(@Nullable PsiMethod psiMethod) { return false; } - /** * 匿名类和内部类可能返回 null *

@@ -106,7 +116,7 @@ public static String getTitle(@NotNull PsiClass psiClass) { if (settings.getTitleUseCommentTag()) { // 注释 @DocView.Title - String docTitleTagValue = CustomPsiCommentUtils.getDocComment(psiClass.getDocComment(), settings.getTitleTag()); + String docTitleTagValue = CustomPsiCommentUtils.tagDocComment(psiClass.getDocComment(), settings.getTitleTag()); if (StringUtils.isNotBlank(docTitleTagValue)) { return docTitleTagValue; @@ -116,7 +126,7 @@ public static String getTitle(@NotNull PsiClass psiClass) { if (settings.getTitleClassComment()) { // 获取类注释 - String comment = CustomPsiCommentUtils.getDocComment(psiClass.getDocComment()); + String comment = CustomPsiCommentUtils.tagDocComment(psiClass.getDocComment()); if (StringUtils.isNotBlank(comment)) { return comment; @@ -149,7 +159,9 @@ public static String getTitle(@NotNull PsiClass psiClass) { *

* 支持 Swagger/方法名/自定义注释 tag * - * @param psiMethod + * 如果是方法注释, 则限制 15 个字符 + * + * @param psiMethod 当前方法 * @return */ @NotNull @@ -179,7 +191,7 @@ public static String getName(@NotNull PsiMethod psiMethod) { // 注释上的 tag if (settings.getNameUseCommentTag()) { - String comment = CustomPsiCommentUtils.getDocComment(psiMethod.getDocComment(), settings.getNameTag()); + String comment = CustomPsiCommentUtils.tagDocComment(psiMethod.getDocComment(), settings.getNameTag()); if (StringUtils.isNotBlank(comment)) { return comment; @@ -187,11 +199,16 @@ public static String getName(@NotNull PsiMethod psiMethod) { } if (settings.getNameMethodComment()) { - // 获取类注释 - String comment = CustomPsiCommentUtils.getDocComment(psiMethod.getDocComment(), true); + // 方法注释 + String comment = CustomPsiCommentUtils.tagDocComment(psiMethod.getDocComment(), true); if (StringUtils.isNotBlank(comment)) { + + if (comment.length() > 15) { + comment = comment.substring(0, 15); + } + return comment; } } @@ -234,10 +251,9 @@ public static String getMethodDesc(@NotNull PsiMethod psiMethod) { } // 最后从注释中获取 - return CustomPsiCommentUtils.getDocComment(psiMethod.getDocComment()); + return CustomPsiCommentUtils.tagDocComment(psiMethod.getDocComment()); } - /** * 判断是否是需要排除的字段 * @@ -271,7 +287,6 @@ public static boolean isExcludeField(@NotNull PsiField psiField) { return true; } - return excludeClassPackage(containingClass, settings); } @@ -297,11 +312,9 @@ private static boolean excludeClassPackage(@NotNull PsiClass psiClass, @NotNull } } - return false; } - /** * 判断是否是需要排除的字段 * @@ -331,7 +344,6 @@ public static boolean isExcludeParameter(@NotNull PsiParameter psiParameter) { return false; } - /** * 判断字段是否必填 * @@ -346,7 +358,6 @@ public static boolean isRequired(@NotNull PsiField psiField) { return true; } - // swagger v3 @Schema PsiAnnotation schemaAnnotation = psiField.getAnnotation(SwaggerConstant.SCHEMA); if (schemaAnnotation != null) { @@ -394,7 +405,6 @@ public static boolean isRequired(@NotNull PsiParameter psiParameter) { return true; } - if (AnnotationUtil.isAnnotated(psiParameter, SpringConstant.REQUEST_PARAM, 0)) { PsiAnnotation annotation = psiParameter.getAnnotation(SpringConstant.REQUEST_PARAM); if (annotation != null) { @@ -413,7 +423,6 @@ public static boolean isRequired(@NotNull PsiParameter psiParameter) { return false; } - /** * 获取字段的描述 *

@@ -442,16 +451,15 @@ public static String fieldDesc(@NotNull PsiField psiField) { } } - PsiComment comment = PsiTreeUtil.findChildOfType(psiField, PsiComment.class); if (comment != null) { // param.setExample(); // 参数举例, 使用 tag 判断 if (comment instanceof PsiDocComment) { - return CustomPsiCommentUtils.getDocComment((PsiDocComment) comment); + return CustomPsiCommentUtils.tagDocComment((PsiDocComment) comment); } - return CustomPsiCommentUtils.getComment(comment); + return CustomPsiCommentUtils.fieldComment(comment); } return ""; } @@ -539,9 +547,7 @@ public static void writeComment(Project project, @NotNull Map findDocViewFromModule(Module module) { - Collection psiAnnotations = JavaAnnotationIndex.getInstance().get("Controller", module.getProject(), GlobalSearchScope.moduleScope(module)); - Collection restController = JavaAnnotationIndex.getInstance().get("RestController", module.getProject(), GlobalSearchScope.moduleScope(module)); + Collection psiAnnotations = JavaAnnotationIndex.getInstance().get("Controller", module.getProject(), + GlobalSearchScope.moduleScope(module)); + Collection restController = JavaAnnotationIndex.getInstance().get("RestController", module.getProject(), + GlobalSearchScope.moduleScope(module)); psiAnnotations.addAll(restController); List psiClasses = new LinkedList<>(); @@ -85,122 +118,155 @@ public static List findDocViewFromModule(Module module) { return psiClasses; } - @NotNull - public static String getMethod(PsiMethod psiMethod) { + public static String method(PsiMethod psiMethod) { String method; if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.GET_MAPPING, 0)) { - method = "GET"; + method = GET; } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.POST_MAPPING, 0)) { - method = "POST"; + method = POST; } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.PUT_MAPPING, 0)) { - method = "PUT"; + method = PUT; } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.DELETE_MAPPING, 0)) { - method = "DELETE"; + method = DELETE; } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.PATCH_MAPPING, 0)) { - method = "PATCH"; + method = PATCH; } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.REQUEST_MAPPING, 0)) { PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMethod, SpringConstant.REQUEST_MAPPING); if (annotation == null) { - method = "GET"; + method = GET; } else { String value = AnnotationUtil.getStringAttributeValue(annotation, "method"); - method = value == null ? "GET" : value; + method = value == null ? GET : value; } } else { - method = "GET"; + method = GET; } - return method; + return method.toUpperCase(); } /** * 从类注解中解析出请求路径 * - * @param psiClass - * @param psiMethod - * @return + * @param psiClass 类 + * @param psiMethod 方法 + * @return 路径, 路径开头为 / + * @see SpringPsiUtils#path(PsiAnnotation) */ @NotNull - public static String getPath(PsiClass psiClass, @NotNull PsiMethod psiMethod) { + public static String path(PsiClass psiClass, @NotNull PsiMethod psiMethod) { - String basePath = getBasePath(psiClass); - String methodPath = getMethodPath(psiMethod); + String classPath = classPath(psiClass); + String methodPath = methodPath(psiMethod); - if (StringUtils.isBlank(basePath)) { + if (StringUtils.isBlank(classPath)) { return methodPath; } if (StringUtils.isBlank(methodPath)) { - return basePath; + return classPath; } - if (!methodPath.startsWith("/")) { - methodPath = "/" + methodPath; - } - - String path = basePath + methodPath; - - return path.replace("//", "/"); + // 拼接最终结果 + return classPath + methodPath; } + /** + * 获取类的路径, 比如 @RequestMapping("/xxx") + * + * @param psiClass 类 + * @return 路径 + */ @NotNull - public static String getBasePath(PsiClass psiClass) { + public static String classPath(PsiClass psiClass) { // controller 路径 PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiClass, SpringConstant.REQUEST_MAPPING); - return getPath(annotation); + return path(annotation); } + /** + * 根据方法获取请求路径, 就是方法注解中写的路径 + * + * @param psiMethod 方法 + * @return 请求方式 + */ + public static String methodPath(PsiMethod psiMethod) { + + String url = ""; + + // 是否包含 Spring xxxMapping 注解 + if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.MAPPING_ANNOTATIONS, 0)) { + url = path(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.MAPPING_ANNOTATIONS)); + } + return url; + } + /** + * 从注解中解析路径, 路径结构都为 /xxx + * + * 开头为 / + * 结束没有 / + * 空时为 "" + * + * @param annotation 需要解析路径的注解, 可能是 xxxController 也可能是 xxxMapping + * @return 注解 value 字段对应的路径 + */ @NotNull - private static String getPath(PsiAnnotation annotation) { + private static String path(PsiAnnotation annotation) { if (annotation == null) { return ""; } - String value = AnnotationUtil.getStringAttributeValue(annotation, "value"); - if (value != null) { - if (value.startsWith("/")) { - return value; - } else { - return "/" + value; + // 获取注解中 value 字段对应的值 + String path = AnnotationUtil.getStringAttributeValue(annotation, "value"); + if (path != null) { + if (!path.startsWith("/")) { + path = "/" + path; + } + + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); } + + return path; } return ""; } + /** + * 获取当前方法的 Context-Type + * + * @param psiMethod 方法 + * @return Context-Type + */ + public static ContentTypeEnum contentType(@NotNull PsiMethod psiMethod) { - public static String getMethodPath(PsiMethod psiMethod) { - String url; + PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); - if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.GET_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.GET_MAPPING)); - } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.POST_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.POST_MAPPING)); - } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.PUT_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.PUT_MAPPING)); - } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.DELETE_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.DELETE_MAPPING)); - } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.PATCH_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.PATCH_MAPPING)); - } else if (AnnotationUtil.isAnnotated(psiMethod, SpringConstant.REQUEST_MAPPING, 0)) { - url = getPath(AnnotationUtil.findAnnotation(psiMethod, SpringConstant.REQUEST_MAPPING)); - } else { - url = ""; + for (PsiParameter parameter : parameters) { + + // 通用排除字段 + if (DocViewUtils.isExcludeParameter(parameter)) { + continue; + } + + if (AnnotationUtil.isAnnotated(parameter, SpringConstant.REQUEST_BODY, 0)) { + return ContentTypeEnum.JSON; + } } - return url; + return ContentTypeEnum.FORM; } - /** * 获取被 RequestBody 注解修饰的参数, 只需要获取第一个即可, 因为多个不会生效. * - * @param psiMethod - * @return + * @param psiMethod 方法 + * @return 被 @RequestBody 修饰的参数 */ - public static PsiParameter getRequestBodyParam(@NotNull PsiMethod psiMethod) { + public static PsiParameter requestBodyParam(@NotNull PsiMethod psiMethod) { PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); for (PsiParameter parameter : parameters) { @@ -217,7 +283,6 @@ public static PsiParameter getRequestBodyParam(@NotNull PsiMethod psiMethod) { return null; } - /** * 构建 Header * @@ -226,10 +291,19 @@ public static PsiParameter getRequestBodyParam(@NotNull PsiMethod psiMethod) { */ @NotNull public static List

buildHeader(@NotNull PsiMethod psiMethod) { + List
list = new ArrayList<>(); + // 先设置 header 中的 contentType + ContentTypeEnum contentType = contentType(psiMethod); + Header contentTypeHeader = new Header(); + contentTypeHeader.setRequired(true); + contentTypeHeader.setName(contentType.getKey()); + contentTypeHeader.setValue(contentType.getValue()); + list.add(contentTypeHeader); + + // 判断有无 @Header 注解的参数 PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); - List
list = new ArrayList<>(); for (PsiParameter parameter : parameters) { if (!AnnotationUtil.isAnnotated(parameter, SpringConstant.REQUEST_HEADER, 0)) { @@ -239,7 +313,7 @@ public static List
buildHeader(@NotNull PsiMethod psiMethod) { PsiType type = parameter.getType(); // 不是 String 就不处理了 - if (!type.getPresentableText().equals("String")) { + if (!"String".equals(type.getPresentableText())) { continue; } @@ -296,9 +370,8 @@ public static Body buildBody(@NotNull PsiParameter parameter) { return root; } - @NotNull - public static String getReqBodyJson(@NotNull PsiParameter parameter, @NotNull Settings settings) { + public static String reqBodyJson(@NotNull PsiParameter parameter, @NotNull Settings settings) { Map fieldMap = new LinkedHashMap<>(); String name = parameter.getName(); PsiType type = parameter.getType(); @@ -319,7 +392,6 @@ public static String getReqBodyJson(@NotNull PsiParameter parameter, @NotNull Se } - /** * 拼装为 kv 形式的键值对 * @@ -327,7 +399,7 @@ public static String getReqBodyJson(@NotNull PsiParameter parameter, @NotNull Se * @return */ @NotNull - public static String getReqParamKV(List requestParam) { + public static String reqParamKV(List requestParam) { if (requestParam == null || requestParam.isEmpty()) { return ""; @@ -339,10 +411,9 @@ public static String getReqParamKV(List requestParam) { paramKV.append("&").append(param.getName()).append("=").append(param.getExample()); } - return paramKV.toString(); + return paramKV.substring(1); } - public static List buildFormParam(PsiMethod psiMethod) { if (!psiMethod.hasParameters()) { @@ -420,7 +491,6 @@ private static Param buildPramFromField(PsiField field) { return param; } - @NotNull private static Param buildPramFromParameter(PsiMethod psiMethod, PsiParameter parameter) { @@ -432,10 +502,9 @@ private static Param buildPramFromParameter(PsiMethod psiMethod, PsiParameter pa // 备注需要从注释中获取 PsiDocComment docComment = psiMethod.getDocComment(); if (docComment != null) { - param.setDesc(CustomPsiCommentUtils.getMethodParam(docComment, parameter)); + param.setDesc(CustomPsiCommentUtils.paramDocComment(docComment, parameter)); } - return param; } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 66f41e1..016cc94 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -35,11 +35,11 @@ - + - + - + @@ -154,7 +154,6 @@ - @@ -217,6 +216,11 @@ + + + diff --git a/src/test/java/com/liuzhihang/doc/view/MainTest.java b/src/test/java/com/liuzhihang/doc/view/MainTest.java index 056f2b2..ba38f68 100644 --- a/src/test/java/com/liuzhihang/doc/view/MainTest.java +++ b/src/test/java/com/liuzhihang/doc/view/MainTest.java @@ -4,17 +4,14 @@ */ package com.liuzhihang.doc.view; -import com.intellij.openapi.util.text.StringUtil; - /** - * @author zijun.lzh - * @version MainTest.java, v 0.1 2022年06月08日 2:39 PM zijun.lzh + * @author liuzhihang + * @version MainTest.java, v 0.1 2022年06月08日 2:39 PM liuzhihang */ public class MainTest { public static void main(String[] args) { - StringUtil. } } \ No newline at end of file