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 ;
|
}
|
/**
|
* 解析上行数据
|
* @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 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) ;
|
|
/**
|
* 构造下行数据(命令)
|
* @param isLowPower 是否在低功耗环境下运行
|
* @param command 命令
|
* @return MidResult[]
|
*/
|
public abstract MidResult[] createCommand(Boolean isLowPower, Command command, Object... params);
|
|
|
}
|