lib/openwfe/expressions/condition.rb in ruote-0.9.18 vs lib/openwfe/expressions/condition.rb in ruote-0.9.19
- old
+ new
@@ -1,244 +1,251 @@
#
#--
# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
+#
+# 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
+# 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
+#
+# 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.
#++
#
#
# "made in Japan"
#
# John Mettraux at openwfe.org
#
-require 'rufus/eval' # gem 'rufus-eval'
+require 'openwfe/util/treechecker'
module OpenWFE
+ #
+ # A ConditionMixin is a mixin for flow expressions like 'if' and 'break' for
+ # example.
+ # It allows for shorter notations like
+ #
+ # <if test="${f:approved} == true"/>
+ #
+ # or
+ #
+ # _loop do
+ # participant :graphical_designer
+ # participant :business_analyst
+ # _break :if => "${f:approved}"
+ # end
+ #
+ module ConditionMixin
+
#
- # A ConditionMixin is a mixin for flow expressions like 'if' and 'break' for
- # example.
- # It allows for shorter notations like
+ # This is the method brought to expression classes including this
+ # mixin. Easy evaluation of a conditon expressed in an attribute.
#
- # <if test="${f:approved} == true"/>
- #
- # or
- #
- # _loop do
- # participant :graphical_designer
- # participant :business_analyst
- # _break :if => "${f:approved}"
- # end
- #
- module ConditionMixin
+ def eval_condition (attname, workitem, nattname=nil)
- #
- # This is the method brought to expression classes including this
- # mixin. Easy evaluation of a conditon expressed in an attribute.
- #
- def eval_condition (attname, workitem, nattname=nil)
+ positive = nil
+ negative = nil
- positive = nil
- negative = nil
+ positive = do_eval_condition(attname, workitem)
+ negative = do_eval_condition(nattname, workitem) if nattname
- positive = do_eval_condition(attname, workitem)
- negative = do_eval_condition(nattname, workitem) if nattname
+ negative = (not negative) if negative != nil
- negative = (not negative) if negative != nil
+ return positive if positive != nil
- return positive if positive != nil
+ negative
+ end
- negative
- end
+ #
+ # Returns nil if the cited attname (without or without 'r' prefix)
+ # is not present.
+ #
+ # Attname may be a String or a Symbol, or an Array of String or Symbol
+ # instances.
+ #
+ # Returns the Symbol the attribute if present.
+ #
+ def determine_condition_attribute (attname)
- #
- # Returns nil if the cited attname (without or without 'r' prefix)
- # is not present.
- #
- # Attname may be a String or a Symbol, or an Array of String or Symbol
- # instances.
- #
- # Returns the Symbol the attribute if present.
- #
- def determine_condition_attribute (attname)
+ attname = [ attname ] unless attname.is_a?(Array)
- attname = [ attname ] unless attname.is_a?(Array)
+ attname.each do |aname|
+ aname = aname.intern if aname.is_a?(String)
+ return aname if has_attribute(aname)
+ return aname if has_attribute("r" + aname.to_s)
+ end
- attname.each do |aname|
- aname = aname.intern if aname.is_a?(String)
- return aname if has_attribute(aname)
- return aname if has_attribute("r" + aname.to_s)
- end
+ nil
+ end
- nil
- end
+ protected
- protected
+ def do_eval_condition (attname, workitem)
- def do_eval_condition (attname, workitem)
+ #attname = pick_attribute(attname) \
+ # if attname.is_a?(Array)
- #attname = pick_attribute(attname) \
- # if attname.is_a?(Array)
+ conditional = lookup_attribute(attname, workitem)
+ rconditional = lookup_attribute("r"+attname.to_s, workitem)
- conditional = lookup_attribute(attname, workitem)
- rconditional = lookup_attribute("r"+attname.to_s, workitem)
+ return do_eval(rconditional, workitem) \
+ if rconditional and not conditional
- return do_eval(rconditional, workitem) \
- if rconditional and not conditional
+ return nil \
+ unless conditional
- return nil \
- unless conditional
+ ldebug { "do_eval_condition() 0 for >#{conditional}<" }
- ldebug { "do_eval_condition() 0 for >#{conditional}<" }
+ conditional = unescape conditional
- conditional = unescape conditional
+ ldebug { "do_eval_condition() 1 for >#{conditional}<" }
- ldebug { "do_eval_condition() 1 for >#{conditional}<" }
+ r = eval_set conditional
+ return r if r != nil
- r = eval_set conditional
- return r if r != nil
+ begin
+ return to_boolean(do_eval(conditional, workitem))
+ rescue Exception => e
+ # probably needs some quoting...
+ ldebug { "do_eval_condition() e : #{e}" }
+ end
- begin
- return to_boolean(do_eval(conditional, workitem))
- rescue Exception => e
- # probably needs some quoting...
- ldebug { "do_eval_condition() e : #{e}" }
- end
+ conditional = do_quote(conditional)
- conditional = do_quote(conditional)
+ ldebug { "do_eval_condition() 2 for >#{conditional}<" }
- ldebug { "do_eval_condition() 2 for >#{conditional}<" }
+ to_boolean(do_eval(conditional, workitem))
+ end
- to_boolean(do_eval(conditional, workitem))
- end
+ SET_REGEX = /(\S*?)( is)?( not)? set$/
- SET_REGEX = /(\S*?)( is)?( not)? set$/
+ #
+ # Evals the 'x [ is][ not] set' notation...
+ #
+ def eval_set (cond)
- #
- # Evals the 'x [ is][ not] set' notation...
- #
- def eval_set (cond)
+ m = SET_REGEX.match cond
- m = SET_REGEX.match cond
+ return nil unless m
- return nil unless m
+ val = m[1]
+ n = m[3]
- val = m[1]
- n = m[3]
+ ldebug do
+ "eval_set() for >#{cond}< "+
+ "m[1] is '#{val}', m[3] is '#{n}'"
+ end
- ldebug do
- "eval_set() for >#{cond}< "+
- "m[1] is '#{val}', m[3] is '#{n}'"
- end
+ val = val.strip if val
+ val = (val != nil and val != '')
+ n = (n and n.strip == 'not')
- val = val.strip if val
- val = (val != nil and val != '')
- n = (n and n.strip == 'not')
+ n ? (not val) : val
+ end
- n ? (not val) : val
- end
+ private
- private
+ #
+ # Returns true if result is the "true" String or the true
+ # boolean value. Returns false else.
+ #
+ def to_boolean (o)
- #
- # Returns true if result is the "true" String or the true
- # boolean value. Returns false else.
- #
- def to_boolean (o)
+ #(o == "true" or o == true)
+ o = o.strip if o.is_a?(String)
+ r = ! (o == nil || o == false || o == 'false' || o == '')
- ldebug { "to_boolean() o is _#{o}_" }
+ ldebug { "to_boolean() o is _#{o}_ => #{r}" }
- #(o == "true" or o == true)
- o = o.strip if o.is_a?(String)
- not (o == nil || o == false || o == 'false' || o == '')
- end
+ r
+ end
- #
- # unescapes '>' and '<'
- #
- def unescape (s)
+ #
+ # unescapes '>' and '<'
+ #
+ def unescape (s)
- s.gsub("&", "&").gsub(">", ">").gsub("<", "<")
- end
+ s.gsub("&", "&").gsub(">", ">").gsub("<", "<")
+ end
- #
- # Quotes the given string so that it can easily get evaluated
- # as Ruby code (a string comparison actually).
- #
- def do_quote (string)
+ #
+ # Quotes the given string so that it can easily get evaluated
+ # as Ruby code (a string comparison actually).
+ #
+ def do_quote (string)
- op = find_operator string
+ op = find_operator string
- return '"' + string + '"' unless op
+ return '"' + string + '"' unless op
- op, i = op
+ op, i = op
- s = '"'
- s << string[0..i-1].strip
- s << '" '
- s << string[i, op.length]
- s << ' "'
- s << string[i+op.length..-1].strip
- s << '"'
- s
- end
+ s = '"'
+ s << string[0..i-1].strip
+ s << '" '
+ s << string[i, op.length]
+ s << ' "'
+ s << string[i+op.length..-1].strip
+ s << '"'
+ s
+ end
- #
- # Returns the operator and its index (position) in the string.
- # Returns nil if not operator was found in the string.
- #
- def find_operator (string)
+ #
+ # Returns the operator and its index (position) in the string.
+ # Returns nil if not operator was found in the string.
+ #
+ def find_operator (string)
- [ "==", "!=", "<=", ">=", "<", ">" ].each do |op|
- i = string.index op
- next unless i
- return [ op, i ]
- end
- nil
- end
+ [ "==", "!=", "<=", ">=", "<", ">" ].each do |op|
+ i = string.index op
+ next unless i
+ return [ op, i ]
+ end
+ nil
+ end
- #
- # Runs the given given within an instance_eval() at a $SAFE
- # level of 4.
- #
- def do_eval (s, workitem)
+ #
+ # Evalutates the given code (after security checks)
+ #
+ def do_eval (s, workitem)
- wi = workitem
- fe = self
- #
- # wi and fe are thus available as well
- # (as self and workitem)
+ #TreeChecker.check_conditional s
+ get_tree_checker.check_conditional s
- Rufus::eval_safely(s, 4, binding())
- end
- end
+ # ok, green for eval
+
+ wi = workitem
+ fe = self
+ #
+ # wi and fe are thus available as well
+ # (as self and workitem)
+
+ #Rufus::eval_safely(s, 4, binding())
+ eval s, binding()
+ end
+ end
end