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);
|
|
|
}
|