Tuesday, August 12, 2014

Using a bean instanciated TaskListener in an Activiti Workflow

In Alfresco (ONE ~ ECM) Activiti you can use a Java TaskListener, which has the following advantages:
 - Is Java, preference for some, is more powerful in Alfresco
 - Compared to inline Activiti JS script, it is easier to reuse
 - Can be changed on running workflows (bug fixes etc.)
 - Can be reloaded dynamically using spring-loaded or JRebel

First you must create your TaskListener (different types exist):

public class StartTaskCreate extends TaskCreateListener {
  public void notify(DelegateTask task) {
     // ... I can walk!

     // you stuff goes here ...

Then yoiu must create a bean definition (using bean parent to init super class):

 <bean id="my.StartTaskCreate"

 Then you must let Activiti know about it (put into activitiBeanRegistry map):

<bean id="my.activitiBeanRegistry"  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="activitiBeanRegistry">
    <property name="targetObject">
      <ref bean="activitiBeanRegistry" />
    <property name="targetMethod" value="put" />
    <property name="arguments">

        <ref bean="my.StartTaskCreate" />

I use method invoking via Spring to add to existing bean-map, this makes the solution deployable as AMP (not tomcat/shared/..) and in a solution with many extensions more robust. Also Alfresco can change the orginal definition somewhat without this breaking, robust across Alfresco versions!

Then use it!
<process ...
<startEvent id="alfrescoStartevent1" name="Start" activiti:formKey="...">
    <activiti:taskListener event="create" delegateExpression="${StartTaskCreate}"/>


Observe the key in activitiBeanRegistry is the word to use in the workflow delegate expression ~ delegateExpression="${StartTaskCreate}"