ruote 0.9.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +24 -0
- data/bin/validate-workflow.rb +89 -0
- data/examples/about_state.rb +81 -0
- data/examples/bigflow.rb +19 -0
- data/examples/csv_weather.rb +23 -0
- data/examples/engine_template.rb +247 -0
- data/examples/flowtracing.rb +24 -0
- data/examples/homeworkreview.rb +68 -0
- data/examples/kotoba.rb +22 -0
- data/examples/mano_tracker.rb +172 -0
- data/examples/openwferu.rb +58 -0
- data/examples/quotereporter.rb +157 -0
- data/examples/scheduler_cron_usage.rb +48 -0
- data/examples/scheduler_usage.rb +56 -0
- data/lib/openwfe.rb +41 -0
- data/lib/openwfe/contextual.rb +111 -0
- data/lib/openwfe/def.rb +46 -0
- data/lib/openwfe/engine.rb +37 -0
- data/lib/openwfe/engine/engine.rb +756 -0
- data/lib/openwfe/engine/expool_methods.rb +172 -0
- data/lib/openwfe/engine/file_persisted_engine.rb +105 -0
- data/lib/openwfe/engine/participant_methods.rb +133 -0
- data/lib/openwfe/engine/status_methods.rb +353 -0
- data/lib/openwfe/engine/update_exp_methods.rb +112 -0
- data/lib/openwfe/exceptions.rb +51 -0
- data/lib/openwfe/expool/errorjournal.rb +476 -0
- data/lib/openwfe/expool/expressionpool.rb +1144 -0
- data/lib/openwfe/expool/expstorage.rb +403 -0
- data/lib/openwfe/expool/history.rb +174 -0
- data/lib/openwfe/expool/journal.rb +224 -0
- data/lib/openwfe/expool/journal_replay.rb +321 -0
- data/lib/openwfe/expool/parser.rb +242 -0
- data/lib/openwfe/expool/representation.rb +121 -0
- data/lib/openwfe/expool/threadedexpstorage.rb +188 -0
- data/lib/openwfe/expool/wfidgen.rb +388 -0
- data/lib/openwfe/expool/yamlexpstorage.rb +224 -0
- data/lib/openwfe/expressions/condition.rb +244 -0
- data/lib/openwfe/expressions/environment.rb +246 -0
- data/lib/openwfe/expressions/expressionmap.rb +258 -0
- data/lib/openwfe/expressions/fe_cancel.rb +109 -0
- data/lib/openwfe/expressions/fe_command.rb +241 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +662 -0
- data/lib/openwfe/expressions/fe_cron.rb +259 -0
- data/lib/openwfe/expressions/fe_cursor.rb +259 -0
- data/lib/openwfe/expressions/fe_define.rb +192 -0
- data/lib/openwfe/expressions/fe_do.rb +168 -0
- data/lib/openwfe/expressions/fe_equals.rb +291 -0
- data/lib/openwfe/expressions/fe_filter.rb +129 -0
- data/lib/openwfe/expressions/fe_filter_definition.rb +168 -0
- data/lib/openwfe/expressions/fe_fqv.rb +250 -0
- data/lib/openwfe/expressions/fe_if.rb +303 -0
- data/lib/openwfe/expressions/fe_iterator.rb +145 -0
- data/lib/openwfe/expressions/fe_listen.rb +371 -0
- data/lib/openwfe/expressions/fe_losfor.rb +111 -0
- data/lib/openwfe/expressions/fe_misc.rb +421 -0
- data/lib/openwfe/expressions/fe_participant.rb +269 -0
- data/lib/openwfe/expressions/fe_reserve.rb +212 -0
- data/lib/openwfe/expressions/fe_save.rb +274 -0
- data/lib/openwfe/expressions/fe_sequence.rb +117 -0
- data/lib/openwfe/expressions/fe_set.rb +139 -0
- data/lib/openwfe/expressions/fe_sleep.rb +166 -0
- data/lib/openwfe/expressions/fe_step.rb +159 -0
- data/lib/openwfe/expressions/fe_subprocess.rb +168 -0
- data/lib/openwfe/expressions/fe_timeout.rb +127 -0
- data/lib/openwfe/expressions/fe_wait.rb +78 -0
- data/lib/openwfe/expressions/fe_when.rb +142 -0
- data/lib/openwfe/expressions/filter.rb +104 -0
- data/lib/openwfe/expressions/flowexpression.rb +847 -0
- data/lib/openwfe/expressions/iterator.rb +221 -0
- data/lib/openwfe/expressions/merge.rb +84 -0
- data/lib/openwfe/expressions/raw.rb +547 -0
- data/lib/openwfe/expressions/rprocdef.rb +375 -0
- data/lib/openwfe/expressions/time.rb +333 -0
- data/lib/openwfe/expressions/timeout.rb +178 -0
- data/lib/openwfe/expressions/value.rb +126 -0
- data/lib/openwfe/filterdef.rb +259 -0
- data/lib/openwfe/flowexpressionid.rb +357 -0
- data/lib/openwfe/listeners/listener.rb +97 -0
- data/lib/openwfe/listeners/listeners.rb +139 -0
- data/lib/openwfe/listeners/socketlisteners.rb +272 -0
- data/lib/openwfe/logging.rb +122 -0
- data/lib/openwfe/omixins.rb +95 -0
- data/lib/openwfe/orest/controlclient.rb +119 -0
- data/lib/openwfe/orest/definitions.rb +113 -0
- data/lib/openwfe/orest/exception.rb +60 -0
- data/lib/openwfe/orest/oldrestservlet.rb +279 -0
- data/lib/openwfe/orest/osocket.rb +148 -0
- data/lib/openwfe/orest/restclient.rb +176 -0
- data/lib/openwfe/orest/workitem.rb +206 -0
- data/lib/openwfe/orest/worklistclient.rb +272 -0
- data/lib/openwfe/orest/xmlcodec.rb +670 -0
- data/lib/openwfe/participants.rb +38 -0
- data/lib/openwfe/participants/enoparticipants.rb +230 -0
- data/lib/openwfe/participants/participant.rb +141 -0
- data/lib/openwfe/participants/participantmap.rb +249 -0
- data/lib/openwfe/participants/participants.rb +407 -0
- data/lib/openwfe/participants/soapparticipants.rb +135 -0
- data/lib/openwfe/participants/socketparticipants.rb +202 -0
- data/lib/openwfe/participants/storeparticipants.rb +254 -0
- data/lib/openwfe/rudefinitions.rb +130 -0
- data/lib/openwfe/service.rb +103 -0
- data/lib/openwfe/storage/yamlcustom.rb +106 -0
- data/lib/openwfe/storage/yamlfilestorage.rb +245 -0
- data/lib/openwfe/tools/flowtracer.rb +81 -0
- data/lib/openwfe/util/dollar.rb +217 -0
- data/lib/openwfe/util/irb.rb +86 -0
- data/lib/openwfe/util/observable.rb +144 -0
- data/lib/openwfe/util/ometa.rb +62 -0
- data/lib/openwfe/util/workqueue.rb +124 -0
- data/lib/openwfe/util/xml.rb +418 -0
- data/lib/openwfe/utils.rb +554 -0
- data/lib/openwfe/version.rb +37 -0
- data/lib/openwfe/workitem.rb +499 -0
- data/lib/openwfe/worklist/oldrest.rb +244 -0
- data/lib/openwfe/worklist/storelocks.rb +293 -0
- data/lib/openwfe/worklist/storeparticipant.rb +44 -0
- data/lib/openwfe/worklist/worklist.rb +297 -0
- data/test/README.txt +27 -0
- data/test/back_0916_test.rb +111 -0
- data/test/bm/bm_1_xml_vs_prog.rb +56 -0
- data/test/bm/bm_2_step.rb +109 -0
- data/test/bm/ft_0f_5ms.rb +35 -0
- data/test/bm/ft_26_load.rb +210 -0
- data/test/bm/ft_26b_load.rb +86 -0
- data/test/bm/ft_26c_load.rb +97 -0
- data/test/bm/ft_26d_load.rb +97 -0
- data/test/bm/ft_recu.rb +71 -0
- data/test/clone_test.rb +122 -0
- data/test/concurrence_test.rb +77 -0
- data/test/condition_test.rb +155 -0
- data/test/console_test.rb +12 -0
- data/test/cron_ltest.rb +15 -0
- data/test/description_test.rb +87 -0
- data/test/eno_test.rb +76 -0
- data/test/expmap_test.rb +54 -0
- data/test/expool_20031219_0916.tgz +0 -0
- data/test/fe_lookup_att_test.rb +62 -0
- data/test/fei_test.rb +181 -0
- data/test/file_persisted_engine_test.rb +64 -0
- data/test/file_persistence_test.rb +134 -0
- data/test/filep_cancel_test.rb +123 -0
- data/test/filter_test.rb +109 -0
- data/test/flowtestbase.rb +351 -0
- data/test/ft_0.rb +68 -0
- data/test/ft_0b_sequence.rb +36 -0
- data/test/ft_0c_testname.rb +33 -0
- data/test/ft_0d_participant.rb +30 -0
- data/test/ft_0e_multibody.rb +34 -0
- data/test/ft_10_loop.rb +134 -0
- data/test/ft_11_ppd.rb +415 -0
- data/test/ft_11b_ppd.rb +54 -0
- data/test/ft_12_blockparticipant.rb +97 -0
- data/test/ft_13_eno.rb +52 -0
- data/test/ft_14_subprocess.rb +88 -0
- data/test/ft_14b_subprocess.rb +192 -0
- data/test/ft_14c_subprocess.rb +68 -0
- data/test/ft_15_iterator.rb +216 -0
- data/test/ft_15b_iterator.rb +74 -0
- data/test/ft_16_fqv.rb +73 -0
- data/test/ft_17_condition.rb +84 -0
- data/test/ft_18_pname.rb +56 -0
- data/test/ft_1_unset.rb +175 -0
- data/test/ft_1b_unset.rb +39 -0
- data/test/ft_20_cron.rb +53 -0
- data/test/ft_21_cron.rb +87 -0
- data/test/ft_21b_cron_pause.rb +82 -0
- data/test/ft_22_history.rb +74 -0
- data/test/ft_23_when.rb +77 -0
- data/test/ft_23b_when.rb +70 -0
- data/test/ft_23c_wait.rb +80 -0
- data/test/ft_23d_cww.rb +58 -0
- data/test/ft_24_def.rb +44 -0
- data/test/ft_25_cancel.rb +89 -0
- data/test/ft_27_getflowpos.rb +147 -0
- data/test/ft_28_fileparticipant.rb +63 -0
- data/test/ft_29_httprb.rb +106 -0
- data/test/ft_2_concurrence.rb +135 -0
- data/test/ft_2b_concurrence.rb +188 -0
- data/test/ft_2c_concurrence.rb +64 -0
- data/test/ft_30_socketlistener.rb +203 -0
- data/test/ft_31_flowname.rb +40 -0
- data/test/ft_32_journal.rb +91 -0
- data/test/ft_32c_journal.rb +102 -0
- data/test/ft_32d_journal.rb +84 -0
- data/test/ft_33_description.rb +107 -0
- data/test/ft_34_cancelwfid.rb +80 -0
- data/test/ft_35_localdefs.rb +75 -0
- data/test/ft_36_subprocids.rb +97 -0
- data/test/ft_37_pnames.rb +70 -0
- data/test/ft_38_tag.rb +127 -0
- data/test/ft_38b_tag.rb +161 -0
- data/test/ft_38c_tag.rb +100 -0
- data/test/ft_39_reserve.rb +63 -0
- data/test/ft_39b_reserve.rb +84 -0
- data/test/ft_3_equals.rb +170 -0
- data/test/ft_3b_lookup_vf.rb +83 -0
- data/test/ft_40_defined.rb +61 -0
- data/test/ft_41_case.rb +110 -0
- data/test/ft_42_environments.rb +75 -0
- data/test/ft_43_pat10.rb +85 -0
- data/test/ft_44_save.rb +70 -0
- data/test/ft_44b_restore.rb +212 -0
- data/test/ft_45_citerator.rb +214 -0
- data/test/ft_46_pparams.rb +62 -0
- data/test/ft_47_filter.rb +160 -0
- data/test/ft_48_fe_filter.rb +88 -0
- data/test/ft_49_condition.rb +126 -0
- data/test/ft_4_misc.rb +237 -0
- data/test/ft_50_xml_attribute.rb +155 -0
- data/test/ft_51_stack.rb +55 -0
- data/test/ft_52_obs_participant.rb +123 -0
- data/test/ft_53_null_noop_participant.rb +62 -0
- data/test/ft_54_listen.rb +288 -0
- data/test/ft_54b_listen.rb +66 -0
- data/test/ft_54c_listen.rb +99 -0
- data/test/ft_55_ptimeout.rb +59 -0
- data/test/ft_56_timeout.rb +59 -0
- data/test/ft_57_a.rb +145 -0
- data/test/ft_58_ejournal.rb +151 -0
- data/test/ft_59_ps.rb +150 -0
- data/test/ft_59b_ps_for_pat.rb +58 -0
- data/test/ft_5_time.rb +118 -0
- data/test/ft_60_ecancel.rb +161 -0
- data/test/ft_61_elsub.rb +51 -0
- data/test/ft_62_procparticipant.rb +71 -0
- data/test/ft_63_pause.rb +124 -0
- data/test/ft_64_alias.rb +102 -0
- data/test/ft_64_clone.rb +69 -0
- data/test/ft_65_stringlaunch.rb +59 -0
- data/test/ft_66_subforget.rb +70 -0
- data/test/ft_67_schedlaunch.rb +116 -0
- data/test/ft_68_ifparticipant.rb +70 -0
- data/test/ft_69_cancelmissing.rb +51 -0
- data/test/ft_6_lambda.rb +64 -0
- data/test/ft_70_lookupvar.rb +55 -0
- data/test/ft_71_log.rb +60 -0
- data/test/ft_72_lookup_processes.rb +76 -0
- data/test/ft_73_cancel_sub.rb +139 -0
- data/test/ft_74_block_and_workitem_dup.rb +63 -0
- data/test/ft_75_ruby_attributes.rb +87 -0
- data/test/ft_76_merge_isolate.rb +88 -0
- data/test/ft_77_segments.rb +35 -0
- data/test/ft_78_eval.rb +150 -0
- data/test/ft_79_tticket.rb +187 -0
- data/test/ft_79b_tticket.rb +172 -0
- data/test/ft_79c_outcome.rb +56 -0
- data/test/ft_7_lose.rb +104 -0
- data/test/ft_7b_lose.rb +78 -0
- data/test/ft_80_spname.rb +91 -0
- data/test/ft_81_exp.rb +60 -0
- data/test/ft_82_trecu.rb +46 -0
- data/test/ft_83_badpause.rb +58 -0
- data/test/ft_84_updateexp.rb +198 -0
- data/test/ft_85_dolhash.rb +43 -0
- data/test/ft_86_dollar_fv.rb +68 -0
- data/test/ft_87_define.rb +74 -0
- data/test/ft_8_forget.rb +44 -0
- data/test/ft_9_cursor.rb +145 -0
- data/test/ft_9b_cursor.rb +105 -0
- data/test/ft_tests.rb +124 -0
- data/test/hash_test.rb +75 -0
- data/test/hparticipant_test.rb +164 -0
- data/test/lookup_att_test.rb +90 -0
- data/test/lookup_vf_test.rb +94 -0
- data/test/misc_test.rb +90 -0
- data/test/nut_0_irb.rb +20 -0
- data/test/obs_test.rb +142 -0
- data/test/orest_test.rb +251 -0
- data/test/param_test.rb +290 -0
- data/test/participant_test.rb +101 -0
- data/test/pending.rb +23 -0
- data/test/ps_representation.rb +133 -0
- data/test/rake_ltest.rb +38 -0
- data/test/rake_qtest.rb +68 -0
- data/test/raw_prog_test.rb +412 -0
- data/test/restart_cron_test.rb +136 -0
- data/test/restart_paused_test.rb +98 -0
- data/test/restart_sleep_test.rb +140 -0
- data/test/restart_tests.rb +18 -0
- data/test/restart_when_test.rb +112 -0
- data/test/ruby_procdef_test.rb +132 -0
- data/test/rutest_utils.rb +63 -0
- data/test/sec_test.rb +205 -0
- data/test/slock_test.rb +80 -0
- data/test/storage_test.rb +44 -0
- data/test/test.rb +3 -0
- data/test/timeout_test.rb +105 -0
- data/test/util_xml_test.rb +112 -0
- data/test/wfid_test.rb +175 -0
- data/test/wi_test.rb +75 -0
- metadata +433 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
|
17
|
+
# used to endorse or promote products derived from this software without
|
|
18
|
+
# specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#++
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# "made in Japan"
|
|
36
|
+
#
|
|
37
|
+
# John Mettraux at openwfe.org
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
require 'openwfe/expressions/flowexpression'
|
|
41
|
+
require 'openwfe/expressions/fe_sequence'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
module OpenWFE
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# The <process-definition> expression.
|
|
48
|
+
#
|
|
49
|
+
# <process-definition name="myprocess" revision="2">
|
|
50
|
+
# <sequence>
|
|
51
|
+
# <participant ref="alpha" />
|
|
52
|
+
# <subprocess ref="sub0" />
|
|
53
|
+
# </sequence>
|
|
54
|
+
# <process-definition name="sub0">
|
|
55
|
+
# <participant ref="bravo" />
|
|
56
|
+
# </process-definition>
|
|
57
|
+
# </process-definition>
|
|
58
|
+
#
|
|
59
|
+
# In a Ruby process definition :
|
|
60
|
+
#
|
|
61
|
+
# class Test0 < OpenWFE::ProcessDefinition
|
|
62
|
+
#
|
|
63
|
+
# sequence do
|
|
64
|
+
# sub0
|
|
65
|
+
# sub1
|
|
66
|
+
# sub2
|
|
67
|
+
# sub3
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# process_definition :name => "sub0" do
|
|
71
|
+
# _print "sub0"
|
|
72
|
+
# end
|
|
73
|
+
# define :name => "sub1" do
|
|
74
|
+
# _print "sub1"
|
|
75
|
+
# end
|
|
76
|
+
# process_definition "sub2" do
|
|
77
|
+
# _print "sub2"
|
|
78
|
+
# end
|
|
79
|
+
# define "sub3" do
|
|
80
|
+
# _print "sub3"
|
|
81
|
+
# end
|
|
82
|
+
# end
|
|
83
|
+
#
|
|
84
|
+
# It is most often used with its "process-definition" name, but "define"
|
|
85
|
+
# and "workflow-definition" are accepted as well.
|
|
86
|
+
#
|
|
87
|
+
class DefineExpression < SequenceExpression
|
|
88
|
+
|
|
89
|
+
is_definition
|
|
90
|
+
|
|
91
|
+
names :define, :process_definition, :workflow_definition
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# A pointer to the body expression of this process definition.
|
|
95
|
+
#
|
|
96
|
+
attr_accessor :body_fei
|
|
97
|
+
|
|
98
|
+
#--
|
|
99
|
+
# Evaluates the definition, but doesn't apply its body, will
|
|
100
|
+
# simply return the body fei.
|
|
101
|
+
#
|
|
102
|
+
#def evaluate (workitem)
|
|
103
|
+
# @eval_only = true
|
|
104
|
+
# apply workitem
|
|
105
|
+
# @body_fei
|
|
106
|
+
#end
|
|
107
|
+
#++
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# Called at the end of the 'evaluation', the 'apply' operation on
|
|
111
|
+
# the body of the definition is done here.
|
|
112
|
+
#
|
|
113
|
+
def reply_to_parent (workitem)
|
|
114
|
+
|
|
115
|
+
#return if @eval_only
|
|
116
|
+
|
|
117
|
+
#puts "/// \n bf #{@body_fei} \n wi.fei #{workitem.fei}"
|
|
118
|
+
|
|
119
|
+
return super(workitem) \
|
|
120
|
+
if @body_fei == nil or @body_fei == workitem.fei
|
|
121
|
+
#unless @body_fei
|
|
122
|
+
|
|
123
|
+
#_fei = @body_fei
|
|
124
|
+
#@body_fei = nil
|
|
125
|
+
#store_itself
|
|
126
|
+
#get_expression_pool.apply _fei, workitem
|
|
127
|
+
|
|
128
|
+
get_expression_pool.apply @body_fei, workitem
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# Overrides the set_variable in FlowExpression to
|
|
133
|
+
# make sure to intercept requests for binding subprocesses
|
|
134
|
+
# at the engine level and to store a copy of the raw expression,
|
|
135
|
+
# not only the flow expression id.
|
|
136
|
+
#
|
|
137
|
+
def set_variable (name, fei)
|
|
138
|
+
|
|
139
|
+
if name[0, 2] == "//"
|
|
140
|
+
|
|
141
|
+
raw_exp = get_expression_pool.fetch_expression(fei).dup
|
|
142
|
+
raw_exp.parent_id = nil
|
|
143
|
+
raw_exp.fei = raw_exp.fei.dup
|
|
144
|
+
fei = raw_exp.fei
|
|
145
|
+
fei.wfid = get_wfid_generator.generate
|
|
146
|
+
|
|
147
|
+
raw_exp.store_itself
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
super name, fei
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
protected
|
|
154
|
+
|
|
155
|
+
#
|
|
156
|
+
# Determines the flowExpressionId of the next child to apply.
|
|
157
|
+
#
|
|
158
|
+
def next_child (current_fei)
|
|
159
|
+
|
|
160
|
+
next_fei = super
|
|
161
|
+
|
|
162
|
+
return nil unless next_fei
|
|
163
|
+
|
|
164
|
+
rawchild = get_expression_pool.fetch_expression next_fei
|
|
165
|
+
|
|
166
|
+
return next_child(next_fei) unless rawchild
|
|
167
|
+
|
|
168
|
+
unless rawchild.is_definition?
|
|
169
|
+
|
|
170
|
+
unless @body_fei
|
|
171
|
+
@body_fei = next_fei
|
|
172
|
+
store_itself
|
|
173
|
+
end
|
|
174
|
+
return next_child(next_fei)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
exp_class = get_expression_map.get_class rawchild
|
|
178
|
+
|
|
179
|
+
if exp_class == DefineExpression
|
|
180
|
+
set_variable rawchild.definition_name, next_fei
|
|
181
|
+
return next_child(next_fei)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
next_fei
|
|
185
|
+
#
|
|
186
|
+
# expression is a 'set', a 'filter-definition' or
|
|
187
|
+
# something like that, let it get applied
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
|
17
|
+
# used to endorse or promote products derived from this software without
|
|
18
|
+
# specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#++
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# "made in Japan"
|
|
36
|
+
#
|
|
37
|
+
# John Mettraux at openwfe.org
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
require 'openwfe/utils'
|
|
41
|
+
require 'openwfe/expressions/flowexpression'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# redo / undo (cancel)
|
|
46
|
+
#
|
|
47
|
+
|
|
48
|
+
module OpenWFE
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# Every expression in OpenWFEru accepts a 'tag' attribute. This tag
|
|
52
|
+
# can later be referenced by an 'undo' or 'redo' expression.
|
|
53
|
+
# Tags are active as soon as an expression is applied and they vanish
|
|
54
|
+
# when the expression replies to its parent expression or is cancelled.
|
|
55
|
+
#
|
|
56
|
+
# Calling for the undo of a non-existent tag throws no error, the flow
|
|
57
|
+
# simply resumes.
|
|
58
|
+
#
|
|
59
|
+
# concurrence do
|
|
60
|
+
# sequence :tag => "side_job" do
|
|
61
|
+
# participant "alice"
|
|
62
|
+
# participant "bob"
|
|
63
|
+
# end
|
|
64
|
+
# sequence do
|
|
65
|
+
# participant "charly"
|
|
66
|
+
# undo :ref => "side_job"
|
|
67
|
+
# end
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# In this example, as soon as the participant charly is over, the sequence
|
|
71
|
+
# 'side_job' gets undone (cancelled). If the sequence 'side_job' was
|
|
72
|
+
# already over, the "undo" will have no effect.
|
|
73
|
+
#
|
|
74
|
+
class UndoExpression < FlowExpression
|
|
75
|
+
|
|
76
|
+
names :undo
|
|
77
|
+
|
|
78
|
+
def apply (workitem)
|
|
79
|
+
|
|
80
|
+
tag = lookup_tag(workitem)
|
|
81
|
+
|
|
82
|
+
undo_self = false
|
|
83
|
+
|
|
84
|
+
if tag
|
|
85
|
+
#OpenWFE::call_in_thread(fei.expression_name, self) do
|
|
86
|
+
process_tag tag
|
|
87
|
+
#end
|
|
88
|
+
|
|
89
|
+
undo_self = tag.fei.ancestor_of?(@fei)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
reply_to_parent(workitem) unless undo_self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Calls the expression pool cancel() method upon the tagged
|
|
97
|
+
# expression.
|
|
98
|
+
#
|
|
99
|
+
def process_tag (tag)
|
|
100
|
+
|
|
101
|
+
ldebug do
|
|
102
|
+
"process_tag() #{fei.to_debug_s} to undo #{tag.fei.to_debug_s}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
#get_expression_pool.cancel_and_reply_to_parent(
|
|
106
|
+
# tag.raw_expression.fei, tag.workitem)
|
|
107
|
+
|
|
108
|
+
exp = get_expression_pool.fetch_expression(tag.raw_expression.fei)
|
|
109
|
+
|
|
110
|
+
get_expression_pool.cancel(tag.raw_expression.fei)
|
|
111
|
+
|
|
112
|
+
get_expression_pool.reply_to_parent(exp, tag.workitem, false)
|
|
113
|
+
#
|
|
114
|
+
# 'remove' is set to false, cancel already removed the
|
|
115
|
+
# expression
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#def reply (workitem)
|
|
119
|
+
#end
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
def lookup_tag (workitem)
|
|
124
|
+
|
|
125
|
+
tagname = lookup_attribute :ref, workitem
|
|
126
|
+
|
|
127
|
+
tag = lookup_variable tagname
|
|
128
|
+
|
|
129
|
+
lwarn { "lookup_tag() no tag named '#{tagname}' found" } \
|
|
130
|
+
unless tag
|
|
131
|
+
|
|
132
|
+
tag
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
# Every expression in OpenWFEru accepts a 'tag' attribute. This tag
|
|
138
|
+
# can later be referenced by an 'undo' or 'redo' expression.
|
|
139
|
+
#
|
|
140
|
+
# Calling for the undo of a non-existent tag throws no error, the flow
|
|
141
|
+
# simply resumes.
|
|
142
|
+
#
|
|
143
|
+
class RedoExpression < UndoExpression
|
|
144
|
+
|
|
145
|
+
names :redo
|
|
146
|
+
|
|
147
|
+
def process_tag (tag)
|
|
148
|
+
|
|
149
|
+
ldebug do
|
|
150
|
+
"process_tag() #{fei.to_debug_s} to redo #{tag.fei.to_debug_s}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
# cancel
|
|
155
|
+
|
|
156
|
+
get_expression_pool.cancel(tag.fei)
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
# [re]apply
|
|
160
|
+
|
|
161
|
+
tag.raw_expression.application_context = @application_context
|
|
162
|
+
|
|
163
|
+
get_expression_pool.apply tag.raw_expression, tag.workitem
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2006-2008, John Mettraux, OpenWFE.org
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
|
17
|
+
# used to endorse or promote products derived from this software without
|
|
18
|
+
# specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#++
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# "made in Japan"
|
|
36
|
+
#
|
|
37
|
+
# John Mettraux at openwfe.org
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
require 'openwfe/workitem'
|
|
41
|
+
require 'openwfe/flowexpressionid'
|
|
42
|
+
require 'openwfe/expressions/flowexpression'
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# expressions like 'set' and 'unset' and their utility methods
|
|
47
|
+
#
|
|
48
|
+
|
|
49
|
+
module OpenWFE
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# A Mixin shared by CompareExpression and DefinedExpression.
|
|
53
|
+
#
|
|
54
|
+
module LookupMixin
|
|
55
|
+
|
|
56
|
+
protected
|
|
57
|
+
|
|
58
|
+
def lookup_var_value (workitem, suffix=nil)
|
|
59
|
+
|
|
60
|
+
v = lookup_var workitem, suffix
|
|
61
|
+
|
|
62
|
+
return lookup_variable(v) if v
|
|
63
|
+
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def lookup_field_value (workitem, suffix=nil)
|
|
68
|
+
|
|
69
|
+
f = lookup_field workitem, suffix
|
|
70
|
+
|
|
71
|
+
return workitem.attributes[f] if f
|
|
72
|
+
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def lookup_var (workitem, suffix=nil)
|
|
77
|
+
|
|
78
|
+
do_lookup workitem, suffix, [ :variable, :var, :v ]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def lookup_field (workitem, suffix=nil)
|
|
82
|
+
|
|
83
|
+
do_lookup workitem, suffix, [ :field, :f ]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def do_lookup (workitem, suffix, atts)
|
|
87
|
+
|
|
88
|
+
atts.each do |a|
|
|
89
|
+
a = a.to_s + '-' + suffix if suffix
|
|
90
|
+
v = lookup_string_attribute a, workitem
|
|
91
|
+
return v if v
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# A parent class for the 'equals' expression.
|
|
100
|
+
#
|
|
101
|
+
# (there should be a 'greater-than' and a 'lesser-than' expression,
|
|
102
|
+
# but there are not that needed for now).
|
|
103
|
+
#
|
|
104
|
+
class ComparisonExpression < FlowExpression
|
|
105
|
+
include LookupMixin
|
|
106
|
+
|
|
107
|
+
def apply (workitem)
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# preparing for children handling... later...
|
|
111
|
+
#
|
|
112
|
+
|
|
113
|
+
reply workitem
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def reply (workitem)
|
|
117
|
+
|
|
118
|
+
value_a, value_b = lookup_values workitem
|
|
119
|
+
|
|
120
|
+
result = compare value_a, value_b
|
|
121
|
+
|
|
122
|
+
ldebug { "apply() result is '#{result}' #{@fei.to_debug_s}" }
|
|
123
|
+
|
|
124
|
+
workitem.set_result result
|
|
125
|
+
|
|
126
|
+
reply_to_parent workitem
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
protected
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# The bulk job of looking up the values to compare
|
|
133
|
+
#
|
|
134
|
+
def lookup_values (workitem)
|
|
135
|
+
|
|
136
|
+
value_a = lookup_value workitem
|
|
137
|
+
value_b = lookup_value workitem, :prefix => 'other'
|
|
138
|
+
|
|
139
|
+
value_c = lookup_variable_or_field_value workitem
|
|
140
|
+
|
|
141
|
+
if not value_a and value_b
|
|
142
|
+
value_a = value_c
|
|
143
|
+
elsif value_a and not value_b
|
|
144
|
+
value_b = value_c
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
[ value_a, value_b ]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# Returns the value pointed at by the variable attribute or by
|
|
152
|
+
# the field attribute, in that order.
|
|
153
|
+
#
|
|
154
|
+
def lookup_variable_or_field_value (workitem)
|
|
155
|
+
|
|
156
|
+
lookup_var_value(workitem) || lookup_field_value(workitem)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# The 'equals' expression compares two values. If those values are equal,
|
|
162
|
+
# the field (attribute) of the workitem named '__result__' will be
|
|
163
|
+
# set to true (else false).
|
|
164
|
+
#
|
|
165
|
+
# Usually, this expression is used within the 'if' expression.
|
|
166
|
+
#
|
|
167
|
+
# <if>
|
|
168
|
+
# <equals field-value="customer_name" other-value="Dupont" />
|
|
169
|
+
# <!-- then -->
|
|
170
|
+
# <participant ref="special_salesman" />
|
|
171
|
+
# <!-- else -->
|
|
172
|
+
# <participant ref="ordinary_salesman" />
|
|
173
|
+
# </if>
|
|
174
|
+
#
|
|
175
|
+
# (The 'if' expression reads the '__result__' field to route the flow
|
|
176
|
+
# either towards the then branch, either towards the else one).
|
|
177
|
+
#
|
|
178
|
+
#
|
|
179
|
+
# With a Ruby process definition, a variation on the same 'equals' :
|
|
180
|
+
#
|
|
181
|
+
# equals :field_value => "phone", :other_value => "090078367"
|
|
182
|
+
# equals :field_val => "phone", :other_value => "090078367"
|
|
183
|
+
# equals :f_value => "phone", :other_value => "090078367"
|
|
184
|
+
# equals :f_val => "phone", :other_value => "090078367"
|
|
185
|
+
# equals :f_val => "phone", :other_val => "090078367"
|
|
186
|
+
#
|
|
187
|
+
# Thus, note that 'variable' in an expression attribute can be
|
|
188
|
+
# shortened to 'var' or 'v'. 'value' can be shortened to 'val' and
|
|
189
|
+
# 'field' to 'f'.
|
|
190
|
+
#
|
|
191
|
+
# Usually, the "test" attribute of the "if" expression is preferred
|
|
192
|
+
# over this 'equals' expression, like in :
|
|
193
|
+
#
|
|
194
|
+
# <if test="${f:customer_name} == Dupont">
|
|
195
|
+
# <!-- then -->
|
|
196
|
+
# <participant ref="special_salesman" />
|
|
197
|
+
# <!-- else -->
|
|
198
|
+
# <participant ref="ordinary_salesman" />
|
|
199
|
+
# </if>
|
|
200
|
+
#
|
|
201
|
+
# Another shortcut : the 'participant' and the 'subprocess' expressions
|
|
202
|
+
# accept an optional 'if' (or 'unless') attribute, so that ifs can be
|
|
203
|
+
# contracted to :
|
|
204
|
+
#
|
|
205
|
+
# participant :ref => "toto", :if => "${f:customer_name} == Alfred"
|
|
206
|
+
# subprocess :ref => "special_delivery", :if => "'${f:special}' != ''"
|
|
207
|
+
#
|
|
208
|
+
# This also works with the implicit form of the participant and the
|
|
209
|
+
# subprocess :
|
|
210
|
+
#
|
|
211
|
+
# toto :if => "${f:customer_name} == Alfred"
|
|
212
|
+
# special_delivery :if => "'${f:special}' != ''"
|
|
213
|
+
#
|
|
214
|
+
class EqualsExpression < ComparisonExpression
|
|
215
|
+
|
|
216
|
+
names :equals
|
|
217
|
+
|
|
218
|
+
protected
|
|
219
|
+
|
|
220
|
+
def compare (a, b)
|
|
221
|
+
|
|
222
|
+
(a == b)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
#
|
|
227
|
+
# This expression class actually implements 'defined' and 'undefined'.
|
|
228
|
+
#
|
|
229
|
+
# They are some kind of 'equals' for validating the presence or not
|
|
230
|
+
# of a variable or a workitem field (attribute).
|
|
231
|
+
#
|
|
232
|
+
# <if>
|
|
233
|
+
# <defined field="customer">
|
|
234
|
+
# <!-- then -->
|
|
235
|
+
# <subprocess ref="call_customer" />
|
|
236
|
+
# </if>
|
|
237
|
+
#
|
|
238
|
+
# Since OpenWFEru 0.9.17, 'defined' and 'undefined' can be easily replaced
|
|
239
|
+
# by the "is [not ]set" suffix in the dollar notation :
|
|
240
|
+
#
|
|
241
|
+
# <if test="${f:customer_name} is set">
|
|
242
|
+
# <!-- then -->
|
|
243
|
+
# <subprocess ref="call_customer" />
|
|
244
|
+
# </if>
|
|
245
|
+
#
|
|
246
|
+
class DefinedExpression < FlowExpression
|
|
247
|
+
include LookupMixin
|
|
248
|
+
|
|
249
|
+
names :defined, :undefined
|
|
250
|
+
|
|
251
|
+
def apply (workitem)
|
|
252
|
+
|
|
253
|
+
fname = lookup_field(workitem, 'value') || lookup_field(workitem)
|
|
254
|
+
|
|
255
|
+
fmatch = lookup_string_attribute(:field_match, workitem)
|
|
256
|
+
|
|
257
|
+
vname = lookup_var(workitem, 'value') || lookup_var(workitem)
|
|
258
|
+
|
|
259
|
+
result = if fname
|
|
260
|
+
workitem.has_attribute?(fname)
|
|
261
|
+
elsif vname
|
|
262
|
+
lookup_variable(vname) != nil
|
|
263
|
+
elsif fmatch
|
|
264
|
+
field_match?(workitem, fmatch)
|
|
265
|
+
else
|
|
266
|
+
false # when in doubt, say 'no' (even when 'undefined' ?)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
result = ( ! result) \
|
|
270
|
+
if result != nil and fei.expression_name == 'undefined'
|
|
271
|
+
|
|
272
|
+
workitem.set_result result
|
|
273
|
+
|
|
274
|
+
reply_to_parent workitem
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
protected
|
|
278
|
+
|
|
279
|
+
def field_match? (workitem, regex)
|
|
280
|
+
|
|
281
|
+
workitem.attributes.each do |k, v|
|
|
282
|
+
|
|
283
|
+
return true if k.match(regex)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
false
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
end
|
|
291
|
+
|