lib/openwfe/expressions/fe_misc.rb in openwferu-0.9.16 vs lib/openwfe/expressions/fe_misc.rb in openwferu-0.9.17

- old
+ new

@@ -1,8 +1,8 @@ # #-- -# Copyright (c) 2006-2007, John Mettraux, OpenWFE.org +# Copyright (c) 2006-2008, 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: # @@ -35,12 +35,13 @@ # "made in Japan" # # John Mettraux at openwfe.org # -require 'openwfe/util/safe' +require 'rufus/eval' require 'openwfe/expressions/flowexpression' +require 'openwfe/expressions/value' module OpenWFE # @@ -63,18 +64,17 @@ # name '__tracer', this expression will append its message to this # instance instead of emitting to the STDOUT. (this is how the # OpenWFEru test suite uses this expression). # class PrintExpression < FlowExpression + include ValueMixin names :print - def apply (workitem) + def reply (workitem) - escape = lookup_boolean_attribute('escape', workitem, false) - - text = fetch_text_content workitem, escape + text = workitem.get_result.to_s text << "\n" tracer = @application_context['__tracer'] if tracer @@ -121,46 +121,214 @@ # end # # Don't embed too much Ruby into your process definitions, it might # hurt... # + # Reval can also be used with the 'code' attribute (or 'field-code' or + # 'variable-code') : + # + # <reval field-code="f0" /> + # + # to eval the Ruby code held in the field named "f0". + # class RevalExpression < FlowExpression + include ValueMixin names :reval # # See for an explanation on Ruby safety levels : # http://www.rubycentral.com/book/taint.html # + # 'reval' is entitled a safe level of 3. + # SAFETY_LEVEL = 3 - def apply (workitem) + def reply (workitem) + raise "evaluation of ruby code is not allowed" \ if @application_context[:ruby_eval_allowed] != true - escape = lookup_boolean_attribute('escape', workitem, false) - - code = lookup_vf_attribute(workitem, 'code') - - code = fetch_text_content(workitem, escape) \ - unless code - + code = lookup_vf_attribute(workitem, 'code') || workitem.get_result code = code.to_s - wi = workitem + wi = workitem + # so that the ruby code being evaluated sees 'wi' and 'workitem' - result = OpenWFE::eval_safely code, SAFETY_LEVEL, binding() + result = Rufus::eval_safely code, SAFETY_LEVEL, binding() workitem.set_result(result) \ if result != nil # 'false' is a valid result reply_to_parent workitem end end # + # An advanced expression : it takes the value in a field or variable (or + # the nested value) and evaluates it as a process definition. + # + # sequence + # set :field => "code", :value => "<print>hello 0</print>" + # _eval :field_def => "code" + # set :field => "code", :value => "_print 'hello 1'" + # _eval :field_def => "code" + # end + # + # will print "hello0\nhello1". + # + # This expression can be useful for evaluating process definition snippets + # coming from participants directly. + # + # It's also dangerous. This 'eval' expression will raise an error if + # the parameter :dynamic_eval_allowed in the engine's application context + # is not set to true. + # + class EvalExpression < FlowExpression + include ValueMixin + + names :eval + + + def reply (workitem) + + raise "dynamic evaluation of process definitions is not allowed" \ + if @application_context[:dynamic_eval_allowed] != true + + df = lookup_vf_attribute(workitem, 'def') || workitem.get_result + + return reply_to_parent(workitem) unless df + # + # currently, 'nothing to eval' means, 'just go on' + + ldebug { "apply() def is >#{df}<" } + + raw_expression = build_raw_expression df + + #puts + #puts "======================================" + #puts raw_expression.to_s + #puts raw_expression.raw_representation + #puts "======================================" + #puts + + raw_expression.apply workitem + end + + protected + + def build_raw_expression (df) + + procdf = get_expression_pool.determine_rep df + + RawExpression.new_raw( + fei, parent_id, environment_id, application_context, procdf) + end + end + + # + # Some kind of limited 'eval' expression. + # + # Here is an usage example : + # + # class ExampleDef < OpenWFE::ProcessDefinition + # + # sequence do + # + # exp :name => "p0" + # exp :name => "sub0" + # + # exp :name => "sequence" do + # p0 + # sub0 + # end + # + # set :var => "a", :value => { "ref" => "p0" } + # exp :name => "participant", :variable_attributes => "a" + # end + # + # process_definition :name => "sub0" do + # _print "sub0" + # end + # end + # + # This example is a bit static, but the point is that the 'exp' + # is extracting the real expression name (or participant or subprocess + # name) from its 'name' attribute. + # + # The 'eval' expression is about evaluating a complete process definition + # branch, 'exp' is only about one node in the process definition. + # + class ExpExpression < RawExpression + + names :exp + + #-- + #def initialize (fei, parent_id, env_id, app_context, att) + # # + # # this responds to the FlowExpression constructor... + # super fei, parent_id, env_id, app_context, nil + # # + # # but this triggers the RawExpression constructor :) + # @attributes = att + # # + # # as this is not done by the RawExpression constructor + #end + #++ + + def apply (workitem) + + @applied_workitem = workitem + + super + end + + protected + + # + # Evaluates the 'name' attribute, if it's not present or empty, + # will return the value for the 'default' attribute. + # + def expression_name + + n = lookup_attribute(:name, @applied_workitem) + + return lookup_attribute(:default, @applied_workitem) \ + if (not n) or (n.strip == '') + + n + end + + # + # If the 'attributes' attribute is present, will return its + # value. Else, will simply return the attributes of the 'exp' + # expression itself ('name' and 'default' included). + # + def extract_attributes + + att = lookup_vf_attribute @applied_workitem, :attributes + # will currently only work with an attribute hash + # whose keys are strings... symbols :( + + att || @attributes + end + + def extract_descriptions + [] + end + + def extract_children + @children + end + + def extract_parameters + [] + end + end + + # # This expression simply emits a message to the application # log (by default logs/openwferu.log). # # <sequence> # <log>before participant alpha</log> @@ -182,17 +350,16 @@ # # Possible log levels are 'debug' (the default), 'info', 'warn' and # 'fatal'. # class LogExpression < FlowExpression + include ValueMixin names :log - def apply (workitem) + def reply (workitem) - escape = lookup_boolean_attribute('escape', workitem, false) - text = fetch_text_content(workitem, escape) - text = lookup_attribute('message', workitem) unless text + text = lookup_attribute('message', workitem) || workitem.get_result level = lookup_attribute('level', workitem) level = level.downcase.to_sym if level level = :debug \