您的位置:首页 > 产品设计 > 产品经理

JBPM在项目中的应用

2013-06-02 16:56 211 查看
前言
在前面的博客中讲到了JBPM4.4与SSH的集成,今天就来讲一下JBPM3在项目中是如何使用的(jbpm3和4的使用流程是一致的,不一样就是实现而已)。
 
正题
1.需求简介
今天要讲解的是根据OA系统中的动态表单那部分,我们先定义流程,然后对该流程定义动态表单(模板),之后新建公文,公文需要绑定流程。
 
2.流程介绍
我们看一下下面的图来了解下整体流程:

1).web.xml(建表)
    从上图我们可以看到配置文件的关联关系,需要在web.xml中配置spring和struts,然后spring中配置jbpm。这样一启动服务我们就可以创建jbpm所需要的表。
 
2).部署流程
    表创建完成后,我们需要定义并部署流程,将定义好的流程配置文件上传并部署(该项目中有上传流程文件功能,即将流程内容以二进制的形式保存入数据库)。
 
    由于业务需要,我们可以给流程绑定动态表单,即给流程绑定一个模板(这个动态表单不是必须的,需要根据业务需求确定)。
 
3).绑定实例
    新建公文信息,先选择一个流程,然后就可以加载相应的模板,填完信息后即可保存公文信息并且生成该公文的流程实例信息。
 
3.核心代码
    其实要想在我们项目中进行流程操作,主要就是需要封装一个关于流程操作的类,之后在需要用到的地方进行调用即可。
 
1)比如我们这里面的流程核心操作类是WorkflowManagerImpl.java:

package com.bjsxt.oa.managers.impl;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.bjsxt.oa.managers.WorkflowManager;
import com.bjsxt.oa.model.Document;
import com.bjsxt.oa.model.Workflow;

public class WorkflowManagerImpl extends HibernateDaoSupport implements
WorkflowManager {

private JbpmConfiguration jbpmConfiguration;

public long addProcessInstance(String workflowName, int documentId) {

JbpmContext context = getContext();

//从JBPM中加载流程定义
ProcessDefinition definition = context.getGraphSession().findLatestProcessDefinition(workflowName);

ProcessInstance instance = new ProcessInstance(definition);

//将公文标识绑定到流程实例
instance.getContextInstance().createVariable("document", documentId);

//存储流程实例的信息
context.save(instance);

return instance.getId();
}

public void delProcessInstance(long processInstanceId) {

JbpmContext context = getContext();

//删除流程实例
context.getGraphSession().deleteProcessInstance(processInstanceId);
}

public void delWorkflow(int workflowId) {

//在OA中删除流程的定义
Workflow workflow = (Workflow)getHibernateTemplate().load(Workflow.class, workflowId);
getHibernateTemplate().delete(workflow);

//在JBPM中删除流程定义
//JBPM对流程定义按版本进行管理,所以在同一个时刻,可能存在同一个流程定义的多个不同的版本
//如果需要对其删除,则应该删除所有的版本

//查找对应流程定义的所有版本
List defs = getContext().getGraphSession().findAllProcessDefinitionVersions(workflow.getName());
for (Iterator iter = defs.iterator(); iter.hasNext();) {
ProcessDefinition def = (ProcessDefinition) iter.next();
getContext().getGraphSession().deleteProcessDefinition(def);
}
}

public void deployProcessDefinition(byte[] processDefinition,
byte[] processImage) {

//通过byte[]创建ProcessDefinition对象
ProcessDefinition def =
ProcessDefinition.parseXmlInputStream(
new ByteArrayInputStream(processDefinition));

//将流程定义文件部署到JBPM
getContext().deployProcessDefinition(def);

//首先查找一下Workflow对象是否已经存在
Workflow workflow = (Workflow)getSession()
.createQuery("select w from Workflow w where w.name = ? ")
.setParameter(0, def.getName())
.uniqueResult();

//如果流程尚未存在,则创建
if(workflow == null){
workflow = new Workflow();
workflow.setName(def.getName());
workflow.setProcessDefinition(processDefinition);
workflow.setProcessImage(processImage);
getHibernateTemplate().save(workflow);
return;
}

//如果流程已经存在,则更新
workflow.setName(def.getName());
workflow.setProcessDefinition(processDefinition);
workflow.setProcessImage(processImage);
getHibernateTemplate().update(workflow);
}

public Workflow findWorkflow(int workflowId) {
return (Workflow)getHibernateTemplate().load(Workflow.class, workflowId);
}

public String flowToNextStep(String username, long processInstanceId,
String transitionName) {

JbpmContext context = getContext();
String status = null;

ProcessInstance instance = context.getProcessInstance(processInstanceId);

//当前节点
String currentNodeName = instance.getRootToken().getNode().getName();

//起始节点
String startNodeName = instance.getProcessDefinition().getStartState().getName();

//如果是在起始节点,因为起始节点不会跟任何人相关联(即不会将任务分配给任何人)
if(currentNodeName.equals(startNodeName)){
//需要使用流程实例的signal()方法来触发流程向下一步流动!
instance.getRootToken().signal(transitionName);
}else{

//首先找出用户的当前任务
List tasks = context.getTaskMgmtSession().findTaskInstances(username);
for (Iterator iter = tasks.iterator(); iter.hasNext();) {
TaskInstance taskInstance = (TaskInstance) iter.next();
if(taskInstance.getProcessInstance().getId() == processInstanceId){

//这就是当前文档对应的任务,需要结束这个任务,从而触发流程向下一步骤移动!
taskInstance.end(transitionName);
break;
}
}
}

//将公文当前所处节点作为状态信息返回
status = instance.getRootToken().getNode().getName();

//判断当前的状态是否已经结束!
if(instance.hasEnded()){
status = Document.STATUS_END;
}

return status;
}

public List searchAllWorkflows() {
return getHibernateTemplate().find("from Workflow");
}

public List searchApprovingDocuments(String username) {

JbpmContext context = getContext();

List docIds = new ArrayList();

//首先获得流转到用户的任务列表
List tasks = context.getTaskMgmtSession().findTaskInstances(username);
for (Iterator iter = tasks.iterator(); iter.hasNext();) {
TaskInstance taskInstance = (TaskInstance) iter.next();

//任务实例是否正在等待审批,如果不是,则忽略(即不应该被列到待审批列表中!)
if(!taskInstance.isSignalling()){
continue;
}

//根据其对应的流程实例,获得公文标识
Integer docId = (Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("document");
docIds.add(docId);
}

return docIds;
}

//下一步都有哪些流向?
public List searchNextTransitions(String username,long processInstanceId) {

JbpmContext context = getContext();

List transitions = new ArrayList();

//根据流程实例标识查找流程实例
ProcessInstance instance = context.getProcessInstance(processInstanceId);

//		//根据流程实例,获得当前的节点,从而得到在当前节点下有哪些流向
//		List nextSteps = instance.getRootToken().getNode().getLeavingTransitions();

//当前节点
String currentNodeName = instance.getRootToken().getNode().getName();

//起始节点
String startNodeName = instance.getProcessDefinition().getStartState().getName();

Collection nextSteps = null;
//如果是在起始节点,因为起始节点不会跟任何人相关联(即不会将任务分配给任何人)
if(currentNodeName.equals(startNodeName)){
//需要使用流程实例的signal()方法来触发流程向下一步流动!
nextSteps = instance.getRootToken().getAvailableTransitions();
}else{

//首先找出用户的当前任务
List tasks = context.getTaskMgmtSession().findTaskInstances(username);
for (Iterator iter = tasks.iterator(); iter.hasNext();) {
TaskInstance taskInstance = (TaskInstance) iter.next();
if(taskInstance.getProcessInstance().getId() == processInstanceId){

nextSteps = taskInstance.getAvailableTransitions();
break;
}
}
}

for (Iterator iter = nextSteps.iterator(); iter.hasNext();) {
Transition transition = (Transition) iter.next();
transitions.add(transition.getName());
}

return transitions;
}

/**
* 获取JbpmContext对象,需要将JbpmContext的session设置为当前的session对象
* @return
*/
private JbpmContext getContext(){
JbpmContext context = jbpmConfiguration.createJbpmContext();
context.setSession(getSession());
return context;
}

public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
this.jbpmConfiguration = jbpmConfiguration;
}
}


 
2)然后我们部署流程的时候只需要再上传流程的那个action中调用workflowManager中的部署流程的方法即可:

//添加流程定义
publicActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequestrequest, HttpServletResponse response) throws Exception {

WorkflowActionFormwaf = (WorkflowActionForm)form;

//TODO做一些判断,判断上传的文件是否为空,决定是否抛出异常,等等!!

//部署流程
workflowManager.deployProcessDefinition(
waf.getProcessDefinition().getFileData(),
waf.getProcessImage().getFileData()
);

returnmapping.findForward("add_success");
}


 
3)绑定实例的时候一样,我们需要在添加公文的DocumentManagerImpl.java类里面调用workflowManager的生成流程实例信息:
 

//添加公文
publicvoid addDocument(Document document, int workflowId, int userId) {

//保存公文信息
document.setWorkflow((Workflow)getHibernateTemplate().load(Workflow.class,workflowId));
document.setCreator((User)getHibernateTemplate().load(User.class,userId));
document.setStatus(Document.STATUS_NEW);
document.setCreateTime(newDate());
getHibernateTemplate().save(document);

//添加流程实例
longprocessInstanceId =workflowManager.addProcessInstance(document.getWorkflow().getName(),document.getId());

//绑定流程实例的标识到公文对象
document.setProcessInstanceId(processInstanceId);
getHibernateTemplate().update(document);
}


 4.小结
    要想把工作流嵌入到项目中,就要把它的各个流程步骤添加进去,即建表——部署流程——创建实例——流程流转。重要的是要知道这几个步骤跟你的项目是如何协同合作的。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: