SystemConstant.java

package com.mycim.valueobject;

import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.valueobject.security.User;

import java.util.List;
import java.util.function.BiFunction;

/**
 * @author yibing.liu
 * @version 1.0
 * @date 2021/5/13
 */
public interface SystemConstant {

    //字符串常量
    class Str {
        public static final String SYSTEM       = "SYSTEM";
        public static final String ON           = "ON";
        public static final String OFF          = "OFF";
        public static final String ZERO         = "0";
        public static final String ONE          = "1";
        public static final String TWO          = "2";
        public static final String THREE        = "3";
        public static final String FOUR         = "4";
        public static final String FIVE         = "5";
        public static final String NINE         = "9";

        public static final String PARALLEL     = "PARALLEL";
        public static final String SERIAL       = "SERIAL";
        public static final String EXIST        = "EXIST";

        public static final String PERCENTAGE   = "%";

        public static final String WAFER        = "WAFER";
        public static final String NO           = "NO";
        public static final String YES          = "YES";

        public static final String ACTION_FLAG  = "actionFlag";

        public static final String NORMAL_MERGE = "NormalMerge";

        public static final String LOT_RRN_LIST = "lotRrnList";

        public static final String CAL_STEP_TIME = "calStepTime";

        public static final String ALL          = "ALL";

        public static final String BR           = "<br>";

        public static final String PAUSE_FLAG   = "pauseFlag";

        public static final String TIME_START   = " 00:00:00";

        public static final String TIME_END     = " 23:59:59";

        public static final String ACTIVE       = "ACTIVE";

        public static final String OTHER_TO_PM  = "_TO_PM";

        public static final String PM_TO_OTHER  = "EQP.PM_TO_";

        public static final String SUCCESS      = "success";

        public static final String MESSAGE      = "message";

        public static final String SUB_RECIPE_SEPARATOR = "-";

        public static final String NUM_TRUE     = "1";

        public static final String RC_SORT_OVER = "rcSortJobOver";

        public static final String BLANK        = " ";

        public static final String SPECIAL_CHAR = "^[ ]*[\\w-@%/\\$\\.()?]+[ ]*$";

        //536的自动创建会使用 按照实施要求 不允许使用或自动创建 $开头的recipe
        public static final String RECIPE_REGEX_FOR_536 = "^[A-Z0-9.%/()_-]{1,127}$";

        //普通recipe创建允许出现$R 535  71 Recipe Setup
        public static final String RECIPE_REGEX="^((\\$R)?[A-Z0-9.%/()_-]?){1,127}$";

        public static final String SPECIAL_ROLE = "SPECIAL_ROLE";

        public static final String MORE_THAN = ">";
        public static final String LESS_THAN = "<";


        /**
         * 截取指定长度的字符串,中文算2,字母和数字算1
         * @param str
         * @param start
         * @param end
         * @return
         */
        public static String SubString(String str, int start, int end) {
            if (start < end) {
                return str;
            }
            int length;
            if ((length = calculateActualLength(str, start, end)) > 0){
                return StringUtils.substring(str, start, length-1);
            }
            return StringUtils.substring(str, start, end);
        }

        private static int calculateActualLength(String str, int start, int end) {
            int length = 0;
            for(int i = start; i < str.length(); i++) {
                int ascii = Character.codePointAt(str, i);
                if(ascii >= 0 && ascii <=255){
                    length++;
                } else {
                    length += 2;
                }
                if (length > end){
                    return i;
                }
            }

            return 0;
        }
    }

    class PmSchedule{
        public static final String CONSUME_BOOKED   = "BOOKED";
        public static final String CONSUMED         = "CONSUMED";
        public static final String PARTS_BANK       = "PARTS_BANK";
        public static final String PM_END_CONSUME   = "PM ID:";
    }

    class AsyncReposition {
        public static final int     QUERY_SIZE          = 10;
        public static final String  QUERY_SIZE_STR      = "QUERYSIZE";
        public static final String  SPECIAL             = "SPECIAL";
        public static final String  NORMAL              = "NORMAL";
        public static final String  QUEUE_SKIP_FLAG_Y   = "Y";
        public static final String  QUEUE_SKIP_FLAG_N   = "N";

        public static final long    NEED_RETRY_ERROR    = 20000;
        public static final long    NEED_DISCARD_ERROR  = 30000;

        public static final long    CODE_SUCCESS        = 10000;

        public static final String  LOT_SAMPLING        = "LOT_SAMPLING";
        public static final String  LOOP_SKIP           = "LOOP_SKIP";

    }

    class SystemUser {
        public static final long SYSTEM_RRN             = 0L;
        public static final String SYSTEM_USER          = "SYSTEM";

        public static User getSystemUser(){
            User user = new User();
            user.setInstanceRrn(SYSTEM_RRN);
            user.setInstanceId(SYSTEM_USER);
            return user;
        }
    }

    class Pcd {
        public static final String  CARRIER    = "CARRIER";
        public static final String  POD        = "POD";
        public static final String  DOOR       = "DOOR";
        public static final String  C          = "C";
        public static final String  P          = "P";
        public static final String  D          = "D";

        public final static String CARRIER_TYPE         = "carrierType";
        public final static String DOOR_TYPE            = "doorType";
        public final static String POD_TYPE             = "podType";

        public final static String CARRIER_COLOR        = "carriercolor";
        public final static String POD_COLOR            = "podcolor";
        public final static String DOOR_COLOR           = "doorcolor";

        public final static String PCD_STATUS           = "PCDSTATUS";
        public final static String DOOR_STATUS          = "doorStatus";
        public final static String POD_STATUS           = "podStatus";

        public final static String PCD_CATEGORY         = "PCDCATEGORY";
        public final static String POD_CATEGORY         = "podCategory";

        public final static String CARRIER_SIZE         = "carrierSize";
        public final static String WAFER_SIZE           = "WAFER_SIZE";

        public final static String BUILD_CARRIER_TYPE   = "buildCarrierType";
        public final static String BUILD_DOOR_TYPE      = "buildDoorType";
        public final static String BUILD_POD_TYPE       = "buildPodType";

        public static final Object PCD_ID_LENGTH        = 64;
        public static final String PCD_ID_OUT_OF_RANGE  = "-1";


        public static String increasePcdPrefix(String ignoreLetter, String currentDBMaxSeq, int numberWidth, String prefix, List<String> ignorePrefixSetting){
            String letterPart, numberPart = StringUtils.EMPTY; //数字正自增,字母反序自增
            final char start = 0x41, z = 0x40;//A
            char [] currentMaxSeqCharArr =  currentDBMaxSeq.toCharArray();// 0001/ 9999/ A999 / Z999
            char[] digitArr = new char[numberWidth];
            char[] letterArr = new char[numberWidth];
            int index = 0;
            for (char c:currentMaxSeqCharArr){
                if (Character.isDigit(c)){
                    digitArr[index++] = c;
                } else {
                    letterArr[index++] = c;
                }
            }
            String digitStr = notNullStr(digitArr);
            String letterStr = notNullStr(letterArr);
            int digitWidth = StringUtils.length(digitStr);//数字长度
            int letterWidth = StringUtils.length(letterStr);//字母长度
            if (digitWidth == numberWidth){ //0001/ 9999/
                String numIncrease = increaseNumber(digitStr);
                if (numIncrease.length() > numberWidth){ //已超出最大数字
                    numIncrease = increaseNumber(numIncrease); //以 尾号1开头。
                    String letterTemp = String.valueOf(z);
                    do {
                        letterTemp = increaseLetter(letterTemp, ignoreLetter);
                        letterPart = prefix + letterTemp;
                    } while (!SystemConstant.Pcd.checkPrefixFunction().apply(ignorePrefixSetting, letterPart));
                    numberPart = StringUtils.substring(numIncrease, 2);
                } else {
                    //纯数字自增
                    letterPart = prefix;
                    numberPart = StringUtils.leftPad(numIncrease, digitWidth,"0");
                }
            } else if (letterWidth == numberWidth) { // ZAZP 纯字母的自增
                String letterTemp = letterStr;
                do {
                    letterTemp = increaseLetter(letterTemp, ignoreLetter);
                    if (letterTemp.length() > letterStr.length()){
                        return PCD_ID_OUT_OF_RANGE; //纯字母超过最大长度了
                    }
                    letterPart = prefix + letterTemp;
                } while (!SystemConstant.Pcd.checkPrefixFunction().apply(ignorePrefixSetting, letterPart));
            } else { // KZ98 / A999 / Z999 / 字母数字 混合自增
                String numIncrease = increaseNumber(digitStr);
                if (numIncrease.length() > digitWidth){
                    numIncrease = increaseNumber(numIncrease);
                    numberPart = StringUtils.substring(numIncrease, 1);//数字位数不变,字母自增
                    //需要自增到字母
                    String letterTemp = letterStr;
                    do {
                        letterTemp = increaseLetter(letterTemp, ignoreLetter);
                        if (letterTemp.length() > letterWidth){
                            letterTemp = letterStr + start;
                            numberPart = StringUtils.substring(numIncrease, 2);//数字位数减少一位,字母增加一位
                        }
                        letterPart = prefix + letterTemp;
                    } while (!SystemConstant.Pcd.checkPrefixFunction().apply(ignorePrefixSetting, letterPart));

                } else {
                    letterPart = prefix + notNullStr(letterArr);
                    numberPart = StringUtils.leftPad(numIncrease, digitWidth,"0");;
                }
            }
            return letterPart + numberPart;
        }

        static BiFunction<List<String>, String, Boolean> checkPrefixFunction() {
            return (ignorePrefixList, createLotId)->{
                if (CollectionUtils.isNotEmpty(ignorePrefixList)){
                    return ignorePrefixList.stream().parallel().noneMatch(createLotId::startsWith);//并发过滤 如果开头在过滤范围内。则直接重新生成
                }
                return true;
            };
        }

        private static String increaseNumber(String numberStr){ return Long.toString(Long.parseLong(numberStr) + 1); }

        private static String increaseLetter(String letterStr, String ignoreLetter){
            final char start = 0x41, end = 0x5A;//A,Z
            char [] lca = letterStr.toCharArray();
            int increaseNum = 0;
            boolean carry = false;
            for (int i = 0; i < lca.length; i++){//从第一位开始 +1
                if (carry){
                    char c = lca[i];
                    if (c < end){
                        c = increase(lca[i], ignoreLetter);
                        if (c < end){
                            lca[i] = c;
                            increaseNum ++;
                            break;
                        }
                    }
                } else {
                    char c = lca[i];
                    if (c < end){
                        c = increase(c, ignoreLetter);
                        if (c < end){
                            lca[i] = c;
                            increaseNum ++;
                            break;
                        } else {
                            carry = true;
                        }
                    } else {//B + 1 = C
                        carry = true;
                    }
                }

            }
            if (increaseNum == 0 && carry){
                return start + notNullStr(lca);
            } else {
                return notNullStr(lca);
            }
        }

        private static char increase(char c, String ignoreLetter){
            do {
                ++c;
            } while (StringUtils.contains(ignoreLetter, String.valueOf((c))));
            return c;
        }

        private static String notNullStr(char[] arr){
            StringBuilder str = new StringBuilder(StringUtils.EMPTY);
            for (char c:arr){
                if (c != '\u0000'){
                    str.append(c);
                }
            }
            return str.toString();
        }

    }


}