Liferay7 BPM门户开发之23: 了解内置工作流(Kaleo Workflow)
Liferay内置的工作流是企业版的功能,虽然简单粗糙,但依然不支持社区版。
既然要用更强大的Activiti来替代它,那就非常有必要学习一下内置工作流的一些思想,以便借鉴。
它的特点:
- 实体的工作流操作可以通过service layer进行集成;
- 需要添加4个额外的字段来跟踪流程状态;
- 通过Service Builder来建立字段,然后更新service layer;
- 视图层UI可以显示实体的工作流状态。
实体集成逻辑
比如,发布一个实体类的工作流支持,首先添加注解:
@Component(
property = {"model.class.name=com.my.app.package.model.FooEntity"},
service = WorkflowHandler.class
)
开发XXXWorkflowHandler,实现Override 三个方法
package com.liferay.docs.foo.workflow; ...
public class FooEntityWorkflowHandler extends BaseWorkflowHandler { public static final String CLASS_NAME = FooEntity.class.getName(); @Override
public String getClassName() { return CLASS_NAME;
} @Override
public String getType(Locale locale) {
return LanguageUtil.get(locale, "model.resource" + CLASS_NAME);
} @Override
public Object updateStatus(int status,
Map<String, Serializable> workflowContext) throws PortalException,
SystemException { long userId = GetterUtil.getLong(
(String)workflowContext.get(WorkflowConstants.CONTEXT_USER_ID));
long fooEntityId = GetterUtil.getLong(
(String)workflowContext.get(
WorkflowConstants.CONTEXT_ENTRY_CLASS_PK)); ServiceContext serviceContext = (ServiceContext)workflowContext.get(
"serviceContext"); return FooEntityLocalServiceUtil.updateStatus(
userId, fooEntityId, status, serviceContext); }
}
为了记录实体的当前流程状态,必须要有以下4个字段(通过Service Builder)
service.xml中添加:
<column name="status" type="int" />
<column name="statusByUserId" type="long" />
<column name="statusByUserName" type="String" />
<column name="statusDate" type="Date" />
比如在更新实体时,自动通过这4个字段,把实体和流程状态相关联:
fooEntity.setStatus(status);
fooEntity.setStatusByUserId(user.getUserId());
fooEntity.setStatusByUserName(user.getFullName());
fooEntity.setStatusDate(serviceContext.getModifiedDate(now)); fooEntityPersistence.update(fooEntity);
启动一个和实体关联的流程:
WorkflowHandlerRegistryUtil.startWorkflowInstance(fooEntity.getCompanyId(),
fooEntity.getGroupId(), fooEntity.getUserId(), FooEntity.class.getName(),
fooEntity.getPrimaryKey(), fooEntity, serviceContext);
如果实体属于Assets,那在为实体设置工作流字段后,就可以添加任何附加的逻辑方法。
例如,如果想根据其工作流状态来设置可见性(未审批就不显示):
if (status == WorkflowConstants.STATUS_APPROVED) {
assetEntryLocalService.updateEntry(
FooEntity.class.getName(), fooEntityId, fooEntity.getDisplayDate(),
null, true, true);
}
else {
assetEntryLocalService.updateVisible(
fooEntity.class.getName(), entryId, false);
}
为了在视图中展示,需要设置finder (service.xml)
<finder name="G_S" return-type="Collection">
<finder-column name="groupId"></finder-column>
<finder-column name="status"></finder-column>
</finder>
实现一个Getter:
public List<FooEntity> getFooEntities(long groupId, int status)
throws SystemException {
return fooEntityPersistence.findByG_S(groupId,
WorkflowConstants.STATUS_APPROVED);
} jsp UI: <liferay-ui:search-container-results
results="<%=FooEntityLocalServiceUtil.getFooEntities(scopeGroupId,
fooEntityId(), Workflowconstants.STATUS_APPROVED, searchContainer.getStart(),
searchContainer.getEnd())%>"
...
流程设计器
这个属于企业版功能,有点弱
这个有点意思:
设置启动任务的签收者,
一共有6种类型:
- 创建者
- 某角色
- 角色ID
- 通过一个代码段来指定
- 特定的用户
- 通过资源
在Kaleo中,只有这6种节点,这实在可怜,恐怕要实现复杂的流程将依靠编写大量的代码来实现。
现在知道为啥Kaleo叫workflow而不是叫BPM了吧,因为其不能实现业务流程集成,但实现仅简单顺序流程,还是没有问题的。
- Condition: 通过脚本来实现条件逻辑(script包含几种语言:Beanshell、Drl、Groovy、JavaScript、Python、Ruby),这有点不太友好和方便;
- Fork: 并行处理
- Join: Fork并行后的汇总,这个可以实现会签,比如说一个节点由领导A、领导B同时审核才能结束,往下走;
- Join XOR: 异或逻辑的汇总,通俗的说就是实现抢签,有点像Activiti的候选组的概念,比如说一个节点由领导A、领导B审核,随便一个领导先审核了,节点就结束,往下走;
- State: 状态节点,比如开始、结束就是属于这个类型;
- Task: 任务节点,比如审批、填写表单....
一个XML的描述文件:
Liferay7 BPM门户开发之23: 了解内置工作流(Kaleo Workflow)的更多相关文章
- Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发
hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...
- Liferay7 BPM门户开发之17: Portlet 生命周期
Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() ...
- Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)
开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...
- Liferay7 BPM门户开发之12:acitiviti和liferay用户权限体系集成
写到第12章才出现Liferay的内容,希望可以厚积薄发. 我们的目标是不使用不维护Activiti的用户组织架构,只维护Liferay的体系,这样的好处是非常明显的,即不用做组织架构的同步工作. 原 ...
- Liferay7 BPM门户开发之11: Activiti工作流程开发的一些统一规则和实现原理(完整版)
注意:以下规则是我为了规范流程的处理过程,不是Activiti公司的官方规定. 1.流程启动需要设置启动者,在Demo程序中,“启动者变量”名统一设置为initUserId 启动时要做的: ident ...
- Liferay7 BPM门户开发之9: 流程表单数据动态映射体系
设计目的: 每个流程表单涉及不同的表单变量.比如请假流程有3个任务节点,分别是 Task1:开始流程,填写请假人.请假原因.请假开始时间.请假结束时间: Task2:上级审批,填写是否同意,审批意见: ...
- Liferay7 BPM门户开发之35: AssetTag的集成查询
Tag是liferay中的Asset特性,可以用来对信息进行分类,在iferay中的Asset类型为: 1. Web Content(自定义内容) 2. Documents and Media(文档库 ...
- Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)
第一步:修改liferay-hook.xml <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Lifer ...
- Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步
在实际的BPM集成开发过程中,Liferay和Activiti这两个异构的系统之间,用户.组的同步需求非常重要,用来实现签收组的概念,比如指定签收组.会签.抢签都需要用到. Activiti可以通过自 ...
随机推荐
- windows from docker 安装部署spring jar包方法
1.安装docker for windows,去官网下载就可以了,按照官网安装 2.把jar和dockerfile放在一个目录下(target 目录下) Dockerfile: FROM java:8 ...
- 微软BI 之SSIS 系列 - 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式
开篇介绍 关于 Slowly Changing Dimension 缓慢渐变维度的理论概念请参看 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型 ...
- MariaDB ColumnStore初探(1):安装、使用及测试
相信大家在对接BI数据报表部门有很深刻的体验,高大上的复杂SQL关联JOIN十几张表在InnoDB里跑起来,会让你酸爽到死.它的出现正是解决这个问题,DBA能不能轻松愉快地玩耍,就要靠它了,“神州行我 ...
- Java线程池的构造以及使用
有时候,系统需要处理非常多的执行时间很短的请求,如果每一个请求都开启一个新线程的话,系统就要不断的进行线程的创建和销毁,有时花在创建和销毁线程上的时间会比线程真正执行的时间还长.而且当线程数量太多时, ...
- zabbix自定义监控
有的时候zabbix提供的监控项目,不能满足我们生产环境下的监控需求,此时我们就要按照zabbix的规范自定义监控项目,达到监控的目的 zabbix_get:模拟zabbix_server和agent ...
- 洛谷1345 [USACO5.4]奶牛的电信Telecowmunication
原题链接 最小割点数转换成最小割边数的模板题(不过这数据好小). 每个点拆成两个点,连一条容量为\(1\)的边,原图的边容量定为\(+\infty\),然后跑最大流即可. 这里用的是\(Dinic\) ...
- 九校联考_24OI——餐馆restaurant
凉心模拟D1T1--最简单的一道题 TAT 餐馆(restaurant) 题目背景 铜企鹅是企鹅餐馆的老板,他正在计划如何使得自己本年度收益增加. 题目描述 共有n 种食材,一份食材i 需要花ti 小 ...
- cpp 区块链模拟示例(五) 序列化
有了区块和区块链的基本结构,有了工作量证明,我们已经可以开始挖矿了.剩下就是最核心的功能-交易,但是在开始实现交易这一重大功能之前,我们还要预先做一些铺垫,比如数据的序列化和启动命令解析. 根据< ...
- KD-树(下)
来自于https://zhuanlan.zhihu.com/p/23966698 构造 kd 树的例子 上面抽象的定义和算法确实是很不好理解,举一个例子会清楚很多.首先随机在 中随机生成 13 个点作 ...
- spring jdbc 记录
@Repository("com.example.demo.dao.impl.SmpUserDaoImpl") public class SmpUserDaoImpl implem ...