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