使用JBPM实现动态会签

原文出处:http://sqz.spaces.live.com/blog/cns!F319B9AFFE33A988!283.entry
目前有很多实现动态会签的文章,但是给人感觉不是很优雅,下面介绍一种实现方式。
1、流程定义文件:
<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代码:
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);
}

/**
* <p>为每个元素创建一个分支</p>
*
* @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<ForkedTransition> forkTransitions = new ArrayList<ForkedTransition>();
// 为每一个元素创建一个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);
}
}
/**
* <p>获得分支token name</p>
*
* @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结束所有节点
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);
}

}
/**
* <p>取消 token</p>
*
* @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);
}
/**
* <p>结束token关联的任务</p>
*
* @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();
}
}
}
}
结束所有分支节点任务,流向结束节点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值