From df0bf5900bcc0881eb9120abe2ba14626f4692d6 Mon Sep 17 00:00:00 2001 From: jbarrez Date: Sun, 14 Nov 2010 15:58:40 +0000 Subject: [PATCH] ACT-221: docced task listeners --- .../engine/delegate/DelegateTask.java | 10 +- .../impl/bpmn/ExpressionTaskListener.java | 2 +- .../engine/impl/bpmn/UserTaskActivity.java | 24 +++- .../engine/impl/bpmn/parser/BpmnParse.java | 4 +- .../history/handler/HistoryParseListener.java | 2 +- .../handler/UserTaskAssignmentHandler.java | 2 +- .../{task => pvm/delegate}/TaskListener.java | 2 +- .../engine/impl/task/TaskDefinition.java | 1 + .../activiti/engine/impl/task/TaskEntity.java | 14 ++ .../bpmn/tasklistener/AssigneeAssignment.java | 2 +- .../CandidateGroupAssignment.java | 2 +- .../tasklistener/CandidateUserAssignment.java | 2 +- .../tasklistener/TaskCompleteListener.java | 2 +- .../bpmn/tasklistener/TaskCreateListener.java | 2 +- .../CustomTaskAssignmentTest.java | 19 ++- .../test/taskassignment/FakeLdapService.java | 7 + ...didateUsersThroughSpringService.bpmn20.xml | 20 +++ .../taskassignment/taskassignment-context.xml | 2 +- userguide/src/en/chapters/ch07-BPMN.xml | 127 +++++++++++++++++- userguide/src/en/chapters/ch10-History.xml | 2 +- 20 files changed, 223 insertions(+), 25 deletions(-) rename modules/activiti-engine/src/main/java/org/activiti/engine/impl/{task => pvm/delegate}/TaskListener.java (94%) create mode 100644 modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/SetCandidateUsersThroughSpringService.bpmn20.xml diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/delegate/DelegateTask.java b/modules/activiti-engine/src/main/java/org/activiti/engine/delegate/DelegateTask.java index 9685c3d6dd..258c15ce38 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/delegate/DelegateTask.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/delegate/DelegateTask.java @@ -12,10 +12,8 @@ */ package org.activiti.engine.delegate; +import java.util.Collection; import java.util.Date; -import java.util.Set; - -import org.activiti.engine.impl.task.IdentityLinkEntity; /** * @author Joram Barrez @@ -73,8 +71,14 @@ public interface DelegateTask { /** Adds the given user as a candidate user to this task. */ void addCandidateUser(String userId); + /** Adds multiple users as candidate user to this task. */ + void addCandidateUsers(Collection candidateUsers); + /** Adds the given group as candidate group to this task */ void addCandidateGroup(String groupId); + + /** Adds multiple groups as candidate group to this task. + void addCandidateGroups(Collection candidateGroups); /** Sets the current assignee of this task to the given user */ void setAssignee(String assignee); diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ExpressionTaskListener.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ExpressionTaskListener.java index f56fe20e75..da563e1fb0 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ExpressionTaskListener.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/ExpressionTaskListener.java @@ -16,9 +16,9 @@ package org.activiti.engine.impl.bpmn; import org.activiti.engine.ActivitiException; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.impl.el.Expression; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.runtime.ExecutionEntity; import org.activiti.engine.impl.task.TaskEntity; -import org.activiti.engine.impl.task.TaskListener; /** diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/UserTaskActivity.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/UserTaskActivity.java index 977aa51cb7..dc3ddf96ff 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/UserTaskActivity.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/UserTaskActivity.java @@ -12,12 +12,15 @@ */ package org.activiti.engine.impl.bpmn; +import java.util.Collection; + +import org.activiti.engine.ActivitiException; import org.activiti.engine.impl.el.Expression; import org.activiti.engine.impl.el.ExpressionManager; import org.activiti.engine.impl.pvm.delegate.ActivityExecution; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.task.TaskDefinition; import org.activiti.engine.impl.task.TaskEntity; -import org.activiti.engine.impl.task.TaskListener; /** * activity implementation for the user task. @@ -59,6 +62,7 @@ public class UserTaskActivity extends TaskActivity { leave(execution); } + @SuppressWarnings({ "unchecked", "rawtypes" }) protected void handleAssignments(TaskEntity task, ActivityExecution execution) { if (taskDefinition.getAssigneeExpression() != null) { task.setAssignee((String) taskDefinition.getAssigneeExpression().getValue(execution)); @@ -66,13 +70,27 @@ public class UserTaskActivity extends TaskActivity { if (!taskDefinition.getCandidateGroupIdExpressions().isEmpty()) { for (Expression groupIdExpr : taskDefinition.getCandidateGroupIdExpressions()) { - task.addCandidateGroup((String) groupIdExpr.getValue(execution)); + Object value = groupIdExpr.getValue(execution); + if (value instanceof String) { + task.addCandidateGroup((String) value); + } else if (value instanceof Collection) { + task.addCandidateGroups((Collection) value); + } else { + throw new ActivitiException("Expression did not resolve to a string or collection of strings"); + } } } if (!taskDefinition.getCandidateUserIdExpressions().isEmpty()) { for (Expression userIdExpr : taskDefinition.getCandidateUserIdExpressions()) { - task.addCandidateUser((String) userIdExpr.getValue(execution)); + Object value = userIdExpr.getValue(execution); + if (value instanceof String) { + task.addCandidateUser((String) value); + } else if (value instanceof Collection) { + task.addCandidateUsers((Collection) value); + } else { + throw new ActivitiException("Expression did not resolve to a string or collection of strings"); + } } } } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java index 70b0302908..7da7d6561e 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java @@ -65,6 +65,7 @@ import org.activiti.engine.impl.jobexecutor.TimerDeclarationImpl; import org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler; import org.activiti.engine.impl.pvm.delegate.ActivityBehavior; import org.activiti.engine.impl.pvm.delegate.ExecutionListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl; import org.activiti.engine.impl.pvm.process.ScopeImpl; @@ -73,7 +74,6 @@ import org.activiti.engine.impl.repository.DeploymentEntity; import org.activiti.engine.impl.repository.ProcessDefinitionEntity; import org.activiti.engine.impl.scripting.ScriptingEngines; import org.activiti.engine.impl.task.TaskDefinition; -import org.activiti.engine.impl.task.TaskListener; import org.activiti.engine.impl.util.ReflectUtil; import org.activiti.engine.impl.util.xml.Element; import org.activiti.engine.impl.util.xml.Parse; @@ -1050,7 +1050,7 @@ public class BpmnParse extends Parse { addError("Invalid eventName for taskListener: choose 'create' |'assignment'", userTaskElement); } } else { - addError("EventName is mandatory on taskListener", userTaskElement); + addError("Event is mandatory on taskListener", userTaskElement); } } } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/HistoryParseListener.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/HistoryParseListener.java index 0ab517c663..b1a2406ffe 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/HistoryParseListener.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/HistoryParseListener.java @@ -17,12 +17,12 @@ import org.activiti.engine.impl.bpmn.UserTaskActivity; import org.activiti.engine.impl.bpmn.parser.BpmnParseListener; import org.activiti.engine.impl.cfg.ProcessEngineConfiguration; import org.activiti.engine.impl.pvm.delegate.ExecutionListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.impl.pvm.process.ScopeImpl; import org.activiti.engine.impl.pvm.process.TransitionImpl; import org.activiti.engine.impl.repository.ProcessDefinitionEntity; import org.activiti.engine.impl.task.TaskDefinition; -import org.activiti.engine.impl.task.TaskListener; import org.activiti.engine.impl.util.xml.Element; import org.activiti.engine.impl.variable.VariableDeclaration; diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/UserTaskAssignmentHandler.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/UserTaskAssignmentHandler.java index 7a0d179649..a89ddcdc87 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/UserTaskAssignmentHandler.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/history/handler/UserTaskAssignmentHandler.java @@ -15,9 +15,9 @@ package org.activiti.engine.impl.history.handler; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.impl.history.HistoricActivityInstanceEntity; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.runtime.ExecutionEntity; import org.activiti.engine.impl.task.TaskEntity; -import org.activiti.engine.impl.task.TaskListener; /** diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskListener.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/delegate/TaskListener.java similarity index 94% rename from modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskListener.java rename to modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/delegate/TaskListener.java index 75ce32711b..986af88879 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskListener.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/delegate/TaskListener.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package org.activiti.engine.impl.task; +package org.activiti.engine.impl.pvm.delegate; import org.activiti.engine.delegate.DelegateTask; diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskDefinition.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskDefinition.java index e18092235c..5931b63ee6 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskDefinition.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskDefinition.java @@ -21,6 +21,7 @@ import java.util.Set; import org.activiti.engine.impl.el.Expression; import org.activiti.engine.impl.form.TaskFormHandler; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** * Container for task definition information gathered at parsing time. diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskEntity.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskEntity.java index e9acad6ff2..10400870cf 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskEntity.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/task/TaskEntity.java @@ -14,6 +14,7 @@ package org.activiti.engine.impl.task; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -27,6 +28,7 @@ import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.impl.cfg.RepositorySession; import org.activiti.engine.impl.db.PersistentObject; import org.activiti.engine.impl.interceptor.CommandContext; +import org.activiti.engine.impl.pvm.delegate.TaskListener; import org.activiti.engine.impl.repository.ProcessDefinitionEntity; import org.activiti.engine.impl.runtime.ExecutionEntity; import org.activiti.engine.impl.util.ClockUtil; @@ -197,10 +199,22 @@ public class TaskEntity implements Task, DelegateTask, Serializable, PersistentO createIdentityLink(userId, null, IdentityLinkType.CANDIDATE); } + public void addCandidateUsers(Collection candidateUsers) { + for (String candidateUser : candidateUsers) { + addCandidateUser(candidateUser); + } + } + public void addCandidateGroup(String groupId) { createIdentityLink(null, groupId, IdentityLinkType.CANDIDATE); } + public void addCandidateGroups(Collection candidateGroups) { + for (String candidateGroup : candidateGroups) { + addCandidateGroup(candidateGroup); + } + } + public List getIdentityLinks() { if (!isIdentityLinksInitialized) { taskIdentityLinkEntities = CommandContext diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/AssigneeAssignment.java b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/AssigneeAssignment.java index 62af34e7c0..c962b78dde 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/AssigneeAssignment.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/AssigneeAssignment.java @@ -13,7 +13,7 @@ package org.activiti.examples.bpmn.tasklistener; import org.activiti.engine.delegate.DelegateTask; -import org.activiti.engine.impl.task.TaskListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateGroupAssignment.java b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateGroupAssignment.java index e8a8edd8a2..95d9e768dc 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateGroupAssignment.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateGroupAssignment.java @@ -13,7 +13,7 @@ package org.activiti.examples.bpmn.tasklistener; import org.activiti.engine.delegate.DelegateTask; -import org.activiti.engine.impl.task.TaskListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateUserAssignment.java b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateUserAssignment.java index 0c88301400..c2fb126d6f 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateUserAssignment.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/CandidateUserAssignment.java @@ -13,7 +13,7 @@ package org.activiti.examples.bpmn.tasklistener; import org.activiti.engine.delegate.DelegateTask; -import org.activiti.engine.impl.task.TaskListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCompleteListener.java b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCompleteListener.java index db087822d8..95d23d32ab 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCompleteListener.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCompleteListener.java @@ -14,7 +14,7 @@ package org.activiti.examples.bpmn.tasklistener; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.impl.el.Expression; -import org.activiti.engine.impl.task.TaskListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** diff --git a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCreateListener.java b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCreateListener.java index 8fa72b0a2c..de10048b77 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCreateListener.java +++ b/modules/activiti-engine/src/test/java/org/activiti/examples/bpmn/tasklistener/TaskCreateListener.java @@ -13,7 +13,7 @@ package org.activiti.examples.bpmn.tasklistener; import org.activiti.engine.delegate.DelegateTask; -import org.activiti.engine.impl.task.TaskListener; +import org.activiti.engine.impl.pvm.delegate.TaskListener; /** diff --git a/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/CustomTaskAssignmentTest.java b/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/CustomTaskAssignmentTest.java index 5128793b68..aac982ff21 100644 --- a/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/CustomTaskAssignmentTest.java +++ b/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/CustomTaskAssignmentTest.java @@ -34,7 +34,24 @@ public class CustomTaskAssignmentTest extends PvmTestCase { runtimeService.startProcessInstanceByKey("assigneeThroughSpringService", CollectionUtil.singletonMap("emp", "fozzie")); assertEquals(1, taskService.createTaskQuery().taskAssignee("Kermit The Frog").count()); - // Remove deployments + cleanup(applicationContext); + } + + public void testSetCandidateUsersThroughSpringService() { + ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("org/activiti/spring/test/taskassignment/taskassignment-context.xml"); + RuntimeService runtimeService = applicationContext.getBean(RuntimeService.class); + TaskService taskService = applicationContext.getBean(TaskService.class); + + runtimeService.startProcessInstanceByKey("candidateUsersThroughSpringService", CollectionUtil.singletonMap("emp", "fozzie")); + assertEquals(1, taskService.createTaskQuery().taskCandidateUser("kermit").count()); + assertEquals(1, taskService.createTaskQuery().taskCandidateUser("fozzie").count()); + assertEquals(1, taskService.createTaskQuery().taskCandidateUser("gonzo").count()); + assertEquals(0, taskService.createTaskQuery().taskCandidateUser("mispiggy").count()); + + cleanup(applicationContext); + } + + private void cleanup(ClassPathXmlApplicationContext applicationContext) { RepositoryService repositoryService = applicationContext.getBean(RepositoryService.class); for (Deployment deployment : repositoryService.createDeploymentQuery().list()) { repositoryService.deleteDeploymentCascade(deployment.getId()); diff --git a/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/FakeLdapService.java b/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/FakeLdapService.java index df72920840..a369b0f807 100644 --- a/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/FakeLdapService.java +++ b/modules/activiti-spring/src/test/java/org/activiti/spring/test/taskassignment/FakeLdapService.java @@ -12,6 +12,9 @@ */ package org.activiti.spring.test.taskassignment; +import java.util.Arrays; +import java.util.List; + /** * @author Joram Barrez @@ -22,5 +25,9 @@ public class FakeLdapService { // Pretty useless LDAP service ... return "Kermit The Frog"; } + + public List findAllSales() { + return Arrays.asList("kermit", "gonzo", "fozzie"); + } } diff --git a/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/SetCandidateUsersThroughSpringService.bpmn20.xml b/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/SetCandidateUsersThroughSpringService.bpmn20.xml new file mode 100644 index 0000000000..90a3700d50 --- /dev/null +++ b/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/SetCandidateUsersThroughSpringService.bpmn20.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/taskassignment-context.xml b/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/taskassignment-context.xml index 85e9234554..52787176cd 100644 --- a/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/taskassignment-context.xml +++ b/modules/activiti-spring/src/test/resources/org/activiti/spring/test/taskassignment/taskassignment-context.xml @@ -30,7 +30,7 @@ - + diff --git a/userguide/src/en/chapters/ch07-BPMN.xml b/userguide/src/en/chapters/ch07-BPMN.xml index 88980b4134..4c52e0d77a 100644 --- a/userguide/src/en/chapters/ch07-BPMN.xml +++ b/userguide/src/en/chapters/ch07-BPMN.xml @@ -1225,9 +1225,11 @@ List<Task> tasks = taskService.createTaskQuery().assignee("kermit&quo <formalExpression>accountancy</formalExpression> -
+
+ +
- Custom extension for simple task assignments + Activiti extensions for task assignment It is clear that user and group assignments are quite cumbersome @@ -1286,9 +1288,61 @@ List<Task> tasks = taskService.createTaskQuery().assignee("kermit&quo -
+ + In case the previous approaches are not sufficient, it is possible to delegate to + custom assignment logic using a task listener + on the create event: + +<userTask id="task1" name="My task" > + <extensionElements> + <activiti:taskListener event="create" class="org.activiti.MyAssignmentHandler" /> + </extensionElements> +</userTask> + The DelegateTask that is passed to the TaskListener + implementation, allows to set the assignee and candidate-users/groups: + +public class MyAssignmentHandler implements TaskListener { + + public void notify(DelegateTask delegateTask) { + // Execute custom identity lookups here + + // and then for example call following methods: + delegateTask.setAssignee("kermit"); + delegateTask.addCandidateUser("fozzie"); + delegateTask.addCandidateGroup("management"); + ... + } + +} + + + + When using Spring it is possible to use the custom assignment attirbutes as described in the section above, + and delegate to a Spring bean using a task listener + with an expression that listens to task create events. + In the following example, the assignee will be set by calling the findManagerOfEmployee + on the ldapService Spring bean. The emp parameter + that is passed, is a process variable>. + <userTask id="task" name="My Task" activiti:assignee="${ldapService.findManagerForEmployee(emp)}"/> + This also works similar for candidate users and groups: + <userTask id="task" name="My Task" activiti:candidateUsers="${ldapService.findAllSales()}"/> + Note that this will only work if the return type of the invoked methods is String + or Collection<String> (for candidate users and groups): + +public class FakeLdapService { + + public String findManagerForEmployee(String employee) { + return "Kermit The Frog"; + } + + public List<String> findAllSales() { + return Arrays.asList("kermit", "gonzo", "fozzie"); + } - +} + + + @@ -1687,7 +1741,7 @@ public class ReverseStringsFieldInjected implements JavaDelegation {
- Execution listeners + Execution listener Execution listeners allow you to execute external Java code or evaluate an expression when certain events occur during process exevcution. The events that can be captured are: @@ -1822,6 +1876,69 @@ public void testExecutionListenerFieldInjection() {
+ +
+ + Task listener + + + A task listener is used to execute custom Java logic or an expression + upon the occurrence of a certain task-related event. + + + + A task listener can only be added in the process definition as a child element of a user task. + Note that this also must happen as a child of the BPMN 2.0 extensionElements + and in the activiti namespace, since a task listener is an Activiti-specific construct. + +<userTask id="myTask" name="My Task" > + <extensionElements> + <activiti:taskListener event="create" class="org.activiti.MyTaskCreateListener" /> + </extensionElements> +</userTask> + A task listener supports following attributes: + + + + event (required): the type of task event on which the task listener will + be invoked. Possible values are 'create' (occurs when the task + has been created an all task properties are set), 'assignment' + (occurs when the task is assigned to somebody) or 'complete' + (occurs when the task is completed and just before the task is deleted from the runtime data). + + + + + class: the delegation class that must be called. + This class must implement the org.activiti.engine.impl.pvm.delegate.TaskListener + interface. + +public class MyTaskCreateListener implements TaskListener { + + public void notify(DelegateTask delegateTask) { + // Custom logic goes here + } + +} + + It is also possible to use field injection to pass + process variables or the execution to the delegation class. + Note that an instance of the delegation class is created upon process deployment + (as is the case with any class delegation in Activiti), which means that the + instance is shared between all process instance executions. + + + + + expression: (cannot be used together with the class attribute): + specifies an expression that will be executed when the event happens. + <activiti:taskListener event="create" expression="${execution.setVariable('myVar', 'Hello from the task listener!')}" /> + + + + + +
diff --git a/userguide/src/en/chapters/ch10-History.xml b/userguide/src/en/chapters/ch10-History.xml index 69236bbf0b..6c1341fa48 100644 --- a/userguide/src/en/chapters/ch10-History.xml +++ b/userguide/src/en/chapters/ch10-History.xml @@ -26,7 +26,7 @@ Also, it will be the information from which the reports will be generated. -
+
History configuration In the activiti.cfg.xml configuration file, you can configure the level of history archiving that needs to happen: -- GitLab