java 工做流

BPM是jboss旗下遵照LGPL許可的java開源工做流,功能比較完善,從4.0開始引入了pvm的概念,支持jPDL、BPEL等流程定義語言。因爲相關資料還比較少,開發本身的一個demo還不是太容易,本文詳細講解如何作一個簡單的demo程序。
    咱們從 http://www.jboss.org/jbossjbpm/jbpm_downloads/下載jBPM,實際使用時發現4.0.CR1和4.1版本各有一些問題,此處把這兩個版本都下載下來。開發使用4.1版本,Eclipse插件GPD(圖形化設計流程)使用4.0.CR1版本的,tomcat使用6.0.18版本的,jdk要求5.0及以上,Eclipse使用eclipse-jee-galileo-win32版本的。
    下載包裏面有自帶的一個example,根據jBMP的文檔能夠部署,但這個example把工做流部分封裝爲RESTful Web Service,學習起來有必定難度,看了會讓人一頭霧水,此處就不講了。如下講述如何把jBPM嵌入到應用系統中去。
    一、在Eclipse中安裝GPD。
    把%jbpm-4.0.CR1_HOME%/gpd下的jbpm-gpd-site.zip安裝到Eclipse中,熟悉Eclipse的知道安裝方法,在jBPM的文檔中也有介紹。
    二、在Eclipse中創建一個動態網站的項目jBPMDemo,複製必要的jar文件到WEB-INF/lib下面。
    把%jbpm-4.1_HOME%/lib下的全部jar文件、%jbpm-4.1_HOME%/jbpm.jar複製過去。
    但juel.jar中javax/el中的類與tomcat中的有衝突,把juel.jar中的javax/el刪除。
    三、配置mysql數據庫。
    在mysql數據庫中創建一個名爲jbpmdb的數據庫,在裏面執行%jbpm-4.1_HOME%/install/src/db/jbpm.mysql.create.sql創建jbpm所需的數據庫表。
    另外創建一個表存放業務數據:
create table ask_for_leave ( 
id MEDIUMINT NOT NULL AUTO_INCREMENT primary key, 
apply_user varchar(50), -- 申請人 
apply_time timestamp default now(), -- 申請時間 
begin_leave_time timestamp, -- 假期開始時間 
end_leave_time timestamp, -- 假期結束時間 
leave_reason varchar(500), -- 請假理由 
approve_user varchar(50), -- 審批人 
approve_time timestamp, -- 審批時間 
is_passed smallint, -- 是否贊成,1 贊成,2 駁回 
approve_remark varchar(500), -- 審批備註,如駁回的緣由 
back_time timestamp -- 銷假時間 
);
    四、配置JOTM事務支持。
    把carol.properties、jta.jar、commons-logging.jar、carol.jar、connector-1_5.jar、jotm.jar、jotm_jrmp_stubs.jar、jts1_0.jar、mysql-connector-java-3.1.11-bin.jar、objectweb-datasource.jar、xapool.jar放到%tomcat_home%/lib下面。
    把howl.jar、jotm.jar、objectweb-datasource.jar、ow_carol.jar、xapool.jar放到WEB-INF/lib下面。
    在jBPLDemo的context配置數據源,代碼以下:
<?xml version='1.0' encoding='utf-8'?> 
<Context displayName="jBPMDemo" 
         docBase="${catalina.base}/webapps/jBPMDemo"  
         path="/jBPMDemo"  
         workDir="work/Catalina/localhost/jBPMDemo" reloadable="true"> 
          
   <Resource name="UserTransaction" 
      auth="Container" 
      type="javax.transaction.UserTransaction" 
      factory="org.objectweb.jotm.UserTransactionFactory" 
      jotm.timeout="180" /> 

   <Resource name="JbpmDS" type="javax.sql.DataSource" 
      factory="org.objectweb.jndi.DataSourceFactory" 
      maxWait="5000" 
      maxActive="300" 
      maxIdle="2" 
      username="root" 
      password="" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://127.0.0.1:3306/jbpmdb" 
   />      
        
</Context>
    在應用的WEB-INF/classes下創建文件jbpm.cfg.xml,內容以下:
<?xml version="1.0" encoding="UTF-8"?> 

<jbpm-configuration> 

  <import resource="jbpm.default.cfg.xml" /> 
  <import resource="jbpm.tx.hibernate.cfg.xml" /> 
  <import resource="jbpm.jpdl.cfg.xml" /> 
  <import resource="jbpm.identity.cfg.xml" /> 
  <import resource="jbpm.businesscalendar.cfg.xml" /> 
  <import resource="jbpm.jobexecutor.cfg.xml" /> 

</jbpm-configuration>
    在應用的WEB-INF/classes下創建文件jbpm.hibernate.cfg.xml,內容以下:
<?xml version="1.0" encoding="utf-8"?> 

<!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
<session-factory> 

<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> 
<property name="hibernate.connection.datasource">java:comp/env/JbpmDS</property> 
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property> 
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JOTMTransactionManagerLookup</property>
<property name="jta.UserTransaction">java:comp/env/UserTransaction</property> 

<mapping resource="jbpm.repository.hbm.xml" /> 
<mapping resource="jbpm.execution.hbm.xml" /> 
<mapping resource="jbpm.history.hbm.xml" /> 
<mapping resource="jbpm.task.hbm.xml" /> 
<mapping resource="jbpm.identity.hbm.xml" /> 

</session-factory> 
</hibernate-configuration>
    五、在Eclipse中GPD定義流程。
    GPD對中文的支持還有問題,要用圖形界面與直接編寫代碼相結合的方式,最後效果以下圖:
流程圖
    產生的代碼askForLeave.jpdl.xml放到應用的WEN-INF/classes/jpdl下面,代碼以下:
<?xml version="1.0" encoding="UTF-8"?> 

<process key="askForLeave" name="請假流程" version="1" xmlns="http://jbpm.org/4.0/jpdl"> 
   <swimlane candidate-groups="manager" name="manager"/> 
   <start g="188,10,48,48" name="start1"> 
      <transition g="-30,-10" name="開始" to="填寫請假申請"/> 
   </start> 
   <task assignee="#{owner}" g="167,86,92,52" name="填寫請假申請"> 
      <transition g="-50,-11" name="提交審批" to="審批"/> 
   </task> 
   <task g="169,159,92,52" name="審批" swimlane="manager"> 
      <transition g="-76,-8" name="判斷審批結果" to="exclusive1"/> 
   </task> 
   <task assignee="#{owner}" g="91,298,92,52" name="銷假"> 
      <transition g="-50,-11" name="休假結束" to="end1"/> 
   </task> 
   <task assignee="#{owner}" g="252,295,92,52" name="查看緣由"> 
      <transition g="-34,-10" name="請假結束" to="end2"/> 
   </task> 
   <end g="116,377,48,48" name="end1"/> 
   <end g="275,372,48,48" name="end2"/> 
   <decision g="190,227,48,48" name="exclusive1"> 
      <transition g="0,-15" name="拒絕" to="查看緣由"> 
        <condition expr="#{is_passed==false}"/> 
      </transition> 
      <transition g="-31,-16" name="經過" to="銷假"/> 
   </decision> 
</process>
    產生的圖片askForLeave.png放到應用的askForLeave文件夾下面。
    六、創建幾個java類。
demo.jbpm.DBUtil:
package demo.jbpm; 

import java.sql.Connection; 

import javax.naming.InitialContext; 
import javax.sql.DataSource; 

import javax.transaction.UserTransaction; 

public class DBUtil { 
    private static DataSource ds; 
    /** 
     * 獲取數據源 
     * @return 
     * @throws Exception 
     */ 
    public static DataSource getDS() throws Exception { 
        if (ds == null) ds = (DataSource) new InitialContext().lookup("java:comp/env/JbpmDS"); 
        return ds; 
    } 
     
    /** 
     * 獲取數據庫鏈接 
     * @return 
     * @throws Exception 
     */ 
    public static Connection getConn() throws Exception { 
        return getDS().getConnection(); 
    } 
     
    /** 
     * 獲取事務UserTransaction 
     * @return 
     * @throws Exception 
     */ 
    public static UserTransaction getUserTransaction() throws Exception { 
        UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/env/UserTransaction"); 
        return ut; 
    } 
}
    demo.jbpm.JBPMUtil.java:
package demo.jbpm; 

import org.jbpm.api.Configuration; 
import org.jbpm.api.ExecutionService; 
import org.jbpm.api.IdentityService; 
import org.jbpm.api.ProcessEngine; 
import org.jbpm.api.RepositoryService; 
import org.jbpm.api.TaskService; 

public class JBPMUtil { 
    private static ProcessEngine pe; 
    private static RepositoryService repositoryService; 
    private static ExecutionService executionService; 
    private static IdentityService identityService; 
    private static TaskService taskService; 
     
    public static void deploy(String jdplPath) { 
        String deployId = getRepositoryService().createDeployment().addResourceFromClasspath(jdplPath).deploy(); 
        System.out.println("----------deploy id:" + deployId); 
    } 
     
    public static ProcessEngine getProcessEngine() { 
        if (pe == null) { 
            Configuration config = new Configuration(); 
            pe = config.buildProcessEngine(); 
        } 
        return pe; 
    } 
     
    public static RepositoryService getRepositoryService() { 
        if (repositoryService == null) repositoryService = getProcessEngine().getRepositoryService(); 
        return repositoryService; 
    } 
     
    public static ExecutionService getExecutionService() { 
        if (executionService == null) executionService = getProcessEngine().getExecutionService(); 
        return executionService; 
    } 
     
    public static IdentityService getIdentityService() { 
        if (identityService == null) identityService = getProcessEngine().getIdentityService(); 
        return identityService; 
    } 
     
    public static TaskService getTaskService() { 
        if (taskService == null) taskService = getProcessEngine().getTaskService(); 
        return taskService; 
    } 
}
    demo.jbpm.AskForLeave.java:
package demo.jbpm; 

import java.sql.Connection; 
import java.sql.ResultSet; 
import java.sql.Statement; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 

import javax.servlet.http.HttpServletRequest; 
import javax.transaction.Status; 
import javax.transaction.UserTransaction; 

import org.jbpm.api.ProcessDefinition; 
import org.jbpm.api.ProcessInstance; 
import org.jbpm.api.model.ActivityCoordinates; 
import org.jbpm.api.task.Task; 

public class AskForLeave { 
    private final static String employeeName = "王三"; 
    private final static String managerName = "李五"; 
     
    public static void deploy() { 
        JBPMUtil.deploy("jpdl/askForLeave.jpdl.xml"); 
        JBPMUtil.getIdentityService().createUser(employeeName, "王", "三"); 
        JBPMUtil.getIdentityService().createUser(managerName, "李", "五"); 
        JBPMUtil.getIdentityService().createGroup("manager"); 
        JBPMUtil.getIdentityService().createMembership(managerName, "manager"); 
    } 
     
    /** 
     * 請假申請 
     * @param request 
     * @throws Exception 
     */ 
    public static void apply(HttpServletRequest request) throws Exception { 
        UserTransaction ut =DBUtil.getUserTransaction(); 
        Connection conn = DBUtil.getConn(); 
        boolean rollback = false; 
        try { 
            ut.begin(); 
            //*********業務部分 
            //請假申請存入數據庫 
            Statement stmt = conn.createStatement(); 
            String sql = "insert into ask_for_leave(apply_user," + 
                  "begin_leave_time,end_leave_time,leave_reason) values(" + 
                  "'" + request.getParameter("apply_user") + "'," + 
                  "'" + request.getParameter("begin_leave_time") + "'," + 
                  "'" + request.getParameter("end_leave_time") + "'," + 
                  "'" + request.getParameter("leave_reason") + "')"; 
            System.out.println("insert:" + sql); 
            stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); 
            ResultSet rs = stmt.getGeneratedKeys(); 
            int id = 0; 
            if (rs.next()) id = rs.getInt(1); 
            System.out.println("--------------id:" + id); 
             
             
            //*********工做流部分 
            //新建工做流實例 
            Map var = new HashMap(); 
            var.put("owner", employeeName); 
            var.put("biz_id", id); 
            ProcessInstance processInstance = JBPMUtil.getExecutionService().startProcessInstanceByKey("askForLeave", var);
             
            //執行動做 
            List<Task> tasks = JBPMUtil.getTaskService().findPersonalTasks(employeeName); 
            for (Task t : tasks) { 
                if (processInstance.getId().equals(JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getId())
                        && t.getActivityName().equals("填寫請假申請")) { 
                     
                    JBPMUtil.getTaskService().completeTask(t.getId()); 
                } 
                 
            } 
        } 
        catch (Exception e) { 
            rollback = true; 
            e.printStackTrace(); 
            throw e; 
        } 
        finally { 
            if (ut != null && ut.getStatus() != Status.STATUS_NO_TRANSACTION) { 
                if (rollback) ut.rollback(); 
                else ut.commit(); 
            } 
             
            if (conn != null) conn.close(); 
        } 
    } 
     
    /** 
     * 獲取經理的工做列表 
     * @return 
     * @throws Exception 
     */ 
    public static List<Map> getManagerWorkList() throws Exception { 
        List<Map> workList = new ArrayList<Map>(); 
        List<Task> tasks = JBPMUtil.getTaskService().findGroupTasks(managerName); 
        System.out.println("---------task count:" + tasks.size()); 
        for (Task t : tasks) { 
            String processDefinitionId = JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getProcessDefinitionId();
            ProcessDefinition processDefinition = JBPMUtil.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(processDefinitionId).uniqueResult();
            System.out.println("---------pro name:" + JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getProcessDefinitionId());
            System.out.println("---------acct name:" + t.getActivityName()); 
            if ("請假流程".equals(processDefinition.getName()) 
                    && t.getActivityName().equals("審批")) { 
                Map item = new HashMap(); 
                item.put("wfId", JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getId());
                item.put("wfName", "請假流程"); 
                item.put("taskId", t.getId()); 
                item.put("taskName", t.getActivityName()); 
                workList.add(item); 
            } 
        } 
        return workList; 
    } 
     
    /** 
     * 獲取位置 
     * @param wfId 
     * @return 
     */ 
    public static List<ActivityCoordinates> getActiveActivityCoordinates(String wfId) { 
        List<ActivityCoordinates> result = new ArrayList<ActivityCoordinates>(); 
        ProcessInstance processInstance = JBPMUtil.getExecutionService().findProcessInstanceById(wfId); 
        String processDefinitionId = processInstance.getProcessDefinitionId(); 
        Set<String> activities = processInstance.findActiveActivityNames(); 
        for (String act : activities) { 
            ActivityCoordinates coor = JBPMUtil.getRepositoryService().getActivityCoordinates(processDefinitionId, act); 
            result.add(coor); 
        } 
         
        return result; 
    } 
     
    /** 
     * 根據請假單id獲取請假單信息 
     * @param id 
     * @return 
     * @throws Exception 
     */ 
    public static Map getById(String id) throws Exception { 
        Map form = new HashMap(); 
        Connection conn = DBUtil.getConn(); 
         
        try { 
            Statement stmt = conn.createStatement(); 
            ResultSet rst = stmt.executeQuery("select * from ask_for_leave where id=" + id); 
            if (rst.next()) { 
                form.put("apply_user", rst.getString("apply_user")); 
                form.put("begin_leave_time", rst.getString("begin_leave_time")); 
                form.put("end_leave_time", rst.getString("end_leave_time")); 
                form.put("leave_reason", rst.getString("leave_reason")); 
            } 
            rst.close(); 
            stmt.close(); 
        } 
        catch (Exception e) { 
            e.printStackTrace(); 
            throw e; 
        } 
        finally { 
             
            if (conn != null) conn.close(); 
        } 
         
        return form; 
    } 
     
    /** 
     * 根據工做流id貨物請假單id 
     * @param wfId 
     * @return 
     * @throws Exception 
     */ 
    public static String getBizId(String taskId) throws Exception { 
         
        return JBPMUtil.getTaskService().getVariable(taskId, "biz_id").toString(); 
    } 
     
    /** 
     * 審批 
     * @param request 
     * @throws Exception 
     */ 
    public static void approval(HttpServletRequest request) throws Exception { 
        UserTransaction ut = DBUtil.getUserTransaction(); 
        Connection conn = DBUtil.getConn(); 
        boolean rollback = false; 
        try { 
            ut.begin(); 
             
            //*********業務部分 
            //審批信息存入數據庫 
            Statement stmt = conn.createStatement(); 
            String sql = "update ask_for_leave set " + 
                  "approve_user='" + managerName + "', " + 
                  "approve_time=now()," + 
                  "is_passed=" + request.getParameter("is_passed") + "," + 
                  "approve_remark='" + request.getParameter("approve_remark") + "' " + 
                  "where id=" + request.getParameter("biz_id"); 
            System.out.println("--------------update:" + sql); 
            stmt.executeUpdate(sql); 
            System.out.println("--------------update complete"); 
             
            //*********工做流部分 
            boolean isPassed = false; 
            if ("1".equals(request.getParameter("is_passed"))) isPassed = true; 
            Map var = new HashMap(); 
            var.put("is_passed", isPassed); 
            JBPMUtil.getTaskService().completeTask(request.getParameter("taskId"), var); 
        } 
        catch (Exception e) { 
            rollback = true; 
            e.printStackTrace(); 
            throw e; 
        } 
        finally { 
            if (ut != null && ut.getStatus() != Status.STATUS_NO_TRANSACTION) { 
                if (rollback) ut.rollback(); 
                else ut.commit(); 
            } 
             
            if (conn != null) conn.close(); 
        } 
    } 
     
    /** 
     * 獲取員工的工做列表 
     * @return 
     * @throws Exception 
     */ 
    public static List<Map> getEmployeeWorkList() throws Exception { 
        List<Map> workList = new ArrayList<Map>(); 
        List<Task> tasks = JBPMUtil.getTaskService().findPersonalTasks(employeeName); 
        System.out.println("---------task count:" + tasks.size()); 
        for (Task t : tasks) { 
            String processDefinitionId = JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getProcessDefinitionId();
            ProcessDefinition processDefinition = JBPMUtil.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(processDefinitionId).uniqueResult();
            System.out.println("---------pro name:" + JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getProcessDefinitionId());
            System.out.println("---------acct name:" + t.getActivityName()); 
            if ("請假流程".equals(processDefinition.getName())) { 
                Map item = new HashMap(); 
                item.put("wfId", JBPMUtil.getExecutionService().findExecutionById(t.getExecutionId()).getProcessInstance().getId());
                item.put("wfName", "請假流程"); 
                item.put("taskId", t.getId()); 
                item.put("taskName", t.getActivityName()); 
                item.put("biz_id", JBPMUtil.getTaskService().getVariable(t.getId(), "biz_id")); 
                workList.add(item); 
            } 
        } 
        return workList; 
    } 
     
    /** 
     * 申請人處理審批後的事務 
     * @param request 
     * @throws Exception 
     */ 
    public static void leave(HttpServletRequest request) throws Exception { 
        UserTransaction ut = DBUtil.getUserTransaction(); 
        Connection conn = DBUtil.getConn(); 
        boolean rollback = false; 
        try { 
            ut.begin(); 
            //處理休假狀況 
            boolean isPassed = (Boolean) JBPMUtil.getTaskService().getVariable(request.getParameter("taskId"), "is_passed");
            int bizId = (Integer) JBPMUtil.getTaskService().getVariable(request.getParameter("taskId"), "biz_id"); 
            if (isPassed) { 
                Statement stmt = conn.createStatement(); 
                String sql = "update ask_for_leave set " + 
                      "back_time=now() " + 
                      "where id=" + bizId; 
                System.out.println("--------------update:" + sql); 
                stmt.executeUpdate(sql); 
            } 
             
            //*********工做流部分 
            JBPMUtil.getTaskService().completeTask(request.getParameter("taskId")); 
        } 
        catch (Exception e) { 
            rollback = true; 
            e.printStackTrace(); 
            throw e; 
        } 
        finally { 
            if (ut != null && ut.getStatus() != Status.STATUS_NO_TRANSACTION) { 
                if (rollback) ut.rollback(); 
                else ut.commit(); 
            } 
             
            if (conn != null) conn.close(); 
        } 
    } 
}
    七、創建jsp文件。
    askForLeave/deploy.jsp(用於部署jpdl,須要首先運行,只須要運行一次):
<%@page import="demo.jbpm.AskForLeave"%> 
<% 
AskForLeave.deploy(); 
%>
    askForLeave/apply.jsp(用於啓動業務,須要第二個運行):
<%@ page language="java" contentType="text/html; charset=UTF-8"     pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<form name="form1" method="POST" action="apply_result.jsp"> 
申請人:<input type="text" name="apply_user" value="suntao"/><br/> 
假期開始時間:<input type="text" name="begin_leave_time" value="2009-08-07 09:00"/>(YYYY-MM-DD HH24:MI)<br/> 
假期結束時間:<input type="text" name="end_leave_time" value="2009-08-07 18:00"/>(YYYY-MM-DD HH24:MI)<br/> 
請假理由:<input type="text" name="leave_reason" value="事假"/><br/> 
<input type="submit" value="提交"/><br/> 
</form> 
</body> 
</html>
    askForLeave/apply_result.jsp(用於響應apply.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<%@page import="demo.jbpm.AskForLeave"%> 
<% 
request.setCharacterEncoding("UTF-8"); 
String result = "成功"; 
try { 
    AskForLeave.apply(request); 

catch(Exception e) { 
    result = "失敗"; 
    e.printStackTrace(); 

%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<%=result %> 
</body> 
</html>
    askForLeave/managerWorkList.jsp(用於顯示經理的工做列表,須要第三個運行):
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<%@page import="demo.jbpm.AskForLeave"%> 
<%@page import="java.util.List"%> 
<%@page import="java.util.Map"%> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<% 
List<Map> workList = AskForLeave.getManagerWorkList(); 
%> 
<table border="1"> 
  <tr> 
    <td>工做名稱</td> 
    <td>工做任務</td> 
    <td>處理</td> 
    <td>流程圖</td> 
  </tr> 
  <%for(int i=0;i<workList.size();i++){ %> 
  <tr> 
    <td><%=workList.get(i).get("wfName") %></td> 
    <td><%=workList.get(i).get("taskName") %></td> 
    <td><a href="approval.jsp?wfId=<%=workList.get(i).get("wfId")%>&taskId=<%=workList.get(i).get("taskId")%>">處理</a></td> 
    <td><a href="viewWfGraph.jsp?wfId=<%=workList.get(i).get("wfId")%>&wfFileName=askForLeave.png">查看</a></td> 
  </tr> 
  <%} %> 
</table> 
</body> 
</html>
    askForLeave/approval.jsp(用於經理審批):
<%@<page<language="java"<contentType="text/html;<charset=UTF-8" 
<<<<pageEncoding="UTF-8"%> 
<!DOCTYPE<html<PUBLIC<"-//W3C//DTD<HTML<4.01<Transitional//EN"<"http://www.w3.org/TR/html4/loose.dtd"> 
<%@page<import="demo.jbpm.AskForLeave"%> 
<%@page<import="java.util.Map"%> 
<html> 
<head> 
<meta<http-equiv="Content-Type"<content="text/html;<charset=UTF-8"> 
<title>apply</title> 
<script<language="javascript"> 
function<go(is_passed) 

<<document.getElementById("is_passed").value<=<is_passed; 
<<document.getElementById("form1").submit(); 

</script> 
</head> 
<body> 
<% 
String<taskId=request.getParameter("taskId"); 
String<id<=<AskForLeave.getBizId(taskId); 
Map<formData<=<AskForLeave.getById(id); 
%> 
<form<id="form1"<name="form1"<method="POST"<action="approval_result.jsp"> 
<input<type="hidden"<name="biz_id"<value="<%=id<%>"/> 
<input<type="hidden"<name="taskId"<value="<%=taskId<%>"/> 
<input<type="hidden"<id="is_passed"<name="is_passed"<value=""/> 
申請人:<%=formData.get("apply_user")<%><br/> 
假期開始時間:<%=formData.get("begin_leave_time")<%><br/> 
假期結束時間:<%=formData.get("end_leave_time")<%><br/> 
請假理由:<%=formData.get("leave_reason")<%><br/> 
審批意見:<input<type="text"<name="approve_remark"<value=""/><br/> 
<input<type="button"<value="贊成"<onclick="go(1)"/>  <input<type="button"<value="拒絕"<onclick="go(2)"/><br/> 
</form> 
</body> 
</html>
    askForLeave/approval_result.jsp(用於響應approval.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<%@page import="demo.jbpm.AskForLeave"%> 
<% 
request.setCharacterEncoding("UTF-8"); 
String result = "成功"; 
try { 
    AskForLeave.approval(request); 

catch(Exception e) { 
    result = "失敗"; 
    e.printStackTrace(); 

%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<%=result %> 
</body> 
</html>
    askForLeave/employeeWorkList.jsp(用於顯示員工工做列表,須要第四個運行):
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<%@page import="demo.jbpm.AskForLeave"%> 
<%@page import="java.util.List"%> 
<%@page import="java.util.Map"%> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<% 
List<Map> workList = AskForLeave.getEmployeeWorkList(); 
%> 
<table border="1"> 
  <tr> 
    <td>工做名稱</td> 
    <td>業務id</td> 
    <td>處理</td> 
    <td>流程圖</td> 
  </tr> 
  <%for(int i=0;i<workList.size();i++){ %> 
  <tr> 
    <% 
    List<Map> actions = (List<Map>) workList.get(i).get("actions");  
    %> 
    <td><%=workList.get(i).get("wfName") %></td> 
    <td><%=workList.get(i).get("biz_id") %></td> 
    <td> 
    <a href="leave_result.jsp?biz_id=<%=workList.get(i).get("biz_id") %>&wfId=<%=workList.get(i).get("wfId") %>&taskId=<%=workList.get(i).get("taskId") %>"><%=workList.get(i).get("taskName") %></a> 
    </td> 
    <td><a href="viewWfGraph.jsp?wfId=<%=workList.get(i).get("wfId")%>&wfFileName=askForLeave.png">查看</a></td> 
  </tr> 
  <%} %> 
</table> 
</body> 
</html>
    askForLeave/leave_result.jsp(用於員工處理後續事務):
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<%@page import="demo.jbpm.AskForLeave"%> 
<% 
request.setCharacterEncoding("UTF-8"); 
String result = "成功"; 
try { 
    AskForLeave.leave(request); 

catch(Exception e) { 
    result = "失敗"; 
    e.printStackTrace(); 

%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>apply</title> 
</head> 
<body> 
<%=result %> 
</body> 
</html>
    八、增長圖形顯示流程狀態。
    此處採用OSWorkflow的作法,把OSWorkflow中的wz_jsgraphics.js放到應用的js目錄下。
    創建askForLeave/viewWfGraph.jsp:
<%@ page import="java.util.List" %> 
<%@page import="demo.jbpm.JBPMUtil"%> 
<%@page import="demo.jbpm.AskForLeave"%> 
<%@page import="org.jbpm.api.model.ActivityCoordinates"%> 
<% 
String wfId = request.getParameter("wfId"); 
String wfFileName = request.getParameter("wfFileName"); 
List<ActivityCoordinates> coors = AskForLeave.getActiveActivityCoordinates(wfId); 
%> 

<div id="workflowCanvas" style="position:relative;height:566px;width:508px;"> 
<img src="<%=wfFileName %>" border=0/> 
</div> 
<script type="text/javascript" src="../js/wz_jsgraphics.js"></script> 

<script type="text/javascript"> 
var jg = new jsGraphics("workflowCanvas"); 
jg.setColor("#ff0000"); 
jg.setStroke(3); 
var xAdjust = 4; 
var yAdjust = 4; 
var widthAdjust = -10; 
var heightAdjust = -10; 
<%for (ActivityCoordinates coor : coors) {%> 
jg.drawRect(parseInt("<%=coor.getX()%>") + xAdjust, parseInt("<%=coor.getY()%>") + yAdjust, parseInt("<%=coor.getWidth()%>") + widthAdjust, parseInt("<%=coor.getHeight()%>") + heightAdjust); 
<%}%> 
jg.paint(); 

</script>
    這樣就作完了,運行應用程序,就能夠看到效果了。值得一提的是,圖形化顯示流程狀態的效果,以下:
 
流程效果圖
相關文章
相關標籤/搜索