Extended OpenSymphony Workflow

OSworkflow is a lightweight, robust workflow system implemented in Java, part of the OpenSymphony project. While osworkflow is used in very many applications, is development seems to have stopped. To enable sophisticated application development in our projects, we needed some enhancements to osworkflow, so we went ahead and implemented them. The result is a modified library that is 100% compatible with osworkflow 2.8.0, but implements two main features (listeners and scoped variables) and adds a simpler alternative API. We are also implementing hierarchical composition of workflows. The main rationale for developing these enhancements was the need for them in the zkWorkflow package, which pairs declarative workflows with declarative AJAX user interfaces developed in ZK. zkWorkflow is also available from this site along with a demonstration.

 This page does not constitute documentation for osworkflow, which is very well documented at its home page  (http://www.opensymphony.com/osworkflow). OSworkflow also has a basic but very usable graphical editor, which can be used very well with our enhancements, all of which are implemented as meta-annotations. The graphic designer is also part of the jar file with our enhancements.

Listener interface

Scoped variables

Our extension recognizes special meta-annotation names as variable definitions, declarations, or assertions. These definitions are evaluated using the MVEL language and can be specified within actions, steps and workflows.

The definitions are evaluated according to their position in the workflow and to an optional sequence parameter. Both action- and step-level metavariables can be set to be evaluated before or after the action is executed or the step is transitioned to. Workflow-level variables are evaluated once at the start of the workflow.

The following examples illustrate the syntax of the variable declaration, which follows the general pattern

<meta name="variable_definition">variable_definition</meta>

The definition will be evaluated using an MVEL expression which is evaluated in the same JVM that runs the workflow. The expression can reference other variable names, which will be resolved according to the current location in the worfklow. In general, action variables can see variables in the same action and in all the current steps. This means that if the same variable is defined in two different steps, the one the action will see is the one defined in whatever step is current when the action is invoked. Workflow-level variables are globals and will be seen everywhere, unless they are shadowed by step or action variables. So workflow variables are perfect to provide defaults.

Here are some examples of variable declarations (the ones you put in the name attribute):

[un]set[.scope][.when][.typeinfo].varname       

will set the variable varname to the value computed by the expression in the meta-attribute value. If unset is used, or the definition is empty, the variable is deleted if it exists. If set is used, the variable is created if it does not exist, or modified if it does.

The scope parameter can be either workflow, action, or step; the default is where the definition is.

The when parameter can be either pre or post; the default is pre. It determines the sequence of evaluation, before or after the transition or action; it only makes sense for steps and actions.

The typeinfo parameter provides a way to externalize the calculation of the variable value. In order to pair a specific typeinfo value to a calculator, a Java class must be defined and connected to the workflow. See the API  section below for details.

require[.scope][.when][.typeinfo].varname       

Behaves like set, but will not modify the current value of the variable. Rather, it will create it from the given definition only if the variable is not there; otherwise it will not modify anything.

assert[.scope][.when][.typeinfo].varname        

Will raise an exception if the variable doesn't evaluate to the result of the definition, or if it's not there. If the definition is empty, it will raise an exception if the variable does not exist. The Java equals() function is used to match calculated objects with existing values.

publish[.scope][.when].varname                  

Creates a new variable in the given scope as a clone() of the local one, which must exist.

execute[.when]                                  

Will ignore any result value and simply execute the definition code in the local context. Can be used, e.g., to print debugging statements or invoke operations with side effects.

Alternative workflow API

Hierarchically composed workflows