openwferu 0.9.13 → 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
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"