ruote 0.9.18

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 (291) hide show
  1. data/README.txt +24 -0
  2. data/bin/validate-workflow.rb +89 -0
  3. data/examples/about_state.rb +81 -0
  4. data/examples/bigflow.rb +19 -0
  5. data/examples/csv_weather.rb +23 -0
  6. data/examples/engine_template.rb +247 -0
  7. data/examples/flowtracing.rb +24 -0
  8. data/examples/homeworkreview.rb +68 -0
  9. data/examples/kotoba.rb +22 -0
  10. data/examples/mano_tracker.rb +172 -0
  11. data/examples/openwferu.rb +58 -0
  12. data/examples/quotereporter.rb +157 -0
  13. data/examples/scheduler_cron_usage.rb +48 -0
  14. data/examples/scheduler_usage.rb +56 -0
  15. data/lib/openwfe.rb +41 -0
  16. data/lib/openwfe/contextual.rb +111 -0
  17. data/lib/openwfe/def.rb +46 -0
  18. data/lib/openwfe/engine.rb +37 -0
  19. data/lib/openwfe/engine/engine.rb +756 -0
  20. data/lib/openwfe/engine/expool_methods.rb +172 -0
  21. data/lib/openwfe/engine/file_persisted_engine.rb +105 -0
  22. data/lib/openwfe/engine/participant_methods.rb +133 -0
  23. data/lib/openwfe/engine/status_methods.rb +353 -0
  24. data/lib/openwfe/engine/update_exp_methods.rb +112 -0
  25. data/lib/openwfe/exceptions.rb +51 -0
  26. data/lib/openwfe/expool/errorjournal.rb +476 -0
  27. data/lib/openwfe/expool/expressionpool.rb +1144 -0
  28. data/lib/openwfe/expool/expstorage.rb +403 -0
  29. data/lib/openwfe/expool/history.rb +174 -0
  30. data/lib/openwfe/expool/journal.rb +224 -0
  31. data/lib/openwfe/expool/journal_replay.rb +321 -0
  32. data/lib/openwfe/expool/parser.rb +242 -0
  33. data/lib/openwfe/expool/representation.rb +121 -0
  34. data/lib/openwfe/expool/threadedexpstorage.rb +188 -0
  35. data/lib/openwfe/expool/wfidgen.rb +388 -0
  36. data/lib/openwfe/expool/yamlexpstorage.rb +224 -0
  37. data/lib/openwfe/expressions/condition.rb +244 -0
  38. data/lib/openwfe/expressions/environment.rb +246 -0
  39. data/lib/openwfe/expressions/expressionmap.rb +258 -0
  40. data/lib/openwfe/expressions/fe_cancel.rb +109 -0
  41. data/lib/openwfe/expressions/fe_command.rb +241 -0
  42. data/lib/openwfe/expressions/fe_concurrence.rb +662 -0
  43. data/lib/openwfe/expressions/fe_cron.rb +259 -0
  44. data/lib/openwfe/expressions/fe_cursor.rb +259 -0
  45. data/lib/openwfe/expressions/fe_define.rb +192 -0
  46. data/lib/openwfe/expressions/fe_do.rb +168 -0
  47. data/lib/openwfe/expressions/fe_equals.rb +291 -0
  48. data/lib/openwfe/expressions/fe_filter.rb +129 -0
  49. data/lib/openwfe/expressions/fe_filter_definition.rb +168 -0
  50. data/lib/openwfe/expressions/fe_fqv.rb +250 -0
  51. data/lib/openwfe/expressions/fe_if.rb +303 -0
  52. data/lib/openwfe/expressions/fe_iterator.rb +145 -0
  53. data/lib/openwfe/expressions/fe_listen.rb +371 -0
  54. data/lib/openwfe/expressions/fe_losfor.rb +111 -0
  55. data/lib/openwfe/expressions/fe_misc.rb +421 -0
  56. data/lib/openwfe/expressions/fe_participant.rb +269 -0
  57. data/lib/openwfe/expressions/fe_reserve.rb +212 -0
  58. data/lib/openwfe/expressions/fe_save.rb +274 -0
  59. data/lib/openwfe/expressions/fe_sequence.rb +117 -0
  60. data/lib/openwfe/expressions/fe_set.rb +139 -0
  61. data/lib/openwfe/expressions/fe_sleep.rb +166 -0
  62. data/lib/openwfe/expressions/fe_step.rb +159 -0
  63. data/lib/openwfe/expressions/fe_subprocess.rb +168 -0
  64. data/lib/openwfe/expressions/fe_timeout.rb +127 -0
  65. data/lib/openwfe/expressions/fe_wait.rb +78 -0
  66. data/lib/openwfe/expressions/fe_when.rb +142 -0
  67. data/lib/openwfe/expressions/filter.rb +104 -0
  68. data/lib/openwfe/expressions/flowexpression.rb +847 -0
  69. data/lib/openwfe/expressions/iterator.rb +221 -0
  70. data/lib/openwfe/expressions/merge.rb +84 -0
  71. data/lib/openwfe/expressions/raw.rb +547 -0
  72. data/lib/openwfe/expressions/rprocdef.rb +375 -0
  73. data/lib/openwfe/expressions/time.rb +333 -0
  74. data/lib/openwfe/expressions/timeout.rb +178 -0
  75. data/lib/openwfe/expressions/value.rb +126 -0
  76. data/lib/openwfe/filterdef.rb +259 -0
  77. data/lib/openwfe/flowexpressionid.rb +357 -0
  78. data/lib/openwfe/listeners/listener.rb +97 -0
  79. data/lib/openwfe/listeners/listeners.rb +139 -0
  80. data/lib/openwfe/listeners/socketlisteners.rb +272 -0
  81. data/lib/openwfe/logging.rb +122 -0
  82. data/lib/openwfe/omixins.rb +95 -0
  83. data/lib/openwfe/orest/controlclient.rb +119 -0
  84. data/lib/openwfe/orest/definitions.rb +113 -0
  85. data/lib/openwfe/orest/exception.rb +60 -0
  86. data/lib/openwfe/orest/oldrestservlet.rb +279 -0
  87. data/lib/openwfe/orest/osocket.rb +148 -0
  88. data/lib/openwfe/orest/restclient.rb +176 -0
  89. data/lib/openwfe/orest/workitem.rb +206 -0
  90. data/lib/openwfe/orest/worklistclient.rb +272 -0
  91. data/lib/openwfe/orest/xmlcodec.rb +670 -0
  92. data/lib/openwfe/participants.rb +38 -0
  93. data/lib/openwfe/participants/enoparticipants.rb +230 -0
  94. data/lib/openwfe/participants/participant.rb +141 -0
  95. data/lib/openwfe/participants/participantmap.rb +249 -0
  96. data/lib/openwfe/participants/participants.rb +407 -0
  97. data/lib/openwfe/participants/soapparticipants.rb +135 -0
  98. data/lib/openwfe/participants/socketparticipants.rb +202 -0
  99. data/lib/openwfe/participants/storeparticipants.rb +254 -0
  100. data/lib/openwfe/rudefinitions.rb +130 -0
  101. data/lib/openwfe/service.rb +103 -0
  102. data/lib/openwfe/storage/yamlcustom.rb +106 -0
  103. data/lib/openwfe/storage/yamlfilestorage.rb +245 -0
  104. data/lib/openwfe/tools/flowtracer.rb +81 -0
  105. data/lib/openwfe/util/dollar.rb +217 -0
  106. data/lib/openwfe/util/irb.rb +86 -0
  107. data/lib/openwfe/util/observable.rb +144 -0
  108. data/lib/openwfe/util/ometa.rb +62 -0
  109. data/lib/openwfe/util/workqueue.rb +124 -0
  110. data/lib/openwfe/util/xml.rb +418 -0
  111. data/lib/openwfe/utils.rb +554 -0
  112. data/lib/openwfe/version.rb +37 -0
  113. data/lib/openwfe/workitem.rb +499 -0
  114. data/lib/openwfe/worklist/oldrest.rb +244 -0
  115. data/lib/openwfe/worklist/storelocks.rb +293 -0
  116. data/lib/openwfe/worklist/storeparticipant.rb +44 -0
  117. data/lib/openwfe/worklist/worklist.rb +297 -0
  118. data/test/README.txt +27 -0
  119. data/test/back_0916_test.rb +111 -0
  120. data/test/bm/bm_1_xml_vs_prog.rb +56 -0
  121. data/test/bm/bm_2_step.rb +109 -0
  122. data/test/bm/ft_0f_5ms.rb +35 -0
  123. data/test/bm/ft_26_load.rb +210 -0
  124. data/test/bm/ft_26b_load.rb +86 -0
  125. data/test/bm/ft_26c_load.rb +97 -0
  126. data/test/bm/ft_26d_load.rb +97 -0
  127. data/test/bm/ft_recu.rb +71 -0
  128. data/test/clone_test.rb +122 -0
  129. data/test/concurrence_test.rb +77 -0
  130. data/test/condition_test.rb +155 -0
  131. data/test/console_test.rb +12 -0
  132. data/test/cron_ltest.rb +15 -0
  133. data/test/description_test.rb +87 -0
  134. data/test/eno_test.rb +76 -0
  135. data/test/expmap_test.rb +54 -0
  136. data/test/expool_20031219_0916.tgz +0 -0
  137. data/test/fe_lookup_att_test.rb +62 -0
  138. data/test/fei_test.rb +181 -0
  139. data/test/file_persisted_engine_test.rb +64 -0
  140. data/test/file_persistence_test.rb +134 -0
  141. data/test/filep_cancel_test.rb +123 -0
  142. data/test/filter_test.rb +109 -0
  143. data/test/flowtestbase.rb +351 -0
  144. data/test/ft_0.rb +68 -0
  145. data/test/ft_0b_sequence.rb +36 -0
  146. data/test/ft_0c_testname.rb +33 -0
  147. data/test/ft_0d_participant.rb +30 -0
  148. data/test/ft_0e_multibody.rb +34 -0
  149. data/test/ft_10_loop.rb +134 -0
  150. data/test/ft_11_ppd.rb +415 -0
  151. data/test/ft_11b_ppd.rb +54 -0
  152. data/test/ft_12_blockparticipant.rb +97 -0
  153. data/test/ft_13_eno.rb +52 -0
  154. data/test/ft_14_subprocess.rb +88 -0
  155. data/test/ft_14b_subprocess.rb +192 -0
  156. data/test/ft_14c_subprocess.rb +68 -0
  157. data/test/ft_15_iterator.rb +216 -0
  158. data/test/ft_15b_iterator.rb +74 -0
  159. data/test/ft_16_fqv.rb +73 -0
  160. data/test/ft_17_condition.rb +84 -0
  161. data/test/ft_18_pname.rb +56 -0
  162. data/test/ft_1_unset.rb +175 -0
  163. data/test/ft_1b_unset.rb +39 -0
  164. data/test/ft_20_cron.rb +53 -0
  165. data/test/ft_21_cron.rb +87 -0
  166. data/test/ft_21b_cron_pause.rb +82 -0
  167. data/test/ft_22_history.rb +74 -0
  168. data/test/ft_23_when.rb +77 -0
  169. data/test/ft_23b_when.rb +70 -0
  170. data/test/ft_23c_wait.rb +80 -0
  171. data/test/ft_23d_cww.rb +58 -0
  172. data/test/ft_24_def.rb +44 -0
  173. data/test/ft_25_cancel.rb +89 -0
  174. data/test/ft_27_getflowpos.rb +147 -0
  175. data/test/ft_28_fileparticipant.rb +63 -0
  176. data/test/ft_29_httprb.rb +106 -0
  177. data/test/ft_2_concurrence.rb +135 -0
  178. data/test/ft_2b_concurrence.rb +188 -0
  179. data/test/ft_2c_concurrence.rb +64 -0
  180. data/test/ft_30_socketlistener.rb +203 -0
  181. data/test/ft_31_flowname.rb +40 -0
  182. data/test/ft_32_journal.rb +91 -0
  183. data/test/ft_32c_journal.rb +102 -0
  184. data/test/ft_32d_journal.rb +84 -0
  185. data/test/ft_33_description.rb +107 -0
  186. data/test/ft_34_cancelwfid.rb +80 -0
  187. data/test/ft_35_localdefs.rb +75 -0
  188. data/test/ft_36_subprocids.rb +97 -0
  189. data/test/ft_37_pnames.rb +70 -0
  190. data/test/ft_38_tag.rb +127 -0
  191. data/test/ft_38b_tag.rb +161 -0
  192. data/test/ft_38c_tag.rb +100 -0
  193. data/test/ft_39_reserve.rb +63 -0
  194. data/test/ft_39b_reserve.rb +84 -0
  195. data/test/ft_3_equals.rb +170 -0
  196. data/test/ft_3b_lookup_vf.rb +83 -0
  197. data/test/ft_40_defined.rb +61 -0
  198. data/test/ft_41_case.rb +110 -0
  199. data/test/ft_42_environments.rb +75 -0
  200. data/test/ft_43_pat10.rb +85 -0
  201. data/test/ft_44_save.rb +70 -0
  202. data/test/ft_44b_restore.rb +212 -0
  203. data/test/ft_45_citerator.rb +214 -0
  204. data/test/ft_46_pparams.rb +62 -0
  205. data/test/ft_47_filter.rb +160 -0
  206. data/test/ft_48_fe_filter.rb +88 -0
  207. data/test/ft_49_condition.rb +126 -0
  208. data/test/ft_4_misc.rb +237 -0
  209. data/test/ft_50_xml_attribute.rb +155 -0
  210. data/test/ft_51_stack.rb +55 -0
  211. data/test/ft_52_obs_participant.rb +123 -0
  212. data/test/ft_53_null_noop_participant.rb +62 -0
  213. data/test/ft_54_listen.rb +288 -0
  214. data/test/ft_54b_listen.rb +66 -0
  215. data/test/ft_54c_listen.rb +99 -0
  216. data/test/ft_55_ptimeout.rb +59 -0
  217. data/test/ft_56_timeout.rb +59 -0
  218. data/test/ft_57_a.rb +145 -0
  219. data/test/ft_58_ejournal.rb +151 -0
  220. data/test/ft_59_ps.rb +150 -0
  221. data/test/ft_59b_ps_for_pat.rb +58 -0
  222. data/test/ft_5_time.rb +118 -0
  223. data/test/ft_60_ecancel.rb +161 -0
  224. data/test/ft_61_elsub.rb +51 -0
  225. data/test/ft_62_procparticipant.rb +71 -0
  226. data/test/ft_63_pause.rb +124 -0
  227. data/test/ft_64_alias.rb +102 -0
  228. data/test/ft_64_clone.rb +69 -0
  229. data/test/ft_65_stringlaunch.rb +59 -0
  230. data/test/ft_66_subforget.rb +70 -0
  231. data/test/ft_67_schedlaunch.rb +116 -0
  232. data/test/ft_68_ifparticipant.rb +70 -0
  233. data/test/ft_69_cancelmissing.rb +51 -0
  234. data/test/ft_6_lambda.rb +64 -0
  235. data/test/ft_70_lookupvar.rb +55 -0
  236. data/test/ft_71_log.rb +60 -0
  237. data/test/ft_72_lookup_processes.rb +76 -0
  238. data/test/ft_73_cancel_sub.rb +139 -0
  239. data/test/ft_74_block_and_workitem_dup.rb +63 -0
  240. data/test/ft_75_ruby_attributes.rb +87 -0
  241. data/test/ft_76_merge_isolate.rb +88 -0
  242. data/test/ft_77_segments.rb +35 -0
  243. data/test/ft_78_eval.rb +150 -0
  244. data/test/ft_79_tticket.rb +187 -0
  245. data/test/ft_79b_tticket.rb +172 -0
  246. data/test/ft_79c_outcome.rb +56 -0
  247. data/test/ft_7_lose.rb +104 -0
  248. data/test/ft_7b_lose.rb +78 -0
  249. data/test/ft_80_spname.rb +91 -0
  250. data/test/ft_81_exp.rb +60 -0
  251. data/test/ft_82_trecu.rb +46 -0
  252. data/test/ft_83_badpause.rb +58 -0
  253. data/test/ft_84_updateexp.rb +198 -0
  254. data/test/ft_85_dolhash.rb +43 -0
  255. data/test/ft_86_dollar_fv.rb +68 -0
  256. data/test/ft_87_define.rb +74 -0
  257. data/test/ft_8_forget.rb +44 -0
  258. data/test/ft_9_cursor.rb +145 -0
  259. data/test/ft_9b_cursor.rb +105 -0
  260. data/test/ft_tests.rb +124 -0
  261. data/test/hash_test.rb +75 -0
  262. data/test/hparticipant_test.rb +164 -0
  263. data/test/lookup_att_test.rb +90 -0
  264. data/test/lookup_vf_test.rb +94 -0
  265. data/test/misc_test.rb +90 -0
  266. data/test/nut_0_irb.rb +20 -0
  267. data/test/obs_test.rb +142 -0
  268. data/test/orest_test.rb +251 -0
  269. data/test/param_test.rb +290 -0
  270. data/test/participant_test.rb +101 -0
  271. data/test/pending.rb +23 -0
  272. data/test/ps_representation.rb +133 -0
  273. data/test/rake_ltest.rb +38 -0
  274. data/test/rake_qtest.rb +68 -0
  275. data/test/raw_prog_test.rb +412 -0
  276. data/test/restart_cron_test.rb +136 -0
  277. data/test/restart_paused_test.rb +98 -0
  278. data/test/restart_sleep_test.rb +140 -0
  279. data/test/restart_tests.rb +18 -0
  280. data/test/restart_when_test.rb +112 -0
  281. data/test/ruby_procdef_test.rb +132 -0
  282. data/test/rutest_utils.rb +63 -0
  283. data/test/sec_test.rb +205 -0
  284. data/test/slock_test.rb +80 -0
  285. data/test/storage_test.rb +44 -0
  286. data/test/test.rb +3 -0
  287. data/test/timeout_test.rb +105 -0
  288. data/test/util_xml_test.rb +112 -0
  289. data/test/wfid_test.rb +175 -0
  290. data/test/wi_test.rb +75 -0
  291. metadata +433 -0
@@ -0,0 +1,375 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # . Redistributions of source code must retain the above copyright notice, this
10
+ # list of conditions and the following disclaimer.
11
+ #
12
+ # . Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # . Neither the name of the "OpenWFE" nor the names of its contributors may be
17
+ # used to endorse or promote products derived from this software without
18
+ # specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ # POSSIBILITY OF SUCH DAMAGE.
31
+ #++
32
+ #
33
+
34
+ #
35
+ # "made in Japan"
36
+ #
37
+ # John Mettraux at openwfe.org
38
+ #
39
+
40
+ require 'rufus/eval' # gem 'rufus-eval'
41
+
42
+ require 'openwfe/utils'
43
+ require 'openwfe/expressions/raw'
44
+
45
+
46
+ module OpenWFE
47
+
48
+ #
49
+ # Extend this class to create a programmatic process definition.
50
+ #
51
+ # A short example :
52
+ #
53
+ # class MyProcessDefinition < OpenWFE::ProcessDefinition
54
+ # def make
55
+ # process_definition :name => "test1", :revision => "0" do
56
+ # sequence do
57
+ # set :variable => "toto", :value => "nada"
58
+ # print "toto:${toto}"
59
+ # end
60
+ # end
61
+ # end
62
+ # end
63
+ #
64
+ # li = OpenWFE::LaunchItem.new(MyProcessDefinition)
65
+ # engine.launch(li)
66
+ #
67
+ #
68
+ class ProcessDefinition
69
+
70
+ def self.metaclass; class << self; self; end; end
71
+
72
+ attr_reader :context
73
+
74
+ def initialize
75
+
76
+ super()
77
+ @context = Context.new
78
+ end
79
+
80
+ def method_missing (m, *args, &block)
81
+
82
+ #puts "__i_method_missing >>>#{m}<<<<"
83
+
84
+ ProcessDefinition.make_expression(
85
+ @context,
86
+ OpenWFE::to_expression_name(m),
87
+ ProcessDefinition.pack_args(args),
88
+ &block)
89
+ end
90
+
91
+ def self.method_missing (m, *args, &block)
92
+
93
+ @ccontext = Context.new \
94
+ if (not @ccontext) or @ccontext.discarded?
95
+
96
+ ProcessDefinition.make_expression(
97
+ @ccontext,
98
+ OpenWFE::to_expression_name(m),
99
+ ProcessDefinition.pack_args(args),
100
+ &block)
101
+ end
102
+
103
+ #
104
+ # builds an actual expression representation (a node in the
105
+ # process definition tree).
106
+ #
107
+ def self.make_expression (context, exp_name, params, &block)
108
+
109
+ string_child = nil
110
+ #attributes = OpenWFE::SymbolHash.new
111
+ attributes = Hash.new
112
+
113
+ #puts " ... params.class is #{params.class}"
114
+
115
+ if params.kind_of?(Hash)
116
+
117
+ params.each do |k, v|
118
+
119
+ if k == '0'
120
+ string_child = v.to_s
121
+ else
122
+ #attributes[OpenWFE::symbol_to_name(k.to_s)] = v.to_s
123
+ attributes[OpenWFE::symbol_to_name(k.to_s)] = v
124
+ end
125
+ end
126
+
127
+ elsif params
128
+
129
+ string_child = params.to_s
130
+ end
131
+
132
+ exp = [ exp_name, attributes, [] ]
133
+
134
+ exp.last << string_child \
135
+ if string_child
136
+
137
+ if context.parent_expression
138
+ #
139
+ # adding this new expression to its parent
140
+ #
141
+ context.parent_expression.last << exp
142
+ else
143
+ #
144
+ # an orphan, a top expression
145
+ #
146
+ context.top_expressions << exp
147
+ end
148
+
149
+ return exp unless block
150
+
151
+ context.push_parent_expression exp
152
+
153
+ result = block.call
154
+
155
+ exp.last << result \
156
+ if result and result.kind_of?(String)
157
+
158
+ context.pop_parent_expression
159
+
160
+ exp
161
+ end
162
+
163
+ def do_make
164
+
165
+ ProcessDefinition.do_make self
166
+ end
167
+
168
+ #
169
+ # A class method for actually "making" the process
170
+ # segment raw representation
171
+ #
172
+ def self.do_make (instance=nil)
173
+
174
+ context = if @ccontext
175
+
176
+ @ccontext.discard
177
+ # preventing further additions in case of reevaluation
178
+ @ccontext
179
+
180
+ elsif instance
181
+
182
+ instance.make
183
+ instance.context
184
+ else
185
+
186
+ pdef = self.new
187
+ pdef.make
188
+ pdef.context
189
+ end
190
+
191
+ return context.top_expression if context.top_expression
192
+
193
+ name, revision =
194
+ extract_name_and_revision(self.metaclass.to_s[8..-2])
195
+
196
+ top_expression = [
197
+ "process-definition",
198
+ { "name" => name, "revision" => revision },
199
+ context.top_expressions
200
+ ]
201
+
202
+ top_expression
203
+ end
204
+
205
+ #
206
+ # Parses the string to find the class name of the process definition
207
+ # and returns that class (instance).
208
+ #
209
+ def self.extract_class (ruby_proc_def_string)
210
+
211
+ ruby_proc_def_string.each_line do |l|
212
+
213
+ m = ClassNameRex.match l
214
+
215
+ return eval(m[1]) if m
216
+ end
217
+
218
+ nil
219
+ end
220
+
221
+ #
222
+ # Turns a String containing a ProcessDefinition ...
223
+ #
224
+ def self.eval_ruby_process_definition (code, safety_level=2)
225
+
226
+ # TODO : insert tree check
227
+
228
+ #puts "\nin:\n#{code}\n"
229
+
230
+ code, is_wrapped = wrap_code code
231
+
232
+ o = Rufus::eval_safely code, safety_level, binding()
233
+
234
+ o = extract_class(code) \
235
+ if (o == nil) or o.is_a?(Array)
236
+ #if (o == nil) or o.is_a?(SimpleExpRepresentation)
237
+ #
238
+ # grab the first process definition class found
239
+ # in the given code
240
+
241
+ #return o.do_make \
242
+ # if o.is_a?(ProcessDefinition) or o.is_a?(Class)
243
+ #o
244
+
245
+ result = o.do_make
246
+
247
+ #return result.first_child if is_wrapped
248
+ return result.last.first if is_wrapped
249
+
250
+ result
251
+ end
252
+
253
+ protected
254
+
255
+ ClassNameRex = Regexp.compile(
256
+ " *class *([a-zA-Z0-9]*) *< .*ProcessDefinition")
257
+ ProcessDefinitionRex = Regexp.compile(
258
+ "^class *[a-zA-Z0-9]* *< .*ProcessDefinition")
259
+ ProcessNameAndDefRex = Regexp.compile(
260
+ "([^0-9_]*)_*([0-9].*)$")
261
+ ProcessNameRex = Regexp.compile(
262
+ "(.*$)")
263
+ EndsInDefinitionRex = Regexp.compile(
264
+ ".*Definition$")
265
+
266
+ def self.wrap_code (code)
267
+
268
+ return [ code, false ] if ProcessDefinitionRex.match(code)
269
+
270
+ s = "class NoName0 < ProcessDefinition"
271
+ s << "\n"
272
+ s << code
273
+ s << "\nend"
274
+
275
+ [ s, true ]
276
+ end
277
+
278
+ def self.pack_args (args)
279
+
280
+ return args[0] if args.length == 1
281
+
282
+ a = {}
283
+ args.each_with_index do |arg, index|
284
+ if arg.is_a?(Hash)
285
+ a = a.merge(arg)
286
+ break
287
+ end
288
+ a[index.to_s] = arg
289
+ end
290
+ a
291
+ end
292
+
293
+ def self.extract_name_and_revision (s)
294
+
295
+ i = s.rindex("::")
296
+ s = s[i+2..-1] if i
297
+
298
+ m = ProcessNameAndDefRex.match s
299
+ return [ as_name(m[1]), as_revision(m[2]) ] if m
300
+
301
+ m = ProcessNameRex.match s
302
+ return [ as_name(m[1]), '0' ] if m
303
+
304
+ [ as_name(s), '0' ]
305
+ end
306
+
307
+ def self.as_name (s)
308
+
309
+ return s[0..-11] if EndsInDefinitionRex.match(s)
310
+ s
311
+ end
312
+
313
+ def self.as_revision (s)
314
+
315
+ s.gsub("_", ".")
316
+ end
317
+
318
+ class Context
319
+
320
+ attr_accessor :parent_expression, :top_expressions
321
+ attr_reader :previous_parent_expressions
322
+
323
+ def initialize
324
+ @parent_expression = nil
325
+ @top_expressions = []
326
+ @previous_parent_expressions = []
327
+ end
328
+
329
+ def discard
330
+ @discarded = true
331
+ end
332
+ def discarded?
333
+ (@discarded == true)
334
+ end
335
+
336
+ #
337
+ # puts the current parent expression on top of the 'previous
338
+ # parent expressions' stack, the current parent expression
339
+ # is replaced with the supplied parent expression.
340
+ #
341
+ def push_parent_expression (exp)
342
+
343
+ @previous_parent_expressions.push(@parent_expression) \
344
+ if @parent_expression
345
+
346
+ @parent_expression = exp
347
+ end
348
+
349
+ #
350
+ # Replaces the current parent expression with the one found
351
+ # on the top of the previous parent expression stack (pop).
352
+ #
353
+ def pop_parent_expression
354
+
355
+ @parent_expression = @previous_parent_expressions.pop
356
+ end
357
+
358
+ #
359
+ # This method returns the top expression among the
360
+ # top expressions...
361
+ #
362
+ def top_expression
363
+
364
+ return nil if @top_expressions.size > 1
365
+
366
+ exp = @top_expressions.first
367
+
368
+ return exp if exp.first == "process-definition"
369
+ nil
370
+ end
371
+ end
372
+ end
373
+
374
+ end
375
+
@@ -0,0 +1,333 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # . Redistributions of source code must retain the above copyright notice, this
10
+ # list of conditions and the following disclaimer.
11
+ #
12
+ # . Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # . Neither the name of the "OpenWFE" nor the names of its contributors may be
17
+ # used to endorse or promote products derived from this software without
18
+ # specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ # POSSIBILITY OF SUCH DAMAGE.
31
+ #++
32
+ #
33
+
34
+ #
35
+ # "made in Japan"
36
+ #
37
+ # John Mettraux at openwfe.org
38
+ #
39
+
40
+ require 'rufus/otime'
41
+ require 'openwfe/expressions/timeout'
42
+
43
+
44
+ module OpenWFE
45
+
46
+ #
47
+ # A parent class for CronExpression and SleepExpression, is never
48
+ # used directly.
49
+ # It contains a simple get_scheduler() method simplifying the scheduler
50
+ # localization for <sleep/> and <cron/>.
51
+ #
52
+ class TimeExpression < FlowExpression
53
+ include Rufus::Schedulable
54
+
55
+ #
56
+ # The workitem received at apply time
57
+ #
58
+ attr_accessor :applied_workitem
59
+
60
+ #
61
+ # The job_id in the scheduler for this expression
62
+ #
63
+ attr_accessor :scheduler_job_id
64
+
65
+ #
66
+ # The tags (if any) for the job in the scheduler
67
+ #
68
+ attr_accessor :scheduler_tags
69
+
70
+ #
71
+ # Makes sure to cancel any scheduler job associated with this
72
+ # expression
73
+ #
74
+ def cancel
75
+ #synchronize do
76
+
77
+ ldebug { "cancel()..." }
78
+
79
+ unschedule
80
+
81
+ super()
82
+
83
+ @applied_workitem
84
+ #end
85
+ end
86
+
87
+ #
88
+ # If the expression has been scheduled, a call to this method
89
+ # will make sure it's unscheduled (removed from the scheduler).
90
+ #
91
+ def unschedule
92
+
93
+ ldebug { "unschedule() @scheduler_job_id is #{@scheduler_job_id}" }
94
+
95
+ sleep get_scheduler.precision + 0.001
96
+ #
97
+ # make sure not to unschedule before the actual scheduling
98
+ # got done.
99
+
100
+ get_scheduler.unschedule(@scheduler_job_id) \
101
+ if @scheduler_job_id
102
+ end
103
+
104
+ protected
105
+
106
+ #
107
+ # looks up potential scheduler tags in the expression
108
+ # attributes
109
+ #
110
+ def determine_scheduler_tags
111
+
112
+ @scheduler_tags = lookup_array_attribute(
113
+ :scheduler_tags, @applied_workitem) || []
114
+
115
+ @scheduler_tags << self.class.name
116
+ end
117
+ end
118
+
119
+ #
120
+ # A parent class for WhenExpression and WaitExpression.
121
+ #
122
+ # All the code for managing waiting for something to occur is
123
+ # concentrated here.
124
+ #
125
+ class WaitingExpression < TimeExpression
126
+ include ConditionMixin
127
+ include TimeoutMixin
128
+
129
+ attr_accessor :frequency
130
+
131
+ uses_template
132
+
133
+ #
134
+ # By default, classes extending this class do poll for their
135
+ # condition every 10 seconds.
136
+ #
137
+ DEFAULT_FREQUENCY = "10s"
138
+
139
+ #
140
+ # Don't go under 300 milliseconds.
141
+ #
142
+ MIN_FREQUENCY = 0.300
143
+
144
+ #
145
+ # Classes extending this WaitingExpression have a 'conditions' class
146
+ # method (like 'attr_accessor').
147
+ #
148
+ def self.conditions (*attnames)
149
+
150
+ attnames = attnames.collect do |n|
151
+ n.to_s.to_sym
152
+ end
153
+ meta_def :condition_attributes do
154
+ attnames
155
+ end
156
+ end
157
+
158
+ def apply (workitem)
159
+
160
+ remove_timedout_flag workitem
161
+
162
+ @applied_workitem = workitem.dup
163
+
164
+ @frequency = lookup_attribute(
165
+ :frequency, workitem, :default => DEFAULT_FREQUENCY)
166
+ @frequency = Rufus::parse_time_string(
167
+ @frequency)
168
+ @frequency = MIN_FREQUENCY \
169
+ if @frequency < MIN_FREQUENCY
170
+
171
+ determine_timeout
172
+ determine_scheduler_tags
173
+
174
+ condition_attribute = determine_condition_attribute(
175
+ self.class.condition_attributes)
176
+
177
+ #
178
+ # register consequence
179
+
180
+ consequence = condition_attribute ?
181
+ raw_children[0] : raw_children[1]
182
+
183
+ get_expression_pool.tprepare_child(
184
+ self,
185
+ consequence,
186
+ 0,
187
+ true, # please register child
188
+ nil # no vars
189
+ ) if consequence
190
+
191
+ #
192
+ # go east...
193
+
194
+ store_itself
195
+
196
+ trigger
197
+ end
198
+
199
+ def reply (workitem)
200
+
201
+ result = workitem.get_result
202
+
203
+ if result
204
+ apply_consequence workitem
205
+ else
206
+ reschedule get_scheduler
207
+ end
208
+ end
209
+
210
+ #
211
+ # Cancels this expression (takes care of unscheduling a timeout
212
+ # if there is one).
213
+ #
214
+ def cancel
215
+
216
+ unschedule_timeout
217
+ super()
218
+ end
219
+
220
+ def trigger (params={})
221
+
222
+ ldebug { "trigger() #{@fei.to_debug_s} params : #{params.inspect}" }
223
+
224
+ if params[:do_timeout!]
225
+ #
226
+ # do timeout...
227
+ #
228
+ set_timedout_flag @applied_workitem
229
+ reply_to_parent @applied_workitem
230
+ return
231
+ end
232
+
233
+ @scheduler_job_id = nil
234
+
235
+ evaluate_condition
236
+ end
237
+
238
+ def reschedule (scheduler)
239
+
240
+ @scheduler_job_id = "waiting_#{fei.to_s}"
241
+
242
+ scheduler.schedule_in(
243
+ @frequency,
244
+ {
245
+ :schedulable => self,
246
+ :job_id => @scheduler_job_id,
247
+ :tags => @scheduler_tags })
248
+
249
+ ldebug { "reschedule() @scheduler_job_id is #{@scheduler_job_id}" }
250
+
251
+ to_reschedule scheduler
252
+ end
253
+
254
+ def reply_to_parent (workitem)
255
+
256
+ unschedule
257
+ unschedule_timeout
258
+
259
+ super workitem
260
+ end
261
+
262
+ protected
263
+
264
+ #
265
+ # The code for the condition evalution is here.
266
+ #
267
+ # This method is overriden by the WhenExpression.
268
+ #
269
+ def evaluate_condition
270
+
271
+ condition_attribute = determine_condition_attribute(
272
+ self.class.condition_attributes)
273
+
274
+ if condition_attribute
275
+
276
+ c = eval_condition condition_attribute, @applied_workitem
277
+
278
+ do_reply c
279
+ return
280
+ end
281
+
282
+ # else, condition is nested as a child
283
+
284
+ #if @children.size < 1
285
+ if raw_children.size < 1
286
+ #
287
+ # no condition attribute and no child attribute,
288
+ # simply reply to parent
289
+ #
290
+ reply_to_parent @applied_workitem
291
+ return
292
+ end
293
+
294
+ # trigger the first child (the condition child)
295
+
296
+ #get_expression_pool.launch_template(
297
+ # self,
298
+ # @environment_id,
299
+ # @condition_sub_id,
300
+ # @children[0],
301
+ # @applied_workitem)
302
+ get_expression_pool.tlaunch_child(
303
+ self,
304
+ raw_children.first,
305
+ (Time.new.to_f * 1000).to_i,
306
+ @applied_workitem.dup,
307
+ false) # not registering as a child
308
+ end
309
+
310
+ #
311
+ # Used when replying to self after an attribute condition
312
+ # got evaluated
313
+ #
314
+ def do_reply (result)
315
+
316
+ @applied_workitem.set_result result
317
+ reply @applied_workitem
318
+ end
319
+
320
+ #
321
+ # This method is overriden by WhenExpression. WaitExpression
322
+ # doesn't override it.
323
+ # This default implementation simply directly replies to
324
+ # the parent expression.
325
+ #
326
+ def apply_consequence (workitem)
327
+
328
+ reply_to_parent workitem
329
+ end
330
+ end
331
+
332
+ end
333
+