h2. OpenWFEru expressions

A few paragraphs and examples about each of the expressions found in OpenWFEru.

For each expression, a link is provided to its "rdoc", which might be pretty "empty".

Usage examples are given in XML and / or as Ruby process definitions.

Expression names in Ruby process definitions are often preceded with an '_' (underscore) to help differentiate them from actual Ruby keywords and identifiers.

It's also worth to have a look at how OpenWFEru implements each of the "workflow control patterns":patterns.html.

&nbsp;

Expressions are enumerated in the alphabetical order, but here is some kind of 'importance order' :

* <a href="#exp_participant">participant</a>  - delivering work to a participant
* <a href="#exp_sequence">sequence</a>  - composing the workflow sequentially
* <a href="#exp_concurrence">concurrence</a>  - organizing the work in parallel
* <a href="#exp_if">if</a>  - branching the process flow
* <a href="#exp_process-definition">process-definition</a>  - defining a process or a sub process
* <a href="#exp_cursor">cursor</a>  - like a 'sequence' but with opportunities to go back
* <a href="#exp_loop">loop</a>  - a 'cursor', with a looping behaviour
* <a href="#exp_iterator">iterator</a>  - some kind of 'for' loop
* <a href="#exp_concurrent-iterator">concurrent-iterator</a>  - each iteration is run in parallel
* <a href="#exp_subprocess">subprocess</a>  - calling a subprocess
* <a href="#exp_cancel-process">cancel-process</a>  - cancelling the current process, explicitely
* <a href="#exp_case">case</a>  - an extended 'if'
* <a href="#exp_cron">cron</a>  - registering process segments for execution at a determined interval time
* <a href="#exp_equals">equals</a>  - checking for equality among values, variables and field (attributes)
* <a href="#exp_defined">defined</a>  - checking that a variable or a workitem field is set
* <a href="#exp_field">field / f</a>  - extracting the value of a workitem field (also called a workitem attribute)
* <a href="#exp_filter">filter</a>  - filtering a workitem before and after a segment of process
* <a href="#exp_filter-definition">filter-definition</a>  - defining a workitem filter
* <a href="#exp_forget">forget</a>  - marking a process segment for 'forgotten execution'
* <a href="#exp_listen">listen</a>  - listening for workitem reaching or coming back from a participant (in any process instance)
* <a href="#exp_lose">lose</a>  - marking a process segment for 'lost execution'
* <a href="#exp_parameter">parameter</a>  - enforcing some parameters for a process or a subprocess
* <a href="#exp_quote">quote / q</a>  - quoting a value for insertion as a process variable or a workitem field
* <a href="#exp_redo">redo</a>  - redoing a segment of a process instance
* <a href="#exp_reserve">reserve</a>  - preventing segments of processes from concurrent execution
* <a href="#exp_restore">restore</a>  - restoring a worktime saved in a process variable
* <a href="#exp_reval">reval</a>  - evaluating some ruby code from the process definition
* <a href="#exp_save">save</a>  - saving a workitem to a process variable
* <a href="#exp_set">set</a>  - setting a process variable or a workitem field
* <a href="#exp_set_fields">set-fields</a>  - an alias for <a href="#exp_restore">restore</a>, setting the payload of a workitem at once
* <a href="#exp_sleep">sleep</a>  - making the process sleep for a while
* <a href="#exp_timeout">timeout</a>  - putting a timeout on a process segment
* <a href="#exp_undefined">undefined</a>  - checking whether a process variable or a workitem is defined
* <a href="#exp_undo">undo</a>  - undoing a process segment
* <a href="#exp_unset">unset</a>  - unsetting a process variable or a workitem field
* <a href="#exp_variable">variable / v</a>  - getting the value of a process variable
* <a href="#exp_when">when</a>  - executing a piece of process only when a condition realizes
* <a href="#exp_wait">wait</a>  - blocking until a condition realizes
* <a href="#exp_attribute">attribute / a</a>  - describing some complex value directly from the process definition
* <a href="#exp_log">log</a>  - logs a message to the application log
* <a href="#exp_eval">eval</a>  - evaluates snippets of process definitions foudn in fields or variables on the fly
* <a href="#exp_exp">exp</a>  - a limited version of 'eval', dynamically decide which expression (or participant or subprocess) should get used, at apply time

<hr>

h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_a"></a>a

'a' is a shortcut for the "attribute":#exp_attribute expression.


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_attribute"></a>attribute

Makes for ugly process definitions, but anyway... With this expression, a complex value (like a list or a map) can be described directly in XML or YAML in the process definition.

"rdoc":rdoc/classes/OpenWFE/AttributeExpression.html for more information


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_cancel-process"></a>cancel-process

Among the first expressions in the alphabetical order... When the workflow engine encounters this expression, it cancels completely the process instance to which it belongs.

#:code#xml#
    <sequence>
        <participant ref="before" />
        <cancel-process />
        <participant ref="after" />
    </sequence>
#:code#

It this example, the participant named "after" is never reached.

Most of the time, "cancel-process" is used as a consequence to an "if" expression or uses its own 'if' attribute, like in :

#:code#ruby#
    require 'openwfe/def'

    class TestDefinition1 < OpenWFE::ProcessDefinition
        sequence do
            participant "customer"
            _cancel_process :if => "${f:no_thanks} == true"
            concurrence do
                participant "accounting"
                participant "logistics"
            end
        end
    end
#:code#

If the participant "customer" set the field "no_thanks" to "true", the flow will never resume to the concurrence.

"rdoc":rdoc/classes/OpenWFE/CancelProcessExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_case"></a>case

The 'case' expression is an extended 'if'. It accepts a list of children and expects the first one to be a condition to evaluate. If this child evaluates to true it will evaluate the second child as a consequence and then exit.

If the first child evaluates to false, it will jump to the third child. If there is none, it will exit, if there is one, it will evaluate it (and if it's a condition...) (this is boring to explain).

#:code#ruby#
    require 'openwfe/def'

    class DefinitionWithCase < OpenWFE::ProcessDefinition
        case do
            equals :field => "customer", :val => "El Wasabi"
            participant :ref => "salesman_1"
            equals :field => "customer", :val => "Rio Coffee"
            participant :ref => "salesman_2"
            participant :ref => "salesman_3"
        end
            #
            # attributing customers to salesmen.
            # salesman number 3 handles anything that is not 'El Wasabi' or
            # 'Rio Coffee'
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/CaseExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_concurrence"></a>concurrence

Divides the process flow into two or more concurrent lanes.

#:code#xml#
    <process-definition name="exp_mydef" revision="0.1">
        <concurrence>
            <participant ref="alice" />
            <participant ref="bob" />
            <sequence>
                <participant ref="charlie" />
                <participant ref="doug" />
            </sequence>
        </concurrence>
    </process-definition>
#:code#

With OpenWFEru you could also write :

#:code#ruby#
    require 'openwfe/def'

    class MyProcessDefinition01 < OpenWFE::ProcessDefinition
        _concurrence do
            _participant :ref => "alice"
            _participant "bob"
            _sequence do
                charlie
                doug
            end
        end
    end
#:code#

Note that in this example, three different ways of 'invoking' a participant have been displayed.
When used alone, participant names have not been preceded by an underscore.


"rdoc":rdoc/classes/OpenWFE/ConcurrenceExpression.html (for an explanation on the merge attributes of the concurrence expression)


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_concurrent-iterator"></a>concurrent-iterator

This is a cross between a "concurrence":#exp_concurrence and an "iterator":#exp_iterator.

It understands the same attributes and behaves as should be : as an iterator spawning parallel copies of its child.

An "explanation with some examples":http://groups.google.com/group/openwferu-dev/msg/0965cf1d5d65533e

See it in action in the "workflow pattern 13, 14 and 15":patterns.html#pat_13_multiple_instances_with_a_priori_design_time_knowledge.

Some snippets, in XML :

#:code#xml#
    <concurrent-iterator on-value="sales, logistics, lob2" to-field="p">
        <participant field-ref="p" />
    </concurrent-iterator>
#:code#

In Ruby :

#:code#ruby#
    sequence do
      set :field => f, :value => %w{ Alan, Bob, Clarence }
      #... 
      concurrent_iterator :on_field => "f", :to_field => "p" do
        participant "${p}"
      end
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/ConcurrentIteratorExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_cron"></a>cron

#:code#xml#
    <!--
        trigger the subprocess 'send-reminder' once per hour from nine to
        five, from Monday to Friday.
    -->
    <cron tab="0 9-17 * * mon-fri" name="//reminder">
        <send-reminder />
    </cron>
#:code#

#:code#ruby#
    #
    # trigger the subprocess named 'send_reminder' every ten seconds.
    #
    cron :every => "10s"
        send_reminder
    end
#:code#

Without setting a 'name' with a double slash prefix, the cron will be bound to its process and will be cancelled when the process exits. Setting a name starting with a double slash prefix will bind the cron at the engine level, and this schedule will survive the end of the bounding process (it will then survive engine restarts as well).

"rdoc":rdoc/classes/OpenWFE/CronExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_cursor"></a>cursor

The 'cursor' expression is a sequence with extended capabilities.

It understands the following commands :

* back : gets back in the sequence for a certain number of 'steps'
* break : exits the cursor immediately
* cancel : an alias for 'break'
* continue : skips the rest of the cursor and exits (if the cursor is a loop, will continue at the beginning)
* jump : positions the cursor to an absolute position (step)
* rewind : an alias for 'continue'
* skip : skips a certain number of steps

Cursor commands accept condition attributes like in :

#:code#xml#
    <cursor>
        <participant field-ref="reference_1"
        <participant field-ref="reference_2"

        <break if="${field:do_not_hire} == true" />
            <!-- do not hire if one of the references set the field
                 'do_not_hire' to true -->

        <participant ref="faculty" />
        <participant ref="hr_department" />
    </cursor>
#:code#

More documentation of those conditions in the "cursor command rdoc":rdoc/classes/OpenWFE/CursorCommandExpression.html

The "loop":#exp_loop expression is a cursor that loops (you have to explicitely break or cancel it, to exit it).

"cursor rdoc":rdoc/classes/OpenWFE/CursorExpression.html
"cursor command rdoc":rdoc/classes/OpenWFE/CursorCommandExpression.html

The 'cursor' expression is used for example in the workflow control pattern 10 :Arbitrary Cycles.

"pattern":patterns.html#pat_10_arbitrary_cycles


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_defined"></a>defined

#:code#xml#
    <if>
        <defined field="customer">
        <!-- then -->
        <subprocess ref="call_customer" />
    </if>
#:code#

Note that since OpenWFEru 0.9.17, it's possible to write :

#:code#ruby#
    _if :test => "${field:customer} is set" do
        sequence do
            participant "A"
            participant "B"
        end
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/DefinedExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_equals"></a>equals

The 'equals' expression is mainly used nested within an "if":#exp_if expression. It's used to compare two values. A value may be a plain string, a variable or a workitem field (attribute).

Read more in the rdoc link that follows.

"rdoc":rdoc/classes/OpenWFE/EqualsExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_eval"></a>eval

"rdoc":rdoc/classes/OpenWFE/EvalExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_exp"></a>exp

The 'exp' expression allows to choose at apply time, which expression (or participant or subprocess) to use :

#:code#ruby#

    sequence do

        my_activity :variant => "sequence"
            # 
            # B works after A

        my_activity :variant => "concurrence"
            # 
            # A and B work in parallel
    end

    process_definition :name => "my_activity" do

        exp :name => "${variant}", :default => "sequence" do

            participant "A"
            participant "B"
        end
    end
#:code#

The 'name' (and the 'default') attribute(s) can refer to an expression, a subprocess name or a participant name, indifferently. See the following rdoc link for a more detailed example.

"rdoc":rdoc/classes/OpenWFE/ExpExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_f"></a>f

Is a shortcut for "field".


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_field"></a>field

"rdoc":rdoc/classes/OpenWFE/FqvExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_filter"></a>filter

The "participant":#exp_participant expression has a 'filter' attribute for filtering in and out the payload of a workitem.

There is a also a 'filter' expression for filtering data in and out of process segments.

#:code#ruby#
    class MyProcessDefinition001 < ProcessDefinition
        sequence do

            set :field => "readable", :value => "bible"
            set :field => "writable", :value => "sand"
            set :field => "randw", :value => "notebook"
            set :field => "hidden", :value => "playboy"

            alice

            filter :name => "filter0" do
                sequence
                    bob
                    charly
                end
            end
        end

        filter_definition :name => "filter0" do
            field :regex => "readable", :permissions => "r"
            field :regex => "writable", :permissions => "w"
            field :regex => "randw", :permissions => "rw"
            field :regex => "hidden", :permissions => ""
        end
    end
#:code#

In that example, participant 'alice' will see and be able to modify all the fields of the workitem, whereas, participants 'bob' and 'charly' will be restricted to read the fields 'readable' and 'randw' and to write to the fields 'sand' and 'randw'.

"rdoc":rdoc/classes/OpenWFE/FilterExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_filter_definition"></a>filter-definition

There is already an example of a filter definition in the description of the "filter":#exp_filter expression.

A filter definition builds and then binds a filter to an OpenWFE variable. A filter may thus be bound locally (no prefix), at the process level ("/" prefix) or at the engine level ("//" prefix).

Filter definition takes place within a process definition. They may be set directly in the process body or outside of it (still within the process definition).

#:code#ruby#
    filter_definition :name => "filter0" do
        field :regex => "readable", :permissions => "r"
        field :regex => "writable", :permissions => "w"
        field :regex => "randw", :permissions => "rw"
        field :regex => "hidden", :permissions => ""
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/FilterDefinitionExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_forget"></a>forget

"rdoc":rdoc/classes/OpenWFE/ForgetExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_if"></a>if

See the "exclusive choice":patterns.html#pat_4_exclusive_choice workflow control pattern.

"rdoc":rdoc/classes/OpenWFE/IfExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_iterator"></a>iterator

Given a list and a child expression (one unique child is expected), 'iterator' will execute the child expression once per element in the list.

#:code#xml#
    <iterator 
        on-value="alice, bob, charly"
        to-variable="next_participant"
    >
        <participant ref="${next_participant}" />
    </iterator>
#:code#

is thus equivalent to

#:code#xml#
    <sequence>
        <participant ref="alice" />
        <participant ref="bob" />
        <participant ref="charly" />
    </sequence>
#:code#

Of course, the list could be a bit more dynamic :

#:code#ruby#
    iterator :on_value => "${f:participant_list}", :to_variable => "p" do
        participant "${p}"
    end
#:code#

and since OpenWFEru 0.9.13, 'iterator' understands the same commands as '"cursor":#exp_cursor' (break/cancel, rewind/continue, skip, jump) :

#:code#ruby#
    iterator :on_value => "${f:participant_list}", :to_variable => "p" do
        sequence do
            participant "${p}"
            _break :if => "${f:participant_reply} == cancel_meeting"
                #
                # if one participant wishes to cancel the meeting, no need
                # to notify the others
        end
    end
#:code#

"iterator rdoc":rdoc/classes/OpenWFE/IteratorExpression.html
"cursor command rdoc":rdoc/classes/OpenWFE/CursorCommandExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_listen"></a>listen

This expression is used to 'listen' on participant events (apply or reply, by default, at apply time) and triggers a piece of process.

#:code#xml#
    <concurrence>

        <listen to="alpha">
            <subprocess ref="send-email-notification" />
        </listen>

        <sequence>
            <participant ref="alpha" />
            <participant ref="bravo" />
            <participant ref="alpha" />
        </sequence>

    </concurrence>
#:code#

Each time a workitem will be dispatched to participant "alpha" (applied), a copy of the workitem will be used to run an instance of the subprocess named "send-memail-notification".

#:code#ruby#
    listen :to => "^customer_.*", :upon => "reply", :where => "${f:customer_name} == Acme" do
        concurrence do
            participant :ref => "operational_sales"
            participant :ref => "strategic_sales"
        end
    end
#:code#

Makes sure that when the next workitem coming back from any participant whose name begins with "customer_" and where the field customer_name is set to "Acme", a copy of this workitem is used to trigger a small concurrence between two sales units.

The 'listen' expression is not limited to its own process instance, it listens to any participant event in the engine.

Since OpenWFEru 0.9.16, listen expressions without children are possible, then simply block, waiting for a 'message' and when it comes in, they let their process instance resume.

#:code#ruby#
    sequence do
        listen :to => "^customer_.*", :upon => "reply"
        subprocess :ref => "order_items"
    end
#:code#

Listen expressions without children only work 'once'.

OpenWFEru 0.9.16 introduces as well the 'intercept' and 'receive' aliases for the 'listen' expression. The concept behind this expression being "listen to", an 'on' attribute as been introduced has a alias to 'to', think "receive on" or "intercept on".

#:code#ruby#
    receive :on => "^customer_.*"
#:code#

0.9.16 also introduces a "merge" attribute, the default value is 'false'. When set to true, the workitem used to trigger the listen expression's nested child will be a merge of the original workitem (the one that activated the listen expression) and the incoming (the listened for) workitem.

#:code#ruby#
    listen :to => "^customer_.*", :merge => true
#:code#

"rdoc":rdoc/classes/OpenWFE/ListenExpression.html for more information


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_log"></a>log

Logs a message to the application log (if not specified otherwise logs/openwferu.log).

"rdoc":rdoc/classes/OpenWFE/LogExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_loop"></a>loop

See "cursor":#exp_cursor.

"rdoc":rdoc/classes/OpenWFE/LoopExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_lose"></a>lose

Loses a process segment. The 'lose' expression applies its child expression, but it never replies to its parent expression.

May be useful in concurrence cases where a certain number of answers are expected.

#:code#xml#
    <concurrence count="1">
        <!-- this concurrence expects two answers -->

        <lose>
            <!-- will be applied, but 'lose' will never reply 
                 to the concurrence -->
            <participant ref="alice" />
        </lose>

        <participant ref="bob" />
        <participant ref="charly" />
            <!-- the concurrence will be over as soon as bob or charly
                 will have replied -->

    </concurrence>
#:code#

"rdoc":rdoc/classes/OpenWFE/LoseExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_parameter"></a>parameter

'parameter' is not a real flow expression. It is used to state and check which required workitem/launchitem fields at present and valid at launch time.

#:code#xml#
<process-definition name="exp_x" revision="0">

    <!-- required workitem fields -->

    <parameter field="customer" />
    <parameter field="address" default="" />
    <parameter field="zip" type="integer" />
    <parameter field="town" />
    <parameter field="phone" match="^[0-9]{3}-[0-9]{7}$" />
    <parameter field="customer_type" default="2" type="int"/>

    <!-- the body of the process definition -->

    <sequence>
        <participant ref="service0" />
        <participant ref="service1" />
        <play-the-music/>
    </sequence>

    <!-- subprocesses -->

    <process-definition name="exp_play-the-music">
        <participant ref="musician" />
    </process-definition>

</process-definition>
#:code#

parameters ('param' is valid as well) have to be located outside of the body of the process definition (as a direct child of the 'process-definition' tag).

In that example, the process launch will immediately fail (even if the launch is asynchronous), if the launchitem doesn't contain the fields (attributes) 'customer', 'zip', 'town' and 'phone'.
If the field 'zip' is set to something that can be converted to an integer, the launch will fail.
If the 'phone' field value doesn't match the given regular expression, the launch will fail.
If the field 'address' is missing, it will be replaced by an empty string (the default value for that field).
If the field 'customer_type' is not explicitely given, its value will be the integer '2'.

In a ruby process definition, it looks like :

#:code#ruby#
    require 'openwfe/def'

    class MyProcessDefinition_01 < OpenWFE::ProcessDefinition

        #
        # required fields in the launchitem

        param :field => "customer"
        param :field => "address", default => ""
        param :field => "zip", type => "integer"
        param :field => "town"
        param :field => "phone", match => "^[0-9]{3}-[0-9]{7}$"
        param :field => "customer_type", default => 2, type => :int

        #
        # process definition body

        sequence do
            service0
            service1
            play_the_music
        end

        #
        # subprocesses

        process_definition :name => "play_the_music"
            musician
        end
    end
#:code#


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_participant"></a>participant

This expression is one of the most important in OpenWFE (it's featured in most of the process definition examples of this page).

A participant is usually located outside of the engine and waits for workitem to be delivered by the engine.

Participants are registered in the participant-map of the engine.

Multiple process definitions may share the same participants (processes != organizational chart).

A classic participant may be a workitem store, queried by a web application for human participants in business processes.

"participant implementations":participants.html shipping with OpenWFEru

"rdoc":rdoc/classes/OpenWFE/ParticipantExpression.html for more information


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_process-definition"></a>process-definition

"rdoc":rdoc/classes/OpenWFE/DefineExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_print"></a>print

"rdoc":rdoc/classes/OpenWFE/PrintExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_q"></a>q

Is a shortcut for "quote".


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_quote"></a>quote

"rdoc":rdoc/classes/OpenWFE/FqvExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_redo"></a>redo

Every expression accepts an implicit 'tag' attribute which defines a name under which a copy of the expression before evaluation is kept along with the workitem as applied (as received by the expression tagged).

The name (the tag) can then be used by a 'redo' or an '<a href="#exp_undo">undo</a>' expression.

#:code#ruby#
    sequence do
        sequence :tag => "core_job" do
            participant "alice"
            participant "bob"
        end
        participant "charly"
        _if :test => "${f:charly_not_happy} == true" do
            _redo :ref => "core_job"
        end
    end
#:code#

Maybe this example should be 'implemented' with a 

"rdoc":rdoc/classes/OpenWFE/RedoExpression.html

related : "using tags for signalling 'process state'":http://jmettraux.wordpress.com/2007/12/03/state-machine/


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_reserve"></a>reserve

This expression ensures that segments of a process instance are not run simultaneously.

It uses a mutex variable. A variable bound at engine level (prefixed with "//") can be used to prevent segments of totally different processes to execute simultaneously.

#:code#ruby#
   concurrence do
       sequence do
           activity_a
           reserve :mutex => :m do
               activity_b
           end
           activity_c
       end
       sequence do
           activity_d
           reserve :mutex => :m do
               sequence do
                   activity_e
                   activity_f
               end
           end
       end
   end
#:code#

In this example, the while the activity_b is performed, the sequence of activities e and f cannot be performed.

Note that for short, a symbol :m was used instead of the string "m". OpenWFEru turns the symbol into the corresponding string.

#:code#xml#
<!-- process A -->

    <process_definition name="A" revision="0.0">
        <sequence>
           <participant ref="alice" />
           <reserve mutex="//guard0">
               <participant ref="alfred" />
           </reserve>
        </sequence>
    </process_definition>

<!-- process B -->

    <process_definition name="B" revision="0.0">
        <sequence>
           <participant ref="bob" />
           <reserve mutex="//guard0">
               <participant ref="berthe" />
           </reserve>
        </sequence>
    </process_definition>
#:code#

In this XML example, the engine will prevent 'alfred' and 'berthe' from performing their task simultaneously, in processes A and B respectively. This is achieved by registering the mutex at the engine level (prefix "//").

"rdoc":rdoc/classes/OpenWFE/ReserveExpression.html

See the "interleaved parallel routing":patterns.html#pat_17_interleaved_parallel_routing workflow control pattern


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_restore"></a>restore

Restores the payload of a workitem previously "saved":#exp_save in a variable or copies the value of a [sub] field as the top value of the workitem payload.

There are many options for this expression. Check the following rdoc for a detailed explanation.

Since OpenWFEru 0.9.17, 'restore' has a 'set-fields' alias. It can be quite convenient for setting the payload of a workitem at the beginning of a business process.

#:code#ruby#
class Registration < OpenWFE::ProcessDefinition
    set_fields :value => {
        "name" => "",
        "address" => "",
        "email" => ""
    }
    sequence do
        approve_registration
        perform_registration :if => "${approved} == true"
        notify_customer
    end
end
#:code#

(The usual technique for pre-filling a workitem is by providing a launchitem when launching the business process

#:code#ruby#
    li = OpenWFE::LaunchItem.new "http://process.server.com/definitions/xyz.xml"
    li.customer = { "name" => "Toto", "age" => 34 }
    li.request_type = "credit"

    openwferu_engine.launch li
#:code#
)

"rdoc":rdoc/classes/OpenWFE/RestoreWorkItemExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_reval"></a>reval

This expression evals the Ruby code nested within it.

#:code#xml#
    <sequence>
        <reval>$i = 0</reval>
        <loop>
            <participant ref="toto" />
            <reval>$i = $i + 1</reval>
            <break if="${r:$i == 10}" />
            <!-- a variant :
            <break rif="$i == 10" />
            -->
        </loop>
    </sequence>
#:code#

Within a 'reval' piece of code, the two principal hooks within the engine 'bowels' are <tt>self</tt> which points to the RawExpression instance itself and <tt>workitem</tt>

#:code#ruby#
    class Reval4 < OpenWFE::ProcessDefinition
        sequence do
            reval """
                engine = self.application_context['__tracer']

                workitem.currently_active_processes =
                    engine.list_processes.join('\n')

                'done' # will be placed in the workitem field '__result__'
            """
            participant :toto
        end
    end
#:code#

The result of 'reval' is placed in the field named <pre>__result__</pre> as a String.

The code is evaluated at a SAFE level of 3 (see "http://www.rubycentral.com/book/taint.html":http://www.rubycentral.com/book/taint.html for more information about those levels).

You have to explicitely set the <tt>:ruby_eval_allowed</tt> param to true in the application context of the engine else the 'reval' expression will raise an exception.

#:code#ruby#
    engine.application_context[:ruby_eval_allowed] = true
#:code#

"rdoc":rdoc/classes/OpenWFE/RevalExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_save"></a>save

Saves a workitem to a variable or save the attributes of a workitem in a field (of that same workitem).

Is used in conjunction with "restore":#exp_restore.

"rdoc":rdoc/classes/OpenWFE/SaveWorkItemExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_sequence"></a>sequence

Simply chaining other flow expressions.

#:code#xml#
    <process-definition name="exp_my_definition" revision="0">
        <sequence>
            <participant ref="alpha" />
            <participant ref="bravo" />
            <participant ref="charly" />
        </sequence>
    </process-definition>
#:code#

In Ruby :

#:code#ruby#
    require 'openwfe/def'

    class MyDefinition0 < OpenWFE::ProcessDefinition
        sequence do
            participant "alpha"
            participant "bravo"
            participant "charly"
        end
    end
#:code#

"pattern":patterns.html#pat_1_sequence
"rdoc":rdoc/classes/OpenWFE/SequenceExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_set"></a>set

Is used to set the value of a variable or the value of a workitem field (attribute).

It may placed outside of the body of a process definition, it will be evaluated before the body gets applied (executed).

#:code#ruby#
    require 'openwfe/def'

    class MyDefinition0 < OpenWFE::ProcessDefinition
        sequence do
            participant "alpha"
        end

        set :field => "city", :value => "Kyoto"
        set :field => "country", :value => "Japan"
    end
#:code#

The participant 'alpha' will recevive a workitem with fields 'city' and 'country' set to 'Kyoto' and 'Japan' respectively. This technique is useful for keeping long settings out of the process 'logic' itself.

The "unset":#exp_unset cannot be placed outside of a process body. "Filter definitions":#exp_filter_definition can.

Shorter version of the attributes are OK :

#:code#ruby#
    require 'openwfe/def'

    class MyDefinition0 < OpenWFE::ProcessDefinition
        sequence do
            set :f => "customer_name", :val => "(fill this field)"
            participant "alpha"
        end
    end
#:code#

The 'set' expression accepts an 'escape' attribute to prevent dollar substituation from occurring.

#:code#ruby#
    set :v => "v0", :val => "my ${template} thing", escape => true
#:code#

"rdoc":rdoc/classes/OpenWFE/SetValueExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_set_fields"></a>set-fields

"set-fields" is an alias for <a href="#exp_restore">restore</a>.

"rdoc":rdoc/classes/OpenWFE/RestoreExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_sleep"></a>sleep

Makes a process segment sleep for a while.

#:code#xml#
    <sequence>

        <sleep for="3d" />
            <!-- sleeping for 3 days -->

        <sleep until="Mon Dec 03 10:48:03 +0900 2007" />

    </sequence>
#:code#

#:code#ruby#
    sequence do

        sleep :for => "3m10s"
            # sleeping for 3 minutes and 10 seconds

        sleep :until => "Mon Dec 03 10:48:03 +0900 2007"
            # sleeping until some point in time

        sleep "3M10d"
            # sleeping for 3 months and 10 days
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/SleepExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_subprocess"></a>subprocess

This expression is used to trigger a subprocess.

#:code#xml#
    <process-definition name="chores" revision="0">

        <sequence>
            <subprocess ref="take_out_garbage" />
            <subprocess ref="do_the_laundry" type="white" />
            <subprocess ref="do_the_laundry" type="colors" />
        </sequence>

        <process-definition name="take_out_garbage">
            <concurrence>
                <participant ref="al" activity="take out old paper" />
                <participant ref="bob" activity="take out garbage" />
            </concurrence>
        </process-definition>

        <process-definition name="do_the_laundry">
            <sequence>
                <participant ref="al" activity="sort ${type}" />
                <participant ref="bob" activity="clean ${type}" />
                <sleep for="1h30m" />
                <participant ref="al" activity="hang ${type}" />
                <participant ref="al" activity="iron ${type}" />
            </sequence>
        </process-definition>
    </process-definition>
#:code#

Note how the variable 'type' was set to 'white' and then 'colors' and used within the "do_the_laundry" subprocess.

#:code#ruby#
    class Chores0 < OpenWFE::ProcessDefinition

        sequence do
            subprocess :ref => "take_out_garbage"
            do_the_laundry :type => "white"
            subprocess :ref => "do_the_laundry", :type => "colors"
        end

        process_definition :name => "take_out_garbage" do
            concurrence do
                participant :ref => "al", :activity => "take out old paper"
                bob :activity => "take out garbage"
            end
        end

        process_definition :name => "do_the_laundry" do
            sequence do
                participant :ref => "al", :activity => "sort ${type}"
                participant :ref => "bob", :activity => "clean ${type}"
                sleep :for => "1h30m"
                al :activity => "hang ${type}"
                al :activity => "iron ${type}"
            end
        end
    end
#:code#

Note how the subprocess name (and the participant names) can be used as expression names for a shorter syntax. Of course names with white spaces and other niceties won't work for this shorter syntax.

"rdoc":rdoc/classes/OpenWFE/SubProcessRefExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_timeout"></a>timeout

A generic timeout mechanism : sets a timeout for a whole process segment, not just a single participant or when expression.

#:code#xml#
    <timeout after="1w">
        <concurrence>
            <participant ref="alpha" />
            <subprocess ref="do_the_homework" />
        </concurrence>
    </timeout>
#:code#

#:code#ruby#
    _timeout :after => "2d" do
        sequence do

            participant :ref => "alpha", :timeout => "1d"
                # of course individal timeout settings are still ok

            participant :ref => "bravo"
        end
    end
#:code#

Note that when using a Ruby process definition, you'd better escape the 'timeout' expression with an underscore at the front to avoid collisions with the 'timeout' method provided by the timeout.rb standard Ruby library.

"rdoc":rdoc/classes/OpenWFE/TimeoutExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_undefined"></a>undefined

#:code#xml#
    <if>
        <undefined field="customer">
        <!-- then -->
        <subprocess ref="determine_customer" />
    </if>
#:code#

Note that since OpenWFEru 0.9.17, it's possible to write :

#:code#ruby#
    _if :test => "${field:customer} is not set" do
        sequence do
            participant "A"
            participant "B"
        end
    end
#:code#

"rdoc":rdoc/classes/OpenWFE/DefinedExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_undo"></a>undo

Every expression accepts an implicit 'tag' attribute which defines a name under which a copy of the expression before evaluation is kept along with the workitem as applied (as received by the expression tagged).

The name (the tag) can then be used by a 'redo' or an 'undo' expression.

#:code#ruby#
    concurrence do
        sequence :tag => "side_job" do
            participant "alice"
            participant "bob"
        end
        sequence do
            participant "charly"
            _undo :ref => "side_job"
        end
    end
#:code#

In this example, after participant 'charly' did his job, the first sequence (tagged 'side_job') will get cancelled (and its reply to the parent 'concurrence' will get triggered).

See also the "redo":#exp_redo expression.

"rdoc":rdoc/classes/OpenWFE/UndoExpression.html

related : "using tags for signalling 'process state'":http://jmettraux.wordpress.com/2007/12/03/state-machine/


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_unset"></a>unset

"rdoc":rdoc/classes/OpenWFE/UnsetValueExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_v"></a>v

Is a shortcut for "variable".


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_variable"></a>variable

"rdoc":rdoc/classes/OpenWFE/FqvExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_when"></a>when

The 'when' expression polls a conditional statement and triggers the nested process segment when the condition evaluates to true.

#:code#xml#
    <concurrence>
        <participant ref="alpha" />
        <when test="${for_bravo} == true">
            <participant ref="bravo" />
        </when>
        <participant ref="charly" />
    </concurrence>
#:code#

When the variable "for_bravo" will contain the value "true", participant "bravo" will receive a workitem.

By default 'when' evaluates the condition until true every 10 seconds.

#:code#ruby#
    concurrence do
        alpha
        when :test => "${for_bravo} == true", :frequency => "1h", :timeout => "13d4h" do
            bravo
        end
        charly
    end
#:code#

In this Ruby process definition (where all the participant expressions where simplified to just their names), the when condition is checked only every hour and after thirteen days and four hours, the 'when' is cancelled (and participant bravo will not receive a workitem).

Note that in both examples, the concurrence will wait until the when expression resumes the process.

"rdoc":rdoc/classes/OpenWFE/WhenExpression.html


h3. <a href="#top" title="back to top of page"><img src="images/ru-light-small.png" border="0" align="right"/></a> <a name="exp_wait"></a>wait

This expression is very similar to when, but it doesn't accept a nested expression. It blocks until its 'until' condition evaluates to true or until it times out.

May make some process definitions more readable.

"rdoc":rdoc/classes/OpenWFE/WaitExpression.html for more information

