SpecialRule.java

package com.mycim.valueobject.edcspc.rule;

import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.valueobject.edcspc.DataCollectionRule;
import com.mycim.valueobject.edcspc.responseModel.ParameterRuleDetailResponse;
import com.mycim.valueobject.wip.Unit;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Aiden
 * @date 2018年12月18日下午4:30:53
 * @description 特殊规则通过top, center, Bottom的概念进行控制
 */
public class SpecialRule extends CollectionRuleAbstract implements CollectionRule {

    public static final String TOP_KEY = "Top";

    protected static final int TOP_LENGTH_KEY = 3;

    protected static final String CENTER_KEY = "Center";

    protected static final int CENTER_LENGTH_KEY = 6;

    protected static final String BOTTOM_KEY = "Bottom";

    protected static final int BOTTOM_LENGTH_KEY = 6;

    protected static final String ADD_KEY = "+";

    protected static final String REDUCE_KEY = "-";

    protected SpecialRule(DataCollectionRule dataCollectionRule, List<Unit> unitList) {
        super(dataCollectionRule, unitList);
    }

    @Override
    public Boolean isAvailableDataCollectionRule() {
        DataCollectionRule dataCollectionRule = getDataCollectionRule();
        List<Unit> unitList = getUnitList();
        int total = unitList.size();
        List<ParameterRuleDetailResponse> ruleDetails = dataCollectionRule.getRuleDetail();
        // 1.check是否能匹配上已有的区间和区间内的采集数量
        ParameterRuleDetailResponse availableDetail = getAvailableDetail(ruleDetails, total);
        if (availableDetail == null) {
            return false;
        }
        String selectedWafer = availableDetail.getSelectedWafer();
        String[] positionInfos = selectedWafer.split(",");
        int sampleSize = positionInfos.length;// 采集数量
        setWaferSamples(positionInfos);
        dataCollectionRule.setWaferSample(selectedWafer);

        // 2. 确定片子
        if (total <= sampleSize) {
            // wafer总数小于等于需要采集的数量时直接全部采集
            sampleSize = total;
            for (int index = 0; index < total; index++) {
                addToResultForNormalIndex(index);
            }
        } else {
            List<Integer> availableUnitIndexs = new ArrayList<Integer>();
            // 2.1 解析位置规则
            for (String positionInfo : positionInfos) {
                Integer availableUnitIndex = getAvailableUnitIndex(positionInfo);
                if (availableUnitIndexs.contains(availableUnitIndex)) {
                    continue;// 存在重复的unit index时,不加入

                    //重复的先跳过,后面edc暂停代码开发好之后再来check这种情况
                    //return false;
                }
                availableUnitIndexs.add(availableUnitIndex);// 用于比较是否重复
                addToResultForNormalIndex(availableUnitIndex);// 增加到可采集的list里
            }

            sampleSize = availableUnitIndexs.size();
        }

        // check 实际可用数量和需要采集的数量是否一致
        return checkResult(sampleSize);
    }


    /**
     * @param ruleDetails
     * @param total
     * @return ParameterRuleDetailResponse
     * @Description 获得可用的匹配区间
     * @author Aiden
     */
    private ParameterRuleDetailResponse getAvailableDetail(List<ParameterRuleDetailResponse> ruleDetails, int total) {
        for (ParameterRuleDetailResponse detail : ruleDetails) {
            Integer qtyRangeStart = detail.getQtyRangeStart();
            Integer qtyRangeEnd = detail.getQtyRangeEnd();
            if (qtyRangeStart <= total && total <= qtyRangeEnd) {
                return detail;
            }
        }
        return null;
    }

    private Integer getAvailableUnitIndex(String positionInfo) {
        int unitSize = getUnitList().size();
        int maxIndex = unitSize - 1;
        int tempIndex = -1;
        String symbol = "+";
        String changeIndexStr = "0";
        //说明:由于加减是根据index来计算的,12寸项目  都是 25~1的slot,所以index计算时,符号反着来
        if (isTop(positionInfo)) {
            tempIndex = 0;
            if (positionInfo.length() > TOP_LENGTH_KEY) {
                //top只能减,但是index是通过加来实现
                symbol = ADD_KEY;
                changeIndexStr = positionInfo.substring(TOP_LENGTH_KEY + 1, positionInfo.length());
            }
        } else if (isCenter(positionInfo)) {
            tempIndex = Math.round((float) getUnitList().size() / 2) - 1;
            if (positionInfo.length() > CENTER_LENGTH_KEY) {
                symbol = positionInfo.substring(CENTER_LENGTH_KEY, CENTER_LENGTH_KEY + 1);
                if (ADD_KEY.equals(symbol)) {
                    symbol = REDUCE_KEY;
                } else if (REDUCE_KEY.equals(symbol)) {
                    symbol = ADD_KEY;
                }
                changeIndexStr = positionInfo.substring(CENTER_LENGTH_KEY + 1, positionInfo.length());
            }
        } else if (isBottom(positionInfo)) {
            tempIndex = maxIndex;
            if (positionInfo.length() > BOTTOM_LENGTH_KEY) {
                //bottom只能加,但是index是通过减法来实现
                symbol = REDUCE_KEY;
                changeIndexStr = positionInfo.substring(BOTTOM_LENGTH_KEY + 1, positionInfo.length());
            }
        }
        int changeIndex = getChangeIndex(changeIndexStr);
        return calculationAvailableIndex(tempIndex, symbol, changeIndex);
    }

    private int getChangeIndex(String changeIndexStr) {
        if (StringUtils.isNumeric(changeIndexStr)) {
            return Integer.valueOf(changeIndexStr);
        } else {
            return 0;
        }
    }

    private int calculationAvailableIndex(int tempIndex, String symbol, int changeIndex) {
        int availableIndex = 0;
        if (ADD_KEY.equals(symbol)) {
            availableIndex = tempIndex + changeIndex;
        } else {
            availableIndex = tempIndex - changeIndex;
        }
        int maxIndex = getUnitList().size() - 1;
        if (availableIndex < 0) {// 不在可用的index范围内时
            return 0;
        } else if (availableIndex > maxIndex) {
            return maxIndex;
        } else {
            return availableIndex;
        }
    }

    protected boolean isTop(String string) {
        return string.startsWith(TOP_KEY) ? true : false;
    }

    protected boolean isCenter(String string) {
        return string.startsWith(CENTER_KEY) ? true : false;
    }

    protected boolean isBottom(String string) {
        return string.startsWith(BOTTOM_KEY) ? true : false;
    }

    protected void addToResultForNormalIndex(Integer index) {
        Unit unit = getUnitList().get(index);
        addToResult(StringUtils.toString(unit.getPositionInCarrier()), unit.getUnitId());
    }


}