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,221 @@
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
+
41
+ module OpenWFE
42
+
43
+ #
44
+ # Iterator instances keep track of the position of an iteration.
45
+ # This class is meant to be used both by <iterator> and
46
+ # <concurrent-iterator>.
47
+ #
48
+ class Iterator
49
+
50
+ ITERATOR_COUNT = "__ic__"
51
+ ITERATOR_POSITION = "__ip__"
52
+
53
+ attr_accessor :iteration_index
54
+ attr_accessor :iteration_list
55
+ attr_accessor :to_field
56
+ attr_accessor :to_variable
57
+ attr_accessor :value_separator
58
+
59
+ #
60
+ # Builds a new iterator, serving a given iterator_expression.
61
+ # The second parameter is the workitem (as applied to the iterator
62
+ # expression).
63
+ #
64
+ def initialize (iterator_expression, workitem)
65
+
66
+ @to_field = iterator_expression\
67
+ .lookup_attribute(:to_field, workitem)
68
+ @to_variable = iterator_expression\
69
+ .lookup_attribute(:to_variable, workitem)
70
+
71
+ @value_separator = iterator_expression\
72
+ .lookup_attribute(:value_separator, workitem)
73
+
74
+ @value_separator = /,\s*/ unless @value_separator
75
+
76
+ @iteration_index = 0
77
+
78
+ #raw_list = iterator_expression.lookup_vf_attribute(
79
+ # workitem, :value, :prefix => :on)
80
+ #raw_list ||= iterator_expression.lookup_attribute(:on, workitem)
81
+
82
+ raw_list =
83
+ iterator_expression.lookup_vf_attribute(
84
+ workitem, :value, :prefix => :on) ||
85
+ iterator_expression.lookup_vf_attribute(
86
+ workitem, nil, :prefix => :on)
87
+
88
+ @iteration_list = extract_iteration_list raw_list
89
+
90
+ workitem.attributes[ITERATOR_COUNT] = @iteration_list.length
91
+ end
92
+
93
+ #
94
+ # Has the iteration a next element ?
95
+ #
96
+ def has_next?
97
+
98
+ @iteration_index < @iteration_list.size
99
+ end
100
+
101
+ #
102
+ # Returns the size of this iterator, or rather, the size of the
103
+ # underlying iteration list.
104
+ #
105
+ def size
106
+
107
+ @iteration_list.size
108
+ end
109
+
110
+ #
111
+ # Prepares the iterator expression and the workitem for the next
112
+ # iteration.
113
+ #
114
+ def next (workitem)
115
+
116
+ position_at workitem, @iteration_index
117
+ end
118
+
119
+ #
120
+ # Positions the iterator back at position 0.
121
+ #
122
+ def rewind (workitem)
123
+
124
+ position_at workitem, 0
125
+ end
126
+
127
+ #
128
+ # Jumps to a given position in the iterator
129
+ #
130
+ def jump (workitem, index)
131
+
132
+ index = if index < 0
133
+ 0
134
+ elsif index >= @iteration_list.size
135
+ @iteration_list.size
136
+ else
137
+ index
138
+ end
139
+
140
+ position_at workitem, index
141
+ end
142
+
143
+ #
144
+ # Jumps a certain number of positions in the iterator.
145
+ #
146
+ def skip (workitem, offset)
147
+
148
+ jump workitem, @iteration_index + offset
149
+ end
150
+
151
+ #
152
+ # The current index (whereas @iteration_index already points to
153
+ # the next element).
154
+ #
155
+ def index
156
+
157
+ @iteration_index - 1
158
+ end
159
+
160
+ protected
161
+
162
+ #
163
+ # Positions the iterator absolutely.
164
+ #
165
+ def position_at (workitem, position)
166
+
167
+ result = {}
168
+
169
+ value = @iteration_list[position]
170
+
171
+ return nil unless value
172
+
173
+ if @to_field
174
+ workitem.attributes[@to_field] = value
175
+ else
176
+ result[@to_variable] = value
177
+ end
178
+
179
+ workitem.attributes[ITERATOR_POSITION] = position
180
+ result[ITERATOR_POSITION] = position
181
+
182
+ @iteration_index = position + 1
183
+
184
+ result
185
+ end
186
+
187
+ #
188
+ # Extracts the iteration list from any value.
189
+ #
190
+ def extract_iteration_list (raw_list)
191
+
192
+ if is_suitable_list?(raw_list)
193
+ raw_list
194
+ else
195
+ extract_list_from_string raw_list.to_s
196
+ end
197
+ end
198
+
199
+ #
200
+ # Returns true if the given instance can be directly
201
+ # used as a list.
202
+ #
203
+ def is_suitable_list? (instance)
204
+
205
+ (not instance.is_a?(String)) and \
206
+ instance.respond_to? :[] and \
207
+ instance.respond_to? :length
208
+ end
209
+
210
+ #
211
+ # Extracts the list from the string (comma separated list
212
+ # usually).
213
+ #
214
+ def extract_list_from_string (s)
215
+
216
+ s.split @value_separator
217
+ end
218
+ end
219
+
220
+ end
221
+
@@ -0,0 +1,84 @@
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 'openwfe/utils'
41
+
42
+
43
+ module OpenWFE
44
+
45
+ #
46
+ # Gathering methods for mixing (merging) workitems.
47
+ #
48
+ module MergeMixin
49
+
50
+ #
51
+ # Merges a source workitem into a target workitem (the fields
52
+ # of the source will overwrite the fields in the target).
53
+ #
54
+ # Returns the resulting (merged) workitem.
55
+ #
56
+ def merge_workitems (wiTarget, wiSource, override=false)
57
+
58
+ return wiSource unless wiTarget
59
+ return wiTarget unless wiSource
60
+
61
+ return wiSource if override
62
+
63
+ #puts "merge()"
64
+ #puts "merge() source : " + wiSource.attributes.inspect
65
+ #puts "merge() target : " + wiTarget.attributes.inspect
66
+
67
+ wiSource.attributes.each do |k, v|
68
+
69
+ #puts "merge() '#{k}' => '#{v}'"
70
+
71
+ nk = OpenWFE::fulldup k
72
+ nv = OpenWFE::fulldup v
73
+
74
+ wiTarget.attributes[nk] = nv
75
+ end
76
+
77
+ #puts "merge() target after : " + wiTarget.attributes.inspect
78
+
79
+ wiTarget
80
+ end
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,547 @@
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 'openwfe/exceptions'
41
+ require 'openwfe/expressions/flowexpression'
42
+ require 'openwfe/rudefinitions'
43
+
44
+
45
+ module OpenWFE
46
+
47
+ #
48
+ # A class storing bits (trees) of process definitions just
49
+ # parsed. Upon application (apply()) these raw expressions get turned
50
+ # into real expressions.
51
+ #
52
+ class RawExpression < FlowExpression
53
+
54
+ #
55
+ # A [static] method for creating new RawExpression instances.
56
+ #
57
+ def self.new_raw (
58
+ fei, parent_id, env_id, app_context, raw_representation)
59
+
60
+ re = self.new
61
+
62
+ re.fei = fei
63
+ re.parent_id = parent_id
64
+ re.environment_id = env_id
65
+ re.application_context = app_context
66
+ re.attributes = nil
67
+ re.children = []
68
+ re.apply_time = nil
69
+
70
+ re.raw_representation = raw_representation
71
+ re
72
+ end
73
+
74
+ #--
75
+ # A duplication method that duplicates everything, except
76
+ # the application context
77
+ #
78
+ #def dup
79
+ # self.class.new_raw(
80
+ # @fei.dup,
81
+ # @parent_id ? @parent_id.dup : nil,
82
+ # @environment_id ? @environment_id.dup : nil,
83
+ # @application_context,
84
+ # raw_representation)
85
+ #end
86
+ #alias :fulldup :dup
87
+ #++
88
+
89
+ def instantiate_real_expression (
90
+ workitem, exp_name=nil, exp_class=nil, attributes=nil)
91
+
92
+ exp_name ||= expression_name
93
+ exp_class ||= expression_class
94
+
95
+ raise "unknown expression '#{exp_name}'" \
96
+ unless exp_class
97
+
98
+ #ldebug do
99
+ # "instantiate_real_expression() exp_class is #{exp_class}"
100
+ #end
101
+
102
+ attributes ||= raw_representation[1]
103
+
104
+ exp = exp_class.new
105
+ exp.fei = @fei
106
+ exp.parent_id = @parent_id
107
+ exp.environment_id = @environment_id
108
+ exp.application_context = @application_context
109
+ exp.attributes = attributes
110
+
111
+ exp.raw_representation = raw_representation
112
+ exp.raw_rep_updated = raw_rep_updated
113
+ #
114
+ # keeping track of how the expression look at apply /
115
+ # instantiation time
116
+
117
+ consider_tag workitem, exp
118
+
119
+ exp.children = extract_children \
120
+ unless exp_class.uses_template?
121
+
122
+ exp
123
+ end
124
+
125
+ #
126
+ # When a raw expression is applied, it gets turned into the
127
+ # real expression which then gets applied.
128
+ #
129
+ def apply (workitem)
130
+
131
+ exp_name, exp_class, attributes = determine_real_expression
132
+
133
+ expression = instantiate_real_expression(
134
+ workitem, exp_name, exp_class, attributes)
135
+
136
+ expression.apply_time = Time.now
137
+ expression.store_itself
138
+
139
+ expression.apply workitem
140
+ end
141
+
142
+ #
143
+ # This method is called by the expression pool when it is about
144
+ # to launch a process, it will interpret the 'parameter' statements
145
+ # in the process definition and raise an exception if the requirements
146
+ # are not met.
147
+ #
148
+ def check_parameters (workitem)
149
+
150
+ extract_parameters.each do |param|
151
+ param.check(workitem)
152
+ end
153
+ end
154
+
155
+ #--
156
+ #def reply (workitem)
157
+ # no implementation necessary
158
+ #end
159
+ #++
160
+
161
+ def is_definition?
162
+
163
+ get_expression_map.is_definition?(expression_name())
164
+ end
165
+
166
+ def expression_class
167
+
168
+ get_expression_map.get_class(expression_name())
169
+ end
170
+
171
+ def definition_name
172
+
173
+ (raw_representation[1]['name'] || raw_children.first).to_s
174
+ end
175
+
176
+ def expression_name
177
+
178
+ raw_representation.first
179
+ end
180
+
181
+ #
182
+ # Forces the raw expression to load the attributes and set them
183
+ # in its @attributes instance variable.
184
+ # Currently only used by FilterDefinitionExpression.
185
+ #
186
+ def load_attributes
187
+
188
+ @attributes = raw_representation[1]
189
+ end
190
+
191
+ #
192
+ # This method has been made public in order to have quick look
193
+ # at the attributes of an expression before it's really
194
+ # 'instantiated'.
195
+ #
196
+ def extract_attributes
197
+
198
+ raw_representation[1]
199
+ end
200
+
201
+ protected
202
+
203
+ #
204
+ # looks up a participant in the participant map, considers
205
+ # "my-participant" and "my_participant" as the same
206
+ # (by doing two lookups).
207
+ #
208
+ def lookup_participant (name)
209
+
210
+ p = get_participant_map.lookup_participant(name)
211
+
212
+ unless p
213
+ name = OpenWFE::to_underscore(name)
214
+ p = get_participant_map.lookup_participant(name)
215
+ end
216
+
217
+ return name if p
218
+
219
+ nil
220
+ end
221
+
222
+ #
223
+ # Determines if this raw expression points to a classical
224
+ # expression, a participant or a subprocess, or nothing at all...
225
+ #
226
+ def determine_real_expression
227
+
228
+ exp_name = expression_name()
229
+ exp_class = expression_class()
230
+ var_value = lookup_variable exp_name
231
+ attributes = extract_attributes
232
+
233
+ unless var_value
234
+ #
235
+ # accomodating "sub_process_name" and "sub-process-name"
236
+ #
237
+ alt = OpenWFE::to_underscore exp_name
238
+ var_value = lookup_variable(alt) if alt != exp_name
239
+
240
+ exp_name = alt if var_value
241
+ end
242
+
243
+ var_value = exp_name \
244
+ if (not exp_class and not var_value)
245
+
246
+ if var_value.is_a?(String)
247
+
248
+ participant_name = lookup_participant var_value
249
+
250
+ if participant_name
251
+ exp_name = participant_name
252
+ exp_class = ParticipantExpression
253
+ attributes['ref'] = participant_name
254
+ end
255
+
256
+ elsif var_value.is_a?(FlowExpressionId) \
257
+ or var_value.is_a?(RawExpression)
258
+
259
+ exp_class = SubProcessRefExpression
260
+ attributes['ref'] = exp_name
261
+ end
262
+ # else, it's a standard expression
263
+
264
+ [ exp_name, exp_class, attributes ]
265
+ end
266
+
267
+ def extract_children
268
+
269
+ i = 0
270
+ result = []
271
+ raw_representation.last.each do |child|
272
+
273
+ if is_not_a_node?(child)
274
+
275
+ result << child
276
+ else
277
+
278
+ cname = child.first.intern
279
+
280
+ next if cname == :param
281
+ next if cname == :parameter
282
+ #next if cname == :description
283
+
284
+ cfei = @fei.dup
285
+ cfei.expression_name = child.first
286
+ cfei.expression_id = "#{cfei.expression_id}.#{i}"
287
+
288
+ efei = @environment_id
289
+
290
+ rawexp = RawExpression.new_raw(
291
+ cfei, @fei, efei, @application_context, child)
292
+
293
+ get_expression_pool.update rawexp
294
+
295
+ i = i + 1
296
+
297
+ result << rawexp.fei
298
+ end
299
+ end
300
+ result
301
+ end
302
+
303
+ def extract_parameters
304
+
305
+ r = []
306
+ raw_representation.last.each do |child|
307
+
308
+ #next unless child.is_a?(SimpleExpRepresentation)
309
+ #next unless child.is_a?(Array)
310
+ next if is_not_a_node?(child)
311
+
312
+ name = child.first.to_sym
313
+ next unless (name == :parameter or name == :param)
314
+
315
+ attributes = child[1]
316
+
317
+ r << Parameter.new(
318
+ attributes['field'],
319
+ attributes['match'],
320
+ attributes['default'],
321
+ attributes['type'])
322
+ end
323
+ r
324
+ end
325
+
326
+ def is_not_a_node? (child)
327
+
328
+ (( ! child.is_a?(Array)) ||
329
+ child.size != 3 ||
330
+ ( ! child.first.is_a?(String)))
331
+ end
332
+
333
+ #
334
+ # Expressions can get tagged. Tagged expressions can easily
335
+ # be cancelled (undone) or redone.
336
+ #
337
+ def consider_tag (workitem, new_expression)
338
+
339
+ tagname = new_expression.lookup_string_attribute :tag, workitem
340
+
341
+ return unless tagname
342
+
343
+ ldebug { "consider_tag() tag is '#{tagname}'" }
344
+
345
+ set_variable tagname, Tag.new(self, workitem)
346
+ #
347
+ # keep copy of raw expression and workitem as applied
348
+
349
+ new_expression.attributes["tag"] = tagname
350
+ #
351
+ # making sure that the value of tag doesn't change anymore
352
+ end
353
+
354
+ #
355
+ # A small class wrapping a tag (a raw expression and the workitem
356
+ # it received at apply time.
357
+ #
358
+ class Tag
359
+
360
+ attr_reader \
361
+ :raw_expression,
362
+ :workitem
363
+
364
+ def flow_expression_id
365
+ @raw_expression.fei
366
+ end
367
+ alias :fei :flow_expression_id
368
+
369
+ def initialize (raw_expression, workitem)
370
+
371
+ @raw_expression = raw_expression.dup
372
+ @workitem = workitem.dup
373
+ end
374
+ end
375
+
376
+ #
377
+ # Encapsulating
378
+ # <parameter field="x" default="y" type="z" match="m" />
379
+ #
380
+ # Somehow I have that : OpenWFEru is not a strongly typed language
381
+ # ... Anyway I implemented that to please Pat.
382
+ #
383
+ class Parameter
384
+
385
+ def initialize (field, match, default, type)
386
+
387
+ @field = to_s field
388
+ @match = to_s match
389
+ @default = to_s default
390
+ @type = to_s type
391
+ end
392
+
393
+ #
394
+ # Will raise an exception if this param requirement is not
395
+ # met by the workitem.
396
+ #
397
+ def check (workitem)
398
+
399
+ unless @field
400
+ raise \
401
+ OpenWFE::ParameterException,
402
+ "'parameter'/'param' without a 'field' attribute"
403
+ end
404
+
405
+ field_value = workitem.attributes[@field]
406
+ field_value = @default unless field_value
407
+
408
+ unless field_value
409
+ raise \
410
+ OpenWFE::ParameterException,
411
+ "field '#{@field}' is missing" \
412
+ end
413
+
414
+ check_match(field_value)
415
+
416
+ enforce_type(workitem, field_value)
417
+ end
418
+
419
+ protected
420
+
421
+ #
422
+ # Used in the constructor to flatten everything to strings.
423
+ #
424
+ def to_s (o)
425
+ return nil unless o
426
+ o.to_s
427
+ end
428
+
429
+ #
430
+ # Will raise an exception if it cannot coerce the type
431
+ # of the value to the one desired.
432
+ #
433
+ def enforce_type (workitem, value)
434
+
435
+ value = if not @type
436
+ value
437
+ elsif @type == "string"
438
+ value.to_s
439
+ elsif @type == "int" or @type == "integer"
440
+ Integer(value)
441
+ elsif @type == "float"
442
+ Float(value)
443
+ else
444
+ raise
445
+ "unknown type '#{@type}' for field '#{@field}'"
446
+ end
447
+
448
+ workitem.attributes[@field] = value
449
+ end
450
+
451
+ def check_match (value)
452
+
453
+ return unless @match
454
+
455
+ unless value.to_s.match(@match)
456
+ raise \
457
+ OpenWFE::ParameterException,
458
+ "value of field '#{@field}' doesn't match"
459
+ end
460
+ end
461
+ end
462
+ end
463
+
464
+ #
465
+ # This class is only present to ensure that OpenWFEru 0.9.17 can read
466
+ # previous (<= 0.9.16) expools.
467
+ #
468
+ class ProgRawExpression < RawExpression
469
+
470
+ def raw_representation
471
+
472
+ @raw_representation.to_a
473
+ end
474
+ end
475
+
476
+ #
477
+ # This class is only present to ensure that OpenWFEru 0.9.17 can read
478
+ # previous (<= 0.9.16) expools.
479
+ #
480
+ class XmlRawExpression < RawExpression
481
+
482
+ def raw_representation
483
+
484
+ #SimpleExpRepresentation.from_xml @raw_representation_s
485
+ DefParser.parse_xml @raw_representation_s
486
+ end
487
+ end
488
+
489
+ #
490
+ # This class is only present to ensure that OpenWFEru 0.9.17 can read
491
+ # previous (<= 0.9.16) expools.
492
+ #
493
+ class SimpleExpRepresentation
494
+
495
+ def to_a
496
+
497
+ children = @children.collect do |c|
498
+ if c.is_a?(SimpleExpRepresentation)
499
+ c.to_a
500
+ else
501
+ c
502
+ end
503
+ end
504
+
505
+ a = [ @name, @attributes, children ]
506
+ end
507
+ end
508
+
509
+ private
510
+
511
+ #
512
+ # OpenWFE process definitions do use some
513
+ # Ruby keywords... The workaround is to put an underscore
514
+ # just before the name to 'escape' it.
515
+ #
516
+ # 'undo' isn't reserved by Ruby, but lets keep it in line
517
+ # with 'do' and 'redo' that are.
518
+ #
519
+ KEYWORDS = [
520
+ :if, :do, :redo, :undo, :print, :sleep, :loop, :break, :when
521
+ #:until, :while
522
+ ]
523
+
524
+ #
525
+ # Ensures the method name is not conflicting with Ruby keywords
526
+ # and turn dashes to underscores.
527
+ #
528
+ def OpenWFE.make_safe (method_name)
529
+
530
+ method_name = OpenWFE::to_underscore(method_name)
531
+
532
+ return "_" + method_name \
533
+ if KEYWORDS.include? eval(":"+method_name)
534
+
535
+ method_name
536
+ end
537
+
538
+ def OpenWFE.to_expression_name (method_name)
539
+
540
+ method_name = method_name.to_s
541
+ method_name = method_name[1..-1] if method_name[0, 1] == "_"
542
+ method_name = OpenWFE::to_dash(method_name)
543
+ method_name
544
+ end
545
+
546
+ end
547
+