zhubaomin
2025-04-07 1a2b07f01ba4616fd9e894dddf474b56d020158c
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Driver.java
New file
@@ -0,0 +1,177 @@
package com.dy.common.mw.protocol;
import java.util.HashMap;
import java.util.Set;
import org.reflections.Reflections;
public abstract class Driver {
   //单线程单例Driver模式下运行
   protected HashMap<String, Class<CodeParse>> upCode2Classes = new HashMap<>() ;
   protected HashMap<String, CodeParse> upCode2ClassInstance = new HashMap<>() ;
   protected HashMap<String, Class<CodeParse>> downCode2Class = new HashMap<>() ;
   protected HashMap<String, CodeParse> downCode2ClassInstance = new HashMap<>() ;
   protected Notify notify ;
   /**
    * 清空自己
    */
   public abstract void clear() ;
   /**
     * 设置RTU信息通知器
     * @param notify 通知
     */
   public void setNotify(Notify notify){
      this.notify = notify ;
   }
   /**
    * 单线程单例Driver模式下运行
    * 扫描识别功能码注解类
    * @throws Exception 异常
    */
   public abstract void scanAnnotationCode() throws Exception ;
   /**
    * 扫描识别功能码注解类
    * @param driver 驱动
    * @param protocolName 协议名称
    * @param scanRootPackage 扫描包
    * @throws Exception 异常
    */
   @SuppressWarnings("unchecked")
   protected void doScanAnnotationCode(Driver driver, String protocolName, String scanRootPackage) throws Exception{
      Reflections reflections = new Reflections(scanRootPackage); // 指定包名
      String code ;
      String[] codes ;
      Class<CodeParse> codeParseClazz ;
      Set<Class<?>> codeUpClasses = reflections.getTypesAnnotatedWith(AnnotationCodeUp.class);
      if (codeUpClasses != null && codeUpClasses.size() > 0) {
         for (Class<?> clazz : codeUpClasses) {
            AnnotationCodeUp ann = clazz.getAnnotation(AnnotationCodeUp.class) ;
            if(ann != null){
               codeParseClazz = (Class<CodeParse>)clazz ;
               codes = ann.ifAny() ;
               if(codes.length > 0){
                  for(String cd: codes){
                     cd = cd.trim() ;
                     if(!(cd.trim().equals(""))){
                        if(driver.upCode2Classes.containsKey(cd)){
                           throw new Exception("严重错误,协议" + protocolName + "的上行数据功能码" + cd + "出现了重复注解!") ;
                        }
                        driver.upCode2Classes.put(cd, codeParseClazz) ;
                     }
                  }
               }else{
                  code = ann.value().trim() ;
                  if(!(code.equals(""))){
                     if(driver.upCode2Classes.containsKey(code)){
                        throw new Exception("严重错误,协议" + protocolName + "的上行数据功能码" + code + "出现了重复注解!") ;
                     }
                     driver.upCode2Classes.put(code, codeParseClazz) ;
                  }
               }
            }
         }
      }
      Set<Class<?>> codeDownClasses = reflections.getTypesAnnotatedWith(AnnotationCodeDown.class);
      if (codeDownClasses != null && codeDownClasses.size() > 0) {
         for (Class<?> clazz : codeDownClasses) {
            AnnotationCodeDown ann = clazz.getAnnotation(AnnotationCodeDown.class) ;
            if(ann != null){
               codeParseClazz = (Class<CodeParse>)clazz ;
               codes = ann.ifAny() ;
               if(codes.length > 0){
                  for(String cd: codes){
                     cd = cd.trim() ;
                     if(!(cd.trim().equals(""))){
                        if(driver.downCode2Class.containsKey(cd)){
                           throw new Exception("严重错误,协议驱动" + protocolName + "的下行数据功能码" + cd + "出现了重复注解!") ;
                        }
                        driver.downCode2Class.put(cd, codeParseClazz) ;
                     }
                  }
               }else{
                  code = ann.value() ;
                  if(!(code.trim().equals(""))){
                     if(driver.downCode2Class.containsKey(code)){
                        throw new Exception("严重错误,协议驱动" + protocolName + "的下行数据功能码" + code + "出现了重复注解!") ;
                     }
                     driver.downCode2Class.put(code, codeParseClazz) ;
                  }
               }
            }
         }
      }
   }
   /**
    * 单线程单例Driver模式下运行
    * 得到上行数据功能码处理类CodeParse对象
    * @param code 功能码
    * @return CodeParse
    * @throws Exception 异常
    */
   public CodeParse getUpCodeParser(String code) throws Exception{
      CodeParse codeParse = upCode2ClassInstance.get(code) ;
      if(codeParse == null){
         Class<CodeParse> clazz = upCode2Classes.get(code) ;
         if(clazz == null){
            clazz = upCode2Classes.get(ProtocolConstant.anyCode) ;
         }
         if(clazz != null){
            //codeParse = clazz.newInstance() ;
            codeParse = clazz.getDeclaredConstructor().newInstance();
            upCode2ClassInstance.put(code, codeParse) ;
         }
      }
      return codeParse ;
   }
   /**
    * 单线程单例Driver模式下运行
    * 得到下行数据功能码处理类CodeParse对象
    * @param code 功能码
    * @return CodeParse
    * @throws Exception 异常
    */
   public CodeParse getDownCodeParser(String code) throws Exception{
      CodeParse codeParse = downCode2ClassInstance.get(code) ;
      if(codeParse == null){
         Class<CodeParse> clazz = downCode2Class.get(code) ;
         if(clazz == null){
            clazz = downCode2Class.get(ProtocolConstant.anyCode) ;
         }
         if(clazz != null){
            //codeParse = clazz.newInstance() ;
            codeParse = clazz.getDeclaredConstructor().newInstance();
            downCode2ClassInstance.put(code, codeParse) ;
         }
      }
      return codeParse ;
   }
   /**
    * 解析RTU上行数据
    * @param isLowPower 是否在低功耗环境下运行
    * @param rtuAddr 控制器地址
    * @param upBuffer 字节数组
    * @param upHex 字节数组16进制形式
    * @param callback 回调
    * @return MidResult[]
    */
   public abstract MidResult[] parseData(Boolean isLowPower, String rtuAddr, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) ;
   /**
    * 构造下行数据(命令)
    * @param isLowPower 是否在低功耗环境下运行
    * @param command 命令
    * @return MidResult[]
    */
   public abstract MidResult[] createCommand(Boolean isLowPower, Command command, Object... params);
}