Commit 8e6f9c27 authored by duanledexianxianxian's avatar duanledexianxianxian 😁

代码重构

parent 2e4958b6
......@@ -4,4 +4,6 @@ dependencies {
compile 'org.asciidoctor:asciidoctorj:2.1.0'
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
compile group: 'com.google.guava', name: 'guava', version: '23.0'
compile group: 'org.apache.commons', name: 'commons-lang3'
compile group: 'org.apache.commons', name: 'commons-collections4'
}
......@@ -9,6 +9,7 @@ import com.github.fengyuchenglun.apidoc.core.schema.Project;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
......@@ -17,7 +18,9 @@ import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeS
import com.github.javaparser.utils.SourceRoot;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.nio.file.Path;
......@@ -26,7 +29,7 @@ import java.util.Objects;
import java.util.ServiceLoader;
/**
* The type ApiDoc.
* apidoc配置类.
*
* @author fengyuchenglun
* @version 1.0.0
......@@ -34,10 +37,6 @@ import java.util.ServiceLoader;
@Slf4j
public class ApiDoc {
/**
* ApiDoc实例
*/
private static ApiDoc INSTANCE;
/**
* 上下文
*/
......@@ -56,6 +55,14 @@ public class ApiDoc {
* The Parser configuration.
*/
private ParserConfiguration parserConfiguration;
/**
* 统一结果
*/
@Setter
@Getter
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration;
/**
* The Type resolvers.
*/
......@@ -84,26 +91,40 @@ public class ApiDoc {
* @return the api doc
*/
public static ApiDoc getInstance() {
return INSTANCE;
return ApiDocInstance.INSTANCE;
}
private static class ApiDocInstance {
/**
* The constant INSTANCE.
*/
public static ApiDoc INSTANCE = new ApiDoc();
}
/**
* 初始化环境配置
*
* @param context the context
*/
private void init(Context context) {
INSTANCE = this;
// 保存自身实例
ApiDocInstance.INSTANCE = this;
this.context = context;
// 初始化项目
project.setId(context.getId());
project.setName(context.getName());
project.setDescription(context.getDescription());
project.setVersion(context.getVersion());
// dependencies设置typeSolver
CombinedTypeSolver typeSolver = new CombinedTypeSolver();
for (Path dependency : context.getDependencies()) {
typeSolver.add(new JavaParserTypeSolver(dependency));
}
// jars设置typeSolver
for (Path jar : context.getJars()) {
try {
typeSolver.add(new JarTypeSolver(jar));
......@@ -111,11 +132,13 @@ public class ApiDoc {
log.warn("exception on {} {}", jar, e.getMessage());
}
}
// 反射?
typeSolver.add(new ReflectionTypeSolver());
parserConfiguration = new ParserConfiguration();
parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
// 加载策略
ParserStrategy strategy = loadParserStrategy();
strategy.onLoad();
visitorParser.setParserStrategy(strategy);
......@@ -135,7 +158,8 @@ public class ApiDoc {
if (strategies.isEmpty()) {
throw new IllegalArgumentException("no ParserStrategy implements found");
}
if (StringHelper.isBlank(context.getFramework())) {
// 用户未配置context的framework
if (StringUtils.isBlank(context.getFramework())) {
return strategies.get(0);
}
for (ParserStrategy strategy : strategies) {
......@@ -147,7 +171,7 @@ public class ApiDoc {
}
/**
* 解析源代码
* 1. 解析源代码
*
* @return project project
*/
......@@ -157,6 +181,7 @@ public class ApiDoc {
try {
for (ParseResult<CompilationUnit> result : root.tryToParse()) {
if (result.isSuccessful() && result.getResult().isPresent()) {
//note: 访问解析器 +当前项目上下文
result.getResult().get().accept(visitorParser, project);
}
}
......@@ -168,7 +193,7 @@ public class ApiDoc {
}
/**
* 渲染解析结果
* 2. 渲染解析结果
*/
public void render() {
for (ProjectRender render : this.context.getRenders()) {
......
......@@ -17,7 +17,8 @@ import java.util.List;
import java.util.Map;
/**
* The type Context.
* 上下文.
* 用户可自定义配置参数
*
* @author fengyuchenglun
* @version 1.0.0
......@@ -42,6 +43,8 @@ public class Context {
*/
public static final String DEFAULT_CODE_STRUCTURE = "src/main/java";
/**
* 设置当前解析框架
*/
......@@ -118,7 +121,7 @@ public class Context {
private Map<String, Object> ext = Maps.newHashMap();
/**
* Add source.
* 添加源码.
*
* @param path the path
*/
......@@ -129,7 +132,9 @@ public class Context {
}
/**
* Add dependency.
* 添加依赖.
* 文件路径:例如
* /url/api-doc/
*
* @param path the path
*/
......@@ -139,7 +144,7 @@ public class Context {
}
/**
* Add jar.
* 添加jar.
*
* @param path the path
*/
......
......@@ -11,9 +11,25 @@ import java.nio.charset.StandardCharsets;
* @since 1.0.0
*/
public class Constants {
/**
* The constant UTF8.
*/
public static final String UTF8 = StandardCharsets.UTF_8.name();
/**
* The constant SLASH.
*/
public static final String SLASH = "/";
/**
* The constant MARKDOWN_EXTENSION.
*/
public static final String MARKDOWN_EXTENSION = ".md";
/**
* markdown模版文件默认路径
*/
public static final String MARKDOWN_TEMPLATE = "/templates/markdown.ftl";
/**
* 自定义tag-mock
*/
public static final String TAG_CUSTOM_JAVA_DOC_MOCK = "mock";
}
package com.github.fengyuchenglun.apidoc.core.common.convert;
import com.google.common.collect.Maps;
import java.sql.JDBCType;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* The enum Field type convert.
*
* @author duanledexianxianxian
*/
public enum FieldTypeConvert implements IFieldTypeConvert {
/**
* String field type convert.
*/
STRING("String", "String"),
/**
* Byte field type convert.
*/
BYTE("Byte", "Byte"),
/**
* Short field type convert.
*/
SHORT("Integer", "Short"),
/**
* Char field type convert.
*/
CHAR("String", "Char"),
/**
* Int field type convert.
*/
INT("Integer", "int"),
/**
* Long field type convert.
*/
LONG("Long", "Long"),
/**
* Boolean field type convert.
*/
BOOLEAN("Boolean", "Boolean"),
/**
* Float field type convert.
*/
FLOAT("Float", "Float"),
/**
* Double field type convert.
*/
DOUBLE("Double", "Double"),
/**
* Local date field type convert.
*/
LOCAL_DATE("Date", "LocalDate"),
/**
* Local date time field type convert.
*/
LOCAL_DATE_TIME("DateTime", "LocalDateTime"),
/**
* Local time field type convert.
*/
LOCAL_TIME("Time", "LocalTime"),
/**
* Other field type convert.
*/
OTHER("object", "Object"),
;
/**
* The Type.
*/
private final String type;
/**
* The Java type.
*/
private final String javaType;
/**
* Instantiates a new Field type convert.
*
* @param type the type
* @param javaType the java type
*/
FieldTypeConvert(String type, String javaType) {
this.type = type;
this.javaType = javaType;
}
@Override
public String getType() {
return type;
}
@Override
public String getJavaType() {
return javaType;
}
/**
* The Field type cache map.
*/
private static Map<String, IFieldTypeConvert> FIELD_TYPE_CACHE_MAP = Maps.newConcurrentMap();
static {
for (IFieldTypeConvert fieldTypeConvert : FieldTypeConvert.values()) {
FIELD_TYPE_CACHE_MAP.put(fieldTypeConvert.getJavaType().toLowerCase(), fieldTypeConvert);
}
}
/**
* Java type of field type convert.
*
* @param javaType the java type
* @return the field type convert
*/
public static IFieldTypeConvert javaTypeOf(String javaType) {
return FIELD_TYPE_CACHE_MAP.get(javaType.toLowerCase());
}
}
package com.github.fengyuchenglun.apidoc.core.common.convert;
/**
* 字段类型转换接口.
*
* @author duanledexianxianxian
*/
public interface IFieldTypeConvert {
/**
* 获取字段类型
* 展示类型
*
* @return 字段类型 type
*/
String getType();
/**
* 获取字段java类型
* 除java.lang包下的包类型
*
* @return 获取字段java类型 java type
*/
String getJavaType();
}
package com.github.fengyuchenglun.apidoc.core.common.description;
import com.github.fengyuchenglun.apidoc.core.common.ObjectMappers;
import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper;
import com.github.fengyuchenglun.apidoc.core.schema.Row;
import com.fasterxml.jackson.databind.node.ArrayNode;
import lombok.Data;
......@@ -11,14 +12,27 @@ import java.util.Collection;
/**
* 数组类型描述
*
* @author duanledexianxianxian
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class ArrayTypeDescription extends TypeDescription {
/**
* The Value.
*/
protected ArrayNode value;
/**
* The Component.
*/
protected TypeDescription component;
/**
* Instantiates a new Array type description.
*
* @param component the component
*/
public ArrayTypeDescription(TypeDescription component) {
this.component = component;
this.value = ObjectMappers.instance.createArrayNode();
......@@ -38,6 +52,11 @@ public class ArrayTypeDescription extends TypeDescription {
}
}
/**
* Primitive.
*
* @param typeDescription the type description
*/
public void primitive(PrimitiveTypeDescription typeDescription) {
switch (typeDescription.getType()) {
case "byte":
......@@ -83,20 +102,31 @@ public class ArrayTypeDescription extends TypeDescription {
}
}
@Override
public String fullKey() {
return StringHelper.join("[].", prefix, key);
}
@Override
public ArrayNode getValue() {
return value;
}
@Override
public Collection<Row> rows() {
public Collection<Row> rows(String parameterType) {
ArrayList<Row> rows = new ArrayList<>();
if (key != null) {
rows.addAll(super.rows());
rows.addAll(super.rows(parameterType));
}
if (component.isAvailable()) {
rows.addAll(component.rows());
rows.addAll(component.rows(parameterType));
}
return rows;
}
@Override
public Collection<Row> rows() {
return rows(null);
}
}
package com.github.fengyuchenglun.apidoc.core.common.description;
import ch.qos.logback.core.util.OptionHelper;
import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper;
import com.github.fengyuchenglun.apidoc.core.common.helper.OptionalHelper;
import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper;
import com.github.fengyuchenglun.apidoc.core.schema.Row;
import com.github.fengyuchenglun.apidoc.core.schema.Tag;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.javadoc.Javadoc;
import com.google.common.collect.Lists;
......@@ -10,11 +13,17 @@ import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static com.github.fengyuchenglun.apidoc.core.common.Constants.TAG_CUSTOM_JAVA_DOC_MOCK;
/**
* The type Type description.
* 对象描述.
*
* @author duanledexianxianxian
*/
......@@ -22,21 +31,30 @@ import java.util.Collection;
public abstract class TypeDescription {
/**
* The Prefix.
* 前缀.
*/
protected String prefix = "";
/**
* The Key.
* key.
*/
protected String key = "";
/**
* The Type.
* 类型.
*/
protected String type;
/**
* The Condition.
* 条件.
*/
protected StringBuilder condition = new StringBuilder();
/**
* 名称
*/
String name;
/**
* 描述
*/
String description;
/**
* 说明.
*/
......@@ -50,6 +68,11 @@ public abstract class TypeDescription {
*/
protected Object defaultValue;
/**
* javadoc 中的tag
*/
Map<String, Tag> tags = new HashMap<>();
/**
* 是否必填.
*/
......@@ -161,6 +184,7 @@ public abstract class TypeDescription {
}
}
/**
* Full key string.
*
......@@ -173,6 +197,7 @@ public abstract class TypeDescription {
/**
* Rows collection.
*
* @param parameterType the parameter type
* @return the collection
*/
public Collection<Row> rows(String parameterType) {
......@@ -181,7 +206,9 @@ public abstract class TypeDescription {
return Lists.newArrayList();
}
String def;
if (defaultValue != null) {
if (null != tags.get(TAG_CUSTOM_JAVA_DOC_MOCK)) {
def = tags.get(TAG_CUSTOM_JAVA_DOC_MOCK).getContent();
} else if (defaultValue != null) {
def = String.valueOf(defaultValue);
} else if (value != null) {
def = String.valueOf(value);
......@@ -206,13 +233,36 @@ public abstract class TypeDescription {
return this.rows(null);
}
/**
* Accept.
*
* @param comment the comment
*/
public void accept(Comment comment) {
String content;
if (!comment.isJavadocComment()) {
setRemark(comment.getContent());
content = comment.getContent();
setRemark(content);
return;
}
Javadoc javadoc = comment.asJavadocComment().parse();
setRemark(CommentHelper.getDescription(javadoc.getDescription()));
content = CommentHelper.getDescription(javadoc.getDescription());
setRemark(content);
}
/**
* Put tag.
*
* @param tag the tag
*/
public void putTag(Tag tag) {
String id = tag.getId();
if (StringHelper.nonBlank(tag.getKey())) {
id += ":" + tag.getKey();
}
tags.put(id, tag);
}
}
......@@ -29,6 +29,7 @@ public class CommentHelper {
public static String getDescription(JavadocDescription description) {
return description.getElements()
.stream()
// 过滤非单行注释
.filter(e -> !(e instanceof JavadocInlineTag))
.map(JavadocDescriptionElement::toText).collect(Collectors.joining());
}
......@@ -65,7 +66,7 @@ public class CommentHelper {
}
/**
* Get comment string.
* 获取字段注释.
*
* @param it the it
* @return the string
......@@ -84,4 +85,14 @@ public class CommentHelper {
}
public static Optional<Comment> getOptionalComment(ResolvedFieldDeclaration it) {
if (it instanceof JavaParserFieldDeclaration) {
FieldDeclaration wrappedNode = ((JavaParserFieldDeclaration) it).getWrappedNode();
Optional<Comment> optional = wrappedNode.getComment();
return optional;
}
return Optional.empty();
}
}
......@@ -6,12 +6,17 @@ import com.github.javaparser.ast.body.EnumDeclaration;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* The type Enum helper.
*
* @author duanledexianxianxian
*/
public class EnumHelper {
......@@ -21,10 +26,10 @@ public class EnumHelper {
* @param enumDeclaration the enum declaration
* @return the string
*/
public static String getNames(ResolvedEnumDeclaration enumDeclaration){
public static String getNames(ResolvedEnumDeclaration enumDeclaration) {
StringBuilder sb = new StringBuilder();
for (ResolvedEnumConstantDeclaration resolvedEnumConstantDeclaration : enumDeclaration.getEnumConstants()) {
if(sb.length()>0){
if (sb.length() > 0) {
sb.append(",");
}
sb.append(resolvedEnumConstantDeclaration.getName());
......@@ -38,8 +43,8 @@ public class EnumHelper {
* @param declaration the declaration
* @return the list
*/
public static List<Cell<String>> toDetails(EnumDeclaration declaration){
List<Cell<String>> cells = new ArrayList<>();
public static List<Cell<String>> toDetails(EnumDeclaration declaration) {
List<Cell<String>> cells = Lists.newArrayList();
for (EnumConstantDeclaration constant : declaration.getEntries()) {
Cell<String> cell = new Cell<>();
cell.add(constant.getNameAsString());
......@@ -47,6 +52,9 @@ public class EnumHelper {
Object value = ExpressionHelper.getValue(expression);
cell.add(String.valueOf(value));
}
if (cell.size() == 2) {
cell.add(1, cell.get(0));
}
cells.add(cell);
}
return cells;
......
......@@ -11,14 +11,20 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 表达式帮助类.
*
* @author duanledexianxianxian
*/
@Slf4j
public class ExpressionHelper {
/**
* 解析表达式,获取表达式的值
* TODO 更复杂的表达式解析
* @param expr
* @return
*
* @param expr the expr
* @return value value
*/
public static Object getValue(Expression expr) {
if (expr.isStringLiteralExpr()) {
......@@ -45,6 +51,12 @@ public class ExpressionHelper {
return expr.toString();
}
/**
* Get string value string.
*
* @param expression the expression
* @return the string
*/
public static String getStringValue(Expression expression){
if(expression.isStringLiteralExpr()){
return expression.asStringLiteralExpr().getValue();
......@@ -59,6 +71,12 @@ public class ExpressionHelper {
return expression.toString();
}
/**
* Get string values list.
*
* @param expression the expression
* @return the list
*/
public static List<String> getStringValues(Expression expression){
List<String> results = new ArrayList<>();
if(expression.isStringLiteralExpr()){
......@@ -76,6 +94,12 @@ public class ExpressionHelper {
return results;
}
/**
* Resolve object.
*
* @param resolvable the resolvable
* @return the object
*/
private static Object resolve(Resolvable resolvable){
try {
Object resolve = resolvable.resolve();
......
......@@ -2,8 +2,20 @@ package com.github.fengyuchenglun.apidoc.core.common.helper;
import java.util.Optional;
/**
* optional帮助类
*
* @author duanledexianxianxian
*/
public class OptionalHelper {
/**
* Any optional.
*
* @param <T> the type parameter
* @param optionals the optionals
* @return the optional
*/
@SafeVarargs
public static <T> Optional<T> any(Optional<T>... optionals) {
for (Optional<T> optional : optionals) {
......
......@@ -10,22 +10,66 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* JavaBean 验证器帮助类
*
* @author duanledexianxianxian
*/
public class ValidationHelper {
/**
* The constant NULL.
*/
public static final String NULL = "Null";
/**
* The constant NOT_NULL.
*/
public static final String NOT_NULL = "NotNull";
/**
* The constant ASSERT_TRUE.
*/
public static final String ASSERT_TRUE = "AssertTrue";
/**
* The constant ASSERT_FALSE.
*/
public static final String ASSERT_FALSE = "AssertFalse";
/**
* The constant NOT_EMPTY.
*/
public static final String NOT_EMPTY = "NotEmpty";
/**
* The constant NOT_BLANK.
*/
public static final String NOT_BLANK = "NotBlank";
/**
* The constant EMAIL.
*/
public static final String EMAIL = "Email";
/**
* The constant MIN.
*/
public static final String MIN = "Min";
/**
* The constant MAX.
*/
public static final String MAX = "Max";
/**
* The constant SIZE.
*/
public static final String SIZE = "Size";
/**
* The constant values.
*/
public static final List<String> values = Lists.newArrayList(NULL,NOT_NULL,NOT_EMPTY,EMAIL,NOT_BLANK);
/**
* Get validations list.
*
* @param declaredField the declared field
* @return the list
*/
public static List<String> getValidations(ResolvedFieldDeclaration declaredField){
List<String> result = new ArrayList<>();
if(declaredField instanceof JavaParserFieldDeclaration){
......
......@@ -11,7 +11,10 @@ import com.github.fengyuchenglun.apidoc.core.common.helper.OptionalHelper;
/**
* The type Visitor parser.
* 访问解析.
* 整个程序的驱动器
*
* @author duanledexianxianxian
*/
public class VisitorParser extends VoidVisitorAdapter<Node> {
......@@ -29,35 +32,13 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
this.parserStrategy = parserStrategy;
}
@Override
public void visit(final EnumDeclaration enumDeclaration, final Node arg) {
// 访问枚举
if (arg instanceof Project) {
// Project project = (Project) arg;
// // 章节
// Chapter chapter = new Chapter();
// enumDeclaration.getFullyQualifiedName().ifPresent(chapter::setId);
// chapter.setName(enumDeclaration.getNameAsString());
// enumDeclaration.getComment().ifPresent(chapter::accept);
// OptionalHelper.any(chapter.getTag("book"), chapter.getTag("group"))
// .ifPresent(tag -> chapter.setBookName(tag.getContent()));
// project.addChapter(chapter);
//放入附录
if (enumDeclaration.getJavadocComment().isPresent()) {
Appendix appendix = Appendix.parse(enumDeclaration.getJavadocComment().get());
ApiDoc.getInstance().getProject().getAppendices().add(appendix);
}
// super.visit(enumDeclaration, chapter);
}
}
/**
* 类或者接口声明
*
* @param classOrInterfaceDeclaration
* @param arg
* @param classOrInterfaceDeclaration 类或者接口
* @param arg 参数
*/
@Override
public void visit(final ClassOrInterfaceDeclaration classOrInterfaceDeclaration, final Node arg) {
......@@ -80,7 +61,39 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
}
}
/**
* 枚举
* @param enumDeclaration 枚举
* @param arg 参数
*/
@Override
public void visit(final EnumDeclaration enumDeclaration, final Node arg) {
// 访问枚举
if (arg instanceof Project) {
// Project project = (Project) arg;
// // 章节
// Chapter chapter = new Chapter();
// enumDeclaration.getFullyQualifiedName().ifPresent(chapter::setId);
// chapter.setName(enumDeclaration.getNameAsString());
// enumDeclaration.getComment().ifPresent(chapter::accept);
// OptionalHelper.any(chapter.getTag("book"), chapter.getTag("group"))
// .ifPresent(tag -> chapter.setBookName(tag.getContent()));
// project.addChapter(chapter);
//放入附录
if (enumDeclaration.getJavadocComment().isPresent()) {
Appendix appendix = Appendix.parse(enumDeclaration.getJavadocComment().get());
ApiDoc.getInstance().getProject().getAppendices().add(appendix);
}
// super.visit(enumDeclaration, chapter);
}
}
/**
* 注释
* @param javadocComment 注释
* @param arg 参数
*/
@Override
public void visit(JavadocComment javadocComment, Node arg) {
if (arg instanceof Chapter) {
......@@ -105,7 +118,7 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
// 常量类||枚举类
if (commentedNode instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) commentedNode;
ApiDoc.getInstance().getProject().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
ApiDoc.getInstance().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
}
}
});
......@@ -116,8 +129,8 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
/**
* 方法声明
*
* @param methodDeclaration
* @param arg
* @param methodDeclaration 方法
* @param arg 参数
*/
@Override
public void visit(final MethodDeclaration methodDeclaration, final Node arg) {
......
package com.github.fengyuchenglun.apidoc.core.render;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.fengyuchenglun.apidoc.core.ApiDoc;
import com.github.fengyuchenglun.apidoc.core.common.ObjectMappers;
import com.github.fengyuchenglun.apidoc.core.common.helper.FileHelper;
import com.github.fengyuchenglun.apidoc.core.common.postman.*;
import com.github.fengyuchenglun.apidoc.core.schema.*;
import lombok.extern.slf4j.Slf4j;
import java.nio.file.Path;
/**
* Postman v2.1 json文件构建
*/
@Slf4j
public class PostmanRenderV2 implements ProjectRender {
@Override
public void render(Project project) {
Postman postman = build(project);
String id = ApiDoc.getInstance().getContext().getId();
Path buildPath = ApiDoc.getInstance().getContext().getBuildPath();
Path file = buildPath.resolve(id).resolve("postman_v2_1.json");
FileHelper.write(file, ObjectMappers.pretty(postman));
log.info("Build Postman {}", file);
}
private Postman build(Project project) {
Postman postman = new Postman();
Info info = new Info();
info.set_postman_id(project.getId());
info.setName(project.getName());
info.setDescription(project.getDescription());
postman.setInfo(info);
for (Book book : project.getBooks().values()) {
Folder folder = new Folder();
folder.setName(book.getId());
for (Chapter chapter : book.getChapters()) {
if (chapter.isIgnore() || chapter.getSections().isEmpty()) {
continue;
}
Folder chapterFolder = new Folder();
chapterFolder.setName(chapter.getName());
chapterFolder.setDescription(chapter.getDescription());
for (Section section : chapter.getSections()) {
if (section.isIgnore()) {
continue;
}
chapterFolder.getItem().add(build(section));
}
folder.getItem().add(chapterFolder);
}
postman.getItem().add(folder);
}
if (postman.getItem().size() == 1) {
Folder folder = postman.getItem().get(0);
postman.setItem(folder.getItem());
}
return postman;
}
private Item build(Section section) {
Item item = new Item();
item.setName(section.getName());
item.setDescription(section.getDescription());
Request request = new Request();
request.setDescription(section.getDescription());
request.getUrl().setPath(section.getUri());
request.setMethod(section.getMethod());
request.getHeaders().addAll(section.getInHeaders().values());
ObjectNode objectNode = (ObjectNode) section.getQueryParameters();
for (String key : section.getRequestRows().keySet()) {
if (objectNode.has(key)) {
Row row = section.getRequestRows().get(key);
request.getUrl().getQuery().add(Parameter.of(row));
}
}
if (section.isQueryParameter()) {
// get请求
if (!Method.GET.equals(request.getMethod())) {
request.getBody().setMode(BodyMode.urlencoded);
objectNode = (ObjectNode) section.getRequestBodyParameters();
for (String key : section.getRequestRows().keySet()) {
if (objectNode.has(key)) {
Row row = section.getRequestRows().get(key);
request.getBody().getUrlencoded().add(Parameter.of(row));
}
}
}
} else {
request.getBody().setMode(BodyMode.raw);
request.getBody().setRaw(section.getRequestBodyParameterString());
}
item.setRequest(request);
Response response = new Response();
response.setName("success");
response.setOriginalRequest(request);
response.getHeaders().addAll(section.getOutHeaders().values());
response.setBody(section.getResponseString());
response.setCode(200);
response.setStatus("OK");
item.getResponse().add(response);
return item;
}
}
......@@ -5,6 +5,11 @@ import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.fengyuchenglun.apidoc.core.common.description.ArrayTypeDescription;
import com.github.javaparser.resolution.types.ResolvedType;
/**
* The type Array type resolver.
*
* @author duanledexianxianxian
*/
public class ArrayTypeResolver implements TypeResolver {
@Override
public boolean accept(ResolvedType type) {
......
package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.helper.*;
import com.github.fengyuchenglun.apidoc.core.schema.Tag;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.javadoc.Javadoc;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.resolution.types.ResolvedReferenceType;
import com.github.javaparser.resolution.types.ResolvedType;
......@@ -8,6 +11,7 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse
import com.github.fengyuchenglun.apidoc.core.ApiDoc;
import com.github.fengyuchenglun.apidoc.core.common.description.ObjectTypeDescription;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional;
......@@ -67,13 +71,14 @@ public class ObjectTypeResolver implements TypeResolver {
//查找json别名
JsonPropertyHelper.getJsonName(declaredField).ifPresent(fieldDescription::setKey);
//解析注释
fieldDescription.addRemark(CommentHelper.getComment(declaredField));
String comment = CommentHelper.getComment(declaredField);
fieldDescription.addRemark(comment);
//查找Validation注解
for (String validation : ValidationHelper.getValidations(declaredField)) {
fieldDescription.getCondition().append(validation).append(" ");
}
//查找字段初始化值
FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr)));
setDefault(declaredField, fieldDescription);
typeDescription.add(fieldDescription);
}
......@@ -82,4 +87,27 @@ public class ObjectTypeResolver implements TypeResolver {
return typeDescription;
}
private void setDefault(ResolvedFieldDeclaration declaredField, TypeDescription fieldDescription) {
Optional<Comment> optional = CommentHelper.getOptionalComment(declaredField);
if (optional.isPresent()) {
Comment comment = optional.get();
if (comment.isJavadocComment()) {
Javadoc javadoc = comment.asJavadocComment().parse();
// 设置tag
javadoc.getBlockTags().forEach(blockTag -> {
Tag tag = new Tag();
tag.setId(blockTag.getTagName());
tag.setKey(blockTag.getName().isPresent() ? blockTag.getName().get() : "");
tag.setContent(CommentHelper.getDescription(blockTag.getContent()));
fieldDescription.putTag(tag);
});
}
FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr)));
}
}
}
\ No newline at end of file
......@@ -5,7 +5,18 @@ import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.resolution.types.ResolvedType;
import com.google.common.collect.ImmutableList;
/**
* 原始类型解析.
*
* @author duanledexianxianxian
*/
public class PrimitiveTypeResolver implements TypeResolver {
/**
* 是否为包装类型.
*
* @param type the type
* @return the boolean
*/
private static boolean isBoxing(ResolvedType type) {
if (!type.isReferenceType()) {
return false;
......@@ -25,6 +36,7 @@ public class PrimitiveTypeResolver implements TypeResolver {
@Override
public boolean accept(ResolvedType type) {
// type.isPrimitive() javaparser
return type.isPrimitive() || isBoxing(type);
}
......
......@@ -3,10 +3,26 @@ package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.ast.type.Type;
/**
* 名称解析器.
* @author 名称解析器
*/
public interface TypeNameResolver {
/**
* Accept boolean.
*
* @param id the id
* @return the boolean
*/
boolean accept(String id);
/**
* Resolve type description.
*
* @param type the type
* @return the type description
*/
TypeDescription resolve(Type type);
}
......@@ -3,10 +3,27 @@ package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.resolution.types.ResolvedType;
/**
* 类型解析器.
*
* @author duanledexianxianxian
*/
public interface TypeResolver {
/**
* Accept boolean.
*
* @param type the type
* @return the boolean
*/
boolean accept(ResolvedType type);
/**
* Resolve type description.
*
* @param type the type
* @return the type description
*/
TypeDescription resolve(ResolvedType type);
}
......@@ -11,32 +11,53 @@ import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 类型解析器.
*
* @author duanledexianxian
*/
@Slf4j
public class TypeResolvers {
/**
* The Object type resolver.
*/
private ObjectTypeResolver objectTypeResolver = new ObjectTypeResolver();
/**
* 类型解析器
*/
private List<TypeResolver> resolvers = Lists.newArrayList(
// 基本类型+包装类型
new PrimitiveTypeResolver(),
// 数组
new ArrayTypeResolver(),
// 字符串
new StringTypeResolver(),
// 集合
new CollectionTypeResolver(),
// 时间日期
new DateTypeResolver(),
// Map
new MapTypeResolver(),
// 枚举
new EnumTypeResolver(),
// Object
new SystemObjectTypeResolver()
);
/**
* 名称解析器.
*/
private List<TypeNameResolver> nameResolvers = Lists.newArrayList();
/**
* 获取类型信息
* 1. 先进行类型解析
* 2. 再进行名称解析
*
* @param type
* @return
* @param type the type
* @return type description
*/
public TypeDescription resolve(Type type) {
try {
......@@ -54,8 +75,8 @@ public class TypeResolvers {
/**
* 解析类型信息
*
* @param type
* @return
* @param type the type
* @return type description
*/
public TypeDescription resolve(ResolvedType type) {
for (TypeResolver typeResolver : resolvers) {
......@@ -69,6 +90,12 @@ public class TypeResolvers {
return new UnAvailableTypeDescription();
}
/**
* Name resolve type description.
*
* @param type the type
* @return the type description
*/
public TypeDescription nameResolve(Type type) {
String id = TypeNameHelper.getName(type);
for (TypeNameResolver nameResolver : nameResolvers) {
......@@ -80,10 +107,20 @@ public class TypeResolvers {
return new UnAvailableTypeDescription();
}
/**
* Add resolver.
*
* @param typeResolver the type resolver
*/
public void addResolver(TypeResolver typeResolver) {
resolvers.add(typeResolver);
}
/**
* Add name resolver.
*
* @param nameResolver the name resolver
*/
public void addNameResolver(TypeNameResolver nameResolver) {
nameResolvers.add(nameResolver);
}
......
......@@ -17,6 +17,8 @@ import java.util.List;
/**
* 附录
*
* @author duanledexianxianxian
*/
@Data
@EqualsAndHashCode(callSuper=true)
......@@ -37,7 +39,6 @@ public class Appendix extends Node {
}
/**
* Parse appendix.
*
......
......@@ -19,7 +19,7 @@ import java.util.TreeSet;
public class Book extends Node {
/**
* The constant DEFAULT.
* book 默认名称.
*/
public static final String DEFAULT = "index";
......
......@@ -9,6 +9,7 @@ import java.util.List;
* 多个数据的组合
*
* @param <T> the type parameter
* @author duanledexianxianxian
*/
@Data
public class Cell<T> {
......@@ -29,8 +30,8 @@ public class Cell<T> {
* @param values the values
*/
@SafeVarargs
public Cell(T ... values) {
this(true,values);
public Cell(T... values) {
this(true, values);
}
/**
......@@ -40,7 +41,7 @@ public class Cell<T> {
* @param values the values
*/
@SafeVarargs
public Cell(boolean enable, T ... values) {
public Cell(boolean enable, T... values) {
this(enable, Lists.newArrayList(values));
}
......@@ -60,7 +61,7 @@ public class Cell<T> {
*
* @return the list
*/
public List<T> toList(){
public List<T> toList() {
return values;
}
......@@ -78,16 +79,27 @@ public class Cell<T> {
*
* @param value the value
*/
public void add(T value){
public void add(T value) {
values.add(value);
}
/**
* 指定位置插入元素.
*
* @param index the index
* @param value the value
*/
public void add(Integer index, T value) {
values.add(index, value);
}
/**
* Size int.
*
* @return the int
*/
public int size(){
public int size() {
return values.size();
}
......@@ -97,7 +109,7 @@ public class Cell<T> {
* @param index the index
* @param t the t
*/
public void set(int index, T t){
public void set(int index, T t) {
values.set(index, t);
}
......@@ -107,7 +119,7 @@ public class Cell<T> {
* @param index the index
* @return the t
*/
public T get(int index){
public T get(int index) {
return values.get(index);
}
......@@ -116,7 +128,7 @@ public class Cell<T> {
*
* @return the cell
*/
public Cell<T> duplicate(){
public Cell<T> duplicate() {
return new Cell<>(isEnable(), Lists.newArrayList(values));
}
......
......@@ -5,10 +5,12 @@ import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.javadoc.Javadoc;
import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper;
import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper;
import com.google.common.collect.Maps;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nonnull;
import java.util.HashMap;
......@@ -52,19 +54,23 @@ public class Node implements Comparable<Node> {
/**
* javadoc 中的tag
*/
Map<String, Tag> tags = new HashMap<>();
Map<String, Tag> tags = Maps.newHashMap();
@Override
public int compareTo(@Nonnull Node other) {
// 类型排序
if (this.type != null && other.type != null) {
return this.type.compareTo(other.type);
}
// 索引排序
if (this.index != other.index) {
return this.index - other.index;
}
// id排序
if (this.id != null && other.id != null) {
return this.id.compareTo(other.id);
}
// 名称排序
if (this.name != null && other.name != null) {
return this.name.compareTo(other.name);
}
......@@ -77,6 +83,7 @@ public class Node implements Comparable<Node> {
* @param comment the comment
*/
public void accept(Comment comment) {
// 不是javadoc注释
if (!comment.isJavadocComment()) {
setNameAndDescription(comment.getContent());
return;
......@@ -84,6 +91,7 @@ public class Node implements Comparable<Node> {
Javadoc javadoc = comment.asJavadocComment().parse();
setNameAndDescription(CommentHelper.getDescription(javadoc.getDescription()));
// 设置tag
javadoc.getBlockTags().forEach(blockTag -> {
Tag tag = new Tag();
tag.id = blockTag.getTagName();
......@@ -96,16 +104,16 @@ public class Node implements Comparable<Node> {
}
/**
* Sets name and description.
* 设置名称与描述.
*
* @param content the content
*/
public void setNameAndDescription(String content) {
String[] arr = content.split("(\\r\\n)|(\\r)|(\\n)+", 2);
if (arr.length >= 1 && StringHelper.nonBlank(arr[0])) {
if (arr.length >= 1 && StringUtils.isNotBlank(arr[0])) {
name = arr[0];
}
if (arr.length >= 2 && StringHelper.nonBlank(arr[1])) {
if (arr.length >= 2 && StringUtils.isNotBlank(arr[1])) {
description = arr[1];
}
}
......
......@@ -33,13 +33,9 @@ public class Project extends Node {
* 附录
*/
List<Appendix> appendices = new LinkedList<>();
/**
* 统一结果
*/
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration;
/**
* Add chapter.
* 添加章节.
*
* @param chapter the chapter
*/
......
package com.github.fengyuchenglun.apidoc.core.schema;
import com.github.fengyuchenglun.apidoc.core.common.convert.FieldTypeConvert;
import com.github.fengyuchenglun.apidoc.core.common.convert.IFieldTypeConvert;
import lombok.*;
import org.apache.commons.lang3.StringUtils;
/**
* The type Row.
......@@ -54,4 +57,35 @@ public class Row {
this.type = type;
}
/**
* 获取html文本样式
*
* @return html remark
*/
public String getHtmlRemark() {
if (StringUtils.isNotBlank(this.remark)) {
return this.remark.replaceAll("(\\r\\n)|(\\r)|(\\n)+", "<br>");
}
return this.remark;
}
/**
* Gets label type.
*
* @return the label type
*/
public String getLabelType() {
String javaType=this.type;
Boolean isArray=false;
if (StringUtils.endsWith(javaType,"[]")){
javaType=StringUtils.substringBefore(this.type,"[]");
isArray=true;
}
IFieldTypeConvert fieldTypeConvert=FieldTypeConvert.javaTypeOf(javaType);
if (null==fieldTypeConvert){
return this.type;
}
return isArray?fieldTypeConvert.getType()+"[]":fieldTypeConvert.getType();
}
}
......@@ -58,10 +58,10 @@ ${section.getRequestBodyParameterString()}
<#-- 请求参数table列表-->
<#if section.requestRows?? && (section.requestRows?size>0)>
| 字段 | 类型 | 参数类型 | 是否必填 | 验证 | 默认值 | 描述 |
| 字段 | 类型 | 参数类型 | 必填 | 验证 | 默认值 | 描述 |
| :------- | :----- | :----- |:-------- |:-------- | :------ | :---------- |
<#list section.requestRows as rowKey,rowValue>
| ${rowValue.key!''} | ${rowValue.type!''} | **${rowValue.parameterType!''}** |${rowValue.required?string('true','false')} | ${rowValue.condition!''} | ${rowValue.def!''} | ${rowValue.remark!''} |
| ${rowValue.key!''} | ${rowValue.getLabelType()!''} | **${rowValue.parameterType!''}** |${rowValue.required?string('true','false')} | ${rowValue.condition!''} | ${rowValue.def!''} | ${rowValue.getHtmlRemark()!''} |
</#list>
</#if>
<#-- 响应-->
......@@ -77,7 +77,7 @@ ${section.getResponseString()}
| 字段 | 类型 | 默认值 | 描述 |
| :------- | :----- |:----- | :---------- |
<#list section.responseRows as rowKey,rowValue>
| ${rowValue.key!''} | ${rowValue.type!''} | ${rowValue.def!''} | ${rowValue.remark!''} |
| ${rowValue.key!''} | ${rowValue.getLabelType()!''} | ${rowValue.def!''} | ${rowValue.getHtmlRemark()!''} |
</#list>
</#if>
</#if>
......@@ -90,6 +90,9 @@ ${section.getResponseString()}
<#------------ END 循环遍历book ---------->
</#if>
# 附录
<#if appendices??>
<#list appendices as appendfix>
......
......@@ -3,17 +3,50 @@ package com.github.fengyuchenglun.apidoc.springmvc;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.Parameter;
/**
* The type Parameter helper.
*/
public class ParameterHelper {
/**
* The constant ANNOTATION_REQUEST_PARAM.
*/
public static final String ANNOTATION_REQUEST_PARAM = "RequestParam";
/**
* The constant ANNOTATION_REQUEST_HEADER.
*/
public static final String ANNOTATION_REQUEST_HEADER = "RequestHeader";
/**
* The constant ANNOTATION_REQUEST_ATTRIBUTE.
*/
public static final String ANNOTATION_REQUEST_ATTRIBUTE = "RequestAttribute";
/**
* The constant ANNOTATION_REQUEST_PART.
*/
public static final String ANNOTATION_REQUEST_PART = "RequestPart";
/**
* The constant ANNOTATION_COOKIE_VALUE.
*/
public static final String ANNOTATION_COOKIE_VALUE = "CookieValue";
/**
* The constant ANNOTATION_PATH_VARIABLE.
*/
public static final String ANNOTATION_PATH_VARIABLE = "PathVariable";
/**
* The constant ANNOTATION_REQUEST_BODY.
*/
public static final String ANNOTATION_REQUEST_BODY = "RequestBody";
/**
* The constant ANNOTATION_MULTIPART_FILE.
*/
public static final String ANNOTATION_MULTIPART_FILE = "MultipartFile";
/**
* Has request body boolean.
*
* @param parameters the parameters
* @return the boolean
*/
public static boolean hasRequestBody(NodeList<Parameter> parameters) {
for (Parameter parameter : parameters) {
if (isRequestBody(parameter)) {
......@@ -23,6 +56,12 @@ public class ParameterHelper {
return false;
}
/**
* 是否是请求参数
*
* @param parameter the parameter
* @return boolean
*/
public static boolean isRequestParam(Parameter parameter) {
if (!parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE) &&
!parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY) &&
......@@ -36,6 +75,12 @@ public class ParameterHelper {
return false;
}
/**
* Is path variable boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isPathVariable(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE)) {
return true;
......@@ -43,6 +88,12 @@ public class ParameterHelper {
return false;
}
/**
* Is request body boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isRequestBody(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY)) {
return true;
......@@ -50,6 +101,12 @@ public class ParameterHelper {
return false;
}
/**
* Is request header boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isRequestHeader(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_HEADER)) {
return true;
......
......@@ -95,18 +95,23 @@ public class SpringParser implements ParserStrategy {
/**
* 解析方法定义
*
* @param n
* @param chapter
* @param section
* @param n 方法声明
* @param chapter 章
* @param section 节
*/
@Override
public void visit(MethodDeclaration n, Chapter chapter, Section section) {
// 解析方法
visitMethod(n, chapter, section);
// 解析url
visitUri(n, chapter, section);
// 解析路径参数
visitPathVariable(n, chapter, section);
// 解析头
visitHeaders(n, chapter, section);
// 解析请求参数
visitParameters(n, chapter, section);
// 解析返回结果
visitReturn(n, chapter, section);
}
......@@ -265,6 +270,7 @@ public class SpringParser implements ParserStrategy {
Object defaultValue = null;
Boolean required = null;
// 是否带有@RequestParam注解
Optional<AnnotationExpr> optional = parameter.getAnnotationByName(ParameterHelper.ANNOTATION_REQUEST_PARAM);
if (optional.isPresent()) {
// 如果有RequestParam注解,则参数必填
......@@ -313,7 +319,7 @@ public class SpringParser implements ParserStrategy {
* @param section the section
*/
private void visitReturn(MethodDeclaration n, Chapter chapter, Section section) {
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getProject().getResultDataClassOrInterfaceDeclaration();
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getResultDataClassOrInterfaceDeclaration();
if (null != resultDataClassOrInterfaceDeclaration) {
ClassOrInterfaceType returnType = new ClassOrInterfaceType();
returnType.setName(resultDataClassOrInterfaceDeclaration.getName());
......
......@@ -12,6 +12,11 @@ import com.github.javaparser.resolution.types.ResolvedType;
import java.util.Optional;
/**
* spring组件解析.
*
* @author duanledexianxianxian
*/
public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolver {
@Override
public boolean accept(ResolvedType type) {
......@@ -44,6 +49,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv
return new UnAvailableTypeDescription();
}
/**
* Is spring component boolean.
*
* @param type the type
* @return the boolean
*/
private static boolean isSpringComponent(ResolvedType type){
if(!type.isReferenceType()){
return false;
......@@ -51,6 +62,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv
return isSpringComponent(type.asReferenceType().getId());
}
/**
* Is spring component boolean.
*
* @param id the id
* @return the boolean
*/
private static boolean isSpringComponent(String id){
return id!=null && (id.startsWith("org.springframework"));
}
......
package com.github.fengyuchenglun.apidoc.springmvc;
import com.github.fengyuchenglun.apidoc.core.ApiDoc;
import com.github.fengyuchenglun.apidoc.core.Context;
import com.github.fengyuchenglun.apidoc.core.render.MarkdownRender;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import org.junit.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* ApiDoc单元测试
*
* @author duanledexianxianxian
*/
public class ApidocTest {
/**
* Get class path.
*/
@Test
public void getClassPath() {
System.out.println(this.getClass().getResource(""));
System.out.println(this.getClass().getResourceAsStream(""));
System.out.println(Paths.get("").toAbsolutePath());
}
@SneakyThrows
@Test
public void appTest() {
// 测试枚举
Context context = new Context();
context.setRenders(Lists.newArrayList(new MarkdownRender()));
context.addSource(Paths.get("").resolve("src/test/java").toAbsolutePath());
ApiDoc apiDoc = new ApiDoc(context);
apiDoc.parse();
apiDoc.render();
}
}
package com.github.fengyuchenglun.apidoc.springmvc.javaparser;
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
}
}
package com.github.fengyuchenglun.apidoc.springmvc.javaparser;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import lombok.SneakyThrows;
import org.junit.Test;
import java.io.FileInputStream;
public class MainTest {
String mainPath =
"F:\\@project@\\@dianli@\\tool\\apidoc\\apidoc-springmvc\\src\\test\\java\\com\\github\\fengyuchenglun\\apidoc\\springmvc\\javaparser\\Main.java";
@SneakyThrows
@Test
public void mainTest() {
FileInputStream in = new FileInputStream(mainPath);
CompilationUnit cu = StaticJavaParser.parse(in);
// visit and print the methods names
new MethodVisitor().visit(cu, null);
}
}
package com.github.fengyuchenglun.apidoc.springmvc.javaparser;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
public class MethodVisitor extends VoidVisitorAdapter {
@Override
public void visit(MethodDeclaration n, Object arg) {
// here you can access the attributes of the method.
// this method will be called for all methods in this
// CompilationUnit, including inner class methods
System.out.println(n.getName());
}
}
......@@ -11,6 +11,6 @@ public class Menu {
int id;
String name;
List<Menu> menus;
// List<Menu> menus;
}
......@@ -3,36 +3,57 @@ package com.github.fengyuchenglun.example.common;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.List;
/**
* The type Query.
*/
@Setter
@Getter
public class Query {
/**
* static will be ignore
*/
public static final String CONSTANS = "";
// /**
// * static will be ignore
// */
// public static final String CONSTANS = "";
//
// /**
// * 用户名称
// *
// * @mock 张三
// */
// @NotNull
// @Size(min = 20)
// private String userName;
// /**
// * 用户手机号码
// *
// * @mock 15173253855
// */
// @Size(min = 20)
// private String userPhoneNum;
// /**
// * 用户邮箱
// *
// * @mock fengyuchenglun@foxmail.com
// */
// private String userEmail;
// /**
// * 开始时间
// *
// * @mock 2020-07-25 01:00:00
// */
// private float startTime;
// /**
// * 结束时间
// * 2020-07-25 01:00:00
// */
// private LocalDateTime endTime;
/**
* 用户名称
*/
private String userName;
/**
* 用户手机号码
*/
private String userPhoneNum;
/**
* 用户邮箱
*/
private String userEmail;
/**
* 开始时间
*/
private LocalDateTime startTime;
/**
* 结束时间
*/
private LocalDateTime endTime;
private List<Menu> menuList;
}
package com.github.fengyuchenglun.example.common;
/**
* 静态常量
*
* @author duanledexianxianxian
* @code
*/
public class StaticFinalCode {
......
......@@ -22,20 +22,20 @@ import java.util.List;
@RequestMapping("/api/v1/users")
public class UserController {
//
// /**
// * 查看用户详情
// *
// * @param userId 用户编号
// * @param age 年龄
// * @param query 过滤条件
// * @return 用户对象 user
// */
// @PostMapping(value = "/{userId}")
// public User detail(@PathVariable String userId, String age, @RequestBody Query query) {
// User user = new User();
// return user;
// }
/**
* 查看用户详情
*
* @param userId 用户编号
* @param age 年龄
* @param query 过滤条件
* @return 用户对象 user
*/
@PostMapping(value = "/{userId}")
public User detail(@PathVariable String userId, String age, @RequestBody Query query) {
User user = new User();
return user;
}
//
// /**
// * 查看用户详情
......@@ -51,14 +51,15 @@ public class UserController {
// }
//
//
//
// /**
// * 测试get的query对象,带RequestParam注解
// *
// * @param query 过滤条件
// * @param query the query
// * @return 用户对象 user
// */
// @GetMapping(value = "/detail3")
// public User detail3(@RequestParam String query) {
// public User detail3(Query query) {
// User user = new User();
// return user;
// }
......
......@@ -19,7 +19,8 @@ allprojects {
dependencies {
compile 'ch.qos.logback:logback-classic:1.2.3'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.10'
compileOnly 'org.projectlombok:lombok:1.18.4'
compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.4'
compileOnly 'org.projectlombok:lombok:1.18.6'
annotationProcessor 'org.projectlombok:lombok:1.18.6'
testCompileOnly 'org.projectlombok:lombok:1.18.4'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment