Warning: Can't synchronize with the repository (GIT backend not available). Look in the Trac log for more information.

Workflow Documentation

Introduction

This wiki page contains the documentation about the Talia Workflow-Engine and shows how it is organised, the steps necessary to implement new actions and the syntax of the configuration file.

Classes description

Workflow-Engine is composed by the following classes:

  • WorkflowBuilder: build workflow from DSL code or load it from the configuration file.
  • Workflow: main workflow class. It defines the following methods:
    • source: get or set source id
    • state: get the current workflow state
    • action: execute a workflow action. This method receives the event symbol, the User instance and some optional parameters.
            # execute an action
            my_workflow.action(:event, user)
      
            # execute an action with argument
            my_workflow.action(:publish, user, {:vote => 10})
      
  • WorkflowContext: class used by the StateMachine? gem which call method when current state is changed.
  • WorkflowAction: workflow action base class. Each action can be defined as a child of WorkflowAction?. In this class it is also present the 'authorized?' method which can be used to check user's authorization.
  • WorkflowRecord: record class used to save data into the workflow_records table.

Creating a new action

Each action are defined as child class of WorkflowAction and it will be stored in workflow/action directory. This class will be called when current state will change.

Example about how to create a new action for reviewed state:

  1. Define the name of the class. The state is called reviewed, so the new class will be ReviewedAction.
  1. Store the new class into the workflow/action directory.
  1. Set this class as a child of WorkflowAction base class.
          class ReviewedAction < WorkflowAction
    

  1. Define execute method for executing some action when workflow enter in this new state.
          # execute action.
          # * user: user.
          # * options: arguments. Default value is nil
          def execute(user, options = nil)
            # check user authorization
            raise "User is not authorized for execute this action" unless authorized?(user)
          end
    
    • user is an instance of User class stored in TALIA_ROOT/Models directory.
    • options contain parameter sended by user.
    • authorized?(user) is need for check user role authorization.

  1. Define the required user's roles.
          # role required
          require_role ["reviewers"]
    
    These roles is used by authorized? method to verify user authorization.

Configuration

The following paragraphs describe the syntax of the workflow configuration file.

YAML syntax

Example:

default:
  - step:
    - "submitted"
    - "review"
    - "reviewed"
  - step:
    - "reviewed"
    - "vote"
    - "reviewed"
  - step:
    - "reviewed"
    - "publish"
    - "published"
  - step:
    - "published"
    - "auto"
    - "published"

default define new workflow statement.
- step define new workflow step. Each step is composed by three elements:

  • initial state for the current transition,
  • event which fire the transition,
  • destination state for the current transition.

Last transition (self-loop) is needed because StateMachine can't be initialized into deadlock state.

DSL syntax

Example:

WorkflowBuilder.workflow do
  WorkflowBuilder.step "submitted", "review",   "reviewed"
  WorkflowBuilder.step "reviewed",  "vote",     "reviewed"
  WorkflowBuilder.step "reviewed",  "publish",  "published"
  WorkflowBuilder.step "published", "auto",     "published"
end

WorkflowBuilder.workflow define new workflow statement.
WorkflowBuilder.step define new step for current workflow. Each step is composed by three elements:

  • initial state for the current transition,
  • event which fire the transition,
  • destination state for the current transition.

Last transition (self-loop) is needed because StateMachine can't be initialized into deadlock state.

XML syntax

Example:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <workflow name="my workflow">
        <step start="submitted" event="review"  end="reviewed"  />
        <step start="reviewed"  event="vote"    end="reviewed"  />
        <step start="reviewed"  event="publish" end="published" />
        <step start="published" event="auto"    end="published" />
    </workflow>
</root>

<workflow name=""> define new workflow. name parameter defines name of the workflow. More workflows can be defined in the same file and each workflow can be identified by its own name.
<step start="" event="" end="" /> define a step for the current workflow. Each step is composed by three elements:

  • initial state for the current transition,
  • event which fire transition,
  • destination state for the current transition.

Last transition (self-loop) is needed because StateMachine can't be initialized into deadlock state.

Example

Defining workflow by code.

# creating workflow
my_workflow = WorkflowBuilder.workflow do
  WorkflowBuilder.step "submitted", "review",   "reviewed"
  WorkflowBuilder.step "reviewed",  "vote",     "reviewed"
  WorkflowBuilder.step "reviewed",  "publish",  "published"
  WorkflowBuilder.step "published", "auto",     "published"
end

# set source id
# if a workflow is already used for this source, the workflow's state will be reload from database
my_workflow.source = 1

Load workflow from XML file.

# build workflow from XML
# first parameter is source id
# second parameter is file to load (without extension) stored in ''TALIA_ROOT/config/workflow'' directory
my_workflow = WorkflowBuilder.load_xml(1, {:filename => "file"})

# build workflow from default XML file
my_workflow = WorkflowBuilder.load_xml(1)

# build workflow from XML file containing more workflow statement
# third parameter is workflow's name
my_workflow = WorkflowBuilder.load_xml(1, {:filename => "file", :name => "name"})

Actions.

# execute an action without parameters
my_workflow.action(:event, user)

# execute an action with argument with vote parameter
my_workflow.action(:publish, user, {:vote => 10})