Wednesday 5 August 2015

Dynamic Roles/User assignment in Liferay Kaleo workflow

What is Kaleo Workflow ?

 Liferay Portal includes a workflow engine called Kaleo. Kaleo workflow allows a user to define any number of simple to complex business processes/workflows, deploy them, and manage them through a portal interface. Those processes have knowledge of users, groups, and roles without writing a single line of code—it only requires the creation of a single XML document.
 You can get all information about kaleo workflow here.
Link:

In kaleo defination xml file you can have <task> tag to define task which have <actions> tag to perform action on workflow, <notification> tag to notify when any action occurs, <assignments> tag to assign workflow to user/role, <transitions> tag to forward workflow to next step. In this blog we are going to discuss about <assignments> tag and  how you can assign workflow task to Role dynamically.

Generally, In <assignments> we give some <role> and <user> tag to assign the workflow task respective to Liferay Role and User. The example as below.
<assignments>
              <roles>
                         <role>
                                     <role-type>organizatiaon</role-type>
                                     <name>Organization Approver</name>
                          </role>
                           <role>
                                     <role-type>regular </role-type>
                                     <name>Portal Content Reviewer</name>
                            </role>
                </roles>
</assignments>

Here Role assignment is static but if you want to make it dynamic or programmatically then how to do?  For that Liferay support Groovy script to assign task dynamically. We are going to understand by taking practical use case.

Use case : Our user case is such that one user create web content and assign some categories to this web content. Now When User will publish this web content then the Role which map to web content categories should have assign this web content for review. Please note that here the mapping between Role and web content as Role name will be Category name + " " + "Approver". So for example if user assign category as "HR" then the web content only assign to Users which have "HR Approver" Role. If user does not assign any category to web content then the default Role is "HR Home Page Reviewer".
 The groovy script for above use cases is as below.
 <assignments>
    <scripted-assignment>
                <script>
                                <![CDATA[
                                     import com.liferay.portal.kernel.util.GetterUtil;
                                     import com.liferay.portal.kernel.workflow.WorkflowConstants;
                                     import com.liferay.portal.model.Role;
                                     import com.liferay.portal.service.ServiceContext;
                                     import com.liferay.portal.service.RoleLocalServiceUtil;
                                     import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
                                     import com.liferay.portlet.asset.model.AssetCategory;
                                                                                                               
                                     long companyId = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_COMPANY_ID));
                                     long groupId = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_GROUP_ID));
                                     roles = new ArrayList<Role>();
                                     ServiceContext serviceContext = (ServiceContext) workflowContext.get(WorkflowConstants.CONTEXT_SERVICE_CONTEXT);
                                     long[] categoryIds = serviceContext.getAssetCategoryIds();
                                     if(categoryIds.length>0){
                                             for(int i=0; i< categoryIds.length;i++){
                                                       try{
                                                                AssetCategory category = AssetCategoryLocalServiceUtil.getCategory(categoryIds[i]);
                                                               Role category_role = RoleLocalServiceUtil.getRole(companyId,category.getName()+" "+"Approver");
                                                                         if(category_role != null){
                                                                                roles.add(category_role);
                                                                        }
                                                                }catch(Exception e){
                                                                }
                                                }
                                     }
                                     if(roles.isEmpty()){
                                            try{
                                                    Role defaultRole = RoleLocalServiceUtil.getRole(companyId, "HR Home Page Reviewer");
                                                    if(defaultRole != null){
                                                            roles.add(defaultRole);
                                                    }
                                             }catch(Exception e){
                                            }
                                     }
                                   user = null;      
                            ]]>
                </script>
                <script-language>groovy</script-language>
    </scripted-assignment>
</assignments>  

Here our use case is to get Role name from web content category name but here in this Groovy script we can write any dynamic code to get Roles and Users.
Please let me know if  you need any more information on this.

No comments:

Post a Comment