1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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 command 命令
     * @return MidResult[]
     */
    public abstract MidResult[] createCommand(Boolean isLowPower, Command command, Object... params);
    
    
}