JBPM4.4(2)-state结点和decision结点

//from http://www.cnblogs.com/skyme/archive/2011/05/04/2036122.html

做一个带有分支的流向流程

在执行seperate状态的时候分成了200和400两种情况

描述文件的内容如下:

View Code 

<?xml version=”1.0″ encoding=”UTF-8″?><process name=”fork” xmlns=”http://jbpm.org/4.4/jpdl”>
<start g=”237,28,48,48″ name=”start1″>
<transition name=”to separate” to=”separate” g=”-71,-17″/>
</start>
<state g=”210,153,92,52″ name=”separate”>
<transition name=”to 200″ to=”200″ g=”-41,-17″/>
<transition name=”to 400″ to=”400″ g=”-41,-17″/>
</state>
<state g=”145,256,92,52″ name=”200″>
<transition name=”to end1″ to=”end1″ g=”-47,-17″/>
</state>
<state g=”306,255,92,52″ name=”400″>
<transition name=”to end1″ to=”end1″ g=”-47,-17″/>
</state>
<end g=”245,375,48,48″ name=”end1″/>
</process>

测试代码如下:

View Code 

public class TestSperator extends JbpmTestCase {String deploymentId;protected void setUp() throws Exception {
super.setUp(); 

deploymentId = repositoryService.createDeployment()
.addResourceFromClasspath(“com/jbpm/fork/fork.jpdl.xml”)
.deploy();
}

protected void tearDown() throws Exception {
repositoryService.deleteDeploymentCascade(deploymentId);

super.tearDown();
}

public void testSeparate() {
ProcessInstance processInstance = executionService
.startProcessInstanceByKey(“fork”);

System.out.println(“流程实例Id:” + processInstance.getId());
System.out.println(“流程定义Id:” + processInstance.getProcessDefinitionId());

ProcessInstance instance = executionService.signalExecutionById(processInstance.getId());

// 判断当前是否位于state节点

System.out.println(“是否位于state节点:” + instance.isActive(“separate”));
System.out.println(“向下执行…”);

ProcessInstance processInstance200=executionService.signalExecutionById(processInstance.getId(), “to 200″);

System.out.println(“当前流程是否位于200节点—->”+processInstance200.isActive(“200″));
System.out.println(“当前流程是否结束—->”+processInstance200.isEnded());

ProcessInstance endinstance=executionService.signalExecutionById(processInstance200.getId());

System.out.println(“当前流程是否结束—->”+endinstance.isEnded());

}
}

执行流程的结果如下:

使流程向下执行

executionService.signalExecutionById();

该方法有多个重载:

ProcessInstance signalExecutionById(String executionId);

//若在流程定义某一个节点没有分支时(只有一个transition时),调用此方法,可将流程继续向下执行 executionId为流程实例Id

ProcessInstance signalExecutionById(String executionId, String signalName);

//若在流程定义某一个节点有多个分支时(有多个transition时),调用此方法,可将流程沿着transition所指的方向向下执行

executionId为流程实例Id, signalName为流程定义中transition节点的name属性的值

ProcessInstance signalExecutionById(String executionId, String signalName, Map<String, ?> parameters);

用于将流程沿着signalName方向(transition的name属性所指的方向)向下继续执行,在执行的过程中顺便传递参数parameters

ProcessInstance signalExecutionById(String executionId, Map<String, ?> parameters);

用于将流程向下继续执行,在执行的过程中顺便传递参数parameters

注:当一个节点有多个分支时,若要通过signalExecutionById()方法将流程向下执行必须明确指出signalName即(transition的name属性所指的方向),否则流程不会向下执行,仍会停留在当前节点。因为jbpm不确定流程该流向那个方向。

接下来是一个decision的例子,这个是一个分支判断的节点,相当于我们程序中的switch case

下面画一个选择向左还是向右的例子

定义文件如下:

View Code
<?xml version=”1.0″ encoding=”UTF-8″?><process name=”decision” xmlns=”http://jbpm.org/4.4/jpdl”>
<start g=”246,30,48,48″ name=”start1″>
<transition name=”to wait” to=”wait” g=”-47,-17″/>
</start>
<state g=”231,112,92,52″ name=”wait”>
<transition name=”to exclusive1″ to=”exclusive1″ g=”-83,-17″/>
</state>
<decision g=”252,204,48,48″ name=”exclusive1″>
<transition name=”to left” to=”left” g=”-47,-17″>
<condition expr=”${coder==’left’}”></condition>
</transition>
<transition name=”to right” to=”right” g=”-53,-17″>
<condition expr=”${coder==’right’}”></condition>
</transition>
</decision>
<state g=”175,295,92,52″ name=”left”>
<transition name=”to end1″ to=”end1″ g=”-47,-17″/>
</state>
<state g=”325,292,92,52″ name=”right”>
<transition name=”to end1″ to=”end1″ g=”-47,-17″/>
</state>
<end g=”268,370,48,48″ name=”end1″/>
</process>

其中有几种方式可以处理流程的走向

第一种,内置条件

即在流程定义中设置每一个transition的子节点condition,并为每一个condition填充expr属性

形如:

<condition expr=“${coder==’left’}”></condition>

对应的测试流程如下,需要增加

View Code
Map<String, String> map=new HashMap<String, String>();
//coder为流程定义中表达式的名称
map.put(“coder”, “left”);ProcessInstance processInstance = executionService.startProcessInstanceByKey(“decision”,map);

如果map中order的值指定的有问题那么就会抛出异常

测试程序如下:

View Code
public class TestDecision extends JbpmTestCase {String deploymentId;protected void setUp() throws Exception {
super.setUp(); 

deploymentId = repositoryService.createDeployment()
.addResourceFromClasspath(“com/jbpm/decision/decision.jpdl.xml”)
.deploy();
}

protected void tearDown() throws Exception {
repositoryService.deleteDeploymentCascade(deploymentId);

super.tearDown();
}

public void testDescsion() {

Map<String, String> map=new HashMap<String, String>();
//coder为流程定义中表达式的名称
map.put(“coder”, “left”);

ProcessInstance processInstance = executionService.startProcessInstanceByKey(“decision”,map);

System.out.println(“流程实例Id:” + processInstance.getId());
System.out.println(“流程定义Id:” + processInstance.getProcessDefinitionId());

System.out.println(“是否位于state节点:” + processInstance.isActive(“wait”));

ProcessInstance decisionInstance = executionService.signalExecutionById(processInstance.getId());

// 判断当前是否位于wait节点
System.out.println(“是否位于wait节点:” + decisionInstance.isActive(“wait”));
System.out.println(“因为已经有值所以自动向下执行…”);
System.out.println(“是否位于left节点:” + decisionInstance.isActive(“left”));

//向下执行
ProcessInstance endinstance=executionService.signalExecutionById(decisionInstance.getId());

System.out.println(“当前流程是否结束—->”+endinstance.isEnded());

}
}

执行结果如图所示:

因为在开始的时候指定了流程处理的方向,所以流程向left方向自动执行。

第二种,更像switch case

在decision节点上指定

<decision g=”252,204,48,48″ name=”exclusive1″ expr=”${toWhere}”>

修改代码为:

View Code 

Map<String, String> map=new HashMap<String, String>();
//coder为流程定义中表达式的名称
map.put(“toWhere”, “to left”);

其它部分不变,可以看到结果和原来的相同。

第三种,配置handler子类

在流程定义中在decision节点内部配置<handler/>子节点,并设置该元素的class属性为你自己的类)该类实现了org.jbpm.api.jpdl.DecisionHandler.你需要重写

String decide(OpenExecution execution);方法即可,在该方法最终返回decision活动后的下一个transition的name属性的值。

修改配置文件

View Code
<decision g=”252,204,48,48″ name=”exclusive1″>
<handler class=”com.jbpm.decision.HandlerDecision”></handler>
<transition name=”to left” to=”left” g=”-47,-17″>
</transition>
<transition name=”to right” to=”right” g=”-53,-17″>
</transition>
</decision>

添加HandlerDecision并且实现DecisionHandler

代码如下:

View Code
@SuppressWarnings(“serial”)
public class HandlerDecision implements DecisionHandler {@Override
public String decide(OpenExecution execution) {
// TODO Auto-generated method stub
String toWhere = execution.getVariable(“toWhere”).toString();
String result = null;if (“left”.equals(toWhere)) {
result = “to left”;
} else if (“right”.equals(toWhere)) {
result = “to right”;
}
return result;

}

测试代码只需将map中的值进行简单修改即可

Map<String, String> map=new HashMap<String, String>();
//coder为流程定义中表达式的名称
map.put(“toWhere”, “left”);

执行测试,得到的流程和之前完全相同。

This entry was posted in Computer, Java. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s