lutaml 0.9.39 → 0.9.40
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 +4 -4
- data/lib/lutaml/command_line.rb +1 -1
- data/lib/lutaml/converter/dsl_to_uml.rb +235 -0
- data/lib/lutaml/converter/xmi_hash_to_uml.rb +196 -0
- data/lib/lutaml/formatter/base.rb +7 -7
- data/lib/lutaml/formatter/graphviz.rb +19 -8
- data/lib/lutaml/formatter.rb +0 -2
- data/lib/lutaml/parser.rb +1 -1
- data/lib/lutaml/uml/action.rb +15 -0
- data/lib/lutaml/uml/actor.rb +0 -8
- data/lib/lutaml/uml/association.rb +25 -34
- data/lib/lutaml/uml/cardinality.rb +10 -0
- data/lib/lutaml/uml/class.rb +43 -68
- data/lib/lutaml/uml/classifier.rb +5 -3
- data/lib/lutaml/uml/connector.rb +5 -8
- data/lib/lutaml/uml/connector_end.rb +20 -0
- data/lib/lutaml/uml/constraint.rb +11 -1
- data/lib/lutaml/uml/data_type.rb +48 -64
- data/lib/lutaml/uml/dependency.rb +5 -8
- data/lib/lutaml/uml/document.rb +46 -73
- data/lib/lutaml/uml/enum.rb +12 -35
- data/lib/lutaml/uml/event.rb +0 -1
- data/lib/lutaml/uml/fidelity.rb +10 -0
- data/lib/lutaml/uml/group.rb +17 -0
- data/lib/lutaml/uml/instance.rb +5 -7
- data/lib/lutaml/uml/model.rb +3 -3
- data/lib/lutaml/uml/namespace.rb +10 -0
- data/lib/lutaml/uml/node/base.rb +1 -1
- data/lib/lutaml/uml/operation.rb +6 -22
- data/lib/lutaml/uml/package.rb +23 -44
- data/lib/lutaml/uml/parsers/dsl.rb +5 -2
- data/lib/lutaml/uml/parsers/yaml.rb +2 -28
- data/lib/lutaml/uml/primitive_type.rb +3 -4
- data/lib/lutaml/uml/property.rb +15 -17
- data/lib/lutaml/uml/region.rb +0 -1
- data/lib/lutaml/uml/state.rb +9 -1
- data/lib/lutaml/uml/state_machine.rb +0 -1
- data/lib/lutaml/uml/top_element.rb +61 -39
- data/lib/lutaml/uml/top_element_attribute.rb +33 -22
- data/lib/lutaml/uml/transition.rb +11 -1
- data/lib/lutaml/uml/trigger.rb +5 -1
- data/lib/lutaml/uml/value.rb +18 -14
- data/lib/lutaml/uml.rb +40 -2
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +1 -1
- data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +2 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +20 -2
- data/lib/lutaml/xmi/parsers/xml.rb +5 -4
- metadata +11 -13
- data/lib/lutaml/uml/constructor_end.rb +0 -16
- data/lib/lutaml/uml/formatter/base.rb +0 -67
- data/lib/lutaml/uml/formatter/graphviz.rb +0 -332
- data/lib/lutaml/uml/formatter.rb +0 -21
- data/lib/lutaml/uml/serializers/association.rb +0 -58
- data/lib/lutaml/uml/serializers/base.rb +0 -16
- data/lib/lutaml/uml/serializers/class.rb +0 -29
- data/lib/lutaml/uml/serializers/top_element_attribute.rb +0 -14
- data/lib/lutaml/uml/serializers/yaml_view.rb +0 -18
- data/lib/lutaml/uml/version.rb +0 -7
- /data/{lib/lutaml/uml/README.adoc → docs/UML_README.adoc} +0 -0
@@ -1,16 +1,18 @@
|
|
1
1
|
require "nokogiri"
|
2
2
|
require "htmlentities"
|
3
|
-
require "lutaml/uml/has_attributes"
|
4
|
-
require "lutaml/uml/document"
|
5
3
|
require "lutaml/xmi"
|
6
4
|
require "xmi"
|
7
5
|
require "lutaml/xmi/parsers/xmi_base"
|
6
|
+
require "lutaml/uml"
|
7
|
+
require "lutaml/converter/xmi_hash_to_uml"
|
8
8
|
|
9
9
|
module Lutaml
|
10
10
|
module XMI
|
11
11
|
module Parsers
|
12
12
|
# Class for parsing .xmi schema files into ::Lutaml::Uml::Document
|
13
13
|
class XML
|
14
|
+
include Lutaml::Converter::XmiHashToUml
|
15
|
+
|
14
16
|
@id_name_mapping_static = {}
|
15
17
|
@xmi_root_model_cache_static = {}
|
16
18
|
|
@@ -98,8 +100,7 @@ module Lutaml
|
|
98
100
|
def parse(xmi_model)
|
99
101
|
set_xmi_model(xmi_model)
|
100
102
|
serialized_hash = serialize_xmi(xmi_model)
|
101
|
-
|
102
|
-
::Lutaml::Uml::Document.new(serialized_hash)
|
103
|
+
create_uml_document(serialized_hash)
|
103
104
|
end
|
104
105
|
|
105
106
|
# @param xmi_model [Lutaml::Model::Serializable]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.40
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expressir
|
@@ -206,12 +206,15 @@ files:
|
|
206
206
|
- bin/plantuml2lutaml
|
207
207
|
- bin/setup
|
208
208
|
- bin/yaml2lutaml
|
209
|
+
- docs/UML_README.adoc
|
209
210
|
- exe/lutaml
|
210
211
|
- exe/lutaml-sysml
|
211
212
|
- exe/lutaml-wsd2uml
|
212
213
|
- exe/lutaml-yaml2uml
|
213
214
|
- lib/lutaml.rb
|
214
215
|
- lib/lutaml/command_line.rb
|
216
|
+
- lib/lutaml/converter/dsl_to_uml.rb
|
217
|
+
- lib/lutaml/converter/xmi_hash_to_uml.rb
|
215
218
|
- lib/lutaml/express.rb
|
216
219
|
- lib/lutaml/express/README.adoc
|
217
220
|
- lib/lutaml/express/parsers/exp.rb
|
@@ -242,31 +245,32 @@ files:
|
|
242
245
|
- lib/lutaml/sysml/version.rb
|
243
246
|
- lib/lutaml/sysml/xmi_file.rb
|
244
247
|
- lib/lutaml/uml.rb
|
245
|
-
- lib/lutaml/uml/README.adoc
|
246
248
|
- lib/lutaml/uml/abstraction.rb
|
249
|
+
- lib/lutaml/uml/action.rb
|
247
250
|
- lib/lutaml/uml/activity.rb
|
248
251
|
- lib/lutaml/uml/actor.rb
|
249
252
|
- lib/lutaml/uml/association.rb
|
250
253
|
- lib/lutaml/uml/behavior.rb
|
254
|
+
- lib/lutaml/uml/cardinality.rb
|
251
255
|
- lib/lutaml/uml/class.rb
|
252
256
|
- lib/lutaml/uml/classifier.rb
|
253
257
|
- lib/lutaml/uml/connector.rb
|
258
|
+
- lib/lutaml/uml/connector_end.rb
|
254
259
|
- lib/lutaml/uml/constraint.rb
|
255
|
-
- lib/lutaml/uml/constructor_end.rb
|
256
260
|
- lib/lutaml/uml/data_type.rb
|
257
261
|
- lib/lutaml/uml/dependency.rb
|
258
262
|
- lib/lutaml/uml/diagram.rb
|
259
263
|
- lib/lutaml/uml/document.rb
|
260
264
|
- lib/lutaml/uml/enum.rb
|
261
265
|
- lib/lutaml/uml/event.rb
|
266
|
+
- lib/lutaml/uml/fidelity.rb
|
262
267
|
- lib/lutaml/uml/final_state.rb
|
263
|
-
- lib/lutaml/uml/
|
264
|
-
- lib/lutaml/uml/formatter/base.rb
|
265
|
-
- lib/lutaml/uml/formatter/graphviz.rb
|
268
|
+
- lib/lutaml/uml/group.rb
|
266
269
|
- lib/lutaml/uml/has_attributes.rb
|
267
270
|
- lib/lutaml/uml/has_members.rb
|
268
271
|
- lib/lutaml/uml/instance.rb
|
269
272
|
- lib/lutaml/uml/model.rb
|
273
|
+
- lib/lutaml/uml/namespace.rb
|
270
274
|
- lib/lutaml/uml/node/base.rb
|
271
275
|
- lib/lutaml/uml/node/class_node.rb
|
272
276
|
- lib/lutaml/uml/node/class_relationship.rb
|
@@ -291,11 +295,6 @@ files:
|
|
291
295
|
- lib/lutaml/uml/pseudostate.rb
|
292
296
|
- lib/lutaml/uml/realization.rb
|
293
297
|
- lib/lutaml/uml/region.rb
|
294
|
-
- lib/lutaml/uml/serializers/association.rb
|
295
|
-
- lib/lutaml/uml/serializers/base.rb
|
296
|
-
- lib/lutaml/uml/serializers/class.rb
|
297
|
-
- lib/lutaml/uml/serializers/top_element_attribute.rb
|
298
|
-
- lib/lutaml/uml/serializers/yaml_view.rb
|
299
298
|
- lib/lutaml/uml/state.rb
|
300
299
|
- lib/lutaml/uml/state_machine.rb
|
301
300
|
- lib/lutaml/uml/top_element.rb
|
@@ -303,7 +302,6 @@ files:
|
|
303
302
|
- lib/lutaml/uml/transition.rb
|
304
303
|
- lib/lutaml/uml/trigger.rb
|
305
304
|
- lib/lutaml/uml/value.rb
|
306
|
-
- lib/lutaml/uml/version.rb
|
307
305
|
- lib/lutaml/uml/vertex.rb
|
308
306
|
- lib/lutaml/version.rb
|
309
307
|
- lib/lutaml/xmi.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
##
|
4
|
-
## Behaviour metamodel
|
5
|
-
##
|
6
|
-
module Lutaml
|
7
|
-
module Uml
|
8
|
-
class ConnectorEnd < TopElement
|
9
|
-
attr_accessor :role, :part_with_port, :connector
|
10
|
-
|
11
|
-
def initialize # rubocop:disable Lint/MissingSuper
|
12
|
-
@role = nil
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "lutaml/uml/formatter"
|
4
|
-
require "lutaml/uml/has_attributes"
|
5
|
-
|
6
|
-
module Lutaml
|
7
|
-
module Uml
|
8
|
-
module Formatter
|
9
|
-
class Base
|
10
|
-
class << self
|
11
|
-
def inherited(subclass) # rubocop:disable Lint/MissingSuper
|
12
|
-
Formatter.all << subclass
|
13
|
-
end
|
14
|
-
|
15
|
-
def format(node, attributes = {})
|
16
|
-
new(attributes).format(node)
|
17
|
-
end
|
18
|
-
|
19
|
-
def name
|
20
|
-
to_s.split("::").last.downcase.to_sym
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
include HasAttributes
|
25
|
-
|
26
|
-
# rubocop:disable Rails/ActiveRecordAliases
|
27
|
-
def initialize(attributes = {})
|
28
|
-
update_attributes(attributes)
|
29
|
-
end
|
30
|
-
# rubocop:enable Rails/ActiveRecordAliases
|
31
|
-
|
32
|
-
def name
|
33
|
-
self.class.name
|
34
|
-
end
|
35
|
-
|
36
|
-
attr_reader :type
|
37
|
-
|
38
|
-
def type=(value)
|
39
|
-
@type = value.to_s.strip.downcase.to_sym
|
40
|
-
end
|
41
|
-
|
42
|
-
def format(node) # rubocop:disable Metrics/CyclomaticComplexity
|
43
|
-
case node
|
44
|
-
when Node::Field then format_field(node)
|
45
|
-
when Node::Method then format_method(node)
|
46
|
-
when Node::Relationship then format_relationship(node)
|
47
|
-
when Node::ClassRelationship then format_class_relationship(node)
|
48
|
-
when Node::ClassNode then format_class(node)
|
49
|
-
when Lutaml::Uml::Document then format_document(node)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def format_field(_node); raise NotImplementedError; end
|
54
|
-
|
55
|
-
def format_method(_node); raise NotImplementedError; end
|
56
|
-
|
57
|
-
def format_relationship(_node); raise NotImplementedError; end
|
58
|
-
|
59
|
-
def format_class_relationship(_node); raise NotImplementedError; end
|
60
|
-
|
61
|
-
def format_class(_node); raise NotImplementedError; end
|
62
|
-
|
63
|
-
def format_document(_node); raise NotImplementedError; end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,332 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "open3"
|
4
|
-
require "lutaml/uml/formatter/base"
|
5
|
-
require "lutaml/layout/graph_viz_engine"
|
6
|
-
|
7
|
-
module Lutaml
|
8
|
-
module Uml
|
9
|
-
module Formatter
|
10
|
-
class Graphviz < Base
|
11
|
-
class Attributes < Hash
|
12
|
-
def to_s
|
13
|
-
to_a
|
14
|
-
.reject { |(_k, val)| val.nil? }
|
15
|
-
.map { |(a, b)| "#{a}=#{b.inspect}" }
|
16
|
-
.join(" ")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
ACCESS_SYMBOLS = {
|
21
|
-
"public" => "+",
|
22
|
-
"protected" => "#",
|
23
|
-
"private" => "-",
|
24
|
-
}.freeze
|
25
|
-
DEFAULT_CLASS_FONT = "Helvetica"
|
26
|
-
|
27
|
-
VALID_TYPES = %i[
|
28
|
-
dot
|
29
|
-
xdot
|
30
|
-
ps
|
31
|
-
pdf
|
32
|
-
svg
|
33
|
-
svgz
|
34
|
-
fig
|
35
|
-
png
|
36
|
-
gif
|
37
|
-
jpg
|
38
|
-
jpeg
|
39
|
-
json
|
40
|
-
imap
|
41
|
-
cmapx
|
42
|
-
].freeze
|
43
|
-
|
44
|
-
def initialize(attributes = {}) # rubocop:disable Metrics/MethodLength
|
45
|
-
super
|
46
|
-
|
47
|
-
@graph = Attributes.new
|
48
|
-
# Associations lines style, `true` gives curved lines
|
49
|
-
# https://graphviz.org/doc/info/attrs.html#d:splines
|
50
|
-
@graph["splines"] = "ortho"
|
51
|
-
# Padding between outside of picture and nodes
|
52
|
-
@graph["pad"] = 0.5
|
53
|
-
# Padding between levels
|
54
|
-
@graph["ranksep"] = "1.2.equally"
|
55
|
-
# Padding between nodes
|
56
|
-
@graph["nodesep"] = "1.2.equally"
|
57
|
-
# TODO: set rankdir
|
58
|
-
# @graph['rankdir'] = 'BT'
|
59
|
-
|
60
|
-
@edge = Attributes.new
|
61
|
-
@edge["color"] = "gray50"
|
62
|
-
|
63
|
-
@node = Attributes.new
|
64
|
-
@node["shape"] = "box"
|
65
|
-
|
66
|
-
@type = :dot
|
67
|
-
end
|
68
|
-
|
69
|
-
attr_reader :graph, :edge, :node
|
70
|
-
|
71
|
-
def type=(value)
|
72
|
-
super
|
73
|
-
|
74
|
-
@type = :dot unless VALID_TYPES.include?(@type)
|
75
|
-
end
|
76
|
-
|
77
|
-
def format(node)
|
78
|
-
dot = super.lines.map(&:rstrip).join("\n")
|
79
|
-
|
80
|
-
generate_from_dot(dot)
|
81
|
-
end
|
82
|
-
|
83
|
-
def escape_html_chars(text)
|
84
|
-
text
|
85
|
-
.gsub("<", "<")
|
86
|
-
.gsub(">", ">")
|
87
|
-
.gsub("[", "[")
|
88
|
-
.gsub("]", "]")
|
89
|
-
end
|
90
|
-
|
91
|
-
def format_field(node) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
92
|
-
symbol = ACCESS_SYMBOLS[node.visibility]
|
93
|
-
result = "#{symbol}#{node.name}"
|
94
|
-
if node.type
|
95
|
-
keyword = node.keyword ? "«#{node.keyword}»" : ""
|
96
|
-
result += " : #{keyword}#{node.type}"
|
97
|
-
end
|
98
|
-
if node.cardinality
|
99
|
-
result += "[#{node.cardinality[:min]}..#{node.cardinality[:max]}]"
|
100
|
-
end
|
101
|
-
result = escape_html_chars(result)
|
102
|
-
result = "<U>#{result}</U>" if node.static
|
103
|
-
|
104
|
-
result
|
105
|
-
end
|
106
|
-
|
107
|
-
def format_method(node) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
108
|
-
symbol = ACCESS_SYMBOLS[node.access]
|
109
|
-
result = "#{symbol} #{node.name}"
|
110
|
-
if node.arguments
|
111
|
-
arguments = node.arguments.map do |argument|
|
112
|
-
"#{argument.name}#{" : #{argument.type}" if argument.type}"
|
113
|
-
end.join(", ")
|
114
|
-
end
|
115
|
-
|
116
|
-
result << "(#{arguments})"
|
117
|
-
result << " : #{node.type}" if node.type
|
118
|
-
result = "<U>#{result}</U>" if node.static
|
119
|
-
result = "<I>#{result}</I>" if node.abstract
|
120
|
-
|
121
|
-
result
|
122
|
-
end
|
123
|
-
|
124
|
-
def format_relationship(node)
|
125
|
-
graph_parent_name = generate_graph_name(node.owner_end)
|
126
|
-
graph_node_name = generate_graph_name(node.member_end)
|
127
|
-
attributes = generate_graph_relationship_attributes(node)
|
128
|
-
graph_attributes = " [#{attributes}]" unless attributes.empty?
|
129
|
-
|
130
|
-
%{#{graph_parent_name} -> #{graph_node_name}#{graph_attributes}}
|
131
|
-
end
|
132
|
-
|
133
|
-
def generate_graph_relationship_attributes(node) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
134
|
-
attributes = Attributes.new
|
135
|
-
if %w[dependency realizes].include?(node.member_end_type)
|
136
|
-
attributes["style"] = "dashed"
|
137
|
-
end
|
138
|
-
attributes["dir"] = if node.owner_end_type && node.member_end_type
|
139
|
-
"both"
|
140
|
-
elsif node.owner_end_type
|
141
|
-
"back"
|
142
|
-
else
|
143
|
-
"direct"
|
144
|
-
end
|
145
|
-
attributes["label"] = node.action if node.action
|
146
|
-
if node.owner_end_attribute_name
|
147
|
-
attributes["headlabel"] = format_label(
|
148
|
-
node.owner_end_attribute_name,
|
149
|
-
node.owner_end_cardinality,
|
150
|
-
)
|
151
|
-
end
|
152
|
-
if node.member_end_attribute_name
|
153
|
-
attributes["taillabel"] = format_label(
|
154
|
-
node.member_end_attribute_name,
|
155
|
-
node.member_end_cardinality,
|
156
|
-
)
|
157
|
-
end
|
158
|
-
|
159
|
-
attributes["arrowtail"] = case node.owner_end_type
|
160
|
-
when "composition"
|
161
|
-
"diamond"
|
162
|
-
when "aggregation"
|
163
|
-
"odiamond"
|
164
|
-
when "direct"
|
165
|
-
"vee"
|
166
|
-
else
|
167
|
-
"onormal"
|
168
|
-
end
|
169
|
-
|
170
|
-
attributes["arrowhead"] = case node.member_end_type
|
171
|
-
when "composition"
|
172
|
-
"diamond"
|
173
|
-
when "aggregation"
|
174
|
-
"odiamond"
|
175
|
-
when "direct"
|
176
|
-
"vee"
|
177
|
-
else
|
178
|
-
"onormal"
|
179
|
-
end
|
180
|
-
# swap labels and arrows if `dir` eq to `back`
|
181
|
-
if attributes["dir"] == "back"
|
182
|
-
attributes["arrowhead"], attributes["arrowtail"] =
|
183
|
-
[attributes["arrowtail"], attributes["arrowhead"]]
|
184
|
-
attributes["headlabel"], attributes["taillabel"] =
|
185
|
-
[attributes["taillabel"], attributes["headlabel"]]
|
186
|
-
end
|
187
|
-
attributes
|
188
|
-
end
|
189
|
-
|
190
|
-
def format_label(name, cardinality = {})
|
191
|
-
res = "+#{name}"
|
192
|
-
if cardinality.nil? ||
|
193
|
-
(cardinality[:min].nil? || cardinality[:max].nil?)
|
194
|
-
return res
|
195
|
-
end
|
196
|
-
|
197
|
-
"#{res} #{cardinality['min']}..#{cardinality['max']}"
|
198
|
-
end
|
199
|
-
|
200
|
-
def format_member_rows(members, hide_members) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
201
|
-
unless !hide_members && members&.length&.positive?
|
202
|
-
return <<~HEREDOC.chomp
|
203
|
-
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
|
204
|
-
<TR><TD ALIGN="LEFT"></TD></TR>
|
205
|
-
</TABLE>
|
206
|
-
HEREDOC
|
207
|
-
end
|
208
|
-
|
209
|
-
field_rows = members.map do |field|
|
210
|
-
%{<TR><TD ALIGN="LEFT">#{format_field(field)}</TD></TR>}
|
211
|
-
end
|
212
|
-
field_table = <<~HEREDOC.chomp
|
213
|
-
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
|
214
|
-
#{field_rows.map { |row| (' ' * 10) + row }.join("\n")}
|
215
|
-
</TABLE>
|
216
|
-
HEREDOC
|
217
|
-
field_table << "\n" << (" " * 6)
|
218
|
-
field_table
|
219
|
-
end
|
220
|
-
|
221
|
-
def format_class(node, hide_members) # rubocop:disable Metrics/AbcSize
|
222
|
-
name = ["<B>#{node.name}</B>"]
|
223
|
-
name.unshift("«#{node.keyword}»") if node.keyword
|
224
|
-
name_html = <<~HEREDOC
|
225
|
-
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
|
226
|
-
#{name.map { |n| %(<TR><TD ALIGN="CENTER">#{n}</TD></TR>) }.join('\n')}
|
227
|
-
</TABLE>
|
228
|
-
HEREDOC
|
229
|
-
|
230
|
-
field_table = format_member_rows(node.attributes, hide_members)
|
231
|
-
method_table = format_member_rows(node.methods, hide_members)
|
232
|
-
table_body = [name_html, field_table, method_table].map do |type|
|
233
|
-
next if type.nil?
|
234
|
-
|
235
|
-
<<~TEXT
|
236
|
-
<TR>
|
237
|
-
<TD>#{type}</TD>
|
238
|
-
</TR>
|
239
|
-
TEXT
|
240
|
-
end
|
241
|
-
|
242
|
-
<<~HEREDOC.chomp
|
243
|
-
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="10">
|
244
|
-
#{table_body.compact.join("\n")}
|
245
|
-
</TABLE>
|
246
|
-
HEREDOC
|
247
|
-
end
|
248
|
-
|
249
|
-
def format_document(node) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
250
|
-
@fontname = node.fontname || DEFAULT_CLASS_FONT
|
251
|
-
@node["fontname"] = "#{@fontname}-bold"
|
252
|
-
|
253
|
-
if node.fidelity
|
254
|
-
hide_members = node.fidelity["hideMembers"]
|
255
|
-
hide_other_classes = node.fidelity["hideOtherClasses"]
|
256
|
-
end
|
257
|
-
classes = (node.classes +
|
258
|
-
node.enums +
|
259
|
-
node.data_types +
|
260
|
-
node.primitives).map do |class_node|
|
261
|
-
graph_node_name = generate_graph_name(class_node.name)
|
262
|
-
|
263
|
-
<<~HEREDOC
|
264
|
-
#{graph_node_name} [
|
265
|
-
shape="plain"
|
266
|
-
fontname="#{@fontname || DEFAULT_CLASS_FONT}"
|
267
|
-
label=<#{format_class(class_node, hide_members)}>]
|
268
|
-
HEREDOC
|
269
|
-
end.join("\n")
|
270
|
-
associations = node.classes.map(&:associations).compact.flatten +
|
271
|
-
node.associations
|
272
|
-
if node.groups
|
273
|
-
associations = sort_by_document_grouping(node.groups,
|
274
|
-
associations)
|
275
|
-
end
|
276
|
-
classes_names = node.classes.map(&:name)
|
277
|
-
associations = associations.map do |assoc_node|
|
278
|
-
if hide_other_classes &&
|
279
|
-
!classes_names.include?(assoc_node.member_end)
|
280
|
-
next
|
281
|
-
end
|
282
|
-
|
283
|
-
format_relationship(assoc_node)
|
284
|
-
end.join("\n")
|
285
|
-
|
286
|
-
classes = classes.lines.map { |line| " #{line}" }.join.chomp
|
287
|
-
associations = associations
|
288
|
-
.lines.map { |line| " #{line}" }.join.chomp
|
289
|
-
|
290
|
-
<<~HEREDOC
|
291
|
-
digraph G {
|
292
|
-
graph [#{@graph}]
|
293
|
-
edge [#{@edge}]
|
294
|
-
node [#{@node}]
|
295
|
-
|
296
|
-
#{classes}
|
297
|
-
|
298
|
-
#{associations}
|
299
|
-
}
|
300
|
-
HEREDOC
|
301
|
-
end
|
302
|
-
|
303
|
-
protected
|
304
|
-
|
305
|
-
def sort_by_document_grouping(groups, associations) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
306
|
-
result = []
|
307
|
-
groups.each do |batch|
|
308
|
-
batch.each do |group_name|
|
309
|
-
associations
|
310
|
-
.select { |assc| assc.owner_end == group_name }
|
311
|
-
.each do |association|
|
312
|
-
result.push(association) unless result.include?(association)
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
associations.each do |association|
|
317
|
-
result.push(association) unless result.include?(association)
|
318
|
-
end
|
319
|
-
result
|
320
|
-
end
|
321
|
-
|
322
|
-
def generate_from_dot(input)
|
323
|
-
Lutaml::Layout::GraphVizEngine.new(input: input).render(@type)
|
324
|
-
end
|
325
|
-
|
326
|
-
def generate_graph_name(name)
|
327
|
-
name.gsub(/[^0-9a-zA-Z]/i, "")
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|
data/lib/lutaml/uml/formatter.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lutaml
|
4
|
-
module Uml
|
5
|
-
module Formatter
|
6
|
-
class << self
|
7
|
-
def all
|
8
|
-
@all ||= []
|
9
|
-
end
|
10
|
-
|
11
|
-
def find_by_name(name)
|
12
|
-
name = name.to_sym
|
13
|
-
|
14
|
-
all.detect { |formatter_class| formatter_class.name == name }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
require "lutaml/uml/formatter/graphviz"
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "lutaml/uml/serializers/base"
|
4
|
-
require "lutaml/uml/serializers/class"
|
5
|
-
|
6
|
-
module Lutaml
|
7
|
-
module Uml
|
8
|
-
module Serializers
|
9
|
-
class Association < Base
|
10
|
-
property :member_end, from: :target
|
11
|
-
property :member_end_attribute_name,
|
12
|
-
from: "relationship",
|
13
|
-
transform_with: (lambda do |val|
|
14
|
-
val.dig("target", "attributes")&.keys&.first ||
|
15
|
-
val.dig("target", "attribute")&.keys&.first
|
16
|
-
end)
|
17
|
-
property :member_end_cardinality,
|
18
|
-
from: "relationship",
|
19
|
-
transform_with: (lambda do |val|
|
20
|
-
res = val.dig("source", "attributes")&.values&.first ||
|
21
|
-
val.dig("source", "attribute")&.values&.first
|
22
|
-
res["cardinality"] if res
|
23
|
-
end)
|
24
|
-
property :member_end_type,
|
25
|
-
from: "relationship",
|
26
|
-
transform_with: (lambda do |val|
|
27
|
-
val.dig("target", "type")
|
28
|
-
end)
|
29
|
-
property :owner_end_attribute_name,
|
30
|
-
from: "relationship",
|
31
|
-
transform_with: (lambda do |val|
|
32
|
-
val.dig("source", "attributes")&.keys&.first ||
|
33
|
-
val.dig("source", "attribute")&.keys&.first
|
34
|
-
end)
|
35
|
-
property :owner_end_cardinality,
|
36
|
-
from: "relationship",
|
37
|
-
transform_with: (lambda do |val|
|
38
|
-
res = val.dig("source", "attributes")&.values&.first ||
|
39
|
-
val.dig("source", "attribute")&.values&.first
|
40
|
-
res["cardinality"] if res
|
41
|
-
end)
|
42
|
-
property :owner_end_type,
|
43
|
-
from: "relationship",
|
44
|
-
transform_with: (lambda do |val|
|
45
|
-
val.dig("source", "type")
|
46
|
-
end)
|
47
|
-
property :action,
|
48
|
-
transform_with: (lambda do |val|
|
49
|
-
if val["direction"] == "target"
|
50
|
-
"#{val['verb']} ▶"
|
51
|
-
else
|
52
|
-
"◀ #{val['verb']}"
|
53
|
-
end
|
54
|
-
end)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hashie"
|
4
|
-
|
5
|
-
module Lutaml
|
6
|
-
module Uml
|
7
|
-
module Serializers
|
8
|
-
class Base < Hashie::Dash
|
9
|
-
include Hashie::Extensions::Dash::PropertyTranslation
|
10
|
-
include Hashie::Extensions::Dash::IndifferentAccess
|
11
|
-
include Hashie::Extensions::Dash::Coercion
|
12
|
-
include Hashie::Extensions::IgnoreUndeclared
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "lutaml/uml/serializers/base"
|
4
|
-
require "lutaml/uml/serializers/top_element_attribute"
|
5
|
-
require "lutaml/uml/serializers/association"
|
6
|
-
|
7
|
-
module Lutaml
|
8
|
-
module Uml
|
9
|
-
module Serializers
|
10
|
-
class Class < Base
|
11
|
-
property :attributes,
|
12
|
-
transform_with: (lambda do |entry|
|
13
|
-
entry
|
14
|
-
.to_a
|
15
|
-
.map do |(name, attributes)|
|
16
|
-
attributes.merge(name: name)
|
17
|
-
end
|
18
|
-
end)
|
19
|
-
property :associations,
|
20
|
-
from: :relations,
|
21
|
-
coerce: [::Lutaml::Uml::Serializers::Association]
|
22
|
-
property :name
|
23
|
-
# property :type, from: :modelType
|
24
|
-
# property :relations,
|
25
|
-
# coerce: Array[Relation]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|