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 classNames = new ClassScan().searchClassFromUrl(new URI[]{uri}, scanRootPackage) ; if(classNames != null && classNames.size() > 0){ String protocolName ; int priority; int onLineDataMinLength; int headMinLength ; HashMap driverMap = ProtocolCache.getDriverMap() ; HashMap prefixedDataAvailableMap = ProtocolCache.getPrefixedDataAvailableMap() ; HashMap 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 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 ; } }