Commit 8e6f9c27 authored by duanledexianxianxian's avatar duanledexianxianxian 😁

代码重构

parent 2e4958b6
...@@ -4,4 +4,6 @@ dependencies { ...@@ -4,4 +4,6 @@ dependencies {
compile 'org.asciidoctor:asciidoctorj:2.1.0' compile 'org.asciidoctor:asciidoctorj:2.1.0'
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30' compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
compile group: 'com.google.guava', name: 'guava', version: '23.0' 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; ...@@ -9,6 +9,7 @@ import com.github.fengyuchenglun.apidoc.core.schema.Project;
import com.github.javaparser.ParseResult; import com.github.javaparser.ParseResult;
import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
...@@ -17,7 +18,9 @@ import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeS ...@@ -17,7 +18,9 @@ import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeS
import com.github.javaparser.utils.SourceRoot; import com.github.javaparser.utils.SourceRoot;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
...@@ -26,7 +29,7 @@ import java.util.Objects; ...@@ -26,7 +29,7 @@ import java.util.Objects;
import java.util.ServiceLoader; import java.util.ServiceLoader;
/** /**
* The type ApiDoc. * apidoc配置类.
* *
* @author fengyuchenglun * @author fengyuchenglun
* @version 1.0.0 * @version 1.0.0
...@@ -34,10 +37,6 @@ import java.util.ServiceLoader; ...@@ -34,10 +37,6 @@ import java.util.ServiceLoader;
@Slf4j @Slf4j
public class ApiDoc { public class ApiDoc {
/**
* ApiDoc实例
*/
private static ApiDoc INSTANCE;
/** /**
* 上下文 * 上下文
*/ */
...@@ -56,6 +55,14 @@ public class ApiDoc { ...@@ -56,6 +55,14 @@ public class ApiDoc {
* The Parser configuration. * The Parser configuration.
*/ */
private ParserConfiguration parserConfiguration; private ParserConfiguration parserConfiguration;
/**
* 统一结果
*/
@Setter
@Getter
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration;
/** /**
* The Type resolvers. * The Type resolvers.
*/ */
...@@ -84,26 +91,40 @@ public class ApiDoc { ...@@ -84,26 +91,40 @@ public class ApiDoc {
* @return the api doc * @return the api doc
*/ */
public static ApiDoc getInstance() { 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 * @param context the context
*/ */
private void init(Context context) { private void init(Context context) {
INSTANCE = this; // 保存自身实例
ApiDocInstance.INSTANCE = this;
this.context = context; this.context = context;
// 初始化项目
project.setId(context.getId()); project.setId(context.getId());
project.setName(context.getName()); project.setName(context.getName());
project.setDescription(context.getDescription()); project.setDescription(context.getDescription());
project.setVersion(context.getVersion()); project.setVersion(context.getVersion());
// dependencies设置typeSolver
CombinedTypeSolver typeSolver = new CombinedTypeSolver(); CombinedTypeSolver typeSolver = new CombinedTypeSolver();
for (Path dependency : context.getDependencies()) { for (Path dependency : context.getDependencies()) {
typeSolver.add(new JavaParserTypeSolver(dependency)); typeSolver.add(new JavaParserTypeSolver(dependency));
} }
// jars设置typeSolver
for (Path jar : context.getJars()) { for (Path jar : context.getJars()) {
try { try {
typeSolver.add(new JarTypeSolver(jar)); typeSolver.add(new JarTypeSolver(jar));
...@@ -111,11 +132,13 @@ public class ApiDoc { ...@@ -111,11 +132,13 @@ public class ApiDoc {
log.warn("exception on {} {}", jar, e.getMessage()); log.warn("exception on {} {}", jar, e.getMessage());
} }
} }
// 反射?
typeSolver.add(new ReflectionTypeSolver()); typeSolver.add(new ReflectionTypeSolver());
parserConfiguration = new ParserConfiguration(); parserConfiguration = new ParserConfiguration();
parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver)); parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
// 加载策略
ParserStrategy strategy = loadParserStrategy(); ParserStrategy strategy = loadParserStrategy();
strategy.onLoad(); strategy.onLoad();
visitorParser.setParserStrategy(strategy); visitorParser.setParserStrategy(strategy);
...@@ -135,7 +158,8 @@ public class ApiDoc { ...@@ -135,7 +158,8 @@ public class ApiDoc {
if (strategies.isEmpty()) { if (strategies.isEmpty()) {
throw new IllegalArgumentException("no ParserStrategy implements found"); throw new IllegalArgumentException("no ParserStrategy implements found");
} }
if (StringHelper.isBlank(context.getFramework())) { // 用户未配置context的framework
if (StringUtils.isBlank(context.getFramework())) {
return strategies.get(0); return strategies.get(0);
} }
for (ParserStrategy strategy : strategies) { for (ParserStrategy strategy : strategies) {
...@@ -147,7 +171,7 @@ public class ApiDoc { ...@@ -147,7 +171,7 @@ public class ApiDoc {
} }
/** /**
* 解析源代码 * 1. 解析源代码
* *
* @return project project * @return project project
*/ */
...@@ -157,6 +181,7 @@ public class ApiDoc { ...@@ -157,6 +181,7 @@ public class ApiDoc {
try { try {
for (ParseResult<CompilationUnit> result : root.tryToParse()) { for (ParseResult<CompilationUnit> result : root.tryToParse()) {
if (result.isSuccessful() && result.getResult().isPresent()) { if (result.isSuccessful() && result.getResult().isPresent()) {
//note: 访问解析器 +当前项目上下文
result.getResult().get().accept(visitorParser, project); result.getResult().get().accept(visitorParser, project);
} }
} }
...@@ -168,7 +193,7 @@ public class ApiDoc { ...@@ -168,7 +193,7 @@ public class ApiDoc {
} }
/** /**
* 渲染解析结果 * 2. 渲染解析结果
*/ */
public void render() { public void render() {
for (ProjectRender render : this.context.getRenders()) { for (ProjectRender render : this.context.getRenders()) {
......
...@@ -17,7 +17,8 @@ import java.util.List; ...@@ -17,7 +17,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* The type Context. * 上下文.
* 用户可自定义配置参数
* *
* @author fengyuchenglun * @author fengyuchenglun
* @version 1.0.0 * @version 1.0.0
...@@ -42,6 +43,8 @@ public class Context { ...@@ -42,6 +43,8 @@ public class Context {
*/ */
public static final String DEFAULT_CODE_STRUCTURE = "src/main/java"; public static final String DEFAULT_CODE_STRUCTURE = "src/main/java";
/** /**
* 设置当前解析框架 * 设置当前解析框架
*/ */
...@@ -118,7 +121,7 @@ public class Context { ...@@ -118,7 +121,7 @@ public class Context {
private Map<String, Object> ext = Maps.newHashMap(); private Map<String, Object> ext = Maps.newHashMap();
/** /**
* Add source. * 添加源码.
* *
* @param path the path * @param path the path
*/ */
...@@ -129,7 +132,9 @@ public class Context { ...@@ -129,7 +132,9 @@ public class Context {
} }
/** /**
* Add dependency. * 添加依赖.
* 文件路径:例如
* /url/api-doc/
* *
* @param path the path * @param path the path
*/ */
...@@ -139,7 +144,7 @@ public class Context { ...@@ -139,7 +144,7 @@ public class Context {
} }
/** /**
* Add jar. * 添加jar.
* *
* @param path the path * @param path the path
*/ */
......
...@@ -11,9 +11,25 @@ import java.nio.charset.StandardCharsets; ...@@ -11,9 +11,25 @@ import java.nio.charset.StandardCharsets;
* @since 1.0.0 * @since 1.0.0
*/ */
public class Constants { public class Constants {
/**
* The constant UTF8.
*/
public static final String UTF8 = StandardCharsets.UTF_8.name(); public static final String UTF8 = StandardCharsets.UTF_8.name();
/**
* The constant SLASH.
*/
public static final String SLASH = "/"; public static final String SLASH = "/";
/**
* The constant MARKDOWN_EXTENSION.
*/
public static final String MARKDOWN_EXTENSION = ".md"; public static final String MARKDOWN_EXTENSION = ".md";
/**
* markdown模版文件默认路径
*/
public static final String MARKDOWN_TEMPLATE = "/templates/markdown.ftl"; 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; package com.github.fengyuchenglun.apidoc.core.common.description;
import com.github.fengyuchenglun.apidoc.core.common.ObjectMappers; 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.github.fengyuchenglun.apidoc.core.schema.Row;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import lombok.Data; import lombok.Data;
...@@ -11,14 +12,27 @@ import java.util.Collection; ...@@ -11,14 +12,27 @@ import java.util.Collection;
/** /**
* 数组类型描述 * 数组类型描述
*
* @author duanledexianxianxian
*/ */
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
public class ArrayTypeDescription extends TypeDescription { public class ArrayTypeDescription extends TypeDescription {
/**
* The Value.
*/
protected ArrayNode value; protected ArrayNode value;
/**
* The Component.
*/
protected TypeDescription component; protected TypeDescription component;
/**
* Instantiates a new Array type description.
*
* @param component the component
*/
public ArrayTypeDescription(TypeDescription component) { public ArrayTypeDescription(TypeDescription component) {
this.component = component; this.component = component;
this.value = ObjectMappers.instance.createArrayNode(); this.value = ObjectMappers.instance.createArrayNode();
...@@ -38,6 +52,11 @@ public class ArrayTypeDescription extends TypeDescription { ...@@ -38,6 +52,11 @@ public class ArrayTypeDescription extends TypeDescription {
} }
} }
/**
* Primitive.
*
* @param typeDescription the type description
*/
public void primitive(PrimitiveTypeDescription typeDescription) { public void primitive(PrimitiveTypeDescription typeDescription) {
switch (typeDescription.getType()) { switch (typeDescription.getType()) {
case "byte": case "byte":
...@@ -83,20 +102,31 @@ public class ArrayTypeDescription extends TypeDescription { ...@@ -83,20 +102,31 @@ public class ArrayTypeDescription extends TypeDescription {
} }
} }
@Override
public String fullKey() {
return StringHelper.join("[].", prefix, key);
}
@Override @Override
public ArrayNode getValue() { public ArrayNode getValue() {
return value; return value;
} }
@Override @Override
public Collection<Row> rows() { public Collection<Row> rows(String parameterType) {
ArrayList<Row> rows = new ArrayList<>(); ArrayList<Row> rows = new ArrayList<>();
if (key != null) { if (key != null) {
rows.addAll(super.rows()); rows.addAll(super.rows(parameterType));
} }
if (component.isAvailable()) { if (component.isAvailable()) {
rows.addAll(component.rows()); rows.addAll(component.rows(parameterType));
} }
return rows; return rows;
} }
@Override
public Collection<Row> rows() {
return rows(null);
}
} }
package com.github.fengyuchenglun.apidoc.core.common.description; 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.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.common.helper.StringHelper;
import com.github.fengyuchenglun.apidoc.core.schema.Row; 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.ast.comments.Comment;
import com.github.javaparser.javadoc.Javadoc; import com.github.javaparser.javadoc.Javadoc;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
...@@ -10,11 +13,17 @@ import lombok.Data; ...@@ -10,11 +13,17 @@ import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection; 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 * @author duanledexianxianxian
*/ */
...@@ -22,21 +31,30 @@ import java.util.Collection; ...@@ -22,21 +31,30 @@ import java.util.Collection;
public abstract class TypeDescription { public abstract class TypeDescription {
/** /**
* The Prefix. * 前缀.
*/ */
protected String prefix = ""; protected String prefix = "";
/** /**
* The Key. * key.
*/ */
protected String key = ""; protected String key = "";
/** /**
* The Type. * 类型.
*/ */
protected String type; protected String type;
/** /**
* The Condition. * 条件.
*/ */
protected StringBuilder condition = new StringBuilder(); protected StringBuilder condition = new StringBuilder();
/**
* 名称
*/
String name;
/**
* 描述
*/
String description;
/** /**
* 说明. * 说明.
*/ */
...@@ -50,6 +68,11 @@ public abstract class TypeDescription { ...@@ -50,6 +68,11 @@ public abstract class TypeDescription {
*/ */
protected Object defaultValue; protected Object defaultValue;
/**
* javadoc 中的tag
*/
Map<String, Tag> tags = new HashMap<>();
/** /**
* 是否必填. * 是否必填.
*/ */
...@@ -161,6 +184,7 @@ public abstract class TypeDescription { ...@@ -161,6 +184,7 @@ public abstract class TypeDescription {
} }
} }
/** /**
* Full key string. * Full key string.
* *
...@@ -173,6 +197,7 @@ public abstract class TypeDescription { ...@@ -173,6 +197,7 @@ public abstract class TypeDescription {
/** /**
* Rows collection. * Rows collection.
* *
* @param parameterType the parameter type
* @return the collection * @return the collection
*/ */
public Collection<Row> rows(String parameterType) { public Collection<Row> rows(String parameterType) {
...@@ -181,7 +206,9 @@ public abstract class TypeDescription { ...@@ -181,7 +206,9 @@ public abstract class TypeDescription {
return Lists.newArrayList(); return Lists.newArrayList();
} }
String def; 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); def = String.valueOf(defaultValue);
} else if (value != null) { } else if (value != null) {
def = String.valueOf(value); def = String.valueOf(value);
...@@ -206,13 +233,36 @@ public abstract class TypeDescription { ...@@ -206,13 +233,36 @@ public abstract class TypeDescription {
return this.rows(null); return this.rows(null);
} }
/**
* Accept.
*
* @param comment the comment
*/
public void accept(Comment comment) { public void accept(Comment comment) {
String content;
if (!comment.isJavadocComment()) { if (!comment.isJavadocComment()) {
setRemark(comment.getContent()); content = comment.getContent();
setRemark(content);
return; return;
} }
Javadoc javadoc = comment.asJavadocComment().parse(); 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 { ...@@ -29,6 +29,7 @@ public class CommentHelper {
public static String getDescription(JavadocDescription description) { public static String getDescription(JavadocDescription description) {
return description.getElements() return description.getElements()
.stream() .stream()
// 过滤非单行注释
.filter(e -> !(e instanceof JavadocInlineTag)) .filter(e -> !(e instanceof JavadocInlineTag))
.map(JavadocDescriptionElement::toText).collect(Collectors.joining()); .map(JavadocDescriptionElement::toText).collect(Collectors.joining());
} }
...@@ -65,7 +66,7 @@ public class CommentHelper { ...@@ -65,7 +66,7 @@ public class CommentHelper {
} }
/** /**
* Get comment string. * 获取字段注释.
* *
* @param it the it * @param it the it
* @return the string * @return the string
...@@ -84,4 +85,14 @@ public class CommentHelper { ...@@ -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; ...@@ -6,12 +6,17 @@ import com.github.javaparser.ast.body.EnumDeclaration;
import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration; import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration; 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.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* The type Enum helper. * The type Enum helper.
*
* @author duanledexianxianxian
*/ */
public class EnumHelper { public class EnumHelper {
...@@ -21,10 +26,10 @@ public class EnumHelper { ...@@ -21,10 +26,10 @@ public class EnumHelper {
* @param enumDeclaration the enum declaration * @param enumDeclaration the enum declaration
* @return the string * @return the string
*/ */
public static String getNames(ResolvedEnumDeclaration enumDeclaration){ public static String getNames(ResolvedEnumDeclaration enumDeclaration) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (ResolvedEnumConstantDeclaration resolvedEnumConstantDeclaration : enumDeclaration.getEnumConstants()) { for (ResolvedEnumConstantDeclaration resolvedEnumConstantDeclaration : enumDeclaration.getEnumConstants()) {
if(sb.length()>0){ if (sb.length() > 0) {
sb.append(","); sb.append(",");
} }
sb.append(resolvedEnumConstantDeclaration.getName()); sb.append(resolvedEnumConstantDeclaration.getName());
...@@ -38,8 +43,8 @@ public class EnumHelper { ...@@ -38,8 +43,8 @@ public class EnumHelper {
* @param declaration the declaration * @param declaration the declaration
* @return the list * @return the list
*/ */
public static List<Cell<String>> toDetails(EnumDeclaration declaration){ public static List<Cell<String>> toDetails(EnumDeclaration declaration) {
List<Cell<String>> cells = new ArrayList<>(); List<Cell<String>> cells = Lists.newArrayList();
for (EnumConstantDeclaration constant : declaration.getEntries()) { for (EnumConstantDeclaration constant : declaration.getEntries()) {
Cell<String> cell = new Cell<>(); Cell<String> cell = new Cell<>();
cell.add(constant.getNameAsString()); cell.add(constant.getNameAsString());
...@@ -47,6 +52,9 @@ public class EnumHelper { ...@@ -47,6 +52,9 @@ public class EnumHelper {
Object value = ExpressionHelper.getValue(expression); Object value = ExpressionHelper.getValue(expression);
cell.add(String.valueOf(value)); cell.add(String.valueOf(value));
} }
if (cell.size() == 2) {
cell.add(1, cell.get(0));
}
cells.add(cell); cells.add(cell);
} }
return cells; return cells;
......
...@@ -11,14 +11,20 @@ import java.util.List; ...@@ -11,14 +11,20 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* 表达式帮助类.
*
* @author duanledexianxianxian
*/
@Slf4j @Slf4j
public class ExpressionHelper { public class ExpressionHelper {
/** /**
* 解析表达式,获取表达式的值 * 解析表达式,获取表达式的值
* TODO 更复杂的表达式解析 * TODO 更复杂的表达式解析
* @param expr *
* @return * @param expr the expr
* @return value value
*/ */
public static Object getValue(Expression expr) { public static Object getValue(Expression expr) {
if (expr.isStringLiteralExpr()) { if (expr.isStringLiteralExpr()) {
...@@ -45,6 +51,12 @@ public class ExpressionHelper { ...@@ -45,6 +51,12 @@ public class ExpressionHelper {
return expr.toString(); return expr.toString();
} }
/**
* Get string value string.
*
* @param expression the expression
* @return the string
*/
public static String getStringValue(Expression expression){ public static String getStringValue(Expression expression){
if(expression.isStringLiteralExpr()){ if(expression.isStringLiteralExpr()){
return expression.asStringLiteralExpr().getValue(); return expression.asStringLiteralExpr().getValue();
...@@ -59,6 +71,12 @@ public class ExpressionHelper { ...@@ -59,6 +71,12 @@ public class ExpressionHelper {
return expression.toString(); return expression.toString();
} }
/**
* Get string values list.
*
* @param expression the expression
* @return the list
*/
public static List<String> getStringValues(Expression expression){ public static List<String> getStringValues(Expression expression){
List<String> results = new ArrayList<>(); List<String> results = new ArrayList<>();
if(expression.isStringLiteralExpr()){ if(expression.isStringLiteralExpr()){
...@@ -76,6 +94,12 @@ public class ExpressionHelper { ...@@ -76,6 +94,12 @@ public class ExpressionHelper {
return results; return results;
} }
/**
* Resolve object.
*
* @param resolvable the resolvable
* @return the object
*/
private static Object resolve(Resolvable resolvable){ private static Object resolve(Resolvable resolvable){
try { try {
Object resolve = resolvable.resolve(); Object resolve = resolvable.resolve();
......
...@@ -2,8 +2,20 @@ package com.github.fengyuchenglun.apidoc.core.common.helper; ...@@ -2,8 +2,20 @@ package com.github.fengyuchenglun.apidoc.core.common.helper;
import java.util.Optional; import java.util.Optional;
/**
* optional帮助类
*
* @author duanledexianxianxian
*/
public class OptionalHelper { public class OptionalHelper {
/**
* Any optional.
*
* @param <T> the type parameter
* @param optionals the optionals
* @return the optional
*/
@SafeVarargs @SafeVarargs
public static <T> Optional<T> any(Optional<T>... optionals) { public static <T> Optional<T> any(Optional<T>... optionals) {
for (Optional<T> optional : optionals) { for (Optional<T> optional : optionals) {
......
...@@ -10,22 +10,66 @@ import java.util.ArrayList; ...@@ -10,22 +10,66 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/**
* JavaBean 验证器帮助类
*
* @author duanledexianxianxian
*/
public class ValidationHelper { public class ValidationHelper {
/**
* The constant NULL.
*/
public static final String NULL = "Null"; public static final String NULL = "Null";
/**
* The constant NOT_NULL.
*/
public static final String NOT_NULL = "NotNull"; public static final String NOT_NULL = "NotNull";
/**
* The constant ASSERT_TRUE.
*/
public static final String ASSERT_TRUE = "AssertTrue"; public static final String ASSERT_TRUE = "AssertTrue";
/**
* The constant ASSERT_FALSE.
*/
public static final String ASSERT_FALSE = "AssertFalse"; public static final String ASSERT_FALSE = "AssertFalse";
/**
* The constant NOT_EMPTY.
*/
public static final String NOT_EMPTY = "NotEmpty"; public static final String NOT_EMPTY = "NotEmpty";
/**
* The constant NOT_BLANK.
*/
public static final String NOT_BLANK = "NotBlank"; public static final String NOT_BLANK = "NotBlank";
/**
* The constant EMAIL.
*/
public static final String EMAIL = "Email"; public static final String EMAIL = "Email";
/**
* The constant MIN.
*/
public static final String MIN = "Min"; public static final String MIN = "Min";
/**
* The constant MAX.
*/
public static final String MAX = "Max"; public static final String MAX = "Max";
/**
* The constant SIZE.
*/
public static final String SIZE = "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); 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){ public static List<String> getValidations(ResolvedFieldDeclaration declaredField){
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
if(declaredField instanceof JavaParserFieldDeclaration){ if(declaredField instanceof JavaParserFieldDeclaration){
......
...@@ -11,7 +11,10 @@ import com.github.fengyuchenglun.apidoc.core.common.helper.OptionalHelper; ...@@ -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> { public class VisitorParser extends VoidVisitorAdapter<Node> {
...@@ -29,35 +32,13 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -29,35 +32,13 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
this.parserStrategy = parserStrategy; 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 classOrInterfaceDeclaration 类或者接口
* @param arg * @param arg 参数
*/ */
@Override @Override
public void visit(final ClassOrInterfaceDeclaration classOrInterfaceDeclaration, final Node arg) { public void visit(final ClassOrInterfaceDeclaration classOrInterfaceDeclaration, final Node arg) {
...@@ -80,7 +61,39 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -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 @Override
public void visit(JavadocComment javadocComment, Node arg) { public void visit(JavadocComment javadocComment, Node arg) {
if (arg instanceof Chapter) { if (arg instanceof Chapter) {
...@@ -105,7 +118,7 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -105,7 +118,7 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
// 常量类||枚举类 // 常量类||枚举类
if (commentedNode instanceof ClassOrInterfaceDeclaration) { if (commentedNode instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) commentedNode; ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) commentedNode;
ApiDoc.getInstance().getProject().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration); ApiDoc.getInstance().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
} }
} }
}); });
...@@ -116,8 +129,8 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -116,8 +129,8 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
/** /**
* 方法声明 * 方法声明
* *
* @param methodDeclaration * @param methodDeclaration 方法
* @param arg * @param arg 参数
*/ */
@Override @Override
public void visit(final MethodDeclaration methodDeclaration, final Node arg) { 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; ...@@ -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.fengyuchenglun.apidoc.core.common.description.ArrayTypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
/**
* The type Array type resolver.
*
* @author duanledexianxianxian
*/
public class ArrayTypeResolver implements TypeResolver { public class ArrayTypeResolver implements TypeResolver {
@Override @Override
public boolean accept(ResolvedType type) { public boolean accept(ResolvedType type) {
......
package com.github.fengyuchenglun.apidoc.core.resolver; package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.helper.*; 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.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedReferenceType;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
...@@ -8,6 +11,7 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse ...@@ -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.ApiDoc;
import com.github.fengyuchenglun.apidoc.core.common.description.ObjectTypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.ObjectTypeDescription;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional; import java.util.Optional;
...@@ -67,13 +71,14 @@ public class ObjectTypeResolver implements TypeResolver { ...@@ -67,13 +71,14 @@ public class ObjectTypeResolver implements TypeResolver {
//查找json别名 //查找json别名
JsonPropertyHelper.getJsonName(declaredField).ifPresent(fieldDescription::setKey); JsonPropertyHelper.getJsonName(declaredField).ifPresent(fieldDescription::setKey);
//解析注释 //解析注释
fieldDescription.addRemark(CommentHelper.getComment(declaredField)); String comment = CommentHelper.getComment(declaredField);
fieldDescription.addRemark(comment);
//查找Validation注解 //查找Validation注解
for (String validation : ValidationHelper.getValidations(declaredField)) { for (String validation : ValidationHelper.getValidations(declaredField)) {
fieldDescription.getCondition().append(validation).append(" "); fieldDescription.getCondition().append(validation).append(" ");
} }
//查找字段初始化值 //查找字段初始化值
FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr))); setDefault(declaredField, fieldDescription);
typeDescription.add(fieldDescription); typeDescription.add(fieldDescription);
} }
...@@ -82,4 +87,27 @@ public class ObjectTypeResolver implements TypeResolver { ...@@ -82,4 +87,27 @@ public class ObjectTypeResolver implements TypeResolver {
return typeDescription; 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; ...@@ -5,7 +5,18 @@ import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
/**
* 原始类型解析.
*
* @author duanledexianxianxian
*/
public class PrimitiveTypeResolver implements TypeResolver { public class PrimitiveTypeResolver implements TypeResolver {
/**
* 是否为包装类型.
*
* @param type the type
* @return the boolean
*/
private static boolean isBoxing(ResolvedType type) { private static boolean isBoxing(ResolvedType type) {
if (!type.isReferenceType()) { if (!type.isReferenceType()) {
return false; return false;
...@@ -25,6 +36,7 @@ public class PrimitiveTypeResolver implements TypeResolver { ...@@ -25,6 +36,7 @@ public class PrimitiveTypeResolver implements TypeResolver {
@Override @Override
public boolean accept(ResolvedType type) { public boolean accept(ResolvedType type) {
// type.isPrimitive() javaparser
return type.isPrimitive() || isBoxing(type); return type.isPrimitive() || isBoxing(type);
} }
......
...@@ -3,10 +3,26 @@ package com.github.fengyuchenglun.apidoc.core.resolver; ...@@ -3,10 +3,26 @@ package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.Type;
/**
* 名称解析器.
* @author 名称解析器
*/
public interface TypeNameResolver { public interface TypeNameResolver {
/**
* Accept boolean.
*
* @param id the id
* @return the boolean
*/
boolean accept(String id); boolean accept(String id);
/**
* Resolve type description.
*
* @param type the type
* @return the type description
*/
TypeDescription resolve(Type type); TypeDescription resolve(Type type);
} }
...@@ -3,10 +3,27 @@ package com.github.fengyuchenglun.apidoc.core.resolver; ...@@ -3,10 +3,27 @@ package com.github.fengyuchenglun.apidoc.core.resolver;
import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription; import com.github.fengyuchenglun.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
/**
* 类型解析器.
*
* @author duanledexianxianxian
*/
public interface TypeResolver { public interface TypeResolver {
/**
* Accept boolean.
*
* @param type the type
* @return the boolean
*/
boolean accept(ResolvedType type); boolean accept(ResolvedType type);
/**
* Resolve type description.
*
* @param type the type
* @return the type description
*/
TypeDescription resolve(ResolvedType type); TypeDescription resolve(ResolvedType type);
} }
...@@ -11,32 +11,53 @@ import lombok.extern.slf4j.Slf4j; ...@@ -11,32 +11,53 @@ import lombok.extern.slf4j.Slf4j;
import java.util.List; import java.util.List;
/**
* 类型解析器.
*
* @author duanledexianxian
*/
@Slf4j @Slf4j
public class TypeResolvers { public class TypeResolvers {
/**
* The Object type resolver.
*/
private ObjectTypeResolver objectTypeResolver = new ObjectTypeResolver(); private ObjectTypeResolver objectTypeResolver = new ObjectTypeResolver();
/** /**
* 类型解析器 * 类型解析器
*/ */
private List<TypeResolver> resolvers = Lists.newArrayList( private List<TypeResolver> resolvers = Lists.newArrayList(
// 基本类型+包装类型
new PrimitiveTypeResolver(), new PrimitiveTypeResolver(),
// 数组
new ArrayTypeResolver(), new ArrayTypeResolver(),
// 字符串
new StringTypeResolver(), new StringTypeResolver(),
// 集合
new CollectionTypeResolver(), new CollectionTypeResolver(),
// 时间日期
new DateTypeResolver(), new DateTypeResolver(),
// Map
new MapTypeResolver(), new MapTypeResolver(),
// 枚举
new EnumTypeResolver(), new EnumTypeResolver(),
// Object
new SystemObjectTypeResolver() new SystemObjectTypeResolver()
); );
/**
* 名称解析器.
*/
private List<TypeNameResolver> nameResolvers = Lists.newArrayList(); private List<TypeNameResolver> nameResolvers = Lists.newArrayList();
/** /**
* 获取类型信息 * 获取类型信息
* 1. 先进行类型解析
* 2. 再进行名称解析
* *
* @param type * @param type the type
* @return * @return type description
*/ */
public TypeDescription resolve(Type type) { public TypeDescription resolve(Type type) {
try { try {
...@@ -54,8 +75,8 @@ public class TypeResolvers { ...@@ -54,8 +75,8 @@ public class TypeResolvers {
/** /**
* 解析类型信息 * 解析类型信息
* *
* @param type * @param type the type
* @return * @return type description
*/ */
public TypeDescription resolve(ResolvedType type) { public TypeDescription resolve(ResolvedType type) {
for (TypeResolver typeResolver : resolvers) { for (TypeResolver typeResolver : resolvers) {
...@@ -69,6 +90,12 @@ public class TypeResolvers { ...@@ -69,6 +90,12 @@ public class TypeResolvers {
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
/**
* Name resolve type description.
*
* @param type the type
* @return the type description
*/
public TypeDescription nameResolve(Type type) { public TypeDescription nameResolve(Type type) {
String id = TypeNameHelper.getName(type); String id = TypeNameHelper.getName(type);
for (TypeNameResolver nameResolver : nameResolvers) { for (TypeNameResolver nameResolver : nameResolvers) {
...@@ -80,10 +107,20 @@ public class TypeResolvers { ...@@ -80,10 +107,20 @@ public class TypeResolvers {
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
/**
* Add resolver.
*
* @param typeResolver the type resolver
*/
public void addResolver(TypeResolver typeResolver) { public void addResolver(TypeResolver typeResolver) {
resolvers.add(typeResolver); resolvers.add(typeResolver);
} }
/**
* Add name resolver.
*
* @param nameResolver the name resolver
*/
public void addNameResolver(TypeNameResolver nameResolver) { public void addNameResolver(TypeNameResolver nameResolver) {
nameResolvers.add(nameResolver); nameResolvers.add(nameResolver);
} }
......
...@@ -17,6 +17,8 @@ import java.util.List; ...@@ -17,6 +17,8 @@ import java.util.List;
/** /**
* 附录 * 附录
*
* @author duanledexianxianxian
*/ */
@Data @Data
@EqualsAndHashCode(callSuper=true) @EqualsAndHashCode(callSuper=true)
...@@ -37,7 +39,6 @@ public class Appendix extends Node { ...@@ -37,7 +39,6 @@ public class Appendix extends Node {
} }
/** /**
* Parse appendix. * Parse appendix.
* *
......
...@@ -19,7 +19,7 @@ import java.util.TreeSet; ...@@ -19,7 +19,7 @@ import java.util.TreeSet;
public class Book extends Node { public class Book extends Node {
/** /**
* The constant DEFAULT. * book 默认名称.
*/ */
public static final String DEFAULT = "index"; public static final String DEFAULT = "index";
......
...@@ -9,6 +9,7 @@ import java.util.List; ...@@ -9,6 +9,7 @@ import java.util.List;
* 多个数据的组合 * 多个数据的组合
* *
* @param <T> the type parameter * @param <T> the type parameter
* @author duanledexianxianxian
*/ */
@Data @Data
public class Cell<T> { public class Cell<T> {
...@@ -29,8 +30,8 @@ public class Cell<T> { ...@@ -29,8 +30,8 @@ public class Cell<T> {
* @param values the values * @param values the values
*/ */
@SafeVarargs @SafeVarargs
public Cell(T ... values) { public Cell(T... values) {
this(true,values); this(true, values);
} }
/** /**
...@@ -40,7 +41,7 @@ public class Cell<T> { ...@@ -40,7 +41,7 @@ public class Cell<T> {
* @param values the values * @param values the values
*/ */
@SafeVarargs @SafeVarargs
public Cell(boolean enable, T ... values) { public Cell(boolean enable, T... values) {
this(enable, Lists.newArrayList(values)); this(enable, Lists.newArrayList(values));
} }
...@@ -60,7 +61,7 @@ public class Cell<T> { ...@@ -60,7 +61,7 @@ public class Cell<T> {
* *
* @return the list * @return the list
*/ */
public List<T> toList(){ public List<T> toList() {
return values; return values;
} }
...@@ -78,16 +79,27 @@ public class Cell<T> { ...@@ -78,16 +79,27 @@ public class Cell<T> {
* *
* @param value the value * @param value the value
*/ */
public void add(T value){ public void add(T value) {
values.add(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. * Size int.
* *
* @return the int * @return the int
*/ */
public int size(){ public int size() {
return values.size(); return values.size();
} }
...@@ -97,7 +109,7 @@ public class Cell<T> { ...@@ -97,7 +109,7 @@ public class Cell<T> {
* @param index the index * @param index the index
* @param t the t * @param t the t
*/ */
public void set(int index, T t){ public void set(int index, T t) {
values.set(index, t); values.set(index, t);
} }
...@@ -107,7 +119,7 @@ public class Cell<T> { ...@@ -107,7 +119,7 @@ public class Cell<T> {
* @param index the index * @param index the index
* @return the t * @return the t
*/ */
public T get(int index){ public T get(int index) {
return values.get(index); return values.get(index);
} }
...@@ -116,7 +128,7 @@ public class Cell<T> { ...@@ -116,7 +128,7 @@ public class Cell<T> {
* *
* @return the cell * @return the cell
*/ */
public Cell<T> duplicate(){ public Cell<T> duplicate() {
return new Cell<>(isEnable(), Lists.newArrayList(values)); return new Cell<>(isEnable(), Lists.newArrayList(values));
} }
......
...@@ -5,10 +5,12 @@ import com.github.javaparser.ast.comments.Comment; ...@@ -5,10 +5,12 @@ import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.javadoc.Javadoc; import com.github.javaparser.javadoc.Javadoc;
import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper; import com.github.fengyuchenglun.apidoc.core.common.helper.CommentHelper;
import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper; import com.github.fengyuchenglun.apidoc.core.common.helper.StringHelper;
import com.google.common.collect.Maps;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.HashMap; import java.util.HashMap;
...@@ -52,19 +54,23 @@ public class Node implements Comparable<Node> { ...@@ -52,19 +54,23 @@ public class Node implements Comparable<Node> {
/** /**
* javadoc 中的tag * javadoc 中的tag
*/ */
Map<String, Tag> tags = new HashMap<>(); Map<String, Tag> tags = Maps.newHashMap();
@Override @Override
public int compareTo(@Nonnull Node other) { public int compareTo(@Nonnull Node other) {
// 类型排序
if (this.type != null && other.type != null) { if (this.type != null && other.type != null) {
return this.type.compareTo(other.type); return this.type.compareTo(other.type);
} }
// 索引排序
if (this.index != other.index) { if (this.index != other.index) {
return this.index - other.index; return this.index - other.index;
} }
// id排序
if (this.id != null && other.id != null) { if (this.id != null && other.id != null) {
return this.id.compareTo(other.id); return this.id.compareTo(other.id);
} }
// 名称排序
if (this.name != null && other.name != null) { if (this.name != null && other.name != null) {
return this.name.compareTo(other.name); return this.name.compareTo(other.name);
} }
...@@ -77,6 +83,7 @@ public class Node implements Comparable<Node> { ...@@ -77,6 +83,7 @@ public class Node implements Comparable<Node> {
* @param comment the comment * @param comment the comment
*/ */
public void accept(Comment comment) { public void accept(Comment comment) {
// 不是javadoc注释
if (!comment.isJavadocComment()) { if (!comment.isJavadocComment()) {
setNameAndDescription(comment.getContent()); setNameAndDescription(comment.getContent());
return; return;
...@@ -84,6 +91,7 @@ public class Node implements Comparable<Node> { ...@@ -84,6 +91,7 @@ public class Node implements Comparable<Node> {
Javadoc javadoc = comment.asJavadocComment().parse(); Javadoc javadoc = comment.asJavadocComment().parse();
setNameAndDescription(CommentHelper.getDescription(javadoc.getDescription())); setNameAndDescription(CommentHelper.getDescription(javadoc.getDescription()));
// 设置tag
javadoc.getBlockTags().forEach(blockTag -> { javadoc.getBlockTags().forEach(blockTag -> {
Tag tag = new Tag(); Tag tag = new Tag();
tag.id = blockTag.getTagName(); tag.id = blockTag.getTagName();
...@@ -96,16 +104,16 @@ public class Node implements Comparable<Node> { ...@@ -96,16 +104,16 @@ public class Node implements Comparable<Node> {
} }
/** /**
* Sets name and description. * 设置名称与描述.
* *
* @param content the content * @param content the content
*/ */
public void setNameAndDescription(String content) { public void setNameAndDescription(String content) {
String[] arr = content.split("(\\r\\n)|(\\r)|(\\n)+", 2); 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]; name = arr[0];
} }
if (arr.length >= 2 && StringHelper.nonBlank(arr[1])) { if (arr.length >= 2 && StringUtils.isNotBlank(arr[1])) {
description = arr[1]; description = arr[1];
} }
} }
......
...@@ -33,13 +33,9 @@ public class Project extends Node { ...@@ -33,13 +33,9 @@ public class Project extends Node {
* 附录 * 附录
*/ */
List<Appendix> appendices = new LinkedList<>(); List<Appendix> appendices = new LinkedList<>();
/**
* 统一结果
*/
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration;
/** /**
* Add chapter. * 添加章节.
* *
* @param chapter the chapter * @param chapter the chapter
*/ */
......
package com.github.fengyuchenglun.apidoc.core.schema; 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 lombok.*;
import org.apache.commons.lang3.StringUtils;
/** /**
* The type Row. * The type Row.
...@@ -54,4 +57,35 @@ public class Row { ...@@ -54,4 +57,35 @@ public class Row {
this.type = type; 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()} ...@@ -58,10 +58,10 @@ ${section.getRequestBodyParameterString()}
<#-- 请求参数table列表--> <#-- 请求参数table列表-->
<#if section.requestRows?? && (section.requestRows?size>0)> <#if section.requestRows?? && (section.requestRows?size>0)>
| 字段 | 类型 | 参数类型 | 是否必填 | 验证 | 默认值 | 描述 | | 字段 | 类型 | 参数类型 | 必填 | 验证 | 默认值 | 描述 |
| :------- | :----- | :----- |:-------- |:-------- | :------ | :---------- | | :------- | :----- | :----- |:-------- |:-------- | :------ | :---------- |
<#list section.requestRows as rowKey,rowValue> <#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> </#list>
</#if> </#if>
<#-- 响应--> <#-- 响应-->
...@@ -77,7 +77,7 @@ ${section.getResponseString()} ...@@ -77,7 +77,7 @@ ${section.getResponseString()}
| 字段 | 类型 | 默认值 | 描述 | | 字段 | 类型 | 默认值 | 描述 |
| :------- | :----- |:----- | :---------- | | :------- | :----- |:----- | :---------- |
<#list section.responseRows as rowKey,rowValue> <#list section.responseRows as rowKey,rowValue>
| ${rowValue.key!''} | ${rowValue.type!''} | ${rowValue.def!''} | ${rowValue.remark!''} | | ${rowValue.key!''} | ${rowValue.getLabelType()!''} | ${rowValue.def!''} | ${rowValue.getHtmlRemark()!''} |
</#list> </#list>
</#if> </#if>
</#if> </#if>
...@@ -90,6 +90,9 @@ ${section.getResponseString()} ...@@ -90,6 +90,9 @@ ${section.getResponseString()}
<#------------ END 循环遍历book ----------> <#------------ END 循环遍历book ---------->
</#if> </#if>
# 附录 # 附录
<#if appendices??> <#if appendices??>
<#list appendices as appendfix> <#list appendices as appendfix>
......
...@@ -3,17 +3,50 @@ package com.github.fengyuchenglun.apidoc.springmvc; ...@@ -3,17 +3,50 @@ package com.github.fengyuchenglun.apidoc.springmvc;
import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.Parameter;
/**
* The type Parameter helper.
*/
public class ParameterHelper { public class ParameterHelper {
/**
* The constant ANNOTATION_REQUEST_PARAM.
*/
public static final String ANNOTATION_REQUEST_PARAM = "RequestParam"; public static final String ANNOTATION_REQUEST_PARAM = "RequestParam";
/**
* The constant ANNOTATION_REQUEST_HEADER.
*/
public static final String ANNOTATION_REQUEST_HEADER = "RequestHeader"; public static final String ANNOTATION_REQUEST_HEADER = "RequestHeader";
/**
* The constant ANNOTATION_REQUEST_ATTRIBUTE.
*/
public static final String ANNOTATION_REQUEST_ATTRIBUTE = "RequestAttribute"; public static final String ANNOTATION_REQUEST_ATTRIBUTE = "RequestAttribute";
/**
* The constant ANNOTATION_REQUEST_PART.
*/
public static final String ANNOTATION_REQUEST_PART = "RequestPart"; public static final String ANNOTATION_REQUEST_PART = "RequestPart";
/**
* The constant ANNOTATION_COOKIE_VALUE.
*/
public static final String ANNOTATION_COOKIE_VALUE = "CookieValue"; public static final String ANNOTATION_COOKIE_VALUE = "CookieValue";
/**
* The constant ANNOTATION_PATH_VARIABLE.
*/
public static final String ANNOTATION_PATH_VARIABLE = "PathVariable"; public static final String ANNOTATION_PATH_VARIABLE = "PathVariable";
/**
* The constant ANNOTATION_REQUEST_BODY.
*/
public static final String ANNOTATION_REQUEST_BODY = "RequestBody"; public static final String ANNOTATION_REQUEST_BODY = "RequestBody";
/**
* The constant ANNOTATION_MULTIPART_FILE.
*/
public static final String ANNOTATION_MULTIPART_FILE = "MultipartFile"; 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) { public static boolean hasRequestBody(NodeList<Parameter> parameters) {
for (Parameter parameter : parameters) { for (Parameter parameter : parameters) {
if (isRequestBody(parameter)) { if (isRequestBody(parameter)) {
...@@ -23,6 +56,12 @@ public class ParameterHelper { ...@@ -23,6 +56,12 @@ public class ParameterHelper {
return false; return false;
} }
/**
* 是否是请求参数
*
* @param parameter the parameter
* @return boolean
*/
public static boolean isRequestParam(Parameter parameter) { public static boolean isRequestParam(Parameter parameter) {
if (!parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE) && if (!parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE) &&
!parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY) && !parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY) &&
...@@ -36,6 +75,12 @@ public class ParameterHelper { ...@@ -36,6 +75,12 @@ public class ParameterHelper {
return false; return false;
} }
/**
* Is path variable boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isPathVariable(Parameter parameter) { public static boolean isPathVariable(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE)) { if (parameter.isAnnotationPresent(ANNOTATION_PATH_VARIABLE)) {
return true; return true;
...@@ -43,6 +88,12 @@ public class ParameterHelper { ...@@ -43,6 +88,12 @@ public class ParameterHelper {
return false; return false;
} }
/**
* Is request body boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isRequestBody(Parameter parameter) { public static boolean isRequestBody(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY)) { if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_BODY)) {
return true; return true;
...@@ -50,6 +101,12 @@ public class ParameterHelper { ...@@ -50,6 +101,12 @@ public class ParameterHelper {
return false; return false;
} }
/**
* Is request header boolean.
*
* @param parameter the parameter
* @return the boolean
*/
public static boolean isRequestHeader(Parameter parameter) { public static boolean isRequestHeader(Parameter parameter) {
if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_HEADER)) { if (parameter.isAnnotationPresent(ANNOTATION_REQUEST_HEADER)) {
return true; return true;
......
...@@ -95,18 +95,23 @@ public class SpringParser implements ParserStrategy { ...@@ -95,18 +95,23 @@ public class SpringParser implements ParserStrategy {
/** /**
* 解析方法定义 * 解析方法定义
* * @param n 方法声明
* @param n * @param chapter 章
* @param chapter * @param section 节
* @param section
*/ */
@Override @Override
public void visit(MethodDeclaration n, Chapter chapter, Section section) { public void visit(MethodDeclaration n, Chapter chapter, Section section) {
// 解析方法
visitMethod(n, chapter, section); visitMethod(n, chapter, section);
// 解析url
visitUri(n, chapter, section); visitUri(n, chapter, section);
// 解析路径参数
visitPathVariable(n, chapter, section); visitPathVariable(n, chapter, section);
// 解析头
visitHeaders(n, chapter, section); visitHeaders(n, chapter, section);
// 解析请求参数
visitParameters(n, chapter, section); visitParameters(n, chapter, section);
// 解析返回结果
visitReturn(n, chapter, section); visitReturn(n, chapter, section);
} }
...@@ -265,6 +270,7 @@ public class SpringParser implements ParserStrategy { ...@@ -265,6 +270,7 @@ public class SpringParser implements ParserStrategy {
Object defaultValue = null; Object defaultValue = null;
Boolean required = null; Boolean required = null;
// 是否带有@RequestParam注解
Optional<AnnotationExpr> optional = parameter.getAnnotationByName(ParameterHelper.ANNOTATION_REQUEST_PARAM); Optional<AnnotationExpr> optional = parameter.getAnnotationByName(ParameterHelper.ANNOTATION_REQUEST_PARAM);
if (optional.isPresent()) { if (optional.isPresent()) {
// 如果有RequestParam注解,则参数必填 // 如果有RequestParam注解,则参数必填
...@@ -313,7 +319,7 @@ public class SpringParser implements ParserStrategy { ...@@ -313,7 +319,7 @@ public class SpringParser implements ParserStrategy {
* @param section the section * @param section the section
*/ */
private void visitReturn(MethodDeclaration n, Chapter chapter, Section section) { private void visitReturn(MethodDeclaration n, Chapter chapter, Section section) {
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getProject().getResultDataClassOrInterfaceDeclaration(); ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration = ApiDoc.getInstance().getResultDataClassOrInterfaceDeclaration();
if (null != resultDataClassOrInterfaceDeclaration) { if (null != resultDataClassOrInterfaceDeclaration) {
ClassOrInterfaceType returnType = new ClassOrInterfaceType(); ClassOrInterfaceType returnType = new ClassOrInterfaceType();
returnType.setName(resultDataClassOrInterfaceDeclaration.getName()); returnType.setName(resultDataClassOrInterfaceDeclaration.getName());
......
...@@ -12,6 +12,11 @@ import com.github.javaparser.resolution.types.ResolvedType; ...@@ -12,6 +12,11 @@ import com.github.javaparser.resolution.types.ResolvedType;
import java.util.Optional; import java.util.Optional;
/**
* spring组件解析.
*
* @author duanledexianxianxian
*/
public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolver { public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolver {
@Override @Override
public boolean accept(ResolvedType type) { public boolean accept(ResolvedType type) {
...@@ -44,6 +49,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv ...@@ -44,6 +49,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
/**
* Is spring component boolean.
*
* @param type the type
* @return the boolean
*/
private static boolean isSpringComponent(ResolvedType type){ private static boolean isSpringComponent(ResolvedType type){
if(!type.isReferenceType()){ if(!type.isReferenceType()){
return false; return false;
...@@ -51,6 +62,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv ...@@ -51,6 +62,12 @@ public class SpringComponentTypeResolver implements TypeResolver, TypeNameResolv
return isSpringComponent(type.asReferenceType().getId()); return isSpringComponent(type.asReferenceType().getId());
} }
/**
* Is spring component boolean.
*
* @param id the id
* @return the boolean
*/
private static boolean isSpringComponent(String id){ private static boolean isSpringComponent(String id){
return id!=null && (id.startsWith("org.springframework")); 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 { ...@@ -11,6 +11,6 @@ public class Menu {
int id; int id;
String name; String name;
List<Menu> menus; // List<Menu> menus;
} }
...@@ -3,36 +3,57 @@ package com.github.fengyuchenglun.example.common; ...@@ -3,36 +3,57 @@ package com.github.fengyuchenglun.example.common;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/**
* The type Query.
*/
@Setter @Setter
@Getter @Getter
public class Query { public class Query {
/** // /**
* static will be ignore // * static will be ignore
*/ // */
public static final String CONSTANS = ""; // 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 List<Menu> menuList;
* 用户名称
*/
private String userName;
/**
* 用户手机号码
*/
private String userPhoneNum;
/**
* 用户邮箱
*/
private String userEmail;
/**
* 开始时间
*/
private LocalDateTime startTime;
/**
* 结束时间
*/
private LocalDateTime endTime;
} }
package com.github.fengyuchenglun.example.common; package com.github.fengyuchenglun.example.common;
/** /**
* 静态常量
*
* @author duanledexianxianxian
* @code * @code
*/ */
public class StaticFinalCode { public class StaticFinalCode {
......
...@@ -22,20 +22,20 @@ import java.util.List; ...@@ -22,20 +22,20 @@ import java.util.List;
@RequestMapping("/api/v1/users") @RequestMapping("/api/v1/users")
public class UserController { public class UserController {
//
// /** /**
// * 查看用户详情 * 查看用户详情
// * *
// * @param userId 用户编号 * @param userId 用户编号
// * @param age 年龄 * @param age 年龄
// * @param query 过滤条件 * @param query 过滤条件
// * @return 用户对象 user * @return 用户对象 user
// */ */
// @PostMapping(value = "/{userId}") @PostMapping(value = "/{userId}")
// public User detail(@PathVariable String userId, String age, @RequestBody Query query) { public User detail(@PathVariable String userId, String age, @RequestBody Query query) {
// User user = new User(); User user = new User();
// return user; return user;
// } }
// //
// /** // /**
// * 查看用户详情 // * 查看用户详情
...@@ -51,14 +51,15 @@ public class UserController { ...@@ -51,14 +51,15 @@ public class UserController {
// } // }
// //
// //
//
// /** // /**
// * 测试get的query对象,带RequestParam注解 // * 测试get的query对象,带RequestParam注解
// * // *
// * @param query 过滤条件 // * @param query the query
// * @return 用户对象 user // * @return 用户对象 user
// */ // */
// @GetMapping(value = "/detail3") // @GetMapping(value = "/detail3")
// public User detail3(@RequestParam String query) { // public User detail3(Query query) {
// User user = new User(); // User user = new User();
// return user; // return user;
// } // }
......
...@@ -19,7 +19,8 @@ allprojects { ...@@ -19,7 +19,8 @@ allprojects {
dependencies { dependencies {
compile 'ch.qos.logback:logback-classic:1.2.3' compile 'ch.qos.logback:logback-classic:1.2.3'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.10' 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' annotationProcessor 'org.projectlombok:lombok:1.18.6'
testCompileOnly 'org.projectlombok:lombok:1.18.4' 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