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 getFilteredMethods() throws Exception { List 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 docetGroupMap = new HashMap<>(); try { Map 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 resolveClass(MetadataReader reader) { List 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 methodMetadatas = new HashSet<>(); methodMetadatas.addAll(metadata.getAnnotatedMethods(DataFilters.class.getCanonicalName())); methodMetadatas.addAll(metadata.getAnnotatedMethods(DataFilter.class.getCanonicalName())); if (CollectionUtil.isNotEmpty(methodMetadatas)) { // 获取类中Api注解的tags属性 Map 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 dataFilterAttributes = annotatedMethod.getAnnotationAttributes(DataFilter.class .getCanonicalName()); if (dataFilterAttributes != null) {// DataFilter注解 method.addField(this.getField(dataFilterAttributes)); } else {// DataFilters注解 Map dataFiltersAttributes = annotatedMethod .getAnnotationAttributes(DataFilters.class.getCanonicalName()); if (dataFiltersAttributes != null) { Map[] dataFilterArray = (Map[]) dataFiltersAttributes .get(VALUE); for (Map attributes : dataFilterArray) { method.addField(this.getField(attributes)); } } } methods.add(method); } } return methods; } private DataFilterField getField(Map 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 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 getPathByMethod(MethodMetadata annotatedMethod) { Map 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; } }