Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步
在实际的BPM集成开发过程中,Liferay和Activiti这两个异构的系统之间,用户、组的同步需求非常重要,用来实现签收组的概念,比如指定签收组、会签、抢签都需要用到。
Activiti可以通过自定义实现SessionFactory,实现customUserManager和customRoleManager的方式集成第三方的用户关系。
这里我介绍一个方法,可以借助Liferay的实体监听器来做用户、组、用户-组成员关系的三种同步。
其实实现原理非常简单
用户组的同步,就是实现 BaseModelListener 泛型接口
package com.lifiti.hooks; import org.osgi.service.component.annotations.Component;
import com.liferay.portal.kernel.exception.ModelListenerException;
import com.liferay.portal.kernel.model.BaseModelListener;
import com.liferay.portal.kernel.model.ModelListener;
import com.liferay.portal.kernel.model.UserGroup;
import com.lifiti.util.IdentifyHelper; @Component(immediate = true, service = ModelListener.class)
public class UserGroupListener extends BaseModelListener<UserGroup>{ @Override
public void onAfterCreate(UserGroup ug) throws ModelListenerException{
System.out.println(ug.getUuid()+ug.getName() + " Added.");
IdentifyHelper.saveGroup(ug.getUuid(), ug.getName(), 1);
} @Override
public void onAfterRemove(UserGroup ug) throws ModelListenerException {
System.out.println(ug.getName() + " Deleted.");
IdentifyHelper.delGroup(ug.getUuid());
} @Override
public void onAfterUpdate(UserGroup ug) throws ModelListenerException {
System.out.println(ug.getName() + " Modified.");
IdentifyHelper.delGroup(ug.getUuid());
IdentifyHelper.saveGroup(ug.getUuid(), ug.getName(), 1);
} }
用户,成员关系的同步
其中onAfterAddAssociation 就是监听成员关系,可以在liferay的users_usergroups表和activiti的act_id_membership查看
实际上就是一个关联中间表
package com.lifiti.hooks; import org.osgi.service.component.annotations.Component;
import com.liferay.portal.kernel.exception.ModelListenerException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.BaseModelListener;
import com.liferay.portal.kernel.model.ModelListener;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.service.UserGroupLocalServiceUtil;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.lifiti.util.IdentifyHelper; @Component(immediate = true, service = ModelListener.class)
public class UserListener extends BaseModelListener<User> { @Override
public void onAfterCreate(User u) throws ModelListenerException {
System.out.println(u.getScreenName() + " Added.");
IdentifyHelper.saveUser(u.getScreenName(), u.getLastName() + u.getFirstName(), u.getEmailAddress());
} @Override
public void onAfterRemove(User u) throws ModelListenerException {
System.out.println(u.getUserId() + " Deleted.");
IdentifyHelper.delUser(u.getScreenName());
} @Override
public void onAfterUpdate(User u) throws ModelListenerException {
System.out.println(u.getUserId() + " Modified.");
IdentifyHelper.delUser(u.getScreenName());
IdentifyHelper.saveUser(u.getScreenName(), u.getLastName() + u.getFirstName(), u.getEmailAddress());
} @Override
public void onAfterAddAssociation(Object classPK, String associationClassName, Object associationClassPK)
throws ModelListenerException {
try {
//对关系类型进行过滤,比如com.liferay.portal.kernel.model.UserRole先不处理
if ("com.liferay.portal.kernel.model.UserGroup".equals(associationClassName)) {
IdentifyHelper.createMembership(
UserLocalServiceUtil.getUser(Long.parseLong(classPK.toString())).getScreenName(),
UserGroupLocalServiceUtil.getUserGroup(Long.parseLong(associationClassPK.toString()))
.getUuid());
System.out.println(classPK.toString() + "#" + associationClassName + "#" + associationClassPK.toString()
+ " associationClassName Modified.");
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (PortalException e) {
e.printStackTrace();
}
} @Override
public void onAfterRemoveAssociation(Object classPK, String associationClassName, Object associationClassPK)
throws ModelListenerException {
try {
if ("com.liferay.portal.kernel.model.UserGroup".equals(associationClassName)) {
IdentifyHelper.deleteMembership(
UserLocalServiceUtil.getUser(Long.parseLong(classPK.toString())).getScreenName(),
UserGroupLocalServiceUtil.getUserGroup(Long.parseLong(associationClassPK.toString()))
.getUuid());
System.out.println(classPK.toString() + "#" + associationClassName + "#" + associationClassPK.toString()
+ " associationClassName Removed.");
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (PortalException e) {
e.printStackTrace();
}
} }
运行情况:
1、用户同步,在liferay的用户管理后台添加用户:

添加后,activiti也有同名的用户了(自动同步),即使修改或删除也能同步:

2、用户组同步
注意,liferay叫用户群组,acitiviti叫组

liferay添加组以后,activiti也自动同步:

3、成员关系同步

同步后,发现activiti也有同样的 “用户-组” 关系了

Activiti的集成开发系列文章集合在这里:
http://www.cnblogs.com/starcrm/p/6047486.html
全部工程源代码下载:
http://download.csdn.net/detail/starcrm/9715804
Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步的更多相关文章
- Liferay7 BPM门户开发之44: 集成Activiti展示流程列表
处理依赖关系 集成Activiti之前,必须搞清楚其中的依赖关系,才能在Gradle里进行配置. 依赖关系: 例如,其中activiti-engine依赖于activiti-bpmn-converte ...
- Liferay7 BPM门户开发之26: 集成Activiti到Liferay7
开发顺序: 实战任务1,开发BPM管理后台(用于在Liferay管理中心管理Activiti模型上传) 一个熟悉Portlet操作的项目,为开发打好基础. http://www.cnblogs.com ...
- Liferay7 BPM门户开发之45: 集成Activiti文件上传部署流程BPMN模型
开发文件上传,部署流程模板. 首先,开发jsp页面,deploy.jsp <%@ include file="/init.jsp" %> <h3>${RET ...
- Liferay7 BPM门户开发之47: 集成Activiti待办已办任务清单和流程启动
首先增加两个Portlet,分别用于待办处理.流程启动.待办是别人发起的流程,流到自己这里的流程:流程启动用于发起新的流程. 程序文件放置于 在ACtivit中待办概念分两种,1是指派给你的,专门的指 ...
- Liferay7 BPM门户开发之16: Liferay中用户\站点\组织架构\角色\用户组以及关联关系
用户 . 站点 . 组织架构 . 角色 . 用户组分别是:Users. Site. Organization. Role. UserGroups Users 用户是Liferay portal中的关键 ...
- Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发
hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...
- Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)
开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...
- Liferay7 BPM门户开发之17: Portlet 生命周期
Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() ...
- Liferay7 BPM门户开发之12:acitiviti和liferay用户权限体系集成
写到第12章才出现Liferay的内容,希望可以厚积薄发. 我们的目标是不使用不维护Activiti的用户组织架构,只维护Liferay的体系,这样的好处是非常明显的,即不用做组织架构的同步工作. 原 ...
随机推荐
- PYTHON学习之路_PYTHON基础(1)
学习内容: 1.Python介绍 2.Python程序初接触和变量 3.Python用户交互 4.Python数据类型 5.Python循环if...(elif)...else 6.Python循环w ...
- vb小菜一枚--------早期绑定和后期绑定
早期绑定和后期绑定 Visual Studio 2005 其他版本 将对象分配给对象变量时,Visual Basic 编译器会执行一个名为 binding 的进程.如果将对象分配给声明为特定对 ...
- XStream学习笔记
XStream 所需jar包: xstream-1.3.jar xpp3_min-1.1.4c.jar xmlpull-1.1.3.1.jar 目录: 1.注解去除,标签中带有包名的节点 2.注解修改 ...
- OpenMP之枚举排序
// EnumSort.cpp : 定义控制台应用程序的入口点. //枚举排序 /* 枚举排序(Enumeration Sort)是一种最简单的排序算法,通常也称为秩排序(Rank Sort). 该算 ...
- 将图片在指定窗口中显示-OpenCV应用学习笔记一
1.OpenCV模块划分 OpenCV其实就是一堆用C和C++语言来实现计算机视觉算法的源代码文件:例如C接口函数cvCany()实现了Canny边缘提取算法,我们可以直接将这些源代码添加到自己的软件 ...
- Anciroid的IPC机制-Binder概述
在Linux系统中,是以进程为单位分配和管理资源的.出于保护机制,一个进程不能直接访问另一个进程的资源,也就是说,进程之间互相封闭.但是,在一个复杂的应用系统中,通常会使用多个相关的进程来共同完成一项 ...
- 微软Connect教程系列—VS2015集成新潮工具(四)
本课程来源与微软connect视频教程,Modern Web Tooling in Visual Studio 2015 本课程主要讲下当下流行的前端工具 bower和grunt 首先简单介绍下这俩货 ...
- 用JQ仿造百度书籍预售页面的单屏滚页效果
今天的项目需要做到一个介绍页面,我主动提出走单屏滚页的风格,毕竟交互性好,逼格也高,具体效果可以参照百度知道书籍预售页面. 其实现效果就大概是这样的: 还是老样子,所有步骤文件可以从我的Github上 ...
- 《C#图解教程》读书笔记之六:接口和转换
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.接口那点事儿 (1)什么是接口? 一组函数成员而未实现的引用类型.只有类和结构能实现接口. (2)从ICom ...
- 详解SQL集合运算
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...