openwferu 0.9.3 → 0.9.4
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/examples/flowtracing.rb +22 -0
- data/lib/openwfe/contextual.rb +5 -2
- data/lib/openwfe/def.rb +47 -0
- data/lib/openwfe/engine/engine.rb +1 -1
- data/lib/openwfe/engine/file_persisted_engine.rb +3 -5
- data/lib/openwfe/expool/expressionpool.rb +45 -6
- data/lib/openwfe/expool/history.rb +117 -0
- data/lib/openwfe/expool/yamlexpstorage.rb +21 -4
- data/lib/openwfe/expressions/environment.rb +3 -0
- data/lib/openwfe/expressions/expressionmap.rb +1 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +22 -12
- data/lib/openwfe/expressions/fe_iterator.rb +3 -1
- data/lib/openwfe/expressions/fe_participant.rb +1 -4
- data/lib/openwfe/expressions/fe_raw.rb +2 -2
- data/lib/openwfe/expressions/fe_time.rb +184 -10
- data/lib/openwfe/expressions/fe_utils.rb +10 -0
- data/lib/openwfe/expressions/flowexpression.rb +3 -1
- data/lib/openwfe/expressions/raw_prog.rb +1 -1
- data/lib/openwfe/expressions/timeout.rb +47 -13
- data/lib/openwfe/flowexpressionid.rb +9 -1
- data/lib/openwfe/participants/csvparticipant.rb +127 -0
- data/lib/openwfe/participants/participant.rb +1 -0
- data/lib/openwfe/participants/participants.rb +26 -3
- data/lib/openwfe/rest/controlclient.rb +3 -3
- data/lib/openwfe/rest/worklistclient.rb +6 -8
- data/lib/openwfe/rest/xmlcodec.rb +6 -6
- data/lib/openwfe/rudefinitions.rb +6 -13
- data/lib/openwfe/storage/yamlfilestorage.rb +1 -1
- data/lib/openwfe/tools/flowtracer.rb +80 -0
- data/lib/openwfe/util/csvtable.rb +378 -0
- data/lib/openwfe/util/dollar.rb +24 -7
- data/lib/openwfe/util/observable.rb +82 -0
- data/lib/openwfe/util/scheduler.rb +14 -0
- data/lib/openwfe/utils.rb +64 -0
- data/lib/openwfe/version.rb +38 -0
- data/lib/openwfe/workitem.rb +53 -0
- data/lib/openwfe/worklist/storeparticipant.rb +19 -4
- data/test/csv_test.rb +285 -0
- data/test/fei_test.rb +1 -1
- data/test/file_persistence_test.rb +2 -2
- data/test/flowtestbase.rb +10 -3
- data/test/ft_0.rb +0 -7
- data/test/ft_0d_participant.rb +29 -0
- data/test/ft_11_ppd.rb +26 -1
- data/test/ft_12_blockparticipant.rb +28 -1
- data/test/ft_19_csv.rb +64 -0
- data/test/ft_20_cron.rb +60 -0
- data/test/ft_21_cron.rb +48 -0
- data/test/ft_22_history.rb +68 -0
- data/test/ft_23_when.rb +50 -0
- data/test/ft_23b_when.rb +45 -0
- data/test/ft_24_def.rb +47 -0
- data/test/ft_9_cursor.rb +20 -0
- data/test/rake_qtest.rb +7 -0
- data/test/rake_test.rb +3 -0
- data/test/timeout_test.rb +46 -4
- data/test/wi_test.rb +66 -0
- metadata +21 -3
- data/test/rake_ptest.rb +0 -18
@@ -37,10 +37,13 @@
|
|
37
37
|
# "made in Japan"
|
38
38
|
#
|
39
39
|
|
40
|
+
require 'openwfe/version'
|
41
|
+
|
42
|
+
|
40
43
|
module OpenWFE
|
41
44
|
|
42
45
|
#OPENWFE_VERSION = '1.7.2pre17'
|
43
|
-
OPENWFE_VERSION = '0.9.
|
46
|
+
#OPENWFE_VERSION = '0.9.4'
|
44
47
|
|
45
48
|
#
|
46
49
|
# service names
|
@@ -64,20 +67,10 @@ module OpenWFE
|
|
64
67
|
|
65
68
|
EN_ENVIRONMENT = 'environment'
|
66
69
|
|
67
|
-
#
|
68
|
-
# some expression attribute names
|
69
|
-
|
70
|
-
#A_FORGET = 'forget'
|
71
|
-
# replaced by a symbol
|
72
|
-
|
73
|
-
A_SYNC = 'sync'
|
74
|
-
A_COUNT = 'count'
|
75
|
-
A_REMAINING = 'remaining'
|
76
|
-
REM_CANCEL = 'cancel'
|
77
|
-
|
78
70
|
#
|
79
71
|
# some file storage default values
|
80
|
-
|
72
|
+
|
73
|
+
DEFAULT_WORK_DIRECTORY = './work'
|
81
74
|
|
82
75
|
#
|
83
76
|
# A mixin for easy OpenWFE service lookup
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, 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
|
+
# $Id: workitem.rb 3556 2006-11-13 04:15:52Z jmettraux $
|
34
|
+
#
|
35
|
+
|
36
|
+
#
|
37
|
+
# Made in Japan
|
38
|
+
#
|
39
|
+
# John Mettraux at OpenWFE dot org
|
40
|
+
#
|
41
|
+
|
42
|
+
require 'openwfe/workitem'
|
43
|
+
require 'openwfe/engine/engine'
|
44
|
+
|
45
|
+
include OpenWFE
|
46
|
+
|
47
|
+
|
48
|
+
module OpenWFE
|
49
|
+
|
50
|
+
def trace_flow (process_definition)
|
51
|
+
li = LaunchItem.new(process_definition)
|
52
|
+
|
53
|
+
engine = Engine.new()
|
54
|
+
|
55
|
+
i = 0
|
56
|
+
|
57
|
+
engine.register_participant(".*") do |workitem|
|
58
|
+
|
59
|
+
puts "-- #{i} ------------------------------------------------------------------------"
|
60
|
+
puts
|
61
|
+
puts " participant '#{workitem.participant_name}' received workitem :"
|
62
|
+
puts
|
63
|
+
puts workitem.to_s
|
64
|
+
puts
|
65
|
+
puts "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
66
|
+
puts
|
67
|
+
puts " expression pool state :"
|
68
|
+
#puts
|
69
|
+
puts engine.get_expression_storage.to_s
|
70
|
+
puts
|
71
|
+
#puts
|
72
|
+
|
73
|
+
i = i + 1
|
74
|
+
end
|
75
|
+
|
76
|
+
engine.launch(li)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,378 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, 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
|
+
# $Id$
|
34
|
+
#
|
35
|
+
|
36
|
+
#
|
37
|
+
# "made in Japan"
|
38
|
+
#
|
39
|
+
# John Mettraux at openwfe.org
|
40
|
+
#
|
41
|
+
|
42
|
+
require 'csv'
|
43
|
+
|
44
|
+
require 'openwfe/utils'
|
45
|
+
require 'openwfe/util/dollar'
|
46
|
+
|
47
|
+
include OpenWFE
|
48
|
+
|
49
|
+
|
50
|
+
module OpenWFE
|
51
|
+
|
52
|
+
#
|
53
|
+
# A 'CsvTable' is called a 'decision table' in OpenWFEja (the initial
|
54
|
+
# Java implementation of OpenWFE).
|
55
|
+
#
|
56
|
+
# A csv table is a description of a set of rules as a CSV (comma
|
57
|
+
# separated values) file. Such a file can be edited / generated by
|
58
|
+
# a spreadsheet (Excel, Google spreadsheets, Gnumeric, ...)
|
59
|
+
#
|
60
|
+
# The following CSV file
|
61
|
+
#
|
62
|
+
# in:topic,in:region,out:team_member
|
63
|
+
# sports,europe,Alice
|
64
|
+
# sports,,Bob
|
65
|
+
# finance,america,Charly
|
66
|
+
# finance,europe,Donald
|
67
|
+
# finance,,Ernest
|
68
|
+
# politics,asia,Fujio
|
69
|
+
# politics,america,Gilbert
|
70
|
+
# politics,,Henry
|
71
|
+
# ,,Zach
|
72
|
+
#
|
73
|
+
# embodies a rule for distributing items (piece of news) labelled with a
|
74
|
+
# topic and a region to various members of a team.
|
75
|
+
# For example, all news about finance from Europe are to be routed to
|
76
|
+
# Donald.
|
77
|
+
#
|
78
|
+
# Evaluation occurs row by row. The "in out" row states which field
|
79
|
+
# is considered at input and which are to be modified if the "ins" do
|
80
|
+
# match.
|
81
|
+
#
|
82
|
+
# The default behaviour is to change the value of the "outs" if all the
|
83
|
+
# "ins" match and then terminate.
|
84
|
+
# An empty "in" cell means "matches any".
|
85
|
+
#
|
86
|
+
# Enough words, some code :
|
87
|
+
#
|
88
|
+
# table = CsvTable.new("""
|
89
|
+
# in:topic,in:region,out:team_member
|
90
|
+
# sports,europe,Alice
|
91
|
+
# sports,,Bob
|
92
|
+
# finance,america,Charly
|
93
|
+
# finance,europe,Donald
|
94
|
+
# finance,,Ernest
|
95
|
+
# politics,asia,Fujio
|
96
|
+
# politics,america,Gilbert
|
97
|
+
# politics,,Henry
|
98
|
+
# ,,Zach
|
99
|
+
# """)
|
100
|
+
#
|
101
|
+
# h = {}
|
102
|
+
# h["topic"] = "politics"
|
103
|
+
#
|
104
|
+
# table.transform(h)
|
105
|
+
#
|
106
|
+
# puts h["team_member"]
|
107
|
+
# # will yield "Henry" who takes care of all the politics stuff,
|
108
|
+
# # except for Asia and America
|
109
|
+
#
|
110
|
+
# Disclaimer : the decision / CSV table system is no replacement for
|
111
|
+
# full rule engines with forward and backward chaining, RETE implementation
|
112
|
+
# and the like...
|
113
|
+
#
|
114
|
+
#
|
115
|
+
# Options :
|
116
|
+
#
|
117
|
+
# You can put options on their own in a cell BEFORE the line containing
|
118
|
+
# "in:xxx" and "out:yyy" (ins and outs).
|
119
|
+
#
|
120
|
+
# Currently, two options are supported, "ignorecase" and "through".
|
121
|
+
#
|
122
|
+
# "ignorecase", if found by the CsvTable will make any match (in the "in"
|
123
|
+
# columns) case unsensitive.
|
124
|
+
#
|
125
|
+
# "through", will make sure that EVERY row is evaluated and potentially
|
126
|
+
# applied. The default behaviour (without "through"), is to stop the
|
127
|
+
# evaluation after applying the results of the first matching row.
|
128
|
+
#
|
129
|
+
#
|
130
|
+
# CSV Tables are available to workflows as CsvParticipant.
|
131
|
+
#
|
132
|
+
#
|
133
|
+
# See also :
|
134
|
+
#
|
135
|
+
# http://jmettraux.wordpress.com/2007/02/11/ruby-decision-tables/
|
136
|
+
# http://rubyforge.org/viewvc/trunk/openwfe-ruby/test/csv_test.rb?root=openwferu&view=co
|
137
|
+
#
|
138
|
+
class CsvTable
|
139
|
+
|
140
|
+
attr_accessor \
|
141
|
+
:first_match,
|
142
|
+
:ignore_case,
|
143
|
+
:header,
|
144
|
+
:rows
|
145
|
+
|
146
|
+
#
|
147
|
+
# The constructor for CsvTable, you can pass a String, an Array
|
148
|
+
# (of arrays), a File object. The CSV parser coming with Ruby will take
|
149
|
+
# care of it and a CsvTable instance will be built.
|
150
|
+
#
|
151
|
+
def initialize (csv_data)
|
152
|
+
|
153
|
+
@first_match = true
|
154
|
+
@ignore_case = false
|
155
|
+
|
156
|
+
@header = nil
|
157
|
+
@rows = []
|
158
|
+
|
159
|
+
csv_array = to_csv_array(csv_data)
|
160
|
+
|
161
|
+
csv_array.each do |row|
|
162
|
+
|
163
|
+
next if empty_row? row
|
164
|
+
|
165
|
+
if @header
|
166
|
+
#@rows << row
|
167
|
+
@rows << row.collect { |c| c.strip if c }
|
168
|
+
else
|
169
|
+
parse_header_row(row)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Returns the workitem massaged by the csv table
|
176
|
+
#
|
177
|
+
def transform_wi (flow_expression, workitem)
|
178
|
+
|
179
|
+
@rows.each do |row|
|
180
|
+
|
181
|
+
if matches?(row, flow_expression, workitem)
|
182
|
+
apply(row, flow_expression, workitem)
|
183
|
+
break if @first_match
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
return workitem
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# Passes a simple Hash instance though the csv table
|
192
|
+
#
|
193
|
+
def transform (hash)
|
194
|
+
wi = InFlowWorkItem.new()
|
195
|
+
wi.attributes = hash
|
196
|
+
return transform_wi(nil, wi).attributes
|
197
|
+
end
|
198
|
+
|
199
|
+
protected
|
200
|
+
|
201
|
+
def to_csv_array (csv_data)
|
202
|
+
|
203
|
+
return csv_data if csv_data.kind_of? Array
|
204
|
+
return CSV::Reader.parse(csv_data)
|
205
|
+
end
|
206
|
+
|
207
|
+
def matches? (row, fexp, wi)
|
208
|
+
|
209
|
+
return false if empty_row? row
|
210
|
+
|
211
|
+
#puts
|
212
|
+
#puts "__row match ?"
|
213
|
+
#require 'pp'
|
214
|
+
#pp row
|
215
|
+
|
216
|
+
@header.ins.each_with_index do |in_header, icol|
|
217
|
+
|
218
|
+
in_header = resolve_in_header(in_header)
|
219
|
+
|
220
|
+
value = OpenWFE::dosub(in_header, fexp, wi)
|
221
|
+
|
222
|
+
cell = row[icol]
|
223
|
+
|
224
|
+
next if not cell
|
225
|
+
|
226
|
+
cell = cell.strip
|
227
|
+
|
228
|
+
next if cell.length < 1
|
229
|
+
|
230
|
+
cell = OpenWFE::dosub(cell, fexp, wi)
|
231
|
+
|
232
|
+
modifiers = 0
|
233
|
+
modifiers += Regexp::IGNORECASE if @ignore_case
|
234
|
+
|
235
|
+
#puts "__does '#{value}' match '#{cell}' ?"
|
236
|
+
|
237
|
+
rcell = Regexp.new(cell, modifiers)
|
238
|
+
return false unless rcell.match(value)
|
239
|
+
end
|
240
|
+
|
241
|
+
#puts "__row matches"
|
242
|
+
|
243
|
+
return true
|
244
|
+
end
|
245
|
+
|
246
|
+
def resolve_in_header (in_header)
|
247
|
+
|
248
|
+
in_header = "f:#{in_header}" \
|
249
|
+
if points_to_nothing? in_header
|
250
|
+
|
251
|
+
return "${#{in_header}}"
|
252
|
+
end
|
253
|
+
|
254
|
+
def apply (row, fexp, wi)
|
255
|
+
|
256
|
+
#puts "__ apply() wi.class : #{wi.class.name}"
|
257
|
+
|
258
|
+
@header.outs.each_with_index do |out_header, icol|
|
259
|
+
|
260
|
+
next unless out_header
|
261
|
+
|
262
|
+
value = row[icol]
|
263
|
+
|
264
|
+
next unless value
|
265
|
+
#next unless value.strip.length > 0
|
266
|
+
next unless value.length > 0
|
267
|
+
|
268
|
+
value = OpenWFE::dosub(value, fexp, wi)
|
269
|
+
|
270
|
+
#puts "___ value:'#{value}'"
|
271
|
+
#puts "___ value:'"+value+"'"
|
272
|
+
|
273
|
+
type, target = points_at(out_header)
|
274
|
+
|
275
|
+
#puts "___ t:'#{type}' target:'#{target}'"
|
276
|
+
|
277
|
+
if type == "v"
|
278
|
+
fexp.set_variable(target, value) if fexp
|
279
|
+
elsif type == "f"
|
280
|
+
wi.set_attribute(target, value)
|
281
|
+
elsif type == "r"
|
282
|
+
instance_eval(value)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def parse_header_row (row)
|
288
|
+
|
289
|
+
row.each_with_index do |cell, icol|
|
290
|
+
|
291
|
+
next unless cell
|
292
|
+
|
293
|
+
cell = cell.strip
|
294
|
+
s = cell.downcase
|
295
|
+
|
296
|
+
if s == "ignorecase" or s == "ignore_case"
|
297
|
+
@ignore_case = true
|
298
|
+
next
|
299
|
+
end
|
300
|
+
|
301
|
+
if s == "through"
|
302
|
+
@first_match = false
|
303
|
+
next
|
304
|
+
end
|
305
|
+
|
306
|
+
if OpenWFE::starts_with(cell, "in:") or OpenWFE::starts_with(cell, "out:")
|
307
|
+
@header = Header.new unless @header
|
308
|
+
@header.add cell, icol
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def empty_row? (row)
|
314
|
+
return true unless row
|
315
|
+
return true if (row.length == 1 and not row[0])
|
316
|
+
row.each do |cell|
|
317
|
+
return false if cell
|
318
|
+
end
|
319
|
+
return true
|
320
|
+
end
|
321
|
+
|
322
|
+
def points_to_nothing? (label)
|
323
|
+
(not points_to_variable? label) and \
|
324
|
+
(not points_to_field? label) and \
|
325
|
+
(not points_to_ruby? label)
|
326
|
+
end
|
327
|
+
def points_at (label)
|
328
|
+
v = points_to_variable? label
|
329
|
+
return "v", v if v
|
330
|
+
r = points_to_ruby? label
|
331
|
+
return "r", r if r
|
332
|
+
f = points_to_field? label
|
333
|
+
return "f", f if f
|
334
|
+
return "f", label # else
|
335
|
+
end
|
336
|
+
def points_to_variable? (label)
|
337
|
+
points_to?(label, [ "v", "var", "variable" ])
|
338
|
+
end
|
339
|
+
def points_to_field? (label)
|
340
|
+
points_to?(label, [ "f", "field" ])
|
341
|
+
end
|
342
|
+
def points_to_ruby? (label)
|
343
|
+
points_to?(label, [ "r", "ruby", "reval" ])
|
344
|
+
end
|
345
|
+
def points_to? (label, names)
|
346
|
+
i = label.index(":")
|
347
|
+
return nil unless i
|
348
|
+
s = label[0..i-1]
|
349
|
+
names.each do |name|
|
350
|
+
return label[i+1..-1] if s == name
|
351
|
+
end
|
352
|
+
return nil
|
353
|
+
end
|
354
|
+
|
355
|
+
class Header
|
356
|
+
|
357
|
+
attr_accessor :ins, :outs
|
358
|
+
|
359
|
+
def initialize
|
360
|
+
@ins = []
|
361
|
+
@outs = []
|
362
|
+
end
|
363
|
+
|
364
|
+
def add (cell, icol)
|
365
|
+
if OpenWFE::starts_with(cell, "in:")
|
366
|
+
@ins[icol] = cell[3..-1]
|
367
|
+
#puts "i added #{@ins[icol]}"
|
368
|
+
elsif OpenWFE::starts_with(cell, "out:")
|
369
|
+
@outs[icol] = cell[4..-1]
|
370
|
+
#puts "o added #{@outs[icol]}"
|
371
|
+
end
|
372
|
+
# else don't add
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
|
data/lib/openwfe/util/dollar.rb
CHANGED
@@ -50,6 +50,9 @@ module OpenWFE
|
|
50
50
|
def OpenWFE.dsub (text, dict)
|
51
51
|
|
52
52
|
#puts "### text is >#{text}<"
|
53
|
+
#puts "### dict is of class #{dict.class.name}"
|
54
|
+
|
55
|
+
#return nil unless text
|
53
56
|
|
54
57
|
j = text.index("}")
|
55
58
|
|
@@ -122,13 +125,18 @@ module OpenWFE
|
|
122
125
|
|
123
126
|
return '' if k == ''
|
124
127
|
|
125
|
-
return @workitem.
|
126
|
-
|
128
|
+
return @workitem.lookup_attribute(k) if p == 'f'
|
129
|
+
|
130
|
+
if p == 'v'
|
131
|
+
return '' unless @flow_expression
|
132
|
+
return @flow_expression.lookup_variable(k)
|
133
|
+
end
|
134
|
+
|
127
135
|
return call_function(k) if p == 'c'
|
128
136
|
return call_ruby(k) if p == 'r'
|
129
137
|
# TODO : implement constant lookup
|
130
138
|
|
131
|
-
return @workitem.
|
139
|
+
return @workitem.lookup_attribute(key)
|
132
140
|
end
|
133
141
|
|
134
142
|
def has_key? (key)
|
@@ -136,13 +144,18 @@ module OpenWFE
|
|
136
144
|
|
137
145
|
return false if k == ''
|
138
146
|
|
139
|
-
return @workitem.
|
140
|
-
|
147
|
+
return @workitem.has_attribute?(k) if p == 'f'
|
148
|
+
|
149
|
+
if p == 'v'
|
150
|
+
return false unless @flow_expression
|
151
|
+
return (@flow_expression.lookup_variable(k) != nil)
|
152
|
+
end
|
153
|
+
|
141
154
|
return true if p == 'c'
|
142
155
|
return true if p == 'r'
|
143
156
|
# TODO : implement constant lookup
|
144
157
|
|
145
|
-
return @workitem.
|
158
|
+
return @workitem.has_attribute?(key)
|
146
159
|
end
|
147
160
|
|
148
161
|
protected
|
@@ -159,7 +172,11 @@ module OpenWFE
|
|
159
172
|
end
|
160
173
|
|
161
174
|
def call_ruby (ruby_code)
|
162
|
-
|
175
|
+
|
176
|
+
binding = nil
|
177
|
+
binding = @flow_expression.get_binding if @flow_expression
|
178
|
+
|
179
|
+
eval(ruby_code, binding).to_s
|
163
180
|
end
|
164
181
|
end
|
165
182
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, 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
|
+
# $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
|
34
|
+
#
|
35
|
+
|
36
|
+
#
|
37
|
+
# "made in Japan"
|
38
|
+
#
|
39
|
+
# John Mettraux at openwfe.org
|
40
|
+
#
|
41
|
+
|
42
|
+
module OpenWFE
|
43
|
+
|
44
|
+
#
|
45
|
+
# A classic : this mixin gathers observability methods. It assumes
|
46
|
+
# that customer classes will have a @observers instance variable
|
47
|
+
# available.
|
48
|
+
# This mixin is chiefly used by the ExpressionPool class.
|
49
|
+
#
|
50
|
+
module Observable
|
51
|
+
|
52
|
+
#
|
53
|
+
# Observers will register themselves to the Observable via
|
54
|
+
# this method.
|
55
|
+
#
|
56
|
+
def add_observer (channel, &callback)
|
57
|
+
(@observers[channel] ||= []) << callback
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
#
|
63
|
+
# Observable classes do call this method to notify their
|
64
|
+
# observers
|
65
|
+
#
|
66
|
+
def onotify (channel, *args)
|
67
|
+
do_notify(channel, channel, *args)
|
68
|
+
do_notify(:all, channel, *args)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def do_notify (target_channel, channel, *args)
|
74
|
+
if @observers[target_channel]
|
75
|
+
@observers[target_channel].each do |obs|
|
76
|
+
obs.call channel, *args
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -306,6 +306,20 @@ module OpenWFE
|
|
306
306
|
return nil
|
307
307
|
end
|
308
308
|
|
309
|
+
#
|
310
|
+
# Returns the number of currently pending jobs in this scheduler.
|
311
|
+
#
|
312
|
+
def pending_job_count
|
313
|
+
@pending_jobs.size
|
314
|
+
end
|
315
|
+
|
316
|
+
#
|
317
|
+
# Returns the number of cron jobs currently active in this scheduler.
|
318
|
+
#
|
319
|
+
def cron_job_count
|
320
|
+
@cron_entries.size
|
321
|
+
end
|
322
|
+
|
309
323
|
protected
|
310
324
|
|
311
325
|
def to_block (schedulable, params, &block)
|