bpmn 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class Element
6
- include ActiveModel::Model
7
-
8
- attr_accessor :id, :name, :extension_elements
9
-
10
- def initialize(attributes = {})
11
- super(attributes.slice(:id, :name))
12
-
13
- @extension_elements = ExtensionElements.new(attributes[:extension_elements]) if attributes[:extension_elements].present?
14
- end
15
-
16
- def inspect
17
- "#<#{self.class.name.gsub(/SpotFlow::/, "")} @id=#{id.inspect} @name=#{name.inspect}>"
18
- end
19
- end
20
-
21
- class Message < Element
22
- end
23
-
24
- class Signal < Element
25
- end
26
-
27
- class Error < Element
28
- end
29
-
30
- class Collaboration < Element
31
- end
32
-
33
- class LaneSet < Element
34
- end
35
-
36
- class Participant < Element
37
- attr_accessor :process_ref, :process
38
-
39
- def initialize(attributes = {})
40
- super(attributes.except(:process_ref))
41
- end
42
- end
43
- end
44
- end
@@ -1,195 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class Event < Step
6
- attr_accessor :event_definitions
7
-
8
- def initialize(attributes = {})
9
- super(attributes.except(:message_event_definition, :signal_event_definition, :error_event_definition, :terminate_event_definition, :timer_event_definition))
10
-
11
- @event_definitions = []
12
-
13
- Array.wrap(attributes[:message_event_definition]).each do |med|
14
- @event_definitions.push MessageEventDefinition.new(med)
15
- end if attributes[:message_event_definition].present?
16
-
17
- Array.wrap(attributes[:signal_event_definition]).each do |sed|
18
- @event_definitions.push SignalEventDefinition.new(sed)
19
- end if attributes[:signal_event_definition].present?
20
-
21
- Array.wrap(attributes[:error_event_definition]).each do |eed|
22
- @event_definitions.push ErrorEventDefinition.new(eed)
23
- end if attributes[:error_event_definition].present?
24
-
25
- Array.wrap(attributes[:terminate_event_definition]).each do |ted|
26
- @event_definitions.push TerminateEventDefinition.new(ted)
27
- end if attributes[:terminate_event_definition].present?
28
-
29
- Array.wrap(attributes[:timer_event_definition]).each do |ted|
30
- @event_definitions.push TimerEventDefinition.new(ted)
31
- end if attributes[:timer_event_definition].present?
32
- end
33
-
34
- def event_definition_ids
35
- event_definitions.map(&:id)
36
- end
37
-
38
- def is_catching?
39
- false
40
- end
41
-
42
- def is_throwing?
43
- false
44
- end
45
-
46
- def is_none?
47
- event_definitions.empty?
48
- end
49
-
50
- def is_conditional?
51
- conditional_event_definition.present?
52
- end
53
-
54
- def is_escalation?
55
- escalation_event_definition.present?
56
- end
57
-
58
- def is_error?
59
- error_event_definition.present?
60
- end
61
-
62
- def is_message?
63
- !message_event_definitions.empty?
64
- end
65
-
66
- def is_signal?
67
- !signal_event_definitions.empty?
68
- end
69
-
70
- def is_terminate?
71
- terminate_event_definition.present?
72
- end
73
-
74
- def is_timer?
75
- timer_event_definition.present?
76
- end
77
-
78
- def conditional_event_definition
79
- event_definitions.find { |ed| ed.is_a?(ConditionalEventDefinition) }
80
- end
81
-
82
- def escalation_event_definition
83
- event_definitions.find { |ed| ed.is_a?(EscalationEventDefinition) }
84
- end
85
-
86
- def error_event_definitions
87
- event_definitions.select { |ed| ed.is_a?(ErrorEventDefinition) }
88
- end
89
-
90
- def error_event_definition
91
- event_definitions.find { |ed| ed.is_a?(ErrorEventDefinition) }
92
- end
93
-
94
- def message_event_definitions
95
- event_definitions.select { |ed| ed.is_a?(MessageEventDefinition) }
96
- end
97
-
98
- def signal_event_definitions
99
- event_definitions.select { |ed| ed.is_a?(SignalEventDefinition) }
100
- end
101
-
102
- def terminate_event_definition
103
- event_definitions.find { |ed| ed.is_a?(TerminateEventDefinition) }
104
- end
105
-
106
- def timer_event_definition
107
- event_definitions.find { |ed| ed.is_a?(TimerEventDefinition) }
108
- end
109
-
110
- def execute(execution)
111
- event_definitions.each { |event_definition| event_definition.execute(execution) }
112
- end
113
- end
114
-
115
- class StartEvent < Event
116
-
117
- def is_catching?
118
- true
119
- end
120
-
121
- def execute(execution)
122
- super
123
- leave(execution)
124
- end
125
- end
126
-
127
- class IntermediateThrowEvent < Event
128
-
129
- def is_throwing?
130
- true
131
- end
132
-
133
- def execute(execution)
134
- super
135
- leave(execution)
136
- end
137
- end
138
-
139
- class IntermediateCatchEvent < Event
140
-
141
- def is_catching?
142
- true
143
- end
144
-
145
- def execute(execution)
146
- super
147
- execution.wait
148
- end
149
-
150
- def signal(execution)
151
- leave(execution)
152
- end
153
- end
154
-
155
- class BoundaryEvent < Event
156
- attr_accessor :attached_to_ref, :attached_to, :cancel_activity
157
-
158
- def initialize(attributes = {})
159
- super(attributes.except(:attached_to_ref, :cancel_activity))
160
-
161
- @attached_to_ref = attributes[:attached_to_ref]
162
- @cancel_activity = true
163
- if attributes[:cancel_activity].present?
164
- @cancel_activity = attributes[:cancel_activity] == "false" ? false : true
165
- end
166
- end
167
-
168
- def is_catching?
169
- true
170
- end
171
-
172
- def execute(execution)
173
- super
174
- execution.wait
175
- end
176
-
177
- def signal(execution)
178
- execution.attached_to.terminate if cancel_activity
179
- leave(execution)
180
- end
181
- end
182
-
183
- class EndEvent < Event
184
-
185
- def is_throwing?
186
- true
187
- end
188
-
189
- def execute(execution)
190
- super
191
- execution.end(true)
192
- end
193
- end
194
- end
195
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class EventDefinition < Element
6
- def execute(execution)
7
- end
8
- end
9
-
10
- class ConditionalEventDefinition < EventDefinition
11
- attr_accessor :variable_name, :variable_events, :condition
12
-
13
- def initialize(attributes = {})
14
- super(attributes.except(:variable_name, :variable_events, :condition))
15
-
16
- @variable_name = moddle[:variable_name] # "var1"
17
- @variable_events = moddle[:variable_events] # "create, update"
18
- @condition = moddle[:condition] # var1 = 1
19
- end
20
- end
21
-
22
- class EscalationEventDefinition < EventDefinition
23
- end
24
-
25
- class ErrorEventDefinition < EventDefinition
26
- attr_accessor :error_ref, :error
27
- attr_accessor :error_code_variable, :error_message_variable
28
-
29
- def initialize(attributes = {})
30
- super(attributes.except(:error_ref, :error_code_variable, :error_message_variable))
31
-
32
- @error_ref = attributes[:error_ref]
33
- @error_code_variable = attributes[:error_code_variable]
34
- @error_message_variable = attributes[:error_message_variable]
35
- end
36
-
37
- def execute(execution)
38
- if execution.step.is_throwing?
39
- execution.throw_error(error_name)
40
- else
41
- execution.error_names.push error_name
42
- end
43
- end
44
-
45
- def error_id
46
- error&.id
47
- end
48
-
49
- def error_name
50
- error&.name
51
- end
52
- end
53
-
54
- class MessageEventDefinition < EventDefinition
55
- attr_accessor :message_ref, :message
56
-
57
- def initialize(attributes = {})
58
- super(attributes.except(:message_ref))
59
-
60
- @message_ref = attributes[:message_ref]
61
- end
62
-
63
- def execute(execution)
64
- if execution.step.is_throwing?
65
- execution.throw_message(message_name)
66
- else
67
- execution.message_names.push message_name
68
- end
69
- end
70
-
71
- def message_id
72
- message&.id
73
- end
74
-
75
- def message_name
76
- message&.name
77
- end
78
- end
79
-
80
- class SignalEventDefinition < EventDefinition
81
- attr_accessor :signal_ref, :signal
82
-
83
- def initialize(attributes = {})
84
- super(attributes.except(:signal_ref))
85
-
86
- @signal_ref = moddle[:signal_ref]
87
- end
88
-
89
- def signal_id
90
- signal&.id
91
- end
92
-
93
- def signal_name
94
- signal&.name
95
- end
96
- end
97
-
98
- class TerminateEventDefinition < EventDefinition
99
-
100
- def execute(execution)
101
- execution.parent&.terminate
102
- end
103
- end
104
-
105
- class TimerEventDefinition < EventDefinition
106
- attr_accessor :time_date, :time_duration_type, :time_duration, :time_cycle
107
-
108
- def initialize(attributes = {})
109
- super(attributes.except(:time_date, :time_duration, :time_cycle))
110
-
111
- @time_duration_type = attributes[:time_duration_type]
112
- @time_duration = attributes[:time_duration]
113
- end
114
-
115
- def execute(execution)
116
- if execution.step.is_catching?
117
- execution.timer_expires_at = time_due
118
- end
119
- end
120
-
121
- private
122
-
123
- def time_due
124
- # Return the next time the timer is due
125
- if time_date
126
- return Date.parse(time_date)
127
- elsif time_duration
128
- return Time.zone.now + ActiveSupport::Duration.parse(time_duration)
129
- else
130
- return Time.zone.now # time_cycle not yet implemented
131
- end
132
- end
133
- end
134
- end
135
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class ExtensionElements
6
- VALID_EXTENSION_NAMESPACES = %w[zeebe]
7
-
8
- attr_accessor :assignment_definition, :called_element, :called_decision, :form_definition, :io_mapping, :properties, :script, :subscription, :task_definition, :task_headers, :task_schedule
9
-
10
- def initialize(attributes = {})
11
- if attributes[:properties].present?
12
- @properties = HashWithIndifferentAccess.new
13
- Array.wrap(attributes[:properties][:property]).each { |property_moddle| @properties[property_moddle[:name]] = property_moddle[:value] }
14
- end
15
-
16
- @assignment_definition = Zeebe::AssignmentDefinition.new(attributes[:assignment_definition]) if attributes[:assignment_definition].present?
17
- @called_element = Zeebe::CalledElement.new(attributes[:called_element]) if attributes[:called_element].present?
18
- @called_decision = Zeebe::CalledDecision.new(attributes[:called_decision]) if attributes[:called_decision].present?
19
- @form_definition = Zeebe::FormDefinition.new(attributes[:form_definition]) if attributes[:form_definition].present?
20
- @io_mapping = Zeebe::IoMapping.new(attributes[:io_mapping]) if attributes[:io_mapping].present?
21
- @script = Zeebe::Script.new(attributes[:script]) if attributes[:script].present?
22
- @subscription = Zeebe::Subscription.new(attributes[:subscription]) if attributes[:subscription].present?
23
- @task_definition = Zeebe::TaskDefinition.new(attributes[:task_definition]) if attributes[:task_definition].present?
24
- @task_headers = Zeebe::TaskHeaders.new(attributes[:task_headers]) if attributes[:task_headers].present?
25
- @task_schedule = Zeebe::TaskSchedule.new(attributes[:task_schedule]) if attributes[:task_schedule].present?
26
- end
27
- end
28
- end
29
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class Extension
6
- include ActiveModel::Model
7
- end
8
- end
9
-
10
- module Zeebe
11
- class AssignmentDefinition < Bpmn::Extension
12
- attr_accessor :assignee, :candidate_groups, :candidate_users
13
- end
14
-
15
- class CalledElement < Bpmn::Extension
16
- attr_accessor :process_id, :propagate_all_child_variables, :propagate_all_parent_variables
17
-
18
- def initialize(attributes = {})
19
- super(attributes.except(:propagate_all_child_variables))
20
-
21
- @propagate_all_parent_variables = true
22
- @propagate_all_parent_variables = attributes[:propagate_all_parent_variables] == "true" if attributes[:propagate_all_parent_variables].present?
23
- @propagate_all_child_variables = attributes[:propagate_all_child_variables] == "true"
24
- end
25
- end
26
-
27
- class CalledDecision < Bpmn::Extension
28
- attr_accessor :decision_id, :result_variable
29
- end
30
-
31
- class FormDefinition < Bpmn::Extension
32
- attr_accessor :form_key
33
- end
34
-
35
- class IoMapping < Bpmn::Extension
36
- attr_reader :inputs, :outputs
37
-
38
- def initialize(attributes = {})
39
- super(attributes.except(:input, :output))
40
-
41
- @inputs = Array.wrap(attributes[:input]).map { |atts| Parameter.new(atts) } if attributes[:input].present?
42
- @outputs = Array.wrap(attributes[:output]).map { |atts| Parameter.new(atts) } if attributes[:output].present?
43
- end
44
- end
45
-
46
- class Parameter < Bpmn::Extension
47
- attr_accessor :source, :target
48
- end
49
-
50
- class Script < Bpmn::Extension
51
- attr_accessor :expression, :result_variable
52
- end
53
-
54
- class Subscription < Bpmn::Extension
55
- attr_accessor :correlation_key
56
- end
57
-
58
- class TaskDefinition < Bpmn::Extension
59
- attr_accessor :type, :retries
60
- end
61
-
62
- class TaskHeaders < Bpmn::Extension
63
- attr_accessor :headers
64
-
65
- def initialize(attributes = {})
66
- super(attributes.except(:header))
67
-
68
- @headers = HashWithIndifferentAccess.new
69
- Array.wrap(attributes[:header]).each { |header| @headers[header[:key]] = header[:value] }
70
- end
71
- end
72
-
73
- class TaskSchedule < Bpmn::Extension
74
- attr_accessor :due_date, :follow_up_date
75
- end
76
- end
77
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class Flow < Element
6
- attr_accessor :source_ref, :target_ref
7
- attr_accessor :source, :target
8
-
9
- def initialize(attributes = {})
10
- super(attributes.except(:source_ref, :target_ref))
11
-
12
- @source_ref = attributes[:source_ref]
13
- @target_ref = attributes[:target_ref]
14
- @source = nil
15
- @target = nil
16
- end
17
-
18
- def inspect
19
- parts = ["#<#{self.class.name.gsub(/SpotFlow::/, "")} @id=#{id.inspect}"]
20
- parts << "@source_ref=#{source_ref.inspect}" if source_ref
21
- parts << "@target_ref=#{target_ref.inspect}" if target_ref
22
- parts.join(" ") + ">"
23
- end
24
- end
25
-
26
- class Association < Flow
27
- end
28
-
29
- class SequenceFlow < Flow
30
- attr_accessor :condition
31
-
32
- def initialize(attributes = {})
33
- super(attributes.except(:condition))
34
-
35
- @condition = attributes[:condition_expression]
36
- end
37
-
38
- def evaluate(execution)
39
- return true unless condition
40
- execution.evaluate_condition(condition)
41
- end
42
- end
43
-
44
- class TextAnnotation < Flow
45
- end
46
- end
47
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFlow
4
- module Bpmn
5
- class Gateway < Step
6
-
7
- def execute(execution)
8
- if converging?
9
- if is_enabled?(execution)
10
- return leave(execution)
11
- else
12
- execution.wait
13
- end
14
- else
15
- return leave(execution)
16
- end
17
- end
18
-
19
- #
20
- # Algorithm from https://researcher.watson.ibm.com/researcher/files/zurich-hvo/bpm2010-1.pdf
21
- #
22
- def is_enabled?(execution)
23
- filled = []
24
- empty = []
25
-
26
- incoming.each { |flow| execution.tokens_in.include?(flow.id) ? filled.push(flow) : empty.push(flow) }
27
-
28
- # Filled slots don't need to be searched for tokens
29
- index = 0
30
- while (index < filled.length)
31
- current_flow = filled[index]
32
- current_flow.source.incoming.each do |incoming_flow|
33
- filled.push(incoming_flow) unless filled.include?(incoming_flow) || incoming_flow.target == self
34
- end
35
- index = index + 1
36
- end
37
-
38
- # Empty slots need to be searched for tokens
39
- index = 0
40
- while (index < empty.length)
41
- current_flow = empty[index]
42
- current_flow.source.incoming.each do |incoming_flow|
43
- empty.push(incoming_flow) unless filled.include?(incoming_flow) || empty.include?(incoming_flow) || incoming_flow.target == self
44
- end
45
- index = index + 1
46
- end
47
-
48
- empty_ids = empty.map { |g| g.id }
49
-
50
- # If there are empty slots with tokens we need to wait
51
- return false if (empty_ids & execution.parent.tokens).length > 0
52
- return true
53
- end
54
- end
55
-
56
- class ExclusiveGateway < Gateway
57
- # RULE: Only one flow is taken
58
- def outgoing_flows(step_execution)
59
- flows = super
60
- return [flows.first]
61
- end
62
- end
63
-
64
- class ParallelGateway < Gateway
65
- # RULE: All flows are taken
66
- end
67
-
68
- class InclusiveGateway < Gateway
69
- # RULE: All valid flows are taken
70
- # NOTE: Camunda 8 only support diverging but not converging inclusive gateways
71
- end
72
-
73
- class EventBasedGateway < Gateway
74
- #
75
- # RULE: when an event created from an event gateway is caught,
76
- # all other waiting events must be canceled.
77
- #
78
- def cancel_waiting_events(execution)
79
- execution.targets.each do |target_execution|
80
- target_execution.terminate unless target_execution.ended?
81
- end
82
- end
83
- end
84
- end
85
- end