Activiti6.0 – 减签
上一篇实现了Activiti6.0的加签功能,本篇就实现一下Activiti6.0的减签功能。
与上一篇思路相同,既然Flowable已经实现了相关的API,我就拿过来小幅度改造以后,直接使用。
所以,找到DeleteMultiInstanceExecutionCmd的所在位置,直接拷贝至项目中。此命令在Flowable中的位置如下图所示:

拷贝后的位置其实与上一篇中AddMultiInstanceExecutionCmd所在的位置相同,如下图:

相同的,直接拷贝后,代码中有较多错误,但是大部分是由于命名空间的问题导致的,还有一些比较容易解决,只有两点有些麻烦:
1. SequentialMultiInstanceBehavior中没有getLoopVariable方法。
2. SequentialMultiInstanceBehavior中没有continueSequentialMultiInstance方法。
第一点相对来说容易解决,追踪Flowable中的源码进入SequentialMultiInstanceBehavior的内部,可以发现getLoopVariable方法相对独立,只是按照传入的参数获得loopCounter而已,所以可以直接复制一份出来。
第二点就比较麻烦了,这个方法是Flowable新增的,为了使串行的多实例节点能够正常流转下去。理论上来讲,只需要将新增的流程执行实例执行一次即可产生对应的Task(可参见Flowable源码解析),但是分析了一下Flowable这块的源码,发现需要赋予流程执行实例本地参数,并且需要判断是否是子流程节点。
对于第二点来说,本次就从简了,不深究,只是满足测试即可,所以就简化了一下,只是让新增的流程执行实例执行一次。如果以后有时间的话,再具体的测试一下这块的代码。
所以关键的代码主体如下:
@Override
public Void execute(CommandContext commandContext) {
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
ExecutionEntity execution = executionEntityManager.findById(executionId);
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());
Activity miActivityElement = (Activity) bpmnModel.getFlowElement(execution.getActivityId());
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = miActivityElement.getLoopCharacteristics();
if (miActivityElement.getLoopCharacteristics() == null) {
throw new RuntimeException("No multi instance execution found for execution id " + executionId);
}
if (!(miActivityElement.getBehavior() instanceof MultiInstanceActivityBehavior)) {
throw new RuntimeException("No multi instance behavior found for execution id " + executionId);
}
ExecutionEntity miExecution = getMultiInstanceRootExecution(execution);
executionEntityManager.deleteChildExecutions(execution, "Delete MI execution", false);
executionEntityManager.deleteExecutionAndRelatedData(execution, "Delete MI execution", false);
int loopCounter = 0;
if (multiInstanceLoopCharacteristics.isSequential()) {
SequentialMultiInstanceBehavior miBehavior = (SequentialMultiInstanceBehavior) miActivityElement.getBehavior();
loopCounter = getLoopVariable(execution, miBehavior.getCollectionElementIndexVariable());
}
if (executionIsCompleted) {
Integer numberOfCompletedInstances = (Integer) miExecution.getVariable(NUMBER_OF_COMPLETED_INSTANCES);
miExecution.setVariableLocal(NUMBER_OF_COMPLETED_INSTANCES, numberOfCompletedInstances + 1);
loopCounter++;
} else {
Integer currentNumberOfInstances = (Integer) miExecution.getVariable(NUMBER_OF_INSTANCES);
miExecution.setVariableLocal(NUMBER_OF_INSTANCES, currentNumberOfInstances - 1);
}
ExecutionEntity childExecution = executionEntityManager.createChildExecution(miExecution);
childExecution.setCurrentFlowElement(miExecution.getCurrentFlowElement());
if (multiInstanceLoopCharacteristics.isSequential()) {
continueSequentialMultiInstance(commandContext, childExecution, loopCounter, miExecution, miActivityElement);
}
return null;
}
protected Integer getLoopVariable(DelegateExecution execution, String variableName) {
Object value = execution.getVariableLocal(variableName);
for(DelegateExecution parent = execution.getParent(); value == null && parent != null; parent = parent.getParent()) {
value = parent.getVariableLocal(variableName);
}
return (Integer)((Integer)(value != null ? value : 0));
}
public void continueSequentialMultiInstance(CommandContext commandContext, DelegateExecution execution, int loopCounter, ExecutionEntity multiInstanceRootExecution, Activity miActivityElement) {
try {
if (execution.getCurrentFlowElement() instanceof SubProcess) {
//TODO 子流程的本地参数赋值
execution.setScope(true);
execution.setCurrentFlowElement(miActivityElement);
}
commandContext.getAgenda().planOperation(new CustomeContinueMultiInstanceOperation(commandContext, (ExecutionEntity) execution, multiInstanceRootExecution, loopCounter));
} catch (BpmnError error) {
// re-throw business fault so that it can be caught by an Error
// Intermediate Event or Error Event Sub-Process in the process
throw error;
} catch (Exception e) {
throw new RuntimeException("Could not execute inner activity behavior of multi instance behavior", e);
}
}
以上,如有问题,欢迎讨论指正。
