package com.zt.core.db.annotation;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.util.ReflectUtil;
|
import com.google.common.base.Predicates;
|
import com.zt.common.annotation.DataFilter;
|
import com.zt.common.annotation.DataFilters;
|
import com.zt.common.constant.Constant;
|
import com.zt.common.utils.SpringContextUtils;
|
import com.zt.core.db.model.DataFilterField;
|
import com.zt.core.db.model.DataFilterMethod;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
import org.springframework.core.io.support.ResourcePatternUtils;
|
import org.springframework.core.type.AnnotationMetadata;
|
import org.springframework.core.type.MethodMetadata;
|
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReader;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.bind.annotation.*;
|
import springfox.documentation.builders.RequestHandlerSelectors;
|
import springfox.documentation.spi.service.contexts.ApiSelector;
|
import springfox.documentation.spring.web.plugins.Docket;
|
|
import java.util.*;
|
|
@Component("dataFilterParser")
|
public class DataFilterParser {
|
|
@Autowired
|
private ResourceLoader resourceLoader;
|
|
private static final String VALUE = "value";
|
|
/**
|
* 获取指定包下所有添加了执行注解的方法信息
|
*
|
* @return
|
* @throws Exception
|
*/
|
public List<DataFilterMethod> getFilteredMethods() throws Exception {
|
List<DataFilterMethod> methods = new ArrayList<>();
|
|
ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
|
MetadataReaderFactory metaReader = new CachingMetadataReaderFactory(resourceLoader);
|
Resource[] resources = resolver.getResources("classpath*:com/zt/**/*.class");
|
|
for (org.springframework.core.io.Resource r : resources) {
|
MetadataReader reader = metaReader.getMetadataReader(r);
|
methods.addAll(resolveClass(reader));
|
}
|
Map<String, String> docetGroupMap = new HashMap<>();
|
try {
|
Map<String, Docket> docketMap = SpringContextUtils.getImplInstance(Docket.class);
|
for (Docket docket : docketMap.values()) {
|
ApiSelector apiSelector = (ApiSelector) ReflectUtil.getFieldValue(docket, "apiSelector");
|
List component1s = (List) ReflectUtil.getFieldValue(apiSelector.getRequestHandlerSelector(),
|
"components");
|
for (Object component1 : component1s) {
|
if (component1.getClass().getName().startsWith(Predicates.class.getName())) {
|
List component2s = (List) ReflectUtil.getFieldValue(component1, "components");
|
for (Object component2 : component2s) {
|
if (component2.getClass().getName().startsWith(RequestHandlerSelectors.class.getName())) {
|
Object[] values = ReflectUtil.getFieldsValue(component2);
|
if (values != null && values.length == 1) {
|
docetGroupMap.put((String) values[0], docket.getGroupName());
|
}
|
}
|
}
|
}
|
}
|
}
|
} catch (UtilException e) {
|
e.printStackTrace();
|
}
|
for (DataFilterMethod method : methods) {
|
for (String classPath : docetGroupMap.keySet()) {
|
if (method.getClassPath().startsWith(classPath)) {
|
method.setSwagger(docetGroupMap.get(classPath));
|
break;
|
}
|
}
|
}
|
|
return methods;
|
}
|
|
private List<DataFilterMethod> resolveClass(MetadataReader reader) {
|
List<DataFilterMethod> methods = new ArrayList<>();
|
// 获取注解元数据
|
AnnotationMetadata metadata = reader.getAnnotationMetadata();
|
// 获取类中RequestMapping注解的value属性
|
String classMapping = getAttr(metadata.getAnnotationAttributes(RequestMapping.class.getCanonicalName()), VALUE);
|
if (classMapping == null) {
|
return methods;
|
}
|
// 获取DataFilters和单独DataFilter注解的方法
|
Set<MethodMetadata> methodMetadatas = new HashSet<>();
|
methodMetadatas.addAll(metadata.getAnnotatedMethods(DataFilters.class.getCanonicalName()));
|
methodMetadatas.addAll(metadata.getAnnotatedMethods(DataFilter.class.getCanonicalName()));
|
|
if (CollectionUtil.isNotEmpty(methodMetadatas)) {
|
// 获取类中Api注解的tags属性
|
Map<String, Object> apiAttributes = metadata.getAnnotationAttributes(Api.class.getCanonicalName());
|
String apiTags = this.getAttr(apiAttributes, "tags");
|
|
for (MethodMetadata annotatedMethod : methodMetadatas) {
|
// 获取方法的mapping
|
String methodMapping = getAttr(
|
annotatedMethod.getAnnotationAttributes(GetMapping.class.getCanonicalName()), VALUE);
|
if (StringUtils.isBlank(methodMapping)) {
|
continue;
|
}
|
String url = classMapping + "/" + methodMapping;
|
|
String methodName = getAttr(
|
annotatedMethod.getAnnotationAttributes(ApiOperation.class.getCanonicalName()), VALUE);
|
|
DataFilterMethod method = new DataFilterMethod(metadata.getClassName(), url, "", apiTags, methodName);
|
|
Map<String, Object> dataFilterAttributes = annotatedMethod.getAnnotationAttributes(DataFilter.class
|
.getCanonicalName());
|
if (dataFilterAttributes != null) {// DataFilter注解
|
method.addField(this.getField(dataFilterAttributes));
|
} else {// DataFilters注解
|
Map<String, Object> dataFiltersAttributes = annotatedMethod
|
.getAnnotationAttributes(DataFilters.class.getCanonicalName());
|
if (dataFiltersAttributes != null) {
|
Map<String, Object>[] dataFilterArray = (Map<String, Object>[]) dataFiltersAttributes
|
.get(VALUE);
|
for (Map<String, Object> attributes : dataFilterArray) {
|
method.addField(this.getField(attributes));
|
}
|
}
|
}
|
|
methods.add(method);
|
}
|
|
}
|
|
return methods;
|
}
|
|
private DataFilterField getField(Map<String, Object> attributes) {
|
String field = getAttr(attributes, "field"), name = getAttr(attributes, "name");
|
if (Constant.Field.TENANT.equals(field)) {
|
name = "租户";
|
} else if (Constant.Field.COMPANY.equals(field)) {
|
name = "公司";
|
} else if (Constant.Field.DEPT.equals(field)) {
|
name = "部门";
|
}
|
return new DataFilterField(name, field, getAttr(attributes, "accept"), getAttr(attributes, "dict"), getAttr(
|
attributes, "op"), getAttr(attributes, "defaul"));
|
}
|
|
/**
|
* 获取注解的属性
|
*
|
* @param attributes
|
* @param key
|
* @return
|
*/
|
private String getAttr(Map<String, Object> attributes, String key) {
|
// 若类无注解
|
if (attributes == null || attributes.get(key) == null) {
|
return null;
|
}
|
// 获取注解的属性值
|
Object value = attributes.get(key);
|
if (value instanceof String) {
|
return (String) value;
|
} else if (value instanceof String[]) {
|
String[] values = (String[]) attributes.get(key);
|
if (0 == values.length) {
|
return null;
|
}
|
return values[0];
|
}
|
return null;
|
}
|
|
private Map<String, Object> getPathByMethod(MethodMetadata annotatedMethod) {
|
Map<String, Object> annotationAttributes = annotatedMethod.getAnnotationAttributes(GetMapping.class
|
.getCanonicalName());
|
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
|
return annotationAttributes;
|
}
|
annotationAttributes = annotatedMethod.getAnnotationAttributes(PostMapping.class.getCanonicalName());
|
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
|
return annotationAttributes;
|
}
|
|
annotationAttributes = annotatedMethod.getAnnotationAttributes(DeleteMapping.class.getCanonicalName());
|
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
|
return annotationAttributes;
|
}
|
|
annotationAttributes = annotatedMethod.getAnnotationAttributes(PutMapping.class.getCanonicalName());
|
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
|
return annotationAttributes;
|
}
|
annotationAttributes = annotatedMethod.getAnnotationAttributes(RequestMapping.class.getCanonicalName());
|
return annotationAttributes;
|
}
|
}
|