goupan
2024-04-03 5506e9a45e717ffcb67ec313b5a4e8206d9b3a39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package cn.stylefeng.roses.kernel.scanner.api.context;
 
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.rule.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.rule.util.ClassTypeUtil;
import cn.stylefeng.roses.kernel.scanner.api.enums.ParamTypeEnum;
 
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 字段处理时的当前上下文
 * <p>
 * 记录每次的解析类的元数据时,处理过哪些实体类型,防止解析字段过程中的无限递归解析实体
 *
 * @author fengshuonan
 * @date 2022/1/15 10:36
 */
public class MetadataContext {
 
    /**
     * 第一个key是唯一id,第二个key是当前context下解析过的实体类,用来标识针对某一次的类元数据解析
     */
    public static ConcurrentHashMap<String, Set<String>> META_DATA_CLASS_COUNT_CONTEXT = new ConcurrentHashMap<>();
 
    /**
     * 第一个key是唯一id,第二个key是当前context下处理的参数类型
     */
    public static ConcurrentHashMap<String, ParamTypeEnum> META_DATA_PARAM_TYPE_CONTEXT = new ConcurrentHashMap<>();
 
    /**
     * 第一个key是唯一id,第二个key是当前context下处理的参数名称
     */
    public static ConcurrentHashMap<String, String> META_DATA_PARAM_NAME_CONTEXT = new ConcurrentHashMap<>();
 
    /**
     * 添加对某次解析的类记录
     *
     * @author fengshuonan
     * @date 2022/1/15 10:47
     */
    public static void addClassRecord(String uuid, String classPathName) {
        Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
        if (classRecords == null) {
            classRecords = new HashSet<>();
        }
        classRecords.add(classPathName);
        META_DATA_CLASS_COUNT_CONTEXT.put(uuid, classRecords);
    }
 
    /**
     * 判断某个类是否已经被解析过
     *
     * @author fengshuonan
     * @date 2022/1/15 10:50
     */
    public static boolean ensureFieldClassHaveParse(String uuid, String classPathName) {
        Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
        if (classRecords == null) {
            return false;
        }
        return classRecords.contains(classPathName);
    }
 
    /**
     * 判断某个类是否已经被解析过
     *
     * @author fengshuonan
     * @date 2022/1/15 10:50
     */
    public static boolean ensureFieldClassHaveParse(String uuid, Type genericType) {
        Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
        if (classRecords != null) {
            // 获取字段类型,如果是数组,collection带实体的,需要获取真实的实体类型
            FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(genericType);
 
            // 如果是对象类型,直接判断
            if (classFieldType.equals(FieldTypeEnum.OBJECT)) {
                return classRecords.contains(((Class<?>) genericType).getName());
            }
 
            // 数组类型,则获取数组的实体
            if (classFieldType.equals(FieldTypeEnum.ARRAY_WITH_OBJECT)) {
                Class<?> originClass = (Class<?>) genericType;
                return classRecords.contains(originClass.getComponentType().getName());
            }
 
            // 集合类型,获取集合的真实类型
            if (classFieldType.equals(FieldTypeEnum.COLLECTION_WITH_OBJECT)) {
                // 获取泛型
                ParameterizedType parameterizedType = (ParameterizedType) genericType;
                Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
                return ensureFieldClassHaveParse(uuid, actualTypeArgument);
            }
        }
        return false;
    }
 
    /**
     * 添加本次解析的参数类型
     *
     * @author fengshuonan
     * @date 2022/1/20 13:50
     */
    public static void addParamTypeMetadata(String uuid, ParamTypeEnum paramTypeEnum) {
        META_DATA_PARAM_TYPE_CONTEXT.put(uuid, paramTypeEnum);
    }
 
    /**
     * 获取本次解析的参数类型
     *
     * @author fengshuonan
     * @date 2022/1/20 13:50
     */
    public static ParamTypeEnum getParamTypeMetadata(String uuid) {
        return META_DATA_PARAM_TYPE_CONTEXT.get(uuid);
    }
 
    /**
     * 设置本次解析的参数名称
     *
     * @author fengshuonan
     * @date 2022/1/24 15:09
     */
    public static void addParameterName(String uuid, String paramName) {
        META_DATA_PARAM_NAME_CONTEXT.put(uuid, paramName);
    }
 
    /**
     * 获取本次解析的参数名称
     *
     * @author fengshuonan
     * @date 2022/1/24 15:09
     */
    public static String getParamName(String uuid) {
        return META_DATA_PARAM_NAME_CONTEXT.get(uuid);
    }
 
 
    /**
     * 清空当前解析的记录
     *
     * @author fengshuonan
     * @date 2022/1/15 10:49
     */
    public static void cleanContext() {
        META_DATA_CLASS_COUNT_CONTEXT.clear();
        META_DATA_PARAM_TYPE_CONTEXT.clear();
        META_DATA_PARAM_NAME_CONTEXT.clear();
    }
 
    /**
     * 清空指定过程的缓存
     *
     * @author fengshuonan
     * @date 2022/1/15 10:49
     */
    public static void cleanContext(String uuid) {
        if (StrUtil.isEmpty(uuid)) {
            return;
        }
        META_DATA_CLASS_COUNT_CONTEXT.remove(uuid);
        META_DATA_PARAM_TYPE_CONTEXT.remove(uuid);
        META_DATA_PARAM_NAME_CONTEXT.remove(uuid);
    }
 
}