ruote 2.1.11 → 2.2.0
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.
- data/CHANGELOG.txt +60 -0
- data/CREDITS.txt +22 -4
- data/LICENSE.txt +1 -1
- data/README.rdoc +6 -7
- data/Rakefile +58 -59
- data/TODO.txt +137 -65
- data/couch_url.txt +1 -0
- data/jruby_issue.txt +32 -0
- data/lib/ruote.rb +1 -1
- data/lib/ruote/context.rb +12 -10
- data/lib/ruote/engine.rb +280 -145
- data/lib/ruote/engine/process_error.rb +5 -5
- data/lib/ruote/engine/process_status.rb +47 -28
- data/lib/ruote/exp/command.rb +7 -10
- data/lib/ruote/exp/commanded.rb +2 -2
- data/lib/ruote/exp/condition.rb +130 -43
- data/lib/ruote/exp/fe_add_branches.rb +2 -2
- data/lib/ruote/exp/fe_apply.rb +1 -1
- data/lib/ruote/exp/fe_cancel_process.rb +3 -3
- data/lib/ruote/exp/fe_command.rb +3 -3
- data/lib/ruote/exp/fe_concurrence.rb +4 -4
- data/lib/ruote/exp/fe_concurrent_iterator.rb +17 -5
- data/lib/ruote/exp/fe_cron.rb +3 -3
- data/lib/ruote/exp/fe_cursor.rb +5 -5
- data/lib/ruote/exp/fe_define.rb +3 -3
- data/lib/ruote/exp/fe_echo.rb +3 -3
- data/lib/ruote/exp/fe_equals.rb +2 -2
- data/lib/ruote/exp/fe_error.rb +2 -2
- data/lib/ruote/exp/fe_filter.rb +519 -0
- data/lib/ruote/exp/fe_forget.rb +9 -2
- data/lib/ruote/exp/fe_given.rb +154 -0
- data/lib/ruote/exp/fe_if.rb +16 -13
- data/lib/ruote/exp/fe_inc.rb +3 -3
- data/lib/ruote/exp/fe_iterator.rb +4 -4
- data/lib/ruote/exp/fe_let.rb +75 -0
- data/lib/ruote/exp/fe_listen.rb +68 -12
- data/lib/ruote/exp/fe_lose.rb +110 -0
- data/lib/ruote/exp/fe_noop.rb +1 -1
- data/lib/ruote/exp/{fe_when.rb → fe_once.rb} +25 -21
- data/lib/ruote/exp/fe_participant.rb +14 -17
- data/lib/ruote/exp/fe_redo.rb +10 -6
- data/lib/ruote/exp/fe_ref.rb +1 -1
- data/lib/ruote/exp/fe_registerp.rb +112 -0
- data/lib/ruote/exp/fe_reserve.rb +3 -3
- data/lib/ruote/exp/fe_restore.rb +2 -2
- data/lib/ruote/exp/fe_save.rb +2 -2
- data/lib/ruote/exp/fe_sequence.rb +3 -4
- data/lib/ruote/exp/fe_set.rb +16 -7
- data/lib/ruote/exp/fe_subprocess.rb +23 -1
- data/lib/ruote/exp/fe_that.rb +92 -0
- data/lib/ruote/exp/fe_undo.rb +3 -3
- data/lib/ruote/exp/fe_unregisterp.rb +71 -0
- data/lib/ruote/exp/fe_wait.rb +2 -2
- data/lib/ruote/exp/flowexpression.rb +153 -78
- data/lib/ruote/exp/iterator.rb +2 -2
- data/lib/ruote/exp/merge.rb +2 -2
- data/lib/ruote/exp/ro_attributes.rb +14 -12
- data/lib/ruote/exp/ro_filters.rb +136 -0
- data/lib/ruote/exp/ro_persist.rb +51 -35
- data/lib/ruote/exp/ro_variables.rb +18 -27
- data/lib/ruote/fei.rb +73 -33
- data/lib/ruote/id/mnemo_wfid_generator.rb +1 -1
- data/lib/ruote/id/wfid_generator.rb +11 -4
- data/lib/ruote/log/default_history.rb +122 -0
- data/lib/ruote/log/pretty.rb +36 -8
- data/lib/ruote/log/storage_history.rb +37 -5
- data/lib/ruote/log/test_logger.rb +26 -24
- data/lib/ruote/log/wait_logger.rb +5 -3
- data/lib/ruote/part/block_participant.rb +22 -11
- data/lib/ruote/part/engine_participant.rb +6 -7
- data/lib/ruote/part/local_participant.rb +6 -12
- data/lib/ruote/part/no_op_participant.rb +4 -4
- data/lib/ruote/part/null_participant.rb +4 -4
- data/lib/ruote/part/smtp_participant.rb +4 -4
- data/lib/ruote/part/storage_participant.rb +40 -20
- data/lib/ruote/part/template.rb +4 -4
- data/lib/ruote/participant.rb +0 -1
- data/lib/ruote/{parser.rb → reader.rb} +30 -25
- data/lib/ruote/{parser → reader}/ruby_dsl.rb +28 -11
- data/lib/ruote/{parser → reader}/xml.rb +6 -5
- data/lib/ruote/receiver/base.rb +35 -13
- data/lib/ruote/storage/base.rb +20 -18
- data/lib/ruote/storage/composite_storage.rb +10 -10
- data/lib/ruote/storage/fs_storage.rb +17 -10
- data/lib/ruote/storage/hash_storage.rb +29 -18
- data/lib/ruote/svc/dispatch_pool.rb +41 -14
- data/lib/ruote/svc/dollar_sub.rb +50 -17
- data/lib/ruote/svc/error_handler.rb +19 -11
- data/lib/ruote/svc/expression_map.rb +4 -4
- data/lib/ruote/svc/participant_list.rb +105 -100
- data/lib/ruote/svc/tracker.rb +58 -18
- data/lib/ruote/svc/treechecker.rb +51 -24
- data/lib/ruote/tree_dot.rb +4 -4
- data/lib/ruote/util/filter.rb +440 -0
- data/lib/ruote/util/hashdot.rb +4 -4
- data/lib/ruote/util/look.rb +2 -6
- data/lib/ruote/util/lookup.rb +9 -7
- data/lib/ruote/util/misc.rb +40 -8
- data/lib/ruote/util/ometa.rb +1 -1
- data/lib/ruote/util/serializer.rb +4 -4
- data/lib/ruote/util/subprocess.rb +29 -9
- data/lib/ruote/util/time.rb +4 -4
- data/lib/ruote/util/tree.rb +3 -3
- data/lib/ruote/version.rb +2 -2
- data/lib/ruote/worker.rb +55 -32
- data/lib/ruote/workitem.rb +64 -11
- data/ruote.gemspec +31 -302
- data/test/bm/launch_bench.rb +37 -0
- data/test/functional/base.rb +60 -18
- data/test/functional/concurrent_base.rb +2 -2
- data/test/functional/ct_0_concurrence.rb +1 -1
- data/test/functional/ct_1_iterator.rb +1 -1
- data/test/functional/ct_2_cancel.rb +1 -1
- data/test/functional/eft_0_process_definition.rb +2 -2
- data/test/functional/eft_10_cancel_process.rb +1 -1
- data/test/functional/eft_11_wait.rb +19 -11
- data/test/functional/eft_12_listen.rb +79 -13
- data/test/functional/eft_13_iterator.rb +13 -10
- data/test/functional/eft_14_cursor.rb +98 -9
- data/test/functional/eft_15_loop.rb +6 -4
- data/test/functional/eft_16_if.rb +12 -0
- data/test/functional/eft_18_concurrent_iterator.rb +31 -32
- data/test/functional/eft_19_reserve.rb +4 -4
- data/test/functional/eft_1_echo.rb +9 -0
- data/test/functional/eft_20_save.rb +4 -4
- data/test/functional/{eft_28_when.rb → eft_28_once.rb} +33 -7
- data/test/functional/eft_30_ref.rb +17 -2
- data/test/functional/eft_31_registerp.rb +130 -0
- data/test/functional/eft_32_lose.rb +93 -0
- data/test/functional/eft_33_let.rb +31 -0
- data/test/functional/eft_34_given.rb +123 -0
- data/test/functional/eft_35_filter.rb +269 -0
- data/test/functional/eft_3_participant.rb +4 -6
- data/test/functional/eft_4_set.rb +16 -2
- data/test/functional/eft_5_subprocess.rb +2 -4
- data/test/functional/eft_6_concurrence.rb +29 -29
- data/test/functional/eft_8_undo.rb +39 -3
- data/test/functional/eft_9_redo.rb +94 -2
- data/test/functional/ft_10_dollar.rb +81 -2
- data/test/functional/ft_11_recursion.rb +13 -17
- data/test/functional/ft_12_launchitem.rb +9 -5
- data/test/functional/ft_13_variables.rb +7 -9
- data/test/functional/ft_14_re_apply.rb +6 -9
- data/test/functional/ft_15_timeout.rb +18 -18
- data/test/functional/ft_16_participant_params.rb +1 -3
- data/test/functional/ft_17_conditional.rb +25 -2
- data/test/functional/ft_18_kill.rb +65 -12
- data/test/functional/ft_1_process_status.rb +147 -71
- data/test/functional/ft_20_storage_participant.rb +0 -1
- data/test/functional/ft_21_forget.rb +82 -1
- data/test/functional/{ft_24_block_participants.rb → ft_24_block_participant.rb} +42 -11
- data/test/functional/ft_25_receiver.rb +47 -17
- data/test/functional/{ft_26_participant_timeout.rb → ft_26_participant_rtimeout.rb} +56 -19
- data/test/functional/ft_29_part_template.rb +6 -5
- data/test/functional/ft_2_errors.rb +21 -37
- data/test/functional/ft_30_smtp_participant.rb +1 -1
- data/test/functional/ft_31_part_blocking.rb +8 -6
- data/test/functional/ft_34_cursor_rewind.rb +13 -10
- data/test/functional/ft_35_add_service.rb +1 -1
- data/test/functional/ft_36_storage_history.rb +24 -1
- data/test/functional/ft_37_default_history.rb +109 -0
- data/test/functional/ft_38_participant_more.rb +10 -10
- data/test/functional/ft_39_wait_for.rb +12 -9
- data/test/functional/ft_3_participant_registration.rb +111 -32
- data/test/functional/ft_40_wait_logger.rb +2 -1
- data/test/functional/ft_41_participants.rb +30 -4
- data/test/functional/ft_43_participant_on_reply.rb +6 -23
- data/test/functional/ft_45_participant_accept.rb +4 -4
- data/test/functional/ft_46_launch_single.rb +36 -2
- data/test/functional/ft_47_wfid_generator.rb +54 -0
- data/test/functional/ft_48_lose.rb +112 -0
- data/test/functional/ft_49_engine_on_error.rb +201 -0
- data/test/functional/ft_4_cancel.rb +66 -6
- data/test/functional/ft_50_engine_config.rb +22 -0
- data/test/functional/ft_51_misc.rb +67 -0
- data/test/functional/ft_52_case.rb +134 -0
- data/test/functional/ft_53_engine_on_terminate.rb +95 -0
- data/test/functional/ft_54_patterns.rb +104 -0
- data/test/functional/{ft_37_engine_participant.rb → ft_55_engine_participant.rb} +4 -5
- data/test/functional/ft_56_filter_attribute.rb +259 -0
- data/test/functional/ft_5_on_error.rb +77 -30
- data/test/functional/ft_6_on_cancel.rb +66 -11
- data/test/functional/ft_7_tags.rb +94 -5
- data/test/functional/ft_8_participant_consumption.rb +36 -5
- data/test/functional/ft_9_subprocesses.rb +10 -10
- data/test/functional/rt_1_listen.rb +3 -3
- data/test/functional/{rt_3_when.rb → rt_3_once.rb} +4 -4
- data/test/functional/storage_helper.rb +15 -13
- data/test/functional/test.rb +1 -3
- data/test/test_helper.rb +0 -8
- data/test/unit/storage.rb +154 -10
- data/test/unit/{ut_0_ruby_parser.rb → ut_0_ruby_reader.rb} +61 -11
- data/test/unit/ut_11_lookup.rb +7 -0
- data/test/unit/ut_13_serializer.rb +1 -1
- data/test/unit/ut_15_util.rb +23 -0
- data/test/unit/{ut_16_parser.rb → ut_16_reader.rb} +11 -13
- data/test/unit/ut_1_fei.rb +57 -10
- data/test/unit/ut_20_composite_storage.rb +25 -11
- data/test/unit/ut_21_participant_list.rb +47 -0
- data/test/unit/ut_22_filter.rb +903 -0
- data/test/unit/ut_3_wait_logger.rb +2 -6
- data/test/unit/ut_6_condition.rb +164 -17
- data/test/unit/ut_7_workitem.rb +28 -0
- data/test/unit/ut_8_tree_to_dot.rb +1 -1
- data/test/unit/{ut_9_xml_parser.rb → ut_9_xml_reader.rb} +5 -5
- metadata +108 -84
- data/.gitignore +0 -4
- data/examples/barley.rb +0 -391
- data/examples/flickr_report.rb +0 -107
- data/examples/pong.rb +0 -37
- data/examples/ruote_quickstart.rb +0 -43
- data/examples/web_first_page.rb +0 -68
- data/lib/ruote/part/hash_participant.rb +0 -91
- data/test/README.rdoc +0 -15
- data/test/functional/crunner.sh +0 -19
- data/test/pdef.xml +0 -7
- data/test/unit/ut_2_wfidgen.rb +0 -21
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -30,7 +30,7 @@ module Ruote
|
|
|
30
30
|
#
|
|
31
31
|
class ProcessError
|
|
32
32
|
|
|
33
|
-
def initialize
|
|
33
|
+
def initialize(h)
|
|
34
34
|
@h = h
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -65,7 +65,7 @@ module Ruote
|
|
|
65
65
|
# A shortcut for modifying the tree of an expression when it has had
|
|
66
66
|
# an error upon being applied.
|
|
67
67
|
#
|
|
68
|
-
def tree=
|
|
68
|
+
def tree=(t)
|
|
69
69
|
@h['msg']['tree'] = t
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -83,7 +83,7 @@ module Ruote
|
|
|
83
83
|
# Exposes the workitem fields directly.
|
|
84
84
|
#
|
|
85
85
|
def fields
|
|
86
|
-
@h['msg']['workitem']['fields']
|
|
86
|
+
@h['msg']['workitem'] && @h['msg']['workitem']['fields']
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# Returns an instance of Ruote::Workitem
|
|
@@ -94,7 +94,7 @@ module Ruote
|
|
|
94
94
|
|
|
95
95
|
protected
|
|
96
96
|
|
|
97
|
-
def to_dot
|
|
97
|
+
def to_dot(opts)
|
|
98
98
|
|
|
99
99
|
i = fei.to_storage_id
|
|
100
100
|
label = "error : #{message.gsub(/"/, "'")}"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -38,6 +38,10 @@ module Ruote
|
|
|
38
38
|
#
|
|
39
39
|
attr_reader :expressions
|
|
40
40
|
|
|
41
|
+
# Returns the expression at the root of the process instance.
|
|
42
|
+
#
|
|
43
|
+
attr_reader :root_expression
|
|
44
|
+
|
|
41
45
|
# An array of the workitems currently in the storage participant for this
|
|
42
46
|
# process instance.
|
|
43
47
|
#
|
|
@@ -55,7 +59,7 @@ module Ruote
|
|
|
55
59
|
#
|
|
56
60
|
attr_reader :schedules
|
|
57
61
|
|
|
58
|
-
def initialize
|
|
62
|
+
def initialize(context, expressions, stored_workitems, errors, schedules)
|
|
59
63
|
|
|
60
64
|
@expressions = expressions.collect { |e|
|
|
61
65
|
Ruote::Exp::FlowExpression.from_h(context, e) }
|
|
@@ -67,16 +71,8 @@ module Ruote
|
|
|
67
71
|
|
|
68
72
|
@errors = errors.sort! { |a, b| a.fei.expid <=> b.fei.expid }
|
|
69
73
|
@schedules = schedules.sort! { |a, b| a['owner'].sid <=> b['owner'].sid }
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Returns the expression at the root of the process instance.
|
|
73
|
-
#
|
|
74
|
-
def root_expression
|
|
75
|
-
|
|
76
|
-
#@expressions.find { |e| e.fei.expid == '0' && e.fei.sub_wfid == nil }
|
|
77
|
-
# vanilla implementation
|
|
78
74
|
|
|
79
|
-
root_expressions.first
|
|
75
|
+
@root_expression = root_expressions.first
|
|
80
76
|
end
|
|
81
77
|
|
|
82
78
|
# Returns a list of all the expressions that have no parent expression.
|
|
@@ -87,7 +83,7 @@ module Ruote
|
|
|
87
83
|
roots = @expressions.select { |e| e.h.parent_id == nil }
|
|
88
84
|
|
|
89
85
|
roots = roots.inject({}) { |h, e|
|
|
90
|
-
h["#{e.h.fei['expid']}__#{e.h.fei['
|
|
86
|
+
h["#{e.h.fei['expid']}__#{e.h.fei['subid']}"] = e; h
|
|
91
87
|
}
|
|
92
88
|
|
|
93
89
|
roots.keys.sort.collect { |k| roots[k] }
|
|
@@ -96,7 +92,7 @@ module Ruote
|
|
|
96
92
|
# Given an expression id, returns the root (top ancestor) for its
|
|
97
93
|
# expression.
|
|
98
94
|
#
|
|
99
|
-
def root_expression_for
|
|
95
|
+
def root_expression_for(fei)
|
|
100
96
|
|
|
101
97
|
sfei = Ruote.sid(fei)
|
|
102
98
|
|
|
@@ -112,7 +108,7 @@ module Ruote
|
|
|
112
108
|
#
|
|
113
109
|
def variables
|
|
114
110
|
|
|
115
|
-
root_expression.variables
|
|
111
|
+
@root_expression && @root_expression.variables
|
|
116
112
|
end
|
|
117
113
|
|
|
118
114
|
# Returns a hash fei => variable_hash containing all the variable bindings
|
|
@@ -131,7 +127,7 @@ module Ruote
|
|
|
131
127
|
#
|
|
132
128
|
def tags
|
|
133
129
|
|
|
134
|
-
variables.select { |k, v| FlowExpressionId.is_a_fei?(v) }
|
|
130
|
+
Hash[variables.select { |k, v| FlowExpressionId.is_a_fei?(v) }]
|
|
135
131
|
end
|
|
136
132
|
|
|
137
133
|
# Returns a hash tagname => array of feis of all the tags set in the process
|
|
@@ -163,7 +159,8 @@ module Ruote
|
|
|
163
159
|
#
|
|
164
160
|
def definition_name
|
|
165
161
|
|
|
166
|
-
root_expression
|
|
162
|
+
@root_expression && (
|
|
163
|
+
@root_expression.attribute('name') || @root_expression.attribute_text)
|
|
167
164
|
end
|
|
168
165
|
|
|
169
166
|
# For a process
|
|
@@ -177,7 +174,7 @@ module Ruote
|
|
|
177
174
|
#
|
|
178
175
|
def definition_revision
|
|
179
176
|
|
|
180
|
-
root_expression.attribute('revision')
|
|
177
|
+
@root_expression && @root_expression.attribute('revision')
|
|
181
178
|
end
|
|
182
179
|
|
|
183
180
|
# Returns the 'position' of the process.
|
|
@@ -198,9 +195,16 @@ module Ruote
|
|
|
198
195
|
def position
|
|
199
196
|
|
|
200
197
|
workitems.collect { |wi|
|
|
198
|
+
|
|
201
199
|
r = [ wi.fei.sid, wi.participant_name ]
|
|
202
|
-
|
|
200
|
+
|
|
201
|
+
params = (wi.fields['params'] || {}).dup
|
|
203
202
|
params.delete('ref')
|
|
203
|
+
|
|
204
|
+
if err = errors.find { |e| e.fei == wi.fei }
|
|
205
|
+
params['error'] = err.message
|
|
206
|
+
end
|
|
207
|
+
|
|
204
208
|
r << params
|
|
205
209
|
r
|
|
206
210
|
}
|
|
@@ -245,14 +249,14 @@ module Ruote
|
|
|
245
249
|
#
|
|
246
250
|
def original_tree
|
|
247
251
|
|
|
248
|
-
root_expression.original_tree
|
|
252
|
+
@root_expression && @root_expression.original_tree
|
|
249
253
|
end
|
|
250
254
|
|
|
251
255
|
# Returns a Time instance indicating when the process instance was launched.
|
|
252
256
|
#
|
|
253
257
|
def launched_time
|
|
254
258
|
|
|
255
|
-
root_expression.created_time
|
|
259
|
+
@root_expression && @root_expression.created_time
|
|
256
260
|
end
|
|
257
261
|
|
|
258
262
|
def to_s
|
|
@@ -267,18 +271,33 @@ module Ruote
|
|
|
267
271
|
|
|
268
272
|
def inspect
|
|
269
273
|
|
|
274
|
+
vars = variables rescue nil
|
|
275
|
+
avars = all_variables.inject({}) { |h, (k, v)| h[Ruote.sid(k)] = v; h }
|
|
276
|
+
|
|
270
277
|
s = [ "== #{self.class} ==" ]
|
|
271
278
|
s << " expressions : #{@expressions.size}"
|
|
272
279
|
@expressions.each do |e|
|
|
273
|
-
s << " #{e.fei.to_storage_id}
|
|
280
|
+
s << " #{e.fei.to_storage_id}"
|
|
281
|
+
s << " | #{e.name}"
|
|
282
|
+
s << " | #{e.attributes.inspect}"
|
|
283
|
+
s << " `-parent--> #{e.h.parent_id ? e.parent_id.to_storage_id : 'nil'}"
|
|
274
284
|
end
|
|
285
|
+
s << " schedules : #{@schedules.size}"
|
|
286
|
+
s << " stored workitems : #{@stored_workitems.size}"
|
|
287
|
+
s << " variables : #{vars.inspect}"
|
|
288
|
+
s << " all_variables : #{avars.inspect}"
|
|
275
289
|
s << " errors : #{@errors.size}"
|
|
276
290
|
@errors.each do |e|
|
|
291
|
+
s << " ***"
|
|
277
292
|
s << " #{e.fei.to_storage_id} :" if e.fei
|
|
278
|
-
s << " #{e.
|
|
293
|
+
s << " action : #{e.action}"
|
|
294
|
+
s << " message : #{e.message}"
|
|
295
|
+
s << " trace :"
|
|
296
|
+
e.trace.split("\n").each do |line|
|
|
297
|
+
s << " #{line}"
|
|
298
|
+
end
|
|
299
|
+
s << " fields : #{e.fields.inspect}"
|
|
279
300
|
end
|
|
280
|
-
s << " schedules : #{@schedules.size}"
|
|
281
|
-
s << " stored workitems : #{@stored_workitems.size}"
|
|
282
301
|
|
|
283
302
|
s.join("\n") + "\n"
|
|
284
303
|
end
|
|
@@ -286,7 +305,7 @@ module Ruote
|
|
|
286
305
|
# Returns a 'dot' representation of the process. A graph describing
|
|
287
306
|
# the tree of flow expressions that compose the process.
|
|
288
307
|
#
|
|
289
|
-
def to_dot
|
|
308
|
+
def to_dot(opts={})
|
|
290
309
|
|
|
291
310
|
s = [ "digraph \"process wfid #{wfid}\" {" ]
|
|
292
311
|
@expressions.each { |e| s.push(*e.send(:to_dot, opts)) }
|
|
@@ -347,7 +366,7 @@ module Ruote
|
|
|
347
366
|
|
|
348
367
|
protected
|
|
349
368
|
|
|
350
|
-
def original_tree_from_parent
|
|
369
|
+
def original_tree_from_parent(e)
|
|
351
370
|
|
|
352
371
|
parent = @expressions.find { |exp| exp.fei == e.parent_id }
|
|
353
372
|
|
|
@@ -355,14 +374,14 @@ module Ruote
|
|
|
355
374
|
end
|
|
356
375
|
end
|
|
357
376
|
|
|
358
|
-
def self.decompose_tree
|
|
377
|
+
def self.decompose_tree(t, pos='0', h={})
|
|
359
378
|
|
|
360
379
|
h[pos] = t[0, 2]
|
|
361
380
|
t[2].each_with_index { |c, i| decompose_tree(c, "#{pos}_#{i}", h) }
|
|
362
381
|
h
|
|
363
382
|
end
|
|
364
383
|
|
|
365
|
-
def self.recompose_tree
|
|
384
|
+
def self.recompose_tree(h, pos='0')
|
|
366
385
|
|
|
367
386
|
t = h[pos]
|
|
368
387
|
|
data/lib/ruote/exp/command.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -37,7 +37,7 @@ module Ruote::Exp
|
|
|
37
37
|
|
|
38
38
|
# TODO : :ignore_workitem / :disallow => 'workitem' thing ?
|
|
39
39
|
|
|
40
|
-
def get_command
|
|
40
|
+
def get_command(workitem)
|
|
41
41
|
|
|
42
42
|
command, step = workitem['fields'].delete(F_COMMAND)
|
|
43
43
|
command, step = lookup_attribute_command(workitem) unless command
|
|
@@ -57,30 +57,27 @@ module Ruote::Exp
|
|
|
57
57
|
[ command, step ]
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def set_command
|
|
60
|
+
def set_command(workitem, command, step=nil)
|
|
61
61
|
|
|
62
62
|
workitem['fields'][F_COMMAND] = [ command, step ]
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
def lookup_attribute_command
|
|
65
|
+
def lookup_attribute_command(workitem)
|
|
66
66
|
|
|
67
67
|
lookup_att_com('if', workitem) || lookup_att_com('unless', workitem)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
def lookup_att_com
|
|
70
|
+
def lookup_att_com(dir, workitem)
|
|
71
71
|
|
|
72
72
|
ATT_COMMANDS.each do |com|
|
|
73
73
|
|
|
74
|
-
c =
|
|
75
|
-
attribute("#{com}_#{dir}", workitem) ||
|
|
76
|
-
attribute("#{com}-#{dir}", workitem)
|
|
74
|
+
c = attribute("#{com}_#{dir}", workitem)
|
|
77
75
|
|
|
78
76
|
next unless c
|
|
79
77
|
|
|
80
78
|
c = Condition.true?(c)
|
|
81
79
|
|
|
82
|
-
return [ com, nil ]
|
|
83
|
-
if (dir == 'if' && c) || (dir == 'unless' && ( ! c))
|
|
80
|
+
return [ com, nil ] if (dir == 'if' && c) || (dir == 'unless' && ( ! c))
|
|
84
81
|
end
|
|
85
82
|
|
|
86
83
|
nil
|
data/lib/ruote/exp/commanded.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -36,7 +36,7 @@ module Ruote::Exp
|
|
|
36
36
|
|
|
37
37
|
include CommandMixin
|
|
38
38
|
|
|
39
|
-
def reply
|
|
39
|
+
def reply(workitem)
|
|
40
40
|
|
|
41
41
|
workitem = h.command_workitem || workitem
|
|
42
42
|
h.command_workitem = nil
|
data/lib/ruote/exp/condition.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2005-
|
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
|
3
3
|
#
|
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -25,12 +25,32 @@
|
|
|
25
25
|
|
|
26
26
|
module Ruote::Exp
|
|
27
27
|
|
|
28
|
+
#
|
|
29
|
+
# A few helper methods for evaluating :if and :unless expression
|
|
30
|
+
# attributes in process definitions.
|
|
31
|
+
#
|
|
28
32
|
module Condition
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
#
|
|
35
|
+
# A runtime error for unusable comparison strings.
|
|
36
|
+
#
|
|
37
|
+
class ConditionError < RuntimeError
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
def initialize(code)
|
|
40
|
+
super(
|
|
41
|
+
"couldn't interpret >#{code}<, " +
|
|
42
|
+
"if it comes from a ${xx} construct, please use ${\"xx} or ${'yy}")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
REGEXES = {
|
|
47
|
+
'evl_set' => /^(.+?)( +is)?( +not)?( +set)$/,
|
|
48
|
+
'evl_null' => /^(.+?)( +is)?( +not)?( +null)$/,
|
|
49
|
+
'evl_empty' => /^(.+[\]}"'])( +is)?( +not)?( +empty)$/,
|
|
50
|
+
'evl_in' => /^(.+?)( +is)?( +not)?( +in +)(\[.*\]|\{.*\})$/
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def self.apply?(sif, sunless)
|
|
34
54
|
|
|
35
55
|
return (true?(sif)) if sif
|
|
36
56
|
return ( ! true?(sunless)) if sunless
|
|
@@ -38,77 +58,144 @@ module Ruote::Exp
|
|
|
38
58
|
true
|
|
39
59
|
end
|
|
40
60
|
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
def self.true? (conditional)
|
|
61
|
+
# Returns true if the given conditional string evaluates to true.
|
|
62
|
+
#
|
|
63
|
+
def self.true?(conditional)
|
|
45
64
|
|
|
46
|
-
conditional = unescape(conditional)
|
|
65
|
+
conditional = unescape(conditional.to_s)
|
|
47
66
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
else
|
|
53
|
-
to_b(conditional)
|
|
67
|
+
REGEXES.each do |method, regex|
|
|
68
|
+
if m = regex.match(conditional)
|
|
69
|
+
return self.send(method, m)
|
|
70
|
+
end
|
|
54
71
|
end
|
|
72
|
+
|
|
73
|
+
evl(conditional) ? true : false
|
|
74
|
+
|
|
75
|
+
rescue ArgumentError => ae
|
|
76
|
+
|
|
77
|
+
raise ConditionError.new(conditional)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Evaluates the given [conditional] code string and returns the
|
|
81
|
+
# result.
|
|
82
|
+
#
|
|
83
|
+
# Note : this is not a full Ruby evaluation !
|
|
84
|
+
#
|
|
85
|
+
def self.eval(code)
|
|
86
|
+
|
|
87
|
+
evl(code)
|
|
88
|
+
|
|
89
|
+
rescue ArgumentError => ae
|
|
90
|
+
|
|
91
|
+
raise ConditionError.new(code)
|
|
55
92
|
end
|
|
56
93
|
|
|
57
94
|
protected
|
|
58
95
|
|
|
59
|
-
def self.
|
|
96
|
+
def self.parse(conditional)
|
|
60
97
|
|
|
61
|
-
|
|
98
|
+
Rufus::TreeChecker.parse(conditional)
|
|
62
99
|
|
|
63
|
-
|
|
100
|
+
rescue NoMethodError => nme
|
|
64
101
|
|
|
65
|
-
|
|
66
|
-
|
|
102
|
+
raise NoMethodError.new(
|
|
103
|
+
"/!\\ please upgrade your rufus-treechecker gem /!\\"
|
|
104
|
+
)
|
|
67
105
|
|
|
68
|
-
|
|
106
|
+
rescue => e
|
|
107
|
+
|
|
108
|
+
[ :false ]
|
|
69
109
|
end
|
|
70
110
|
|
|
71
|
-
def self.unescape
|
|
111
|
+
def self.unescape(s)
|
|
72
112
|
|
|
73
|
-
s
|
|
113
|
+
s.gsub('&', '&').gsub('>', '>').gsub('<', '<')
|
|
74
114
|
end
|
|
75
115
|
|
|
76
|
-
|
|
116
|
+
COMPARATORS = %w[ == > < != >= <= ].collect { |c| c.to_sym }
|
|
77
117
|
|
|
78
|
-
|
|
118
|
+
def self.evl(tree)
|
|
79
119
|
|
|
80
|
-
|
|
81
|
-
|
|
120
|
+
return evl(parse(tree)) if tree.is_a?(String)
|
|
121
|
+
|
|
122
|
+
return nil if tree == []
|
|
123
|
+
|
|
124
|
+
return tree.last if tree.first == :str
|
|
125
|
+
return tree.last if tree.first == :lit
|
|
126
|
+
return tree.last.to_s if tree.first == :const
|
|
127
|
+
return nil if tree == [ :nil ]
|
|
128
|
+
return true if tree == [ :true ]
|
|
129
|
+
return false if tree == [ :false ]
|
|
82
130
|
|
|
83
|
-
|
|
131
|
+
return ( ! evl(tree.last)) if tree.first == :not
|
|
84
132
|
|
|
85
|
-
return (
|
|
133
|
+
return evl(tree[1]) && evl(tree[2]) if tree[0] == :and
|
|
134
|
+
return evl(tree[1]) || evl(tree[2]) if tree[0] == :or
|
|
86
135
|
|
|
87
|
-
|
|
88
|
-
|
|
136
|
+
return tree[1..-1].collect { |e| evl(e) } if tree[0] == :array
|
|
137
|
+
return Hash.[](*tree[1..-1].collect { |e| evl(e) }) if tree[0] == :hash
|
|
89
138
|
|
|
90
|
-
if
|
|
91
|
-
|
|
92
|
-
b = m[3]
|
|
139
|
+
if tree[0] == :match3
|
|
140
|
+
return evl(tree[2]) =~ evl(tree[1])
|
|
93
141
|
end
|
|
142
|
+
if tree[0] == :call && tree[2] == :=~
|
|
143
|
+
return evl(tree[1]) =~ Regexp.new(evl(tree.last.last).to_s)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if tree[0] == :call && COMPARATORS.include?(tree[2])
|
|
147
|
+
return evl(tree[1]).send(tree[2], evl(tree.last.last))
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
return flatten(tree) if tree[0] == :call
|
|
151
|
+
|
|
152
|
+
raise ArgumentError
|
|
153
|
+
|
|
154
|
+
#require 'ruby2ruby'
|
|
155
|
+
#Ruby2Ruby.new.process(Sexp.from_array(tree))
|
|
156
|
+
# returns the raw Ruby as a String
|
|
157
|
+
# it's nice but "Loan/Grant" becomes "(Loan / Grant)"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
KEYWORDS = %w[ call const arglist ].collect { |w| w.to_sym }
|
|
161
|
+
|
|
162
|
+
def self.flatten(tree)
|
|
94
163
|
|
|
95
|
-
|
|
96
|
-
|
|
164
|
+
(tree.flatten - KEYWORDS).collect { |e| e.nil? ? ' ' : e.to_s }.join.strip
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def self.evl_set(match)
|
|
168
|
+
|
|
169
|
+
set = evl(match[1])
|
|
170
|
+
set = set != nil && set != ''
|
|
171
|
+
set = false if match[1].match(/is$/) && match[2].nil?
|
|
172
|
+
|
|
173
|
+
match[3].nil? ? set : ( ! set)
|
|
174
|
+
end
|
|
97
175
|
|
|
98
|
-
|
|
99
|
-
|
|
176
|
+
def self.evl_empty(match)
|
|
177
|
+
|
|
178
|
+
object = evl(match[1])
|
|
179
|
+
|
|
180
|
+
empty = if object.respond_to?(:empty?)
|
|
181
|
+
object.empty?
|
|
182
|
+
elsif object.nil?
|
|
183
|
+
true
|
|
184
|
+
else
|
|
185
|
+
false
|
|
186
|
+
end
|
|
100
187
|
|
|
101
|
-
|
|
188
|
+
( ! match[3].nil? ^ empty)
|
|
102
189
|
end
|
|
103
190
|
|
|
104
|
-
def self.
|
|
191
|
+
def self.evl_null(match)
|
|
105
192
|
|
|
106
|
-
|
|
193
|
+
( ! match[3].nil? ^ evl(match[1]).nil?)
|
|
107
194
|
end
|
|
108
195
|
|
|
109
|
-
def self.
|
|
196
|
+
def self.evl_in(match)
|
|
110
197
|
|
|
111
|
-
|
|
198
|
+
( ! match[3].nil? ^ evl(match[5]).include?(evl(match[1]))) rescue false
|
|
112
199
|
end
|
|
113
200
|
end
|
|
114
201
|
end
|