| package com.dy.common.mw.protocol; | 
|   | 
| import java.net.URI; | 
| import java.util.HashMap; | 
| import java.util.List; | 
|   | 
| import com.dy.common.util.ClassScan; | 
|   | 
|   | 
| 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<>() ; | 
|   | 
|     /** | 
|      * 单线程单例Driver模式下运行 | 
|      * 扫描识别功能码注解类 | 
|      * @throws Exception 异常 | 
|      */ | 
|     public abstract void scanAnnotationCode() throws Exception ; | 
|      | 
|     /** | 
|      * 扫描识别功能码注解类 | 
|      * @param driver 驱动 | 
|      * @param protocolName 协议名称 | 
|      * @param uri URI | 
|      * @param scanRootPackage 扫描包 | 
|      * @throws Exception 异常 | 
|      */ | 
|     @SuppressWarnings("unchecked") | 
|     protected void doScanAnnotationCode(Driver driver, String protocolName, URI uri, String scanRootPackage) throws Exception{ | 
|         ClassLoader load = driver.getClass().getClassLoader() ; | 
|         List<String> classNames = new ClassScan().searchClassFromUrl(new URI[]{uri}, scanRootPackage) ; | 
|         if(classNames != null && classNames.size() > 0){ | 
|             String code ; | 
|             String[] codes ; | 
|             for(String cName : classNames){ | 
|                 String className = cName.substring(0,  cName.lastIndexOf('.')) ; | 
|                 Class<?> clazz = load.loadClass(className) ; | 
|                 Class<CodeParse> codeParseClazz ; | 
|                 if(clazz.isAnnotationPresent(AnnotationCodeUp.class)){ | 
|                     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) ; | 
|                             } | 
|                         } | 
|                     } | 
|                 } | 
|                  | 
|                 if(clazz.isAnnotationPresent(AnnotationCodeDown.class)){ | 
|                     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); | 
|      | 
|      | 
| } |