openwferu 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/validate-workflow.rb +1 -0
- data/examples/openwferu.rb +57 -0
- data/lib/openwfe/contextual.rb +2 -0
- data/lib/openwfe/engine/engine.rb +109 -17
- data/lib/openwfe/engine/file_persisted_engine.rb +11 -1
- data/lib/openwfe/exceptions.rb +53 -0
- data/lib/openwfe/expool/expressionpool.rb +195 -137
- data/lib/openwfe/expool/journal.rb +175 -0
- data/lib/openwfe/expool/journal_replay.rb +121 -0
- data/lib/openwfe/expool/wfidgen.rb +318 -0
- data/lib/openwfe/expool/yamlexpstorage.rb +23 -54
- data/lib/openwfe/expressions/condition.rb +14 -2
- data/lib/openwfe/expressions/environment.rb +47 -37
- data/lib/openwfe/expressions/expressionmap.rb +73 -67
- data/lib/openwfe/expressions/fe_cancel.rb +2 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +14 -1
- data/lib/openwfe/expressions/fe_cron.rb +186 -0
- data/lib/openwfe/expressions/fe_cursor.rb +6 -0
- data/lib/openwfe/expressions/fe_define.rb +2 -0
- data/lib/openwfe/expressions/fe_fqv.rb +2 -0
- data/lib/openwfe/expressions/fe_iterator.rb +2 -0
- data/lib/openwfe/expressions/fe_losfor.rb +4 -0
- data/lib/openwfe/expressions/fe_misc.rb +16 -1
- data/lib/openwfe/expressions/fe_participant.rb +7 -0
- data/lib/openwfe/expressions/fe_raw.rb +125 -8
- data/lib/openwfe/expressions/fe_sequence.rb +2 -0
- data/lib/openwfe/expressions/fe_sleep.rb +213 -0
- data/lib/openwfe/expressions/fe_subprocess.rb +2 -0
- data/lib/openwfe/expressions/fe_value.rb +8 -0
- data/lib/openwfe/expressions/fe_when.rb +205 -0
- data/lib/openwfe/expressions/flowexpression.rb +62 -9
- data/lib/openwfe/expressions/raw_prog.rb +147 -45
- data/lib/openwfe/expressions/raw_xml.rb +50 -5
- data/lib/openwfe/expressions/timeout.rb +32 -5
- data/lib/openwfe/flowexpressionid.rb +6 -4
- data/lib/openwfe/listeners/listeners.rb +4 -3
- data/lib/openwfe/listeners/socketlisteners.rb +30 -4
- data/lib/openwfe/logging.rb +9 -1
- data/lib/openwfe/participants/participants.rb +9 -9
- data/lib/openwfe/participants/socketparticipants.rb +41 -8
- data/lib/openwfe/rudefinitions.rb +21 -0
- data/lib/openwfe/storage/yamlextras.rb +115 -0
- data/lib/openwfe/storage/yamlfilestorage.rb +23 -4
- data/lib/openwfe/util/csvtable.rb +76 -6
- data/lib/openwfe/util/dollar.rb +5 -0
- data/lib/openwfe/util/kotoba.rb +236 -0
- data/lib/openwfe/util/ometa.rb +64 -0
- data/lib/openwfe/util/safe.rb +2 -0
- data/lib/openwfe/util/scheduler.rb +58 -11
- data/lib/openwfe/utils.rb +27 -0
- data/lib/openwfe/version.rb +1 -1
- data/lib/openwfe/worklist/storeparticipant.rb +2 -3
- data/test/csv_test.rb +57 -0
- data/test/expmap_test.rb +54 -0
- data/test/file_persistence_test.rb +9 -9
- data/test/flowtestbase.rb +19 -1
- data/test/ft_11_ppd.rb +18 -0
- data/test/ft_15_iterator.rb +27 -0
- data/test/ft_23b_when.rb +2 -2
- data/test/ft_27_getflowpos.rb +19 -9
- data/test/ft_29_httprb.rb +31 -2
- data/test/ft_30_socketlistener.rb +3 -5
- data/test/ft_31_flowname.rb +40 -0
- data/test/ft_32_journal.rb +60 -0
- data/test/ft_33_description.rb +100 -0
- data/test/ft_34_cancelwfid.rb +69 -0
- data/test/ft_35_localdefs.rb +63 -0
- data/test/ft_7_lose.rb +0 -61
- data/test/ft_7b_lose.rb +85 -0
- data/test/ft_tests.rb +49 -0
- data/test/kotoba_test.rb +72 -0
- data/test/misc_test.rb +4 -12
- data/test/param_test.rb +284 -0
- data/test/rake_qtest.rb +13 -35
- data/test/rake_test.rb +2 -3
- data/test/raw_prog_test.rb +9 -7
- data/test/restart_cron_test.rb +9 -5
- data/test/restart_sleep_test.rb +104 -0
- data/test/restart_tests.rb +15 -0
- data/test/restart_when_test.rb +105 -0
- data/test/scheduler_test.rb +2 -2
- data/test/sec_test.rb +163 -0
- data/test/wfid_test.rb +69 -13
- metadata +31 -16
- data/lib/openwfe/expressions/fe_time.rb +0 -454
- data/test/restart_test.rb +0 -79
@@ -141,9 +141,10 @@ module OpenWFE
|
|
141
141
|
def reply_to_socket (socket, result)
|
142
142
|
|
143
143
|
socket.puts result.to_s
|
144
|
+
socket.puts
|
144
145
|
socket.close_write
|
145
146
|
|
146
|
-
ldebug { "reply_to_socket() result is
|
147
|
+
#ldebug { "reply_to_socket() result is >#{result}<" }
|
147
148
|
end
|
148
149
|
|
149
150
|
#
|
@@ -165,9 +166,20 @@ module OpenWFE
|
|
165
166
|
|
166
167
|
linfo { "listen() listening on #{@server.addr.join(' ')}" }
|
167
168
|
|
168
|
-
while
|
169
|
+
while true
|
170
|
+
|
171
|
+
socket = nil
|
172
|
+
|
173
|
+
begin
|
174
|
+
socket = @server.accept
|
175
|
+
rescue Exception => e
|
176
|
+
linfo { "listen() shut down '#{e}'" }
|
177
|
+
end
|
178
|
+
|
179
|
+
return unless socket
|
180
|
+
|
169
181
|
OpenWFE.call_in_thread(@service_name, self) do
|
170
|
-
handle_socket(socket) if is_allowed? socket
|
182
|
+
handle_socket(socket) if socket and is_allowed? socket
|
171
183
|
end
|
172
184
|
end
|
173
185
|
end
|
@@ -221,7 +233,21 @@ module OpenWFE
|
|
221
233
|
end
|
222
234
|
end
|
223
235
|
|
224
|
-
result =
|
236
|
+
result = nil
|
237
|
+
|
238
|
+
begin
|
239
|
+
|
240
|
+
result = get_engine.reply(wi)
|
241
|
+
|
242
|
+
ldebug { "handle_socket() result is >>#{result}<<" }
|
243
|
+
|
244
|
+
rescue Exception => e
|
245
|
+
|
246
|
+
result = "ERROR\n\n"
|
247
|
+
result << OpenWFE::exception_to_s(e)
|
248
|
+
|
249
|
+
ldebug { "handle_socket() error reply :\n" + result }
|
250
|
+
end
|
225
251
|
|
226
252
|
reply_to_socket(socket, result)
|
227
253
|
|
data/lib/openwfe/logging.rb
CHANGED
@@ -40,7 +40,8 @@
|
|
40
40
|
#
|
41
41
|
|
42
42
|
require 'logger'
|
43
|
-
require 'openwfe/
|
43
|
+
require 'openwfe/utils'
|
44
|
+
#require 'openwfe/rudefinitions'
|
44
45
|
|
45
46
|
|
46
47
|
module OpenWFE
|
@@ -74,6 +75,13 @@ module OpenWFE
|
|
74
75
|
do_log(:unknown, message, &block)
|
75
76
|
end
|
76
77
|
|
78
|
+
#
|
79
|
+
# A simplification of caller_to_s for direct usage when debugging
|
80
|
+
#
|
81
|
+
def ldebug_callstack (msg, max_lines=nil)
|
82
|
+
ldebug { "#{msg}\n" + OpenWFE::caller_to_s(9, max_lines) }
|
83
|
+
end
|
84
|
+
|
77
85
|
private
|
78
86
|
|
79
87
|
def do_log (level, message, &block)
|
@@ -68,15 +68,15 @@ module OpenWFE
|
|
68
68
|
#
|
69
69
|
def initialize (context_or_dir=nil)
|
70
70
|
|
71
|
-
if context_or_dir.kind_of? Hash
|
72
|
-
|
73
|
-
|
74
|
-
else
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
@workdir = "
|
71
|
+
#if context_or_dir.kind_of? Hash
|
72
|
+
# @application_context = context_or_dir
|
73
|
+
# @workdir = @application_context[:work_directory]
|
74
|
+
#else
|
75
|
+
# @workdir = context_or_dir
|
76
|
+
#end
|
77
|
+
#@workdir = OpenWFE::DEFAULT_WORK_DIRECTORY unless @workdir
|
78
|
+
#@workdir = "#{@workdir}/out/"
|
79
|
+
@workdir = OpenWFE::get_work_directory(context_or_dir) + "/out/"
|
80
80
|
|
81
81
|
@reply_anyway = false
|
82
82
|
end
|
@@ -41,8 +41,8 @@
|
|
41
41
|
|
42
42
|
require 'yaml'
|
43
43
|
require 'socket'
|
44
|
+
require 'timeout'
|
44
45
|
|
45
|
-
#require 'openwfe/utils'
|
46
46
|
require 'openwfe/rest/xmlcodec'
|
47
47
|
require 'openwfe/participants/participant'
|
48
48
|
|
@@ -80,19 +80,22 @@ module OpenWFE
|
|
80
80
|
|
81
81
|
#
|
82
82
|
# The method called by the engine for each incoming workitem.
|
83
|
+
# Will dispatch the workitem over a TCP connection.
|
83
84
|
#
|
84
85
|
def consume (workitem)
|
85
86
|
|
87
|
+
dispatch(workitem)
|
88
|
+
end
|
89
|
+
|
90
|
+
def dispatch (workitem)
|
91
|
+
|
86
92
|
socket = TCPSocket.new(@host, @port)
|
87
93
|
socket.puts encode_workitem(workitem)
|
94
|
+
socket.puts
|
88
95
|
socket.close_write
|
89
96
|
|
90
|
-
reply =
|
91
|
-
|
92
|
-
r = socket.gets
|
93
|
-
break unless r
|
94
|
-
reply << r
|
95
|
-
end
|
97
|
+
reply = fetch_reply(socket)
|
98
|
+
|
96
99
|
socket.close
|
97
100
|
|
98
101
|
decode_reply(reply)
|
@@ -108,7 +111,7 @@ module OpenWFE
|
|
108
111
|
#
|
109
112
|
def SocketParticipant.dispatch (host, port, workitem)
|
110
113
|
|
111
|
-
SocketParticipant.new(host, port).
|
114
|
+
SocketParticipant.new(host, port).dispatch(workitem)
|
112
115
|
end
|
113
116
|
|
114
117
|
protected
|
@@ -127,6 +130,32 @@ module OpenWFE
|
|
127
130
|
def decode_reply (r)
|
128
131
|
r
|
129
132
|
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# The code that waits for the reply from the server, nicely
|
136
|
+
# wrapped inside a timeout and a rescue block.
|
137
|
+
#
|
138
|
+
def fetch_reply (socket)
|
139
|
+
|
140
|
+
reply = ""
|
141
|
+
|
142
|
+
begin
|
143
|
+
|
144
|
+
timeout(7) do
|
145
|
+
while true
|
146
|
+
r = socket.gets
|
147
|
+
break unless r
|
148
|
+
reply << r
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
rescue Exception => e
|
153
|
+
puts e
|
154
|
+
raise "timeout while waiting for reply"
|
155
|
+
end
|
156
|
+
|
157
|
+
reply
|
158
|
+
end
|
130
159
|
end
|
131
160
|
|
132
161
|
#
|
@@ -155,6 +184,10 @@ module OpenWFE
|
|
155
184
|
|
156
185
|
protected
|
157
186
|
|
187
|
+
#
|
188
|
+
# This implementation encodes the workitem as an XML document.
|
189
|
+
# This is compatible with OpenWFEja.
|
190
|
+
#
|
158
191
|
def encode_workitem (wi)
|
159
192
|
|
160
193
|
sxml = OpenWFE::xml_encode(wi)
|
@@ -37,6 +37,8 @@
|
|
37
37
|
# "made in Japan"
|
38
38
|
#
|
39
39
|
|
40
|
+
require 'fileutils'
|
41
|
+
|
40
42
|
require 'openwfe/utils'
|
41
43
|
require 'openwfe/version'
|
42
44
|
|
@@ -50,6 +52,7 @@ module OpenWFE
|
|
50
52
|
|
51
53
|
S_ENGINE = 'engine'
|
52
54
|
S_EXPRESSION_MAP = 'expressionMap'
|
55
|
+
S_WFID_GENERATOR = 'wfidGenerator'
|
53
56
|
S_EXPRESSION_POOL = 'expressionPool'
|
54
57
|
S_EXPRESSION_STORAGE = 'expressionStorage'
|
55
58
|
S_PARTICIPANT_MAP = 'participantMap'
|
@@ -70,6 +73,21 @@ module OpenWFE
|
|
70
73
|
|
71
74
|
DEFAULT_WORK_DIRECTORY = './work'
|
72
75
|
|
76
|
+
#
|
77
|
+
# Returns the work directory for the OpenWFE[ru] application context
|
78
|
+
# (if any).
|
79
|
+
#
|
80
|
+
def OpenWFE.get_work_directory (dir=nil)
|
81
|
+
|
82
|
+
dir = DEFAULT_WORK_DIRECTORY unless @application_context
|
83
|
+
dir = @application_context[:work_directory] unless dir
|
84
|
+
dir = DEFAULT_WORK_DIRECTORY unless dir
|
85
|
+
|
86
|
+
FileUtils.makedirs(dir) unless File.exist?(dir)
|
87
|
+
|
88
|
+
dir
|
89
|
+
end
|
90
|
+
|
73
91
|
#
|
74
92
|
# A mixin for easy OpenWFE service lookup
|
75
93
|
# (assumes the presence of an application context instance var)
|
@@ -85,6 +103,9 @@ module OpenWFE
|
|
85
103
|
def get_expression_map
|
86
104
|
return @application_context[S_EXPRESSION_MAP]
|
87
105
|
end
|
106
|
+
def get_wfid_generator
|
107
|
+
return @application_context[S_WFID_GENERATOR]
|
108
|
+
end
|
88
109
|
def get_expression_pool
|
89
110
|
return @application_context[S_EXPRESSION_POOL]
|
90
111
|
end
|
@@ -0,0 +1,115 @@
|
|
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
|
+
require 'yaml'
|
43
|
+
|
44
|
+
|
45
|
+
module OpenWFE
|
46
|
+
|
47
|
+
#
|
48
|
+
# reopening some classes in order to facilitate their
|
49
|
+
# yaml serialization
|
50
|
+
#
|
51
|
+
|
52
|
+
#
|
53
|
+
# opening for tuning yaml persistence
|
54
|
+
#
|
55
|
+
class FlowExpression
|
56
|
+
|
57
|
+
def to_yaml_properties
|
58
|
+
|
59
|
+
l = super()
|
60
|
+
|
61
|
+
l.delete("@application_context")
|
62
|
+
|
63
|
+
l.delete("@timeout_job_id")
|
64
|
+
#l.delete("@scheduler_job_id")
|
65
|
+
# scheduler ids should not get persisted
|
66
|
+
|
67
|
+
return l
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# making sure that the FlowExpressionId is serialized as a unique String
|
73
|
+
#
|
74
|
+
class FlowExpressionId
|
75
|
+
|
76
|
+
yaml_as "tag:ruby.yaml.org,2002:#{self}"
|
77
|
+
|
78
|
+
#def to_yaml (opts={})
|
79
|
+
# @s = to_s
|
80
|
+
# super
|
81
|
+
#end
|
82
|
+
#def to_yaml_properties
|
83
|
+
# [ "@s" ]
|
84
|
+
#end
|
85
|
+
|
86
|
+
def to_yaml (opts={})
|
87
|
+
YAML::quick_emit(self.object_id, opts) do |out|
|
88
|
+
out.map(taguri) do |map|
|
89
|
+
map.add("s", to_s)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def FlowExpressionId.yaml_new (klass, tag, val)
|
95
|
+
s = val["s"]
|
96
|
+
begin
|
97
|
+
FlowExpressionId.to_fei(s)
|
98
|
+
rescue Exception => e
|
99
|
+
raise "failed to decode FlowExpressionId out of '#{s}'"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# opening for tuning yaml persistence
|
106
|
+
#
|
107
|
+
class XmlRawExpression
|
108
|
+
def to_yaml_properties
|
109
|
+
l = super()
|
110
|
+
l.delete("@raw_representation")
|
111
|
+
return l
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
@@ -142,7 +142,10 @@ module OpenWFE
|
|
142
142
|
|
143
143
|
fei_path = compute_file_path(fei)
|
144
144
|
|
145
|
-
|
145
|
+
if not File.exist?(fei_path)
|
146
|
+
ldebug { "[] didn't find file at #{fei_path}" }
|
147
|
+
return nil
|
148
|
+
end
|
146
149
|
|
147
150
|
load_object(fei_path)
|
148
151
|
end
|
@@ -151,7 +154,7 @@ module OpenWFE
|
|
151
154
|
# Returns the count of objects currently stored in this instance.
|
152
155
|
#
|
153
156
|
def length
|
154
|
-
|
157
|
+
|
155
158
|
count_objects()
|
156
159
|
end
|
157
160
|
|
@@ -161,8 +164,6 @@ module OpenWFE
|
|
161
164
|
|
162
165
|
def load_object (path)
|
163
166
|
|
164
|
-
#data = IO.read(path)
|
165
|
-
#object = YAML.load(data)
|
166
167
|
object = YAML.load_file(path)
|
167
168
|
|
168
169
|
object.application_context = @application_context \
|
@@ -171,10 +172,18 @@ module OpenWFE
|
|
171
172
|
object
|
172
173
|
end
|
173
174
|
|
175
|
+
#
|
176
|
+
# Returns the number of 'objects' currently in this storage.
|
177
|
+
#
|
174
178
|
def count_objects
|
179
|
+
|
175
180
|
count = 0
|
181
|
+
|
176
182
|
Find.find(@basepath) do |path|
|
183
|
+
|
184
|
+
next unless File.exist? path
|
177
185
|
next if File.stat(path).directory?
|
186
|
+
|
178
187
|
count += 1 if OpenWFE::ends_with(path, ".yaml")
|
179
188
|
end
|
180
189
|
return count
|
@@ -184,11 +193,16 @@ module OpenWFE
|
|
184
193
|
# Passes each object path to the given block
|
185
194
|
#
|
186
195
|
def each_object_path (&block)
|
196
|
+
|
187
197
|
return unless block
|
198
|
+
|
188
199
|
synchronize do
|
189
200
|
Find.find(@basepath) do |path|
|
201
|
+
|
202
|
+
next unless File.exist? path
|
190
203
|
next if File.stat(path).directory?
|
191
204
|
next unless OpenWFE::ends_with(path, ".yaml")
|
205
|
+
|
192
206
|
ldebug { "each_object_path() considering #{path}" }
|
193
207
|
block.call path
|
194
208
|
end
|
@@ -212,6 +226,11 @@ module OpenWFE
|
|
212
226
|
|
213
227
|
protected
|
214
228
|
|
229
|
+
#
|
230
|
+
# Each object is meant to have a unique file path,
|
231
|
+
# this method wraps the determination of that path. It has to
|
232
|
+
# be provided by extending classes.
|
233
|
+
#
|
215
234
|
def compute_file_path (object)
|
216
235
|
raise NotImplementedError.new
|
217
236
|
end
|
@@ -107,6 +107,27 @@ module OpenWFE
|
|
107
107
|
# # will yield "Henry" who takes care of all the politics stuff,
|
108
108
|
# # except for Asia and America
|
109
109
|
#
|
110
|
+
# '>', '>=', '<' and '<=' can be put in front of individual cell values :
|
111
|
+
#
|
112
|
+
# table = CsvTable.new("""
|
113
|
+
# ,
|
114
|
+
# in:fx, out:fy
|
115
|
+
# ,
|
116
|
+
# >100,a
|
117
|
+
# >=10,b
|
118
|
+
# ,c
|
119
|
+
# """)
|
120
|
+
#
|
121
|
+
# h = { 'fx' => '10' }
|
122
|
+
# table.transform(h)
|
123
|
+
#
|
124
|
+
# require 'pp'; pp h
|
125
|
+
# # will yield { 'fx' => '10', 'fy' => 'b' }
|
126
|
+
#
|
127
|
+
# Such comparisons are done after the elements are transformed to float
|
128
|
+
# numbers. By default, non-numeric arguments will get compared as Strings.
|
129
|
+
#
|
130
|
+
#
|
110
131
|
# Disclaimer : the decision / CSV table system is no replacement for
|
111
132
|
# full rule engines with forward and backward chaining, RETE implementation
|
112
133
|
# and the like...
|
@@ -229,13 +250,15 @@ module OpenWFE
|
|
229
250
|
|
230
251
|
cell = OpenWFE::dosub(cell, fexp, wi)
|
231
252
|
|
232
|
-
modifiers = 0
|
233
|
-
modifiers += Regexp::IGNORECASE if @ignore_case
|
234
|
-
|
235
253
|
#puts "__does '#{value}' match '#{cell}' ?"
|
236
254
|
|
237
|
-
|
238
|
-
|
255
|
+
b = if cell[0, 1] == '<' or cell[0, 1] == '>'
|
256
|
+
numeric_compare(value, cell)
|
257
|
+
else
|
258
|
+
regex_compare(value, cell)
|
259
|
+
end
|
260
|
+
|
261
|
+
return false unless b
|
239
262
|
end
|
240
263
|
|
241
264
|
#puts "__row matches"
|
@@ -243,6 +266,52 @@ module OpenWFE
|
|
243
266
|
return true
|
244
267
|
end
|
245
268
|
|
269
|
+
def regex_compare (value, cell)
|
270
|
+
|
271
|
+
modifiers = 0
|
272
|
+
modifiers += Regexp::IGNORECASE if @ignore_case
|
273
|
+
|
274
|
+
rcell = Regexp.new(cell, modifiers)
|
275
|
+
|
276
|
+
rcell.match(value)
|
277
|
+
end
|
278
|
+
|
279
|
+
def numeric_compare (value, cell)
|
280
|
+
|
281
|
+
comparator = cell[0, 1]
|
282
|
+
comparator += "=" if cell[1, 1] == "="
|
283
|
+
cell = cell[comparator.length..-1]
|
284
|
+
|
285
|
+
nvalue = narrow(value)
|
286
|
+
ncell = narrow(cell)
|
287
|
+
|
288
|
+
if nvalue.is_a? String or ncell.is_a? String
|
289
|
+
value = '"' + value + '"'
|
290
|
+
cell = '"' + cell + '"'
|
291
|
+
else
|
292
|
+
value = nvalue
|
293
|
+
cell = ncell
|
294
|
+
end
|
295
|
+
|
296
|
+
s = "#{value} #{comparator} #{cell}"
|
297
|
+
|
298
|
+
#puts "...>>>#{s}<<<"
|
299
|
+
|
300
|
+
begin
|
301
|
+
return OpenWFE::eval_safely(s, 4)
|
302
|
+
rescue Exception => e
|
303
|
+
return false
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def narrow (s)
|
308
|
+
begin
|
309
|
+
return Float(s)
|
310
|
+
rescue Exception => e
|
311
|
+
return s
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
246
315
|
def resolve_in_header (in_header)
|
247
316
|
|
248
317
|
in_header = "f:#{in_header}" \
|
@@ -279,7 +348,8 @@ module OpenWFE
|
|
279
348
|
elsif type == "f"
|
280
349
|
wi.set_attribute(target, value)
|
281
350
|
elsif type == "r"
|
282
|
-
instance_eval(value)
|
351
|
+
#instance_eval(value)
|
352
|
+
OpenWFE::instance_eval_safely(self, value, 3)
|
283
353
|
end
|
284
354
|
end
|
285
355
|
end
|
data/lib/openwfe/util/dollar.rb
CHANGED
@@ -188,6 +188,11 @@ module OpenWFE
|
|
188
188
|
|
189
189
|
def call_ruby (ruby_code)
|
190
190
|
|
191
|
+
if @flow_expression
|
192
|
+
return "" \
|
193
|
+
if @flow_expression.ac[:ruby_eval_allowed] != true
|
194
|
+
end
|
195
|
+
|
191
196
|
#binding = nil
|
192
197
|
#binding = @flow_expression.get_binding if @flow_expression
|
193
198
|
#eval(ruby_code, binding).to_s
|