trailblazer-developer 0.0.21 → 0.0.24

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: f473ed5e4a7acf0ed54a78e9ebee0f43921b1fbdeb71af7901b6f3db0dd797e1
4
- data.tar.gz: 9a305618d631ace6ffbc3cc5cc1512a80a7339b19f47eb609a5408e81e97ed59
3
+ metadata.gz: 23a6eb4a9f753e270064c377f75c08045ffcfffe1ee4643c82b52a59df0e38c6
4
+ data.tar.gz: 48f8e2b81baff35b7545deb747fa50e09dea67ea4eca1c55af5566a04edf917d
5
5
  SHA512:
6
- metadata.gz: 475297ef62977030fa0f392a448868f9fe6dd8c3cf253b202b36610c3a87c946c4ec0a04214e2133ff1410cb2dbe0575e1acd9402c3382726aca2f9c08d38336
7
- data.tar.gz: e7d0ebd5d2f82050d6d0fa7c12347f747cc4d9107ca6ac714f1a42f900f2f85f2bbe05e647b9175b2cc269c4fd2abda576c3e5781494cf8e3cfbc291231b42cf
6
+ metadata.gz: 1ec36ea0cfe3b6bafe10ab4029651dfa13db4557bad3fd121fae6e1d28629551f1d747793ad93f95a20a7eabc918254e929ce53eaac7337eb9a3d5db255961da
7
+ data.tar.gz: 3586db8c45fe02f4ccb99199690916e1ac6f208afe0a9f2a2d12bf5dcccccaae2b20bc65da32ef830bf39661276899fc94e4d5250879c7e02af3a2658be96e7d
@@ -0,0 +1,17 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ fail-fast: false
7
+ matrix:
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]
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: ${{ matrix.ruby }}
16
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
17
+ - run: bundle exec rake
data/CHANGES.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 0.0.24
2
+
3
+ * Use `trailblazer-activity-dsl-linear` >= 1.0.
4
+
5
+ # 0.0.23
6
+
7
+ * Remove `representable` dependency.
8
+ * Moved all editor-specific code to the `pro` gem (`client.rb` and `generate.rb`).
9
+
10
+ # 0.0.22
11
+
12
+ * Upgrade trb-activity, trb-activity-dsl-linear and representable versions.
13
+
1
14
  # 0.0.21
2
15
 
3
16
  * Ruby 3.0 support. :sunset:
data/Gemfile CHANGED
@@ -4,9 +4,7 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  # gem "trailblazer-activity", ">= 0.7.1"
7
- gem "trailblazer-activity", path: "../trailblazer-activity"
8
- gem "trailblazer-context", path: "../trailblazer-context"
9
- gem "trailblazer-activity-dsl-linear", path: "../trailblazer-activity-dsl-linear"
10
-
11
- gem "faraday"
12
- gem "multi_json"
7
+ # gem "trailblazer-activity", path: "../trailblazer-activity"
8
+ # gem "trailblazer-activity-dsl-linear", path: "../trailblazer-activity-dsl-linear"
9
+ gem "trailblazer-activity-dsl-linear", github: "trailblazer/trailblazer-activity-dsl-linear"
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.21"
4
+ VERSION = "0.0.24"
5
5
  end
6
6
  end
7
7
  end
@@ -12,8 +12,5 @@ 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"
@@ -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.11.0", "< 1.0.0"
27
- spec.add_dependency "trailblazer-activity-dsl-linear"
28
- spec.add_dependency "representable"
26
+ spec.add_dependency "trailblazer-activity-dsl-linear", ">= 1.0.0", "< 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.21
4
+ version: 0.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-26 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
@@ -67,53 +67,25 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: trailblazer-activity
70
+ name: trailblazer-activity-dsl-linear
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
- - !ruby/object:Gem::Version
75
- version: 0.11.0
76
- - - "<"
77
74
  - !ruby/object:Gem::Version
78
75
  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.11.0
86
76
  - - "<"
87
77
  - !ruby/object:Gem::Version
88
- version: 1.0.0
89
- - !ruby/object:Gem::Dependency
90
- name: trailblazer-activity-dsl-linear
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '0'
78
+ version: 1.1.0
96
79
  type: :runtime
97
80
  prerelease: false
98
81
  version_requirements: !ruby/object:Gem::Requirement
99
82
  requirements:
100
83
  - - ">="
101
84
  - !ruby/object:Gem::Version
102
- version: '0'
103
- - !ruby/object:Gem::Dependency
104
- name: representable
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- type: :runtime
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
85
+ version: 1.0.0
86
+ - - "<"
115
87
  - !ruby/object:Gem::Version
116
- version: '0'
88
+ version: 1.1.0
117
89
  - !ruby/object:Gem::Dependency
118
90
  name: hirb
119
91
  requirement: !ruby/object:Gem::Requirement
@@ -128,15 +100,15 @@ dependencies:
128
100
  - - ">="
129
101
  - !ruby/object:Gem::Version
130
102
  version: '0'
131
- description: 'Developer tools for Trailblazer: debugger, tracing, visual editor integration.'
103
+ description: 'Developer tools for Trailblazer: debugger, activity visualizer and tracing.'
132
104
  email:
133
105
  - apotonick@gmail.com
134
106
  executables: []
135
107
  extensions: []
136
108
  extra_rdoc_files: []
137
109
  files:
110
+ - ".github/workflows/ci.yml"
138
111
  - ".gitignore"
139
- - ".travis.yml"
140
112
  - CHANGES.md
141
113
  - Gemfile
142
114
  - LICENSE
@@ -146,8 +118,6 @@ files:
146
118
  - bin/setup
147
119
  - gems.local.rb
148
120
  - lib/trailblazer/developer.rb
149
- - lib/trailblazer/developer/client.rb
150
- - lib/trailblazer/developer/generate.rb
151
121
  - lib/trailblazer/developer/render/circuit.rb
152
122
  - lib/trailblazer/developer/render/linear.rb
153
123
  - lib/trailblazer/developer/trace.rb
@@ -157,7 +127,6 @@ files:
157
127
  - lib/trailblazer/developer/version.rb
158
128
  - lib/trailblazer/developer/wtf.rb
159
129
  - lib/trailblazer/developer/wtf/renderer.rb
160
- - lib/trailblazer/diagram/bpmn.rb
161
130
  - trailblazer-developer.gemspec
162
131
  homepage: http://trailblazer.to
163
132
  licenses:
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- before_install: gem install bundler
3
- cache: bundler
4
- rvm:
5
- - 3.0
6
- - 2.7
7
- - 2.6
8
- - 2.5
9
- - 2.4
@@ -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>