openwferu 0.9.16 → 0.9.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/examples/about_state.rb +81 -0
  2. data/examples/engine_template.rb +7 -0
  3. data/lib/openwfe/contextual.rb +2 -2
  4. data/lib/openwfe/def.rb +2 -3
  5. data/lib/openwfe/{util/schedulers.rb → engine.rb} +3 -39
  6. data/lib/openwfe/engine/engine.rb +202 -251
  7. data/lib/openwfe/engine/process_status.rb +359 -0
  8. data/lib/openwfe/expool/errorjournal.rb +6 -6
  9. data/lib/openwfe/expool/expressionpool.rb +161 -239
  10. data/lib/openwfe/expool/expstorage.rb +185 -55
  11. data/lib/openwfe/expool/journal.rb +1 -2
  12. data/lib/openwfe/expool/parser.rb +233 -0
  13. data/lib/openwfe/expool/threadedexpstorage.rb +6 -18
  14. data/lib/openwfe/expool/wfidgen.rb +25 -7
  15. data/lib/openwfe/expool/yamlexpstorage.rb +60 -37
  16. data/lib/openwfe/expressions/condition.rb +49 -12
  17. data/lib/openwfe/expressions/environment.rb +45 -15
  18. data/lib/openwfe/expressions/expressionmap.rb +39 -19
  19. data/lib/openwfe/expressions/fe_concurrence.rb +24 -13
  20. data/lib/openwfe/expressions/fe_cron.rb +19 -18
  21. data/lib/openwfe/expressions/fe_cursor.rb +69 -28
  22. data/lib/openwfe/expressions/fe_define.rb +4 -1
  23. data/lib/openwfe/expressions/fe_do.rb +1 -3
  24. data/lib/openwfe/expressions/fe_equals.rb +131 -20
  25. data/lib/openwfe/expressions/fe_fqv.rb +27 -3
  26. data/lib/openwfe/expressions/fe_iterator.rb +14 -7
  27. data/lib/openwfe/expressions/fe_listen.rb +7 -2
  28. data/lib/openwfe/expressions/fe_misc.rb +187 -20
  29. data/lib/openwfe/expressions/fe_participant.rb +8 -7
  30. data/lib/openwfe/expressions/fe_reserve.rb +105 -33
  31. data/lib/openwfe/expressions/fe_save.rb +55 -5
  32. data/lib/openwfe/expressions/{fe_value.rb → fe_set.rb} +6 -82
  33. data/lib/openwfe/expressions/fe_sleep.rb +25 -15
  34. data/lib/openwfe/expressions/fe_subprocess.rb +2 -2
  35. data/lib/openwfe/expressions/fe_wait.rb +3 -2
  36. data/lib/openwfe/expressions/fe_when.rb +7 -15
  37. data/lib/openwfe/expressions/flowexpression.rb +90 -49
  38. data/lib/openwfe/expressions/merge.rb +7 -1
  39. data/lib/openwfe/expressions/raw.rb +261 -63
  40. data/lib/openwfe/expressions/{raw_prog.rb → rprocdef.rb} +94 -179
  41. data/lib/openwfe/expressions/time.rb +36 -12
  42. data/lib/openwfe/expressions/timeout.rb +9 -7
  43. data/lib/openwfe/expressions/value.rb +126 -0
  44. data/lib/openwfe/flowexpressionid.rb +52 -22
  45. data/lib/openwfe/listeners/listeners.rb +3 -3
  46. data/lib/openwfe/listeners/socketlisteners.rb +8 -5
  47. data/lib/openwfe/logging.rb +6 -3
  48. data/lib/openwfe/omixins.rb +8 -6
  49. data/lib/openwfe/orest/xmlcodec.rb +16 -12
  50. data/lib/openwfe/participants.rb +38 -0
  51. data/lib/openwfe/participants/participant.rb +1 -1
  52. data/lib/openwfe/participants/participantmap.rb +24 -10
  53. data/lib/openwfe/participants/participants.rb +4 -3
  54. data/lib/openwfe/participants/soapparticipants.rb +1 -1
  55. data/lib/openwfe/participants/socketparticipants.rb +1 -1
  56. data/lib/openwfe/rudefinitions.rb +7 -5
  57. data/lib/openwfe/storage/yamlcustom.rb +10 -10
  58. data/lib/openwfe/storage/yamlfilestorage.rb +12 -12
  59. data/lib/openwfe/tools/flowtracer.rb +6 -5
  60. data/lib/openwfe/util/dollar.rb +42 -85
  61. data/lib/openwfe/util/ometa.rb +1 -3
  62. data/lib/openwfe/util/workqueue.rb +1 -1
  63. data/lib/openwfe/utils.rb +33 -11
  64. data/lib/openwfe/version.rb +2 -2
  65. data/lib/openwfe/workitem.rb +76 -14
  66. data/lib/openwfe/worklist/storelocks.rb +9 -4
  67. data/lib/openwfe/worklist/storeparticipant.rb +1 -1
  68. data/test/back_0916_test.rb +101 -0
  69. data/test/bm/ft_26_load.rb +1 -1
  70. data/test/bm/ft_26b_load.rb +1 -1
  71. data/test/bm/ft_26c_load.rb +3 -2
  72. data/test/bm/ft_26d_load.rb +97 -0
  73. data/test/bm/ft_recu.rb +71 -0
  74. data/test/concurrence_test.rb +1 -1
  75. data/test/condition_test.rb +152 -0
  76. data/test/description_test.rb +12 -7
  77. data/test/eno_test.rb +1 -1
  78. data/test/expool_20031219_0916.tgz +0 -0
  79. data/test/fe_lookup_att_test.rb +1 -1
  80. data/test/fei_test.rb +16 -0
  81. data/test/file_persistence_test.rb +8 -12
  82. data/test/filep_cancel_test.rb +116 -0
  83. data/test/flowtestbase.rb +47 -25
  84. data/test/ft_0.rb +1 -1
  85. data/test/ft_10_loop.rb +29 -14
  86. data/test/{ft_10b_loop2.rb → ft_10b_loop.rb} +2 -11
  87. data/test/ft_11_ppd.rb +6 -17
  88. data/test/ft_11b_ppd.rb +1 -4
  89. data/test/ft_12_blockparticipant.rb +1 -1
  90. data/test/ft_13_eno.rb +1 -1
  91. data/test/ft_15_iterator.rb +1 -1
  92. data/test/ft_15b_iterator.rb +1 -1
  93. data/test/ft_17_condition.rb +6 -6
  94. data/test/ft_18_pname.rb +1 -1
  95. data/test/ft_20_cron.rb +1 -1
  96. data/test/ft_21_cron.rb +6 -4
  97. data/test/ft_22_history.rb +1 -1
  98. data/test/ft_23_when.rb +1 -1
  99. data/test/ft_23b_when.rb +18 -6
  100. data/test/ft_23c_wait.rb +8 -6
  101. data/test/ft_25_cancel.rb +7 -5
  102. data/test/ft_27_getflowpos.rb +22 -17
  103. data/test/ft_28_fileparticipant.rb +1 -2
  104. data/test/ft_2_concurrence.rb +1 -1
  105. data/test/ft_2b_concurrence.rb +25 -20
  106. data/test/ft_30_socketlistener.rb +0 -3
  107. data/test/ft_34_cancelwfid.rb +9 -9
  108. data/test/ft_35_localdefs.rb +0 -1
  109. data/test/ft_36_subprocids.rb +6 -6
  110. data/test/ft_38_tag.rb +3 -2
  111. data/test/ft_38b_tag.rb +229 -0
  112. data/test/ft_39_reserve.rb +3 -18
  113. data/test/ft_39b_reserve.rb +34 -5
  114. data/test/ft_3b_lookup_vf.rb +83 -0
  115. data/test/ft_40_defined.rb +2 -11
  116. data/test/ft_42_environments.rb +4 -6
  117. data/test/ft_44b_restore.rb +88 -22
  118. data/test/ft_45_citerator.rb +57 -11
  119. data/test/ft_49_condition.rb +4 -2
  120. data/test/ft_4_misc.rb +24 -3
  121. data/test/ft_50_xml_attribute.rb +17 -20
  122. data/test/ft_54_listen.rb +1 -1
  123. data/test/ft_54b_listen.rb +2 -2
  124. data/test/ft_56_timeout.rb +8 -1
  125. data/test/ft_57_a.rb +10 -10
  126. data/test/ft_59_ps.rb +49 -16
  127. data/test/ft_60_ecancel.rb +52 -10
  128. data/test/ft_63_pause.rb +8 -8
  129. data/test/ft_65_stringlaunch.rb +4 -6
  130. data/test/ft_67_schedlaunch.rb +4 -4
  131. data/test/ft_69_cancelmissing.rb +4 -2
  132. data/test/ft_70_lookupvar.rb +2 -2
  133. data/test/ft_72_lookup_processes.rb +2 -2
  134. data/test/ft_73_cancel_sub.rb +8 -8
  135. data/test/ft_77_segments.rb +38 -0
  136. data/test/ft_78_eval.rb +154 -0
  137. data/test/ft_79_tticket.rb +185 -0
  138. data/test/ft_80_spname.rb +95 -0
  139. data/test/ft_81_exp.rb +64 -0
  140. data/test/ft_82_trecu.rb +48 -0
  141. data/test/ft_83_badpause.rb +62 -0
  142. data/test/ft_84_updateexp.rb +125 -0
  143. data/test/ft_9b_cursor.rb +105 -0
  144. data/test/ft_tests.rb +14 -1
  145. data/test/hash_test.rb +7 -7
  146. data/test/hparticipant_test.rb +4 -4
  147. data/test/lookup_vf_test.rb +94 -0
  148. data/test/misc_test.rb +5 -3
  149. data/test/orest_test.rb +4 -3
  150. data/test/param_test.rb +12 -16
  151. data/test/participant_test.rb +36 -0
  152. data/test/pending.rb +10 -10
  153. data/test/rake_ltest.rb +1 -10
  154. data/test/rake_qtest.rb +7 -6
  155. data/test/raw_prog_test.rb +89 -121
  156. data/test/restart_cron_test.rb +84 -36
  157. data/test/restart_paused_test.rb +100 -0
  158. data/test/restart_sleep_test.rb +1 -1
  159. data/test/restart_tests.rb +1 -0
  160. data/test/restart_when_test.rb +33 -22
  161. data/test/ruby_procdef_test.rb +19 -18
  162. data/test/sec_test.rb +74 -35
  163. data/test/storage_test.rb +44 -0
  164. data/test/test.rb +3 -0
  165. data/test/timeout_test.rb +7 -18
  166. data/test/wfid_test.rb +2 -1
  167. data/test/wi_test.rb +29 -18
  168. metadata +121 -57
  169. data/lib/openwfe/expressions/raw_xml.rb +0 -176
  170. data/lib/openwfe/expressions/simplerep.rb +0 -266
  171. data/lib/openwfe/util/kotoba.rb +0 -236
  172. data/lib/openwfe/util/lru.rb +0 -171
  173. data/lib/openwfe/util/otime.rb +0 -246
  174. data/lib/openwfe/util/safe.rb +0 -160
  175. data/lib/openwfe/util/scheduler.rb +0 -1158
  176. data/test/cron_test.rb +0 -113
  177. data/test/cronline_test.rb +0 -60
  178. data/test/dollar_test.rb +0 -90
  179. data/test/kotoba_test.rb +0 -72
  180. data/test/lru_test.rb +0 -79
  181. data/test/safely_test.rb +0 -84
  182. data/test/scheduler_1_test.rb +0 -88
  183. data/test/scheduler_test.rb +0 -363
  184. data/test/time_test.rb +0 -84
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006-2007, Nicolas Modryzk and John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2008, Nicolas Modryzk and John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -40,9 +40,11 @@
40
40
 
41
41
  require 'fileutils'
42
42
 
43
+ #require 'rufus/lru'
44
+
43
45
  require 'openwfe/service'
44
- require 'openwfe/util/lru'
45
46
  require 'openwfe/flowexpressionid'
47
+ require 'openwfe/rudefinitions'
46
48
 
47
49
 
48
50
  module OpenWFE
@@ -63,29 +65,107 @@ module OpenWFE
63
65
  end
64
66
  get_expression_pool.add_observer(:remove) do |channel, fei|
65
67
  ldebug { ":delete for #{fei}" }
66
- self.delete(fei)
68
+ self.delete fei
67
69
  end
68
70
  end
69
71
 
72
+ #
73
+ # a human readable representation of the content of the expression
74
+ # storage.
75
+ #
76
+ # Warning : this will display the content of the real storage,
77
+ # (especially when called against a cache).
78
+ #
70
79
  def to_s
71
80
 
72
81
  s = "\n\n==== #{self.class} ===="
73
82
 
74
- self.each do |k, v|
83
+ find_expressions.each do |fexp|
84
+
75
85
  s << "\n"
76
- if v.kind_of?(RawExpression)
86
+ if fexp.kind_of?(RawExpression)
77
87
  s << "*raw"
78
88
  else
79
89
  s << " "
80
90
  end
81
- #s << v.to_s
82
- s << v.fei.to_s
83
- s << " key/value mismatch !" if k != v.fei
91
+ s << fexp.fei.to_s
84
92
  end
85
93
  s << "\n==== . ====\n"
86
94
 
87
95
  s
88
96
  end
97
+
98
+ #
99
+ # This method is used by the various implementations of
100
+ # find_expressions()
101
+ #
102
+ def does_match? (options, fexp_or_fei)
103
+
104
+ wfid = options[:wfid]
105
+ wfid_prefix = options[:wfid_prefix]
106
+ parent_wfid = options[:parent_wfid]
107
+
108
+ wfname = options[:wfname]
109
+ wfrevision = options[:wfrevision]
110
+
111
+ ic = options[:include_classes]
112
+ ec = options[:exclude_classes]
113
+ ic = Array(ic) if ic
114
+ ec = Array(ec) if ec
115
+
116
+ cs = options[:consider_subprocesses]
117
+
118
+ ap = options[:applied]
119
+
120
+ fexp, fei = if fexp_or_fei.is_a?(FlowExpressionId)
121
+ [ nil, fexp_or_fei ]
122
+ else
123
+ [ fexp_or_fei, fexp_or_fei.fei ]
124
+ end
125
+
126
+ #
127
+ # let's make it verbose...
128
+
129
+ if fexp
130
+ return false if (ap == true and not fexp.apply_time)
131
+ return false if (ap == false and fexp.apply_time)
132
+ return false unless class_accepted?(fexp, ic, ec)
133
+ end
134
+
135
+ return false \
136
+ if wfname and fei.wfname != wfname
137
+ return false \
138
+ if wfrevision and fei.wfrevision != wfrevision
139
+
140
+ return false \
141
+ if cs and fei.sub_instance_id != ""
142
+ return false \
143
+ if wfid and fei.wfid != wfid
144
+ return false \
145
+ if wfid_prefix and not fei.wfid.match("^#{wfid_prefix}")
146
+ return false \
147
+ if parent_wfid and not fei.parent_wfid == parent_wfid
148
+
149
+ true
150
+ end
151
+
152
+ #
153
+ # Returns true if the given expression is in the list of included
154
+ # classes or false if it's in the list of excluded classes...
155
+ #
156
+ # include_classes has precedence of exclude_classes.
157
+ #
158
+ def class_accepted? (fexp, include_classes, exclude_classes)
159
+
160
+ return false if include_classes and (not include_classes.find do |klazz|
161
+ fexp.is_a?(klazz)
162
+ end)
163
+ return false if exclude_classes and exclude_classes.find do |klazz|
164
+ fexp.is_a?(klazz)
165
+ end
166
+
167
+ true
168
+ end
89
169
  end
90
170
 
91
171
  #
@@ -115,8 +195,7 @@ module OpenWFE
115
195
 
116
196
  service_init(service_name, application_context)
117
197
 
118
- size = @application_context[:expression_cache_size]
119
- size = DEFAULT_SIZE unless size
198
+ size = @application_context[:expression_cache_size] || DEFAULT_SIZE
120
199
  size = MIN_SIZE unless size > MIN_SIZE
121
200
 
122
201
  linfo { "new() size is #{size}" }
@@ -152,59 +231,55 @@ module OpenWFE
152
231
 
153
232
  def []= (fei, fe)
154
233
 
155
- #linfo { "[]= caching #{fei}" }
234
+ ldebug { "[]= caching #{fei}" }
156
235
 
157
236
  @cache[fei.hash] = fe
158
237
  end
159
238
 
160
239
  def delete (fei)
240
+
161
241
  @cache.delete fei.hash
162
242
  end
163
243
 
164
244
  def length
245
+
165
246
  @cache.length
166
247
  end
167
248
 
168
249
  alias :size :length
169
250
 
170
251
  def clear
252
+
171
253
  @cache.clear
172
254
  end
173
255
 
174
256
  alias :purge :clear
175
257
 
176
258
  #
177
- # Simply redirects the call to the each_of_kind() method of
178
- # the 'real storage'.
259
+ # This implementations of find_expressions() immediately passes
260
+ # the call to the underlying real storage.
179
261
  #
180
- def each_of_kind (kind, &block)
262
+ def find_expressions (options={})
181
263
 
182
- get_real_storage.each_of_kind(kind, &block)
264
+ get_real_storage.find_expressions options
183
265
  end
184
266
 
185
267
  #
186
- # Passes a block to the expressions currently in the cache.
268
+ # Attempts at fetching the root expression of a given process
269
+ # instance.
187
270
  #
188
- def each (wfid_prefix=nil, &block)
271
+ def fetch_root (wfid)
189
272
 
190
- #@cache.each(&block)
273
+ #
274
+ # at first, look in the cache
191
275
 
192
- if wfid_prefix
193
- @cache.each do |fei, fexp|
194
- next unless fei.wfid.match "^#{wfid_prefix}"
195
- block.call fei, fexp
196
- end
197
- else
198
- @cache.each(&block)
199
- end
200
- end
276
+ @cache.each do |hashed_fei, fexp|
201
277
 
202
- #
203
- # This each() just delegates to the real storage each() method.
204
- #
205
- def real_each (wfid_prefix=nil, &block)
278
+ return fexp \
279
+ if fexp.fei.wfid == wfid and fexp.is_a?(DefineExpression)
280
+ end
206
281
 
207
- get_real_storage.each(wfid_prefix, &block)
282
+ get_real_storage.fetch_root wfid
208
283
  end
209
284
 
210
285
  protected
@@ -215,12 +290,12 @@ module OpenWFE
215
290
  #
216
291
  def get_real_storage
217
292
 
218
- return @real_storage if @real_storage
219
-
220
- @real_storage =
221
- @application_context[S_EXPRESSION_STORAGE + ".1"]
293
+ #return @real_storage if @real_storage
294
+ #@real_storage =
295
+ # @application_context[S_EXPRESSION_STORAGE + ".1"]
296
+ #@real_storage
222
297
 
223
- @real_storage
298
+ @application_context["expressionStorage.1"]
224
299
  end
225
300
  end
226
301
 
@@ -235,39 +310,94 @@ module OpenWFE
235
310
 
236
311
  def initialize (service_name, application_context)
237
312
 
238
- service_init(service_name, application_context)
313
+ service_init service_name, application_context
239
314
 
240
315
  observe_expool
241
316
  end
242
317
 
243
318
  alias :purge :clear
244
319
 
245
- #
320
+ #--
246
321
  # Allows to pass a block to each expressions of a given kind (type).
247
322
  #
248
- def each_of_kind (kind, &block)
323
+ #def each_of_kind (kind, &block)
324
+ # self.each_value do |fexp|
325
+ # block.call(fexp.fei, fexp) if fexp.kind_of?(kind)
326
+ # end
327
+ #end
328
+ #
329
+ # An iterator on the expression stored in here.
330
+ #
331
+ #def each (wfid_prefix=nil, &block)
332
+ # if wfid_prefix
333
+ # super() do |fei, fexp|
334
+ # next unless fei.wfid.match "^#{wfid_prefix}"
335
+ # block.call fei, fexp
336
+ # end
337
+ # else
338
+ # super(&block)
339
+ # end
340
+ #end
341
+ #alias :real_each :each
342
+ #++
249
343
 
250
- self.each_value do |fexp|
251
- block.call(fexp.fei, fexp) if fexp.kind_of?(kind)
344
+ #
345
+ # Finds expressions matching the given criteria (returns a list
346
+ # of expressions).
347
+ #
348
+ # This methods is called by the expression pool, it's thus not
349
+ # very "public" (not used directly by integrators, who should
350
+ # just focus on the methods provided by the Engine).
351
+ #
352
+ # :wfid ::
353
+ # will list only one process,
354
+ # <tt>:wfid => '20071208-gipijiwozo'</tt>
355
+ # :parent_wfid ::
356
+ # will list only one process, and its subprocesses,
357
+ # <tt>:parent_wfid => '20071208-gipijiwozo'</tt>
358
+ # :consider_subprocesses ::
359
+ # if true, "process-definition" expressions
360
+ # of subprocesses will be returned as well.
361
+ # :wfid_prefix ::
362
+ # allows your to query for specific workflow instance
363
+ # id prefixes. for example :
364
+ # <tt>:wfid_prefix => "200712"</tt>
365
+ # for the processes started in December.
366
+ # :include_classes ::
367
+ # excepts a class or an array of classes, only instances of these
368
+ # classes will be returned. Parent classes or mixins can be
369
+ # given.
370
+ # <tt>:includes_classes => OpenWFE::SequenceExpression</tt>
371
+ # :exclude_classes ::
372
+ # works as expected.
373
+ # :wfname ::
374
+ # will return only the expressions who belongs to the given
375
+ # workflow [name].
376
+ # :wfrevision ::
377
+ # usued in conjuction with :wfname, returns only the expressions
378
+ # with a given workflow revision.
379
+ # :applied ::
380
+ # if this option is set to true, will only return the expressions
381
+ # that have been applied (exp.apply_time != nil).
382
+ #
383
+ def find_expressions (options={})
384
+
385
+ values.find_all do |fexp|
386
+ does_match? options, fexp
252
387
  end
253
388
  end
254
389
 
255
- def each (wfid_prefix=nil, &block)
256
-
257
- if wfid_prefix
258
-
259
- super() do |fei, fexp|
260
- next unless fei.wfid.match "^#{wfid_prefix}"
261
- block.call fei, fexp
262
- end
263
- else
390
+ #
391
+ # Attempts at fetching the root expression of a given process
392
+ # instance.
393
+ #
394
+ def fetch_root (wfid)
264
395
 
265
- super(&block)
266
- end
396
+ find_expressions(
397
+ :wfid => wfid,
398
+ :include_classes => DefineExpression)[0]
267
399
  end
268
400
 
269
- alias :real_each :each
270
-
271
401
  end
272
402
 
273
403
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2007, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,6 @@ require 'openwfe/service'
44
44
  require 'openwfe/omixins'
45
45
  require 'openwfe/rudefinitions'
46
46
  require 'openwfe/flowexpressionid'
47
- require 'openwfe/util/otime'
48
47
  require 'openwfe/storage/yamlcustom'
49
48
  require 'openwfe/expool/journal_replay'
50
49
 
@@ -0,0 +1,233 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 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 'rexml/document'
41
+ require 'openwfe/expressions/rprocdef'
42
+
43
+
44
+ module OpenWFE
45
+
46
+ #
47
+ # A process definition parser.
48
+ #
49
+ # Currently supports XML, Ruby process pdefinitions, YAML and JSON.
50
+ #
51
+ module DefParser
52
+
53
+ #
54
+ # in : a process pdefinition
55
+ # out : a tree [ name, attributes, children ]
56
+ #
57
+ def self.parse (pdef)
58
+
59
+ return pdef \
60
+ if pdef.is_a?(Array)
61
+
62
+ return parse_string(pdef) \
63
+ if pdef.is_a?(String)
64
+
65
+ return pdef.do_make \
66
+ if pdef.is_a?(ProcessDefinition) or pdef.is_a?(Class)
67
+
68
+ return pdef.to_a \
69
+ if pdef.is_a?(SimpleExpRepresentation)
70
+ # for legacy stuff
71
+
72
+ raise "cannot handle pdefinition of class #{pdef.class.name}"
73
+ end
74
+
75
+ def self.parse_string (pdef)
76
+
77
+ pdef = pdef.strip
78
+
79
+ #return SimpleExpRepresentation.from_xml(param) \
80
+ return parse_xml(pdef) \
81
+ if pdef[0, 1] == "<"
82
+
83
+ return YAML.load(s) \
84
+ if pdef.match /^--- ./
85
+
86
+ #
87
+ # else it's some ruby code to eval
88
+
89
+ ProcessDefinition.eval_ruby_process_definition pdef, 2
90
+ end
91
+
92
+ #
93
+ # The process definition is expressed as XML, turn that into
94
+ # an expression tree.
95
+ #
96
+ def self.parse_xml (xml)
97
+
98
+ xml = REXML::Document.new(xml) \
99
+ if xml.is_a?(String)
100
+
101
+ xml = xml.root \
102
+ if xml.is_a?(REXML::Document)
103
+
104
+ if xml.is_a?(REXML::Text)
105
+
106
+ s = xml.to_s.strip
107
+
108
+ return s if s.length > 0
109
+
110
+ return nil
111
+ end
112
+
113
+ return nil if xml.is_a?(REXML::Comment)
114
+
115
+ # xml element thus...
116
+
117
+ name = xml.name
118
+
119
+ attributes = xml.attributes.inject({}) do |r, (k, v)|
120
+ r[k] = v
121
+ r
122
+ end
123
+
124
+ rep = [ name, attributes, [] ]
125
+
126
+ xml.children.each do |c|
127
+
128
+ #r = if c.is_a?(REXML::Element) and c.prefix != xml.prefix
129
+ # c
130
+ #else
131
+ # parse_xml c
132
+ #end
133
+ r = parse_xml c
134
+
135
+ rep.last << r if r
136
+ end
137
+
138
+ rep
139
+ end
140
+ end
141
+
142
+ #
143
+ # A set of methods for manipulating / querying a process expression tree
144
+ #
145
+ module ExpressionTree
146
+
147
+ #
148
+ # Extracts the description out of a process definition tree.
149
+ #
150
+ # TODO #14964 : add language support here
151
+ #
152
+ def self.get_description (tree)
153
+
154
+ return tree.last.first.to_s if tree.first == 'description'
155
+
156
+ tree.last.each do |child|
157
+ d = get_description(child)
158
+ return d if d
159
+ end
160
+
161
+ nil
162
+ end
163
+
164
+ #
165
+ # Returns a string containing the ruby code that generated this
166
+ # raw representation tree.
167
+ #
168
+ def self.to_code_s (tree, indentation = 0)
169
+
170
+ s = ""
171
+ tab = " "
172
+ ind = tab * indentation
173
+
174
+ s << ind
175
+ s << OpenWFE::make_safe(tree.first)
176
+
177
+ sa = ""
178
+ tree[1].each do |k, v|
179
+ sa << ", :#{OpenWFE::to_underscore(k)} => '#{v}'"
180
+ end
181
+ s << sa[1..-1] if sa.length > 0
182
+
183
+ if tree.last.length > 0
184
+ s << " do\n"
185
+ tree.last.each do |child|
186
+ #if child.respond_to?(:to_code_s)
187
+ if child.is_a?(Array) and child.size == 3 # and ...
188
+ s << to_code_s(child, indentation + 1)
189
+ else
190
+ s << ind
191
+ s << tab
192
+ s << "'#{child.to_s}'"
193
+ end
194
+ s << "\n"
195
+ end
196
+ s << ind
197
+ s << "end"
198
+ end
199
+
200
+ s
201
+ end
202
+
203
+ def self.to_xml (tree)
204
+
205
+ elt = REXML::Element.new tree.first
206
+
207
+ tree[1].each do |k, v|
208
+
209
+ elt.attributes[k] = v
210
+ end
211
+
212
+ tree.last.each do |child|
213
+
214
+ #if child.kind_of?(SimpleExpRepresentation)
215
+ if child.is_a?(Array) and child.size == 3
216
+
217
+ elt << to_xml(child)
218
+ else
219
+
220
+ elt << REXML::Text.new(child.to_s)
221
+ end
222
+ end
223
+
224
+ elt
225
+ end
226
+
227
+ def self.to_s (tree)
228
+
229
+ to_xml(tree).to_s
230
+ end
231
+ end
232
+ end
233
+