liurunyu
2024-05-17 22139031145838326262323b61d61ecc46617397
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
package com.dy.common.mw.protocol;
 
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
 
import com.dy.common.util.ClassScan;
import com.dy.common.util.NumUtil;
 
/**
 * 扫描:
 *   协议驱动类
 *   上行数据完整性检查类(断包粘包检查)
 *   上线数据(连接后第一包数据)处理类(识别协议及终端地址)
 * @author Administrator
 *
 */
@SuppressWarnings("unused")
public class AnnotationScan {
    
    private static String scanRootPackage = "com.dy.common.mw.protocol." ;
 
    private static AnnotationScan instance ;
    
    private AnnotationScan(){
    }
    
    /**
     * 得到唯一实例,
     * 并在生成唯一实例时,扫描注解类
     * @return AnnotationScan
     * @throws Exception 异常
     */
    public static AnnotationScan getIntance()throws Exception{
        if(instance == null){
            instance = new AnnotationScan() ;
            instance.scanEndpointAnnotations();
        }
        return instance ;
    }
    
    /**
     * 扫描出注解的类
     * @throws ClassNotFoundException 异常
     * @throws Exception 异常
     */
    private void scanEndpointAnnotations() throws Exception{
        ClassLoader load = this.getClass().getClassLoader() ;
        
        if(!scanRootPackage.endsWith(".")){
            scanRootPackage += "." ;
        }
        URL url = AnnotationScan.class.getResource("/" + scanRootPackage.replace('.', '/'));
        if(url != null){
            String urlStr = url.toString() ;
            if(urlStr != null){
                URI uri = new URI(url.toString());
 
                List<String> classNames = new ClassScan().searchClassFromUrl(new URI[]{uri}, scanRootPackage) ;
                if(classNames != null && classNames.size() > 0){
                    String protocolName ;
                    int priority;
                    int onLineDataMinLength;
                    int headMinLength ;
 
                    HashMap<String, AnnotationDriverVo> driverMap = ProtocolCache.getDriverMap() ;
                    HashMap<String, AnnotationPrefixedDataAvailableVo> prefixedDataAvailableMap = ProtocolCache.getPrefixedDataAvailableMap() ;
                    HashMap<String, AnnotationOnLineVo> onLineMap = ProtocolCache.getOnLineMap() ;
 
                    for(String cName : classNames){
                        String className = cName.substring(0,  cName.lastIndexOf('.')) ;
                        Class<?> clazz = load.loadClass(className) ;
                        if(clazz.isAnnotationPresent(AnnotationDriver.class)){
                            AnnotationDriver ann = clazz.getAnnotation(AnnotationDriver.class) ;
                            if(ann != null){
                                if(ann.enable()){
                                    protocolName = ann.name() ;
                                    if(!(protocolName.trim().equals(""))){
                                        if(driverMap.containsKey(protocolName)){
                                            throw new Exception("严重错误,协议驱动名称" + protocolName + "出现了重复注解!") ;
                                        }
                                        driverMap.put(protocolName, new AnnotationDriverVo(clazz)) ;
                                    }else{
                                        throw new Exception("严重错误,协议驱动名称注解值为空字符串") ;
                                    }
                                }
                            }
                        }
 
 
                        if(clazz.isAnnotationPresent(AnnotationPrefixedDataAvailable.class)){
                            AnnotationPrefixedDataAvailable ann = clazz.getAnnotation(AnnotationPrefixedDataAvailable.class) ;
                            if(ann != null){
                                if(ann.enable()){
                                    protocolName = ann.protocolName() ;
                                    if(!(protocolName.trim().equals(""))){
                                        if(prefixedDataAvailableMap.containsKey(protocolName)){
                                            throw new Exception("严重错误, 上行数据完整性检查所配协议驱动" + protocolName + "出现了重复注解!") ;
                                        }
                                    }else{
                                        throw new Exception("严重错误,上行数据完整性检查所配协议驱动注解值为空字符串") ;
                                    }
 
                                    priority = ann.priority() ;
                                    if(priority == 0){
                                        throw new Exception("严重错误, 上行数据完整性检查所配优先级注解不能为0") ;
                                    }
                                    if(isRepeatPrefixedDataAvailablePriority(priority, prefixedDataAvailableMap)){
                                        throw new Exception("严重错误, 上行数据完整性检查所配优先级注解(priority)数值" + priority + "重复") ;
                                    }
 
                                    onLineDataMinLength = ann.onLineDataMinLength() ;
                                    /*气象协议为0
                                    if(onLineDataMinLength == 0){
                                        throw new Exception("严重错误, 上行数据完整性检查所配上线数据最小长度注解不能为0") ;
                                    }
                                    */
                                                headMinLength = ann.headMinLength() ;
                                    /*气象协议为0
                                    if(headMinLength == 0){
                                        throw new Exception("严重错误, 上行数据完整性检查所配上报数据的头部最小长度注解不能为0") ;
                                    }
                                    */
                                    prefixedDataAvailableMap.put(protocolName, new AnnotationPrefixedDataAvailableVo(clazz, protocolName, priority, onLineDataMinLength, headMinLength, ProtocolConstant.errorMaxLength)) ;
                                }
                            }
                        }
 
                        if(clazz.isAnnotationPresent(AnnotationOnLine.class)){
                            AnnotationOnLine ann = clazz.getAnnotation(AnnotationOnLine.class) ;
                            if(ann != null){
                                if(ann.enable()){
                                    protocolName = ann.protocolName() ;
                                    if(!(protocolName.trim().equals(""))){
                                        if(onLineMap.containsKey(protocolName)){
                                            throw new Exception("严重错误, 上线数据分析所配协议驱动" + protocolName + "出现了重复注解!") ;
                                        }
                                    }else{
                                        throw new Exception("严重错误,上线数据分析所配协议驱动注解值为空字符串") ;
                                    }
 
                                    priority = ann.priority() ;
                                    if(priority == 0){
                                        throw new Exception("严重错误, 上线数据分析所配优先级注解不能为0") ;
                                    }
                                    if(isRepeatOnLinePriority(priority, onLineMap)){
                                        throw new Exception("严重错误, 上线数据分析所配优先级注解(priority)数值" + priority + "重复") ;
                                    }
 
                                    onLineMap.put(protocolName, new AnnotationOnLineVo(clazz, protocolName, priority)) ;
                                }
                            }
                        }
                    }
 
                    String error = this.hasErrorInDriver(driverMap) ;
                    if(error != null){
                        throw new Exception(error) ;
                    }else{
                        error = this.hasErrorInPrefixedDataAvailable(driverMap, prefixedDataAvailableMap) ;
                        if(error != null){
                            throw new Exception(error) ;
                        }else{
                            error = this.hasErrorInOnLine(driverMap, onLineMap) ;
                            if(error != null){
                                throw new Exception(error) ;
                            }
                        }
                    }
                }else{
                    throw new Exception("严重错误, 扫描协议相关注解所得到类型集合为空,扫描根路径是" + scanRootPackage) ;
                }
            }
        }
    }
    /**
     * 检查优先级重复
     * @param priority 优先级
     * @return 结果
     */
    private boolean isRepeatPrefixedDataAvailablePriority(int priority, HashMap<String, AnnotationPrefixedDataAvailableVo> prefixedDataAvailableMap){
        Collection<AnnotationPrefixedDataAvailableVo> col = prefixedDataAvailableMap.values(); 
        for(AnnotationPrefixedDataAvailableVo vo : col){
            if(vo.priority == priority){
                return true ;
            }
        }
        return false ;
    }
    /**
     * 检查优先级重复
     * @param priority 优先级
     * @return 结果
     */
    private boolean isRepeatOnLinePriority(int priority, HashMap<String, AnnotationOnLineVo> onLineMap){
        Collection<AnnotationOnLineVo> col = onLineMap.values(); 
        for(AnnotationOnLineVo vo : col){
            if(vo.priority == priority){
                return true ;
            }
        }
        return false ;
    }
    
    private String hasErrorInDriver(HashMap<String, AnnotationDriverVo> driverMap){
        if(driverMap.size() == 0){
            return "严重错误,未注解任何协议驱动" ;
        }
        return null ;
    }
 
    private String hasErrorInPrefixedDataAvailable(HashMap<String, AnnotationDriverVo> driverMap, 
            HashMap<String, AnnotationPrefixedDataAvailableVo> prefixedDataAvailableMap){
        Collection<AnnotationPrefixedDataAvailableVo> col = prefixedDataAvailableMap.values(); 
        for(AnnotationPrefixedDataAvailableVo vo : col){
            if(!driverMap.containsKey(vo.protocolName)){
                return "严重错误,上行数据完整性检查所配驱动名称(" + vo.protocolName + ")在协议驱动中未配置" ;
            }
        }
        
        int[] prioritys = new int[prefixedDataAvailableMap.size()] ;
        int count = 0 ;
        col = prefixedDataAvailableMap.values(); 
        for(AnnotationPrefixedDataAvailableVo vo : col){
            prioritys[count++] = vo.priority ;
        }
        NumUtil.sort(prioritys, true) ;
        
        int firstPriority = prioritys[0] ;
        if(ProtocolConstant.firstPriority != firstPriority){
            return "严重错误,上行数据完整性检查所配优先级必须从 " + ProtocolConstant.firstPriority + " 开始" ;
        }
        int  prePriority = prioritys[0] ;
        int  nextPriority;
        if(prioritys.length > 1){
            for(int i = 1 ; i < prioritys.length; i++){
                nextPriority = prioritys[i] ;
                if(nextPriority - prePriority != 1){
                    return "严重错误,上行数据完整性检查所配各个优先级必须相差1" ;
                }else{
                    prePriority = nextPriority ;
                }
            }
        }
        return null ;
    }
    
    private String hasErrorInOnLine(HashMap<String, AnnotationDriverVo> driverMap,
            HashMap<String, AnnotationOnLineVo> onLineMap){
        Collection<AnnotationOnLineVo> col = onLineMap.values(); 
        for(AnnotationOnLineVo vo : col){
            if(!driverMap.containsKey(vo.protocolName)){
                return "严重错误,上线数据分析所配驱动名称(" + vo.protocolName + ")在协议驱动中未配置" ;
            }
        }
        
        int[] prioritys = new int[onLineMap.size()] ;
        int count = 0 ;
        col = onLineMap.values(); 
        for(AnnotationOnLineVo vo : col){
            prioritys[count++] = vo.priority ;
        }
        NumUtil.sort(prioritys, true) ;
        
        int firstPriority = prioritys[0] ;
        if(ProtocolConstant.firstPriority != firstPriority){
            return "严重错误,上线数据分析所配优先级必须从 " + ProtocolConstant.firstPriority + " 开始" ;
        }
        int  prePriority = prioritys[0] ;
        int  nextPriority;
        if(prioritys.length > 1){
            for(int i = 1 ; i < prioritys.length; i++){
                nextPriority = prioritys[i] ;
                if(nextPriority - prePriority != 1){
                    return "严重错误,上线数据分析所配各个优先级必须相差1" ;
                }else{
                    prePriority = nextPriority ;
                }
            }
        }
        return null ;
    }
}