目前有很多实现动态会签的文章,但是给人感觉不是很优雅,下面介绍一种实现方式。
1、流程定义文件:
在这里我们从node节点动态生成任务节点,会签时当有一个是reject时便结束所有节点。
2、动态派生ForEachFork代码:
在具体应用中需要灵活的根据业务逻辑需要派生所需要的分支。
结束所有分支节点任务,流向结束节点。
1、流程定义文件:
xml 代码
- <process-definition
- xmlns="urn:jbpm.org:jpdl-3.1" name="foreach">
- <start-state name="start">
- <task name="one">
- </task>
- <transition name="a" to="foreachf"></transition>
- </start-state>
- <node name="foreachf">
- <action class="com.framework.workflow.jbpm.ForEachFork">
- <foreach>#{bpm_assignees}</foreach>
- <var>reviewer</var>
- </action>
- <transition name="review" to="review"></transition>
- </node>
- <task-node name="review">
- <task name="reviewTask">
- <assignment class="com.framework.workflow.jbpm.DefaultAssignment">
- <actor>#{reviewer}</actor>
- </assignment>
- </task>
- <transition name="reject" to="endreview">
- <action class="com.framework.workflow.jbpm.JoinEndForkedTokens" />
- </transition>
- <transition name="approve" to="endreview"></transition>
- </task-node>
- <join name="endreview">
- <transition name="toend" to="end1"></transition>
- </join>
- <end-state name="end1"></end-state>
- </process-definition>
在这里我们从node节点动态生成任务节点,会签时当有一个是reject时便结束所有节点。
2、动态派生ForEachFork代码:
java 代码
- public class ForEachFork implements ActionHandler
- {
- private Element foreach;
- private String var;
- //测试数据
- private static Map map = new HashMap();
- static{
- List list = new ArrayList();
- list.add("1234");
- list.add("2345");
- list.add("3456");
- map.put("bpm_assignees", list);
- }
- /**
- *
- 为每个元素创建一个分支
- *
- * @param executionContext
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- public void execute(final ExecutionContext executionContext)
- throws Exception
- {
- if (foreach == null)
- {
- throw new WorkflowException("forEach has not been provided");
- }
- List forEachColl = null;
- String forEachCollStr = foreach.getTextTrim();
- if (forEachCollStr != null)
- {
- if (forEachCollStr.startsWith("#{"))
- {
- String expression = forEachCollStr.substring(2, forEachCollStr.length() -1);
- forEachColl = (List)map.get(expression);
- }
- }
- if (var == null || var.length() == 0)
- {
- throw new WorkflowException("forEach variable name has not been provided");
- }
- //
- // 创建分支
- //
- Token rootToken = executionContext.getToken();
- Node node = executionContext.getNode();
- List forkTransitions = new ArrayList();
- // 为每一个元素创建一个token
- for (int i = 0; i < node.getLeavingTransitions().size(); i++)
- {
- Transition transition = (Transition) node.getLeavingTransitions().get(i);
- for (int iVar = 0; iVar < forEachColl.size(); iVar++)
- {
- // 为每一个新token创建一个path
- String tokenName = getTokenName(rootToken, transition.getName(), iVar);
- Token loopToken = new Token(rootToken, tokenName);
- loopToken.setTerminationImplicit(true);
- executionContext.getJbpmContext().getSession().save(loopToken);
- //赋予一个新变量
- final ExecutionContext newExecutionContext = new ExecutionContext(loopToken);
- newExecutionContext.getContextInstance().createVariable(var, forEachColl.get(iVar), loopToken);
- // 记录下每一transition
- ForkedTransition forkTransition = new ForkedTransition();
- forkTransition.executionContext = newExecutionContext;
- forkTransition.transition = transition;
- forkTransitions.add(forkTransition);
- }
- }
- //
- // 转向下一个节点
- //
- for (ForkedTransition forkTransition : forkTransitions)
- {
- node.leave(forkTransition.executionContext, forkTransition.transition);
- }
- }
- /**
- *
- 获得分支token name
- *
- * @param parent
- * @param transitionName
- * @return
- */
- protected String getTokenName(Token parent, String transitionName, int loopIndex)
- {
- String tokenName = null;
- if (transitionName != null)
- {
- if (!parent.hasChild(transitionName))
- {
- tokenName = transitionName;
- }
- else
- {
- int i = 2;
- tokenName = transitionName + Integer.toString(i);
- while (parent.hasChild(tokenName))
- {
- i++;
- tokenName = transitionName + Integer.toString(i);
- }
- }
- }
- else
- {
- // 没有转向
- int size = ( parent.getChildren()!=null ? parent.getChildren().size()+1 : 1 );
- tokenName = Integer.toString(size);
- }
- return tokenName + "." + loopIndex;
- }
- /**
- * Fork Transition
- */
- private class ForkedTransition
- {
- private ExecutionContext executionContext;
- private Transition transition;
- }
- }
在具体应用中需要灵活的根据业务逻辑需要派生所需要的分支。
3、DefaultAssignment
进行简单的权限操作,这里面主要是将#{reviewer}值作为actorId进行设置
4、JoinEndForkedTokens结束所有节点
java 代码
- public class JoinEndForkedTokens implements ActionHandler
- {
- public JoinEndForkedTokens()
- {
- }
- /* (non-Javadoc)
- * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
- */
- public void execute(ExecutionContext executionContext)
- {
- Token token = executionContext.getToken().getParent();
- Map childTokens = token.getActiveChildren();
- for (Object childToken : childTokens.values())
- {
- cancelToken(executionContext, (Token)childToken);
- }
- }
- /**
- *
- 取消 token
- *
- * @param executionContext
- * @param token
- */
- protected void cancelToken(ExecutionContext executionContext, Token token)
- {
- Map childTokens = token.getActiveChildren();
- for (Object childToken : childTokens.values())
- {
- cancelToken(executionContext, (Token)childToken);
- }
- if (!token.hasEnded())
- {
- token.end(true);
- }
- cancelTokenTasks(executionContext, token);
- }
- /**
- *
- 结束token关联的任务
- *
- * @param executionContext
- * @param token
- */
- protected void cancelTokenTasks(ExecutionContext executionContext, Token token)
- {
- TaskMgmtInstance tms = executionContext.getTaskMgmtInstance();
- Collection tasks = tms.getUnfinishedTasks(token);
- for (Object task : tasks)
- {
- TaskInstance taskInstance = (TaskInstance)task;
- if (taskInstance.isBlocking())
- {
- taskInstance.setBlocking(false);
- }
- if (taskInstance.isSignalling())
- {
- taskInstance.setSignalling(false);
- }
- if (!taskInstance.hasEnded())
- {
- taskInstance.end();
- }
- }
- }
- }
结束所有分支节点任务,流向结束节点。