openwferu 0.9.16 → 0.9.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/examples/about_state.rb +81 -0
  2. data/examples/engine_template.rb +7 -0
  3. data/lib/openwfe/contextual.rb +2 -2
  4. data/lib/openwfe/def.rb +2 -3
  5. data/lib/openwfe/{util/schedulers.rb → engine.rb} +3 -39
  6. data/lib/openwfe/engine/engine.rb +202 -251
  7. data/lib/openwfe/engine/process_status.rb +359 -0
  8. data/lib/openwfe/expool/errorjournal.rb +6 -6
  9. data/lib/openwfe/expool/expressionpool.rb +161 -239
  10. data/lib/openwfe/expool/expstorage.rb +185 -55
  11. data/lib/openwfe/expool/journal.rb +1 -2
  12. data/lib/openwfe/expool/parser.rb +233 -0
  13. data/lib/openwfe/expool/threadedexpstorage.rb +6 -18
  14. data/lib/openwfe/expool/wfidgen.rb +25 -7
  15. data/lib/openwfe/expool/yamlexpstorage.rb +60 -37
  16. data/lib/openwfe/expressions/condition.rb +49 -12
  17. data/lib/openwfe/expressions/environment.rb +45 -15
  18. data/lib/openwfe/expressions/expressionmap.rb +39 -19
  19. data/lib/openwfe/expressions/fe_concurrence.rb +24 -13
  20. data/lib/openwfe/expressions/fe_cron.rb +19 -18
  21. data/lib/openwfe/expressions/fe_cursor.rb +69 -28
  22. data/lib/openwfe/expressions/fe_define.rb +4 -1
  23. data/lib/openwfe/expressions/fe_do.rb +1 -3
  24. data/lib/openwfe/expressions/fe_equals.rb +131 -20
  25. data/lib/openwfe/expressions/fe_fqv.rb +27 -3
  26. data/lib/openwfe/expressions/fe_iterator.rb +14 -7
  27. data/lib/openwfe/expressions/fe_listen.rb +7 -2
  28. data/lib/openwfe/expressions/fe_misc.rb +187 -20
  29. data/lib/openwfe/expressions/fe_participant.rb +8 -7
  30. data/lib/openwfe/expressions/fe_reserve.rb +105 -33
  31. data/lib/openwfe/expressions/fe_save.rb +55 -5
  32. data/lib/openwfe/expressions/{fe_value.rb → fe_set.rb} +6 -82
  33. data/lib/openwfe/expressions/fe_sleep.rb +25 -15
  34. data/lib/openwfe/expressions/fe_subprocess.rb +2 -2
  35. data/lib/openwfe/expressions/fe_wait.rb +3 -2
  36. data/lib/openwfe/expressions/fe_when.rb +7 -15
  37. data/lib/openwfe/expressions/flowexpression.rb +90 -49
  38. data/lib/openwfe/expressions/merge.rb +7 -1
  39. data/lib/openwfe/expressions/raw.rb +261 -63
  40. data/lib/openwfe/expressions/{raw_prog.rb → rprocdef.rb} +94 -179
  41. data/lib/openwfe/expressions/time.rb +36 -12
  42. data/lib/openwfe/expressions/timeout.rb +9 -7
  43. data/lib/openwfe/expressions/value.rb +126 -0
  44. data/lib/openwfe/flowexpressionid.rb +52 -22
  45. data/lib/openwfe/listeners/listeners.rb +3 -3
  46. data/lib/openwfe/listeners/socketlisteners.rb +8 -5
  47. data/lib/openwfe/logging.rb +6 -3
  48. data/lib/openwfe/omixins.rb +8 -6
  49. data/lib/openwfe/orest/xmlcodec.rb +16 -12
  50. data/lib/openwfe/participants.rb +38 -0
  51. data/lib/openwfe/participants/participant.rb +1 -1
  52. data/lib/openwfe/participants/participantmap.rb +24 -10
  53. data/lib/openwfe/participants/participants.rb +4 -3
  54. data/lib/openwfe/participants/soapparticipants.rb +1 -1
  55. data/lib/openwfe/participants/socketparticipants.rb +1 -1
  56. data/lib/openwfe/rudefinitions.rb +7 -5
  57. data/lib/openwfe/storage/yamlcustom.rb +10 -10
  58. data/lib/openwfe/storage/yamlfilestorage.rb +12 -12
  59. data/lib/openwfe/tools/flowtracer.rb +6 -5
  60. data/lib/openwfe/util/dollar.rb +42 -85
  61. data/lib/openwfe/util/ometa.rb +1 -3
  62. data/lib/openwfe/util/workqueue.rb +1 -1
  63. data/lib/openwfe/utils.rb +33 -11
  64. data/lib/openwfe/version.rb +2 -2
  65. data/lib/openwfe/workitem.rb +76 -14
  66. data/lib/openwfe/worklist/storelocks.rb +9 -4
  67. data/lib/openwfe/worklist/storeparticipant.rb +1 -1
  68. data/test/back_0916_test.rb +101 -0
  69. data/test/bm/ft_26_load.rb +1 -1
  70. data/test/bm/ft_26b_load.rb +1 -1
  71. data/test/bm/ft_26c_load.rb +3 -2
  72. data/test/bm/ft_26d_load.rb +97 -0
  73. data/test/bm/ft_recu.rb +71 -0
  74. data/test/concurrence_test.rb +1 -1
  75. data/test/condition_test.rb +152 -0
  76. data/test/description_test.rb +12 -7
  77. data/test/eno_test.rb +1 -1
  78. data/test/expool_20031219_0916.tgz +0 -0
  79. data/test/fe_lookup_att_test.rb +1 -1
  80. data/test/fei_test.rb +16 -0
  81. data/test/file_persistence_test.rb +8 -12
  82. data/test/filep_cancel_test.rb +116 -0
  83. data/test/flowtestbase.rb +47 -25
  84. data/test/ft_0.rb +1 -1
  85. data/test/ft_10_loop.rb +29 -14
  86. data/test/{ft_10b_loop2.rb → ft_10b_loop.rb} +2 -11
  87. data/test/ft_11_ppd.rb +6 -17
  88. data/test/ft_11b_ppd.rb +1 -4
  89. data/test/ft_12_blockparticipant.rb +1 -1
  90. data/test/ft_13_eno.rb +1 -1
  91. data/test/ft_15_iterator.rb +1 -1
  92. data/test/ft_15b_iterator.rb +1 -1
  93. data/test/ft_17_condition.rb +6 -6
  94. data/test/ft_18_pname.rb +1 -1
  95. data/test/ft_20_cron.rb +1 -1
  96. data/test/ft_21_cron.rb +6 -4
  97. data/test/ft_22_history.rb +1 -1
  98. data/test/ft_23_when.rb +1 -1
  99. data/test/ft_23b_when.rb +18 -6
  100. data/test/ft_23c_wait.rb +8 -6
  101. data/test/ft_25_cancel.rb +7 -5
  102. data/test/ft_27_getflowpos.rb +22 -17
  103. data/test/ft_28_fileparticipant.rb +1 -2
  104. data/test/ft_2_concurrence.rb +1 -1
  105. data/test/ft_2b_concurrence.rb +25 -20
  106. data/test/ft_30_socketlistener.rb +0 -3
  107. data/test/ft_34_cancelwfid.rb +9 -9
  108. data/test/ft_35_localdefs.rb +0 -1
  109. data/test/ft_36_subprocids.rb +6 -6
  110. data/test/ft_38_tag.rb +3 -2
  111. data/test/ft_38b_tag.rb +229 -0
  112. data/test/ft_39_reserve.rb +3 -18
  113. data/test/ft_39b_reserve.rb +34 -5
  114. data/test/ft_3b_lookup_vf.rb +83 -0
  115. data/test/ft_40_defined.rb +2 -11
  116. data/test/ft_42_environments.rb +4 -6
  117. data/test/ft_44b_restore.rb +88 -22
  118. data/test/ft_45_citerator.rb +57 -11
  119. data/test/ft_49_condition.rb +4 -2
  120. data/test/ft_4_misc.rb +24 -3
  121. data/test/ft_50_xml_attribute.rb +17 -20
  122. data/test/ft_54_listen.rb +1 -1
  123. data/test/ft_54b_listen.rb +2 -2
  124. data/test/ft_56_timeout.rb +8 -1
  125. data/test/ft_57_a.rb +10 -10
  126. data/test/ft_59_ps.rb +49 -16
  127. data/test/ft_60_ecancel.rb +52 -10
  128. data/test/ft_63_pause.rb +8 -8
  129. data/test/ft_65_stringlaunch.rb +4 -6
  130. data/test/ft_67_schedlaunch.rb +4 -4
  131. data/test/ft_69_cancelmissing.rb +4 -2
  132. data/test/ft_70_lookupvar.rb +2 -2
  133. data/test/ft_72_lookup_processes.rb +2 -2
  134. data/test/ft_73_cancel_sub.rb +8 -8
  135. data/test/ft_77_segments.rb +38 -0
  136. data/test/ft_78_eval.rb +154 -0
  137. data/test/ft_79_tticket.rb +185 -0
  138. data/test/ft_80_spname.rb +95 -0
  139. data/test/ft_81_exp.rb +64 -0
  140. data/test/ft_82_trecu.rb +48 -0
  141. data/test/ft_83_badpause.rb +62 -0
  142. data/test/ft_84_updateexp.rb +125 -0
  143. data/test/ft_9b_cursor.rb +105 -0
  144. data/test/ft_tests.rb +14 -1
  145. data/test/hash_test.rb +7 -7
  146. data/test/hparticipant_test.rb +4 -4
  147. data/test/lookup_vf_test.rb +94 -0
  148. data/test/misc_test.rb +5 -3
  149. data/test/orest_test.rb +4 -3
  150. data/test/param_test.rb +12 -16
  151. data/test/participant_test.rb +36 -0
  152. data/test/pending.rb +10 -10
  153. data/test/rake_ltest.rb +1 -10
  154. data/test/rake_qtest.rb +7 -6
  155. data/test/raw_prog_test.rb +89 -121
  156. data/test/restart_cron_test.rb +84 -36
  157. data/test/restart_paused_test.rb +100 -0
  158. data/test/restart_sleep_test.rb +1 -1
  159. data/test/restart_tests.rb +1 -0
  160. data/test/restart_when_test.rb +33 -22
  161. data/test/ruby_procdef_test.rb +19 -18
  162. data/test/sec_test.rb +74 -35
  163. data/test/storage_test.rb +44 -0
  164. data/test/test.rb +3 -0
  165. data/test/timeout_test.rb +7 -18
  166. data/test/wfid_test.rb +2 -1
  167. data/test/wi_test.rb +29 -18
  168. metadata +121 -57
  169. data/lib/openwfe/expressions/raw_xml.rb +0 -176
  170. data/lib/openwfe/expressions/simplerep.rb +0 -266
  171. data/lib/openwfe/util/kotoba.rb +0 -236
  172. data/lib/openwfe/util/lru.rb +0 -171
  173. data/lib/openwfe/util/otime.rb +0 -246
  174. data/lib/openwfe/util/safe.rb +0 -160
  175. data/lib/openwfe/util/scheduler.rb +0 -1158
  176. data/test/cron_test.rb +0 -113
  177. data/test/cronline_test.rb +0 -60
  178. data/test/dollar_test.rb +0 -90
  179. data/test/kotoba_test.rb +0 -72
  180. data/test/lru_test.rb +0 -79
  181. data/test/safely_test.rb +0 -84
  182. data/test/scheduler_1_test.rb +0 -88
  183. data/test/scheduler_test.rb +0 -363
  184. data/test/time_test.rb +0 -84
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,9 @@ module OpenWFE
52
52
 
53
53
  names :define, :process_definition, :workflow_definition
54
54
 
55
+ #
56
+ # A pointer to the body expression of this process definition.
57
+ #
55
58
  attr_accessor :body_fei
56
59
 
57
60
  #--
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -85,7 +83,7 @@ module OpenWFE
85
83
 
86
84
  if tag
87
85
  #OpenWFE::call_in_thread(fei.expression_name, self) do
88
- process_tag(tag)
86
+ process_tag tag
89
87
  #end
90
88
 
91
89
  undo_self = tag.fei.ancestor_of?(@fei)
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -48,10 +48,61 @@ require 'openwfe/expressions/flowexpression'
48
48
 
49
49
  module OpenWFE
50
50
 
51
+ #
52
+ # A Mixin shared by CompareExpression and DefinedExpression.
53
+ #
54
+ module LookupMixin
55
+
56
+ protected
57
+
58
+ def lookup_var_value (workitem, suffix=nil)
59
+
60
+ v = lookup_var workitem, suffix
61
+
62
+ return lookup_variable(v) if v
63
+
64
+ nil
65
+ end
66
+
67
+ def lookup_field_value (workitem, suffix=nil)
68
+
69
+ f = lookup_field workitem, suffix
70
+
71
+ return workitem.attributes[f] if f
72
+
73
+ nil
74
+ end
75
+
76
+ def lookup_var (workitem, suffix=nil)
77
+
78
+ do_lookup workitem, suffix, [ :variable, :var, :v ]
79
+ end
80
+
81
+ def lookup_field (workitem, suffix=nil)
82
+
83
+ do_lookup workitem, suffix, [ :field, :f ]
84
+ end
85
+
86
+ def do_lookup (workitem, suffix, atts)
87
+
88
+ atts.each do |a|
89
+ a = a.to_s + '-' + suffix if suffix
90
+ v = lookup_string_attribute a, workitem
91
+ return v if v
92
+ end
93
+
94
+ nil
95
+ end
96
+ end
97
+
51
98
  #
52
99
  # A parent class for the 'equals' expression.
53
100
  #
101
+ # (there should be a 'greater-than' and a 'lesser-than' expression,
102
+ # but there are not that needed for now).
103
+ #
54
104
  class ComparisonExpression < FlowExpression
105
+ include LookupMixin
55
106
 
56
107
  def apply (workitem)
57
108
 
@@ -85,7 +136,7 @@ module OpenWFE
85
136
  value_a = lookup_value workitem
86
137
  value_b = lookup_value workitem, :prefix => 'other'
87
138
 
88
- value_c = lookup_variable_or_field workitem
139
+ value_c = lookup_variable_or_field_value workitem
89
140
 
90
141
  if not value_a and value_b
91
142
  value_a = value_c
@@ -100,20 +151,65 @@ module OpenWFE
100
151
  # Returns the value pointed at by the variable attribute or by
101
152
  # the field attribute, in that order.
102
153
  #
103
- def lookup_variable_or_field (workitem)
104
-
105
- v = lookup_string_attribute :variable, workitem
106
- return lookup_variable(v) if v
107
-
108
- f = lookup_string_attribute :field, workitem
109
- return workitem.attributes[f] if f
154
+ def lookup_variable_or_field_value (workitem)
110
155
 
111
- nil
156
+ lookup_var_value(workitem) || lookup_field_value(workitem)
112
157
  end
113
158
  end
114
159
 
115
160
  #
116
- # <equals value="x" other-value="y"/>
161
+ # The 'equals' expression compares two values. If those values are equal,
162
+ # the field (attribute) of the workitem named '__result__' will be
163
+ # set to true (else false).
164
+ #
165
+ # Usually, this expression is used within the 'if' expression.
166
+ #
167
+ # <if>
168
+ # <equals field-value="customer_name" other-value="Dupont" />
169
+ # <!-- then -->
170
+ # <participant ref="special_salesman" />
171
+ # <!-- else -->
172
+ # <participant ref="ordinary_salesman" />
173
+ # </if>
174
+ #
175
+ # (The 'if' expression reads the '__result__' field to route the flow
176
+ # either towards the then branch, either towards the else one).
177
+ #
178
+ #
179
+ # With a Ruby process definition, a variation on the same 'equals' :
180
+ #
181
+ # equals :field_value => "phone", :other_value => "090078367"
182
+ # equals :field_val => "phone", :other_value => "090078367"
183
+ # equals :f_value => "phone", :other_value => "090078367"
184
+ # equals :f_val => "phone", :other_value => "090078367"
185
+ # equals :f_val => "phone", :other_val => "090078367"
186
+ #
187
+ # Thus, note that 'variable' in an expression attribute can be
188
+ # shortened to 'var' or 'v'. 'value' can be shortened to 'val' and
189
+ # 'field' to 'f'.
190
+ #
191
+ # Usually, the "test" attribute of the "if" expression is preferred
192
+ # over this 'equals' expression, like in :
193
+ #
194
+ # <if test="${f:customer_name} == Dupont">
195
+ # <!-- then -->
196
+ # <participant ref="special_salesman" />
197
+ # <!-- else -->
198
+ # <participant ref="ordinary_salesman" />
199
+ # </if>
200
+ #
201
+ # Another shortcut : the 'participant' and the 'subprocess' expressions
202
+ # accept an optional 'if' (or 'unless') attribute, so that ifs can be
203
+ # contracted to :
204
+ #
205
+ # participant :ref => "toto", :if => "${f:customer_name} == Alfred"
206
+ # subprocess :ref => "special_delivery", :if => "'${f:special}' != ''"
207
+ #
208
+ # This also works with the implicit form of the participant and the
209
+ # subprocess :
210
+ #
211
+ # toto :if => "${f:customer_name} == Alfred"
212
+ # special_delivery :if => "'${f:special}' != ''"
117
213
  #
118
214
  class EqualsExpression < ComparisonExpression
119
215
 
@@ -122,37 +218,52 @@ module OpenWFE
122
218
  protected
123
219
 
124
220
  def compare (a, b)
125
- #ldebug { "compare() #{fei.to_debug_s}" }
126
- #ldebug { "compare() '#{a}' == '#{b}'" }
127
- return a == b
221
+
222
+ (a == b)
128
223
  end
129
224
  end
130
225
 
131
226
  #
132
227
  # This expression class actually implements 'defined' and 'undefined'.
133
228
  #
229
+ # They are some kind of 'equals' for validating the presence or not
230
+ # of a variable or a workitem field (attribute).
231
+ #
232
+ # <if>
233
+ # <defined field="customer">
234
+ # <!-- then -->
235
+ # <subprocess ref="call_customer" />
236
+ # </if>
237
+ #
238
+ # Since OpenWFEru 0.9.17, 'defined' and 'undefined' can be easily replaced
239
+ # by the "is [not ]set" suffix in the dollar notation :
240
+ #
241
+ # <if test="${f:customer_name} is set">
242
+ # <!-- then -->
243
+ # <subprocess ref="call_customer" />
244
+ # </if>
245
+ #
134
246
  class DefinedExpression < FlowExpression
247
+ include LookupMixin
135
248
 
136
249
  names :defined, :undefined
137
250
 
138
251
  def apply (workitem)
139
252
 
140
- fname = lookup_string_attribute(:field_value, workitem)
141
- fname = lookup_string_attribute(:field, workitem) unless fname
253
+ fname = lookup_field(workitem, 'value') || lookup_field(workitem)
142
254
 
143
255
  fmatch = lookup_string_attribute(:field_match, workitem)
144
256
 
145
- vname = lookup_string_attribute(:variable_value, workitem)
146
- vname = lookup_string_attribute(:variable, workitem) unless vname
257
+ vname = lookup_var(workitem, 'value') || lookup_var(workitem)
147
258
 
148
259
  result = if fname
149
- workitem.has_attribute? fname
260
+ workitem.has_attribute?(fname)
150
261
  elsif vname
151
262
  lookup_variable(vname) != nil
152
263
  elsif fmatch
153
264
  field_match?(workitem, fmatch)
154
265
  else
155
- false
266
+ false # when in doubt, say 'no' (even when 'undefined' ?)
156
267
  end
157
268
 
158
269
  result = ( ! result) \
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -155,10 +155,34 @@ module OpenWFE
155
155
 
156
156
  def apply workitem
157
157
 
158
- text = fetch_text_content workitem
158
+ #text = fetch_text_content workitem
159
+ #text = text.strip
160
+ #result = if text[0, 3] == "---"
161
+ # YAML.load text
162
+ #else
163
+ # d = REXML::Document.new text
164
+ # XmlCodec::decode_attribute d.root
165
+ #end
166
+
167
+ child = @children.first
168
+
169
+ text = if child.is_a?(String)
170
+
171
+ child
172
+
173
+ elsif child.is_a?(FlowExpressionId)
174
+
175
+ exp = get_expression_pool.fetch_expression child
176
+ ExpressionTree.to_s exp.raw_representation
177
+
178
+ else
179
+
180
+ child.to_s
181
+ end
182
+
159
183
  text = text.strip
160
184
 
161
- result = if text[0, 3] == "---"
185
+ result = if text[0, 3] == '---'
162
186
  YAML.load text
163
187
  else
164
188
  d = REXML::Document.new text
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -134,7 +134,7 @@ module OpenWFE
134
134
  store_itself
135
135
 
136
136
  get_expression_pool.launch_template(
137
- self, @iterator.index, @children[0], workitem, vars)
137
+ self, nil, @iterator.index, @children[0], workitem, vars)
138
138
  end
139
139
  end
140
140
 
@@ -173,10 +173,17 @@ module OpenWFE
173
173
 
174
174
  @iteration_index = 0
175
175
 
176
- raw_list = iterator_expression.lookup_vf_attribute(
177
- workitem, :value, :prefix => :on)
176
+ #raw_list = iterator_expression.lookup_vf_attribute(
177
+ # workitem, :value, :prefix => :on)
178
+ #raw_list ||= iterator_expression.lookup_attribute(:on, workitem)
178
179
 
179
- @iteration_list = extract_iteration_list(raw_list)
180
+ raw_list =
181
+ iterator_expression.lookup_vf_attribute(
182
+ workitem, :value, :prefix => :on) ||
183
+ iterator_expression.lookup_vf_attribute(
184
+ workitem, nil, :prefix => :on)
185
+
186
+ @iteration_list = extract_iteration_list raw_list
180
187
 
181
188
  workitem.attributes[ITERATOR_COUNT] = @iteration_list.length
182
189
  end
@@ -283,7 +290,7 @@ module OpenWFE
283
290
  if is_suitable_list?(raw_list)
284
291
  raw_list
285
292
  else
286
- extract_list_from_string(raw_list.to_s)
293
+ extract_list_from_string raw_list.to_s
287
294
  end
288
295
  end
289
296
 
@@ -304,7 +311,7 @@ module OpenWFE
304
311
  #
305
312
  def extract_list_from_string (s)
306
313
 
307
- s.split(@value_separator)
314
+ s.split @value_separator
308
315
  end
309
316
  end
310
317
 
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -300,7 +300,12 @@ module OpenWFE
300
300
  parent = @once ? self : nil
301
301
 
302
302
  get_expression_pool.launch_template(
303
- parent, @call_count - 1, @children[0], workitem, nil)
303
+ parent,
304
+ nil,
305
+ @call_count - 1,
306
+ @children[0],
307
+ workitem,
308
+ nil)
304
309
  else
305
310
  #
306
311
  # 'blocking listen'
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,9 @@
37
37
  # John Mettraux at openwfe.org
38
38
  #
39
39
 
40
- require 'openwfe/util/safe'
40
+ require 'rufus/eval'
41
41
  require 'openwfe/expressions/flowexpression'
42
+ require 'openwfe/expressions/value'
42
43
 
43
44
 
44
45
  module OpenWFE
@@ -65,14 +66,13 @@ module OpenWFE
65
66
  # OpenWFEru test suite uses this expression).
66
67
  #
67
68
  class PrintExpression < FlowExpression
69
+ include ValueMixin
68
70
 
69
71
  names :print
70
72
 
71
- def apply (workitem)
72
-
73
- escape = lookup_boolean_attribute('escape', workitem, false)
73
+ def reply (workitem)
74
74
 
75
- text = fetch_text_content workitem, escape
75
+ text = workitem.get_result.to_s
76
76
  text << "\n"
77
77
 
78
78
  tracer = @application_context['__tracer']
@@ -123,7 +123,15 @@ module OpenWFE
123
123
  # Don't embed too much Ruby into your process definitions, it might
124
124
  # hurt...
125
125
  #
126
+ # Reval can also be used with the 'code' attribute (or 'field-code' or
127
+ # 'variable-code') :
128
+ #
129
+ # <reval field-code="f0" />
130
+ #
131
+ # to eval the Ruby code held in the field named "f0".
132
+ #
126
133
  class RevalExpression < FlowExpression
134
+ include ValueMixin
127
135
 
128
136
  names :reval
129
137
 
@@ -131,25 +139,23 @@ module OpenWFE
131
139
  # See for an explanation on Ruby safety levels :
132
140
  # http://www.rubycentral.com/book/taint.html
133
141
  #
142
+ # 'reval' is entitled a safe level of 3.
143
+ #
134
144
  SAFETY_LEVEL = 3
135
145
 
136
- def apply (workitem)
146
+
147
+ def reply (workitem)
137
148
 
138
149
  raise "evaluation of ruby code is not allowed" \
139
150
  if @application_context[:ruby_eval_allowed] != true
140
151
 
141
- escape = lookup_boolean_attribute('escape', workitem, false)
142
-
143
- code = lookup_vf_attribute(workitem, 'code')
144
-
145
- code = fetch_text_content(workitem, escape) \
146
- unless code
147
-
152
+ code = lookup_vf_attribute(workitem, 'code') || workitem.get_result
148
153
  code = code.to_s
149
154
 
150
- wi = workitem
155
+ wi = workitem
156
+ # so that the ruby code being evaluated sees 'wi' and 'workitem'
151
157
 
152
- result = OpenWFE::eval_safely code, SAFETY_LEVEL, binding()
158
+ result = Rufus::eval_safely code, SAFETY_LEVEL, binding()
153
159
 
154
160
  workitem.set_result(result) \
155
161
  if result != nil # 'false' is a valid result
@@ -158,6 +164,168 @@ module OpenWFE
158
164
  end
159
165
  end
160
166
 
167
+ #
168
+ # An advanced expression : it takes the value in a field or variable (or
169
+ # the nested value) and evaluates it as a process definition.
170
+ #
171
+ # sequence
172
+ # set :field => "code", :value => "<print>hello 0</print>"
173
+ # _eval :field_def => "code"
174
+ # set :field => "code", :value => "_print 'hello 1'"
175
+ # _eval :field_def => "code"
176
+ # end
177
+ #
178
+ # will print "hello0\nhello1".
179
+ #
180
+ # This expression can be useful for evaluating process definition snippets
181
+ # coming from participants directly.
182
+ #
183
+ # It's also dangerous. This 'eval' expression will raise an error if
184
+ # the parameter :dynamic_eval_allowed in the engine's application context
185
+ # is not set to true.
186
+ #
187
+ class EvalExpression < FlowExpression
188
+ include ValueMixin
189
+
190
+ names :eval
191
+
192
+
193
+ def reply (workitem)
194
+
195
+ raise "dynamic evaluation of process definitions is not allowed" \
196
+ if @application_context[:dynamic_eval_allowed] != true
197
+
198
+ df = lookup_vf_attribute(workitem, 'def') || workitem.get_result
199
+
200
+ return reply_to_parent(workitem) unless df
201
+ #
202
+ # currently, 'nothing to eval' means, 'just go on'
203
+
204
+ ldebug { "apply() def is >#{df}<" }
205
+
206
+ raw_expression = build_raw_expression df
207
+
208
+ #puts
209
+ #puts "======================================"
210
+ #puts raw_expression.to_s
211
+ #puts raw_expression.raw_representation
212
+ #puts "======================================"
213
+ #puts
214
+
215
+ raw_expression.apply workitem
216
+ end
217
+
218
+ protected
219
+
220
+ def build_raw_expression (df)
221
+
222
+ procdf = get_expression_pool.determine_rep df
223
+
224
+ RawExpression.new_raw(
225
+ fei, parent_id, environment_id, application_context, procdf)
226
+ end
227
+ end
228
+
229
+ #
230
+ # Some kind of limited 'eval' expression.
231
+ #
232
+ # Here is an usage example :
233
+ #
234
+ # class ExampleDef < OpenWFE::ProcessDefinition
235
+ #
236
+ # sequence do
237
+ #
238
+ # exp :name => "p0"
239
+ # exp :name => "sub0"
240
+ #
241
+ # exp :name => "sequence" do
242
+ # p0
243
+ # sub0
244
+ # end
245
+ #
246
+ # set :var => "a", :value => { "ref" => "p0" }
247
+ # exp :name => "participant", :variable_attributes => "a"
248
+ # end
249
+ #
250
+ # process_definition :name => "sub0" do
251
+ # _print "sub0"
252
+ # end
253
+ # end
254
+ #
255
+ # This example is a bit static, but the point is that the 'exp'
256
+ # is extracting the real expression name (or participant or subprocess
257
+ # name) from its 'name' attribute.
258
+ #
259
+ # The 'eval' expression is about evaluating a complete process definition
260
+ # branch, 'exp' is only about one node in the process definition.
261
+ #
262
+ class ExpExpression < RawExpression
263
+
264
+ names :exp
265
+
266
+ #--
267
+ #def initialize (fei, parent_id, env_id, app_context, att)
268
+ # #
269
+ # # this responds to the FlowExpression constructor...
270
+ # super fei, parent_id, env_id, app_context, nil
271
+ # #
272
+ # # but this triggers the RawExpression constructor :)
273
+ # @attributes = att
274
+ # #
275
+ # # as this is not done by the RawExpression constructor
276
+ #end
277
+ #++
278
+
279
+ def apply (workitem)
280
+
281
+ @applied_workitem = workitem
282
+
283
+ super
284
+ end
285
+
286
+ protected
287
+
288
+ #
289
+ # Evaluates the 'name' attribute, if it's not present or empty,
290
+ # will return the value for the 'default' attribute.
291
+ #
292
+ def expression_name
293
+
294
+ n = lookup_attribute(:name, @applied_workitem)
295
+
296
+ return lookup_attribute(:default, @applied_workitem) \
297
+ if (not n) or (n.strip == '')
298
+
299
+ n
300
+ end
301
+
302
+ #
303
+ # If the 'attributes' attribute is present, will return its
304
+ # value. Else, will simply return the attributes of the 'exp'
305
+ # expression itself ('name' and 'default' included).
306
+ #
307
+ def extract_attributes
308
+
309
+ att = lookup_vf_attribute @applied_workitem, :attributes
310
+ # will currently only work with an attribute hash
311
+ # whose keys are strings... symbols :(
312
+
313
+ att || @attributes
314
+ end
315
+
316
+ def extract_descriptions
317
+ []
318
+ end
319
+
320
+ def extract_children
321
+ @children
322
+ end
323
+
324
+ def extract_parameters
325
+ []
326
+ end
327
+ end
328
+
161
329
  #
162
330
  # This expression simply emits a message to the application
163
331
  # log (by default logs/openwferu.log).
@@ -184,14 +352,13 @@ module OpenWFE
184
352
  # 'fatal'.
185
353
  #
186
354
  class LogExpression < FlowExpression
355
+ include ValueMixin
187
356
 
188
357
  names :log
189
358
 
190
- def apply (workitem)
359
+ def reply (workitem)
191
360
 
192
- escape = lookup_boolean_attribute('escape', workitem, false)
193
- text = fetch_text_content(workitem, escape)
194
- text = lookup_attribute('message', workitem) unless text
361
+ text = lookup_attribute('message', workitem) || workitem.get_result
195
362
 
196
363
  level = lookup_attribute('level', workitem)
197
364
  level = level.downcase.to_sym if level