一个JBPM工作流管理示例

转载 2007年09月27日 20:26:00
示例:
在某一公司中,部门员工要休假的话需要部门主管的批准。如果休假天数大于10天的话,在部门主管的同意后,还必须上级主管批准。如果是部门主管要休假只要上级主管批准即可。在休假被批准之前,申请人可以撤销休假申请。
每个员工还有多少天休假必须管理起来,在员工提交休假申请时要检查申请天数是否超过可用天数。申请批准后,要在可用天数里减去申请天数。每次休假申请结束之后,不管通过未通过或是否取消,都必须记录下来。主管在批复申请之后,系统要将批复结果Email给申请人。对于大于10天的申请,如果部门主管已批准同意而上级主管还未批准,这时申请人撤销申请后,系统应发Email通知部门主管申请已撤销。 
  processdefinition.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSPY v2004 rel. 3 U (
http://www.xmlspy.com) by keller (zju) -->
<!DOCTYPE process-definition PUBLIC
    "-//jBpm/jBpm Mapping DTD 2.0//EN"
    "http://jbpm.org/dtd/processdefinition-2.0.dtd">
<process-definition  name="RequestLeave">
 <swimlane name="requester">
  <description>申请者</description>
 </swimlane>
 <swimlane name="chief">
  <description>部门主管</description>
  <delegation class="kellerdu.jbpm.delegation.ChiefSwimlane"/>
 </swimlane>
 <swimlane name="boss">
  <description>上级主管</description>
  <delegation class="kellerdu.jbpm.delegation.BossSwimlane"/>
 </swimlane>
 <start-state name="request" swimlane="requester">
  <transition to="BeginRequest"/>
 </start-state>
 <fork name="BeginRequest">
  <transition to="RequesterCancel"/>
  <transition to="IsChief"/>
 </fork>
 <decision name="IsChief">
  <delegation class="kellerdu.jbpm.delegation.ChiefDecision"/>
  <transition name="BossApprove"  to="BossApprove"/>
  <transition name="ChiefApprove"  to="ChiefApprove"/>
 </decision>
 <state name="RequesterCancel">
  <assignment swimlane="requester"/>
  <transition name="cancel" to="Decided">
   <action>
    <!-- 将请假的状态改变为“取消”-->
    <delegation class="kellerdu.jbpm.action.RequestCancel"/>
   </action>
  </transition>
 </state>
 <state name="ChiefApprove">
  <assignment swimlane="chief"/>
  <transition name="approve" to="NeedBossApprove">
   <action>
    <!-- 将请假的状态改变为“主管批准”-->
    <delegation class="kellerdu.jbpm.action.ChiefApprove"/>
   </action>
  </transition>
  <transition name="disapprove" to="Decided">
   <action>
    <!-- 将请假的状态改变为“主管否决”-->
    <delegation class="kellerdu.jbpm.action.ChiefDisapprove"/>
   </action>
  </transition>
 </state>
 <state name="BossApprove">
  <assignment swimlane="boss"/>
  <transition name="approve" to="Decided">
   <action>
    <!-- 将请假的状态改变为“老板批准”-->
    <delegation class="kellerdu.jbpm.action.BossApprove"/>
   </action>
  </transition>
  <transition name="disapprove" to="Decided">
   <action>
    <!-- 将请假的状态改变为“老板否决”-->
    <delegation class="kellerdu.jbpm.action.BossDisapprove"/>
   </action>
  </transition>
 </state>
 <decision name="NeedBossApprove">
  <!-- 请假天数大于10天的要老板批准  -->
  <delegation class="kellerdu.jbpm.delegation.NeedBossApproveDecision"/>
  <transition name="need" to="BossApprove"/>
  <transition name="notNeed" to="Decided"/>
 </decision>
 <join name="Decided">
  <description>有一个先到达即进行父Token</description>
  <delegation class="kellerdu.jbpm.delegation.DecidedJoin"/>
  <transition to="DoSomething"/>
 </join>
 <decision name="DoSomething">
  <description>
    根据请求的状态决定。
    (1)“主管或者老板批准”-‘approve’:修改员工休假的总天数,设定发给用户E-Mail的信息。
    (2)“主管或者老板否决”-“disapprove”:设定发给用户E-Mail的信息。
    (3)“撤销”-"cancel"-设定发给用户E-Mail的信息。如果主管批准,要发给主管消息说明已经撤销。
    </description>
  <delegation class="kellerdu.jbpm.delegation.DoSomethingDecision"/>
  <transition name="disapprove" to="Finished">
   <action>
    <delegation class="kellerdu.jbpm.action.Disapprove"/>
   </action>
  </transition>
  <transition name="approve" to="Finished">
   <action>
    <delegation class="kellerdu.jbpm.action.Approve"/>
   </action>
  </transition>
  <transition name="cancel" to="Finished">
   <action>
    <delegation class="kellerdu.jbpm.action.Cancel"/>
   </action>
  </transition>
 </decision>
 <end-state name="Finished"/>
 <action event-type="process-end">
  <!-- 发送E-Mail消息给申请者,记录请假日志 -->
  <delegation class="kellerdu.jbpm.action.ProcessEndAction"/>
 </action>
</process-definition>
 

Action指明的是当前状态要执行的一些额外的操作,如记录log、发邮件等。
(1)Swimline的delegation要做的就是判别当前Actor的身份。
package kellerdu.jbpm.delegation;

import org.jbpm.delegation.*;
import kellerdu.jbpm.LogsFactory;
import org.apache.commons.logging.Log;

public class BossSwimlane implements AssignmentHandler {
    public BossSwimlane() {
    }

    /**
     * 当前的状态有哪个actor来具体负责处理,选择是老板的actor来处理。
     *
     * 如果王林是老板,那么他请假可以用他的名称来开始一个请假流程,当他检查他需要批示的
     * 请假时,使用actorId=boss来找出所有的批示。这时selectActor返回的值就是一个常量“boss”
     *
     *
     * @param assignmentContext AssignmentContext
     * @return String
     * @todo Implement this org.jbpm.delegation.AssignmentHandler method
     */
    public String selectActor(AssignmentContext assignmentContext) {
        Log log = LogsFactory.getLogInstance(this.getClass());
        log.info("任务分配给老板");
        return "boss";
    }
}
========================================
ackage kellerdu.jbpm.delegation;

import org.jbpm.delegation.*;
import kellerdu.jbpm.LogsFactory;
import org.apache.commons.logging.Log;

public class ChiefSwimlane implements AssignmentHandler {
    public ChiefSwimlane() {
    }

    /**
     * selectActor
     * @see BossSwimlane
     *
     * @param assignmentContext AssignmentContext
     * @return String
     * @todo Implement this org.jbpm.delegation.AssignmentHandler method
     */
    public String selectActor(AssignmentContext assignmentContext) {
       Log log = LogsFactory.getLogInstance(this.getClass());
        log.info("任务分配给上级主管");
       return "chief";
    }
}
(二)Decision
package kellerdu.jbpm.delegation;

import org.jbpm.delegation.*;
import kellerdu.jbpm.LogsFactory;
import org.apache.commons.logging.Log;
import kellerdu.jbpm.Constants;

public class ChiefDecision implements DecisionHandler {
    public ChiefDecision() {
    }

    /**
     * 判断是否需要主管批准,决定下一个要进行的transition
     *
     * @param executionContext ExecutionContext
     * @return String
     * @todo Implement this org.jbpm.delegation.DecisionHandler method
     */
    public String decide(ExecutionContext executionContext) {
        Log log=LogsFactory.getLogInstance(this.getClass());
        String ac=(String)executionContext.getVariable(Constants.USER_NAME);
        if(ac!=null&&(ac.equals("dali")||ac.equals("wang"))){
            log.info(ac+"需要老板批准!");
            return "BossApprove";
        }else{
            log.info(ac+"需要先经主管批准");
            return "ChiefApprove";
        }
    }
}
=======================
(三)fork
package kellerdu.jbpm.delegation;

import org.jbpm.*;
import org.jbpm.delegation.*;
import org.jbpm.model.execution.*;
import java.util.*;

public class DecidedJoin implements JoinHandler {
    public DecidedJoin() {
    }

    /**
     * fork,只要一个分支到达,即可进行下一步操作,同时取消其它同时进行的分支。
     * 这里就是用户如果取消,请假就取消。如果用户请假批准,则用户不能取消。
     *
     * @param forkContext ForkContext
     * @throws ExecutionException
     * @todo Implement this org.jbpm.delegation.ForkHandler method
     */
    public void join(JoinContext joinContext) throws ExecutionException {
        Iterator it=joinContext.getConcurrentTokens().values().iterator();
        Token arrivingToken = joinContext.getToken();
        while(it.hasNext()){
            Token to=(Token)it.next();
            if(to.getId().equals(arrivingToken.getId())){
                //取消其它执行的Token
                joinContext.getExecutionService().cancelToken(to.getId());
            }
        }
         // reactivate the parent token.
          joinContext.reactivateToken( arrivingToken.getParent() );
    }
}
 (一)  开始一个请假流程
       //user是请假人的actorId
       ExecutionService es=JbpmServiceFactory.getInstance().openExecutionService(user);
        HashMap vs=new HashMap();
       //一些参数
        vs.put(Constants.REQUEST_STATUS,String.valueOf(0));
        vs.put(Constants.REQUEST_RETURN_INFO,"No info!");
        vs.put(Constants.USER_NAME,EncodeTransfer.toISO(user));
        vs.put(Constants.REQUEST_DAYS,String.valueOf(rea.getDays()));
        try {
           //开启请假流程
            es.startProcessInstance(Constants.WORK_NAME, vs);
            log.info("["+user+"]"+"申请假期开始!请假"+rea.getDays()+"天!");
            return am.findForward("main");
        } catch (ExecutionException ex) {
            ex.printStackTrace();
            log.error("请假进程无法开始!");
            return am.findForward("error");
        }finally{
            es.close();
        }
(二)当前执行任务
    对于部门经理或者老板,找到要处理的请假。
       String actorId = (String) req.getSession().getAttribute(Constants.USER);
            if(actorId.equals("wang")){
                actorId="boss";
            }else if(actorId.equals("bigli")){
                actorId="chief";
            }
            // get the execution service
            ExecutionService executionService = JbpmServiceFactory.getInstance().
                                                openExecutionService(actorId);

            // get the tasklist from jbpm for user
            List tasks = new ArrayList();
            // add the jbpm tasks
            tasks.addAll(executionService.getTaskList(actorId));
            // put the tasklist into the form
            mf.setTasks(tasks);
            // get the tasklist from jbpm for user
            List definitions = new ArrayList();
            // add the jbpm definitions
            definitions.addAll(executionService.getLatestDefinitions());
            // put the tasklist into the form
            mf.setRequests(definitions);
            // close the execution service
            executionService.close();
            req.getSession().setAttribute("mainForm",mf);
            log.debug("任务: " + tasks);
            log.debug("当前可以执行的请求: " + definitions);
(三)处理请假
           String actorId = (String) reqrest.getSession().getAttribute(Constants.
                    USER);
            Long tokenId=new Long(req.getParameter("tokenId"));
            // get the execution service
            ExecutionService executionService = JbpmServiceFactory.getInstance().
                                                openExecutionService(actorId);
            Map hm=executionService.getVariables(tokenId);//变量
            String act=req.getParameter("action");//进行转换的transition
            executionService.endOfState(tokenId,hm,act);
            executionService.close();


阅读全文(6851) | 回复(6) | TrackBack(6) | 编辑 | 精华
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

huang(游客)发表评论于2007-6-8 15:20:29

ding

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

yy(游客)发表评论于2006-10-26 15:16:48

写得好

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

lion(游客)发表评论于2006-9-26 15:16:32

顶!!

非常感谢楼主!!


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

father(游客)发表评论于2006-9-6 13:37:41

不明白你的AssignmentHandler 里面怎么还有selectActor方法. jbpm里面没有定义这个接口

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

father(游客)发表评论于2006-9-6 13:35:54

public class MyAssignmentHandler implements AssignmentHandler {

 public void assign(Assignable arg0, ExecutionContext arg1) throws Exception {
  
  arg0.setActorId("papa");
  System.out.println();
 }


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:一个JBPM工作流管理示例
软件技术,  电脑与网络

sss(游客)发表评论于2006-8-25 14:16:48

hao

hao


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 
 

【代码篇】JBPM4.4结合业务实现简单工作流

继博客【思想篇】工作流技术JBPM开发入门(三)的实现完成!应对业务的变化。   其实这次对于工作流的学习大概分了3主要个阶段:   1,结合业务开发一个简单的工作流,应对业务的变更 2,结合业务开发...
  • hejingyuan6
  • hejingyuan6
  • 2015年01月13日 21:48
  • 4472

浅析JBPM工作流引擎

JBPM中文意为java业务流程管理,它通过JPDL(Java 流程定义语言)制定一套流程规则,也就是一条流程实例,将整个业务分成多个节点,该业务的执行将按照该流程实例所定义好的节点顺序依次进行。JB...
  • a1314517love
  • a1314517love
  • 2014年02月07日 15:55
  • 6870

工作流引擎:jbpm和activiti

目前流行的工作流引擎有Activiti和jBPM5,而在jBPM5发布以前大多数项目、平台都是基于jBPM3、jBPM4开发的。jbpmJBPM,全称是Java Business Process Ma...
  • zhang_study_it
  • zhang_study_it
  • 2015年09月09日 23:45
  • 1380

宅急送 项目第八天 JBPM工作流框架

项目第八天和项目第九天 学习 JBPM 理论部分 项目第十天 权限管理模块 项目第十一天 项目第十二天 JBPM 应用 1. 工作流框架概述1.1. 什么是工作流工作流(Workflow),就是“...
  • CSDN_AF
  • CSDN_AF
  • 2017年04月23日 22:59
  • 1009

如何用jbpm做出一个状态可视化动态可编辑的工作流平台-1

什么是JBPM在我们决定学习JBPM之前,还是先来看看这头骡子是个什么东西,以下是百度百科上的解释: JBPM,全称是Java Business Process Management(业务流程管理)...
  • u013613428
  • u013613428
  • 2016年05月28日 13:06
  • 11683

JBPM(二)---JBPM工作流基本操作

流程定义的管理: 将定义业务流程,部署到 jbpm框架中 (流程定义 jpdl.xml 描述文件) 通过gpd 插件 先根据业务流程,绘制流程图 (holiday.jpdl.xml 和 holid...
  • qq_36414013
  • qq_36414013
  • 2017年06月08日 21:54
  • 1031

JBPM学习(一):实现一个简单的工作流例子全过程

test.png
  • v123411739
  • v123411739
  • 2014年05月02日 17:32
  • 42844

j2ee常用工作流比较(shart、osworkflow、jbpm)

工作流引擎   Shark(EnhydraShark) Osworkflow opensymphony Jbpm(JBoss JBPM) 工作流描述语言...
  • shadowkiss
  • shadowkiss
  • 2013年05月07日 15:14
  • 2210

初识工作流 BPMN Activiti以及JBPM

最近做OA系统,接触了工作流,知道了JBPM和Activiti两种工作流引擎。 工作流    BPMN   BPMN全称Business Process Model And Notation...
  • u013045552
  • u013045552
  • 2017年02月05日 19:30
  • 1938

Java工作流引擎学习----JBPM(一)

Java工作流引擎学习----JBPM  一、简介 主动性编程: 方法  --->  类 --->  jar ---> 类库    特性:已经封装好的功能,供我们去调用,通过组合这些功能来完成代码...
  • qq_26504875
  • qq_26504875
  • 2016年01月09日 10:53
  • 5883
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个JBPM工作流管理示例
举报原因:
原因补充:

(最多只允许输入30个字)