NonRTMathUtil.java

package com.mycim.utils;

import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalStateException;
import com.mycim.framework.utils.lang.StringUtils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.math.BigDecimal;
import java.util.Arrays;


/**
 * @author songpy
 * <p>
 * 根据绍兴版本,优化离线导入
 * </p>
 */
public class NonRTMathUtil {

    public static String NONRT_FORMULA_PRE_KEY = "PRE";

    public static String NONRT_FORMULA_POST_KEY = "POST";

    public static String NONRT_FORMULA_TIME_KEY = "TIME";

    public static String NONRT_IMPORT_TYPE_MANUAL = "Manual";

    public static String NONRT_IMPORT_TYPE_AUTO = "Semi-auto";

    public static String NONRT_IMPORT_TYPE_AUTO_MONITOR = "AutoMonitor";

    public static boolean isNeedHoldEqptImportType(String importType) {

        String[] needHoldType = new String[]{NONRT_IMPORT_TYPE_MANUAL, NONRT_IMPORT_TYPE_AUTO};

        for (String type : needHoldType) {
            if (StringUtils.equals(importType, type)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isAvaliableFormula(String formulaType) {
        return StringUtils.isNotBlank(getNonRTFormula(formulaType));
    }

    public static String getNonRTFormula(String formulaType) {
        String formula = "";

        if (StringUtils.startsWith(formulaType, "A")) {
            formula = "POST";
        } else if (StringUtils.startsWith(formulaType, "B")) {
            formula = "(PRE-POST)/TIME";
        } else if (StringUtils.startsWith(formulaType, "C")) {
            formula = "POST-PRE";
        } else if (StringUtils.startsWith(formulaType, "D")) {
            formula = "(POST-PRE)/TIME";
        } else if (StringUtils.startsWith(formulaType, "E")) {
            formula = "MFC/LF";
        } else if (StringUtils.startsWith(formulaType, "F")) {
            formula = "(MAX-MIN)/(2*AVG)";
        } else if (StringUtils.startsWith(formulaType, "G")) {
            formula = "STDEV/MEAN";
        }
        return formula;
    }

    public static boolean isBasicFormula(String formulaType) {
        String[] deriveFormula = new String[]{"E", "F", "G"};
        if (Arrays.asList(deriveFormula).contains(formulaType)) {
            return false;
        }
        return true;
    }

    public static boolean isNeedPreValue(String formulaType) {
        String[] needPreValueFormulaType = new String[]{"B", "C", "D"};

        for (String needPreValue : needPreValueFormulaType) {
            if (StringUtils.contains(formulaType, needPreValue)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isDirectUploadFormula(String formulaType) {
        if (StringUtils.contains(formulaType, "A")) {
            return true;
        }
        return false;
    }

    public static boolean isEqptNonRT(String formulaType) {
        if (StringUtils.equals(formulaType, "E")) {
            return true;
        }
        return false;
    }

    public static boolean isNeedDeriveChart(String formulaType) {
        if (StringUtils.contains(formulaType, ",")) {
            return true;
        }
        return false;
    }

    private static double mathDataValue(String formula) {

        try {
            ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
            return new BigDecimal(new Double(jse.eval(formula).toString())).setScale(4, BigDecimal.ROUND_HALF_UP)
                                                                           .doubleValue();
        } catch (Exception e) {
            throw new SystemIllegalStateException(Errors.create().content(e.getMessage()).build());
        }
    }

    public static double mathDataValue(String formulaType, double[] dataValues) {
        String formula = getNonRTFormula(formulaType);

        if (dataValues.length > 1) {
            if (StringUtils.equals("F", formulaType)) {
                double max = 0;
                double min = 0;
                double all = 0;
                for (int i = 0; i < dataValues.length; i++) {
                    if (i == 0) {
                        max = dataValues[i];
                        min = dataValues[i];
                    }
                    if (dataValues[i] > max) {
                        max = dataValues[i];
                    }
                    if (dataValues[i] < min) {
                        min = dataValues[i];
                    }
                    all += dataValues[i];
                }
                double avg = all / dataValues.length;

                formula = StringUtils.replace(formula, "MAX", "(" + max + ")");
                formula = StringUtils.replace(formula, "MIN", "(" + min + ")");
                formula = StringUtils.replace(formula, "AVG", "(" + avg + ")");
            } else if (StringUtils.equals("G", formulaType)) {
                double all = 0;
                for (int i = 0; i < dataValues.length; i++) {
                    all += dataValues[i];
                }
                double avg = all / dataValues.length;

                double stdev = 0;
                for (int i = 0; i < dataValues.length; i++) {
                    stdev += (dataValues[i] - avg) * (dataValues[i] - avg);
                }
                stdev = stdev / (dataValues.length - 1);
                stdev = Math.sqrt(stdev);

                formula = StringUtils.replace(formula, "STDEV", "(" + stdev + ")");
                formula = StringUtils.replace(formula, "MEAN", "(" + avg + ")");
            }
        } else {
            return 0d;
        }

        return mathDataValue(formula) * 100;
    }

    public static double mathDataValue(String formulaType, double pre, double post, String time) {
        String formula = getNonRTFormula(formulaType);
        formula = StringUtils.replace(formula, NONRT_FORMULA_PRE_KEY, "(" + pre + ")");
        formula = StringUtils.replace(formula, NONRT_FORMULA_POST_KEY, "(" + post + ")");
        formula = StringUtils.replace(formula, NONRT_FORMULA_TIME_KEY, transFractionTime(time));
        return mathDataValue(formula);
    }

    private static String transFractionTime(String time) {
        if (StringUtils.contains(time, "/")) {
            time = StringUtils.replace(time, "/", ")*(");
        }
        time = "(" + time + ")";
        return time;
    }

}