| New file | 
 |  |  | 
 |  |  | 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); | 
 |  |  | 	 | 
 |  |  |  | 
 |  |  |    /** | 
 |  |  |     * 构造下行透传数据(命令) | 
 |  |  |     * @param isLowPower 是否在低功耗环境下运行 | 
 |  |  |     * @param command 命令 | 
 |  |  |     * @return MidResult[] | 
 |  |  |     */ | 
 |  |  |    public MidResult[] transparentCommand(Boolean isLowPower, Command command, Object... params){ | 
 |  |  |       return null ; | 
 |  |  |    } | 
 |  |  |  | 
 |  |  |  | 
 |  |  | } |