|  |  |  | 
|---|
|  |  |  | package com.dy.common.mw.protocol; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.net.URI; | 
|---|
|  |  |  | import java.util.HashMap; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  | import java.util.Set; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.dy.common.util.ClassScan; | 
|---|
|  |  |  | import org.reflections.Reflections; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public abstract class Driver { | 
|---|
|  |  |  | 
|---|
|  |  |  | * @throws Exception 异常 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public abstract void scanAnnotationCode() throws Exception ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 扫描识别功能码注解类 | 
|---|
|  |  |  | * @param driver 驱动 | 
|---|
|  |  |  | 
|---|
|  |  |  | * @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) ; | 
|---|
|  |  |  | 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) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }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) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }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对象 | 
|---|
|  |  |  | 
|---|
|  |  |  | return codeParse ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 解析上行数据 | 
|---|
|  |  |  | * 解析RTU上行数据 | 
|---|
|  |  |  | * @param isLowPower 是否在低功耗环境下运行 | 
|---|
|  |  |  | * @param rtuAddr 控制器地址 | 
|---|
|  |  |  | * @param upBuffer 字节数组 | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return MidResult[] | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public abstract MidResult[] parseData(Boolean isLowPower, String rtuAddr, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) ; | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 解析电信平台上行数据 | 
|---|
|  |  |  | * @param isLowPower 是否在低功耗环境下运行 | 
|---|
|  |  |  | * @param rtuAddr 控制器地址 | 
|---|
|  |  |  | * @param productId 电信平台产品ID,当不在电信平台中运行时,为null | 
|---|
|  |  |  | * @param deviceId 电信平台设备ID,当不在电信平台中运行时,为null | 
|---|
|  |  |  | * @param upBuffer 字节数组 | 
|---|
|  |  |  | * @param upHex 字节数组16进制形式 | 
|---|
|  |  |  | * @param callback 回调 | 
|---|
|  |  |  | * @return MidResult[] | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public abstract MidResult[] parseData(Boolean isLowPower, String rtuAddr, Integer productId, String deviceId, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 构造下行数据(命令) | 
|---|