7 jBPM 的客户端开发
有了前面的 HelloWorld 后台流程,我们就要开始客户端程序了。正如前面提到的,本文不写 JSP ,而改采用 JUnit 的形式,输出则用 System.out.println 。举一反三,知道在方法中输入及用 println 输出,在 JSP 和 SWING 等 GUI 界面还不是一样嘛。
这个 JUnit 客户端,我们就借用创建项目时自动生成的 SimpleProcessTest.java 了,改写后如下:
package
com.sample;
import junit.framework.TestCase;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
public class SimpleProcessTest extends TestCase{
private JbpmConfigurationconfig = JbpmConfiguration.getInstance();
private JbpmContextctx = config.createJbpmContext();
// helloworld对应于jbpm_processdefinition表的name字段值,也即processdefinition.xml的name
// 这个值得取比较耗时,实际项目里最好和“数据库的JDBC连接”一样,让它共享,不要频繁打开关闭。
private ProcessDefinitionprocessDefinition = ctx.getGraphSession().findLatestProcessDefinition( " helloworld " );
public void testNewRequest(){
long id = newRequest();
System.out.println( " id= " + id);
checkNewRequest(id);
confirmRequest(id);
checkconfirmRequest(id);
ctx.close(); // 关闭jbpm容器
}
/**
*创建一个请假单
*
* @return
*/
private long newRequest(){
// 创建一个新流程
ProcessInstancepi = processDefinition.createProcessInstance();
// 取得流程的数据环境
ContextInstanceci = pi.getContextInstance();
// 创建一张请假单
ci.setVariable( " name " , " 陈刚www.chengang.com.cn " );
ci.setVariable( " day " , 2 );
assertEquals( null ,ci.getVariable( " note " ));
// 请假申请结束,转到下一个流程结点
pi.signal();
return pi.getId();
}
/**
*检查请假单的数据
*
* @param id
*/
private void checkNewRequest( long id){
// 从数据库提取原流程
ProcessInstancepi = ctx.loadProcessInstance(id);
// 取得流程的数据环境
ContextInstanceci = pi.getContextInstance();
// 创建一张请假单
assertEquals( " 陈刚www.chengang.com.cn " ,ci.getVariable( " name " ));
assertEquals(Integer.valueOf( 2 ),ci.getVariable( " day " ));
assertEquals( " 我要请假 " ,ci.getVariable( " note " ));
// 当前是结点为confirm
assertEquals(pi.getRootToken().getNode().getName(), " confirm " );
// 流程还没结束
assertFalse(pi.hasEnded());
}
/**
*审批陈刚的请假申请
*
* @param id
*/
private void confirmRequest( long id){
ProcessInstancepi = ctx.loadProcessInstance(id);
ContextInstanceci = pi.getContextInstance();
// 不通过
ci.setVariable( " note " , " 不准请假,继续加班 " );
// 审批结束,到下一个流程结点
pi.signal();
}
private void checkConfirmRequest( long id){
ProcessInstancepi = ctx.loadProcessInstance(id);
ContextInstanceci = pi.getContextInstance();
// ConfirmAction类在signal后执行,所以覆盖了经理的审批意见
assertEquals( " 准假 " ,ci.getVariable( " note " ));
// 当前是结点为end
assertEquals(pi.getRootToken().getNode().getName(), " end " );
// 流程结束了
assertTrue(pi.hasEnded());
}
}
import junit.framework.TestCase;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
public class SimpleProcessTest extends TestCase{
private JbpmConfigurationconfig = JbpmConfiguration.getInstance();
private JbpmContextctx = config.createJbpmContext();
// helloworld对应于jbpm_processdefinition表的name字段值,也即processdefinition.xml的name
// 这个值得取比较耗时,实际项目里最好和“数据库的JDBC连接”一样,让它共享,不要频繁打开关闭。
private ProcessDefinitionprocessDefinition = ctx.getGraphSession().findLatestProcessDefinition( " helloworld " );
public void testNewRequest(){
long id = newRequest();
System.out.println( " id= " + id);
checkNewRequest(id);
confirmRequest(id);
checkconfirmRequest(id);
ctx.close(); // 关闭jbpm容器
}
/**
*创建一个请假单
*
* @return
*/
private long newRequest(){
// 创建一个新流程
ProcessInstancepi = processDefinition.createProcessInstance();
// 取得流程的数据环境
ContextInstanceci = pi.getContextInstance();
// 创建一张请假单
ci.setVariable( " name " , " 陈刚www.chengang.com.cn " );
ci.setVariable( " day " , 2 );
assertEquals( null ,ci.getVariable( " note " ));
// 请假申请结束,转到下一个流程结点
pi.signal();
return pi.getId();
}
/**
*检查请假单的数据
*
* @param id
*/
private void checkNewRequest( long id){
// 从数据库提取原流程
ProcessInstancepi = ctx.loadProcessInstance(id);
// 取得流程的数据环境
ContextInstanceci = pi.getContextInstance();
// 创建一张请假单
assertEquals( " 陈刚www.chengang.com.cn " ,ci.getVariable( " name " ));
assertEquals(Integer.valueOf( 2 ),ci.getVariable( " day " ));
assertEquals( " 我要请假 " ,ci.getVariable( " note " ));
// 当前是结点为confirm
assertEquals(pi.getRootToken().getNode().getName(), " confirm " );
// 流程还没结束
assertFalse(pi.hasEnded());
}
/**
*审批陈刚的请假申请
*
* @param id
*/
private void confirmRequest( long id){
ProcessInstancepi = ctx.loadProcessInstance(id);
ContextInstanceci = pi.getContextInstance();
// 不通过
ci.setVariable( " note " , " 不准请假,继续加班 " );
// 审批结束,到下一个流程结点
pi.signal();
}
private void checkConfirmRequest( long id){
ProcessInstancepi = ctx.loadProcessInstance(id);
ContextInstanceci = pi.getContextInstance();
// ConfirmAction类在signal后执行,所以覆盖了经理的审批意见
assertEquals( " 准假 " ,ci.getVariable( " note " ));
// 当前是结点为end
assertEquals(pi.getRootToken().getNode().getName(), " end " );
// 流程结束了
assertTrue(pi.hasEnded());
}
}
这个例子还是很简单,而且关键是缺少用户、组、权限等工作流系统必须的东西,不过没关系。下面的内容我将完成一个更完整的实例。