废话不多说,上代码。代码格式不对劲,因为某些原因,只能一点点拷贝出来。
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;
}