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 \