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> upCode2Classes = new HashMap<>() ; protected HashMap upCode2ClassInstance = new HashMap<>() ; protected HashMap> downCode2Class = new HashMap<>() ; protected HashMap 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 codeParseClazz ; Set> 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)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> 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)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 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 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); }