Example Workflow
A simple example of the Cinnamon workflow API
Example Workflow: The Review Workflow
The review workflow has three tasks:
- start
- review
- edit
The start task
The start task's job is to gather the input required to start the whole process. It is created by during the execution of the createWorkflow API command on the server. Technicallly, a task is an OSD (ObjectSystemData) object. The metadata field of a task defines and stores the required input as well as the available transitions.
The start task's metadata looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<meta>
<metaset type="task_definition">
<name>cinnamon.test.StartTask</name>
<manual>true</manual>
<description>Configuration of the Review Workflow</description>
<input>
<required>
<param>
<type>user</type>
<!-- a Cinnamon user id -->
<label>reviewer</label>
<!-- screen label -->
<name>reviewer</name>
<!-- parameter name -->
<value></value>
<valueAssistance>set_to_owner</valueAssistance>
<!-- the content of valueAssistance should be something from
which the client can deduce the proper param value (or a select list) -->
</param>
<param>
<type>document</type>
<!-- id of a Cinnamon document -->
<label>document</label>
<name>document</name>
<value></value>
<valueAssistance>set_to_document</valueAssistance>
</param>
</required>
<optional></optional>
</input>
</metaset>
<metaset type="transition">
<manual>true</manual>
<default>start_task_to_review_task</default>
<deadline_transition>deadline_transition</deadline_transition>
<transition>
<show>true</show>
<confirm>false</confirm>
<name>start_task_to_review_task</name>
<label>transition.start.review</label>
<class>workflow.transition.test.StartToReview</class>
<tasks>
<task name="review_task">cinnamon.test.ReviewTask</task>
<!-- how does this transition find the new task to create?
the task@name is a constant, the content of the element ("ReviewTask") is
the configurable name of the task object.
This way, we can change the task object without compiling.
-->
</tasks>
</transition>
<transition>
<show>true</show>
<confirm>true</confirm>
<name>cancel.review</name>
<label>transition.cancel.review</label>
<class>workflow.transition.test.CancelReviewWorkflow</class>
</transition>
<transition>
<show>false</show>
<name>deadline_transition</name>
<label>transition.deadline</label>
<class>workflow.transition.test.DeadlineTransition</class>
</transition>
</metaset>
</meta>
A client which displays the start task to the user should query for the id of a reviewer and the id of a document to review. The information is to be stored in the respective <value> elements.
Before the user may select a transition, the required input has to be in place (and the updated metadata must be stored in the task object).
The start tasks's transitions are defined in the "transitions"-metaset. The transition is marked as manual - non-manual transitions would be done automatically on the server once a task is set to 'done'.
The client should present the available tranisitons (in this case: transition.start.review and transition.cancel.review) to the user. The default transition should be pre-selected automatically.
The <confirm> element provides a hint to the client which should require the user to confirm the selection of this task (in this case, there is no undo for a canceled workflow).
After the required input has been collected and the appropriate transition was chosen, the client calls the server command "doTransition".
The server loads the workflow object and the task object and the Java class defined in //transition/class. Then it executes this class with the task's metadata content as the given input. The transition class is responsible for validating the input (for example, does the specified review user exist?). It sets the status of the task to 'done' and creates new tasks as needed. The new tasks receive their input from the transition class, which sets the document id on the following tasks (so the reviewer and the editor do not need to specify it again, which would defeat the purpose of the workflow).
Afterwards, the server checks if there are any open tasks left in this workflow - if not, the workflow is finished and marked as such. The objects are updated in the Lucene index and the successful transition is reported to the client.
The review task
The review task introduces a new element which is not present in the start task: the <fixed> list of params:
<?xml version="1.0" encoding="UTF-8"?>
<meta>
<metaset type="task_definition">
<name>cinnamon.test.ReviewTask</name>
<manual>true</manual>
<description>Edit the document</description>
<input>
<fixed> <!-- This parameter should be set via the transition leading here. -->
<param>
<type>document</type>
<!-- id of a Cinnamon document -->
<label>document</label>
<name>document</name>
<value></value>
</param>
<param>
<type>string</type>
<label>message.to.editor</label>
<name>message</name>
<value></value>
</param>
</fixed>
<required>
<param>
<type>user</type>
<!-- a Cinnamon user id -->
<label>editor</label>
<!-- screen label -->
<name>editor</name>
<!-- parameter name -->
<value></value>
</param>
</required>
<optional>
<param>
<type>string</type>
<label>message.to.reviewer</label>
<name>message</name>
<value></value>
</param>
</optional>
</input>
</metaset>
<metaset type="transition">
<manual>true</manual>
<default>review_to_end</default>
<transition>
<show>true</show>
<confirm>false</confirm>
<name>review_to_edit</name>
<label>transition.edit</label>
<class>workflow.transition.test.ReviewToEdit</class>
<tasks>
<task name="edit_task">cinnamon.test.EditTask</task>
</tasks>
</transition>
<transition>
<show>true</show>
<confirm>false</confirm>
<name>review_to_end</name>
<label>transition.review.finished</label>
<class>workflow.transition.test.ReviewToEnd</class>
<tasks>
</tasks>
</transition>
<transition>
<show>true</show>
<confirm>true</confirm>
<name>cancel.review</name>
<label>transition.cancel.review</label>
<class>workflow.transition.test.CancelReviewWorkflow</class>
</transition>
</metaset>
</meta>
The <fixed> parameters should be set by the transition class. They must not be editable on the client.
The review task has the following transitions:
- review_to_edit (if the document should be edited)
- review_to_end (if the document is accepted)
- cancel.review (if the workflow is to be terminated)
The edit task
The edit task has the following metadata:
<?xml version="1.0" encoding="UTF-8"?>
<meta>
<metaset type="task_definition">
<name>cinnamon.test.EditTask</name>
<manual>true</manual>
<description>Review the document</description>
<input>
<fixed> <!-- This parameter should be set via the transition leading here. -->
<param>
<type>document</type>
<!-- id of a Cinnamon document -->
<label>document</label>
<name>document</name>
<value></value>
</param>
</fixed>
<required>
<param>
<type>user</type>
<!-- a Cinnamon user id -->
<label>reviewer</label>
<!-- screen label -->
<name>reviewer</name>
<!-- parameter name -->
<value></value>
</param>
</required>
<optional>
<param>
<type>string</type>
<label>message.to.editor</label>
<name>message</name>
<value></value>
</param>
</optional>
</input>
</metaset>
<metaset type="transition">
<manual>true</manual>
<default>edit_to_review</default>
<transition>
<show>true</show>
<name>edit_to_review</name>
<label>transition.edit_to_review</label>
<class>workflow.transition.test.EditToReview</class>
<tasks>
<task name="review_task">cinnamon.test.ReviewTask</task>
</tasks>
</transition>
<transition>
<show>true</show>
<confirm>true</confirm>
<name>cancel.review</name>
<label>transition.cancel.review</label>
<class>workflow.transition.test.CancelReviewWorkflow</class>
</transition>
</metaset>
</meta>
It requires the editor to select a reviewer, a data point that also could be turned into a fixed parameter upon creation of the worklow (or when the first reviewer starts his review task).
The edit task has two transitions available:
- edit_to_review (return the [edited] document to the reviewer)
- cancel.review (as before)
As the transition will create a new review task, which in turn can lead to a new edit task, this workflow can go on for quite some time, until the reviewer is satisfied with the document. Then, the reviewer selects the review_to_end transition in his task.
The end transition
The end transition does not create any new tasks - it sets the document to 'review_ok', the last task to 'done'and the workflow to 'finished'.

