package com.qianwen.core.scanner.modular;
|
|
import cn.hutool.core.util.StrUtil;
|
import io.swagger.annotations.ApiOperation;
|
import java.lang.annotation.Annotation;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Date;
|
import java.util.List;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import com.qianwen.core.scanner.config.properties.ScannerProperties;
|
import com.qianwen.core.scanner.modular.annotation.DeleteResource;
|
import com.qianwen.core.scanner.modular.annotation.GetResource;
|
import com.qianwen.core.scanner.modular.annotation.PostResource;
|
import com.qianwen.core.scanner.modular.annotation.PutResource;
|
import com.qianwen.core.scanner.modular.constants.ConfigPrefixConstants;
|
import com.qianwen.core.scanner.modular.factory.ApiResourceFactory;
|
import com.qianwen.core.scanner.modular.model.ResourceDefinition;
|
import com.qianwen.core.scanner.modular.stereotype.ApiResource;
|
import com.qianwen.core.scanner.modular.util.AopTargetUtils;
|
import com.qianwen.core.tool.utils.CollectionUtil;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.StringUtil;
|
import org.springframework.beans.BeansException;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.stereotype.Controller;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RestController;
|
|
/* loaded from: blade-starter-scanner-9.3.0.0-SNAPSHOT.jar:org/springblade/core/scanner/modular/ApiResourceScanner.class */
|
public class ApiResourceScanner implements BeanPostProcessor {
|
private static final Logger log = LoggerFactory.getLogger(ApiResourceScanner.class);
|
private ApiResourceFactory apiResourceFactory;
|
private ScannerProperties scannerProperties;
|
|
public ApiResourceScanner(ApiResourceFactory apiResourceFactory, ScannerProperties scannerProperties, String springApplicationName) {
|
this.apiResourceFactory = apiResourceFactory;
|
this.scannerProperties = scannerProperties;
|
}
|
|
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
return bean;
|
}
|
|
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
if (!this.scannerProperties.getOpen().booleanValue()) {
|
return bean;
|
}
|
if ("oauth2ClientContext".equals(beanName)) {
|
return bean;
|
}
|
Object aopTarget = AopTargetUtils.getTarget(bean);
|
if (aopTarget == null) {
|
aopTarget = bean;
|
}
|
Class<?> clazz = aopTarget.getClass();
|
boolean controllerFlag = getControllerFlag(clazz);
|
if (!controllerFlag) {
|
return bean;
|
}
|
List<ResourceDefinition> apiResources = doScan(clazz);
|
persistApiResources(apiResources);
|
return bean;
|
}
|
|
private boolean getControllerFlag(Class<?> clazz) {
|
Annotation[] annotations = clazz.getAnnotations();
|
for (Annotation annotation : annotations) {
|
if (RestController.class.equals(annotation.annotationType()) || Controller.class.equals(annotation.annotationType())) {
|
return true;
|
}
|
}
|
return false;
|
}
|
|
private List<ResourceDefinition> doScan(Class<?> clazz) {
|
ApiResource classApiAnnotation = (ApiResource) clazz.getAnnotation(ApiResource.class);
|
if (classApiAnnotation != null) {
|
if (StrUtil.isEmpty(classApiAnnotation.code())) {
|
String className = clazz.getSimpleName();
|
int controllerIndex = className.indexOf("Controller");
|
if (controllerIndex == -1) {
|
throw new IllegalArgumentException("controller class name is not illegal, it should end with Controller!");
|
}
|
String code = className.substring(0, controllerIndex);
|
this.apiResourceFactory.bindResourceName(StrUtil.toUnderlineCase(code), classApiAnnotation.name());
|
} else {
|
this.apiResourceFactory.bindResourceName(StrUtil.toUnderlineCase(classApiAnnotation.code()), classApiAnnotation.name());
|
}
|
}
|
ArrayList<ResourceDefinition> apiResources = new ArrayList<>();
|
Method[] declaredMethods = clazz.getDeclaredMethods();
|
if (declaredMethods != null && declaredMethods.length > 0) {
|
for (Method declaredMethod : declaredMethods) {
|
Annotation apiResource = (ApiResource) declaredMethod.getAnnotation(ApiResource.class);
|
Annotation getResource = (GetResource) declaredMethod.getAnnotation(GetResource.class);
|
Annotation postResource = (PostResource) declaredMethod.getAnnotation(PostResource.class);
|
Annotation putResource = (PutResource) declaredMethod.getAnnotation(PutResource.class);
|
Annotation deleteResource = (DeleteResource) declaredMethod.getAnnotation(DeleteResource.class);
|
Annotation annotation = null;
|
if (apiResource != null) {
|
annotation = apiResource;
|
}
|
if (getResource != null) {
|
annotation = getResource;
|
}
|
if (postResource != null) {
|
annotation = postResource;
|
}
|
if (putResource != null) {
|
annotation = putResource;
|
}
|
if (deleteResource != null) {
|
annotation = deleteResource;
|
}
|
if (annotation != null) {
|
ResourceDefinition definition = createDefinition(clazz, declaredMethod, annotation);
|
apiResources.add(definition);
|
log.debug("扫描到资源: " + definition);
|
}
|
}
|
}
|
return apiResources;
|
}
|
|
private void persistApiResources(List<ResourceDefinition> apiResources) {
|
this.apiResourceFactory.registerDefinition(apiResources);
|
}
|
|
private ResourceDefinition createDefinition(Class<?> clazz, Method method, Annotation apiResource) {
|
ApiOperation annotation;
|
ResourceDefinition resourceDefinition = new ResourceDefinition();
|
resourceDefinition.setClassName(clazz.getSimpleName());
|
resourceDefinition.setMethodName(method.getName());
|
String className = resourceDefinition.getClassName();
|
int controllerIndex = className.indexOf("Controller");
|
if (controllerIndex == -1) {
|
throw new IllegalArgumentException("controller class name is not illegal, it should end with Controller!");
|
}
|
String modular = className.substring(0, controllerIndex);
|
resourceDefinition.setControllerCode(modular);
|
ApiResource classApiAnnotation = (ApiResource) clazz.getAnnotation(ApiResource.class);
|
if (classApiAnnotation != null && Func.isNotEmpty(classApiAnnotation.moduleCode())) {
|
resourceDefinition.setModuleCode(classApiAnnotation.moduleCode());
|
}
|
String code = (String) invokeAnnotationMethod(apiResource, "code", String.class);
|
if (StrUtil.isEmpty(code)) {
|
resourceDefinition.setCode(StrUtil.toUnderlineCase(modular) + this.scannerProperties.getLinkSymbol() + StrUtil.toUnderlineCase(method.getName()));
|
} else {
|
resourceDefinition.setCode(StrUtil.toUnderlineCase(modular) + this.scannerProperties.getLinkSymbol() + StrUtil.toUnderlineCase(code));
|
}
|
String name = (String) invokeAnnotationMethod(apiResource, "name", String.class);
|
String[] path = (String[]) invokeAnnotationMethod(apiResource, "path", String[].class);
|
String[] value = (String[]) invokeAnnotationMethod(apiResource, "value", String[].class);
|
RequestMethod[] requestMethods = (RequestMethod[]) invokeAnnotationMethod(apiResource, "method", RequestMethod[].class);
|
Boolean buttonFlag = (Boolean) invokeAnnotationMethod(apiResource, "buttonFlag", Boolean.class);
|
resourceDefinition.setName(name);
|
resourceDefinition.setButtonFlag(buttonFlag);
|
if (CollectionUtil.isNotEmpty(Arrays.asList(path))) {
|
if (!path[0].startsWith("/") && Func.isNotEmpty(path[0])) {
|
path[0] = "/" + path[0];
|
}
|
resourceDefinition.setUrl(getControllerClassRequestPath(clazz) + path[0].replaceAll("\\{[^}]*\\}", "*"));
|
} else if (CollectionUtil.isNotEmpty(Arrays.asList(value))) {
|
if (!value[0].startsWith("/") && Func.isNotEmpty(value[0])) {
|
value[0] = "/" + value[0];
|
}
|
resourceDefinition.setUrl(getControllerClassRequestPath(clazz) + value[0].replaceAll("\\{[^}]*\\}", "*"));
|
} else {
|
resourceDefinition.setUrl(getControllerClassRequestPath(clazz));
|
}
|
List<String> splitPath = StringUtil.splitTrim(resourceDefinition.getUrl(), ConfigPrefixConstants.SPLIT_CHAR.charValue());
|
if (splitPath.size() > 1 && Func.isEmpty(resourceDefinition.getModuleCode())) {
|
resourceDefinition.setModuleCode(splitPath.get(0));
|
}
|
if (Func.isEmpty(resourceDefinition.getModuleCode())) {
|
resourceDefinition.setModuleCode(ConfigPrefixConstants.DEFAULT_MODULE_CODE);
|
}
|
String methodNames = "";
|
for (RequestMethod requestMethod : requestMethods) {
|
methodNames = methodNames + requestMethod.name() + ",";
|
}
|
resourceDefinition.setHttpMethod(StrUtil.removeSuffix(methodNames, ","));
|
resourceDefinition.setCreateTime(new Date());
|
if (Func.isEmpty(resourceDefinition.getName()) && (annotation = method.getAnnotation(ApiOperation.class)) != null) {
|
resourceDefinition.setName(annotation.value());
|
}
|
return resourceDefinition;
|
}
|
|
private String getControllerClassRequestPath(Class<?> clazz) {
|
String result;
|
ApiResource controllerRequestMapping = (ApiResource) clazz.getDeclaredAnnotation(ApiResource.class);
|
if (controllerRequestMapping == null) {
|
result = "";
|
} else {
|
String[] paths = controllerRequestMapping.path();
|
String[] values = controllerRequestMapping.value();
|
if (paths.length > 0) {
|
result = paths[0];
|
} else if (values.length > 0) {
|
result = values[0];
|
} else {
|
result = "";
|
}
|
}
|
return "/" + result;
|
}
|
|
private <T> T invokeAnnotationMethod(Annotation apiResource, String methodName, Class<T> resultType) {
|
try {
|
Class<? extends Annotation> annotationType = apiResource.annotationType();
|
Method method = annotationType.getMethod(methodName, new Class[0]);
|
return (T) method.invoke(apiResource, new Object[0]);
|
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
log.error("扫描api资源时出错!", e);
|
throw new RuntimeException("扫描api资源时出错!");
|
}
|
}
|
}
|