The workflow support has been substantially improved and simplified in Ametys 3.0.
SVN Location | |
Ivy organisation | org.ametys.plugins |
Ivy module | workflow |
Latest nightly build | http://releases.ametys.org/nightly/org.ametys.plugins/workflow/latest/ |
Issue tracker |
This plugins provides workflow feature using OpenSymphony OSWorkflow.
Workflow instances can be created and used for anything (task, bug, ...) but the main use case is content management.
Because of this, default implementation stores workflow instances inside a JCR (JSR 170) content repository and especially using Jackrabbit.
This plugin also provides JDBC workflow storage (MySQL, PostgreSQL, Oracle).
TODO insert here changelog from JIRA.
Workflow plugin comes with two Avalon components.
Workflow component is responsible for creating workflow instances, executing actions on them, fetching current steps, etc, ...
Workflow definitions are declared into WEB-INF/param/workflows.xml with the following syntax:
<workflows> <workflow name="myworkflow" type="file" location="myworkflow.xml"/> ... </workflows>
location attribute value is relative to WEB-INF/param directory, for more information on XML syntax see OSWorkflow documentation .
Avalon component can be used as OSWorkflow FunctionProvider, Condition, Register, Validator inside workflow definition and must be declared like this:
... <pre-functions> <function type="avalon"> <arg name="role">org.ametys.example.MyFunction</arg> </function> </pre-functions> ... <condition> <function type="avalon"> <arg name="role">org.ametys.example.MyCondition</arg> </function> </condition> ...
As any Avalon component you need to declare them inside a plugin.xml file and all Ametys Avalon features are supported (Serviceable, Contextualizable, Configurable, ...).
Just do not forget that this component will be instantiated only once by the plugin manager (instead of each time when you used class type).
In order to attach an user for each action (caller property), CurrentUserProvider component is used.
Storage is delegated to the WorkflowStore component (see below).
WorkflowStore component is responsible for storing workflow instances.
Default implementation uses a JCR repository provided by Repository plugin in order to store workflow instances information.
Other implementation can be used by deactivating this component (in runtime.xml) and by declaring another:
For creating a workflow instance and performing an action:
Workflow workflow = (Workflow) manager.lookup(Workflow.ROLE); long workflowId = workflow.initialize("myworkflow", 1, null); workflow.doAction(workflowid, 2, null);
As this kind of code is typically found inside a Cocoon Action, standard actions are provided:
... <map:action name="initialize" src="org.ametys.plugins.workflow.cocoon.InitializeWorkflowAction"/> <map:action name="do-action" src="org.ametys.plugins.workflow.cocoon.WorkflowAction"/> ... <map:match pattern="create-workflow/*"> <map:act type="do-action"> <map:parameter name="workflowName" value="myworkflow"/> <map:parameter name="actionId" value="{1}"/> <map:generate type="action-result"> <map:parameter name="workflowId" value="{workflowId}"/> </map:generate> <map:serialize type="xml"/> </map:act> </map:match> ... <map:match pattern="do-action/*/for/*"> <map:act type="do-action"> <map:parameter name="workflowId" value="{2}"/> <map:parameter name="actionId" value="{1}"/> <map:generate type="action-result"/> <map:serialize type="xml"/> </map:act> </map:match>
A higher layer is used in CMS for Ametys content to simplify even more actions performed against a workflow.
For ease development of FunctionProvider or Condition, you can use AbstractWorkflowComponent which provides:
For checking rights, the org.ametys.plugins.workflow.component.CheckRightsCondition condition can be used:
... <condition> <function type="avalon"> <arg name="role">org.ametys.plugins.workflow.component.CheckRightsCondition</arg> <arg name="right">Right_Edition</arg> <arg name="context">/contributor</arg> </function> </condition> ...
right argument is mandatory and choose the right to check.
context argument is optional (default to /contributor) and choose the context to use.