Convert the Boolean judgment expression into a conditional Javabean (the conditional structure can theoretically iterate through countless levels), and use it to judge the Boolean result finally generated by the form submission parameters.

Without further ado, let’s get into the code. The code format is wrong, and for some reason, it can only be copied bit by bit.

public List<ActBPMNSequenceFlowConditionExpression> parseConditionExpressionToList(String conditionExpressionStr, Boolean ifJustExtra) {
        //1. Initialize variables
        //1.1 The aggregated conditional expression of the current flow direction to be finally returned
        List<ActBPMNSequenceFlowConditionExpression> conditionExpressions = new ArrayList<>();
        //1.2 Level 1 is the highest level, returning the levels of all expressions and their coordinates
        LinkedHashMap<Integer, List<ActAtomicCoordinate>> sortedMap = this.getBracketPairs(conditionExpressionStr, ActivitiConst.BRACKET_LEFT_CHAR);
        //1.3 All English column names that need to be converted to Chinese columns
        Set<String> colEnNames = new HashSet<>();
        //2. Start aggregating conditional expressions
        // The size<=1 of sortedMap indicates that the Boolean expression contains only basic sign-off judgment conditions or no content, and no processing is required.
        if (sortedMap.size() > 1) {
            //2.1 First obtain the lowest level, that is, the most detailed Boolean judgment conditions. These conditions are all single conditions.
            Integer levelCount = sortedMap.size();
            List<ActAtomicCoordinate> basicCoordinates = sortedMap.get(levelCount);
            List<BoolstrToBoolentity> lowerBoolstrToEntityList = new ArrayList<>();
            //The position of )’ in the previous bool expression
            Integer lastY = null;
            //The position of (’ in the current bool expression
            Integer thisX;
            //The position of )’ in the current bool expression
            Integer thisY;
for (ActAtomicCoordinate basicCoordinate : basicCoordinates) {
                thisX = basicCoordinate.getX().intValue();
                thisY = basicCoordinate.getY().intValue();
                String basicBoolExpressionStr = conditionExpressionStr.substring(thisX, thisY + 1);
                ActBPMNSequenceFlowConditionExpression singleBasicBoolExpressionEntity = this.assembleExpressionEntity(basicBoolExpressionStr, colEnNames);
                lowerBoolstrToEntityList.add(new BoolstrToBoolentity(basicBoolExpressionStr, singleBasicBoolExpressionEntity));
                //2.1.1 Set the connector between conditions
                lastY = this.setConnecor(conditionExpressionStr, singleBasicBoolExpressionEntity, thisX, thisY, lastY);
            }
            /**2.2 Start aggregating the upper expression entities from low to high start **/
            for (int i = levelCount - 1; i > 1; i--) {
                lastY = null;
                List<ActAtomicCoordinate> upperCoordinates = sortedMap.get(i);
                for (ActAtomicCoordinate upperCoordinate : upperCoordinates) {
                    //2.2.1 Initialize the bool expression Entity of the current segment of the current layer
                    ActBPMNSequenceFlowConditionExpression singleUpperBoolExpressionEntity = new ActBPMNSequenceFlowConditionExpression();
                    thisX = upperCoordinate.getX().intValue();
                    thisY = upperCoordinate.getY().intValue();
                    List<String> removedList = new ArrayList<>();
                    List<String> addList = new ArrayList<>();
                    //2.2.2 Obtain the original text of a bool expression string of the current layer based on x and y coordinates
String upperBoolExpressionStr = conditionExpressionStr.substring(thisX, thisY + 1);
                    //2.2.3 If a certain string in the lower layer exists in [original part of the string in the current layer],
                    // Then prove that the boolEntity represented by the lower-level string should be added as a sub-condition to the set of sub-conditions of the boolEntity represented by [the original text of this part of the string in the current layer].
                    // If the number of bracket levels = 2, then counting the outermost curly bracket, the actual extra Boolean expression has only one level, which is a single condition rather than a compound condition.
                    Iterator it = lowerBoolstrToEntityList.iterator();
                    while (it.hasNext()) {
                        String key = ((BoolstrToBoolentity) it.next()).getBoolExpressionStr();
                        if (upperBoolExpressionStr.contains(key)) {
                            ActBPMNSequenceFlowConditionExpression lowerBoolEntity = lowerBoolstrToEntityList.stream().filter(l -> l.getBoolExpressionStr().equals(key)).findFirst().get().getBoolExpressionEntity();
                            if (singleUpperBoolExpressionEntity.getChildren() == null) {
                                List<ActBPMNSequenceFlowConditionExpression> subBoolExpressionEntities = new ArrayList<>();
                                subBoolExpressionEntities.add(lowerBoolEntity);
                                singleUpperBoolExpressionEntity.setChildren(subBoolExpressionEntities);
                            } else {
                                if (!addList.contains(key)) {
                                    singleUpperBoolExpressionEntity.getChildren().add(lowerBoolEntity);
                                }
                            }
                            if (!addList.contains(key)) {
                                addList.add(key);
                            }
                            if (!removedList.contains(key)) {
                                it.remove();
                                removedList.add(key);
                            }
                        }
                    }
//If [some part of the original string text of the current layer] does not contain any lower-level string, then it means that it is not a compound condition, but a single condition
                    if (singleUpperBoolExpressionEntity.getChildren() == null) {
                        singleUpperBoolExpressionEntity = this.assembleExpressionEntity(upperBoolExpressionStr, colEnNames);
                    }
                    lowerBoolstrToEntityList.add(new BoolstrToBoolentity(upperBoolExpressionStr, singleUpperBoolExpressionEntity));
                    //2.2.4 Set the connector between conditions
                    lastY = this.setConnecor(conditionExpressionStr, singleUpperBoolExpressionEntity, thisX, thisY, lastY);
                }
            }
            /**2.2 starts to aggregate the upper expression entities in order from low to high end **/
            //Aggregation ends and all conditional expressions of the current flow direction are returned in aggregated form
            conditionExpressions.addAll(lowerBoolstrToEntityList.stream().map(l -> l.getBoolExpressionEntity()).collect(Collectors.toList()));
        }
        //Only basic judgment conditions
        if (!ifJustExtra) {
            String ss[] = conditionExpressionStr.split(ActivitiConst.VAR_AND);
            String basicAuditConditionStr = ss[ss.length - 1];
            ActBPMNSequenceFlowConditionExpression conditionExpression = new ActBPMNSequenceFlowConditionExpression();
            conditionExpression.setConnector(ActivitiConst.VAR_AND);
            conditionExpression.setBasicAuditCondition(basicAuditConditionStr);
            conditionExpressions.add(conditionExpression);
        }
        //3. Process the Chinese name of the field
        if (CollectionUtils.isNotEmpty(colEnNames)) {
            List<ActAtomicField> actAtomicFields = actCompanyLevelBusinesstypeProcdefRelationService.getBusinessFieldsByColEnNames(new ArrayList<>(colEnNames));
            processColChnNames(conditionExpressions, actAtomicFields);
        }
        return conditionExpressions;
    }

getBracketPairs method:

/**
     * Convert the Boolean expression in the picture into:
     * A set of bracket coordinates descending hierarchically
     */
    private LinkedHashMap<Integer, List<ActAtomicCoordinate>> getBracketPairs(String string, Character symbolLeft) {
        Map<Character, Character> characterHashMap = new HashMap<>();
        characterHashMap.put('(', ')');
        characterHashMap.put('[', ']');
        characterHashMap.put('{', '}');
        Character symbolRight = characterHashMap.get(symbolLeft);
        if (symbolRight == null || symbolRight.toString().length() < 1) {
            return new LinkedHashMap<>();
        }
        char[] strArray = string.toCharArray();
        //Find all left and right () positions
        ArrayList<Integer> rightIndexes = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < strArray.length; i + + ) {
            if (strArray[i] == symbolLeft) {
                list.add(i);
            } else if (strArray[i] == symbolRight) {
                rightIndexes.add(i);
                list.add(i);
            }
        }
LinkedList<Integer> leftIndexList = new LinkedList<>();
        Map<Integer, Integer> integerMap = new HashMap<>();
        Map<Integer, List<ActAtomicCoordinate>> levelToCoordinates = new LinkedHashMap<>();
        Integer maxLevel = 0;
        for (Integer index : list) {
            //If a is the left bracket coordinate, linkedList adds a
            boolean contains = rightIndexes.stream().anyMatch(x -> x == index);
            if (!contains) {
                leftIndexList.add(index);
                maxLevel = leftIndexList.size() > maxLevel ? leftIndexList.size() : maxLevel;
            } else {
                //Look from left to right and encounter the right bracket coordinates
                //Find the coordinates of the closest left bracket to it, forming a pair of brackets
                if (leftIndexList.size() > 0) {
                    Integer leftIndex = leftIndexList.get(leftIndexList.size() - 1);
                    Integer currentLevel = leftIndexList.size();
                    ActAtomicCoordinate coordinate = new ActAtomicCoordinate(leftIndex.doubleValue(), index.doubleValue());
                    if (levelToCoordinates.get(currentLevel) == null) {
                        List<ActAtomicCoordinate> coordinates = new ArrayList<>();
                        coordinates.add(coordinate);
                        levelToCoordinates.put(leftIndexList.size(), coordinates);
                    } else {
                        levelToCoordinates.get(currentLevel).add(coordinate);
                    }

                    integerMap.put(leftIndex, index);
                    //The left bracket coordinates have been matched and are deleted from the left coordinate list to avoid affecting the next right bracket coordinate matching.
                    leftIndexList.removeLast();
                }
            }
        }
return levelToCoordinates.entrySet().stream()
                .sorted((o1, o2) -> {
                    int c1 = o1.getKey();
                    int c2 = o2.getKey();
                    return Integer.compare(c1, c2);
                })
                .collect(LinkedHashMap::new, (map, entry) -> {
                    map.put(entry.getKey(), entry.getValue());
                }, LinkedHashMap::putAll);
    }

ActBPMNSequenceFlowConditionExpression class:

package com.gree.lyentech.dev3.business.entity.activiti.bpmn;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.List;

/**
 * <p>
 * Workflow: Flowchart definition-connection conditions. Only additional conditions are displayed on the front end, and basic user approval conditions are not included.
 *</p>
 *
 * @author yangk
 * @since 2021-07-16
 */

@ApiModel(value = "Flowchart definition - connection conditions. Only additional conditions are displayed for the front end, and basic user sign-off conditions are not included", description = "Flowchart definition - connection conditions. Only additional conditions are displayed for the front end, not included Basic user sign-in conditions")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ActBPMNSequenceFlowConditionExpression implements Serializable {

    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "The first line of connector is left blank")
    private String connector;
    @ApiModelProperty(value = "field")
    private String field;
    @ApiModelProperty(value = "Field Chinese name")
    private String fieldCh;
    @ApiModelProperty(value = "relational operator")
    private String operator;
    @ApiModelProperty(value = "Operation value")
    private String value;
    @ApiModelProperty(value = "actual value")
    private String varValue;

    @ApiModelProperty(value = "User's basic signature determination condition string. Mutually exclusive with all other properties", hidden = true)
    private String basicAuditCondition;

    @ApiModelProperty(value = "Single segment operation Boolean value", hidden = true)
    private Boolean result;

    @ApiModelProperty(value = "Sub-condition of iteration")
    private List<ActBPMNSequenceFlowConditionExpression> children;
}

After returning the condition, determine whether the expression is ultimately true or false based on the form value submitted in varMap.

/**
     * Iteratively process the final Boolean value and varMap
     * @param sf
     * @param conditionExpressions
     * @param varMap
     * @param businessType
     * @param businessValue
     * @return
     */
    public Boolean processVarmapAndFinalbool(SequenceFlow sf, List<ActBPMNSequenceFlowConditionExpression> conditionExpressions, Map<String, Object> varMap, String businessType, Object businessValue) {
        for (ActBPMNSequenceFlowConditionExpression conditionExpression : conditionExpressions) {
            Boolean result = null;
            String basicAuditCondition = conditionExpression.getBasicAuditCondition();
            if (StringUtils.isBlank(basicAuditCondition)) {
                //1.1 Determine additional conditions
                //1.1.1 Get the corresponding parameter value from varMap according to the parameter name in the condition
                String varName = conditionExpression.getField();
                if (StringUtils.isNotBlank(varName)) {
                    //Single field judgment Boolean value and varMap settings:
                    if (!varMap.containsKey(varName)) {
                        throw new BusinessException(String.format(ErrMsg.PARAM_BUSINESSENTITYMAPPING_NOTEXISTS, sf.getName(), varName));
                    }
                    String operator = conditionExpression.getOperator();
                    //Submit value
                    Object varValue = varMap.get(varName);
                    Double varValueDouble = null;
                    if (varValue.toString().matches(ActivitiConst.IS_NUMBER)) {
                        varValueDouble = new Double(varValue.toString());
                    }
//Expression value
                    String conValue = conditionExpression.getValue();
                    Double conValueDouble = null;
                    if (conValue.matches(ActivitiConst.IS_NUMBER)) {
                        conValueDouble = new Double(conValue);
                    }
                    conditionExpression.setVarValue(varValue.toString());
                    switch (operator) {
                        case ActivitiConst.VAR_EQ:
                            result = varValue.toString().equals(conValue);
                            break;
                        case ActivitiConst.VAR_NEQ:
                            result = !(varValue.toString().equals(conValue));
                            break;
                        case ActivitiConst.VAR_GT:
                            if (varValueDouble != null & amp; & amp; conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) > 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) > 0;
                            }
                            break;
                        case ActivitiConst.VAR_LT:
                            if (varValueDouble != null & amp; & amp; conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) < 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) < 0;
                            }
                            break;
case ActivitiConst.VAR_EGT:
                            if (varValueDouble != null & amp; & amp; conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) >= 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) >= 0;
                            }
                            break;
                        case ActivitiConst.VAR_ELT:
                            if (varValueDouble != null & amp; & amp; conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) <= 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) <= 0;
                            }
                            break;
                        case ActivitiConst.VAR_CONTAINS:
                            result = varValue.toString().contains(conValue);
                            varMap.put(varName + operator + conValue.replaceAll(ActivitiConst.VAR_COMMA, ActivitiConst.VAR_SPLIT_IN_COLLECTION), result.toString());
                            break;
                        case ActivitiConst.VAR_NOTCONTAINS:
                            result = !(varValue.toString().contains(conValue));
                            varMap.put(varName + operator + conValue.replaceAll(ActivitiConst.VAR_COMMA, ActivitiConst.VAR_SPLIT_IN_COLLECTION), result.toString());
                            break;
                        default:
                            result = false;
                    }
} else {
                    //Composite condition judgment Boolean value and varMap settings:
                    if (CollectionUtils.isNotEmpty(conditionExpression.getChildren())) {
                        result = processVarmapAndFinalbool(sf, conditionExpression.getChildren(), varMap, businessType, businessValue);
                    }
                }
            } else {
                //1.2 Determine the user’s basic signing conditions
                //1.2.1 Verify whether the format of the basic approval conditions defined in the flow chart is correct
                String[] conditionOrPair = basicAuditCondition.split(ActivitiConst.VAR_OR_REGEX);
                for (String subCondition : conditionOrPair) {
                    String[] conditionPair = subCondition.split("==");
                    String conditionBusinessType = conditionPair[0];
                    String conditionValue = conditionPair[1];
                    if ((StringUtils.isNotEmpty(conditionBusinessType) & amp; & amp; StringUtils.isEmpty(conditionValue))
                            || (StringUtils.isEmpty(conditionBusinessType) & amp; & amp; StringUtils.isNotEmpty(conditionValue))) {
                        throw new BusinessException(String.format(ErrMsg.SEQUENCEFLOW_CONDITION_ERROR, sf.getName()));
                    }
                }
                //1.2.2 Determine whether the basic approval parameters passed by the user can make the connection judgment condition true.
                result = basicAuditCondition.contains(businessType + "==" + businessValue.toString());
            }
            conditionExpression.setResult(result);
        }
//2. Organize the above results to obtain the final Boolean value
        StringBuilder finalBoolStr = new StringBuilder();
        Boolean finalBool = null;
        for (ActBPMNSequenceFlowConditionExpression conditionExpression : conditionExpressions) {
            finalBoolStr.append(conditionExpression.getField()).append(conditionExpression.getOperator()).append(conditionExpression.getValue()).
                    append(", varValue=").append(conditionExpression.getVarValue()).append(", singleBool=").append(conditionExpression.getResult()).append("\
");
            Boolean singleBool = conditionExpression.getResult();
            String connector = conditionExpression.getConnector();
            if (finalBool == null) {
                finalBool = singleBool;
            }
            if (StringUtils.isNotBlank(connector)) {
                if (connector.equals(ActivitiConst.VAR_AND)) {
                    finalBool = finalBool & amp; & amp; singleBool;
                } else if (connector.equals(ActivitiConst.VAR_OR)) {
                    finalBool = finalBool || singleBool;
                }
            }
        }
        log.info("The business flow judgment process is as follows:" + finalBoolStr.toString());
        return finalBool;
    }