seam與jbpm工作流實現了無縫整合,在基於seam來開發具有工作流的功能時,只需簡單的將hibernate.cfg.xml和jbpm.cfg.xml的文件配置一下,在WAR的components.xml聲明使用流程定義的jpdl流程定義文件就實現了系統的整合。工作流的核心工作分爲二個部分,一爲流程的定義,二爲流程實例與業務數據實例綁定。之後以不同的角色實現流程的流轉即可。
本例的流程定義十分簡單,共五個節點,爲開始節點,結束節點和三個不同角色的節點的流程。頁面的導航在page.xml是配置,各節點的任務開始和結束使用註解式聲明,頁面的任務列表使用seam提供的單用戶。集合表達式和JSF標籤來完成用戶交互操作。
1 流程定義文件,此流程定義會持久化到對應的數據表內。
2 對登陸類進行指定jbpm用戶
3 用戶邏輯實現類,用戶頁面跳轉、流程開始、節點流轉等。
4 定義業務實體
5 頁面交互頁面。
代碼如下:
1 processdefinition.xml流程定義文件
<?xml version="1.0" encoding="UTF-8"?>
<process-definition name="文檔測試流程">
<start-state name="開始">
<transition name="提交張三審批" to="張三審批"></transition>
</start-state>
<task-node name="張三審批">
<task name="審批1">
<assignment actor-id="#{actor.id}"/>
</task>
<transition name="提交李四審批" to="李四審批"></transition>
</task-node>
<task-node name="李四審批">
<task name="審批2">
<assignment actor-id="#{actor.id}"/>
</task>
<transition name="提交王五審批" to="王五審批"></transition>
</task-node>
<task-node name="王五審批">
<task name="審批3">
<assignment actor-id="#{actor.id}"/>
</task>
<transition name="結束流程" to="結束"></transition>
</task-node>
<end-state name="結束"></end-state>
</process-definition>
2 對登陸類進行指定jbpm用戶
@In(create=true) Actor actor;
actor.setId(user.getUsername());
3 用戶邏輯實現類,用戶頁面跳轉、流程開始、節點流轉等
/*******************************************************************************
* 文件名:WorkFlowAction.java<br>
* 版本: <br>
* 描述: <br>
* 版權所有: <br>
* //////////////////////////////////////////////////////// <br>
* 創建者: 沙振中 <br>
* 創建日期: May 12, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改說明: <br>
******************************************************************************/
package org.shaneseam.action;
import javax.annotation.Resource;
import javax.ejb.Remove;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.shaneseam.action.inte.WorkFlow;
import org.shaneseam.entitybean.WorkFlowDoc;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.bpm.BeginTask;
import org.jboss.seam.annotations.bpm.CreateProcess;
import org.jboss.seam.annotations.bpm.EndTask;
@Stateful
@Name("workflowaction")
public class WorkFlowAction implements WorkFlow{
@PersistenceContext
EntityManager em;
@Resource
SessionContext ctx;
@In(create=true)
@Out
WorkFlowDoc workFlowDoc;
@In (required=false)
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
Long workFlowId;
@CreateProcess(definition="文檔測試流程")
public String createDoc() {
em.persist(workFlowDoc);
workFlowId= workFlowDoc.getWorkFlowId();
return "success";
}
public String toPage(){
return "topage";
}
@BeginTask
@EndTask
public String taskOne() {
System.out.println("workFlowId========="+workFlowId);
workFlowDoc=(WorkFlowDoc)em.createQuery("select o from WorkFlowDoc o where o.workFlowId= :workFlowId")
.setParameter("workFlowId", workFlowId).getSingleResult();
return "accept";
}
public String toListNode()
{
return "tonodetwo";
}
@BeginTask
@EndTask
public String taskTwo() {
return "accept";
}
@BeginTask
@EndTask
public String taskThree() {
return "finish";
}
@Remove
public void destroy() {}
}
4 定義業務實體
/*******************************************************************************
* 文件名:WorkFlowDoc.java<br>
* 版本: <br>
* 描述: <br>
* 版權所有: <br>
* //////////////////////////////////////////////////////// <br>
* 創建者: 沙振中 <br>
* 創建日期: May 12, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改說明: <br>
******************************************************************************/
package org.shaneseam.entitybean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.jboss.seam.annotations.Name;
@Entity
@Name("workFlowDoc")
public class WorkFlowDoc {
Long workFlowId;
String workOneTitle;
String workOneContext;
String workTwoTitle;
String workTwoContext;
String workThreeTitle;
String workThreeContext;
public WorkFlowDoc()
{}
/**
* @return the workFlowId
*/
@Id @GeneratedValue
public Long getWorkFlowId() {
return workFlowId;
}
/**
* @param workFlowId the workFlowId to set
*/
public void setWorkFlowId(Long workFlowId) {
this.workFlowId = workFlowId;
}
/**
* @return the workOneTitle
*/
public String getWorkOneTitle() {
return workOneTitle;
}
/**
* @param workOneTitle the workOneTitle to set
*/
public void setWorkOneTitle(String workOneTitle) {
this.workOneTitle = workOneTitle;
}
/**
* @return the workTwoTitle
*/
public String getWorkTwoTitle() {
return workTwoTitle;
}
/**
* @param workTwoTitle the workTwoTitle to set
*/
public void setWorkTwoTitle(String workTwoTitle) {
this.workTwoTitle = workTwoTitle;
}
/**
* @return the workTwoContext
*/
public String getWorkTwoContext() {
return workTwoContext;
}
/**
* @param workTwoContext the workTwoContext to set
*/
public void setWorkTwoContext(String workTwoContext) {
this.workTwoContext = workTwoContext;
}
/**
* @return the workThreeTitle
*/
public String getWorkThreeTitle() {
return workThreeTitle;
}
/**
* @param workThreeTitle the workThreeTitle to set
*/
public void setWorkThreeTitle(String workThreeTitle) {
this.workThreeTitle = workThreeTitle;
}
/**
* @return the workThreeContext
*/
public String getWorkThreeContext() {
return workThreeContext;
}
/**
* @param workThreeContext the workThreeContext to set
*/
public void setWorkThreeContext(String workThreeContext) {
this.workThreeContext = workThreeContext;
}
/**
* @return the workOneContext
*/
public String getWorkOneContext() {
return workOneContext;
}
/**
* @param workOneContext the workOneContext to set
*/
public void setWorkOneContext(String workOneContext) {
this.workOneContext = workOneContext;
}
}
5 頁面交互頁面
5.1 增加公文頁面workdoc.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<div >
This is doc.
<h:form id="NewDocForm">
<table border="0">
<tr>
<td>step1 title</td>
<td>
<h:inputText id="stepTitle" required="true" value="#{workFlowDoc.workOneTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step1 context</td>
<td>
<h:inputText id="stepContext" required="true" value="#{workFlowDoc.workOneContext}"></h:inputText>
</td>
</tr>
<tr>
<td>step2 title</td>
<td>
<h:inputText id="stepTitle2" required="true" value="#{workFlowDoc.workTwoTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step2 context</td>
<td>
<h:inputText id="stepContext2" required="true" value="#{workFlowDoc.workTwoContext}"></h:inputText>
</td>
</tr>
<tr>
<td>step3 title</td>
<td>
<h:inputText id="stepTitle3" required="true" value="#{workFlowDoc.workThreeTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step3 context</td>
<td>
<h:inputText id="stepContext3" required="true" value="#{workFlowDoc.workThreeContext}"></h:inputText>
</td>
</tr>
</table>
<h:commandButton id="createDoc" value="createDoc" action="#{workflowaction.createDoc}" />
</h:form>
</div>
</body>
</html>
5.2 第一個節點審批列表onetask.xhtml, taskInstanceListForType用於提供單用戶的任務實例集合
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<div >
This is first step Task list.
<h:form id="NewDocForm">
<h:dataTable value="#{taskInstanceListForType['審批1']}" var="task">
<h:column>
<f:facet name="header">doc id </f:facet>
<h:outputText value="#{task.variables['workFlowId']}"/>
<h:inputHidden id="workFlowId" value="#{task.variables['workFlowId']}"></h:inputHidden>
</h:column>
<h:column>
<s:button action="#{workflowaction.taskOne}" taskInstance="#{task}" value="doc"/>
</h:column>
</h:dataTable>
</h:form>
</div>
</body>
</html>
5.3 表單與流程綁定查看頁面taskshow.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<div >
This is doc show on task one node. 綁定表單內容。
<h:form id="NewDocForm">
<table border="0">
<tr>
<td>step1 title</td>
<td>
<h:inputText id="stepTitle" required="true" value="#{workFlowDoc.workOneTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step1 context</td>
<td>
<h:inputText id="stepContext" required="true" value="#{workFlowDoc.workOneContext}"></h:inputText>
</td>
</tr>
<tr>
<td>step2 title</td>
<td>
<h:inputText id="stepTitle2" required="true" value="#{workFlowDoc.workTwoTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step2 context</td>
<td>
<h:inputText id="stepContext2" required="true" value="#{workFlowDoc.workTwoContext}"></h:inputText>
</td>
</tr>
<tr>
<td>step3 title</td>
<td>
<h:inputText id="stepTitle3" required="true" value="#{workFlowDoc.workThreeTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>step3 context</td>
<td>
<h:inputText id="stepContext3" required="true" value="#{workFlowDoc.workThreeContext}"></h:inputText>
</td>
</tr>
</table>
<h:commandButton id="twonodelist" value="twonodelist" action="#{workflowaction.toListNode}" />
</h:form>
</div>
</body>
</html>
5.4 第二個節點列表面頁twotask.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<div >
節點二 ,This is second step Task list.
<h:form id="NewDocForm">
<h:dataTable value="#{taskInstanceListForType['審批2']}" var="task">
<h:column>
<f:facet name="header">doc id </f:facet>
<h:outputText value="#{task.variables['workFlowId']}"/>
<h:inputHidden id="workFlowId" value="#{task.variables['workFlowId']}"></h:inputHidden>
</h:column>
<h:column>
<s:button action="#{workflowaction.taskTwo}" taskInstance="#{task}" value="doc"/>
</h:column>
</h:dataTable>
</h:form>
</div>
</body>
</html>
5.5 第三個節點列表頁面threetask.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<div >
This is thrid step Task list. 第三個節點
<h:form id="NewDocForm">
<h:dataTable value="#{taskInstanceListForType['審批3']}" var="task">
<h:column>
<f:facet name="header">doc id </f:facet>
<h:outputText value="#{task.variables['workFlowId']}"/>
<h:inputHidden id="workFlowId" value="#{task.variables['workFlowId']}"></h:inputHidden>
</h:column>
<h:column>
<s:button action="#{workflowaction.taskThree}" taskInstance="#{task}" value="doc"/>
</h:column>
</h:dataTable>
</h:form>
</div>
</body>
</html>
5.5 任務完結頁面finish.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>finish.xhtml</title>
<meta http-equiv="keywords" content="enter,your,keywords,here" />
<meta http-equiv="description" content="A short description of this page." />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<!--<link rel="stylesheet" type="text/css" href="styles.css">-->
</head>
<body>
<p>
workflow process is finish. you did good job. 三個節點流轉完成.
</p>
</body>
</html>
6 page.xml導航文件
<page view-id="/main.xhtml">
<navigation>
<rule if-outcome="topage">
<redirect view-id="/workflow/workdoc.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/workflow/workdoc.xhtml">
<navigation>
<rule if-outcome="success">
<redirect view-id="/workflow/onetask.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/workflow/onetask.xhtml">
<navigation>
<rule if-outcome="accept">
<redirect view-id="/workflow/taskshow.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/workflow/taskshow.xhtml">
<navigation>
<rule if-outcome="tonodetwo">
<redirect view-id="/workflow/twotask.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/workflow/twotask.xhtml">
<navigation>
<rule if-outcome="accept">
<redirect view-id="/workflow/threetask.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/workflow/threetask.xhtml">
<navigation>
<rule if-outcome="finish">
<redirect view-id="/workflow/finish.xhtml"/>
</rule>
</navigation>
</page>
7 components.xml增加工作流配置
<bpm:jbpm>
<bpm:process-definitions>
<value>/document/processdefinition.xml</value>
</bpm:process-definitions>
</bpm:jbpm>