shz.spring.api.doc.SpringApiDocGenerator Maven / Gradle / Ivy
package shz.spring.api.doc;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import shz.core.NullHelp;
import shz.core.net.api.ApiMethodAndPath;
import shz.core.net.api.doc.ApiDocGenerator;
import shz.core.net.api.doc.ApiDocRequestModel;
import shz.core.net.api.doc.ApiDocTree;
import shz.core.net.api.doc.ApiDocType;
import shz.spring.BeanContainer;
import shz.spring.api.ApiMethodAndPathGetter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class SpringApiDocGenerator extends ApiDocGenerator {
@Override
protected ApiMethodAndPath methodAndPath(Class> cls, Method method) {
return ApiMethodAndPathGetter.get(cls, method);
}
@Override
protected boolean isFile(Class> cls) {
return MultipartFile.class.isAssignableFrom(cls);
}
@Override
protected boolean required(Class> cls, Field field) {
return field.isAnnotationPresent(NotBlank.class)
|| field.isAnnotationPresent(NotEmpty.class)
|| field.isAnnotationPresent(NotNull.class);
}
@Override
protected void setRequest(Method method, ApiDocRequestModel request) {
String[] parameterNames = BeanContainer.getParameterNames(method);
if (NullHelp.isEmpty(parameterNames)) return;
List pathVariables = new ArrayList<>();
List params = new ArrayList<>();
List parts = new ArrayList<>();
request.setPathVariables(pathVariables);
request.setParams(params);
request.setParts(parts);
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class>[] parameterTypes = method.getParameterTypes();
Type[] genericParameterTypes = method.getGenericParameterTypes();
Set existParamName = new HashSet<>();
ApiDocType type;
if (NullHelp.isEmpty(parameterAnnotations)) {
for (int i = 0; i < parameterNames.length; ++i) {
if (existParamName.contains(parameterNames[i])) continue;
existParamName.add(parameterNames[i]);
if (Map.class.isAssignableFrom(parameterTypes[i]) || simpleParam(type = type(parameterTypes[i])))
params.add(tree(parameterTypes[i], genericParameterTypes[i], Boolean.FALSE, methodParamComment(method, parameterNames[i]), parameterNames[i], null));
else if (objectParam(type)) {
ApiDocTree apiDocTree = tree(parameterTypes[i], genericParameterTypes[i], Boolean.FALSE, methodParamComment(method, parameterNames[i]), parameterNames[i], null);
List children = apiDocTree.getChildren();
if (NullHelp.nonEmpty(children)) {
for (ApiDocTree child : children) {
if (existParamName.contains(child.getField())) continue;
existParamName.add(child.getField());
params.add(child);
}
}
}
}
return;
}
Map requires = new HashMap<>();
Map values = new HashMap<>();
Map pathVariablesMap = new HashMap<>();
int bodyIdx = -1;
Map paramsMap = new HashMap<>();
Map partsMap = new HashMap<>();
boolean mark;
for (int i = 0; i < parameterNames.length; ++i) {
mark = false;
if (NullHelp.nonEmpty(parameterAnnotations[i])) {
for (Annotation a : parameterAnnotations[i]) {
if (a instanceof PathVariable) {
PathVariable pathVariable = (PathVariable) a;
requires.put(i, pathVariable.required());
if (NullHelp.nonBlank(pathVariable.value())) pathVariablesMap.put(i, pathVariable.value());
else if (NullHelp.nonBlank(pathVariable.name()))
pathVariablesMap.put(i, pathVariable.name());
else pathVariablesMap.put(i, parameterNames[i]);
mark = true;
break;
} else if (a instanceof RequestBody) {
RequestBody requestBody = (RequestBody) a;
requires.put(i, requestBody.required());
bodyIdx = i;
mark = true;
break;
} else if (a instanceof RequestParam) {
RequestParam requestParam = (RequestParam) a;
requires.put(i, requestParam.required());
if (!"\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n".equals(requestParam.defaultValue()))
values.put(i, requestParam.defaultValue());
if (NullHelp.nonBlank(requestParam.value())) paramsMap.put(i, requestParam.value());
else if (NullHelp.nonBlank(requestParam.name())) paramsMap.put(i, requestParam.name());
else paramsMap.put(i, parameterNames[i]);
mark = true;
break;
} else if (a instanceof RequestAttribute) {
RequestAttribute requestAttribute = (RequestAttribute) a;
requires.put(i, requestAttribute.required());
if (NullHelp.nonBlank(requestAttribute.value()))
paramsMap.put(i, requestAttribute.value());
else if (NullHelp.nonBlank(requestAttribute.name()))
paramsMap.put(i, requestAttribute.name());
else paramsMap.put(i, parameterNames[i]);
mark = true;
break;
} else if (a instanceof RequestPart) {
RequestPart requestPart = (RequestPart) a;
requires.put(i, requestPart.required());
if (NullHelp.nonBlank(requestPart.value())) partsMap.put(i, requestPart.value());
else if (NullHelp.nonBlank(requestPart.name())) partsMap.put(i, requestPart.name());
else partsMap.put(i, parameterNames[i]);
mark = true;
break;
}
}
}
if (!mark) {
requires.put(i, Boolean.FALSE);
paramsMap.put(i, parameterNames[i]);
}
}
if (bodyIdx != -1) {
for (int i = 0; i < parameterNames.length; ++i) {
if (pathVariablesMap.containsKey(i)) {
if (pathVariable(type(parameterTypes[i])))
pathVariables.add(tree(parameterTypes[i], genericParameterTypes[i], Boolean.TRUE, methodParamComment(method, parameterNames[i]), pathVariablesMap.get(i), null));
} else if (i == bodyIdx)
request.setBody(tree(parameterTypes[i], genericParameterTypes[i], requires.get(i), methodParamComment(method, parameterNames[i]), null, null));
}
} else {
for (int i = 0; i < parameterNames.length; ++i) {
if (pathVariablesMap.containsKey(i)) {
if (pathVariable(type(parameterTypes[i])))
pathVariables.add(tree(parameterTypes[i], genericParameterTypes[i], Boolean.TRUE, methodParamComment(method, parameterNames[i]), pathVariablesMap.get(i), null));
} else if (partsMap.containsKey(i)) {
if (part(type(parameterTypes[i])))
parts.add(tree(parameterTypes[i], genericParameterTypes[i], requires.get(i), methodParamComment(method, parameterNames[i]), partsMap.get(i), null));
} else if (paramsMap.containsKey(i)) {
if (existParamName.contains(paramsMap.get(i))) continue;
existParamName.add(paramsMap.get(i));
if (Map.class.isAssignableFrom(parameterTypes[i]) || simpleParam(type = type(parameterTypes[i])))
params.add(tree(parameterTypes[i], genericParameterTypes[i], requires.get(i), methodParamComment(method, parameterNames[i]), paramsMap.get(i), values.get(i)));
else if (objectParam(type)) {
ApiDocTree apiDocTree = tree(parameterTypes[i], genericParameterTypes[i], requires.get(i), methodParamComment(method, parameterNames[i]), paramsMap.get(i), values.get(i));
List children = apiDocTree.getChildren();
if (NullHelp.nonEmpty(children)) {
for (ApiDocTree child : children) {
if (existParamName.contains(child.getField())) continue;
existParamName.add(child.getField());
params.add(child);
}
}
}
}
}
}
}
private boolean simpleParam(ApiDocType type) {
return type == ApiDocType.string || type == ApiDocType.bool || type == ApiDocType.integer || type == ApiDocType.number || type == ApiDocType.date || type == ApiDocType.file || type == ApiDocType.array;
}
private boolean objectParam(ApiDocType type) {
return type == ApiDocType.object;
}
private boolean pathVariable(ApiDocType type) {
return type == ApiDocType.string || type == ApiDocType.bool || type == ApiDocType.integer || type == ApiDocType.number || type == ApiDocType.date || type == ApiDocType.array;
}
private boolean part(ApiDocType type) {
return type == ApiDocType.file || type == ApiDocType.array;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy