trailblazer-developer 0.0.22 → 0.0.25

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a222410dc0b884dcbcdfe24f5b9a4a5832be21fb49dad5dd704aedb52c4e7343
4
- data.tar.gz: b01faa368af768154576c6e0bdf2f2bbc881711379d28272360a2a24a767a4bc
3
+ metadata.gz: 0e213c664a285173ad64b7236f17a026dda9159c7e53c4e595f5c9b36a3bcd15
4
+ data.tar.gz: 2beca5ea9fb78c56263302c7dee6a5566e798b5a40db737283a63dcb5a35295c
5
5
  SHA512:
6
- metadata.gz: 0c2b7dd4169678f037105935e21b8bdd41ce97d2f79a225c0d3f5b404fcf0e417f38040185c19bc4943f0915f5412470ac870006b05f0b9a9797a0a1d740dd6c
7
- data.tar.gz: 228a6f5e0408ac370c4f1d46f98672605834cf1e0a4813732fdcc6d9b60a4fcdea2c9b35bf4921dc6ad4061f4f5d3f03a39ea6ecc4d6258790163855869cff9d
6
+ metadata.gz: ff33e213922bb017b4b9b6ba4b9a26cd7fb359437a03ed20902c9667cd593a026763253880fa43f9327858f0f871b95e3919e1247f49d04446d6c0fd462a490d
7
+ data.tar.gz: 9386d74ddd3f3fcfaa30f74b8a3fb7ed1aad1d692e6f19b28f8555e115dbae6e2c4a765f30d887bae8e5ab30763179aa5488ecb0b8a0833e255cd21c7bb22175
@@ -6,7 +6,7 @@ jobs:
6
6
  fail-fast: false
7
7
  matrix:
8
8
  # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
9
- ruby: [2.5, 2.6, 2.7, '3.0', head, jruby, jruby-head]
9
+ ruby: [2.5, 2.6, 2.7, '3.0', head, jruby]
10
10
  runs-on: ubuntu-latest
11
11
  steps:
12
12
  - uses: actions/checkout@v2
data/CHANGES.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 0.0.25
2
+
3
+ * Use `trailblazer-activity-dsl-linear` >= 1.0.0.beta1. This allows using this gem for testing beta versions.
4
+
5
+ # 0.0.24
6
+
7
+ * Use `trailblazer-activity-dsl-linear` >= 1.0.
8
+
9
+ # 0.0.23
10
+
11
+ * Remove `representable` dependency.
12
+ * Moved all editor-specific code to the `pro` gem (`client.rb` and `generate.rb`).
13
+
1
14
  # 0.0.22
2
15
 
3
16
  * Upgrade trb-activity, trb-activity-dsl-linear and representable versions.
data/Gemfile CHANGED
@@ -7,6 +7,4 @@ gemspec
7
7
  # gem "trailblazer-activity", path: "../trailblazer-activity"
8
8
  # gem "trailblazer-activity-dsl-linear", path: "../trailblazer-activity-dsl-linear"
9
9
  # gem "trailblazer-activity-dsl-linear", github: "trailblazer/trailblazer-activity-dsl-linear"
10
-
11
- gem "faraday"
12
- gem "multi_json"
10
+ # gem "trailblazer-activity", github: "trailblazer/trailblazer-activity"
data/README.md CHANGED
@@ -10,8 +10,11 @@ Find the complete documentation on the project website: [https://trailblazer.to/
10
10
 
11
11
  The `developer` gem provides the following neat tools.
12
12
 
13
- * Quick rendering of activities, including their taskWraps.
14
- * `wtf?` mode™: Run a broken activity and trace where an exception happened.
15
- * Connect to the visual TRB-editor: load, store, organize and render your app's activities.
16
- * Generate {Intermediate} data structures from TRB-editor.js files.
17
- * Debugging mode: run and debug workflows in the TRB-editor.
13
+ ## `wtf?` mode™
14
+
15
+ Run an activity and see its flow on the command line. Or - run a _broken_ activity and trace where an exception happened.
16
+
17
+ ![Tracing is awesome!](https://trailblazer.to/images/sketch/wtf.png)
18
+
19
+
20
+ ## Quick rendering of activities, including their taskWraps.
@@ -6,15 +6,15 @@ module Trailblazer
6
6
  # NOTE: this is absolutely to be considered as prototyping and acts more like a test helper ATM as
7
7
 
8
8
  module Developer
9
- def self.railway(*args)
10
- Render::Linear.(*args)
9
+ def self.railway(*args, **kws)
10
+ Render::Linear.(*args, **kws)
11
11
  end
12
12
 
13
13
  module Render
14
14
  module Linear
15
15
  module_function
16
16
 
17
- def call(operation, options = {style: :line})
17
+ def call(operation, style: :line)
18
18
  graph = Activity::Introspect::Graph(operation)
19
19
 
20
20
  rows = graph.collect do |node, i|
@@ -27,7 +27,7 @@ module Trailblazer
27
27
 
28
28
  rows = rows[1..-1] # remove start
29
29
 
30
- return inspect_line(rows) if options[:style] == :line
30
+ return inspect_line(rows) if style == :line
31
31
 
32
32
  return inspect_rows(rows)
33
33
  end
@@ -1,5 +1,3 @@
1
- require 'hirb'
2
-
3
1
  module Trailblazer
4
2
  module Developer
5
3
  module Trace
@@ -43,9 +43,15 @@ module Trailblazer::Developer
43
43
  #
44
44
  # @private
45
45
  def merge_plan
46
- Activity::TaskWrap::Pipeline::Merge.new(
47
- [Activity::TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.capture_args", Trace.method(:capture_args)]],
48
- [Activity::TaskWrap::Pipeline.method(:append), nil, ["task_wrap.capture_return", Trace.method(:capture_return)]],
46
+ Activity::TaskWrap::Extension.new(
47
+ {
48
+ insert: [Activity::Adds::Insert.method(:Prepend), "task_wrap.call_task"],
49
+ row: Activity::TaskWrap::Pipeline.Row("task_wrap.capture_args", Trace.method(:capture_args))
50
+ },
51
+ {
52
+ insert: [Activity::Adds::Insert.method(:Append)], # append to the very end of tW.
53
+ row: Activity::TaskWrap::Pipeline.Row("task_wrap.capture_return", Trace.method(:capture_return))
54
+ },
49
55
  )
50
56
  end
51
57
 
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Developer
4
- VERSION = "0.0.22"
4
+ VERSION = "0.0.25"
5
5
  end
6
6
  end
7
7
  end
@@ -12,8 +12,6 @@ require "trailblazer/developer/trace"
12
12
  require "trailblazer/developer/trace/present"
13
13
  require "trailblazer/developer/trace/focusable"
14
14
  require "trailblazer/developer/trace/inspector"
15
- require "trailblazer/developer/generate"
16
15
  require "trailblazer/developer/render/circuit"
17
16
  require "trailblazer/developer/render/linear"
18
-
19
- # require "trailblazer/developer/client"
17
+ require "trailblazer/developer/render/task_wrap"
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["apotonick@gmail.com"]
10
10
 
11
11
  spec.summary = "Developer tools for Trailblazer."
12
- spec.description = "Developer tools for Trailblazer: debugger, tracing, visual editor integration."
12
+ spec.description = "Developer tools for Trailblazer: debugger, activity visualizer and tracing."
13
13
  spec.homepage = "http://trailblazer.to"
14
14
  spec.license = "LGPL-3.0"
15
15
 
@@ -23,8 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "minitest-line"
24
24
  spec.add_development_dependency "rake"
25
25
 
26
- spec.add_dependency "trailblazer-activity", ">= 0.12.2", "< 1.0.0"
27
- spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.4.1", "< 1.0.0"
28
- spec.add_dependency "representable", ">= 3.1.1", "< 4.0.0"
26
+ spec.add_dependency "trailblazer-activity-dsl-linear", ">= 1.0.0.beta1", "< 1.1.0"
29
27
  spec.add_dependency "hirb"
30
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-developer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.22
4
+ version: 0.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-08 00:00:00.000000000 Z
11
+ date: 2022-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,66 +66,26 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: trailblazer-activity
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: 0.12.2
76
- - - "<"
77
- - !ruby/object:Gem::Version
78
- version: 1.0.0
79
- type: :runtime
80
- prerelease: false
81
- version_requirements: !ruby/object:Gem::Requirement
82
- requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- version: 0.12.2
86
- - - "<"
87
- - !ruby/object:Gem::Version
88
- version: 1.0.0
89
69
  - !ruby/object:Gem::Dependency
90
70
  name: trailblazer-activity-dsl-linear
91
71
  requirement: !ruby/object:Gem::Requirement
92
72
  requirements:
93
73
  - - ">="
94
74
  - !ruby/object:Gem::Version
95
- version: 0.4.1
96
- - - "<"
97
- - !ruby/object:Gem::Version
98
- version: 1.0.0
99
- type: :runtime
100
- prerelease: false
101
- version_requirements: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: 0.4.1
106
- - - "<"
107
- - !ruby/object:Gem::Version
108
- version: 1.0.0
109
- - !ruby/object:Gem::Dependency
110
- name: representable
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- version: 3.1.1
75
+ version: 1.0.0.beta1
116
76
  - - "<"
117
77
  - !ruby/object:Gem::Version
118
- version: 4.0.0
78
+ version: 1.1.0
119
79
  type: :runtime
120
80
  prerelease: false
121
81
  version_requirements: !ruby/object:Gem::Requirement
122
82
  requirements:
123
83
  - - ">="
124
84
  - !ruby/object:Gem::Version
125
- version: 3.1.1
85
+ version: 1.0.0.beta1
126
86
  - - "<"
127
87
  - !ruby/object:Gem::Version
128
- version: 4.0.0
88
+ version: 1.1.0
129
89
  - !ruby/object:Gem::Dependency
130
90
  name: hirb
131
91
  requirement: !ruby/object:Gem::Requirement
@@ -140,7 +100,7 @@ dependencies:
140
100
  - - ">="
141
101
  - !ruby/object:Gem::Version
142
102
  version: '0'
143
- description: 'Developer tools for Trailblazer: debugger, tracing, visual editor integration.'
103
+ description: 'Developer tools for Trailblazer: debugger, activity visualizer and tracing.'
144
104
  email:
145
105
  - apotonick@gmail.com
146
106
  executables: []
@@ -158,8 +118,6 @@ files:
158
118
  - bin/setup
159
119
  - gems.local.rb
160
120
  - lib/trailblazer/developer.rb
161
- - lib/trailblazer/developer/client.rb
162
- - lib/trailblazer/developer/generate.rb
163
121
  - lib/trailblazer/developer/render/circuit.rb
164
122
  - lib/trailblazer/developer/render/linear.rb
165
123
  - lib/trailblazer/developer/trace.rb
@@ -169,13 +127,12 @@ files:
169
127
  - lib/trailblazer/developer/version.rb
170
128
  - lib/trailblazer/developer/wtf.rb
171
129
  - lib/trailblazer/developer/wtf/renderer.rb
172
- - lib/trailblazer/diagram/bpmn.rb
173
130
  - trailblazer-developer.gemspec
174
131
  homepage: http://trailblazer.to
175
132
  licenses:
176
133
  - LGPL-3.0
177
134
  metadata: {}
178
- post_install_message:
135
+ post_install_message:
179
136
  rdoc_options: []
180
137
  require_paths:
181
138
  - lib
@@ -190,8 +147,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
147
  - !ruby/object:Gem::Version
191
148
  version: '0'
192
149
  requirements: []
193
- rubygems_version: 3.0.8
194
- signing_key:
150
+ rubygems_version: 3.2.3
151
+ signing_key:
195
152
  specification_version: 4
196
153
  summary: Developer tools for Trailblazer.
197
154
  test_files: []
@@ -1,95 +0,0 @@
1
- require "faraday"
2
- require "base64"
3
- require "json"
4
- require "representable/json"
5
-
6
- module Trailblazer::Developer
7
- module Client
8
- Diagram = Struct.new(:id, :body)
9
-
10
- class Diagram::Representer < Representable::Decorator
11
- include Representable::JSON
12
- property :id
13
- property :body, as: :diagram
14
- end
15
-
16
- module_function
17
-
18
- def Diagram(id, body)
19
- Diagram.new(id, body).freeze
20
- end
21
-
22
- def import(id:, query:"", **options)
23
- token = retrieve_token(**options)
24
- export_diagram(id: id, token: token, query: query, **options)
25
- end
26
-
27
- def retrieve_token(email:, api_key:, url: "/signin", **options)
28
- body = JSON.generate({email: email, api_key: api_key})
29
-
30
- response = request(token: nil, method: :get, url: url, body: body, **options)
31
- return false unless response.status == 200
32
-
33
- # token = CGI::Cookie.parse(response.headers["set-cookie"])["token"][0]
34
- JSON.parse(response.body)["token"]
35
- end
36
-
37
- def export_diagram(id:, query:, **options)
38
- response = request(body: nil, url: "/api/v1/diagrams/#{id}/export#{query}", method: :get, **options)
39
-
40
- # parse_response(response)
41
- response.body
42
- end
43
-
44
- def duplicate(id:, **options)
45
- token = retrieve_token(**options)
46
-
47
- response = request(body: nil, token: token, url: "/api/v1/diagrams/#{id}/duplicate", method: :get, **options)
48
- parse_response(response)
49
- end
50
-
51
- # DISCUSS: do we need that?
52
- def new_diagram(token:, **options)
53
- response = request(body: nil, url: "/api/v1/diagrams/new", method: :get, token: token, **options)
54
-
55
- # TODO: use Dry::Struct
56
- # TODO: handle unauthorized/errors
57
- parse_response(response)
58
- end
59
-
60
- def request(host:, url:, method:, token:, body:, **)
61
- conn = Faraday.new(url: host)
62
-
63
- conn.send(method) do |req|
64
- req.url url
65
- req.headers["Content-Type"] = "application/json"
66
- req.body = body
67
- req.headers["Authorization"] = token
68
- end
69
- end
70
-
71
- def parse_response(response)
72
- diagram = Diagram.new
73
- Diagram::Representer.new(diagram).from_json(response.body) # a parsed hash would be cooler?
74
-
75
- diagram
76
- end
77
-
78
- # TODO: remove me!
79
- def self.push(operation:, name:)
80
- xml = Trailblazer::Diagram::BPMN.to_xml(operation["__activity__"], operation["__sequence__"].map(&:id))
81
- token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJpZCI6MywidXNlcm5hbWUiOiJhcG90b25pY2siLCJlbWFpbCI6Im5pY2tAdHJhaWxibGF6ZXIudG8ifQ." # rubocop:disable Metrics/LineLength
82
- conn = Faraday.new(url: "https://api.trb.to")
83
- response = conn.post do |req|
84
- req.url "/dev/v1/import"
85
- req.headers["Content-Type"] = "application/json"
86
- req.headers["Authorization"] = token
87
- require "base64"
88
-
89
- req.body = %({ "name": "#{name}", "xml":"#{Base64.strict_encode64(xml)}" })
90
- end
91
-
92
- puts response.status.inspect
93
- end
94
- end
95
- end
@@ -1,98 +0,0 @@
1
- require "representable/hash"
2
- require "trailblazer/activity/dsl/linear" # Railway.
3
-
4
- module Trailblazer
5
- module Developer
6
- # Computes an {Intermediate} data structure from a TRB-editor.js file.
7
- module Generate
8
- module_function
9
-
10
- Element = Struct.new(:id, :type, :linksTo, :data, :label, :parent)
11
- Arrow = Struct.new(:target, :label, :message, :target_lane)
12
-
13
- module Representer
14
- class Activity < Representable::Decorator
15
- include Representable::Hash
16
-
17
- collection :elements, class: Element do
18
- property :id
19
- property :type
20
- collection :linksTo, class: Arrow, default: ::Declarative::Variables::Append([]) do
21
- property :target
22
- property :label
23
- property :message
24
- property :target_lane
25
- end
26
- property :data, default: {}
27
-
28
- property :label
29
- property :parent # TODO: remove?
30
- end
31
- end
32
- end
33
-
34
- def call(hash)
35
- _, (ctx, _) = Activity::TaskWrap.invoke(Pipeline, [{hash: hash}, {}])
36
- ctx[:intermediate]
37
- end
38
-
39
- def transform_from_hash(ctx, hash:, parser: Representer::Activity, **)
40
- ctx[:elements] = parser.new(OpenStruct.new).from_hash(hash).elements
41
- end
42
-
43
- def find_start_events(ctx, elements:, **)
44
- ctx[:start_events] = elements.find_all { |el| el.type == "Event" }
45
- end
46
-
47
- def compute_intermediate(ctx, elements:, start_events:, **)
48
- end_events = elements.find_all { |el| el.type == "EndEventTerminate" } # DISCUSS: is it really called TERMINATE?
49
-
50
- inter = Activity::Schema::Intermediate
51
-
52
- wiring = elements.collect { |el|
53
- data = data_for(el)
54
-
55
- [inter.TaskRef(el.id, data), el.linksTo.collect { |arrow| inter.Out(semantic_for(**arrow.to_h), arrow.target) } ] }
56
- wiring = Hash[wiring]
57
-
58
- # end events need this stupid special handling
59
- # DISCUSS: currently, the END-SEMANTIC is read from the event's label.
60
- wiring = wiring.merge(Hash[
61
- end_events.collect do |_end|
62
- ref, = wiring.find { |ref, _| ref.id == _end.id }
63
-
64
- [ref, [inter.Out(semantic_for(**_end.to_h)|| raise, nil)]] # TODO: test the raise, happens when the semantic of an End can't be distinguished. # TODO: don't extract semantic from :label but from :data.
65
- end
66
- ])
67
- # pp wiring
68
-
69
- ctx[:intermediate] = inter.new(wiring, end_events.collect(&:id), start_events.collect(&:id))
70
- end
71
-
72
- # private
73
-
74
- def data_for(element)
75
- {type: element.type}.merge(element.data)
76
- end
77
-
78
- # We currently use the {:label} field of an arrow to encode an output semantic.
79
- # The {:symbol_style} part will be filtered out as semantic. Defaults to {:success}.
80
- def semantic_for(label:nil, **)
81
- return :success unless label
82
-
83
- extract_semantic(label)
84
- end
85
-
86
- def extract_semantic(label)
87
- label.to_sym
88
- end
89
-
90
- class Pipeline < Trailblazer::Activity::Railway
91
- step Generate.method(:transform_from_hash), id: :transform_from_hash
92
- step Generate.method(:find_start_events), id: :find_start_events
93
- step Generate.method(:compute_intermediate), id: :compute_intermediate
94
- end
95
- end
96
- end
97
- end
98
- # [Inter::Out(:success, nil)]
@@ -1,338 +0,0 @@
1
- require "representable"
2
- require "representable/xml"
3
-
4
- require "trailblazer/developer/activity"
5
-
6
- module Trailblazer
7
- module Diagram
8
- module BPMN # rubocop:disable Metrics/ModuleLength
9
- Plane = Struct.new(:element, :shapes, :edges)
10
- Shape = Struct.new(:id, :element, :bounds)
11
- Edge = Struct.new(:id, :element, :waypoints)
12
- Bounds = Struct.new(:x, :y, :width, :height)
13
- Waypoint = Struct.new(:x, :y)
14
-
15
- require "tsort"
16
- # Helps sorting the tasks in a process "topologically", which is basically what the
17
- # Sequence does for us, but this works for any kind of process.
18
- # DISCUSS: should we work on the Model or Graph interface?
19
- def self.topological_sort(model)
20
- edges = {}
21
- model.end_events.each { |task| edges[task.id] = {} }
22
- model.sequence_flow.each do |edge|
23
- edges[edge.sourceRef] ||= []
24
- edges[edge.sourceRef] << edge.targetRef
25
- end
26
-
27
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
28
- each_node = ->(&b) { edges.each_key(&b) }
29
- each_child = ->(n, &b) { edges[n].each(&b) }
30
- TSort.tsort(each_node, each_child).reverse #=> [4, 2, 3, 1]
31
- end
32
-
33
- # FIXME: this should be called "linear layouter or something"
34
- # Render an `Activity`'s circuit to a BPMN 2.0 XML `<process>` structure.
35
- # @param activity Activity
36
- # @param linear_task_ids [String] A list of task IDs that should be layouted sequentially in the provided order.
37
- def self.to_xml(activity, linear_task_ids = nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
38
- model = Trailblazer::Developer::Activity::Graph.to_model(activity.graph)
39
-
40
- linear_task_ids ||= topological_sort(model)
41
-
42
- # this layouter doesn't want End events in the linear part, we arrange them manually.
43
- linear_task_ids -= model.end_events.map(&:id)
44
- linear_task_ids -= model.start_events.map(&:id)
45
- linear_tasks = linear_task_ids.collect do |id|
46
- model.task.find { |task| task.id == id } || raise("task #{id} is not in model!")
47
- end
48
-
49
- start_x = 200
50
- y_right = 200
51
- y_left = 300
52
-
53
- event_width = 54
54
-
55
- shape_width = 81
56
- shape_height = 54
57
- shape_to_shape = 45
58
-
59
- current = start_x
60
- shapes = []
61
-
62
- # add start.
63
- shapes << Shape.new(
64
- "Shape_#{model.start_events[0][:id]}",
65
- model.start_events[0][:id],
66
- Bounds.new(current, y_right, event_width, event_width)
67
- )
68
- current += event_width + shape_to_shape
69
-
70
- # add tasks.
71
- linear_tasks.each do |task|
72
- is_right = %i[pass step].include?(task.options[:created_by])
73
-
74
- shapes << Shape.new(
75
- "Shape_#{task[:id]}",
76
- task[:id],
77
- Bounds.new(current, is_right ? y_right : y_left, shape_width, shape_height)
78
- )
79
- current += shape_width + shape_to_shape
80
- end
81
-
82
- # add ends.
83
- horizontal_end_offset = 90
84
-
85
- defaults = {
86
- "End.success" => {y: y_right},
87
- "End.failure" => {y: y_left},
88
- "End.pass_fast" => {y: y_right - 90},
89
- "End.fail_fast" => {y: y_left + 90}
90
- }
91
-
92
- success_end_events = []
93
- failure_end_events = [] # rubocop:disable Lint/UselessAssignment
94
-
95
- model.end_events.each do |evt|
96
- id = evt[:id]
97
- y = defaults[id] ? defaults[id][:y] : success_end_events.last + horizontal_end_offset
98
-
99
- success_end_events << y
100
-
101
- shapes << Shape.new("Shape_#{id}", id, Bounds.new(current, y, event_width, event_width))
102
- end
103
-
104
- edges = []
105
- model.sequence_flow.each do |flow|
106
- source = shapes.find { |shape| shape.id == "Shape_#{flow.sourceRef}" }.bounds
107
- target = shapes.find { |shape| shape.id == "Shape_#{flow.targetRef}" }.bounds
108
-
109
- edges << Edge.new("SequenceFlow_#{flow[:id]}", flow[:id], Path(source, target, target.x != current))
110
- end
111
-
112
- diagram = Struct.new(:plane).new(Plane.new(model.id, shapes, edges))
113
-
114
- # render XML.
115
- Representer::Definitions.new(Definitions.new(model, diagram)).to_xml
116
- end
117
-
118
- def self.Path(source, target, do_straight_line) # rubocop:disable Metrics/AbcSize
119
- if source.y == target.y # --->
120
- [Waypoint.new(*fromRight(source)), Waypoint.new(*toLeft(target))]
121
- elsif do_straight_line
122
- [Waypoint.new(*fromBottom(source)), Waypoint.new(*toLeft(target))]
123
- elsif target.y > source.y # target below source.
124
- [
125
- l = Waypoint.new(*fromBottom(source)),
126
- r = Waypoint.new(l.x, target.y + target.height / 2),
127
- Waypoint.new(target.x, r.y)
128
- ]
129
- else # target above source.
130
- [l = Waypoint.new(*fromTop(source)), r = Waypoint.new(l.x, target.y + target.height / 2), Waypoint.new(target.x, r.y)]
131
- end
132
- end
133
-
134
- def self.fromRight(left)
135
- [left.x + left.width, left.y + left.height / 2]
136
- end
137
-
138
- def self.toLeft(bounds)
139
- [bounds.x, bounds.y + bounds.height / 2]
140
- end
141
-
142
- def self.fromBottom(bounds)
143
- [bounds.x + bounds.width / 2, bounds.y + bounds.height]
144
- end
145
-
146
- def self.fromTop(bounds)
147
- [bounds.x + bounds.width / 2, bounds.y]
148
- end
149
-
150
- Definitions = Struct.new(:process, :diagram)
151
-
152
- # Representers for BPMN XML.
153
- module Representer
154
- class Task < Representable::Decorator
155
- include Representable::XML
156
- include Representable::XML::Namespace
157
- namespace "http://www.omg.org/spec/BPMN/20100524/MODEL"
158
-
159
- self.representation_wrap = :task # overridden via :as.
160
-
161
- property :id, attribute: true
162
- property :name, attribute: true
163
-
164
- collection :outgoing, exec_context: :decorator
165
- collection :incoming, exec_context: :decorator
166
-
167
- def outgoing
168
- represented.outgoing.collect { |edge| edge[:id] }
169
- end
170
-
171
- def incoming
172
- represented.incoming.collect { |edge| edge[:id] }
173
- end
174
- end
175
-
176
- class SequenceFlow < Representable::Decorator
177
- include Representable::XML
178
- include Representable::XML::Namespace
179
- self.representation_wrap = :sequenceFlow
180
- namespace "http://www.omg.org/spec/BPMN/20100524/MODEL"
181
-
182
- property :id, attribute: true
183
- property :sourceRef, attribute: true, exec_context: :decorator
184
- property :targetRef, attribute: true, exec_context: :decorator
185
- property :direction, as: :conditionExpression
186
-
187
- def sourceRef
188
- represented.sourceRef
189
- end
190
-
191
- def targetRef
192
- represented.targetRef
193
- end
194
- end
195
-
196
- class Process < Representable::Decorator
197
- include Representable::XML
198
- include Representable::XML::Namespace
199
- self.representation_wrap = :process
200
-
201
- namespace "http://www.omg.org/spec/BPMN/20100524/MODEL"
202
-
203
- property :id, attribute: true
204
-
205
- collection :start_events, as: :startEvent, decorator: Task
206
- collection :end_events, as: :endEvent, decorator: Task
207
- collection :task, decorator: Task
208
- collection :sequence_flow, decorator: SequenceFlow, as: :sequenceFlow
209
- end
210
-
211
- module Diagram
212
- class Bounds < Representable::Decorator
213
- include Representable::XML
214
- include Representable::XML::Namespace
215
- self.representation_wrap = :Bounds
216
-
217
- namespace "http://www.omg.org/spec/DD/20100524/DC"
218
-
219
- property :x, attribute: true
220
- property :y, attribute: true
221
- property :width, attribute: true
222
- property :height, attribute: true
223
- end
224
-
225
- class Diagram < Representable::Decorator
226
- feature Representable::XML
227
- feature Representable::XML::Namespace
228
- self.representation_wrap = :BPMNDiagram
229
-
230
- namespace "http://www.omg.org/spec/BPMN/20100524/DI"
231
-
232
- property :plane, as: "BPMNPlane" do
233
- self.representation_wrap = :plane
234
-
235
- property :element, as: :bpmnElement, attribute: true
236
-
237
- namespace "http://www.omg.org/spec/BPMN/20100524/DI"
238
-
239
- collection :shapes, as: "BPMNShape" do
240
- self.representation_wrap = :BPMNShape
241
- namespace "http://www.omg.org/spec/BPMN/20100524/DI"
242
-
243
- property :id, attribute: true
244
- property :element, as: :bpmnElement, attribute: true
245
-
246
- property :bounds, as: "Bounds", decorator: Bounds
247
- end
248
-
249
- collection :edges, as: "BPMNEdge" do
250
- self.representation_wrap = :BPMNEdge
251
- namespace "http://www.omg.org/spec/BPMN/20100524/DI"
252
-
253
- property :id, attribute: true
254
- property :element, as: :bpmnElement, attribute: true
255
-
256
- # <di:waypoint xsi:type="dc:Point" x="136" y="118" />
257
- collection :waypoints, as: :waypoint do
258
- namespace "http://www.omg.org/spec/DD/20100524/DI"
259
-
260
- property :type, as: "xsi:type", exec_context: :decorator, attribute: true
261
- property :x, attribute: true
262
- property :y, attribute: true
263
-
264
- def type
265
- "dc:Point"
266
- end
267
- end
268
- end
269
- end
270
-
271
- # namespace "http://www.w3.org/2001/XMLSchema-instance" # xsi
272
- end
273
- end
274
-
275
- class Definitions < Representable::Decorator
276
- include Representable::XML
277
- include Representable::XML::Namespace
278
- self.representation_wrap = :definitions
279
-
280
- namespace "http://www.omg.org/spec/BPMN/20100524/MODEL"
281
- namespace_def bpmn: "http://www.omg.org/spec/BPMN/20100524/MODEL"
282
- namespace_def bpmndi: "http://www.omg.org/spec/BPMN/20100524/DI"
283
- namespace_def di: "http://www.omg.org/spec/DD/20100524/DI"
284
-
285
- namespace_def dc: "http://www.omg.org/spec/DD/20100524/DC" # <cd:Bounds>
286
- namespace_def xsi: "http://www.w3.org/2001/XMLSchema-instance" # used in waypoint.
287
-
288
- property :process, decorator: Process
289
- property :diagram, decorator: Diagram::Diagram, as: :BPMNDiagram
290
- end
291
- end
292
- end
293
- end
294
- end
295
-
296
- # <bpmndi:BPMNDiagram id="BPMNDiagram_1">
297
- # <bpmndi:BPMNPlane id="BPMNPlane_1">
298
- # <bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_2">
299
- # <dc:Bounds x="100" y="100" width="36" height="36" />
300
- # </bpmndi:BPMNShape>
301
- # <bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_3">
302
- # <dc:Bounds x="236" y="78" width="100" height="80" />
303
- # </bpmndi:BPMNShape>
304
- # <bpmndi:BPMNEdge id="_BPMNConnection_Flow_4" bpmnElement="Flow_4">
305
- # <di:waypoint xsi:type="dc:Point" x="136" y="118" />
306
- # <di:waypoint xsi:type="dc:Point" x="236" y="118" />
307
- # </bpmndi:BPMNEdge>
308
- # <bpmndi:BPMNShape id="_BPMNShape_Task_5" bpmnElement="Task_5">
309
- # <dc:Bounds x="436" y="78" width="100" height="80" />
310
- # </bpmndi:BPMNShape>
311
- # <bpmndi:BPMNEdge id="_BPMNConnection_Flow_6" bpmnElement="Flow_6">
312
- # <di:waypoint xsi:type="dc:Point" x="336" y="118" />
313
- # <di:waypoint xsi:type="dc:Point" x="436" y="118" />
314
- # </bpmndi:BPMNEdge>
315
- # <bpmndi:BPMNShape id="_BPMNShape_Task_1" bpmnElement="Task_1">
316
- # <dc:Bounds x="636" y="100" width="36" height="36" />
317
- # </bpmndi:BPMNShape>
318
- # <bpmndi:BPMNShape id="_BPMNShape_Task_8" bpmnElement="Task_8">
319
- # <dc:Bounds x="636" y="266" width="100" height="80" />
320
- # </bpmndi:BPMNShape>
321
- # <bpmndi:BPMNEdge id="_BPMNConnection_Flow_7" bpmnElement="Flow_7">
322
- # <di:waypoint xsi:type="dc:Point" x="536" y="118" />
323
- # <di:waypoint xsi:type="dc:Point" x="636" y="118" />
324
- # </bpmndi:BPMNEdge>
325
- # <bpmndi:BPMNEdge id="_BPMNConnection_Flow_9" bpmnElement="Flow_9">
326
- # <di:waypoint xsi:type="dc:Point" x="536" y="118" />
327
- # <di:waypoint xsi:type="dc:Point" x="586" y="118" />
328
- # <di:waypoint xsi:type="dc:Point" x="586" y="306" />
329
- # <di:waypoint xsi:type="dc:Point" x="636" y="306" />
330
- # </bpmndi:BPMNEdge>
331
- # <bpmndi:BPMNEdge id="_BPMNConnection_Flow_10" bpmnElement="Flow_10">
332
- # <di:waypoint xsi:type="dc:Point" x="686" y="266" />
333
- # <di:waypoint xsi:type="dc:Point" x="686" y="201" />
334
- # <di:waypoint xsi:type="dc:Point" x="654" y="201" />
335
- # <di:waypoint xsi:type="dc:Point" x="654" y="136" />
336
- # </bpmndi:BPMNEdge>
337
- # </bpmndi:BPMNPlane>
338
- # </bpmndi:BPMNDiagram>