how can i get the full user list of an actor in groovy script ?

I want to send email to a group users which all defined in an actor, how can i get the full user list of an actor in groovy script?

so that get the email address of all the users.

Hi,

Users can be mapped to an actor different ways:

  1. directly
  2. through a role that the user belongs to
  3. through a group that the user belongs to
  4. through a membership that the user belongs to (= group + role). For instance, let's say: will form part of an actor of a task all users that are testers in R&D depatement. That is, all users that have the role tester AND the group R&D

​There is not one direct method for that, as it has not been identified as a need.

Your script would look like:

        IdentityAPI identityAPI = apiAccessor.getIdentityAPI();
        ProcessAPI processAPI = apiAccessor.getProcessAPI();
        long actorId = 1L;
        List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);
        boolean hasMore = true;
        int shift = 0;
        while (hasMore) {
            println("hasMore, continuing...")
            List<ActorMember> page = processAPI.getActorMembers(actorId, 0+shift, 100)
            hasMore = actorMembers.addAll();
            shift += 100;
        }
        List<User> users = new ArrayList<User>();
        for (ActorMember actorMember : actorMembers) {
            long userId = actorMember.getUserId();
            long roleId = actorMember.getRoleId();
            long groupId = actorMember.getGroupId();
            if (userId > 0L && roleId == 0L && groupId == 0L) {
                // user is directly associated to the actor:
                users.add(identityAPI.getUser(userId));
            } else if (userId == 0L && roleId > 0L && groupId == 0L) {
                // should loop here...
                users.addAll(identityAPI.getUsersInRole(roleId, 0, 100, UserCriterion.LAST_NAME_ASC));
            } else if (userId == 0L && roleId == 0L && groupId > 0L) {
                // should loop here...
                users.addAll(identityAPI.getUsersInGroup(groupId, 0, 100, UserCriterion.LAST_NAME_ASC));
            }
        }
        return users;

 

Below is a better, more complete, tested answer:
Hope this helps.

import org.bonitasoft.engine.api.IdentityAPI;
import org.bonitasoft.engine.bpm.actor.ActorCriterion;
import org.bonitasoft.engine.bpm.actor.ActorMember;
import org.bonitasoft.engine.identity.User;
import org.bonitasoft.engine.identity.UserCriterion;
import org.bonitasoft.engine.identity.UserSearchDescriptor;
import org.bonitasoft.engine.search.SearchOptionsBuilder;
import com.bonitasoft.engine.api.ProcessAPI; IdentityAPI identityAPI = apiAccessor.getIdentityAPI();
ProcessAPI processAPI = apiAccessor.getProcessAPI();
long actorId = processAPI.getActors(processDefinitionId, 0, 1, ActorCriterion.NAME_ASC).get(0).getId();
List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);
boolean hasMore = true;
int pageSize = 2;
int shift = 0;
while (hasMore) {
    List<ActorMember> page = processAPI.getActorMembers(actorId, shift, pageSize);
    hasMore = actorMembers.addAll(page);
    shift += pageSize;
}
List<User> users = new ArrayList<User>();
for (ActorMember actorMember : actorMembers) {
    long userId = actorMember.getUserId();
    long roleId = actorMember.getRoleId();
    long groupId = actorMember.getGroupId();
    if (userId > 0 && roleId < 0 && groupId < 0) {
        // user is directly associated to the actor:
        users.add(identityAPI.getUser(userId));
    } else if (userId < 0 && roleId > 0 && groupId < 0) {
        // should loop here...
        users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).done()).getResult());
    } else if (userId < 0 && roleId < 0 && groupId > 0) {
        // should loop here...
        users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.GROUP_ID, groupId).done()).getResult());
    } else if (userId < 0 && roleId > 0 && groupId > 0) {
        // should loop here...
        users.addAll(identityAPI.searchUsers(
                new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).filter(UserSearchDescriptor.GROUP_ID, groupId).done())
                .getResult());
    }
}
return users;

Trying this in a email connector in the "to" field using Groovy I get the following error:

unable to resolve class com.bonitasoft.engine.api.ProcessAPI

on line:

import com.bonitasoft.engine.api.ProcessAPI;

My code *should* be what is posted above:

import org.bonitasoft.engine.api.IdentityAPI;
import org.bonitasoft.engine.bpm.actor.ActorCriterion;
 import org.bonitasoft.engine.bpm.actor.ActorMember;
 import org.bonitasoft.engine.identity.User;
 import org.bonitasoft.engine.identity.UserCriterion;
 import org.bonitasoft.engine.identity.UserSearchDescriptor;
 import org.bonitasoft.engine.search.SearchOptionsBuilder;
 import org.bonitasoft.engine.api.ProcessAPI;
 
 IdentityAPI identityAPI = apiAccessor.getIdentityAPI();
 ProcessAPI processAPI = apiAccessor.getProcessAPI();
 long actorId = processAPI.getActors(processDefinitionId, 0, 1, ActorCriterion.NAME_ASC).get(0).getId();
 List<ActorMember> actorMembers = new ArrayList<ActorMember>(10);
 boolean hasMore = true;
 int pageSize = 2;
 int shift = 0;
 while (hasMore) { List<ActorMember> page = processAPI.getActorMembers(actorId, shift, pageSize);
 hasMore = actorMembers.addAll(page);
 shift += pageSize;
 }
 List<User> users = new ArrayList<User>();
 for (ActorMember actorMember : actorMembers) { long userId = actorMember.getUserId();
 long roleId = actorMember.getRoleId();
 long groupId = actorMember.getGroupId();
 if (userId > 0 && roleId < 0 && groupId < 0) { // user is directly associated to the actor: users.add(identityAPI.getUser(userId));
 } else if (userId < 0 && roleId > 0 && groupId < 0) {
     // should loop here...
     users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).done()).getResult());
 } else if (userId < 0 && roleId < 0 && groupId > 0) {
     // should loop here...
     users.addAll(identityAPI.searchUsers(new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.GROUP_ID, groupId).done()).getResult());
 } else if (userId < 0 && roleId > 0 && groupId > 0) {
     // should loop here...
     users.addAll(identityAPI.searchUsers( new SearchOptionsBuilder(0, 100).filter(UserSearchDescriptor.ROLE_ID, roleId).filter(UserSearchDescriptor.GROUP_ID, groupId).done()) .getResult());
 } }
return users;

 

I don't know much about groovy. I am guessing that the script is trying to return an arrayList called users when the "to" field is expecting string? The error in my studio execution engine is:

Feb 15, 2014 10:05:09 PM org.bonitasoft.engine.log.technical.TechnicalLoggerSLF4JImpl log
WARNING: Exception was:Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors
org.bonitasoft.engine.expression.exception.SInvalidExpressionException: Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors
    at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.checkReturnType(ExpressionServiceImpl.java:157)
    at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.evaluate(ExpressionServiceImpl.java:99)
    at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionWithResolvedDependencies(ExpressionResolverServiceImpl.java:150)
    at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionsFlatten(ExpressionResolverServiceImpl.java:109)
    at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluate(ExpressionResolverServiceImpl.java:72)
    at org.bonitasoft.engine.core.connector.impl.ConnectorServiceImpl.evaluateInputParameters(ConnectorServiceImpl.java:326)
    at org.bonitasoft.engine.connector.ConnectorServiceDecorator.evaluateInputParameters(ConnectorServiceDecorator.java:105)
    at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:183)
    at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:147)
    at org.bonitasoft.engine.transaction.JTATransactionServiceImpl.executeInTransaction(JTATransactionServiceImpl.java:207)
    at org.bonitasoft.engine.execution.work.ExecuteConnectorWork.work(ExecuteConnectorWork.java:119)
    at org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork.work(FailureHandlingBonitaWork.java:72)
    at org.bonitasoft.engine.work.BonitaWork.run(BonitaWork.java:56)
    at org.bonitasoft.engine.work.SequenceRunnableExecutor.innerRun(SequenceRunnableExecutor.java:45)
    at org.bonitasoft.engine.work.BonitaRunnable.run(BonitaRunnable.java:35)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

<p>
	Feb 15, 2014 10:05:09 PM org.bonitasoft.engine.log.technical.TechnicalLoggerSLF4JImpl log<br />
	WARNING: Error while executing connector with id 6<br />
	org.bonitasoft.engine.expression.exception.SInvalidExpressionException: Declared return type class java.lang.String is not compatible with evaluated type class java.util.ArrayList for expression retrieveEmailsOfActors<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.checkReturnType(ExpressionServiceImpl.java:157)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.evaluate(ExpressionServiceImpl.java:99)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionWithResolvedDependencies(ExpressionResolverServiceImpl.java:150)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionsFlatten(ExpressionResolverServiceImpl.java:109)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluate(ExpressionResolverServiceImpl.java:72)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.core.connector.impl.ConnectorServiceImpl.evaluateInputParameters(ConnectorServiceImpl.java:326)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.connector.ConnectorServiceDecorator.evaluateInputParameters(ConnectorServiceDecorator.java:105)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:183)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:147)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.transaction.JTATransactionServiceImpl.executeInTransaction(JTATransactionServiceImpl.java:207)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.execution.work.ExecuteConnectorWork.work(ExecuteConnectorWork.java:119)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork.work(FailureHandlingBonitaWork.java:72)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.work.BonitaWork.run(BonitaWork.java:56)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.work.SequenceRunnableExecutor.innerRun(SequenceRunnableExecutor.java:45)<br />
	&nbsp;&nbsp; &nbsp;at org.bonitasoft.engine.work.BonitaRunnable.run(BonitaRunnable.java:35)<br />
	&nbsp;&nbsp; &nbsp;at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)<br />
	&nbsp;&nbsp; &nbsp;at java.util.concurrent.FutureTask.run(Unknown Source)<br />
	&nbsp;&nbsp; &nbsp;at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)<br />
	&nbsp;&nbsp; &nbsp;at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)<br />
	&nbsp;&nbsp; &nbsp;at java.lang.Thread.run(Unknown Source)</p>

OOOps. Please see my "Answer" I just posted. I guess I should have posted it as a connent instead.