ruote-maestrodev 2.2.1

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 (265) hide show
  1. data/CHANGELOG.txt +290 -0
  2. data/CREDITS.txt +99 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.rdoc +88 -0
  5. data/Rakefile +108 -0
  6. data/TODO.txt +488 -0
  7. data/lib/ruote.rb +7 -0
  8. data/lib/ruote/context.rb +194 -0
  9. data/lib/ruote/engine.rb +1062 -0
  10. data/lib/ruote/engine/process_error.rb +122 -0
  11. data/lib/ruote/engine/process_status.rb +448 -0
  12. data/lib/ruote/exp/command.rb +87 -0
  13. data/lib/ruote/exp/commanded.rb +69 -0
  14. data/lib/ruote/exp/condition.rb +227 -0
  15. data/lib/ruote/exp/fe_add_branches.rb +138 -0
  16. data/lib/ruote/exp/fe_apply.rb +154 -0
  17. data/lib/ruote/exp/fe_cancel_process.rb +78 -0
  18. data/lib/ruote/exp/fe_command.rb +156 -0
  19. data/lib/ruote/exp/fe_concurrence.rb +321 -0
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
  21. data/lib/ruote/exp/fe_cron.rb +141 -0
  22. data/lib/ruote/exp/fe_cursor.rb +324 -0
  23. data/lib/ruote/exp/fe_define.rb +112 -0
  24. data/lib/ruote/exp/fe_echo.rb +60 -0
  25. data/lib/ruote/exp/fe_equals.rb +115 -0
  26. data/lib/ruote/exp/fe_error.rb +82 -0
  27. data/lib/ruote/exp/fe_filter.rb +648 -0
  28. data/lib/ruote/exp/fe_forget.rb +88 -0
  29. data/lib/ruote/exp/fe_given.rb +154 -0
  30. data/lib/ruote/exp/fe_if.rb +127 -0
  31. data/lib/ruote/exp/fe_inc.rb +205 -0
  32. data/lib/ruote/exp/fe_iterator.rb +234 -0
  33. data/lib/ruote/exp/fe_let.rb +75 -0
  34. data/lib/ruote/exp/fe_listen.rb +304 -0
  35. data/lib/ruote/exp/fe_lose.rb +110 -0
  36. data/lib/ruote/exp/fe_noop.rb +45 -0
  37. data/lib/ruote/exp/fe_once.rb +215 -0
  38. data/lib/ruote/exp/fe_participant.rb +287 -0
  39. data/lib/ruote/exp/fe_read.rb +69 -0
  40. data/lib/ruote/exp/fe_redo.rb +82 -0
  41. data/lib/ruote/exp/fe_ref.rb +152 -0
  42. data/lib/ruote/exp/fe_registerp.rb +110 -0
  43. data/lib/ruote/exp/fe_reserve.rb +126 -0
  44. data/lib/ruote/exp/fe_restore.rb +102 -0
  45. data/lib/ruote/exp/fe_save.rb +72 -0
  46. data/lib/ruote/exp/fe_sequence.rb +59 -0
  47. data/lib/ruote/exp/fe_set.rb +154 -0
  48. data/lib/ruote/exp/fe_subprocess.rb +211 -0
  49. data/lib/ruote/exp/fe_that.rb +92 -0
  50. data/lib/ruote/exp/fe_undo.rb +67 -0
  51. data/lib/ruote/exp/fe_unregisterp.rb +69 -0
  52. data/lib/ruote/exp/fe_wait.rb +95 -0
  53. data/lib/ruote/exp/flowexpression.rb +886 -0
  54. data/lib/ruote/exp/iterator.rb +81 -0
  55. data/lib/ruote/exp/merge.rb +118 -0
  56. data/lib/ruote/exp/ro_attributes.rb +212 -0
  57. data/lib/ruote/exp/ro_filters.rb +136 -0
  58. data/lib/ruote/exp/ro_persist.rb +154 -0
  59. data/lib/ruote/exp/ro_variables.rb +189 -0
  60. data/lib/ruote/exp/ro_vf.rb +68 -0
  61. data/lib/ruote/fei.rb +260 -0
  62. data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
  63. data/lib/ruote/id/wfid_generator.rb +81 -0
  64. data/lib/ruote/log/default_history.rb +122 -0
  65. data/lib/ruote/log/pretty.rb +176 -0
  66. data/lib/ruote/log/storage_history.rb +159 -0
  67. data/lib/ruote/log/test_logger.rb +208 -0
  68. data/lib/ruote/log/wait_logger.rb +64 -0
  69. data/lib/ruote/part/block_participant.rb +137 -0
  70. data/lib/ruote/part/code_participant.rb +81 -0
  71. data/lib/ruote/part/engine_participant.rb +189 -0
  72. data/lib/ruote/part/local_participant.rb +138 -0
  73. data/lib/ruote/part/no_op_participant.rb +60 -0
  74. data/lib/ruote/part/null_participant.rb +54 -0
  75. data/lib/ruote/part/rev_participant.rb +169 -0
  76. data/lib/ruote/part/smtp_participant.rb +116 -0
  77. data/lib/ruote/part/storage_participant.rb +392 -0
  78. data/lib/ruote/part/template.rb +84 -0
  79. data/lib/ruote/participant.rb +7 -0
  80. data/lib/ruote/reader.rb +278 -0
  81. data/lib/ruote/reader/json.rb +49 -0
  82. data/lib/ruote/reader/radial.rb +290 -0
  83. data/lib/ruote/reader/ruby_dsl.rb +186 -0
  84. data/lib/ruote/reader/xml.rb +99 -0
  85. data/lib/ruote/receiver/base.rb +212 -0
  86. data/lib/ruote/storage/base.rb +364 -0
  87. data/lib/ruote/storage/composite_storage.rb +121 -0
  88. data/lib/ruote/storage/fs_storage.rb +139 -0
  89. data/lib/ruote/storage/hash_storage.rb +211 -0
  90. data/lib/ruote/svc/dispatch_pool.rb +158 -0
  91. data/lib/ruote/svc/dollar_sub.rb +298 -0
  92. data/lib/ruote/svc/error_handler.rb +138 -0
  93. data/lib/ruote/svc/expression_map.rb +97 -0
  94. data/lib/ruote/svc/participant_list.rb +397 -0
  95. data/lib/ruote/svc/tracker.rb +172 -0
  96. data/lib/ruote/svc/treechecker.rb +141 -0
  97. data/lib/ruote/tree_dot.rb +85 -0
  98. data/lib/ruote/util/filter.rb +525 -0
  99. data/lib/ruote/util/hashdot.rb +79 -0
  100. data/lib/ruote/util/look.rb +128 -0
  101. data/lib/ruote/util/lookup.rb +127 -0
  102. data/lib/ruote/util/misc.rb +167 -0
  103. data/lib/ruote/util/ometa.rb +71 -0
  104. data/lib/ruote/util/serializer.rb +103 -0
  105. data/lib/ruote/util/subprocess.rb +88 -0
  106. data/lib/ruote/util/time.rb +100 -0
  107. data/lib/ruote/util/tree.rb +58 -0
  108. data/lib/ruote/version.rb +29 -0
  109. data/lib/ruote/worker.rb +386 -0
  110. data/lib/ruote/workitem.rb +394 -0
  111. data/phil.txt +14 -0
  112. data/ruote.gemspec +44 -0
  113. data/test/bm/ci.rb +55 -0
  114. data/test/bm/ici.rb +71 -0
  115. data/test/bm/juuman.rb +54 -0
  116. data/test/bm/launch_bench.rb +37 -0
  117. data/test/bm/load_26c.rb +97 -0
  118. data/test/bm/mega.rb +64 -0
  119. data/test/bm/seq_thousand.rb +31 -0
  120. data/test/bm/t.rb +35 -0
  121. data/test/functional/base.rb +247 -0
  122. data/test/functional/concurrent_base.rb +98 -0
  123. data/test/functional/crunner.rb +31 -0
  124. data/test/functional/ct_0_concurrence.rb +65 -0
  125. data/test/functional/ct_1_iterator.rb +67 -0
  126. data/test/functional/ct_2_cancel.rb +81 -0
  127. data/test/functional/eft_0_process_definition.rb +65 -0
  128. data/test/functional/eft_10_cancel_process.rb +46 -0
  129. data/test/functional/eft_11_wait.rb +109 -0
  130. data/test/functional/eft_12_listen.rb +500 -0
  131. data/test/functional/eft_13_iterator.rb +342 -0
  132. data/test/functional/eft_14_cursor.rb +456 -0
  133. data/test/functional/eft_15_loop.rb +69 -0
  134. data/test/functional/eft_16_if.rb +183 -0
  135. data/test/functional/eft_17_equals.rb +55 -0
  136. data/test/functional/eft_18_concurrent_iterator.rb +410 -0
  137. data/test/functional/eft_19_reserve.rb +136 -0
  138. data/test/functional/eft_1_echo.rb +68 -0
  139. data/test/functional/eft_20_save.rb +116 -0
  140. data/test/functional/eft_21_restore.rb +61 -0
  141. data/test/functional/eft_22_noop.rb +28 -0
  142. data/test/functional/eft_23_apply.rb +168 -0
  143. data/test/functional/eft_24_add_branches.rb +98 -0
  144. data/test/functional/eft_25_command.rb +28 -0
  145. data/test/functional/eft_26_error.rb +77 -0
  146. data/test/functional/eft_27_inc.rb +280 -0
  147. data/test/functional/eft_28_once.rb +135 -0
  148. data/test/functional/eft_29_cron.rb +64 -0
  149. data/test/functional/eft_2_sequence.rb +58 -0
  150. data/test/functional/eft_30_ref.rb +155 -0
  151. data/test/functional/eft_31_registerp.rb +130 -0
  152. data/test/functional/eft_32_lose.rb +93 -0
  153. data/test/functional/eft_33_let.rb +31 -0
  154. data/test/functional/eft_34_given.rb +123 -0
  155. data/test/functional/eft_35_filter.rb +375 -0
  156. data/test/functional/eft_36_read.rb +95 -0
  157. data/test/functional/eft_3_participant.rb +149 -0
  158. data/test/functional/eft_4_set.rb +296 -0
  159. data/test/functional/eft_5_subprocess.rb +163 -0
  160. data/test/functional/eft_6_concurrence.rb +304 -0
  161. data/test/functional/eft_7_forget.rb +61 -0
  162. data/test/functional/eft_8_undo.rb +114 -0
  163. data/test/functional/eft_9_redo.rb +138 -0
  164. data/test/functional/ft_0_worker.rb +65 -0
  165. data/test/functional/ft_10_dollar.rb +304 -0
  166. data/test/functional/ft_11_recursion.rb +109 -0
  167. data/test/functional/ft_12_launchitem.rb +43 -0
  168. data/test/functional/ft_13_variables.rb +151 -0
  169. data/test/functional/ft_14_re_apply.rb +324 -0
  170. data/test/functional/ft_15_timeout.rb +226 -0
  171. data/test/functional/ft_16_participant_params.rb +98 -0
  172. data/test/functional/ft_17_conditional.rb +102 -0
  173. data/test/functional/ft_18_kill.rb +138 -0
  174. data/test/functional/ft_19_participant_code.rb +67 -0
  175. data/test/functional/ft_1_process_status.rb +796 -0
  176. data/test/functional/ft_20_storage_participant.rb +543 -0
  177. data/test/functional/ft_21_forget.rb +153 -0
  178. data/test/functional/ft_22_process_definitions.rb +90 -0
  179. data/test/functional/ft_23_load_defs.rb +79 -0
  180. data/test/functional/ft_24_block_participant.rb +235 -0
  181. data/test/functional/ft_25_receiver.rb +207 -0
  182. data/test/functional/ft_26_participant_rtimeout.rb +179 -0
  183. data/test/functional/ft_27_var_indirection.rb +128 -0
  184. data/test/functional/ft_28_null_noop_participants.rb +51 -0
  185. data/test/functional/ft_29_part_template.rb +60 -0
  186. data/test/functional/ft_2_errors.rb +380 -0
  187. data/test/functional/ft_30_smtp_participant.rb +122 -0
  188. data/test/functional/ft_31_part_blocking.rb +72 -0
  189. data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
  190. data/test/functional/ft_34_cursor_rewind.rb +101 -0
  191. data/test/functional/ft_35_add_service.rb +56 -0
  192. data/test/functional/ft_36_storage_history.rb +150 -0
  193. data/test/functional/ft_37_default_history.rb +109 -0
  194. data/test/functional/ft_38_participant_more.rb +193 -0
  195. data/test/functional/ft_39_wait_for.rb +136 -0
  196. data/test/functional/ft_3_participant_registration.rb +574 -0
  197. data/test/functional/ft_40_wait_logger.rb +62 -0
  198. data/test/functional/ft_41_participants.rb +91 -0
  199. data/test/functional/ft_42_storage_copy.rb +71 -0
  200. data/test/functional/ft_43_participant_on_reply.rb +87 -0
  201. data/test/functional/ft_44_var_participant.rb +35 -0
  202. data/test/functional/ft_45_participant_accept.rb +64 -0
  203. data/test/functional/ft_46_launch_single.rb +83 -0
  204. data/test/functional/ft_47_wfid_generator.rb +54 -0
  205. data/test/functional/ft_48_lose.rb +112 -0
  206. data/test/functional/ft_49_engine_on_error.rb +201 -0
  207. data/test/functional/ft_4_cancel.rb +132 -0
  208. data/test/functional/ft_50_engine_config.rb +22 -0
  209. data/test/functional/ft_51_misc.rb +67 -0
  210. data/test/functional/ft_52_case.rb +134 -0
  211. data/test/functional/ft_53_engine_on_terminate.rb +95 -0
  212. data/test/functional/ft_54_patterns.rb +104 -0
  213. data/test/functional/ft_55_engine_participant.rb +303 -0
  214. data/test/functional/ft_56_filter_attribute.rb +259 -0
  215. data/test/functional/ft_57_rev_participant.rb +252 -0
  216. data/test/functional/ft_58_workitem.rb +69 -0
  217. data/test/functional/ft_59_pause.rb +343 -0
  218. data/test/functional/ft_5_on_error.rb +384 -0
  219. data/test/functional/ft_60_code_participant.rb +45 -0
  220. data/test/functional/ft_61_trailing_fields.rb +34 -0
  221. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  222. data/test/functional/ft_6_on_cancel.rb +221 -0
  223. data/test/functional/ft_7_tags.rb +177 -0
  224. data/test/functional/ft_8_participant_consumption.rb +124 -0
  225. data/test/functional/ft_9_subprocesses.rb +146 -0
  226. data/test/functional/restart_base.rb +34 -0
  227. data/test/functional/rt_0_wait.rb +55 -0
  228. data/test/functional/rt_1_listen.rb +56 -0
  229. data/test/functional/rt_2_errors.rb +56 -0
  230. data/test/functional/rt_3_once.rb +70 -0
  231. data/test/functional/rt_4_cron.rb +64 -0
  232. data/test/functional/rt_5_timeout.rb +60 -0
  233. data/test/functional/rtest.rb +8 -0
  234. data/test/functional/storage_helper.rb +93 -0
  235. data/test/functional/test.rb +44 -0
  236. data/test/functional/vertical.rb +46 -0
  237. data/test/path_helper.rb +15 -0
  238. data/test/test.rb +13 -0
  239. data/test/test_helper.rb +28 -0
  240. data/test/unit/storage.rb +428 -0
  241. data/test/unit/storages.rb +37 -0
  242. data/test/unit/test.rb +28 -0
  243. data/test/unit/ut_0_ruby_reader.rb +223 -0
  244. data/test/unit/ut_11_lookup.rb +122 -0
  245. data/test/unit/ut_13_serializer.rb +65 -0
  246. data/test/unit/ut_14_is_uri.rb +28 -0
  247. data/test/unit/ut_15_util.rb +57 -0
  248. data/test/unit/ut_16_reader.rb +225 -0
  249. data/test/unit/ut_18_engine.rb +47 -0
  250. data/test/unit/ut_19_part_template.rb +86 -0
  251. data/test/unit/ut_1_fei.rb +165 -0
  252. data/test/unit/ut_20_composite_storage.rb +74 -0
  253. data/test/unit/ut_21_svc_participant_list.rb +46 -0
  254. data/test/unit/ut_22_filter.rb +1094 -0
  255. data/test/unit/ut_23_svc_tracker.rb +48 -0
  256. data/test/unit/ut_24_radial_reader.rb +332 -0
  257. data/test/unit/ut_25_merge.rb +113 -0
  258. data/test/unit/ut_3_wait_logger.rb +39 -0
  259. data/test/unit/ut_4_expmap.rb +20 -0
  260. data/test/unit/ut_5_tree.rb +54 -0
  261. data/test/unit/ut_6_condition.rb +303 -0
  262. data/test/unit/ut_7_workitem.rb +99 -0
  263. data/test/unit/ut_8_tree_to_dot.rb +72 -0
  264. data/test/unit/ut_9_xml_reader.rb +61 -0
  265. metadata +504 -0
@@ -0,0 +1,298 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ require 'rufus/dollar' # gem 'rufus-dollar'
27
+ require 'ruote/svc/treechecker'
28
+ require 'ruote/util/lookup'
29
+
30
+
31
+ module Ruote
32
+
33
+ #
34
+ # This service is in charge of extrapolating strings like
35
+ # "${f:nada} == ${f:y}".
36
+ #
37
+ # It relies on the rufus-dollar gem.
38
+ #
39
+ # It's OK to override this service with your own.
40
+ #
41
+ class DollarSubstitution
42
+
43
+ def initialize(context)
44
+
45
+ @context = context
46
+ end
47
+
48
+ # Performs 'dollar substitution' on a piece of text with as input
49
+ # a flow expression and a workitem (fields and variables).
50
+ #
51
+ # With help from Nick Petrella (2008/03/20)
52
+ #
53
+ def s(text, flow_expression, workitem)
54
+
55
+ if text.is_a?(String)
56
+
57
+ literal_sub(
58
+ Rufus.dsub(text, dict_class.new(flow_expression, workitem)),
59
+ flow_expression,
60
+ workitem)
61
+
62
+ elsif text.is_a?(Array)
63
+
64
+ text.collect { |e| s(e, flow_expression, workitem) }
65
+
66
+ elsif text.is_a?(Hash)
67
+
68
+ text.inject({}) { |h, (k, v)|
69
+
70
+ h[s(k, flow_expression, workitem)] = s(v, flow_expression, workitem)
71
+ h
72
+ }
73
+
74
+ else
75
+
76
+ text
77
+ end
78
+ end
79
+
80
+ # This method is public, for easy overriding. This implementation returns
81
+ # Ruote::Dollar::Dict whose instances are used to extrapolate dollar
82
+ # strings like "${f:customer}" or "${r:Time.now.to_s}/${f:year_target}"
83
+ #
84
+ def dict_class
85
+
86
+ ::Ruote::Dollar::Dict
87
+ end
88
+
89
+ protected
90
+
91
+ # If the final text is of the form "$f:x" or "$v:y" will lookup the
92
+ # x field or the y variable. If the lookup is successful (not nil) will
93
+ # return the, not the text.
94
+ #
95
+ def literal_sub(s, fexp, wi)
96
+
97
+ result = case s
98
+ when /^\$([^{}:])$/, /^\$(?:field|fld|f):([^{}]+)$/
99
+ Ruote.lookup(wi['fields'], $~[1])
100
+ when /^\$(?:variable|var|v):([^{}]+)$/
101
+ fexp.lookup_variable($~[1])
102
+ else
103
+ s
104
+ end
105
+
106
+ result.nil? ? s : result
107
+ end
108
+ end
109
+
110
+
111
+ #
112
+ # A mini-namespace Ruote::Dollar for Dict and RubyContext, just to separate
113
+ # them from the rest of Ruote.
114
+ #
115
+ module Dollar
116
+
117
+ #
118
+ # Wrapping a flow expression and the current workitem as a
119
+ # Hash-like object ready for lookup at substitution time.
120
+ #
121
+ class Dict
122
+
123
+ attr_reader :fexp
124
+ attr_reader :workitem
125
+
126
+ def initialize(flowexpression, workitem)
127
+
128
+ @fexp = flowexpression
129
+ @workitem = workitem
130
+ end
131
+
132
+ def [](key)
133
+
134
+ return @fexp.fei.to_storage_id if key == 'fei'
135
+ return @fexp.fei.wfid if key == 'wfid'
136
+ return @fexp.fei.subid if key == 'subid'
137
+ return @fexp.fei.subid if key == 'sub_wfid' # deprecated in 2.1.12
138
+ return @fexp.fei.expid if key == 'expid'
139
+ return @fexp.fei.engine_id if key == 'engine_id'
140
+
141
+ pr, k = extract_prefix(key)
142
+
143
+ # stage 0
144
+
145
+ v = lookup(pr[0, 1], k)
146
+
147
+ return v if v != nil
148
+
149
+ # stage 1
150
+
151
+ return '' if pr.size < 2
152
+
153
+ lookup(pr[1, 1], k)
154
+ end
155
+
156
+ def []=(key, value)
157
+
158
+ pr, k = extract_prefix(key)
159
+ pr = pr[0, 1]
160
+
161
+ if pr == 'f'
162
+
163
+ @workitem.set_attribute(k, value)
164
+
165
+ elsif @fexp
166
+
167
+ @fexp.set_variable(k, value)
168
+ end
169
+ end
170
+
171
+ def has_key?(key)
172
+
173
+ pr, k = extract_prefix(key)
174
+
175
+ return true if pr == 'r'
176
+
177
+ (self[key] != nil)
178
+ end
179
+
180
+ protected
181
+
182
+ def lookup(pr, key)
183
+
184
+ case pr
185
+ when 'v' then @fexp.lookup_variable(key)
186
+ when 'f' then Ruote.lookup(@workitem['fields'], key)
187
+ when 'r' then ruby_eval(key)
188
+ else nil
189
+ end
190
+ end
191
+
192
+ def extract_prefix(key)
193
+
194
+ i = key.index(':')
195
+
196
+ return [ 'f', key ] if not i
197
+ # 'f' is the default prefix (field, not variable)
198
+
199
+ pr = key[0..i-1] # until ':'
200
+ pr = pr[0, 2] # the first two chars
201
+
202
+ pr = pr[0, 1] unless (pr == 'vf') or (pr == 'fv')
203
+
204
+ [ pr, key[i+1..-1] ]
205
+ end
206
+
207
+ # TODO : rdoc me
208
+ #
209
+ def ruby_eval(ruby_code)
210
+
211
+ raise ArgumentError.new(
212
+ "'ruby_eval_allowed' is set to false, cannot evaluate >" +
213
+ ruby_code +
214
+ "< (http://ruote.rubyforge.org/dollar.html)"
215
+ ) if @fexp.context['ruby_eval_allowed'] != true
216
+
217
+ @fexp.context.treechecker.dollar_check(ruby_code)
218
+
219
+ RubyContext.new(self).instance_eval(ruby_code)
220
+ end
221
+ end
222
+
223
+ # Dict uses this RubyContext class to evaluate ruby code. The method
224
+ # of this instance are directly visible to "${r:ruby_code}" ruby code.
225
+ #
226
+ class RubyContext < Ruote::BlankSlate
227
+
228
+ attr_reader :workitem
229
+
230
+ def initialize(dict)
231
+
232
+ @dict = dict
233
+ @workitem = Ruote::Workitem.new(@dict.workitem)
234
+ end
235
+
236
+ # The FlowExpression for which the rendering/substitution is occurring.
237
+ #
238
+ def flow_expression
239
+
240
+ @dict.fexp
241
+ end
242
+
243
+ alias fe flow_expression
244
+ alias fexp flow_expression
245
+
246
+ # The FlowExpressionId of the expression for which the
247
+ # rendering/substitution is occurring.
248
+ #
249
+ def fei
250
+
251
+ @dict.fexp.fei
252
+ end
253
+
254
+ alias wi workitem
255
+
256
+ # The engine_id, if any.
257
+ #
258
+ def engine_id
259
+
260
+ @dict.fexp.context.engine_id
261
+ end
262
+
263
+ # This 'd' function can be called from inside ${r:...} notations.
264
+ #
265
+ # pdef = Ruote.process_definition do
266
+ # sequence do
267
+ # set 'f:toto' => 'person'
268
+ # echo "${r:d('f:toto')}"
269
+ # end
270
+ # end
271
+ #
272
+ # will yield "person".
273
+ #
274
+ def d(s)
275
+
276
+ Rufus.dsub("${#{s}}", @dict)
277
+ end
278
+
279
+ # Given a workitem with the field "newspaper" set to "NYT",
280
+ # "${r:newspaper}" will eval to "NYT".
281
+ #
282
+ # If the field "cars" hold the value [ "bmw", "volkswagen" ],
283
+ # "${r:cars[0]}" will eval to "bmw".
284
+ #
285
+ # Else the regular NoMethodError will be raised.
286
+ #
287
+ def method_missing(m, *args)
288
+
289
+ if args.length < 1 && v = @workitem.fields[m.to_s]
290
+ return v
291
+ end
292
+
293
+ super
294
+ end
295
+ end
296
+ end
297
+ end
298
+
@@ -0,0 +1,138 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ #
29
+ # A ruote service for turning exceptions into process errors (or letting
30
+ # those error fire any potential :on_error attributes in the process
31
+ # definition).
32
+ #
33
+ # This service is used, by the worker, the dispatch pool and some
34
+ # receivers (like the one in ruote-beanstalk).
35
+ #
36
+ class ErrorHandler
37
+
38
+ def initialize(context)
39
+
40
+ @context = context
41
+ end
42
+
43
+ # As used by the dispatch pool and the worker.
44
+ #
45
+ def msg_handle(msg, exception)
46
+
47
+ fexp = Ruote::Exp::FlowExpression.fetch(
48
+ @context, msg['fei'] || msg['workitem']['fei']
49
+ ) rescue nil
50
+
51
+ handle(msg, fexp, exception)
52
+ end
53
+
54
+ # As used by some receivers (see ruote-beanstalk's receiver).
55
+ #
56
+ def action_handle(action, fei, exception)
57
+
58
+ fexp = Ruote::Exp::FlowExpression.fetch(@context, fei)
59
+
60
+ msg = {
61
+ 'action' => action,
62
+ 'fei' => fei,
63
+ 'participant_name' => fexp.h.participant_name,
64
+ 'workitem' => fexp.h.applied_workitem }
65
+
66
+ handle(msg, fexp, exception)
67
+ end
68
+
69
+ protected
70
+
71
+ # As used by the worker.
72
+ #
73
+ def handle(msg, fexp, exception)
74
+
75
+ wfid = msg['wfid'] || (msg['fei']['wfid'] rescue nil)
76
+ fei = msg['fei'] || (fexp.h.fei rescue nil)
77
+
78
+ backtrace = exception.backtrace || []
79
+
80
+ # debug only
81
+
82
+ if $DEBUG || ARGV.include?('-d')
83
+
84
+ puts "\n== worker intercepted error =="
85
+ puts
86
+ p exception
87
+ puts backtrace[0, 20].join("\n")
88
+ puts '...'
89
+ puts
90
+ puts '-- msg --'
91
+ key_length = msg.keys.collect { |k| k.length }.max + 1
92
+ msg.keys.sort.each { |k|
93
+ v = msg[k]
94
+ v = (Ruote.sid(v) rescue nil) if k == 'fei' || k == 'parent_id'
95
+ printf("%*s : %s\n", key_length, k, v.inspect)
96
+ }
97
+ puts '-- . --'
98
+ puts
99
+ end
100
+
101
+ # on_error ?
102
+
103
+ return if fexp && fexp.handle_on_error(msg, exception)
104
+
105
+ # emit 'msg'
106
+ #
107
+ # (this message might get intercepted by a tracker)
108
+
109
+ dev = exception.respond_to?(:deviations) ? exception.deviations : nil
110
+
111
+ @context.storage.put_msg(
112
+ 'error_intercepted',
113
+ 'error' => {
114
+ 'fei' => fei,
115
+ 'at' => Ruote.now_to_utc_s,
116
+ 'class' => exception.class.name,
117
+ 'message' => exception.message,
118
+ 'trace' => backtrace,
119
+ 'deviations' => dev },
120
+ 'wfid' => wfid,
121
+ 'fei' => fei,
122
+ 'msg' => msg)
123
+
124
+ # fill error in the error journal
125
+
126
+ @context.storage.put(
127
+ 'type' => 'errors',
128
+ '_id' => "err_#{Ruote.to_storage_id(fei)}",
129
+ 'message' => exception.inspect,
130
+ 'trace' => backtrace.join("\n"),
131
+ 'deviations' => dev,
132
+ 'fei' => fei,
133
+ 'msg' => msg
134
+ ) if fei
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,97 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+ module Exp
28
+ # just introducing the namespace
29
+ end
30
+ end
31
+
32
+ require 'ruote/exp/flowexpression'
33
+
34
+
35
+ exppath = File.join(File.dirname(__FILE__), '..', 'exp')
36
+
37
+ Dir.new(exppath).entries.each do |pa|
38
+ require(File.join('ruote', 'exp', pa)) if pa.match(/^fe_.*\.rb$/)
39
+ end
40
+
41
+
42
+ module Ruote
43
+
44
+ #
45
+ # Mapping from expression names (sequence, concurrence, ...) to expression
46
+ # classes (Ruote::SequenceExpression, Ruote::ConcurrenceExpression, ...)
47
+ #
48
+ # Requiring this ruote/svc/expression_map.rb file will automatically load
49
+ # all the expressions in ruote/exp/fe_*.rb.
50
+ #
51
+ # When the ExpressionMap is
52
+ # instantiated by the engine, it will look at the Ruote::Exp namespace
53
+ # and register as expression any constant in there whose name ends with
54
+ # "Expression", like "SequenceExpression" or "ParticipantExpression".
55
+ #
56
+ # So adding expressions to ruote should be as simple as making sure the
57
+ # engine sees your classes under Ruote::Exp before it instantiates this
58
+ # expression map (so that the expression map will automatically register
59
+ # your expressions).
60
+ #
61
+ class ExpressionMap
62
+
63
+ # Will load any expression in the Ruote::Exp:: namespace and map
64
+ # its names to its class.
65
+ #
66
+ def initialize(worker)
67
+
68
+ @map = {}
69
+
70
+ Ruote::Exp.constants.each do |con|
71
+
72
+ con = con.to_s
73
+ next unless con.match(/Expression$/)
74
+
75
+ cla = Ruote::Exp.const_get(con)
76
+ next unless cla.respond_to?(:expression_names)
77
+
78
+ add(cla)
79
+ end
80
+ end
81
+
82
+ # Returns the expression class for the given expression name
83
+ #
84
+ def expression_class(exp_name)
85
+
86
+ @map[exp_name]
87
+ end
88
+
89
+ protected
90
+
91
+ def add(exp_class)
92
+
93
+ exp_class.expression_names.each { |n| @map[n] = exp_class }
94
+ end
95
+ end
96
+ end
97
+