#
#--
# Copyright (c) 2006-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/workitem'
require 'openwfe/flowexpressionid'
require 'openwfe/expressions/condition'
require 'openwfe/expressions/flowexpression'
#
# expressions like 'set' and 'unset' and their utility methods
#
module OpenWFE
#
# The 'if' expression.
#
#
#
#
#
#
#
# It accepts an 'else' clause :
#
#
#
#
#
#
#
#
#
# The 'test' attribute can be used instead of a condition child :
#
#
#
#
#
#
# The 'rtest' attribute can be used to embed a condition expressed directly
# in Ruby :
#
#
#
#
#
#
# Used alone with 'test' or 'rtest', the 'if' expression simply sets the
# the __result__ field of its workitem to the result of its attribute
# evaluation :
#
#
#
# will set the __result__ field of the workitem to 'false'.
#
class IfExpression < FlowExpression
include ConditionMixin
names :if
attr_accessor \
:condition_replied
def apply (workitem)
workitem.unset_result
test = eval_condition(:test, workitem)
if @children.length < 1
workitem.set_result test if test
reply_to_parent(workitem)
return
end
@condition_replied = (test != nil)
#
# if the "test" attribute is not used, test will be null
store_itself()
if test != nil
apply_consequence(test, workitem, 0)
else
get_expression_pool.apply(@children[0], workitem)
end
end
def reply (workitem)
if @condition_replied
reply_to_parent(workitem)
return
end
result = workitem.attributes[FIELD_RESULT]
@condition_replied = true
store_itself()
apply_consequence result, workitem
end
def reply_to_parent(workitem)
clean_children()
super workitem
end
protected
def apply_consequence (index, workitem, offset=1)
if index == true
index = 0
elsif index == false
index = 1
elsif index == nil
index = 1
elsif not index.integer?
index = 0
end
index = index + offset
if index >= @children.length
reply_to_parent workitem
else
get_expression_pool.apply @children[index], workitem
end
end
end
#
# The 'case' expression.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
# A generalized 'if'. Will evaluate its children, expecting the order :
#
# - condition
# - consequence
# - condition
# - consequence
# ...
# - else consequence (optional)
#
# The 'switch' nickname can be used for 'case'.
#
class CaseExpression < FlowExpression
names :case, :switch
attr_accessor \
:offset,
:evaluating_condition
def apply (workitem)
workitem.unset_result
@offset = nil
trigger_child workitem, true
end
def reply (workitem)
if @evaluating_condition
result = workitem.get_boolean_result
#ldebug { "reply() result : '#{result.to_s}' (#{result.class})" }
trigger_child workitem, !result
else
reply_to_parent workitem
end
end
protected
def trigger_child (workitem, is_condition)
@offset = if !@offset
0
elsif is_condition
@offset + 2
else
@offset + 1
end
#ldebug { "trigger_child() is_condition ? #{is_condition}" }
#ldebug { "trigger_child() next offset is #{@offset}" }
unless @children[@offset]
reply_to_parent workitem
return
end
@evaluating_condition = is_condition
store_itself
get_expression_pool.apply(@children[@offset], workitem)
end
end
end