JBPM工作流管理例子

2023-10-26

工作中要用到JBPM写工作流,自习的时候找到一篇较好的文章,贴过来共享下!

=========================================================================

在某一公司中,部门员工要休假的话需要部门主管的批准。如果休假天数大于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();

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JBPM工作流管理例子 的相关文章

  • 如何从 Apache .htaccess 创建虚拟主机?

    我在用Apache 之友 XAMPP http www apachefriends org en xampp html在 Windows 本地服务器 中 我将虚拟主机设置为httpd vhosts conf在 Apache 配置目录中 如下
  • Apache Shiro EhCache初始化异常:同一VM中已存在另一个未命名的CacheManager

    我正在尝试将 EhCache 配置为处理启用 Apache Shiro 的 Web 服务中的授权缓存 目前我收到以下异常 org apache shiro cache CacheException net sf ehcache CacheE
  • MAMP 未在 El Capitan 10.11.1 上启动 Apache 服务器

    因此 我在 Yosemite 上的 Apache 服务器上使用 MAMP 已经有一段时间了 我只需要一台本地主机 因此我使用常规 MAMP 而不是 MAMP Pro 我使用的是 MAMP 3 4 当我单击 启动服务器 按钮时 它不响应单击
  • 重写规则以返回某些 URL 的状态 200

    我希望具有特定路径的 URL 自动返回 200 状态响应 我已尝试以下操作 但当我尝试启动 Apache 时出现错误 第一个错误 RewriteCond 错误的标志分隔符 RewriteEngine On RewriteCond THE R
  • 阻止对目录的外部访问,但允许 SSI 访问(或者,“FilesMatch”指令实际上如何工作?)

    在我使用 PHP 的旧网站上 我有一个 htaccess在目录中 noaccess如下 noaccess htaccess
  • 如何使用移动设备访问 Apache 虚拟主机?

    设置主机名为 server1 和 server2 的 Apache 虚拟主机后 由于无法修改 iOS 或 Android 中的 etc hosts 文件 我将如何使用 iPhone 或任何移动设备 访问它们 我的理解是 您必须按名称引用虚拟
  • Mac OS X 上的 Heroku Local 和 PHP

    目前 除了始终在线的 apache 代理 php fpm 之外 我只使用额外的终端选项卡来手动启动工作进程和时钟进程 当我开始使用heroku时 我尝试了heroku local 但它的设置打败了我 现在我想再试一次 我在 High Sie
  • .htaccess 无法阻止“此连接不受信任”警告

    拥有带有插件域的托管帐户 目录结构如下 public html main site is hosted in this directory public html secondary site secondary site is hoste
  • cURL 错误:SSL 对等证书或 SSH 远程密钥不正常 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions Using
  • 阿帕奇“找不到文件。”而不是 404. 错误文档

    我想设置自定义 404 错误文档 但我遇到了问题 首先 我的 htaccess 中有两个 RewriteRules RewriteRule 2 3 php lang 1 L RewriteRule 2 3 4 php lang 1 L 所以
  • apache从非www重定向到www

    我有一个网站似乎没有从非 www 重定向到 www 我的Apache配置如下 RewriteEngine On re direct to www RewriteCond http host www example com nc Rewrit
  • 如何重置 Apache Archiva 密码

    我正在使用 apache archiva 2 2 0 版本 我丢失了管理员密码 因此我想重置管理员用户的密码 我尝试通过删除下面提到的文件来重置密码 apache archiva 2 2 0 data databases users dbe
  • 如何为特定目录设置open_basedir

    我有一个目录 htdocs unsecured我想限制该目录或其子目录中的任何内容访问该目录之外的任何内容 在哪里以及如何设置open basedir仅适用于此目录 您可以设置open basedir在您的 Apache 配置文件 php
  • Apache 反向代理 https 到 http

    我已经在这里和互联网上进行了大量的浏览 但我无法配置我的 apache 将 https 反向代理为 http 不过我觉得我已经很接近了 我遵循的所有示例似乎都适用于除我之外的每个人 而且我的设置非常简单
  • tomcat 7.0.42 上的 403 访问被拒绝

    我有错误tomcat 7 0 42 上的 403 访问被拒绝访问 Tomcat Manager 应用程序时 这就是我所拥有的tomcat 用户 xml文件 我曾多次尝试更换角色 但没有成功 注意 我从 NetBeans 7 3 1 启动 停
  • 为 SSL 配置 MAMP

    好吧 各位编码员 我正在尝试在我的 mac 上使用 SSL 配置 MAMP 以用于开发目的 我已阅读并尝试了以下说明 http www emersonlackey com article mamp with ssl https http w
  • 验证 htaccess 重写规则中的 utf-8

    我使用重写规则验证包含 utf 8 字符的 url RewriteRule a z 2 a z0 9 1 256 print 1 256 index php 语言 1 categories 2 get query 3 大 get query
  • 使用 Grok for Logstash 解析 Apache2 错误日志

    我试图解析我的 apache2 错误日志 但遇到了一些麻烦 它似乎与过滤器不匹配 我很确定时间戳部分是错误的 但我不确定 而且我真的找不到任何文档来解决它 另外 有没有办法获取其中的内容fields errmsg to me message
  • 从 PHP/Apache 返回 100-Continue

    我正在尝试找到一种方法来防止脚本将不必要的数据上传到 PHP 脚本 我最初试图终止传入的读取连接 这显然违反了 HTTP 协议 我无法让它工作 但我一直在研究替代方案 发现100 Continue状态码正是我所需要的 我的客户应该发送所需的
  • apache 和 httpd 正在运行,但我看不到我的网站 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我已经在我的服务器上安装了 apache 但是我无法通过我的服务器 IP 浏览我的网站 apache 的设置是 var www htdocs 下的单帐

随机推荐

  • C语言学习之认识exit()函数

    C语言学习之认识exit 函数 在C语言的main函数中我们通常使用return 0 exit 0 表示程序正常退出 exit exit 1 表示程序异常退出 exit 结束当前进程 当前程序 在整个程序中 只要调用 exit 就结束 但在
  • unity下HybridCLR热更新简易框架

    简易打AB包工具 using System Collections using System Collections Generic using UnityEngine using UnityEditor using HybridCLR E
  • servlet的生命周期

    Servlet的生命周期可以分为5个阶段 加载阶段 创建阶段 初始化阶段 处理客户请求 服务 阶段 销毁阶段 1 加载阶段 服务器接收到客户端请求之后首先会通过类加载器使用servlet类对应的文件加载servlet 2 创建阶段 然后we
  • 河海大学计算机esi排名,河海大学材料科学学科进入ESI国际排名前1%

    根据汤森路透基本科学指标数据库 Essential Science Indicators 简称ESI 2018年3月最新公布的数据 河海大学材料科学学科继工程学 环境 生态学 计算机科学之后首次进入ESI国际学科排名全球前1 实现了学校学科
  • 面试算法题:O(nlogn)查询l~r区间内k的个数

    查询用户文章喜好 我们对用户按照它们的注册时间先后来标号 对于一类文章 每个用户都有不同的喜好值 我们会想知道某一段时间内注册的用户 标号相连的一批用户 中 有多少用户对这类文章喜好值为k 因为一些特殊的原因 不会出现一个查询的用户区间完全
  • 小程序/js/uni订单金额播放

    之前发现直接播放会自动中断 所以纠结了半天 先说思路 首先金额转成字符串 然后截取 得到两段数组 然后遍历 前段需要追加单位 后段小数点后 之后得到需要播放的音频数组 在每段播放完进行完后播放下一段 语音包有点问题就不放了 还是看代码吧 d
  • Chrome浏览器命令行启动参数

    Chrome浏览器命令行启动参数 http blog csdn net qq 32786873 article details 70173265 http blog csdn net u012593626 article details 4
  • Markdown 基本语法

    Markdown 基本语法 初级 一 什么是Markdown Markdown 是一种轻量级标记语言 它允许人们使用易读易写的纯文本格式编写文档 将格式元素添加到纯文本文档 Markdown 允许您使用易于阅读 易于编写的纯文本格式进行编写
  • [运营专题]零预算引爆个人和企业品牌

    文章推荐 Selenium 自动化测试从零实战 原文链接 原来这样做 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Android 物体识别 原文链接 TensorFlow on An
  • File 类和 InputStream, OutputStream 的用法总结

    目录 一 File 类 1 File类属性 2 构造方法 3 普通方法 二 InputStream 1 方法 2 FileInputStream 三 OutputStream 1 方法 2 FileOutputStream 四 针对字符流对
  • 点云数据生成三维模型_Agisoftphotoscan生成三维模型步骤

    随着航空测量技术的飞速发展 利用低空无人飞机进行航空摄影获取遥感数据已成为现实 利用Agisoftphotoscan软件进行影像数据处理 生成数字地表模型 DSM 和正射影像图 DOM 产品的生产 数据生产流程 1 无人机的用途及种类的不同
  • FFmpeg编译配置命令

    configure help Usage configure options Options defaults in brackets after descriptions Help options help print this mess
  • 华为OD机试 - 城市聚集度(Java)

    题目描述 一张地图上有n个城市 城市和城市之间有且只有一条道路相连 要么直接相连 要么通过其它城市中转相连 可中转一次或多次 城市与城市之间的道路都不会成环 当切断通往某个城市 i 的所有道路后 地图上将分为多个连通的城市群 设该城市i的聚
  • 我在项目中遇到的一些经典功能bug

    1 传参类型不同 类型是数组 实际传的是字符串 导致重置搜索条件后导出失败 刷新页面 或者切换中英文也是刷新页面的效果 初始化赋值为null 可以导出成功 重置搜索条件后 导出失败 2 下划线 百分号 可能是适配符 特殊字符 空格 边界值
  • AlSD 系列智能安全配电装置是安科瑞电气有限公司专门为低压配电侧开发的一款智能安全用电产 品-安科瑞黄安南

    一 应用背景 电力作为一种清洁能源 给人们带来了舒适 便捷的电气化生活 与此同时 由于使用不当 维护 不及时等原因引发的漏电触电和电气火灾事故 也给人们的生命和财产带来了巨大的威胁和损失 为了防止低压配电系统发生漏电和电气火灾事故 传统的方
  • 网络运维词汇汇总

    本篇之所以起该名字 是因为我在一家网络公司工作所遇到的一些相关词汇 仅供参考 1 关系型数据库服务 RDS 关系型数据库服务 RelationalDatabase Service 简称RDS 是一种稳定可靠 可弹性伸缩的在线数据库服务 RD
  • Metasploitable2在VMware上的安装与初步渗透学习

    环境 靶机 Metasploitable2 IP 未知 攻击机 KALI IP 192 168 127 5 平台 VMware 16 2 4 一 Metasploitable2的简介 Metasploitable2是一个故意易受攻击的Lin
  • JDK8之Stream流

    1 集合处理数据的弊端 当我们在需要对集合中的元素进行操作的时候 除了必需的添加 删除 获取外 最典型的操作就是集合遍历 public class StreamTest01 public static void main String ar
  • 在cmd控制台运行java程序,错误: 编码GBK的不可映射字符?

    此错误是由于字符编码造成的 出现这样的错误 一般是因为代码中含有中文字符 注释中的中文字符也算 由于使用CMD运行java程序的时候 系统默认的编码格式是gbk 而包含中文字符的代码一般是UNICODE格式 所以直接运行含有中文字符的代码就
  • JBPM工作流管理例子

    工作中要用到JBPM写工作流 自习的时候找到一篇较好的文章 贴过来共享下 在某一公司中 部门员工要休假的话需要部门主管的批准 如果休假天数大于10天的话 在部门主管的同意后 还必须上级主管批准 如果是部门主管要休假只要上级主管批准即可 在休