Dec 8, 2019 11:27:42 PM Thomas Dumont avatar

Code with workflows


Presentation

A workflow in a Lutece site is a set of processing carried out on a resource.

The workflow consists of a set of states of the resource. This one goes from a starting state to a state of arrival by a action. An action groups a list of tasks. Each task constitutes a processing performed on the resource (modification, deletion, notification...) in order to move it to the next state.

There are two types of actions:

  • Classic actions are triggered by an explicit call in Java code.
  • automatic actions are triggered automatically when the resource arrives in the start state if all prerequisites are set.

Workflow implementation architecture

Workflow operation involves the following components :

Name Function Source code
Lutece Core Defines an IWorkflowProvider interface and WorkflowService to manipulate workflows lutece-core/src/java/fr/paris/lutece/portal/service/workflow/
Library Workflow Core Defines the business objects of the workflow and the services to handle them lutece-wf-library-workflow-core
Plugin Workflow Implementing the Workflow Provider lutece-wf-plugin-workflow
Module Workflow Define task types of the workflow

Define a Workflow resource type

To define a new workflow resource type, the corresponding object must have an integer unique identifier.

Resource types are identified by a string of characters. For example, for the standard resources of a directory lutece, the string is :

public static final String WORKFLOW_RESOURCE_TYPE = "DIRECTORY_RECORD";

The unique identifier of a resource in the workflow is the couple (business_identifier, resource_type)

Description of the API

The API is lutece-core class fr.paris.lutece.portal.service.workflow.WorkflowService

Initialize/get the status of a resource

//Initialize the workflow, this creates the state for our resource
WorkflowService.getInstance(  ).getState( idResource, WORKFLOW_RESOURCE_TYPE, idWorkflow, -1 );
  • We get the id of the workflow for example by looking in the database. We can simplify define a property that can be changed if the plugin has to coexist with other plugins using different workflow in a file <plugin-trade> .properties:

pluginmetier.idWorkflow = 1

  • If the state of the resource does not exist, it is created and takes the initial value.

Get actions available for a resource

WorkflowService.getInstance(  ).getActions( idResource, RESOURCE_TYPE, idWorkflow, getUser(  ) );

Useful for displaying available actions for a list of resources.

Execute an action on a resource

WorkflowService.getInstance(  ).doProcessAction( idResource, WORKFLOW_RESOURCE_TYPE, idAction, -1, request, locale, isAutomatic );
  • To obtain the id of the action, we can simplify to use the same mechanism as for the id of the workflow in a file properties if the workflow does not change.
  • If isAutomatic is true, the user ID of the backoffice user is not verified.

Force the execution of automatic actions

WorkflowService.getInstance(  ).executeActionAutomatic( idResource, WORKFLOW_RESOURCE_TYPE, idWorkflow, -1 );

If the automatic action is not forced, a daemon looks for eligible resources and performs actions regularly.

View the history of a resource (HTML)

WorkflowService.getInstance(  ).getDisplayDocumentHistory( idResource, WORKFLOW_RESOURCE_TYPE, idWorkflow, request, getLocale(  ) );

Get the list of all resources with a given state

WorkflowService.getInstance(  ).getResourceIdListByIdState( idState, WORKFLOW_RESOURCE_TYPE );
  • To get the id of the state, we can simplify to use the same mechanism as for the id of the workflow in a file properties if the workflow does not change.

Other methods of WorkflowService

You can look at the other methods of the class fr.paris.lutece.portal.service.workflow.WorkflowService in lutece-core/src/java/fr/paris/lutece/portal/services/workflow/WorkflowService.java

Display resource's state and action in an HTML page with freemarker

To display the name of the status and the icons corresponding to the actions in html with freemarker, one can take inspiration from the following example:

<td><#if workflow_state??>${workflow_state.name}<#else>workflow desactive</#if></td>
<td>
<#if workflow_state??><#list workflow_action_list as action >
    <a href="METIER_JSP_URL?id_action=${action.id}&id_resource=${id}">
        <img src="image?resource_type=workflow_icon_img&id=${action.icon.id}"
                <#if action.icon.width!=-1> width="${action.icon.width}"</#if>
                <#if action.icon.height!=-1> height="${action.icon.height}"</#if>
                title="${action.name}"
                alt="${action.name}"/>
     </a>
</#list></#if>
</td>
  • for each element of the list, the java code generating the list adds the result of:
// Put these in the freemarker model with model.put(...)
WorkflowService.getInstance(  ).getActions( idResource, WORKFLOW_RESOURCE_TYPE, idWorkflow, getUser(  ) );
WorkflowService.getInstance(  ).getState( idResource, WORKFLOW_RESOURCE_TYPE, idWorkflow, -1 );
  • METIER_JSP_URL must parse the arguments and call doProcessAction

Create workflow tasks

The creation of workflow tasks is described in Create a workflow module

Create prerequisites for automatic actions

The creation of prerequisites for automatic actions is described in Create a prerequisite for automatic actions