时间:2007-09-19 关键字: jbpm/工作流/workflow
原文出处:http://sqz.spaces.live.com/blog/cns!F319B9AFFE33A988!283.entry
目前有很多实现动态会签的文章,但是给人感觉不是很优雅,下面介绍一种实现方式。
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);
- }
-
-
-
-
-
-
-
-
-
-
- @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();
-
- for (int i = 0; i < node.getLeavingTransitions().size(); i++)
- {
- Transition transition = (Transition) node.getLeavingTransitions().get(i);
- for (int iVar = 0; iVar < forEachColl.size(); iVar++)
- {
-
- 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);
-
-
- ForkedTransition forkTransition = new ForkedTransition();
- forkTransition.executionContext = newExecutionContext;
- forkTransition.transition = transition;
- forkTransitions.add(forkTransition);
- }
- }
-
-
-
- for (ForkedTransition forkTransition : forkTransitions)
- {
- node.leave(forkTransition.executionContext, forkTransition.transition);
- }
- }
-
-
-
-
-
-
-
-
-
-
- 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;
- }
-
-
-
-
-
-
- private class ForkedTransition
- {
- private ExecutionContext executionContext;
- private Transition transition;
- }
- }
在具体应用中需要灵活的根据业务逻辑需要派生所需要的分支。
3、DefaultAssignment
进行简单的权限操作,这里面主要是将#{reviewer}值作为actorId进行设置
4、JoinEndForkedTokens结束所有节点
java 代码
- public class JoinEndForkedTokens implements ActionHandler
- {
-
- public JoinEndForkedTokens()
- {
- }
-
-
-
- public void execute(ExecutionContext executionContext)
- {
- Token token = executionContext.getToken().getParent();
- Map childTokens = token.getActiveChildren();
- for (Object childToken : childTokens.values())
- {
- cancelToken(executionContext, (Token)childToken);
- }
-
- }
-
-
-
-
-
-
-
-
-
- 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);
- }
-
-
-
-
-
-
-
-
-
- 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();
- }
- }
- }
- }
结束所有分支节点任务,流向结束节点。