把布尔判断表达式转换成条件javabean(条件结构理论上可迭代无数层),并用于判断表单提交参数最终生成的布尔结果

废话不多说,上代码。代码格式不对劲,因为某些原因,只能一点点拷贝出来。

public List<ActBPMNSequenceFlowConditionExpression> parseConditionExpressionToList(String conditionExpressionStr, Boolean ifJustExtra) {
        //1. 初始化变量
        //1.1 要最终返回的当前流向的聚合好的条件表达式
        List<ActBPMNSequenceFlowConditionExpression> conditionExpressions = new ArrayList<>();
        //1.2 1级为最高级,返回所有表达式的层级和它们的坐标
        LinkedHashMap<Integer, List<ActAtomicCoordinate>> sortedMap = this.getBracketPairs(conditionExpressionStr, ActivitiConst.BRACKET_LEFT_CHAR);
        //1.3 所有需要转中文列的英文列名
        Set<String> colEnNames = new HashSet<>();
        //2. 开始聚合条件表达式
        // sortedMap的size<=1说明布尔表达式内只有基本签审判定条件或无内容,无需处理
        if (sortedMap.size() > 1) {
            //2.1 先获取最低层的即最细化的布尔判断条件,这些条件全部是单一条件
            Integer levelCount = sortedMap.size();
            List<ActAtomicCoordinate> basicCoordinates = sortedMap.get(levelCount);
            List<BoolstrToBoolentity> lowerBoolstrToEntityList = new ArrayList<>();
            //上一段段bool表达式的‘)’的位置
            Integer lastY = null;
            //当前段bool表达式的‘(’的位置
            Integer thisX;
            //当前段bool表达式的‘)’的位置
            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 设置条件之间的connector
                lastY = this.setConnecor(conditionExpressionStr, singleBasicBoolExpressionEntity, thisX, thisY, lastY);
            }
            /**2.2开始由低到高依次对上层表达式实体进行聚合 start **/
            for (int i = levelCount - 1; i > 1; i--) {
                lastY = null;
                List<ActAtomicCoordinate> upperCoordinates = sortedMap.get(i);
                for (ActAtomicCoordinate upperCoordinate : upperCoordinates) {
                    //2.2.1 初始化当前层的当前段的bool表达式Entity
                    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 根据x,y坐标获取当前层的某bool表达式字符串原文
String upperBoolExpressionStr = conditionExpressionStr.substring(thisX, thisY + 1);
                    //2.2.3 低层的某字符串如果存在【当前层的某部分字符串原文】中,
                    //      那么证明该低层字符串代表的boolEntity应作为子条件加入【当前层的该部分字符串原文】代表的boolEntity的子条件集合中。
                    //      如果括号层数=2,那么算上最外层那个大括号,实际的extra布尔表达式只有一层,是单一条件而非复合条件
                    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 (singleUpperBoolExpressionEntity.getChildren() == null) {
                        singleUpperBoolExpressionEntity = this.assembleExpressionEntity(upperBoolExpressionStr, colEnNames);
                    }
                    lowerBoolstrToEntityList.add(new BoolstrToBoolentity(upperBoolExpressionStr, singleUpperBoolExpressionEntity));
                    //2.2.4 设置条件之间的connector
                    lastY = this.setConnecor(conditionExpressionStr, singleUpperBoolExpressionEntity, thisX, thisY, lastY);
                }
            }
            /**2.2开始由低到高依次对上层表达式实体进行聚合 end **/
            //聚合结束,并以聚合好的形式返回当前流向的所有条件表达式
            conditionExpressions.addAll(lowerBoolstrToEntityList.stream().map(l -> l.getBoolExpressionEntity()).collect(Collectors.toList()));
        }
        //只有基本判定条件
        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. 处理字段的中文名
        if (CollectionUtils.isNotEmpty(colEnNames)) {
            List<ActAtomicField> actAtomicFields = actCompanyLevelBusinesstypeProcdefRelationService.getBusinessFieldsByColEnNames(new ArrayList<>(colEnNames));
            processColChnNames(conditionExpressions, actAtomicFields);
        }
        return conditionExpressions;
    }

 getBracketPairs方法:

/**
     * 把图中的布尔表达式转化为:
     * 按层级依次降低的括号坐标集合
     */
    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();
        //找到所有左右()的位置
        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) {
            //如果a是左括号坐标,linkedList加入a
            boolean contains = rightIndexes.stream().anyMatch(x -> x == index);
            if (!contains) {
                leftIndexList.add(index);
                maxLevel = leftIndexList.size() > maxLevel ? leftIndexList.size() : maxLevel;
            } else {
                //从左往右找,遇到右括号坐标
                //找到离它最近的左括号坐标,构成一对括号的坐标
                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);
                    //该左括号坐标已匹配完毕,从左坐标列表中删除,以免影响下次的右括号坐标匹配
                    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类:

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>
 * 工作流: 流程图定义-连线条件。对前端只展示额外条件,不包含用户基本签审条件
 * </p>
 *
 * @author yangk
 * @since 2021-07-16
 */

@ApiModel(value = "流程图定义-连线条件。对前端只展示额外条件,不包含用户基本签审条件", description = "流程图定义-连线条件。对前端只展示额外条件,不包含用户基本签审条件")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ActBPMNSequenceFlowConditionExpression implements Serializable {

    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "连接符 第一行不填")
    private String connector;
    @ApiModelProperty(value = "字段")
    private String field;
    @ApiModelProperty(value = "字段中文名称")
    private String fieldCh;
    @ApiModelProperty(value = "关系运算符")
    private String operator;
    @ApiModelProperty(value = "运算值")
    private String value;
    @ApiModelProperty(value = "实际值")
    private String varValue;

    @ApiModelProperty(value = "用户基本签审判定条件字符串。与其它所有属性互斥", hidden = true)
    private String basicAuditCondition;

    @ApiModelProperty(value = "单段运算布尔值", hidden = true)
    private Boolean result;

    @ApiModelProperty(value = "迭代的子条件")
    private List<ActBPMNSequenceFlowConditionExpression> children;
}

返回条件后,根据varMap中提交的表单值,来判断表达式最终为真还是为假

/**
     * 迭代处理最终布尔值和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 判断额外条件
                //1.1.1 根据条件中的参数名称去varMap中拿对应的参数值
                String varName = conditionExpression.getField();
                if (StringUtils.isNotBlank(varName)) {
                    //单一字段判断布尔值与varMap设置:
                    if (!varMap.containsKey(varName)) {
                        throw new BusinessException(String.format(ErrMsg.PARAM_BUSINESSENTITYMAPPING_NOTEXISTS, sf.getName(), varName));
                    }
                    String operator = conditionExpression.getOperator();
                    //提交值
                    Object varValue = varMap.get(varName);
                    Double varValueDouble = null;
                    if (varValue.toString().matches(ActivitiConst.IS_NUMBER)) {
                        varValueDouble = new Double(varValue.toString());
                    }
//表达式值
                    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 && conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) > 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) > 0;
                            }
                            break;
                        case ActivitiConst.VAR_LT:
                            if (varValueDouble != null && conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) < 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) < 0;
                            }
                            break;
case ActivitiConst.VAR_EGT:
                            if (varValueDouble != null && conValueDouble != null) {
                                result = varValueDouble.compareTo(conValueDouble) >= 0;
                            } else {
                                result = varValue.toString().compareTo(conValue) >= 0;
                            }
                            break;
                        case ActivitiConst.VAR_ELT:
                            if (varValueDouble != null && 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 {
                    //复合条件判断布尔值与varMap设置:
                    if (CollectionUtils.isNotEmpty(conditionExpression.getChildren())) {
                        result = processVarmapAndFinalbool(sf, conditionExpression.getChildren(), varMap, businessType, businessValue);
                    }
                }
            } else {
                //1.2 判断用户基本签审条件
                //1.2.1 校验流程图中定义的基本签审条件格式是否正确
                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) && StringUtils.isEmpty(conditionValue))
                            || (StringUtils.isEmpty(conditionBusinessType) && StringUtils.isNotEmpty(conditionValue))) {
                        throw new BusinessException(String.format(ErrMsg.SEQUENCEFLOW_CONDITION_ERROR, sf.getName()));
                    }
                }
                //1.2.2 判断用户传来的基本签审参数是否可以使连线的判断条件为真
                result = basicAuditCondition.contains(businessType + "==" + businessValue.toString());
            }
            conditionExpression.setResult(result);
        }
//2. 对上述结果进行整理,得到最终的布尔值
        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("\n");
            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 && singleBool;
                } else if (connector.equals(ActivitiConst.VAR_OR)) {
                    finalBool = finalBool || singleBool;
                }
            }
        }
        log.info("业务流转判断过程如下:" + finalBoolStr.toString());
        return finalBool;
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值