pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/AnnotationScan.java
@@ -1,13 +1,13 @@
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;
/**
 * 扫描:
@@ -19,14 +19,16 @@
 */
@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(){
   }
   /**
    * 得到唯一实例,
    * 并在生成唯一实例时,扫描注解类
@@ -40,148 +42,135 @@
      }
      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;
         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 = 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("严重错误,协议驱动名称注解值为空字符串") ;
                           }
                        }
         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<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("严重错误,上行数据完整性检查所配协议驱动注解值为空字符串");
                  }
                  priority = ann.priority();
                  if (priority == 0) {
                     throw new Exception("严重错误, 上行数据完整性检查所配优先级注解不能为0");
                  }
                  if (isRepeatPrefixedDataAvailablePriority(priority, prefixedDataAvailableMap)) {
                     throw new Exception("严重错误, 上行数据完整性检查所配优先级注解(priority)数值" + priority + "重复");
                  }
                  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() ;
                  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){
                        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)) ;
                        }
                     }
                  }
                  prefixedDataAvailableMap.put(protocolName, new AnnotationPrefixedDataAvailableVo(clazz, protocolName, 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("严重错误,上线数据分析所配协议驱动注解值为空字符串");
                  }
                  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();
      Collection<AnnotationPrefixedDataAvailableVo> col = prefixedDataAvailableMap.values();
      for(AnnotationPrefixedDataAvailableVo vo : col){
         if(vo.priority == priority){
            return true ;
@@ -195,7 +184,7 @@
    * @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 ;
@@ -203,7 +192,7 @@
      }
      return false ;
   }
   private String hasErrorInDriver(HashMap<String, AnnotationDriverVo> driverMap){
      if(driverMap.size() == 0){
         return "严重错误,未注解任何协议驱动" ;
@@ -211,23 +200,23 @@
      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 + ")在协议驱动中未配置" ;
         }
      }
      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 + " 开始" ;
@@ -246,24 +235,24 @@
      }
      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 + ")在协议驱动中未配置" ;
         }
      }
      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 + " 开始" ;