cancel
Showing results for 
Search instead for 
Did you mean: 

requirement for config assignee mode

woodfox
Champ in-the-making
Champ in-the-making
I am a new developer for Activiti, I have a requirement for some kind of assignee  configuration:

suppose customer has a group “GM" which has three user : gm0, gm1, gm2

when we design process, we have a user task for the GM Audit node, our customer want to control a flag so that they can control the audit behaviors :

if flag is true :

the audit task can be completed by all users in GM group that completed their task instances,

in this case, we create a multi instance use task and it create the task instances according to the assigneeList


if flag is false :

the audit task can be completed by one of the users in GM group that completed his task instance,

in this case, we can set candidate groups value to "GM".


they all work fine, however the problem is : we can't use a process define for both of them !

I have try the following way :

set a collection of User bean for the multi instance :



public class User {
   
    private String assignee;
    private String groups;

   ….
}



then set value ${user.assignee} for "assignee" property and value ${assignee.groups} for "candidate groups" property

and


   if(flag){
      assigneeList.add(new User("gm0"));
      assigneeList.add(new User("gm1"));
      assigneeList.add(new User("gm2"));
   }else{
      User u = new User();
      u.setGroups("GM");
      assigneeList.add(u);
   }



well… this code does't work because I found the code in handleAssignments() method at org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior


   if (!taskDefinition.getCandidateGroupIdExpressions().isEmpty()) {
      for (Expression groupIdExpr : taskDefinition.getCandidateGroupIdExpressions()) {
        Object value = groupIdExpr.getValue(execution);
        if (value instanceof String) {
          List<String> candiates = extractCandidates((String) value);
          task.addCandidateGroups(candiates);
        } else if (value instanceof Collection) {
          task.addCandidateGroups((Collection) value);
        } else {
          throw new ActivitiIllegalArgumentException("Expression did not resolve to a string or collection of strings");
        }
      }
    }

    if (!taskDefinition.getCandidateUserIdExpressions().isEmpty()) {
      for (Expression userIdExpr : taskDefinition.getCandidateUserIdExpressions()) {
        Object value = userIdExpr.getValue(execution);
        if (value instanceof String) {
          List<String> candiates = extractCandidates((String) value);
          task.addCandidateUsers(candiates);
        } else if (value instanceof Collection) {
          task.addCandidateUsers((Collection) value);
        } else {
          throw new ActivitiException("Expression did not resolve to a string or collection of strings");
        }
      }
    }


if one of the expressions return null, it will throw an Exception,


and the following code is my hoped logic :



     if (!taskDefinition.getCandidateGroupIdExpressions().isEmpty()) {
      for (Expression groupIdExpr : taskDefinition.getCandidateGroupIdExpressions()) {
        Object value = groupIdExpr.getValue(execution);
         if(value == null){
            //do nothing, just ignore
         }else if (value instanceof String) {
      …..


     if (!taskDefinition.getCandidateUserIdExpressions().isEmpty()) {
      for (Expression userIdExpr : taskDefinition.getCandidateUserIdExpressions()) {
        Object value = userIdExpr.getValue(execution);
       if(value == null){
            //do nothing, just ignore
         }else if (value instanceof String) {




I hope the code can just ignore the null value returned by expression.


any help is appreciated !
4 REPLIES 4

woodfox
Champ in-the-making
Champ in-the-making
PS : is there any way to set an execution Listener globally ? currently, I have to config it in every sequenceFlow

<code>
   <sequenceFlow id="flow6" sourceRef="exclusivegateway1" targetRef="PMAudit">
      <documentation>PM</documentation>
      <extensionElements>
        <activiti:executionListener event="take" class="UserExecutionListener"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>
</code>

woodfox
Champ in-the-making
Champ in-the-making
I expect some kind of assignee listener to handle the assignee behavior before into the user task

woodfox
Champ in-the-making
Champ in-the-making
I found a solution for this according to ACT-1782

create a subclass of DefaultActivityBehaviorFactory, then override createUserTaskActivityBehavior() method to create a custom UserTaskActivityBehavior class ,in this class, override handleAssignments method so that we can use a custom assignee behaviors instead. 

jbarrez
Star Contributor
Star Contributor
That is indeed a way to solve your use case.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.