Activiti Docking Business Table Implementing Custom Users and User Groups

Keywords: Programming Java Session Spring

Statement: Activiti Version 5.22.0. act_id_* series tables related to users and user groups are generated when Activiti is initialized, but in actual business, our system may not access workflow in the initial stage. Later access involves how to connect users in existing business tables with Activiti. This paper briefly introduces the ideas below.

1. Custom Implementation of Activiti User Management Interface

The custom class CustomUserEntityManagerFactory implements the SessionFactory interface and overrides the getSessionType and openSession methods. The core code is as follows:

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.UserIdentityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomUserEntityManagerFactory implements SessionFactory{
	@Autowired 
	private CustomUserEntityManager customUserEntityManager;

	@Override
	public Class<?> getSessionType() {
		return UserIdentityManager.class;
	}

	@Override
	public Session openSession() {
		return customUserEntityManager;
	}
	
}

Where the class CustomUserEntityManager inherits the UserEntityManager class:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.UserQueryImpl;
import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.impl.persistence.entity.UserEntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.fengunion.scf.data.usermanage.role.service.RoleService;
import com.fengunion.scf.data.usermanage.user.entity.User;
import com.fengunion.scf.data.usermanage.user.service.UserService;
import com.fengunion.scf.data.workflow.common.constant.WorkflowConstants;
import com.fengunion.scf.data.workflow.common.util.ActivitiUserUtil;

@Component
public class CustomUserEntityManager extends UserEntityManager{

	@Autowired
	@Lazy
	private UserService userService;
	@Autowired
	@Lazy
	private RoleService roleService;
	@Override
	public UserEntity findUserById(String userId) {
		User user = getUser(userId);
		return ActivitiUserUtil.toActivitiUser(user);
	}

	@Override
	public List<Group> findGroupsByUser(String userId) {
		if (userId == null) {
            return null;
		}
		User uparam = new User();
		uparam.setPkid(Long.valueOf(userId));
		User user = userService.selectOne(uparam);
		List<String> list = roleService.fingRoleCodeByUserId(Long.valueOf(userId));
		List<Group> gs = ActivitiUserUtil.toActivitiGroups(user.getFkEnterpriseBasicId(),list);
		return gs;
	}

	@Override
	public List<org.activiti.engine.identity.User> findUserByQueryCriteria(UserQueryImpl query, Page page) {
		User user = getUser(query.getId());
		List<org.activiti.engine.identity.User> list = new ArrayList<>();
		list.add(ActivitiUserUtil.toActivitiUser(user));
		return list;
	}
	
	private User getUser(String userId) {
		User user = new User();
		if(WorkflowConstants.INTERFACE_SYSTEM_ID.equals(userId)) {
			user.setPkid(Long.valueOf(WorkflowConstants.INTERFACE_SYSTEM_ID));
			user.setNickName(WorkflowConstants.INTERFACE_SYSTEM_NAME);
			user.setRealName(WorkflowConstants.INTERFACE_SYSTEM_NAME); 
			user.setPswd("");
			user.setEmail("");
		}else {
			User prarmUser = new User();
			prarmUser.setPkid(Long.valueOf(userId));
			user = userService.selectOne(prarmUser);
		}
		return user;
	}

	@Override
	public long findUserCountByQueryCriteria(UserQueryImpl query) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public IdentityInfoEntity findUserInfoByUserIdAndKey(String userId, String key) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public List<String> findUserInfoKeysByUserIdAndType(String userId, String type) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public List<org.activiti.engine.identity.User> findPotentialStarterUsers(String proceDefId) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public List<org.activiti.engine.identity.User> findUsersByNativeQuery(Map<String, Object> parameterMap,
			int firstResult, int maxResults) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public long findUserCountByNativeQuery(Map<String, Object> parameterMap) {
		throw new RuntimeException("not implement method.");
	}
	
}

2. Custom Implementation of Activiti User Management Interface

Custom class CustomGroupEntityManagerFactory implements SessionFactory interface, rewrites getSessionType and openSession methods, and the core code is as follows:

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomGroupEntityManagerFactory implements SessionFactory{
	@Autowired
	private CustomGroupEntityManager customGroupEntityManager;	  

	@Override
	public Class<?> getSessionType() {
		return GroupIdentityManager.class;
	}

	@Override
	public Session openSession() {
		return customGroupEntityManager;
	}

}

Among them, the CustomGroupEntityManager class is as follows:

import java.util.List;
import java.util.Map;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.GroupQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.persistence.entity.GroupEntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Component;
import com.fengunion.scf.data.usermanage.role.service.RoleService;
import com.fengunion.scf.data.usermanage.user.entity.User;
import com.fengunion.scf.data.usermanage.user.service.UserService;
import com.fengunion.scf.data.workflow.common.util.ActivitiUserUtil;

@Component
public class CustomGroupEntityManager extends GroupEntityManager{
	@Lazy
	@Autowired
	private RoleService roleService;
	
	@Lazy
	@Autowired
	private UserService userService;
	
	@Override
	public List<Group> findGroupsByUser(String userId) {
		if (userId == null){  
            return null;
		}
        try {
    		User uparam = new User();
    		uparam.setPkid(Long.valueOf(userId));
    		User user = userService.selectOne(uparam);
    		List<String> list = roleService.fingRoleCodeByUserId(Long.valueOf(userId));
    		List<Group> gs = ActivitiUserUtil.toActivitiGroups(user.getFkEnterpriseBasicId(),list);
            return gs;
        } catch (EmptyResultDataAccessException e) {  
            return null;  
        }
	}

	@Override
	public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public long findGroupCountByQueryCriteria(GroupQueryImpl query) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public List<Group> findGroupsByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {
		throw new RuntimeException("not implement method.");
	}

	@Override
	public long findGroupCountByNativeQuery(Map<String, Object> parameterMap) {
		throw new RuntimeException("not implement method.");
	}
	
	

}

3. Register the user and user group management classes defined by yourself in the Activiti configuration. The core code is as follows (I take spring boot configuration as an example):

...
@Autowired
	private CustomUserEntityManagerFactory customUserEntityManagerFactory;
	
	@Autowired
	private CustomGroupEntityManagerFactory customGroupEntityManagerFactory;
...
	@Override
	public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
...
 		//Custom Users and Groups
		List<SessionFactory> customSessionFactories = new ArrayList<>();
		customSessionFactories.add(customUserEntityManagerFactory);
		customSessionFactories.add(customGroupEntityManagerFactory);
        processEngineConfiguration.setCustomSessionFactories(customSessionFactories);
...
}

The ActivitiUserUtil tool class is as follows:

import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.persistence.entity.GroupEntity;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import com.fengunion.scf.data.usermanage.user.entity.User;


public class ActivitiUserUtil {
	public static UserEntity toActivitiUser(User bUser){  
		UserEntity userEntity = new UserEntity();  
        userEntity.setId(bUser.getPkid().toString());  
        userEntity.setFirstName(bUser.getNickName());  
        userEntity.setLastName(bUser.getRealName());  
        userEntity.setPassword(bUser.getPswd());  
        userEntity.setEmail(bUser.getEmail());  
        userEntity.setRevision(1);  
        return userEntity;  
    } 
    
    public static GroupEntity toActivitiGroup(Long enterpriseBasicId,String code){  
        GroupEntity groupEntity = new GroupEntity();  
        groupEntity.setRevision(1);  
        groupEntity.setType("assignment");  
        groupEntity.setId(enterpriseBasicId+"_"+code);  
        return groupEntity;  
    }  
  
    public static List<Group> toActivitiGroups(Long enterpriseBasicId,List<String> roleCodeList){  
        List<Group> groups = new ArrayList<>();  
        for (String code : roleCodeList) {  
            GroupEntity groupEntity = toActivitiGroup(enterpriseBasicId,code);  
            groups.add(groupEntity);  
        }  
        return groups;  
    }  
}

So far, the implementation of custom users and user groups is basically achieved.

Posted by dzoddi on Sun, 27 Jan 2019 17:03:14 -0800