lib/openwfe/expressions/fe_cursor.rb in openwferu-0.9.8 vs lib/openwfe/expressions/fe_cursor.rb in openwferu-0.9.9
- old
+ new
@@ -58,17 +58,42 @@
C_SKIP = "skip"
C_BREAK = "break"
C_CANCEL = "cancel"
C_REWIND = "rewind"
C_CONTINUE = "continue"
+ C_JUMP = "jump"
A_STEP = "step"
#
# The 'cursor' is much like a sequence, but you can go
- # back and forth within it.
+ # back and forth within it, as it reads the field '\_\_cursor_command__' (or
+ # the field specified in the 'command-field' attribute) at each
+ # transition (each time it's supposed to move from one child expression to
+ # the next).
#
+ # cursor do
+ # participant "alpha"
+ # skip :step => "2"
+ # participant "bravo"
+ # participant "charly"
+ # set :field => "__cursor_command__", value => "2"
+ # participant "delta"
+ # participant "echo"
+ # skip 2
+ # participant "fox"
+ # #
+ # # in that cursor example, only the participants alpha, charly and
+ # # echo will be handed a workitem
+ # # (notice the last 'skip' with its light syntax)
+ # #
+ # end
+ #
+ # As you can see, you can directly set the value of the field
+ # '\_\_cursor_command__' or use a CursorCommandExpression like 'skip' or
+ # 'jump'.
+ #
class CursorExpression < WithTemplateExpression
names :cursor
attr_accessor \
@@ -98,26 +123,40 @@
#
reply_to_parent(workitem)
return
end
- command_field = lookup_command_field(workitem)
- command = lookup_command(command_field, workitem)
- disallow_list = lookup_disallow(workitem)
+ command_field = lookup_command_field workitem
+ command, step = lookup_command command_field, workitem
+
+ disallow_list = lookup_disallow workitem
+
command = nil \
- if disallow_list and disallow_list.include? command
+ if disallow_list and disallow_list.include?(command)
+ ldebug { "reply() command is '#{command} #{step}'" }
+
if command == C_BREAK or command == C_CANCEL
- reply_to_parent(workitem)
+ reply_to_parent workitem
return
end
if command == C_REWIND or command == C_CONTINUE
+
@current_child_id = 0
- else
- step = lookup_step(command)
+
+ elsif command and command.match "^#{C_JUMP}"
+
+ @current_child_id = step
+ @current_child_id = 0 if @current_child_id < 0
+
+ @current_child_id = @children.length - 1 \
+ if @current_child_id >= @children.length
+
+ else # C_SKIP or C_BACK
+
@current_child_id = @current_child_id + step
@current_child_id = 0 if @current_child_id < 0
if @current_child_id >= @children.length
@@ -146,91 +185,155 @@
end
#
# takes care of cancelling the current child if necessary
#
- def cancel ()
+ def cancel
get_expression_pool.cancel(@current_child_fei) \
if @current_child_fei
- super()
+ super
end
#
- # returns false, the child class LoopExpression does return true.
+ # Returns false, the child class LoopExpression does return true.
#
def is_loop
- return false
+ false
end
protected
- def lookup_step (command)
-
- return 1 if not command
-
- step = 1
-
- ss = command.split()
-
- if ss.length > 1
- step = Integer(ss[1])
- end
-
- step = -step if OpenWFE::starts_with(command, C_BACK)
-
- return step
- end
-
+ #
+ # Makes sure that only flow expression are left in the cursor
+ # children list (text and comment nodes get discarded).
+ #
def clean_children_list
c = @children
@children = []
c.each do |child|
@children << child \
- if child.kind_of? OpenWFE::FlowExpressionId
+ if child.kind_of?(OpenWFE::FlowExpressionId)
end
end
+ #
+ # Looks up the value in the command field.
+ #
def lookup_command_field (workitem)
- return lookup_attribute(A_COMMAND_FIELD, workitem, F_COMMAND)
+ lookup_attribute(A_COMMAND_FIELD, workitem, F_COMMAND)
end
+ #
+ # Returns the command and the step
+ #
def lookup_command (command_field, workitem)
command = workitem.attributes[command_field]
- command = command.strip() if command
- return command
+ return [ nil, 1 ] unless command
+ #
+ # this corresponds to the "just one step forward" default
+
+ command, step = command.strip.split
+
+ step = if step
+ step.to_i
+ else
+ 1
+ end
+
+ step = -step if command == C_BACK
+
+ [ command, step ]
end
+ #
+ # Fetches the value of the 'disallow' cursor attribute.
+ #
def lookup_disallow (workitem)
- return lookup_comma_list_attribute(A_DISALLOW, workitem)
+ lookup_comma_list_attribute(A_DISALLOW, workitem)
end
end
#
# The 'loop' expression is like 'cursor' but it doesn't exit until
- # it's broken.
+ # it's broken (with 'break' or 'cancel').
#
class LoopExpression < CursorExpression
names :loop
def is_loop
- return true
+ true
end
end
#
- # 'skip', 'continue', and the like
+ # This class implements the following expressions : back, break,
+ # cancel, continue, jump, rewind, skip.
#
+ # They are generally used inside of a 'cursor' (CursorExpression) or
+ # a 'loop' (LoopExpression), they can be used outside, but their result
+ # (the value of the field '\_\_cursor_command__' will be used as soon as the
+ # flow enters a cursor or a loop).
+ #
+ # In fact, this expression is only a nice wrapper that sets the
+ # value of the field "\_\_cursor_command__" to its name ('back' for example)
+ # plus to the 'step' attribute value.
+ #
+ # For example <skip step="3"/> simply sets the value of the field
+ # '\_\_cursor_command__' to 'skip 3'.
+ #
+ # (The field \_\_cursor_command__ is, by default, read and
+ # obeyed by the 'cursor' expression).
+ #
+ # With Ruby process definitions, you can directly write :
+ #
+ # skip 2
+ # jump "0"
+ #
+ # instead of
+ #
+ # skip :step => "2"
+ # jump :step => "0"
+ #
+ # Likewise, in an XML process definition, you can write
+ #
+ # <skip>2</skip>
+ #
+ # although that might still look lighter (it's longer though) :
+ #
+ # <skip step="2"/>
+ #
+ #
+ # About the command themselves :
+ #
+ # * back : will go back from the number of given steps, 1 by default
+ # * break : will exit the cursor (or the loop)
+ # * cancel : an alias for 'break'
+ # * continue : will exit the cursor, if in a loop, will get back at step 0
+ # * jump : will move the cursor (or loop) to an absolute given position (count starts at 0)
+ # * rewind : an alias for continue
+ # * skip : skips the given number of steps
+ #
+ #
+ # All those command support an 'if' attribute to restrict their execution :
+ #
+ # cursor do
+ # go_to_shop
+ # check_prices
+ # _break :if => "${price} > ${f:current_cash}"
+ # buy_stuff
+ # end
+ #
class CursorCommandExpression < FlowExpression
include ConditionMixin
- names :back, :skip, :continue, :break, :cancel, :rewind
+ names :back, :skip, :continue, :break, :cancel, :rewind, :jump
def apply (workitem)
conditional = eval_condition(:if, workitem)
#
@@ -238,18 +341,20 @@
if conditional == nil or conditional
command = @fei.expression_name
- step = lookup_attribute(A_STEP, workitem, "1")
+ step = lookup_attribute(A_STEP, workitem)
+ step = fetch_text_content(workitem) unless step
+ step = 1 unless step
step = Integer(step)
- command = "#{command} #{step}" if step != 1
+ command = "#{command} #{step}" #if step != 1
workitem.attributes[F_COMMAND] = command
end
- reply_to_parent(workitem)
+ reply_to_parent workitem
end
end
end