openwferu 0.9.13 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/examples/bigflow.rb +19 -0
  2. data/examples/csv_weather.rb +23 -0
  3. data/examples/engine_template.rb +7 -0
  4. data/lib/openwfe/contextual.rb +0 -2
  5. data/lib/openwfe/engine/engine.rb +137 -34
  6. data/lib/openwfe/engine/file_persisted_engine.rb +0 -5
  7. data/lib/openwfe/exceptions.rb +0 -2
  8. data/lib/openwfe/expool/errorjournal.rb +83 -7
  9. data/lib/openwfe/expool/expressionpool.rb +279 -60
  10. data/lib/openwfe/expool/expstorage.rb +7 -6
  11. data/lib/openwfe/expool/yamlexpstorage.rb +17 -14
  12. data/lib/openwfe/expressions/condition.rb +10 -7
  13. data/lib/openwfe/expressions/environment.rb +11 -1
  14. data/lib/openwfe/expressions/fe_command.rb +14 -1
  15. data/lib/openwfe/expressions/fe_cron.rb +29 -14
  16. data/lib/openwfe/expressions/fe_define.rb +26 -1
  17. data/lib/openwfe/expressions/fe_iterator.rb +2 -0
  18. data/lib/openwfe/expressions/fe_losfor.rb +20 -15
  19. data/lib/openwfe/expressions/fe_misc.rb +0 -2
  20. data/lib/openwfe/expressions/fe_participant.rb +78 -24
  21. data/lib/openwfe/expressions/fe_reserve.rb +0 -2
  22. data/lib/openwfe/expressions/fe_sleep.rb +0 -4
  23. data/lib/openwfe/expressions/fe_subprocess.rb +34 -0
  24. data/lib/openwfe/expressions/fe_value.rb +46 -4
  25. data/lib/openwfe/expressions/fe_wait.rb +0 -2
  26. data/lib/openwfe/expressions/flowexpression.rb +39 -9
  27. data/lib/openwfe/expressions/raw.rb +73 -48
  28. data/lib/openwfe/expressions/raw_prog.rb +45 -15
  29. data/lib/openwfe/expressions/simplerep.rb +54 -7
  30. data/lib/openwfe/expressions/time.rb +5 -2
  31. data/lib/openwfe/expressions/timeout.rb +0 -2
  32. data/lib/openwfe/flowexpressionid.rb +26 -2
  33. data/lib/openwfe/participants/enoparticipants.rb +6 -1
  34. data/lib/openwfe/participants/participant.rb +0 -2
  35. data/lib/openwfe/participants/participantmap.rb +21 -7
  36. data/lib/openwfe/participants/participants.rb +29 -0
  37. data/lib/openwfe/rest/exception.rb +0 -2
  38. data/lib/openwfe/storage/yamlfilestorage.rb +4 -1
  39. data/lib/openwfe/util/dollar.rb +0 -2
  40. data/lib/openwfe/util/lru.rb +0 -2
  41. data/lib/openwfe/util/observable.rb +1 -1
  42. data/lib/openwfe/util/scheduler.rb +4 -4
  43. data/lib/openwfe/util/schedulers.rb +0 -2
  44. data/lib/openwfe/util/workqueue.rb +34 -91
  45. data/lib/openwfe/utils.rb +35 -28
  46. data/lib/openwfe/version.rb +1 -1
  47. data/lib/openwfe/workitem.rb +1 -1
  48. data/test/clone_test.rb +51 -0
  49. data/test/concurrence_test.rb +78 -0
  50. data/test/cron_test_2.rb +50 -0
  51. data/test/flowtestbase.rb +40 -12
  52. data/test/ft_21_cron.rb +32 -6
  53. data/test/ft_26_load.rb +8 -2
  54. data/test/ft_26c_load.rb +19 -0
  55. data/test/ft_27_getflowpos.rb +4 -4
  56. data/test/ft_2_concurrence.rb +14 -9
  57. data/test/ft_32_journal.rb +1 -1
  58. data/test/ft_32c_journal.rb +3 -2
  59. data/test/ft_32d_journal.rb +2 -1
  60. data/test/ft_34_cancelwfid.rb +7 -3
  61. data/test/ft_35_localdefs.rb +13 -0
  62. data/test/ft_38_tag.rb +8 -6
  63. data/test/ft_49_condition.rb +7 -1
  64. data/test/ft_55_ptimeout.rb +13 -14
  65. data/test/ft_57_a.rb +17 -0
  66. data/test/ft_58_ejournal.rb +3 -3
  67. data/test/ft_59_ps.rb +6 -6
  68. data/test/ft_60_ecancel.rb +3 -5
  69. data/test/ft_61_elsub.rb +2 -4
  70. data/test/ft_63_pause.rb +122 -0
  71. data/test/ft_64_alias.rb +102 -0
  72. data/test/ft_64_clone.rb +69 -0
  73. data/test/ft_65_stringlaunch.rb +61 -0
  74. data/test/ft_66_subforget.rb +70 -0
  75. data/test/ft_67_schedlaunch.rb +102 -0
  76. data/test/ft_68_ifparticipant.rb +70 -0
  77. data/test/ft_69_cancelmissing.rb +49 -0
  78. data/test/ft_6_lambda.rb +23 -3
  79. data/test/ft_70_lookupvar.rb +55 -0
  80. data/test/ft_7_lose.rb +1 -1
  81. data/test/ft_tests.rb +10 -1
  82. data/test/hparticipant_test.rb +6 -6
  83. data/test/param_test.rb +1 -1
  84. data/test/{rake_test.rb → rake_ltest.rb} +9 -2
  85. data/test/rake_qtest.rb +3 -1
  86. data/test/raw_prog_test.rb +11 -3
  87. data/test/restart_sleep_test.rb +44 -6
  88. data/test/ruby_procdef_test.rb +129 -0
  89. data/test/rutest_utils.rb +1 -0
  90. data/test/sec_test.rb +3 -3
  91. metadata +19 -4
@@ -29,6 +29,7 @@
29
29
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
+ #
32
33
 
33
34
  #
34
35
  # "made in Japan"
@@ -100,6 +101,8 @@ module OpenWFE
100
101
  def delete (key)
101
102
  synchronize do
102
103
 
104
+ ldebug { "#{fei.to_debug_s} delete() '#{key}'" }
105
+
103
106
  @variables.delete key
104
107
  store_itself()
105
108
  end
@@ -113,13 +116,18 @@ module OpenWFE
113
116
  #
114
117
  def unbind ()
115
118
 
119
+ #ldebug { "unbind() for #{fei.to_s}" }
120
+
116
121
  @variables.each do |key, value|
117
122
 
118
123
  #ldebug { "unbind() '#{key}' => #{value.class}" }
119
124
 
120
125
  if value.kind_of? FlowExpressionId
126
+
121
127
  get_expression_pool().remove(value)
128
+
122
129
  elsif value.kind_of? FlowExpression
130
+
123
131
  value.cancel
124
132
  end
125
133
  end
@@ -129,7 +137,8 @@ module OpenWFE
129
137
  # Returns true if this environment is the engine environment
130
138
  #
131
139
  def is_engine_environment?
132
- return @fei == get_expression_pool().engine_environment_id
140
+
141
+ (@fei == get_expression_pool().engine_environment_id)
133
142
  end
134
143
 
135
144
  #
@@ -137,6 +146,7 @@ module OpenWFE
137
146
  # for the Schedulable aspect of an environment expression.
138
147
  #
139
148
  def trigger (params)
149
+
140
150
  raise "an environment should never get directly triggered"
141
151
  end
142
152
 
@@ -38,7 +38,6 @@
38
38
  #
39
39
 
40
40
  require 'openwfe/expressions/condition'
41
- #require 'openwfe/expressions/flowexpression'
42
41
 
43
42
 
44
43
  module OpenWFE
@@ -193,6 +192,20 @@ module OpenWFE
193
192
  # buy_stuff
194
193
  # end
195
194
  #
195
+ # The 'rif' attribute may be used instead of the 'if' attribute. Its value
196
+ # is some ruby code that, when evaluating to true will let the command
197
+ # be executed.
198
+ #
199
+ # _skip 2, :rif => "workitem.customers.size % 2 == 0"
200
+ # #
201
+ # # skips if the nb of customers is pair
202
+ #
203
+ # Note that the 'rif' attribute will work only if the
204
+ # <tt>:ruby_eval_allowed</tt> parameter is set to true in the engine's
205
+ # application context.
206
+ #
207
+ # engine.application_context[:ruby_eval_allowed] = true
208
+ #
196
209
  class CursorCommandExpression < FlowExpression
197
210
  include CommandConstants
198
211
  include ConditionMixin
@@ -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"
@@ -39,7 +37,6 @@
39
37
  # John Mettraux at openwfe.org
40
38
  #
41
39
 
42
- #require 'openwfe/rudefinitions'
43
40
  require 'openwfe/utils'
44
41
  require 'openwfe/util/otime'
45
42
  require 'openwfe/util/scheduler'
@@ -65,12 +62,22 @@ module OpenWFE
65
62
  # engine is a persisted one, the cron will continue when the engine
66
63
  # restarts).
67
64
  #
65
+ # Since OpenWFEru 0.9.14, it's possible to specify 'every' instead of
66
+ # 'tab' :
67
+ #
68
+ # cron :every => "10m3s" do
69
+ # send_reminder
70
+ # end
71
+ #
72
+ # The subprocess 'send_reminder' will thus be triggered every ten minutes
73
+ # and three seconds.
74
+ #
68
75
  class CronExpression < TimeExpression
69
76
 
70
77
  names :cron
71
78
 
72
79
  attr_accessor \
73
- :raw_child, :tab, :name, :counter
80
+ :raw_child, :tab, :every, :name, :counter
74
81
 
75
82
  def apply (workitem)
76
83
 
@@ -85,7 +92,10 @@ module OpenWFE
85
92
  @applied_workitem.flow_expression_id = nil
86
93
 
87
94
  @tab = lookup_attribute(:tab, workitem)
95
+ @every = lookup_attribute(:every, workitem)
96
+
88
97
  @name = lookup_attribute(:name, workitem)
98
+ @name = fei.to_s unless @name
89
99
 
90
100
  @raw_child, _fei = get_expression_pool.fetch(@children[0])
91
101
  @raw_child.parent_id = nil
@@ -104,7 +114,7 @@ module OpenWFE
104
114
  # (have to do it after the reschedule, so that the schedule
105
115
  # info is stored within the variable)
106
116
 
107
- set_variable(@name, self) if @name
117
+ set_variable(@name, self)
108
118
 
109
119
  #
110
120
  # resume flow
@@ -122,13 +132,11 @@ module OpenWFE
122
132
  # implemented in parent TimeExpression class
123
133
 
124
134
  #
125
- # This is the method called each time, the scheduler triggers
135
+ # This is the method called each time the scheduler triggers
126
136
  # this cron. The contained segment of process will get
127
137
  # executed.
128
138
  #
129
139
  def trigger (params)
130
- #
131
- # launch raw child
132
140
 
133
141
  ldebug { "trigger() cron : #{@fei.to_debug_s}" }
134
142
 
@@ -144,7 +152,7 @@ module OpenWFE
144
152
 
145
153
  @counter += 1
146
154
 
147
- set_variable(@name, self) if @name
155
+ #set_variable(@name, self)
148
156
 
149
157
  rescue
150
158
  lerror do
@@ -166,12 +174,19 @@ module OpenWFE
166
174
  @scheduler_job_id = @name.dup
167
175
 
168
176
  @scheduler_job_id = "#{@fei.wfid}__#{@scheduler_job_id}" \
169
- if not OpenWFE::starts_with(@name, "//")
170
-
171
- get_scheduler.schedule(
172
- @tab,
173
- { :schedulable => self, :job_id => @scheduler_job_id })
177
+ unless OpenWFE::starts_with(@name, "//")
178
+
179
+ if @tab
180
+ get_scheduler.schedule(
181
+ @tab,
182
+ { :schedulable => self, :job_id => @scheduler_job_id })
183
+ else
184
+ get_scheduler.schedule_every(
185
+ @every,
186
+ { :schedulable => self, :job_id => @scheduler_job_id })
187
+ end
174
188
 
189
+ ldebug { "reschedule() name is '#{@name}'" }
175
190
  ldebug { "reschedule() job id is '#{@scheduler_job_id}'" }
176
191
 
177
192
  #store_itself()
@@ -29,6 +29,7 @@
29
29
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
+ #
32
33
 
33
34
  #
34
35
  # "made in Japan"
@@ -61,8 +62,10 @@ module OpenWFE
61
62
  def evaluate (workitem)
62
63
 
63
64
  @eval_only = true
65
+
64
66
  apply workitem
65
- return @body_fei
67
+
68
+ @body_fei
66
69
  end
67
70
 
68
71
  #
@@ -86,6 +89,28 @@ module OpenWFE
86
89
  get_expression_pool.apply fei, workitem
87
90
  end
88
91
 
92
+ #
93
+ # Overrides the set_variable in FlowExpression to
94
+ # make sure to intercept requests for binding subprocesses
95
+ # at the engine level and to store a copy of the raw expression,
96
+ # not only the flow expression id.
97
+ #
98
+ def set_variable (name, fei)
99
+
100
+ if name[0, 2] == "//"
101
+
102
+ raw_exp = get_expression_pool.fetch_expression(fei).dup
103
+ raw_exp.parent_id = nil
104
+ raw_exp.fei = raw_exp.fei.dup
105
+ fei = raw_exp.fei
106
+ fei.wfid = get_wfid_generator.generate
107
+
108
+ raw_exp.store_itself
109
+ end
110
+
111
+ super name, fei
112
+ end
113
+
89
114
  protected
90
115
 
91
116
  def get_to_next_child
@@ -71,6 +71,8 @@ module OpenWFE
71
71
  # end
72
72
  # end
73
73
  #
74
+ # For more information about those commands, see CursorCommandExpression.
75
+ #
74
76
  class IteratorExpression < WithTemplateExpression
75
77
  include CommandMixin
76
78
 
@@ -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"
@@ -47,8 +45,15 @@ module OpenWFE
47
45
  #
48
46
  # Triggers the first (and supposedly unique child of this expression)
49
47
  # but never wait for its reply (lose it).
48
+ #
50
49
  # A 'lose' expression never replies to its parent expression.
51
50
  #
51
+ # <lose>
52
+ # <participant ref="toto" />
53
+ # </lose>
54
+ #
55
+ # Useful only some special process cases.
56
+ #
52
57
  class LoseExpression < FlowExpression
53
58
 
54
59
  names :lose
@@ -77,23 +82,23 @@ module OpenWFE
77
82
 
78
83
  wi = workitem.dup
79
84
 
80
- Thread.new do
81
- begin
85
+ #Thread.new do
86
+ #begin
82
87
 
83
- child = @children[0]
84
- get_expression_pool.forget(self, child)
85
- get_expression_pool.apply(child, wi)
88
+ child = @children[0]
89
+ get_expression_pool.forget(self, child)
90
+ get_expression_pool.apply(child, wi)
86
91
 
87
- rescue Exception => e
88
- lwarn do
89
- "apply() failed to apply child to forget "+
90
- OpenWFE::exception_to_s(e)
91
- end
92
- end
93
- end
92
+ #rescue Exception => e
93
+ # lwarn do
94
+ # "apply() failed to apply child to forget "+
95
+ # OpenWFE::exception_to_s(e)
96
+ # end
97
+ #end
98
+ #end
94
99
  end
95
100
 
96
- reply_to_parent(workitem)
101
+ reply_to_parent workitem
97
102
  end
98
103
 
99
104
  def reply (workitem)
@@ -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"
@@ -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"
@@ -106,9 +104,21 @@ module OpenWFE
106
104
  # the same FlowExpressionId as the initial workitem and the participant
107
105
  # implementation is responsible for the cancel application).
108
106
  #
107
+ # The participant expression accepts an optional 'if' (or 'unless')
108
+ # attribute. It's used for conditional execution of the participant :
109
+ #
110
+ # participant :ref => "toto", :if => "${weather} == raining"
111
+ # # the participant toto will receive a workitem only if
112
+ # # it's raining
113
+ #
114
+ # boss :unless => "#{f:matter} == 'very trivial'"
115
+ # # the boss will not participate in the proces if the matter
116
+ # # is 'very trivial'
117
+ #
109
118
  class ParticipantExpression < FlowExpression
110
119
  include FilterMixin
111
120
  include TimeoutMixin
121
+ include ConditionMixin
112
122
 
113
123
  names :participant
114
124
 
@@ -118,15 +128,28 @@ module OpenWFE
118
128
 
119
129
  def apply (workitem)
120
130
 
121
- remove_timedout_flag workitem
131
+ conditional = eval_condition(:if, workitem, :unless)
122
132
 
123
- @applied_workitem = workitem.dup
133
+ if conditional == false
134
+ super_reply_to_parent workitem
135
+ return
136
+ end
124
137
 
125
138
  @participant_name = lookup_ref workitem
126
139
 
127
140
  @participant_name = fetch_text_content workitem \
128
141
  unless @participant_name
129
142
 
143
+ participant = \
144
+ get_participant_map.lookup_participant(@participant_name)
145
+
146
+ raise "No participant named '#{@participant_name}'" \
147
+ unless participant
148
+
149
+ remove_timedout_flag workitem
150
+
151
+ @applied_workitem = workitem.dup
152
+
130
153
  schedule_timeout()
131
154
 
132
155
  filter_in workitem
@@ -135,14 +158,32 @@ module OpenWFE
135
158
 
136
159
  workitem.params = lookup_attributes workitem
137
160
 
138
- get_participant_map.dispatch @participant_name, workitem
139
- get_participant_map.onotify @participant_name, :apply, workitem
140
- #
141
- # these two pmap calls were combined, but with the :reply
142
- # notification in reply_to_parent() it feels more
143
- # elegant like that
161
+ #
162
+ # threading AFTER the store_itself()
163
+ #
164
+ Thread.new do
165
+ begin
166
+
167
+ # these two pmap calls were combined, but with the :reply
168
+ # notification in reply_to_parent() it feels more
169
+ # elegant like that
170
+
171
+ get_participant_map.dispatch(
172
+ participant, @participant_name, workitem)
173
+
174
+ get_participant_map.onotify(
175
+ @participant_name, :apply, workitem)
176
+
177
+ rescue Exception => e
178
+
179
+ get_expression_pool.notify_error(
180
+ e, fei, :do_apply, workitem)
181
+ end
182
+ end
144
183
  end
145
184
 
185
+ alias :super_reply_to_parent :reply_to_parent
186
+
146
187
  def reply_to_parent (workitem)
147
188
 
148
189
  get_participant_map.onotify @participant_name, :reply, workitem
@@ -165,17 +206,9 @@ module OpenWFE
165
206
  #
166
207
  def cancel
167
208
 
168
- unschedule_timeout()
169
-
170
- wi = super()
171
-
172
- return wi unless @applied_workitem
209
+ unschedule_timeout
173
210
 
174
- #
175
- # have to cancel the workitem on the participant side
176
-
177
- cancelitem = OpenWFE::CancelItem.new(@applied_workitem)
178
- get_participant_map.dispatch(@participant_name, cancelitem)
211
+ cancel_participant
179
212
 
180
213
  nil
181
214
  end
@@ -186,7 +219,7 @@ module OpenWFE
186
219
  #
187
220
  def trigger (scheduler)
188
221
 
189
- ldebug { "trigger() timeout requested for #{@fei.to_debug_s}" }
222
+ linfo { "trigger() timeout requested for #{@fei.to_debug_s}" }
190
223
 
191
224
  begin
192
225
 
@@ -194,11 +227,11 @@ module OpenWFE
194
227
  #
195
228
  # so that cancel won't unschedule without need
196
229
 
197
- cancel()
230
+ cancel_participant
198
231
 
199
- set_timedout_flag(@applied_workitem)
232
+ set_timedout_flag @applied_workitem
200
233
 
201
- reply_to_parent(@applied_workitem)
234
+ reply_to_parent @applied_workitem
202
235
  rescue
203
236
  lerror do
204
237
  "trigger() problem while timing out\n"+
@@ -206,6 +239,27 @@ module OpenWFE
206
239
  end
207
240
  end
208
241
  end
242
+
243
+ protected
244
+
245
+ #
246
+ # Have to cancel the workitem on the participant side
247
+ #
248
+ def cancel_participant
249
+
250
+ return unless @applied_workitem
251
+ #
252
+ # if there is an applied workitem, it means there
253
+ # is a participant to cancel...
254
+
255
+ participant = \
256
+ get_participant_map.lookup_participant(@participant_name)
257
+
258
+ cancelitem = CancelItem.new(@applied_workitem)
259
+
260
+ get_participant_map.dispatch(
261
+ participant, @participant_name, cancelitem)
262
+ end
209
263
  end
210
264
 
211
265
  end
@@ -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"
@@ -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"
@@ -70,7 +68,6 @@ module OpenWFE
70
68
  :awakening_time
71
69
 
72
70
  def apply (workitem)
73
- #synchronize do
74
71
 
75
72
  sfor = lookup_attribute(:for, workitem)
76
73
  suntil = lookup_attribute(:until, workitem)
@@ -102,7 +99,6 @@ module OpenWFE
102
99
  @applied_workitem = workitem.dup
103
100
 
104
101
  reschedule(get_scheduler)
105
- #end
106
102
  end
107
103
 
108
104
  #def reply (workitem)
@@ -72,13 +72,45 @@ module OpenWFE
72
72
  # end
73
73
  # end
74
74
  #
75
+ # The 'subprocess' expression accepts a 'forget' attribute :
76
+ #
77
+ # class AnotherDefinition1 < OpenWFE::ProcessDefinition
78
+ # sequence do
79
+ # subprocess :ref => "my_subprocess", :forget => true
80
+ # participant :ref => "ringo"
81
+ # end
82
+ # process-definition :name => "my_subprocess" do
83
+ # participant :ref => "fake steve jobs"
84
+ # end
85
+ # end
86
+ #
87
+ # The 'subprocess' expression accepts an 'if' (or 'unless') attribute :
88
+ #
89
+ # subprocess :ref => "interview_process", :if => "${f:screened}"
90
+ # # will trigger the subprocess only if the field screened
91
+ # # contains the string 'true' or the boolean 'true'
92
+ #
93
+ # interview_process :if => "${f:screened}"
94
+ # # idem
95
+ #
96
+ # interview_process :unless => "${f:has_had_problem_with_justice_?}"
97
+ # # well...
98
+ #
75
99
  class SubProcessRefExpression < FlowExpression
100
+ include ConditionMixin
76
101
 
77
102
  names :subprocess
78
103
 
79
104
 
80
105
  def apply (workitem)
81
106
 
107
+ conditional = eval_condition(:if, workitem, :unless)
108
+
109
+ if conditional == false
110
+ reply_to_parent workitem
111
+ return
112
+ end
113
+
82
114
  ref = lookup_ref(workitem)
83
115
 
84
116
  raise "'subprocess' expression misses a 'ref', 'field-ref' or 'variable-ref' attribute" unless ref
@@ -106,6 +138,8 @@ module OpenWFE
106
138
 
107
139
  get_expression_pool.launch_template(
108
140
  requester, get_next_sub_id, template, workitem, params)
141
+
142
+ reply_to_parent(workitem) if forget
109
143
  end
110
144
 
111
145
  #def reply (workitem)
@@ -29,6 +29,7 @@
29
29
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
+ #
32
33
 
33
34
  #
34
35
  # "made in Japan"
@@ -43,6 +44,35 @@ require 'openwfe/expressions/flowexpression'
43
44
 
44
45
  module OpenWFE
45
46
 
47
+ #
48
+ # A small mixin providing value for looking up the attributes
49
+ # variable/var/v and field/fld/f.
50
+ #
51
+ module ValueMixin
52
+
53
+ def lookup_variable_attribute (workitem)
54
+
55
+ lookup [ "variable", "var", "v" ], workitem
56
+ end
57
+
58
+ def lookup_field_attribute (workitem)
59
+
60
+ lookup [ "field", "fld", "f" ], workitem
61
+ end
62
+
63
+ private
64
+
65
+ def lookup (name_array, workitem)
66
+
67
+ name_array.each do |n|
68
+ v = lookup_attribute(n, workitem)
69
+ return v if v
70
+ end
71
+
72
+ nil
73
+ end
74
+ end
75
+
46
76
  #
47
77
  # The 'set' expression is used to set the value of a (process) variable or
48
78
  # a (workitem) field.
@@ -58,7 +88,18 @@ module OpenWFE
58
88
  # they will be evaluated sequentially before the body gets applied
59
89
  # (executed).
60
90
  #
91
+ # Since OpenWFEru 0.9.14, shorter attributes are OK :
92
+ #
93
+ # <set f="price" val="CHF 12.00" />
94
+ # <set v="/stage" val="3" />
95
+ # <set v="/stage" field-val="f_stage" />
96
+ # <set f="stamp" val="${r:Time.now.to_i}" />
97
+ #
98
+ # set :f => "price", :val => "USD 12.50"
99
+ # set :v => "toto", :val => "elvis"
100
+ #
61
101
  class SetValueExpression < FlowExpression
102
+ include ValueMixin
62
103
 
63
104
  is_definition
64
105
 
@@ -88,8 +129,8 @@ module OpenWFE
88
129
 
89
130
  def reply (workitem)
90
131
 
91
- vkey = lookup_attribute("variable", workitem)
92
- fkey = lookup_attribute("field", workitem)
132
+ vkey = lookup_variable_attribute(workitem)
133
+ fkey = lookup_field_attribute(workitem)
93
134
 
94
135
  value = workitem.attributes[FIELD_RESULT]
95
136
 
@@ -129,13 +170,14 @@ module OpenWFE
129
170
  # unset :variable => "eval_result"
130
171
  #
131
172
  class UnsetValueExpression < FlowExpression
173
+ include ValueMixin
132
174
 
133
175
  names :unset
134
176
 
135
177
  def apply (workitem)
136
178
 
137
- vkey = lookup_attribute("variable", workitem)
138
- fkey = lookup_attribute("field", workitem)
179
+ vkey = lookup_variable_attribute(workitem)
180
+ fkey = lookup_field_attribute(workitem)
139
181
 
140
182
  if vkey
141
183
  delete_variable(vkey)
@@ -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"