package com.dy.common.mw.protocol; import java.util.Collection; import java.util.HashMap; import java.util.Set; import com.dy.common.util.NumUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.reflections.Reflections; /** * 扫描: * 协议驱动类 * 上行数据完整性检查类(断包粘包检查) * 上线数据(连接后第一包数据)处理类(识别协议及终端地址) * @author Administrator * */ @SuppressWarnings("unused") public class AnnotationScan { private static final Logger log = LogManager.getLogger(AnnotationScan.class); 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 { Reflections reflections = new Reflections(scanRootPackage); // 指定包名 Set> driverClasses = reflections.getTypesAnnotatedWith(AnnotationDriver.class); if (driverClasses != null && driverClasses.size() > 0) { String protocolName; int priority; int onLineDataMinLength; int headMinLength; HashMap driverMap = ProtocolCache.getDriverMap(); HashMap prefixedDataAvailableMap = ProtocolCache.getPrefixedDataAvailableMap(); HashMap onLineMap = ProtocolCache.getOnLineMap(); for (Class clazz : driverClasses) { 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("严重错误,协议驱动名称注解值为空字符串"); } } } } Set> prefixedClass = reflections.getTypesAnnotatedWith(AnnotationPrefixedDataAvailable.class); for (Class clazz : prefixedClass) { 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)); } } } Set> onLineClass = reflections.getTypesAnnotatedWith(AnnotationOnLine.class); for (Class clazz : onLineClass) { 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 prefixedDataAvailableMap){ Collection col = prefixedDataAvailableMap.values(); for(AnnotationPrefixedDataAvailableVo vo : col){ if(vo.priority == priority){ return true ; } } return false ; } /** * 检查优先级重复 * @param priority 优先级 * @return 结果 */ private boolean isRepeatOnLinePriority(int priority, HashMap onLineMap){ Collection col = onLineMap.values(); for(AnnotationOnLineVo vo : col){ if(vo.priority == priority){ return true ; } } return false ; } private String hasErrorInDriver(HashMap driverMap){ if(driverMap.size() == 0){ return "严重错误,未注解任何协议驱动" ; } return null ; } private String hasErrorInPrefixedDataAvailable(HashMap driverMap, HashMap prefixedDataAvailableMap){ Collection 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 driverMap, HashMap onLineMap){ Collection 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 ; } }