trailblazer-developer 0.0.21 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
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>