Commit 3d71573f authored by duanledexianxianxian's avatar duanledexianxianxian 😁

Merge branch 'dev' into 'master'

Dev

See merge request !1
parents 80acc032 f4af126d
...@@ -2,4 +2,5 @@ dependencies { ...@@ -2,4 +2,5 @@ dependencies {
compile 'com.github.javaparser:javaparser-symbol-solver-core:3.14.4' compile 'com.github.javaparser:javaparser-symbol-solver-core:3.14.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.2' compile 'com.fasterxml.jackson.core:jackson-databind:2.5.2'
compile 'org.asciidoctor:asciidoctorj:2.1.0' compile 'org.asciidoctor:asciidoctorj:2.1.0'
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
} }
package kim.apidoc.core; package com.kim.apidoc.core;
import kim.apidoc.core.common.helper.StringHelper; import com.kim.apidoc.core.common.helper.StringHelper;
import kim.apidoc.core.parser.ParserStrategy; import com.kim.apidoc.core.parser.ParserStrategy;
import kim.apidoc.core.parser.VisitorParser; import com.kim.apidoc.core.parser.VisitorParser;
import kim.apidoc.core.render.ProjectRender; import com.kim.apidoc.core.render.ProjectRender;
import kim.apidoc.core.resolver.TypeResolvers; import com.kim.apidoc.core.resolver.TypeResolvers;
import kim.apidoc.core.schema.Project; import com.kim.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;
...@@ -135,15 +135,15 @@ public class ApiDoc { ...@@ -135,15 +135,15 @@ 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.framework)) { if (StringHelper.isBlank(context.getFramework())) {
return strategies.get(0); return strategies.get(0);
} }
for (ParserStrategy strategy : strategies) { for (ParserStrategy strategy : strategies) {
if (Objects.equals(context.framework, strategy.name())) { if (Objects.equals(context.getFramework(), strategy.name())) {
return strategy; return strategy;
} }
} }
throw new IllegalArgumentException("no ParserStrategy implements found for " + context.framework); throw new IllegalArgumentException("no ParserStrategy implements found for " + context.getFramework());
} }
/** /**
......
package kim.apidoc.core; package com.kim.apidoc.core;
import kim.apidoc.core.common.helper.FileHelper;
import kim.apidoc.core.render.AsciiDocRender;
import kim.apidoc.core.render.PostmanRender;
import kim.apidoc.core.render.ProjectRender;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.kim.apidoc.core.common.helper.FileHelper;
import com.kim.apidoc.core.render.MarkdownRender;
import com.kim.apidoc.core.render.ProjectRender;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -14,6 +13,8 @@ import java.nio.file.Paths; ...@@ -14,6 +13,8 @@ import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.kim.apidoc.core.common.Constants.MARKDOWN_TEMPLATE;
/** /**
* The type Context. * The type Context.
* *
...@@ -44,15 +45,16 @@ public class Context { ...@@ -44,15 +45,16 @@ public class Context {
* 设置当前解析框架 * 设置当前解析框架
*/ */
@Setter @Setter
public String framework; private String framework;
/** /**
* The Renders. * The Renders.
*/ */
@Setter @Setter
public List<ProjectRender> renders = Lists.newArrayList( private List<ProjectRender> renders = Lists.newArrayList(
new AsciiDocRender(), //new AsciiDocRender(),
new PostmanRender()); //new PostmanRender(),
new MarkdownRender());
/** /**
* 编译目录 * 编译目录
...@@ -102,17 +104,24 @@ public class Context { ...@@ -102,17 +104,24 @@ public class Context {
@Setter @Setter
private String css; private String css;
/**
* markdown模版文件路径
*/
@Setter
private String markdownTemplate = MARKDOWN_TEMPLATE;
/** /**
* 自定义扩展参数 * 自定义扩展参数
*/ */
private Map<String,Object> ext= Maps.newHashMap(); private Map<String, Object> ext = Maps.newHashMap();
/** /**
* Add source. * Add source.
* *
* @param path the path * @param path the path
*/ */
public void addSource(Path path){ public void addSource(Path path) {
sources.add(path); sources.add(path);
sources.addAll(FileHelper.find(path, DEFAULT_CODE_STRUCTURE)); sources.addAll(FileHelper.find(path, DEFAULT_CODE_STRUCTURE));
addDependency(path); addDependency(path);
...@@ -123,7 +132,7 @@ public class Context { ...@@ -123,7 +132,7 @@ public class Context {
* *
* @param path the path * @param path the path
*/ */
public void addDependency(Path path){ public void addDependency(Path path) {
dependencies.add(path); dependencies.add(path);
dependencies.addAll(FileHelper.find(path, DEFAULT_CODE_STRUCTURE)); dependencies.addAll(FileHelper.find(path, DEFAULT_CODE_STRUCTURE));
} }
...@@ -133,10 +142,9 @@ public class Context { ...@@ -133,10 +142,9 @@ public class Context {
* *
* @param path the path * @param path the path
*/ */
public void addJar(Path path){ public void addJar(Path path) {
jars.add(path); jars.add(path);
} }
} }
package kim.apidoc.core.common; package com.kim.apidoc.core.common;
import com.google.common.base.Strings; import com.google.common.base.Strings;
......
package com.kim.apidoc.core.common;
import java.nio.charset.StandardCharsets;
/**
* 常量类
*
* @author duanledexianxianxian
* @version 1.0.0
* @date 2020 /3/26 23:00
* @since 1.0.0
*/
public class Constants {
public static final String UTF8 = StandardCharsets.UTF_8.name();
public static final String SLASH = "/";
public static final String MARKDOWN_EXTENSION = ".md";
public static final String MARKDOWN_TEMPLATE = "/templates/markdown.ftl";
}
package kim.apidoc.core.common; package com.kim.apidoc.core.common;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
......
package kim.apidoc.core.common; package com.kim.apidoc.core.common;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
......
package kim.apidoc.core.common; package com.kim.apidoc.core.common;
import kim.apidoc.core.common.helper.StringHelper; import com.kim.apidoc.core.common.helper.StringHelper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
......
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
import kim.apidoc.core.common.ObjectMappers; import com.kim.apidoc.core.schema.Row;
import kim.apidoc.core.schema.Row; import com.kim.apidoc.core.common.ObjectMappers;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
/**
* 数组类型描述
*/
public class ArrayTypeDescription extends TypeDescription { public class ArrayTypeDescription extends TypeDescription {
protected ArrayNode value; protected ArrayNode value;
......
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
import kim.apidoc.core.common.ObjectMappers; import com.kim.apidoc.core.schema.Row;
import kim.apidoc.core.schema.Row; import com.kim.apidoc.core.common.ObjectMappers;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.Getter; import lombok.Getter;
...@@ -10,18 +10,40 @@ import lombok.Setter; ...@@ -10,18 +10,40 @@ import lombok.Setter;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
/**
* 对象类型描述
*
* @author fengyuchenglun
* @version 1.0.0
*/
@Setter @Setter
@Getter @Getter
public class ObjectTypeDescription extends TypeDescription { public class ObjectTypeDescription extends TypeDescription {
/**
* The Members.
*/
protected List<TypeDescription> members = Lists.newArrayList(); protected List<TypeDescription> members = Lists.newArrayList();
/**
* The Value.
*/
private ObjectNode value = ObjectMappers.instance.createObjectNode(); private ObjectNode value = ObjectMappers.instance.createObjectNode();
/**
* Merge.
*
* @param other the other
*/
public void merge(ObjectTypeDescription other) { public void merge(ObjectTypeDescription other) {
value.setAll(other.getValue()); value.setAll(other.getValue());
members.addAll(other.members); members.addAll(other.members);
} }
/**
* Add.
*
* @param component the component
*/
public void add(TypeDescription component) { public void add(TypeDescription component) {
members.add(component); members.add(component);
if (component.isPrimitive()) { if (component.isPrimitive()) {
...@@ -35,6 +57,11 @@ public class ObjectTypeDescription extends TypeDescription { ...@@ -35,6 +57,11 @@ public class ObjectTypeDescription 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":
...@@ -101,4 +128,15 @@ public class ObjectTypeDescription extends TypeDescription { ...@@ -101,4 +128,15 @@ public class ObjectTypeDescription extends TypeDescription {
} }
return rows; return rows;
} }
@Override
public Collection<Row> rows(String requestParameterType) {
Collection<Row> rows = super.rows(null);
for (TypeDescription member : members) {
if (member.isAvailable()) {
rows.addAll(member.rows(requestParameterType));
}
}
return rows;
}
} }
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedReferenceType;
/**
* 原始类型描述
*/
public class PrimitiveTypeDescription extends TypeDescription { public class PrimitiveTypeDescription extends TypeDescription {
/**
* Instantiates a new Primitive type description.
*
* @param referenceType the reference type
*/
public PrimitiveTypeDescription(ResolvedReferenceType referenceType) { public PrimitiveTypeDescription(ResolvedReferenceType referenceType) {
switch (referenceType.getId()) { switch (referenceType.getId()) {
case "java.lang.Byte": case "java.lang.Byte":
...@@ -44,6 +51,11 @@ public class PrimitiveTypeDescription extends TypeDescription { ...@@ -44,6 +51,11 @@ public class PrimitiveTypeDescription extends TypeDescription {
} }
/**
* Instantiates a new Primitive type description.
*
* @param resolvedPrimitiveType the resolved primitive type
*/
public PrimitiveTypeDescription(ResolvedPrimitiveType resolvedPrimitiveType) { public PrimitiveTypeDescription(ResolvedPrimitiveType resolvedPrimitiveType) {
type = resolvedPrimitiveType.describe(); type = resolvedPrimitiveType.describe();
switch (resolvedPrimitiveType) { switch (resolvedPrimitiveType) {
......
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
/**
* 字符串类型
*/
public class StringTypeDescription extends TypeDescription { public class StringTypeDescription extends TypeDescription {
/**
* Instantiates a new String type description.
*
* @param type the type
* @param charSequence the char sequence
*/
public StringTypeDescription(String type, CharSequence charSequence) { public StringTypeDescription(String type, CharSequence charSequence) {
this.type = type; this.type = type;
value = charSequence.toString(); value = charSequence.toString();
......
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
import kim.apidoc.core.common.helper.StringHelper; import com.github.javaparser.ast.comments.Comment;
import kim.apidoc.core.schema.Row; import com.github.javaparser.javadoc.Javadoc;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.kim.apidoc.core.common.helper.CommentHelper;
import com.kim.apidoc.core.common.helper.StringHelper;
import com.kim.apidoc.core.schema.Row;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Collection; import java.util.Collection;
/**
* The type Type description.
*/
@Setter @Setter
@Getter @Getter
public abstract class TypeDescription { public abstract class TypeDescription {
/**
* The Prefix.
*/
protected String prefix = ""; protected String prefix = "";
/**
* The 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();
/**
* 说明.
*/
protected String remark; protected String remark;
/**
* 值.
*/
protected Object value; protected Object value;
/**
* 默认值.
*/
protected Object defaultValue; protected Object defaultValue;
/**
* 是否必填.
*/
protected Boolean required; protected Boolean required;
/**
* Is available boolean.
*
* @return the boolean
*/
public boolean isAvailable() { public boolean isAvailable() {
return !isUnAvailable(); return !isUnAvailable();
} }
/**
* Is un available boolean.
*
* @return the boolean
*/
public boolean isUnAvailable() { public boolean isUnAvailable() {
return this instanceof UnAvailableTypeDescription; return this instanceof UnAvailableTypeDescription;
} }
/**
* Is primitive boolean.
*
* @return the boolean
*/
public boolean isPrimitive() { public boolean isPrimitive() {
return this instanceof PrimitiveTypeDescription; return this instanceof PrimitiveTypeDescription;
} }
/**
* As primitive primitive type description.
*
* @return the primitive type description
*/
public PrimitiveTypeDescription asPrimitive() { public PrimitiveTypeDescription asPrimitive() {
return (PrimitiveTypeDescription) this; return (PrimitiveTypeDescription) this;
} }
/**
* Is string boolean.
*
* @return the boolean
*/
public boolean isString() { public boolean isString() {
return this instanceof StringTypeDescription; return this instanceof StringTypeDescription;
} }
/**
* As string string type description.
*
* @return the string type description
*/
public StringTypeDescription asString() { public StringTypeDescription asString() {
return (StringTypeDescription) this; return (StringTypeDescription) this;
} }
/**
* Is array boolean.
*
* @return the boolean
*/
public boolean isArray() { public boolean isArray() {
return this instanceof ArrayTypeDescription; return this instanceof ArrayTypeDescription;
} }
/**
* As array array type description.
*
* @return the array type description
*/
public ArrayTypeDescription asArray() { public ArrayTypeDescription asArray() {
return (ArrayTypeDescription) this; return (ArrayTypeDescription) this;
} }
/**
* Is object boolean.
*
* @return the boolean
*/
public boolean isObject() { public boolean isObject() {
return this instanceof ObjectTypeDescription; return this instanceof ObjectTypeDescription;
} }
/**
* As object object type description.
*
* @return the object type description
*/
public ObjectTypeDescription asObject() { public ObjectTypeDescription asObject() {
return (ObjectTypeDescription) this; return (ObjectTypeDescription) this;
} }
/**
* Add remark.
*
* @param value the value
*/
public void addRemark(String value) { public void addRemark(String value) {
if (value == null) { if (value == null) {
return; return;
...@@ -72,13 +157,23 @@ public abstract class TypeDescription { ...@@ -72,13 +157,23 @@ public abstract class TypeDescription {
} }
} }
/**
* Full key string.
*
* @return the string
*/
public String fullKey() { public String fullKey() {
return StringHelper.join(".", prefix, key); return StringHelper.join(".", prefix, key);
} }
public Collection<Row> rows() { /**
String key = fullKey(); * Rows collection.
if (StringHelper.isBlank(key)) { *
* @return the collection
*/
public Collection<Row> rows(String requestParameterType) {
String fullKey = fullKey();
if (StringHelper.isBlank(fullKey)) {
return Lists.newArrayList(); return Lists.newArrayList();
} }
String def; String def;
...@@ -94,7 +189,26 @@ public abstract class TypeDescription { ...@@ -94,7 +189,26 @@ public abstract class TypeDescription {
condition.append("required=").append(required); condition.append("required=").append(required);
} }
return Lists.newArrayList(new Row(key, type, condition.toString(), def, remark)); return Lists.newArrayList(new Row(key, type, false, condition.toString(), def, remark, requestParameterType));
}
/**
* Rows collection.
*
* @return the collection
*/
public Collection<Row> rows() {
return this.rows(null);
}
public void accept(Comment comment) {
if (!comment.isJavadocComment()) {
setRemark(comment.getContent());
return;
}
Javadoc javadoc = comment.asJavadocComment().parse();
setRemark(CommentHelper.getDescription(javadoc.getDescription()));
} }
} }
package kim.apidoc.core.common.description; package com.kim.apidoc.core.common.description;
import kim.apidoc.core.schema.Row; import com.kim.apidoc.core.schema.Row;
import java.util.Collection; import java.util.Collection;
......
package kim.apidoc.core.common.diff; package com.kim.apidoc.core.common.diff;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import lombok.Getter; import lombok.Getter;
......
package kim.apidoc.core.common.diff; package com.kim.apidoc.core.common.diff;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package kim.apidoc.core.common.diff; package com.kim.apidoc.core.common.diff;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
...@@ -24,7 +24,7 @@ public class AnnotationHelper { ...@@ -24,7 +24,7 @@ public class AnnotationHelper {
} }
if (annotationExpr.isNormalAnnotationExpr()) { if (annotationExpr.isNormalAnnotationExpr()) {
for (MemberValuePair pair : annotationExpr.asNormalAnnotationExpr().getPairs()) { for (MemberValuePair pair : annotationExpr.asNormalAnnotationExpr().getPairs()) {
if (Objects.equals(key, pair.getNameAsString())){ if (Objects.equals(key, pair.getNameAsString())) {
return Optional.of(pair.getValue()); return Optional.of(pair.getValue());
} }
} }
...@@ -32,10 +32,10 @@ public class AnnotationHelper { ...@@ -32,10 +32,10 @@ public class AnnotationHelper {
return Optional.empty(); return Optional.empty();
} }
public static Optional<Expression> getAnyAttribute(AnnotationExpr annotationExpr, String ... keys) { public static Optional<Expression> getAnyAttribute(AnnotationExpr annotationExpr, String... keys) {
for (String key : keys) { for (String key : keys) {
Optional<Expression> optional = getAttribute(annotationExpr, key); Optional<Expression> optional = getAttribute(annotationExpr, key);
if(optional.isPresent()){ if (optional.isPresent()) {
return optional; return optional;
} }
} }
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedReferenceType;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
@Slf4j @Slf4j
...@@ -28,9 +25,9 @@ public class ClassDeclarationHelper { ...@@ -28,9 +25,9 @@ public class ClassDeclarationHelper {
if (resolvedReferenceType.getTypeDeclaration() instanceof JavaParserClassDeclaration) { if (resolvedReferenceType.getTypeDeclaration() instanceof JavaParserClassDeclaration) {
JavaParserClassDeclaration typeDeclaration = (JavaParserClassDeclaration) resolvedReferenceType.getTypeDeclaration(); JavaParserClassDeclaration typeDeclaration = (JavaParserClassDeclaration) resolvedReferenceType.getTypeDeclaration();
return Optional.of(typeDeclaration.getWrappedNode()); return Optional.of(typeDeclaration.getWrappedNode());
}else if(resolvedReferenceType.getTypeDeclaration() instanceof ReflectionClassDeclaration){ } else if (resolvedReferenceType.getTypeDeclaration() instanceof ReflectionClassDeclaration) {
ReflectionClassDeclaration typeDeclaration = (ReflectionClassDeclaration) resolvedReferenceType.getTypeDeclaration(); ReflectionClassDeclaration typeDeclaration = (ReflectionClassDeclaration) resolvedReferenceType.getTypeDeclaration();
System.out.println("type Declaration:"+typeDeclaration); System.out.println("type Declaration:" + typeDeclaration);
//TODO //TODO
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -39,4 +36,16 @@ public class ClassDeclarationHelper { ...@@ -39,4 +36,16 @@ public class ClassDeclarationHelper {
return Optional.empty(); return Optional.empty();
} }
public static String getClassOrInterfacePackageName(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) {
final String[] result = {null};
classOrInterfaceDeclaration.findCompilationUnit().ifPresent(x -> {
x.getPackageDeclaration().ifPresent(y -> {
result[0] = y.getNameAsString() + "." + classOrInterfaceDeclaration.getName();
});
});
return result[0];
}
} }
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.MethodDeclaration;
...@@ -15,49 +15,73 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse ...@@ -15,49 +15,73 @@ import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParse
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* The type Comment helper.
*/
public class CommentHelper { public class CommentHelper {
/** /**
* 获取完整注释字符串 * 获取完整注释字符串
* @param description *
* @return * @param description the description
* @return string
*/ */
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());
} }
public static String getContent(Comment comment){ /**
if(!comment.isJavadocComment()){ * Get content string.
*
* @param comment the comment
* @return the string
*/
public static String getContent(Comment comment) {
if (!comment.isJavadocComment()) {
return comment.getContent(); return comment.getContent();
} }
return getDescription(comment.asJavadocComment().parse().getDescription()); return getDescription(comment.asJavadocComment().parse().getDescription());
} }
public static String getComment(MethodUsage it){ /**
* Get comment string.
*
* @param it the it
* @return the string
*/
public static String getComment(MethodUsage it) {
if (it.getDeclaration() instanceof JavaParserMethodDeclaration) { if (it.getDeclaration() instanceof JavaParserMethodDeclaration) {
MethodDeclaration wrappedNode = ((JavaParserMethodDeclaration) it.getDeclaration()).getWrappedNode(); MethodDeclaration wrappedNode = ((JavaParserMethodDeclaration) it.getDeclaration()).getWrappedNode();
Optional<Comment> optional = wrappedNode.getComment(); Optional<Comment> optional = wrappedNode.getComment();
if(optional.isPresent()){ if (optional.isPresent()) {
return CommentHelper.getContent(optional.get()); return CommentHelper.getContent(optional.get());
} }
} }
return null; return null;
} }
public static String getComment(ResolvedFieldDeclaration it){
if(it instanceof JavaParserFieldDeclaration){ /**
* Get comment string.
*
* @param it the it
* @return the string
*/
public static String getComment(ResolvedFieldDeclaration it) {
if (it instanceof JavaParserFieldDeclaration) {
FieldDeclaration wrappedNode = ((JavaParserFieldDeclaration) it).getWrappedNode(); FieldDeclaration wrappedNode = ((JavaParserFieldDeclaration) it).getWrappedNode();
Optional<Comment> optional = wrappedNode.getComment(); Optional<Comment> optional = wrappedNode.getComment();
if(optional.isPresent()){ if (optional.isPresent()) {
return CommentHelper.getContent(optional.get()); return CommentHelper.getContent(optional.get());
} }
}else if(it instanceof JavaParserClassDeclaration){ } else if (it instanceof JavaParserClassDeclaration) {
JavaParserClassDeclaration classDeclaration = (JavaParserClassDeclaration) it; JavaParserClassDeclaration classDeclaration = (JavaParserClassDeclaration) it;
} }
return null; return null;
} }
} }
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node; import com.github.javaparser.ast.Node;
...@@ -7,11 +7,11 @@ import java.util.Optional; ...@@ -7,11 +7,11 @@ import java.util.Optional;
public class CompilationUnitHelper { public class CompilationUnitHelper {
public static Optional<CompilationUnit> getCompilationUnit(Node node){ public static Optional<CompilationUnit> getCompilationUnit(Node node) {
if(node instanceof CompilationUnit){ if (node instanceof CompilationUnit) {
return Optional.of((CompilationUnit) node); return Optional.of((CompilationUnit) node);
} }
if (node.getParentNode().isPresent()){ if (node.getParentNode().isPresent()) {
return getCompilationUnit(node.getParentNode().get()); return getCompilationUnit(node.getParentNode().get());
} }
return Optional.empty(); return Optional.empty();
......
package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.EnumConstantDeclaration;
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.kim.apidoc.core.schema.Cell;
import java.util.ArrayList;
import java.util.List;
/**
* The type Enum helper.
*/
public class EnumHelper {
/**
* Get names string.
*
* @param enumDeclaration the enum declaration
* @return the string
*/
public static String getNames(ResolvedEnumDeclaration enumDeclaration){
StringBuilder sb = new StringBuilder();
for (ResolvedEnumConstantDeclaration resolvedEnumConstantDeclaration : enumDeclaration.getEnumConstants()) {
if(sb.length()>0){
sb.append(",");
}
sb.append(resolvedEnumConstantDeclaration.getName());
}
return sb.toString();
}
/**
* To details list.
*
* @param declaration the declaration
* @return the list
*/
public static List<Cell<String>> toDetails(EnumDeclaration declaration){
List<Cell<String>> cells = new ArrayList<>();
for (EnumConstantDeclaration constant : declaration.getEntries()) {
Cell<String> cell = new Cell<>();
cell.add(constant.getNameAsString());
for (Expression expression : constant.getArguments()) {
Object value = ExpressionHelper.getValue(expression);
cell.add(String.valueOf(value));
}
cells.add(cell);
}
return cells;
}
}
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.expr.*;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration;
import com.kim.apidoc.core.schema.Cell;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
/**
* The type Field helper.
*/
public class FieldHelper { public class FieldHelper {
/** /**
* 通过access方法,获取属性名 * 通过access方法,获取属性名
*
* @param methodName access方法名 * @param methodName access方法名
* @return 属性名 * @return 属性名 string
*/ */
public static String getByAccessMethod(String methodName){ public static String getByAccessMethod(String methodName) {
if(methodName.startsWith("is") && methodName.length()>2){ if (methodName.startsWith("is") && methodName.length() > 2) {
String first = methodName.substring(2, 3); String first = methodName.substring(2, 3);
String less = methodName.substring(3); String less = methodName.substring(3);
return first.toLowerCase() + less; return first.toLowerCase() + less;
} }
if(methodName.startsWith("get") && methodName.length()>3){ if (methodName.startsWith("get") && methodName.length() > 3) {
String first = methodName.substring(3, 4); String first = methodName.substring(3, 4);
String less = methodName.substring(4); String less = methodName.substring(4);
return first.toLowerCase() + less; return first.toLowerCase() + less;
...@@ -27,12 +38,45 @@ public class FieldHelper { ...@@ -27,12 +38,45 @@ public class FieldHelper {
return null; return null;
} }
public static Optional<Expression> getInitializer(ResolvedFieldDeclaration declaredField){ /**
if(declaredField instanceof JavaParserFieldDeclaration){ * Get initializer optional.
*
* @param declaredField the declared field
* @return the optional
*/
public static Optional<Expression> getInitializer(ResolvedFieldDeclaration declaredField) {
if (declaredField instanceof JavaParserFieldDeclaration) {
JavaParserFieldDeclaration field = (JavaParserFieldDeclaration) declaredField; JavaParserFieldDeclaration field = (JavaParserFieldDeclaration) declaredField;
return field.getVariableDeclarator().getInitializer(); return field.getVariableDeclarator().getInitializer();
} }
return Optional.empty(); return Optional.empty();
} }
/**
* 获取常量
*
* @param declaration the declaration
* @return constants
*/
public static List<Cell<String>> getConstants(ClassOrInterfaceDeclaration declaration) {
List<Cell<String>> cells = new ArrayList<>();
for (FieldDeclaration field : declaration.getFields()) {
if (field.isStatic() && field.isPublic() && field.isFinal()) {
VariableDeclarator variable = field.getVariable(0);
String value = null;
String description = null;
if (variable.getInitializer().isPresent()) {
value = String.valueOf(ExpressionHelper.getValue(variable.getInitializer().get()));
}
if (field.getComment().isPresent()) {
description = CommentHelper.getContent(field.getComment().get());
}
cells.add(new Cell<>(variable.getNameAsString(), value, description));
}
}
return cells;
}
} }
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -32,10 +32,10 @@ public class FileHelper { ...@@ -32,10 +32,10 @@ public class FileHelper {
} }
} }
public static List<Path> find(Path start, String structure){ public static List<Path> find(Path start, String structure) {
try { try {
return Files.walk(start) return Files.walk(start)
.filter(p->p.endsWith(structure)).collect(Collectors.toList()); .filter(p -> p.endsWith(structure)).collect(Collectors.toList());
} catch (IOException e) { } catch (IOException e) {
log.warn("find path error:{} {}", start, e.getMessage()); log.warn("find path error:{} {}", start, e.getMessage());
} }
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.expr.AnnotationExpr;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import java.util.Optional; import java.util.Optional;
public class OptionalHelper { public class OptionalHelper {
@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) {
if(optional.isPresent()){ if (optional.isPresent()) {
return optional; return optional;
} }
} }
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.google.common.base.Strings; import com.google.common.base.Strings;
...@@ -13,26 +13,26 @@ public class StringHelper { ...@@ -13,26 +13,26 @@ public class StringHelper {
} }
public static boolean isBlank(Object text) { public static boolean isBlank(Object text) {
if(text instanceof String){ if (text instanceof String) {
return isBlank(((String) text)); return isBlank(((String) text));
} }
return isBlank(String.valueOf(text)); return isBlank(String.valueOf(text));
} }
public static boolean nonBlank(Object text) { public static boolean nonBlank(Object text) {
if(text instanceof String){ if (text instanceof String) {
return nonBlank(((String) text)); return nonBlank(((String) text));
} }
return nonBlank(String.valueOf(text)); return nonBlank(String.valueOf(text));
} }
public static String join(String delimiter, String ... values){ public static String join(String delimiter, String... values) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (String value : values) { for (String value : values) {
if(isBlank(value)){ if (isBlank(value)) {
continue; continue;
} }
if(builder.length()>0){ if (builder.length() > 0) {
builder.append(delimiter); builder.append(delimiter);
} }
builder.append(value); builder.append(value);
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.ImportDeclaration;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedReferenceType;
......
package kim.apidoc.core.common.helper; package com.kim.apidoc.core.common.helper;
import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.expr.AnnotationExpr;
......
package kim.apidoc.core.common.markup; package com.kim.apidoc.core.common.markup;
import kim.apidoc.core.common.markup.asciidoc.AsciiDocBuilder; import com.kim.apidoc.core.common.markup.asciidoc.AsciiDocBuilder;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
......
package kim.apidoc.core.common.markup.asciidoc; package com.kim.apidoc.core.common.markup.asciidoc;
public enum AsciiDoc implements CharSequence { public enum AsciiDoc implements CharSequence {
EXTENSION(".adoc"), EXTENSION(".adoc"),
......
package kim.apidoc.core.common.markup.asciidoc; package com.kim.apidoc.core.common.markup.asciidoc;
import kim.apidoc.core.common.Assert; import com.kim.apidoc.core.common.markup.MarkupBuilder;
import kim.apidoc.core.common.markup.MarkupBuilder; import com.kim.apidoc.core.common.Assert;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import java.util.List; import java.util.List;
......
package kim.apidoc.core.common.markup.asciidoc; package com.kim.apidoc.core.common.markup.asciidoc;
/** /**
* https://en.wikipedia.org/wiki/Web_colors#HTML_color_names * https://en.wikipedia.org/wiki/Web_colors#HTML_color_names
......
package kim.apidoc.core.common.markup.markdown; package com.kim.apidoc.core.common.markup.markdown;
public enum Markdown implements CharSequence { public enum Markdown implements CharSequence {
EXTENSION(".md"), EXTENSION(".md"),
......
package kim.apidoc.core.common.markup.markdown; package com.kim.apidoc.core.common.markup.markdown;
import kim.apidoc.core.common.Assert; import com.kim.apidoc.core.common.markup.MarkupBuilder;
import kim.apidoc.core.common.markup.MarkupBuilder; import com.kim.apidoc.core.common.Assert;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import java.util.List; import java.util.List;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
/** /**
* 对应postman定义的mode * 对应postman定义的mode
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter; import lombok.Getter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import kim.apidoc.core.schema.Row; import com.kim.apidoc.core.schema.Row;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import kim.apidoc.core.schema.Header; import com.kim.apidoc.core.schema.Header;
import kim.apidoc.core.schema.Method; import com.kim.apidoc.core.schema.Method;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import kim.apidoc.core.schema.Header; import com.kim.apidoc.core.schema.Header;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.common.postman; package com.kim.apidoc.core.common.postman;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.parser; package com.kim.apidoc.core.parser;
import kim.apidoc.core.schema.Chapter; import com.kim.apidoc.core.schema.Chapter;
import kim.apidoc.core.schema.Section; import com.kim.apidoc.core.schema.Section;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.MethodDeclaration;
......
package kim.apidoc.core.parser; package com.kim.apidoc.core.parser;
import kim.apidoc.core.common.helper.OptionalHelper;
import kim.apidoc.core.schema.Chapter;
import kim.apidoc.core.schema.Node;
import kim.apidoc.core.schema.Project;
import kim.apidoc.core.schema.Section;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.EnumDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.kim.apidoc.core.ApiDoc;
import com.kim.apidoc.core.common.helper.OptionalHelper;
import com.kim.apidoc.core.schema.*;
/** /**
* The type Visitor parser. * The type Visitor parser.
...@@ -28,15 +29,33 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -28,15 +29,33 @@ 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);
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) {
if (arg instanceof Project) {
if (arg instanceof Project && parserStrategy.accept(classOrInterfaceDeclaration)) {
Project project = (Project) arg; Project project = (Project) arg;
// 章节 // 章节
Chapter chapter = new Chapter(); Chapter chapter = new Chapter();
...@@ -44,17 +63,55 @@ public class VisitorParser extends VoidVisitorAdapter<Node> { ...@@ -44,17 +63,55 @@ public class VisitorParser extends VoidVisitorAdapter<Node> {
chapter.setName(classOrInterfaceDeclaration.getNameAsString()); chapter.setName(classOrInterfaceDeclaration.getNameAsString());
classOrInterfaceDeclaration.getComment().ifPresent(chapter::accept); classOrInterfaceDeclaration.getComment().ifPresent(chapter::accept);
OptionalHelper.any(chapter.getTag("book"),chapter.getTag("group")) OptionalHelper.any(chapter.getTag("book"), chapter.getTag("group"))
.ifPresent(tag -> chapter.setBookName(tag.getContent())); .ifPresent(tag -> chapter.setBookName(tag.getContent()));
if (parserStrategy.accept(classOrInterfaceDeclaration)) {
parserStrategy.visit(classOrInterfaceDeclaration, chapter); parserStrategy.visit(classOrInterfaceDeclaration, chapter);
project.addChapter(chapter); project.addChapter(chapter);
}
super.visit(classOrInterfaceDeclaration, chapter); super.visit(classOrInterfaceDeclaration, chapter);
} }
} }
@Override
public void visit(JavadocComment javadocComment, Node arg) {
if (arg instanceof Chapter) {
Chapter chapter = (Chapter) arg;
OptionalHelper.any(chapter.getTag("code"))
.ifPresent(tag -> {
if (javadocComment.getCommentedNode().isPresent()) {
com.github.javaparser.ast.Node commentedNode = javadocComment.getCommentedNode().get();
// 常量类||枚举类
if (commentedNode instanceof ClassOrInterfaceDeclaration
|| commentedNode instanceof EnumDeclaration) {
Appendix appendix = Appendix.parse(javadocComment);
if (appendix != null) {
ApiDoc.getInstance().getProject().getAppendices().add(appendix);
}
}
}
});
OptionalHelper.any(chapter.getTag("resultData"))
.ifPresent(tag -> {
if (javadocComment.getCommentedNode().isPresent()) {
com.github.javaparser.ast.Node commentedNode = javadocComment.getCommentedNode().get();
// 常量类||枚举类
if (commentedNode instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) commentedNode;
ApiDoc.getInstance().getProject().setResultDataClassOrInterfaceDeclaration(classOrInterfaceDeclaration);
}
}
});
}
super.visit(javadocComment, arg);
}
/** /**
* 方法声明 * 方法声明
*
* @param methodDeclaration * @param methodDeclaration
* @param arg * @param arg
*/ */
......
package kim.apidoc.core.render; package com.kim.apidoc.core.render;
import kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.helper.FileHelper;
import kim.apidoc.core.common.helper.StringHelper;
import kim.apidoc.core.common.markup.MarkupBuilder;
import kim.apidoc.core.common.markup.asciidoc.AsciiDoc;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import kim.apidoc.core.schema.*; import com.kim.apidoc.core.ApiDoc;
import com.kim.apidoc.core.common.helper.FileHelper;
import com.kim.apidoc.core.common.helper.StringHelper;
import com.kim.apidoc.core.common.markup.MarkupBuilder;
import com.kim.apidoc.core.common.markup.asciidoc.AsciiDoc;
import com.kim.apidoc.core.schema.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.asciidoctor.Asciidoctor; import org.asciidoctor.Asciidoctor;
import org.asciidoctor.AttributesBuilder; import org.asciidoctor.AttributesBuilder;
...@@ -46,7 +46,7 @@ public class AsciiDocRender implements ProjectRender { ...@@ -46,7 +46,7 @@ public class AsciiDocRender implements ProjectRender {
project.getBooks().forEach((name, book) -> { project.getBooks().forEach((name, book) -> {
MarkupBuilder builder = MarkupBuilder.getInstance(); MarkupBuilder builder = MarkupBuilder.getInstance();
String displayName = project.getName(); String displayName = project.getName();
if(!Objects.equals(Book.DEFAULT, name)){ if (!Objects.equals(Book.DEFAULT, name)) {
displayName += " - " + name; displayName += " - " + name;
} }
builder.header(displayName, attrs); builder.header(displayName, attrs);
...@@ -61,7 +61,7 @@ public class AsciiDocRender implements ProjectRender { ...@@ -61,7 +61,7 @@ public class AsciiDocRender implements ProjectRender {
builder.title(1, chapter.getName()); builder.title(1, chapter.getName());
builder.paragraph(chapter.getDescription()); builder.paragraph(chapter.getDescription());
for (Section section : chapter.getSections()) { for (Section section : chapter.getSections()) {
if(section.isIgnore()){ if (section.isIgnore()) {
continue; continue;
} }
builder.title(2, section.getName()); builder.title(2, section.getName());
...@@ -71,7 +71,7 @@ public class AsciiDocRender implements ProjectRender { ...@@ -71,7 +71,7 @@ public class AsciiDocRender implements ProjectRender {
builder.title(4, "request"); builder.title(4, "request");
builder.listing(b -> { builder.listing(b -> {
b.textLine(section.getRequestLine()); b.textLine(section.getRequestLine());
section.getInHeaders().values().forEach(header->builder.textLine(header.toString())); section.getInHeaders().values().forEach(header -> builder.textLine(header.toString()));
if (section.hasRequestBody()) { if (section.hasRequestBody()) {
b.br(); b.br();
b.text(section.getParameterString()); b.text(section.getParameterString());
...@@ -87,7 +87,7 @@ public class AsciiDocRender implements ProjectRender { ...@@ -87,7 +87,7 @@ public class AsciiDocRender implements ProjectRender {
if (section.hasResponseBody()) { if (section.hasResponseBody()) {
b.br(); b.br();
b.text(section.getResponseString()); b.text(section.getResponseString());
}else{ } else {
b.text("N/A"); b.text("N/A");
} }
}, "source,JSON"); }, "source,JSON");
......
package com.kim.apidoc.core.render;
import com.kim.apidoc.core.ApiDoc;
import com.kim.apidoc.core.common.Constants;
import com.kim.apidoc.core.common.ObjectMappers;
import com.kim.apidoc.core.common.helper.FileHelper;
import com.kim.apidoc.core.schema.Project;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.nio.file.Path;
/**
* 生成markdown api文档
*
* @author duanledexianxianxian
* @version 1.0.0
* @date 2020 /3/26 19:03
* @since 1.0.0
*/
@Slf4j
public class MarkdownRender implements ProjectRender {
private Configuration configuration;
public MarkdownRender init() {
configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding(Constants.UTF8);
configuration.setClassForTemplateLoading(MarkdownRender.class, Constants.SLASH);
return this;
}
@Override
public void render(Project project) {
this.init();
try {
this.build(project);
} catch (Exception e) {
log.error("Build Markdown Fail {}", e.getMessage());
}
}
private void build(Project project) throws Exception {
String templatePath = ApiDoc.getInstance().getContext().getMarkdownTemplate();
String id = ApiDoc.getInstance().getContext().getId();
Path buildPath = ApiDoc.getInstance().getContext().getBuildPath();
Path markdownFile = buildPath.resolve(id).resolve(id + Constants.MARKDOWN_EXTENSION);
Template template = configuration.getTemplate(templatePath);
StringWriter writer = new StringWriter();
template.process(project, writer);
writer.flush();
writer.close();
FileHelper.write(markdownFile, writer.getBuffer().toString());
log.info("Build Markdown {}", markdownFile);
}
}
package kim.apidoc.core.render; package com.kim.apidoc.core.render;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.ObjectMappers; import com.kim.apidoc.core.common.ObjectMappers;
import kim.apidoc.core.common.helper.FileHelper; import com.kim.apidoc.core.common.helper.FileHelper;
import kim.apidoc.core.common.postman.*; import com.kim.apidoc.core.common.postman.*;
import kim.apidoc.core.schema.*; import com.kim.apidoc.core.schema.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.nio.file.Path; import java.nio.file.Path;
...@@ -38,14 +38,14 @@ public class PostmanRender implements ProjectRender { ...@@ -38,14 +38,14 @@ public class PostmanRender implements ProjectRender {
Folder folder = new Folder(); Folder folder = new Folder();
folder.setName(book.getId()); folder.setName(book.getId());
for (Chapter chapter : book.getChapters()) { for (Chapter chapter : book.getChapters()) {
if(chapter.isIgnore() || chapter.getSections().isEmpty()){ if (chapter.isIgnore() || chapter.getSections().isEmpty()) {
continue; continue;
} }
Folder chapterFolder = new Folder(); Folder chapterFolder = new Folder();
chapterFolder.setName(chapter.getName()); chapterFolder.setName(chapter.getName());
chapterFolder.setDescription(chapter.getDescription()); chapterFolder.setDescription(chapter.getDescription());
for (Section section : chapter.getSections()) { for (Section section : chapter.getSections()) {
if(section.isIgnore()){ if (section.isIgnore()) {
continue; continue;
} }
chapterFolder.getItem().add(build(section)); chapterFolder.getItem().add(build(section));
...@@ -55,7 +55,7 @@ public class PostmanRender implements ProjectRender { ...@@ -55,7 +55,7 @@ public class PostmanRender implements ProjectRender {
postman.getItem().add(folder); postman.getItem().add(folder);
} }
if(postman.getItem().size()==1){ if (postman.getItem().size() == 1) {
Folder folder = postman.getItem().get(0); Folder folder = postman.getItem().get(0);
postman.setItem(folder.getItem()); postman.setItem(folder.getItem());
} }
...@@ -74,18 +74,18 @@ public class PostmanRender implements ProjectRender { ...@@ -74,18 +74,18 @@ public class PostmanRender implements ProjectRender {
request.setMethod(section.getMethod()); request.setMethod(section.getMethod());
request.getHeaders().addAll(section.getInHeaders().values()); request.getHeaders().addAll(section.getInHeaders().values());
if(section.isQueryParameter()){ if (section.isQueryParameter()) {
if(Method.GET.equals(request.getMethod())){ if (Method.GET.equals(request.getMethod())) {
ObjectNode objectNode = (ObjectNode)section.getParameter(); ObjectNode objectNode = (ObjectNode) section.getParameter();
for (String key : section.getRequestRows().keySet()) { for (String key : section.getRequestRows().keySet()) {
if (objectNode.has(key)) { if (objectNode.has(key)) {
Row row = section.getRequestRows().get(key); Row row = section.getRequestRows().get(key);
request.getUrl().getQuery().add(Parameter.of(row)); request.getUrl().getQuery().add(Parameter.of(row));
} }
} }
}else{ } else {
request.getBody().setMode(BodyMode.urlencoded); request.getBody().setMode(BodyMode.urlencoded);
ObjectNode objectNode = (ObjectNode)section.getParameter(); ObjectNode objectNode = (ObjectNode) section.getParameter();
for (String key : section.getRequestRows().keySet()) { for (String key : section.getRequestRows().keySet()) {
if (objectNode.has(key)) { if (objectNode.has(key)) {
Row row = section.getRequestRows().get(key); Row row = section.getRequestRows().get(key);
...@@ -93,7 +93,7 @@ public class PostmanRender implements ProjectRender { ...@@ -93,7 +93,7 @@ public class PostmanRender implements ProjectRender {
} }
} }
} }
}else{ } else {
request.getBody().setMode(BodyMode.raw); request.getBody().setMode(BodyMode.raw);
request.getBody().setRaw(section.getParameterString()); request.getBody().setRaw(section.getParameterString());
} }
......
package kim.apidoc.core.render; package com.kim.apidoc.core.render;
import kim.apidoc.core.schema.Project; import com.kim.apidoc.core.schema.Project;
/** /**
* The interface Project render. * The interface Project render.
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.ArrayTypeDescription; import com.kim.apidoc.core.common.description.ArrayTypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
public class ArrayTypeResolver implements TypeResolver { public class ArrayTypeResolver implements TypeResolver {
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.helper.TypeParameterHelper; import com.kim.apidoc.core.common.helper.TypeParameterHelper;
import kim.apidoc.core.common.description.ArrayTypeDescription; import com.kim.apidoc.core.common.description.ArrayTypeDescription;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.UnAvailableTypeDescription; import com.kim.apidoc.core.common.description.UnAvailableTypeDescription;
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;
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.StringTypeDescription; import com.kim.apidoc.core.common.description.StringTypeDescription;
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;
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.StringTypeDescription; import com.kim.apidoc.core.common.description.StringTypeDescription;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
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.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.UnAvailableTypeDescription; import com.kim.apidoc.core.common.description.UnAvailableTypeDescription;
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;
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
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;
import kim.apidoc.core.ApiDoc; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import kim.apidoc.core.common.description.ObjectTypeDescription; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.ObjectTypeDescription;
import kim.apidoc.core.common.helper.*; import com.kim.apidoc.core.common.description.TypeDescription;
import com.kim.apidoc.core.common.helper.*;
import java.util.Optional; import java.util.Optional;
...@@ -27,15 +28,16 @@ public class ObjectTypeResolver implements TypeResolver { ...@@ -27,15 +28,16 @@ public class ObjectTypeResolver implements TypeResolver {
ObjectTypeDescription typeDescription = new ObjectTypeDescription(); ObjectTypeDescription typeDescription = new ObjectTypeDescription();
typeDescription.setType(referenceType.getTypeDeclaration().getName()); typeDescription.setType(referenceType.getTypeDeclaration().getName());
((JavaParserClassDeclaration) referenceType.getTypeDeclaration()).getWrappedNode().getComment().ifPresent(typeDescription::accept);
//类型解析缓冲池,防止循环引用 //类型解析缓冲池,防止循环引用
if(!ReferenceContext.getInstance().push(referenceType.describe())){ if (!ReferenceContext.getInstance().push(referenceType.describe())) {
return typeDescription; return typeDescription;
} }
//解析父类属性,并合并至当前 //解析父类属性,并合并至当前
for (ResolvedReferenceType directAncestor : referenceType.getDirectAncestors()) { for (ResolvedReferenceType directAncestor : referenceType.getDirectAncestors()) {
TypeDescription ancestorDescription = ApiDoc.getInstance().getTypeResolvers().resolve(directAncestor); TypeDescription ancestorDescription = ApiDoc.getInstance().getTypeResolvers().resolve(directAncestor);
if(ancestorDescription.isAvailable() && ancestorDescription.isObject()){ if (ancestorDescription.isAvailable() && ancestorDescription.isObject()) {
typeDescription.merge(ancestorDescription.asObject()); typeDescription.merge(ancestorDescription.asObject());
} }
} }
...@@ -43,19 +45,19 @@ public class ObjectTypeResolver implements TypeResolver { ...@@ -43,19 +45,19 @@ public class ObjectTypeResolver implements TypeResolver {
//TODO fix use access method //TODO fix use access method
for (ResolvedFieldDeclaration declaredField : referenceType.getTypeDeclaration().getDeclaredFields()) { for (ResolvedFieldDeclaration declaredField : referenceType.getTypeDeclaration().getDeclaredFields()) {
if(declaredField.isStatic()){ if (declaredField.isStatic()) {
continue; continue;
} }
ResolvedType fieldType = declaredField.getType(); ResolvedType fieldType = declaredField.getType();
if(fieldType.isReferenceType()){ if (fieldType.isReferenceType()) {
//将父类的T,传递给 属性的T //将父类的T,传递给 属性的T
fieldType = TypeParameterHelper.useClassTypeParameter(referenceType,fieldType.asReferenceType()); fieldType = TypeParameterHelper.useClassTypeParameter(referenceType, fieldType.asReferenceType());
} }
if(declaredField.getType().isTypeVariable()){ if (declaredField.getType().isTypeVariable()) {
//类型为T,这种泛型 //类型为T,这种泛型
Optional<ResolvedType> optional = TypeParameterHelper.getTypeParameter(referenceType, declaredField.getType().asTypeParameter().getName()); Optional<ResolvedType> optional = TypeParameterHelper.getTypeParameter(referenceType, declaredField.getType().asTypeParameter().getName());
if(optional.isPresent()){ if (optional.isPresent()) {
fieldType = optional.get(); fieldType = optional.get();
} }
} }
...@@ -71,7 +73,7 @@ public class ObjectTypeResolver implements TypeResolver { ...@@ -71,7 +73,7 @@ public class ObjectTypeResolver implements TypeResolver {
fieldDescription.getCondition().append(validation).append(" "); fieldDescription.getCondition().append(validation).append(" ");
} }
//查找字段初始化值 //查找字段初始化值
FieldHelper.getInitializer(declaredField).ifPresent(expr-> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr))); FieldHelper.getInitializer(declaredField).ifPresent(expr -> fieldDescription.setDefaultValue(ExpressionHelper.getValue(expr)));
typeDescription.add(fieldDescription); typeDescription.add(fieldDescription);
} }
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.PrimitiveTypeDescription; import com.kim.apidoc.core.common.description.PrimitiveTypeDescription;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.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;
public class PrimitiveTypeResolver implements TypeResolver { public class PrimitiveTypeResolver implements TypeResolver {
@Override private static boolean isBoxing(ResolvedType type) {
public boolean accept(ResolvedType type) { if (!type.isReferenceType()) {
return type.isPrimitive() || isBoxing(type);
}
@Override
public TypeDescription resolve(ResolvedType type) {
if(type.isPrimitive()){
return new PrimitiveTypeDescription(type.asPrimitive());
}else{
return new PrimitiveTypeDescription(type.asReferenceType());
}
}
private static boolean isBoxing(ResolvedType type){
if(!type.isReferenceType()){
return false; return false;
} }
String id = type.asReferenceType().getId(); String id = type.asReferenceType().getId();
...@@ -37,4 +23,18 @@ public class PrimitiveTypeResolver implements TypeResolver { ...@@ -37,4 +23,18 @@ public class PrimitiveTypeResolver implements TypeResolver {
).contains(id); ).contains(id);
} }
@Override
public boolean accept(ResolvedType type) {
return type.isPrimitive() || isBoxing(type);
}
@Override
public TypeDescription resolve(ResolvedType type) {
if (type.isPrimitive()) {
return new PrimitiveTypeDescription(type.asPrimitive());
} else {
return new PrimitiveTypeDescription(type.asReferenceType());
}
}
} }
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.StringTypeDescription; import com.kim.apidoc.core.common.description.StringTypeDescription;
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;
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.UnAvailableTypeDescription; import com.kim.apidoc.core.common.description.UnAvailableTypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
public class SystemObjectTypeResolver implements TypeResolver { public class SystemObjectTypeResolver implements TypeResolver {
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.Type;
public interface TypeNameResolver { public interface TypeNameResolver {
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
public interface TypeResolver { public interface TypeResolver {
......
package kim.apidoc.core.resolver; package com.kim.apidoc.core.resolver;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.helper.TypeNameHelper; import com.kim.apidoc.core.common.helper.TypeNameHelper;
import kim.apidoc.core.common.description.UnAvailableTypeDescription; import com.kim.apidoc.core.common.description.UnAvailableTypeDescription;
import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.Type;
import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.UnsolvedSymbolException;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
...@@ -34,55 +34,57 @@ public class TypeResolvers { ...@@ -34,55 +34,57 @@ public class TypeResolvers {
/** /**
* 获取类型信息 * 获取类型信息
*
* @param type * @param type
* @return * @return
*/ */
public TypeDescription resolve(Type type){ public TypeDescription resolve(Type type) {
try{ try {
ResolvedType resolvedType = type.resolve(); ResolvedType resolvedType = type.resolve();
return resolve(resolvedType); return resolve(resolvedType);
} catch (UnsolvedSymbolException e){ } catch (UnsolvedSymbolException e) {
//解析失败时,尝试降级,使用名称解析 //解析失败时,尝试降级,使用名称解析
return nameResolve(type); return nameResolve(type);
} catch (Exception e){ } catch (Exception e) {
log.error(e.getMessage(),e); log.error(e.getMessage(), e);
} }
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
/** /**
* 解析类型信息 * 解析类型信息
*
* @param type * @param type
* @return * @return
*/ */
public TypeDescription resolve(ResolvedType type){ public TypeDescription resolve(ResolvedType type) {
for (TypeResolver typeResolver : resolvers) { for (TypeResolver typeResolver : resolvers) {
if(typeResolver.accept(type)){ if (typeResolver.accept(type)) {
return typeResolver.resolve(type); return typeResolver.resolve(type);
} }
} }
if(objectTypeResolver.accept(type)){ if (objectTypeResolver.accept(type)) {
return objectTypeResolver.resolve(type); return objectTypeResolver.resolve(type);
} }
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
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) {
if (nameResolver.accept(id)) { if (nameResolver.accept(id)) {
return nameResolver.resolve(type); return nameResolver.resolve(type);
} }
} }
log.warn("type({}) resolve failed",id); log.warn("type({}) resolve failed", id);
return new UnAvailableTypeDescription(); return new UnAvailableTypeDescription();
} }
public void addResolver(TypeResolver typeResolver){ public void addResolver(TypeResolver typeResolver) {
resolvers.add(typeResolver); resolvers.add(typeResolver);
} }
public void addNameResolver(TypeNameResolver nameResolver){ public void addNameResolver(TypeNameResolver nameResolver) {
nameResolvers.add(nameResolver); nameResolvers.add(nameResolver);
} }
......
package com.kim.apidoc.core.schema;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
import com.kim.apidoc.core.common.helper.EnumHelper;
import com.kim.apidoc.core.common.helper.FieldHelper;
import com.kim.apidoc.core.common.helper.FileHelper;
import lombok.Getter;
import lombok.Setter;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* 附录
*/
@Setter
@Getter
public class Appendix extends Node {
/**
* The Cells.
*/
List<Cell<String>> cells = new ArrayList<>();
/**
* Is empty boolean.
*
* @return the boolean
*/
public boolean isEmpty() {
return cells.isEmpty();
}
/**
* Parse appendix.
*
* @param n the n
* @return the appendix
*/
@Nullable
public static Appendix parse(JavadocComment n) {
if (!n.getCommentedNode().isPresent()) {
return null;
}
final com.github.javaparser.ast.Node node = n.getCommentedNode().get();
if (!(node instanceof BodyDeclaration)) {
return null;
}
final BodyDeclaration bodyDeclaration = (BodyDeclaration) node;
// 不是枚举且不是类
if (!bodyDeclaration.isEnumDeclaration() && !bodyDeclaration.isClassOrInterfaceDeclaration()) {
return null;
}
Appendix appendix = new Appendix();
// 是枚举
if (bodyDeclaration.isEnumDeclaration()) {
appendix.getCells().addAll(EnumHelper.toDetails(bodyDeclaration.asEnumDeclaration()));
} else if (bodyDeclaration.isClassOrInterfaceDeclaration()) {
// 常量类
appendix.getCells().addAll(FieldHelper.getConstants(bodyDeclaration.asClassOrInterfaceDeclaration()));
}
if (node instanceof NodeWithSimpleName) {
appendix.setName(((NodeWithSimpleName) node).getNameAsString());
}
if (node.getComment().isPresent()) {
appendix.accept(node.getComment().get());
}
return appendix;
}
}
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package com.kim.apidoc.core.schema;
import com.google.common.collect.Lists;
import java.util.List;
/**
* 多个数据的组合
*
* @param <T> the type parameter
*/
public class Cell<T> {
/**
* The Values.
*/
private List<T> values;
/**
* The Enable.
*/
private boolean enable;
/**
* Instantiates a new Cell.
*
* @param values the values
*/
@SafeVarargs
public Cell(T ... values) {
this(true,values);
}
/**
* Instantiates a new Cell.
*
* @param enable the enable
* @param values the values
*/
@SafeVarargs
public Cell(boolean enable, T ... values) {
this(enable, Lists.newArrayList(values));
}
/**
* Instantiates a new Cell.
*
* @param enable the enable
* @param values the values
*/
public Cell(boolean enable, List<T> values) {
this.values = values;
this.enable = enable;
}
/**
* To list list.
*
* @return the list
*/
public List<T> toList(){
return values;
}
/**
* Is enable boolean.
*
* @return the boolean
*/
public boolean isEnable() {
return enable;
}
/**
* Add.
*
* @param value the value
*/
public void add(T value){
values.add(value);
}
/**
* Size int.
*
* @return the int
*/
public int size(){
return values.size();
}
/**
* Set.
*
* @param index the index
* @param t the t
*/
public void set(int index, T t){
values.set(index, t);
}
/**
* Get t.
*
* @param index the index
* @return the t
*/
public T get(int index){
return values.get(index);
}
/**
* Duplicate cell.
*
* @return the cell
*/
public Cell<T> duplicate(){
return new Cell<>(isEnable(), Lists.newArrayList(values));
}
/**
* Sets enable.
*
* @param enable the enable
*/
public void setEnable(boolean enable) {
this.enable = enable;
}
}
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -15,12 +15,13 @@ import java.util.TreeSet; ...@@ -15,12 +15,13 @@ import java.util.TreeSet;
@Setter @Setter
@Getter @Getter
public class Chapter extends Node { public class Chapter extends Node {
/** /**
* The Book name. * The Book name.
*/ */
String bookName; String bookName;
Project project;
/** /**
* The Sections. * The Sections.
*/ */
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import kim.apidoc.core.Context;
import kim.apidoc.core.common.helper.CommentHelper;
import kim.apidoc.core.common.helper.StringHelper;
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.kim.apidoc.core.Context;
import com.kim.apidoc.core.common.helper.CommentHelper;
import com.kim.apidoc.core.common.helper.StringHelper;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -22,7 +22,10 @@ import java.util.Optional; ...@@ -22,7 +22,10 @@ import java.util.Optional;
@Setter @Setter
@Getter @Getter
public class Node implements Comparable<Node> { public class Node implements Comparable<Node> {
/**
* 节点类型
*/
String type;
/** /**
* 节点编号 * 节点编号
*/ */
...@@ -52,6 +55,9 @@ public class Node implements Comparable<Node> { ...@@ -52,6 +55,9 @@ public class Node implements Comparable<Node> {
@Override @Override
public int compareTo(@Nonnull Node other) { public int compareTo(@Nonnull Node other) {
if (this.type != null && other.type != null) {
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;
} }
...@@ -120,7 +126,7 @@ public class Node implements Comparable<Node> { ...@@ -120,7 +126,7 @@ public class Node implements Comparable<Node> {
* @return the param tag * @return the param tag
*/ */
public Optional<Tag> getParamTag(String id) { public Optional<Tag> getParamTag(String id) {
return Optional.ofNullable(tags.get("param:"+id)); return Optional.ofNullable(tags.get("param:" + id));
} }
/** /**
...@@ -130,7 +136,7 @@ public class Node implements Comparable<Node> { ...@@ -130,7 +136,7 @@ public class Node implements Comparable<Node> {
*/ */
public void putTag(Tag tag) { public void putTag(Tag tag) {
String id = tag.id; String id = tag.id;
if(StringHelper.nonBlank(tag.getKey())){ if (StringHelper.nonBlank(tag.getKey())) {
id += ":" + tag.getKey(); id += ":" + tag.getKey();
} }
tags.put(id, tag); tags.put(id, tag);
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.*; import java.util.*;
/** /**
* 项目 * 项目
* *
...@@ -25,12 +27,22 @@ public class Project extends Node { ...@@ -25,12 +27,22 @@ public class Project extends Node {
*/ */
Map<String, Book> books = new TreeMap<>(); Map<String, Book> books = new TreeMap<>();
/**
* 附录
*/
List<Appendix> appendices = new LinkedList<>();
/**
* 统一结果
*/
ClassOrInterfaceDeclaration resultDataClassOrInterfaceDeclaration;
/** /**
* Add chapter. * Add chapter.
* *
* @param chapter the chapter * @param chapter the chapter
*/ */
public void addChapter(Chapter chapter) { public void addChapter(Chapter chapter) {
chapter.setProject(this);
if (Objects.isNull(chapter.getBookName())) { if (Objects.isNull(chapter.getBookName())) {
chapter.setBookName(Book.DEFAULT); chapter.setBookName(Book.DEFAULT);
} }
......
package com.kim.apidoc.core.schema;
/**
* 请求参数枚举类型
*
* @author duanledexianxianxian
* @date 2020 /3/29 0:37
* @since 1.0.0
*/
public enum RequestParameterType {
/**
* 查询参数.
*/
QUERY,
/**
* 路径参数.
*/
PATH,
/**
* 请求参数体.
*/
BODY
}
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.*; import lombok.*;
...@@ -23,19 +23,29 @@ public class Row { ...@@ -23,19 +23,29 @@ public class Row {
* The Type. * The Type.
*/ */
String type; String type;
/**
* 是否必填.
*/
Boolean required;
/** /**
* The Condition. * The Condition.
*/ */
String condition; String condition;
/** /**
* The Def. * 默认值.
*/ */
String def; String def;
/** /**
* The Remark. * 说明.
*/ */
String remark; String remark;
/**
* 请求参数类型
*/
String requestParameterType;
/** /**
* Instantiates a new Row. * Instantiates a new Row.
* *
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import kim.apidoc.core.common.ObjectMappers; import com.kim.apidoc.core.common.ObjectMappers;
import kim.apidoc.core.common.QueryStringBuilder; import com.kim.apidoc.core.common.QueryStringBuilder;
import kim.apidoc.core.common.helper.StringHelper; import com.kim.apidoc.core.common.helper.StringHelper;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter; import lombok.Getter;
...@@ -21,19 +21,19 @@ import java.util.*; ...@@ -21,19 +21,19 @@ import java.util.*;
public class Section extends Node { public class Section extends Node {
/** /**
* The Method. * 请求方法.
*/ */
Method method; Method method;
/** /**
* The Uri. * 请求url.
*/ */
String uri; String uri;
/** /**
* The In headers. * 请求头.
*/ */
Map<String, Header> inHeaders = new LinkedHashMap<>(); Map<String, Header> inHeaders = new LinkedHashMap<>();
/** /**
* The Path variable. * 路径变量.
*/ */
ObjectNode pathVariable = ObjectMappers.instance.createObjectNode(); ObjectNode pathVariable = ObjectMappers.instance.createObjectNode();
/** /**
...@@ -44,6 +44,7 @@ public class Section extends Node { ...@@ -44,6 +44,7 @@ public class Section extends Node {
* The Query parameter. * The Query parameter.
*/ */
boolean queryParameter = true; boolean queryParameter = true;
/** /**
* The Request rows. * The Request rows.
*/ */
...@@ -66,6 +67,7 @@ public class Section extends Node { ...@@ -66,6 +67,7 @@ public class Section extends Node {
*/ */
Object rawResponse; Object rawResponse;
/** /**
* Add request row. * Add request row.
* *
......
package kim.apidoc.core.schema; package com.kim.apidoc.core.schema;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
......
package kim.apidoc.core.render;
import kim.apidoc.core.schema.Project;
/**
* 生成markdown api文档
*
* @author duanledexianxianxian
* @version 1.0.0
* @date 2020 /3/26 19:03
* @since 1.0.0
*/
public class MarkdownRender implements ProjectRender {
@Override
public void render(Project project) {
}
}
[TOC]
<#-- ---------- BEGIN 循环遍历book ---------->
<#if books??>
<#list books as bookKey,bookValue>
<#if bookValue.name??>
<#--book名称-->
# ${bookValue.name}
</#if>
<#-- ---------- BEGIN 循环遍历chapter ---------->
<#assign chapterIndex=0>
<#list bookValue.chapters as chapter>
<#if !chapter.isIgnore()>
<#assign chapterIndex++>
<#-- 章节名称-->
## ${chapterIndex}. ${chapter.name}
<#-- 章节描述-->
<#if chapter.description??>
${chapter.description}
</#if>
<#-- ---------- BEGIN 循环遍历section ---------->
<#assign sectionIndex=0>
<#list chapter.sections as section>
<#if !section.isIgnore()>
<#assign sectionIndex++/>
<#-- 接口名称-->
### ${chapterIndex}.${sectionIndex} ${section.name}
<#-- 接口描述-->
<#if section.description??>
${section.description}
</#if>
<#-- 请求-->
**请求**
<#-- 请求示例-->
```HTTP
${section.method} ${section.uri!''} HTTP/1.1
<#if section.inHeaders??>
<#list section.inHeaders as inHeaderKey,inHeaderValue>
${inHeaderValue!''}
</#list>
</#if>
<#if section.hasRequestBody()>
${section.getParameterString()}
</#if>
```
<#-- 请求参数table列表-->
<#if section.requestRows?? && (section.requestRows?size>0)>
| 字段 | 类型 | 参数类型 | 是否必填 | 验证 | 默认值 | 描述 |
| :------- | :----- | :----- |:-------- |:-------- | :------ | :---------- |
<#list section.requestRows as rowKey,rowValue>
| ${rowValue.key!''} | ${rowValue.type!''} | **${rowValue.requestParameterType!''}** |${rowValue.required?string('true','false')} | ${rowValue.condition!''} | ${rowValue.def!''} | ${rowValue.remark!''} |
</#list>
</#if>
<#-- 响应-->
<#if section.hasResponseBody()>
**响应**
```
${section.getResponseString()}
```
</#if>
<#-- 响应参数table列表-->
<#if section.responseRows?? && (section.responseRows?size>0)>
| 字段 | 类型 | 描述 |
| :------- | :----- | :---------- |
<#list section.responseRows as rowKey,rowValue>
| ${rowValue.key!''} | ${rowValue.type!''} | ${rowValue.remark!''} |
</#list>
</#if>
</#if>
</#list>
<#------------ END 循环遍历section ---------->
</#if>
</#list>
<#------------ END 循环遍历chapter ---------->
</#list>
<#------------ END 循环遍历book ---------->
</#if>
package com.kim.apidoc.springmvc; package com.kim.apidoc.springmvc;
import kim.apidoc.core.common.URI; import com.kim.apidoc.core.common.URI;
import kim.apidoc.core.common.helper.AnnotationHelper; import com.kim.apidoc.core.common.helper.AnnotationHelper;
import kim.apidoc.core.common.helper.ClassDeclarationHelper; import com.kim.apidoc.core.common.helper.ClassDeclarationHelper;
import kim.apidoc.core.common.helper.ExpressionHelper; import com.kim.apidoc.core.common.helper.ExpressionHelper;
import kim.apidoc.core.schema.Method; import com.kim.apidoc.core.schema.Method;
import com.github.javaparser.ast.Node; import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
......
package com.kim.apidoc.springmvc; package com.kim.apidoc.springmvc;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.Data; import lombok.Data;
......
package com.kim.apidoc.springmvc; package com.kim.apidoc.springmvc;
import com.kim.apidoc.springmvc.resovler.SpringComponentTypeResolver;
import kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.URI;
import kim.apidoc.core.common.description.ObjectTypeDescription;
import kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.helper.AnnotationHelper;
import kim.apidoc.core.common.helper.ExpressionHelper;
import kim.apidoc.core.common.helper.StringHelper;
import kim.apidoc.core.parser.ParserStrategy;
import kim.apidoc.core.schema.Chapter;
import kim.apidoc.core.schema.Header;
import kim.apidoc.core.schema.Row;
import kim.apidoc.core.schema.Section;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.kim.apidoc.core.ApiDoc;
import com.kim.apidoc.core.common.URI;
import com.kim.apidoc.core.common.description.ObjectTypeDescription;
import com.kim.apidoc.core.common.description.TypeDescription;
import com.kim.apidoc.core.common.helper.*;
import com.kim.apidoc.core.parser.ParserStrategy;
import com.kim.apidoc.core.schema.Chapter;
import com.kim.apidoc.core.schema.Header;
import com.kim.apidoc.core.schema.Row;
import com.kim.apidoc.core.schema.Section;
import com.kim.apidoc.springmvc.resovler.SpringComponentTypeResolver;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import static com.kim.apidoc.core.schema.RequestParameterType.*;
/** /**
* spring 解析 * spring 解析
...@@ -43,7 +44,6 @@ public class SpringParser implements ParserStrategy { ...@@ -43,7 +44,6 @@ public class SpringParser implements ParserStrategy {
public static final String EXT_URI = "uri"; public static final String EXT_URI = "uri";
@Override @Override
public String name() { public String name() {
return FRAMEWORK; return FRAMEWORK;
...@@ -157,8 +157,11 @@ public class SpringParser implements ParserStrategy { ...@@ -157,8 +157,11 @@ public class SpringParser implements ParserStrategy {
if (ParameterHelper.isPathVariable(parameter)) { if (ParameterHelper.isPathVariable(parameter)) {
section.getPathVariable().put(parameter.getNameAsString(), ""); section.getPathVariable().put(parameter.getNameAsString(), "");
Row row = new Row(); Row row = new Row();
row.setRequestParameterType(PATH.name());
row.setKey(parameter.getNameAsString()); row.setKey(parameter.getNameAsString());
row.setType(parameter.getType().toString()); row.setType(parameter.getType().toString());
// 路径参数必填
row.setRequired(true);
section.getParamTag(row.getKey()).ifPresent(tag -> row.setRemark(tag.getContent())); section.getParamTag(row.getKey()).ifPresent(tag -> row.setRemark(tag.getContent()));
section.addRequestRow(row); section.addRequestRow(row);
} }
...@@ -233,7 +236,7 @@ public class SpringParser implements ParserStrategy { ...@@ -233,7 +236,7 @@ public class SpringParser implements ParserStrategy {
} else if (description.isObject()) { } else if (description.isObject()) {
section.setParameter(description.asObject().getValue()); section.setParameter(description.asObject().getValue());
} }
section.addRequestRows(description.rows()); section.addRequestRows(description.rows(BODY.name()));
} }
break; break;
} }
...@@ -292,17 +295,25 @@ public class SpringParser implements ParserStrategy { ...@@ -292,17 +295,25 @@ public class SpringParser implements ParserStrategy {
} }
} }
section.setParameter(objectTypeDescription.getValue()); section.setParameter(objectTypeDescription.getValue());
section.addRequestRows(objectTypeDescription.rows()); section.addRequestRows(objectTypeDescription.rows(QUERY.name()));
} }
/** /**
* 解析方法返回参数 * 解析方法返回参
* *
* @param n the n * @param n the n
* @param chapter the chapter * @param chapter the chapter
* @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();
if (null != resultDataClassOrInterfaceDeclaration) {
ClassOrInterfaceType returnType = new ClassOrInterfaceType();
returnType.setName(resultDataClassOrInterfaceDeclaration.getName());
returnType.setTypeArguments(n.getType());
n.findCompilationUnit().get().addImport(ClassDeclarationHelper.getClassOrInterfacePackageName(resultDataClassOrInterfaceDeclaration));
n.setType(returnType);
}
TypeDescription description = ApiDoc.getInstance().getTypeResolvers().resolve(n.getType()); TypeDescription description = ApiDoc.getInstance().getTypeResolvers().resolve(n.getType());
if (description.isAvailable()) { if (description.isAvailable()) {
if (description.isPrimitive()) { if (description.isPrimitive()) {
......
package com.kim.apidoc.springmvc.resovler; package com.kim.apidoc.springmvc.resovler;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.common.description.TypeDescription; import com.kim.apidoc.core.common.description.TypeDescription;
import kim.apidoc.core.common.description.UnAvailableTypeDescription; import com.kim.apidoc.core.common.description.UnAvailableTypeDescription;
import kim.apidoc.core.common.helper.TypeParameterHelper; import com.kim.apidoc.core.common.helper.TypeParameterHelper;
import kim.apidoc.core.resolver.TypeNameResolver; import com.kim.apidoc.core.resolver.TypeNameResolver;
import kim.apidoc.core.resolver.TypeResolver; import com.kim.apidoc.core.resolver.TypeResolver;
import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.Type;
import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedType;
......
package com.kim.apidoc.example; package com.kim.apidoc.example;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.Context; import com.kim.apidoc.core.Context;
import org.junit.Test; import org.junit.Test;
import java.nio.file.Paths; import java.nio.file.Paths;
......
...@@ -3,6 +3,14 @@ package com.kim.apidoc.example.common; ...@@ -3,6 +3,14 @@ package com.kim.apidoc.example.common;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
/**
* The type Result data.
*
* @param <T> the type parameter
* @author fengyuchenglun
* @version 1.0.0
* @resultData
*/
@Setter @Setter
@Getter @Getter
public class ResultData<T> { public class ResultData<T> {
...@@ -11,13 +19,33 @@ public class ResultData<T> { ...@@ -11,13 +19,33 @@ public class ResultData<T> {
* 返回码 * 返回码
*/ */
int code; int code;
//返回信息 /**
* The Msg.
*/
//返回信息
String msg; String msg;
/**
* The Data.
*/
T data; T data;
/**
* Ok result data.
*
* @param <T> the type parameter
* @return the result data
*/
public static <T> ResultData<T> ok(){ public static <T> ResultData<T> ok(){
return ok(null); return ok(null);
} }
/**
* Ok result data.
*
* @param <T> the type parameter
* @param data the data
* @return the result data
*/
public static <T> ResultData<T> ok(T data){ public static <T> ResultData<T> ok(T data){
ResultData<T> resultData = new ResultData<>(); ResultData<T> resultData = new ResultData<>();
resultData.code = 0; resultData.code = 0;
......
...@@ -2,14 +2,34 @@ package com.kim.apidoc.example.common; ...@@ -2,14 +2,34 @@ package com.kim.apidoc.example.common;
/** /**
* 用户角色 * 用户角色
*
* @code * @code
*/ */
public enum Role { public enum Role {
ADMIN("管理员"),USER("用户"),VIP("会员"); /**
* Admin role.
*/
ADMIN("管理员"),
/**
* User role.
*/
USER("用户"),
/**
* Vip role.
*/
VIP("会员");
/**
* The Text.
*/
String text; String text;
/**
* Instantiates a new Role.
*
* @param text the text
*/
Role(String text) { Role(String text) {
this.text = text; this.text = text;
} }
......
...@@ -8,19 +8,39 @@ import javax.validation.constraints.Min; ...@@ -8,19 +8,39 @@ import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Date; import java.util.Date;
import java.util.List;
/**
* 用户对象
*
* @author fengyuchenglun
* @version 1.0.0
*/
@Setter @Setter
@Getter @Getter
public class User { public class User {
/**
* 用户编号.
*/
int id; int id;
/**
* 用户名称.
*/
@NotBlank @NotBlank
String name; String name;
/**
* 用户年龄.
*/
@Min(1) @Min(1)
@NotNull @NotNull
Integer age; Integer age;
/**
* 创建时间.
*/
Date createAt; Date createAt;
/**
* 性别.
*/
@NotBlank @NotBlank
@JsonProperty("Sex") @JsonProperty("Sex")
String sex; String sex;
......
package com.kim.apidoc.example.spring;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 示例controller继承的情况
* 子类继承父类的路径
*/
@RequestMapping("/restdoc")
public class BaseController {
}
package com.kim.apidoc.example.spring.advanced;
import com.kim.apidoc.example.common.ResultData;
import com.kim.apidoc.example.spring.BaseController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
/**
* @index 3
*/
@Controller
@RequestMapping("/auth")
public class AuthController extends BaseController{
/**
*
* @param token 上报的身份验证token,jwt
* @return
*/
@PostMapping
public ResultData auth(@RequestHeader() String token){
return ResultData.ok();
}
}
package com.kim.apidoc.example.spring.advanced;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* will be ignore
*/
@RestController
@RequestMapping("/empty")
public class EmptyController {
}
package com.kim.apidoc.example.spring.advanced;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* will be ignore
* @ignore
*/
@RestController
@RequestMapping("/ignore")
public class IgnoreController {
@RequestMapping
public void ignoreThis(){
}
}
package com.kim.apidoc.example.spring.advanced; package com.kim.apidoc.example.spring.advanced;
import com.kim.apidoc.example.annotation.KimController; import com.kim.apidoc.example.annotation.KimController;
import com.kim.apidoc.example.common.ResultData; import com.kim.apidoc.example.common.Query;
import com.kim.apidoc.example.common.User; import com.kim.apidoc.example.common.User;
import com.kim.apidoc.example.common.ResultData;
import com.kim.apidoc.example.common.ResultData;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
/** /**
* kim接口 * The type Kim user controller.
* *
* @author duanledexianxianxian * @author duanledexianxianxian
* @version 1.0.0 * @version 1.0.0
...@@ -21,24 +23,25 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -21,24 +23,25 @@ import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/api/v1") @RequestMapping("/api/v1")
public class KimUserController { public class KimUserController {
/** /**
* 用户详情信息 * Detail user.
* 主动根据id获取用户的信息
* *
* @param id 用户编号 * @param id the id
* @return result data * @param query the query
* @return 用户对象 user
*/ */
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
public ResultData<User> detail(@PathVariable String id) { public User detail(@PathVariable String id, Query query) {
User user = new User(); User user = new User();
return ResultData.ok(user); return user;
} }
/** /**
* Add integer. * Add integer.
* *
* @return the integer * @return integer integer
*/ */
@PostMapping @PostMapping
public Integer add() { public Integer add() {
......
package com.kim.apidoc.example.spring.advanced;
import com.apigcc.model.Info;
import com.apigcc.model.InfoQuery;
import com.kim.apidoc.example.common.*;
import com.kim.apidoc.example.spring.BaseController;
import com.kim.apidoc.example.spring.hello.Greeting;
import org.jruby.ir.Tuple;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
/**
* @index 4
*/
@Controller
@RequestMapping("/page")
public class PageController extends BaseController {
/**
* 默认页面,由于不是restful的,restdoc将忽略该Endpoint
*
* @return
*/
@GetMapping
public ModelAndView index() {
return new ModelAndView();
}
/**
* Hello with ResponseBody
* *********
* 由于带有@ResponseBody,restdoc将解析该Endpoint
* <p>
* hhh
* \*********
* *********
* hhhh
* *********
* <p>
* class ************** {
* <p>
* }
*
* @return
*/
@GetMapping("/hello")
@ResponseBody
public Greeting hello() {
return new Greeting(1, "hello world");
}
/**
* 未知的多泛型的tuple 演示
*
* @return
*/
@GetMapping("/tuple")
@ResponseBody
public Tuple<UserDTO, User> tuple() {
return null;
}
/**
* 多个RequestMethod
*
* @return
*/
@RequestMapping(value = "/multiMethod", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
@ResponseBody
public ResultData multiMethod() {
return null;
}
@PostMapping("/multi")
@ResponseBody
public ResultData<Wrapper<UserDTO>> multi(@RequestBody ResultData<Wrapper<List<UserDTO>>> resultData) {
return null;
}
/**
* 引用二方Jar
* 使用二方Jar的类时,代码解析器无法获取类上的注释,注解
* 只能获取属性的名称和类型
* @param infoQuery
* @return
*/
@PostMapping("/jar")
@ResponseBody
public Info jar(@RequestBody InfoQuery infoQuery){
return null;
}
/**
* 一个复杂的类型 List<Map<String,User>>
* @return
*/
@GetMapping("/map")
@ResponseBody
public List<Map<String,User>> map(){
return null;
}
/**
* 一个更复杂的类型 List<Map<String,ResultData<Map<Integer,User>>>>
* @return
*/
@GetMapping("/map")
@ResponseBody
public List<Map<String,ResultData<Map<Integer,User>>>> maps(){
return null;
}
/**
* 一个问号类型 List<Map<String,List<?>>>
* @return
*/
@GetMapping("/map")
@ResponseBody
public List<Map<String,List<?>>> maps1(){
return null;
}
/**
* 多级菜单
* @return
*/
@GetMapping("/menus")
@ResponseBody
public List<Menu> menus(){
return null;
}
}
package com.kim.apidoc.example.spring.advanced;
import com.kim.apidoc.example.common.*;
import com.kim.apidoc.example.spring.BaseController;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户模块(标题)
* 用户示例模块文字描述(详情)
* 支持多行文字
* @index 2
*/
@RestController
@RequestMapping("/users")
public class UserController extends BaseController {
/**
* 用户详情信息
* 主动根据id获取用户的信息
*
* @param id 用户编号
* @return
*/
@GetMapping(value = "/{id}")
public ResultData<User> detail(@PathVariable String id) {
User user = new User();
return ResultData.ok(user);
}
/**
* 用户详情信息(根据email或电话号码)
* 多路径适配
*
* @param email
* @param phone
* @return
*/
@GetMapping(value = {"/detail", "/info"})
public ResultData<User> detailOrInfo(String email, String phone) {
return ResultData.ok(new User());
}
/**
* 用户信息新增
*
* @param user 用户信息
* @return
*/
@PostMapping
public ResultData add(@RequestBody UserDTO user) {
return ResultData.ok();
}
/**
* 用户信息更新
*
* @param user 用户信息
* @return
*/
@PatchMapping
public ResultData update(@RequestBody UserDTO user) {
return ResultData.ok();
}
/**
* 用户列表信息查询
* 默认展示GET方法查询
* 返回集合类的结果
*
* @param page 页码
* @param size 每页条数
* @return
*/
@RequestMapping("/list")
public ResultData<List<User>> list(@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) {
return ResultData.ok();
}
/**
* 用户列表信息搜索
* POST搜索时,请求参数将放在请求体中
*
* @param userQuery 查询参数
* @return
*/
@PostMapping("/search")
public ResultData<List<User>> search(UserQuery userQuery) {
return ResultData.ok();
}
/**
* 用户信息删除
* ResponseEntity、Model以及未知类型将忽略
*
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<ResultData> delete(@PathVariable String id, Model model) {
return ResponseEntity.ok(ResultData.ok());
}
/**
* 用户禁用
* 某些项目使用自定义的ArgumentResolver,让spring自动注入一些信息
* restdoc在解析时,可通过env.ignoreTypes("UserDtails")来忽略这些
*
* @param userDetails 当前登录用户的信息
* @return
*/
@RequestMapping(value = "/{id}/disable", method = RequestMethod.PUT)
public ResultData disable(UserDetails userDetails) {
return ResultData.ok();
}
/**
* 查询角色下的用户总数
* @param role 枚举类型{@link Role}
* @return
*/
@GetMapping("/role")
public ResultData<Integer> listFromRole(Role role){
return ResultData.ok();
}
/**
* 批量上传用户信息
* @param list
* @return com.apigcc.example.common.UserDTO
*/
@PostMapping("/batch")
public void batch(@RequestBody List<UserDTO> list){
}
}
package com.kim.apidoc.example.spring.hello;
public class Greeting {
/**
* 编号
*/
private final long id;
/**
* 内容
*/
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
package com.kim.apidoc.example.spring.hello;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicLong;
/**
* 欢迎使用Apiggs
*
* @author fengyuchenglun
* @version 1.0.0
* @index 1
*/
@RestController
public class GreetingController {
/**
* The constant template.
*/
private static final String template = "Hello, %s!";
/**
* The Counter.
*/
private final AtomicLong counter = new AtomicLong();
/**
* 示例接口
* 自定义错误编码
*
* @param name 名称
* @return greeting greeting
* @errorCode ERROR_CODE_1 错误编码1 很长很长的描述
* @errorCode ERROR_CODE_2 错误编码2 很长很长的描述
* @errorCode ERROR_CODE_3 错误编码3 很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述
* @errorCode ERROR_CODE_4 错误编码4 很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述很长很长的描述
*/
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "apigcc") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
package com.kim.apidoc.springmvc; package com.kim.apidoc.springmvc;
import kim.apidoc.core.ApiDoc; import com.kim.apidoc.core.ApiDoc;
import kim.apidoc.core.Context; import com.kim.apidoc.core.Context;
import kim.apidoc.core.common.diff.FileMatcher; import com.kim.apidoc.core.common.diff.FileMatcher;
import org.junit.Test; import org.junit.Test;
import java.io.IOException; import java.io.IOException;
......
...@@ -18,7 +18,7 @@ allprojects { ...@@ -18,7 +18,7 @@ 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'
compileOnly 'org.projectlombok:lombok:1.18.4' compileOnly 'org.projectlombok:lombok:1.18.4'
annotationProcessor 'org.projectlombok:lombok:1.18.6' annotationProcessor 'org.projectlombok:lombok:1.18.6'
......
This diff is collapsed.
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