| | |
| | | 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 java.util.Set; |
| | | |
| | | import com.dy.common.util.ClassScan; |
| | | import com.dy.common.util.NumUtil; |
| | | import org.apache.logging.log4j.LogManager; |
| | | import org.apache.logging.log4j.Logger; |
| | | import org.reflections.Reflections; |
| | | |
| | | /** |
| | | * 扫描: |
| | |
| | | */ |
| | | @SuppressWarnings("unused") |
| | | public class AnnotationScan { |
| | | |
| | | private static String scanRootPackage = "com.dy.common.mw.protocol." ; |
| | | |
| | | 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 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()); |
| | | private void scanEndpointAnnotations() throws Exception { |
| | | Reflections reflections = new Reflections(scanRootPackage); // 指定包名 |
| | | Set<Class<?>> driverClasses = reflections.getTypesAnnotatedWith(AnnotationDriver.class); |
| | | if (driverClasses != null && driverClasses.size() > 0) { |
| | | String protocolName; |
| | | short protocolVersion; |
| | | String key ; |
| | | int priority; |
| | | int onLineDataMinLength; |
| | | int headMinLength; |
| | | |
| | | 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(); |
| | | |
| | | HashMap<String, AnnotationDriverVo> driverMap = ProtocolCach.getDriverMap() ; |
| | | HashMap<String, AnnotationPrefixedDataAvailableVo> prefixedDataAvailableMap = ProtocolCach.getPrefixedDataAvailableMap() ; |
| | | HashMap<String, AnnotationOnLineVo> onLineMap = ProtocolCach.getOnLineMap() ; |
| | | for (Class<?> clazz : driverClasses) { |
| | | AnnotationDriver ann = clazz.getAnnotation(AnnotationDriver.class); |
| | | if (ann != null) { |
| | | if (ann.enable()) { |
| | | protocolName = ann.name(); |
| | | protocolVersion = ann.version() ; |
| | | if(protocolName == null || protocolName.trim().equals("")){ |
| | | throw new Exception("严重错误,协议驱动名称注解值为空字符串"); |
| | | } |
| | | if(protocolVersion == -1){ |
| | | throw new Exception("严重错误,协议驱动版本号未配置"); |
| | | } |
| | | key = protocolName + protocolVersion ; |
| | | if (driverMap.containsKey(key)) { |
| | | throw new Exception("严重错误,协议驱动(名称+版本号)" + key + "出现了重复注解!"); |
| | | } |
| | | driverMap.put(key, new AnnotationDriverVo(clazz)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | 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){ |
| | | 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<Class<?>> 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("严重错误,上行数据完整性检查所配协议驱动注解值为空字符串"); |
| | | } |
| | | |
| | | protocolVersion = ann.protocolVersion(); |
| | | if (protocolVersion == -1) { |
| | | throw new Exception("严重错误, 上行数据完整性检查所配协议版本号未配置"); |
| | | } |
| | | |
| | | if(clazz.isAnnotationPresent(AnnotationPrefixedDataAvailable.class)){ |
| | | AnnotationPrefixedDataAvailable ann = clazz.getAnnotation(AnnotationPrefixedDataAvailable.class) ; |
| | | if(ann != null){ |
| | | 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 + "重复"); |
| | | } |
| | | |
| | | priority = ann.priority() ; |
| | | if(priority == 0){ |
| | | throw new Exception("严重错误, 上行数据完整性检查所配优先级注解不能为0") ; |
| | | } |
| | | if(isRepeatPrefixedDataAvailablePriority(priority, prefixedDataAvailableMap)){ |
| | | throw new Exception("严重错误, 上行数据完整性检查所配优先级注解(priority)数值" + priority + "重复") ; |
| | | } |
| | | |
| | | onLineDataMinLength = ann.onLineDataMinLength() ; |
| | | onLineDataMinLength = ann.onLineDataMinLength(); |
| | | /*气象协议为0 |
| | | if(onLineDataMinLength == 0){ |
| | | throw new Exception("严重错误, 上行数据完整性检查所配上线数据最小长度注解不能为0") ; |
| | | } |
| | | */ |
| | | headMinLength = ann.headMinLength() ; |
| | | 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){ |
| | | 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)) ; |
| | | } |
| | | } |
| | | key = protocolName + protocolVersion ; |
| | | prefixedDataAvailableMap.put(key, new AnnotationPrefixedDataAvailableVo(clazz, protocolName, protocolVersion, priority, onLineDataMinLength, headMinLength, ProtocolConstant.errorMaxLength)); |
| | | } |
| | | |
| | | 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) ; |
| | | } |
| | | } |
| | | |
| | | Set<Class<?>> 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("严重错误,上线数据分析所配协议驱动注解值为空字符串"); |
| | | } |
| | | |
| | | protocolVersion = ann.protocolVersion(); |
| | | if (protocolVersion == -1) { |
| | | throw new Exception("严重错误, 上线数据分析所配协议版本号未配置"); |
| | | } |
| | | |
| | | priority = ann.priority(); |
| | | if (priority == 0) { |
| | | throw new Exception("严重错误, 上线数据分析所配优先级注解不能为0"); |
| | | } |
| | | if (isRepeatOnLinePriority(priority, onLineMap)) { |
| | | throw new Exception("严重错误, 上线数据分析所配优先级注解(priority)数值" + priority + "重复"); |
| | | } |
| | | |
| | | key = protocolName + protocolVersion ; |
| | | onLineMap.put(key, new AnnotationOnLineVo(clazz, protocolName, protocolVersion, 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(); |
| | | Collection<AnnotationPrefixedDataAvailableVo> col = prefixedDataAvailableMap.values(); |
| | | for(AnnotationPrefixedDataAvailableVo vo : col){ |
| | | if(vo.priority == priority){ |
| | | return true ; |
| | |
| | | * @return 结果 |
| | | */ |
| | | private boolean isRepeatOnLinePriority(int priority, HashMap<String, AnnotationOnLineVo> onLineMap){ |
| | | Collection<AnnotationOnLineVo> col = onLineMap.values(); |
| | | 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(); |
| | | 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 + ")在协议驱动中未配置" ; |
| | | if(!driverMap.containsKey(vo.protocolName + vo.protocolVersion)){ |
| | | return "严重错误,上行数据完整性检查所配驱动名称(" + (vo.protocolName + vo.protocolVersion) + ")在协议驱动中未配置" ; |
| | | } |
| | | } |
| | | |
| | | |
| | | int[] prioritys = new int[prefixedDataAvailableMap.size()] ; |
| | | int count = 0 ; |
| | | col = prefixedDataAvailableMap.values(); |
| | | 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 + " 开始" ; |
| | |
| | | } |
| | | return null ; |
| | | } |
| | | |
| | | |
| | | private String hasErrorInOnLine(HashMap<String, AnnotationDriverVo> driverMap, |
| | | HashMap<String, AnnotationOnLineVo> onLineMap){ |
| | | Collection<AnnotationOnLineVo> col = onLineMap.values(); |
| | | HashMap<String, AnnotationOnLineVo> onLineMap){ |
| | | Collection<AnnotationOnLineVo> col = onLineMap.values(); |
| | | for(AnnotationOnLineVo vo : col){ |
| | | if(!driverMap.containsKey(vo.protocolName)){ |
| | | return "严重错误,上线数据分析所配驱动名称(" + vo.protocolName + ")在协议驱动中未配置" ; |
| | | if(!driverMap.containsKey(vo.protocolName + vo.protocolVersion)){ |
| | | return "严重错误,上线数据分析所配驱动名称(" + (vo.protocolName + vo.protocolVersion) + ")在协议驱动中未配置" ; |
| | | } |
| | | } |
| | | |
| | | |
| | | int[] prioritys = new int[onLineMap.size()] ; |
| | | int count = 0 ; |
| | | col = onLineMap.values(); |
| | | 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 + " 开始" ; |