状态设计模式之实践。

需求如下:

These are the filters, in priority order:

1- GetCardInput.AcqIndexList:

If application send this list, then the library must search just for these index in the table.

For example:

GetCardInput.AcqIndexList = ('1701', '1702', '1703').

In this case, if the card inserted/swiped does not match with these three rows, library must return GetCardOutput.ReturnCode = CARDAPPNAV.

IF GetCardInput.AcqIndexList == null, then try to filter by CardAppType:

2- GetCardInput.CardAppType:

If application sends GetCardInput.CardAppType == 1, then the library must filter all the table by app type and return just rows with app type == 1.

If application sends GetCardInput.CardAppType == 2, then the library must filter all the table by app type and return just rows with app type == 2.

If the card inserted/swiped does not match, library must return GetCardOutput.ReturnCode = CARDAPPNAV.

If application sends GetCardInput.CardAppType == 99, then the library use the hole table rows.

IF GetCardInput.CardAppType == 0, then try to filter by AcquirerId:

3- GetCardInput.AcquirerId:

In this case, the library must filter all the table by acquirer id;

4- If application sends GetCardInput.CardAppType != 0 and Acquirer Id != 0, then library must use the both values to filter the table.

1.在把AID添加到内核的时候执行添加动作。进入过滤状态设计模式。退出的时候就已经把值赋值好了。

首先,需要设置context类,这个类包括数据库句柄。

GetCardInput inputData;

List<AidInfo> filteredTable;用于保存从数据库里查询出来的AID及优先级。

public boolean addAidList() {
        cardFilterContext.setState(new InitialState(cardFilterContext));
        try {
            while (true) {
                cardFilterContext.applyFilter();
                if (cardFilterContext.getState() instanceof QuitFiltertable) {
                    // Logic for quitting CVM
                    Logs.d(TAG, "QuitFiltertable");
                    addAidToEmvList();
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

其中,抽象状态类。要设置成抽象,因为还有公共的实现函数。并且把context类放在里面,

便于具体状态类继承并使用。

public abstract class State {

    protected CardFilterContext cardFilterContext;

    public State(CardFilterContext cardFilterContext ) {
        this.cardFilterContext = cardFilterContext;
    }
    static final String TAG = InitializeAppState.class.getSimpleName();
    public abstract void applyFilter();

    public  List<AidInfo> processQueryResult(List<Map<String, Object>> queryResult) {
        List<AidInfo> aidInfoList = new ArrayList<>();
        for (Map<String, Object> result : queryResult) {
            // 根据实际情况处理每一行结果,并转换为 AidInfo 对象
            String aidValue = (String) result.get(EmvDbHelper.aid);
            int priority = (int) result.get(EmvDbHelper.aidPriority);
//            byte priority = (byte) result.get(EmvDbHelper.aidPriority);
            Logs.d(TAG,"aidValue "+ aidValue);
            Logs.d(TAG,"aidPriority "+ priority);
            AidInfo aidInfo = new AidInfo(aidValue, (byte)priority);
            aidInfoList.add(aidInfo);
        }
        return aidInfoList;
    }
}

3.具体状态类。

public class InitialState extends State {

    private final String TAG = "InitialState";
    public InitialState(CardFilterContext context) {
        super(context);
    }
    @Override
    public void applyFilter() {
        if (cardFilterContext.inputData.getAcqIndexList() != null && !cardFilterContext.inputData.getAcqIndexList().isEmpty()) {
            // Execute AcqIndexList filter
            List<String> acqIndexList = cardFilterContext.inputData.getAcqIndexList();
            List<Map<String, Object>> queryResult = queryDbWithAcqIndexList(acqIndexList,cardFilterContext.getDbManager());
            List<AidInfo> aidInfoList = processQueryResult(queryResult);
            cardFilterContext.setFilteredTable(aidInfoList);
            cardFilterContext.setState(new QuitFiltertable(cardFilterContext));
        } else {
            // Transition to CardAppType state
            cardFilterContext.setState(new CardAppTypeState(cardFilterContext));
        }
    }

    public List<Map<String, Object>> queryDbWithAcqIndexList(List<String> acqIndexList,DbManager dbManager) {
        String[] selectionColumns = {EmvDbHelper.acquirerId, EmvDbHelper.aidIndex};
        String[] columnsToSelect = {EmvDbHelper.aid, EmvDbHelper.aidPriority};
        List<Map<String, Object>> result = new ArrayList<>();
        // 初始化一个空数组
        String[] selectionValues = new String[2];
        // 遍历 acqIndexList,对每个字符串进行拆分并查询
        for (String acqIndex : acqIndexList) {
            // 进行拆分逻辑,这里示例取前两个字符
            if (acqIndex.length() >= 4) {
                // 取前两个字符作为第一个值
                String part1 = acqIndex.substring(0, 2);
                // 取后两个字符作为第二个值
                String part2 = acqIndex.substring(2, 4);
                // 将拆分后的值赋值给 selectionValues 数组
                selectionValues[0] = part1;
                selectionValues[1] = part2;
                // 进行查询并将结果添加到结果集
                List<Map<String, Object>> queryResult = dbManager.getColumnMapValuesWithCondition(
                        selectionColumns, selectionValues, columnsToSelect);
                result.addAll(queryResult);
            } else {
                Logs.e(TAG,"acqIndex.length() "+ acqIndex.length());
                break;
            }
        }
        // 返回查询结果
        return result;
    }

}

还有一个需求就是返回ReturnCode = CARDAPPNAV.

如果拿到选择应用的结果就返回并设置对应的ReturnCode

 public boolean Appselect() {
        ContextAppSelete contextAppSelete = new ContextAppSelete();
        contextAppSelete.setState(new SelectAppState(contextAppSelete));
        try {
            while (true) {
                contextAppSelete.executeSelectFinalApp();
                if (contextAppSelete.getState() instanceof QuitFinalAppState) {
                    contextAppSelete.executeSelectFinalApp();
                    if (contextAppSelete.getErrorCode()!=0) {
                        getCardOutput.setReturnCode(contextAppSelete.getReturnCodes());
                        return false;
                    } else {
                        emv_candlist = contextAppSelete.getEmvCandlist();
                        Logs.d(TAG, "emv_candlist.aid " + tools.hexString(emv_candlist.aid, 0, emv_candlist.aidLen));
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
相关推荐
tyler_download1 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
编程、小哥哥16 分钟前
设计模式之抽象工厂模式(替换Redis双集群升级,代理类抽象场景)
redis·设计模式·抽象工厂模式
2401_8574396919 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧66620 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
李老头探索22 分钟前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试
weixin_4493108427 分钟前
高效集成:聚水潭采购数据同步到MySQL
android·数据库·mysql
芒果披萨27 分钟前
Filter和Listener
java·filter
qq_49244844632 分钟前
Java实现App自动化(Appium Demo)
java
阿华的代码王国40 分钟前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
Cachel wood1 小时前
Github配置ssh key原理及操作步骤
运维·开发语言·数据库·windows·postgresql·ssh·github