# #-- # Copyright (c) 2007, John Mettraux, OpenWFE.org # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # . Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # . Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # . Neither the name of the "OpenWFE" nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. #++ # # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $ # # # "made in Japan" # # John Mettraux at openwfe.org # require 'openwfe/expressions/condition' require 'openwfe/expressions/wtemplate' require 'openwfe/expressions/flowexpression' # # 'cursor' and 'loop' expressions # module OpenWFE A_COMMAND_FIELD = "command-field" F_COMMAND = "__cursor_command__" A_DISALLOW = "disallow" C_BACK = "back" C_SKIP = "skip" C_BREAK = "break" C_CANCEL = "cancel" C_REWIND = "rewind" C_CONTINUE = "continue" A_STEP = "step" # # The 'cursor' is much like a sequence, but you can go # back and forth within it. # class CursorExpression < WithTemplateExpression attr_accessor \ :loop_id, :current_child_id, :current_child_fei # # apply / reply def apply (workitem) @loop_id = 0 @current_child_id = -1 clean_children_list() reply(workitem) end def reply (workitem) if @children.length < 1 # # well, currently, no infinite empty loop allowed # reply_to_parent(workitem) return end command_field = lookup_command_field(workitem) command = lookup_command(command_field, workitem) disallow_list = lookup_disallow(workitem) command = nil \ if disallow_list and disallow_list.include? command if command == C_BREAK or command == C_CANCEL reply_to_parent(workitem) return end if command == C_REWIND or command == C_CONTINUE @current_child_id = 0 else step = lookup_step(command) @current_child_id = @current_child_id + step @current_child_id = 0 if @current_child_id < 0 if @current_child_id >= @children.length if not is_loop reply_to_parent(workitem) return end @loop_id += 1 @current_child_id = 0 end end workitem.attributes.delete(command_field) @current_child_fei = nil store_itself() @current_child_fei = @children[@current_child_id] # # launch the next child as a template get_expression_pool.launch_template( self, @loop_id, @current_child_fei, workitem, nil) end # # takes care of cancelling the current child if necessary # def cancel () get_expression_pool.cancel(@current_child_fei) \ if @current_child_fei super() end # # returns false, the child class LoopExpression does return true. # def is_loop return 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 def clean_children_list c = @children @children = [] c.each do |child| @children << child \ if child.kind_of? OpenWFE::FlowExpressionId end end def lookup_command_field (workitem) return lookup_attribute(A_COMMAND_FIELD, workitem, F_COMMAND) end def lookup_command (command_field, workitem) command = workitem.attributes[command_field] command = command.strip() if command return command end def lookup_disallow (workitem) return lookup_comma_list_attribute(A_DISALLOW, workitem) end end # # The 'loop' expression is like 'cursor' but it doesn't exit until # it's broken. # class LoopExpression < CursorExpression def is_loop return true end end # # 'skip', 'continue', and the like # class CursorCommandExpression < FlowExpression include ConditionMixin def apply (workitem) conditional = eval_condition(:if, workitem) # # for example : if conditional == nil or conditional command = @fei.expression_name step = lookup_attribute(A_STEP, workitem, "1") step = Integer(step) command = "#{command} #{step}" if step != 1 workitem.attributes[F_COMMAND] = command end reply_to_parent(workitem) end end end