lutaml 0.9.41 → 0.9.42
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/converter/xmi_to_uml.rb +440 -0
- data/lib/lutaml/uml/association_generalization.rb +17 -0
- data/lib/lutaml/uml/class.rb +2 -3
- data/lib/lutaml/uml/classifier.rb +4 -2
- data/lib/lutaml/uml/diagram.rb +7 -0
- data/lib/lutaml/uml/general_attribute.rb +22 -0
- data/lib/lutaml/uml/generalization.rb +35 -0
- data/lib/lutaml/uml/top_element_attribute.rb +4 -0
- data/lib/lutaml/uml.rb +3 -0
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +13 -1
- data/lib/lutaml/xmi/parsers/xml.rb +3 -4
- metadata +6 -3
- data/lib/lutaml/converter/xmi_hash_to_uml.rb +0 -196
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85b66d72112efe826e3e86d693b6710915c20df890036b2ce3085054a5227512
|
4
|
+
data.tar.gz: 4f255d33142b96347c7f8efcde22661ae8eff33a7bba7caecbff17f1a7f0362e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4d00853656f53a73d011ace7843d5443a6afd4e3447bdd8f9acfeb1d1a8f1dc6b9e40bfc94f8bdb441dc60ea7495b72d0a48ef203e292923b72c6be028fa4c1
|
7
|
+
data.tar.gz: 9426ded45a58f49d6b3de1b2279ca2bb64327d52dcb2d101314ad734caf70219421ebf00e0c23f59c662e0bbccc436ce47fba04bff666efa6899b0fecdb5f541
|
@@ -0,0 +1,440 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Converter
|
3
|
+
module XmiToUml
|
4
|
+
def create_uml_document(xmi_model)
|
5
|
+
::Lutaml::Uml::Document.new.tap do |doc|
|
6
|
+
doc.name = xmi_model.model.name
|
7
|
+
doc.packages = create_uml_packages(xmi_model.model)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_uml_packages(model)
|
12
|
+
return [] if model.packaged_element.nil?
|
13
|
+
|
14
|
+
packages = model.packaged_element.select do |e|
|
15
|
+
e.type?("uml:Package")
|
16
|
+
end
|
17
|
+
|
18
|
+
packages.map do |package|
|
19
|
+
create_uml_package(package)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_uml_package(package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
24
|
+
pkg = ::Lutaml::Uml::Package.new
|
25
|
+
pkg.xmi_id = package.id
|
26
|
+
pkg.name = get_package_name(package)
|
27
|
+
pkg.definition = doc_node_attribute_value(package.id, "documentation")
|
28
|
+
pkg.stereotype = doc_node_attribute_value(package.id, "stereotype")
|
29
|
+
|
30
|
+
pkg.packages = create_uml_packages(package)
|
31
|
+
pkg.classes = create_uml_classes(package)
|
32
|
+
pkg.enums = create_uml_enums(package)
|
33
|
+
pkg.data_types = create_uml_data_types(package)
|
34
|
+
pkg.diagrams = create_uml_diagrams(package.id)
|
35
|
+
|
36
|
+
pkg
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_uml_classes(package)
|
40
|
+
return [] if package.packaged_element.nil?
|
41
|
+
|
42
|
+
klasses = package.packaged_element.select do |e|
|
43
|
+
e.type?("uml:Class") || e.type?("uml:AssociationClass") ||
|
44
|
+
e.type?("uml:Interface")
|
45
|
+
end
|
46
|
+
|
47
|
+
klasses.map do |klass|
|
48
|
+
create_uml_class(klass)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_uml_class(klass) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
53
|
+
::Lutaml::Uml::Class.new.tap do |k| # rubocop:disable Metrics/BlockLength
|
54
|
+
k.xmi_id = klass.id
|
55
|
+
k.name = klass.name
|
56
|
+
k.type = klass.type.split(":").last
|
57
|
+
k.is_abstract = doc_node_attribute_value(klass.id, "isAbstract")
|
58
|
+
k.definition = doc_node_attribute_value(klass.id, "documentation")
|
59
|
+
k.stereotype = doc_node_attribute_value(klass.id, "stereotype")
|
60
|
+
|
61
|
+
k.attributes = create_uml_class_attributes(klass)
|
62
|
+
k.associations = create_uml_associations(klass.id)
|
63
|
+
k.operations = create_uml_operations(klass)
|
64
|
+
k.constraints = create_uml_constraints(klass.id)
|
65
|
+
k.association_generalization = create_uml_assoc_generalizations(klass)
|
66
|
+
|
67
|
+
if klass.type?("uml:Class")
|
68
|
+
k.generalization = create_uml_generalization(klass)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_uml_enums(package) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
74
|
+
return [] if package.packaged_element.nil?
|
75
|
+
|
76
|
+
enums = package.packaged_element.select do |e|
|
77
|
+
e.type?("uml:Enumeration")
|
78
|
+
end
|
79
|
+
|
80
|
+
enums.map do |enum|
|
81
|
+
::Lutaml::Uml::Enum.new.tap do |en|
|
82
|
+
en.xmi_id = enum.id
|
83
|
+
en.name = enum.name
|
84
|
+
en.values = create_uml_values(enum)
|
85
|
+
en.definition = doc_node_attribute_value(enum.id, "documentation")
|
86
|
+
en.stereotype = doc_node_attribute_value(enum.id, "stereotype")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_uml_data_types(package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
92
|
+
return [] if package.packaged_element.nil?
|
93
|
+
|
94
|
+
data_types = package.packaged_element.select do |e|
|
95
|
+
e.type?("uml:DataType")
|
96
|
+
end
|
97
|
+
|
98
|
+
data_types.map do |dt|
|
99
|
+
::Lutaml::Uml::DataType.new.tap do |data_type|
|
100
|
+
data_type.xmi_id = dt.id
|
101
|
+
data_type.name = dt.name
|
102
|
+
data_type.is_abstract = doc_node_attribute_value(
|
103
|
+
dt.id, "isAbstract"
|
104
|
+
)
|
105
|
+
data_type.definition = doc_node_attribute_value(
|
106
|
+
dt.id, "documentation"
|
107
|
+
)
|
108
|
+
data_type.stereotype = doc_node_attribute_value(
|
109
|
+
dt.id, "stereotype"
|
110
|
+
)
|
111
|
+
|
112
|
+
data_type.attributes = create_uml_class_attributes(dt)
|
113
|
+
data_type.operations = create_uml_operations(dt)
|
114
|
+
data_type.associations = create_uml_associations(dt.id)
|
115
|
+
data_type.constraints = create_uml_constraints(dt.id)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def create_uml_diagrams(node_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
121
|
+
return [] if @xmi_root_model.extension&.diagrams&.diagram.nil?
|
122
|
+
|
123
|
+
diagrams = @xmi_root_model.extension.diagrams.diagram.select do |d|
|
124
|
+
d.model.package == node_id
|
125
|
+
end
|
126
|
+
|
127
|
+
diagrams.map do |diagram|
|
128
|
+
::Lutaml::Uml::Diagram.new.tap do |dia|
|
129
|
+
dia.xmi_id = diagram.id
|
130
|
+
dia.name = diagram&.properties&.name
|
131
|
+
dia.definition = diagram&.properties&.documentation
|
132
|
+
|
133
|
+
package_id = diagram&.model&.package
|
134
|
+
if package_id
|
135
|
+
dia.package_id = package_id
|
136
|
+
dia.package_name = find_packaged_element_by_id(package_id)&.name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_uml_class_attributes(klass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
143
|
+
return [] if klass.owned_attribute.nil?
|
144
|
+
|
145
|
+
owned_attributes = klass.owned_attribute.select do |attr|
|
146
|
+
attr.type?("uml:Property")
|
147
|
+
end
|
148
|
+
|
149
|
+
owned_attributes.map do |oa|
|
150
|
+
create_uml_attribute(oa)
|
151
|
+
end.compact
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_uml_attribute(owned_attr) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
155
|
+
uml_type = owned_attr.uml_type
|
156
|
+
uml_type_idref = uml_type.idref if uml_type
|
157
|
+
|
158
|
+
::Lutaml::Uml::TopElementAttribute.new.tap do |attr|
|
159
|
+
attr.id = owned_attr.id
|
160
|
+
attr.name = owned_attr.name
|
161
|
+
attr.type = lookup_entity_name(uml_type_idref) || uml_type_idref
|
162
|
+
attr.xmi_id = uml_type_idref
|
163
|
+
attr.is_derived = owned_attr.is_derived
|
164
|
+
attr.cardinality = ::Lutaml::Uml::Cardinality.new.tap do |car|
|
165
|
+
car.min = owned_attr.lower_value&.value
|
166
|
+
car.max = owned_attr.upper_value&.value
|
167
|
+
end
|
168
|
+
attr.definition = lookup_attribute_documentation(owned_attr.id)
|
169
|
+
|
170
|
+
if owned_attr.association
|
171
|
+
attr.association = owned_attr.association
|
172
|
+
attr.definition = loopup_assoc_def(owned_attr.association)
|
173
|
+
attr.type_ns = get_ns_by_xmi_id(attr.xmi_id)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def create_uml_cardinality(hash)
|
179
|
+
::Lutaml::Uml::Cardinality.new.tap do |cardinality|
|
180
|
+
cardinality.min = hash[:min]
|
181
|
+
cardinality.max = hash[:max]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def create_uml_attributes(uml_general_obj) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
186
|
+
upper_klass = uml_general_obj.general_upper_klass
|
187
|
+
gen_attrs = uml_general_obj.general_attributes
|
188
|
+
gen_name = uml_general_obj.general_name
|
189
|
+
|
190
|
+
gen_attrs&.each do |i|
|
191
|
+
name_ns = case i.type_ns
|
192
|
+
when "core", "gml"
|
193
|
+
upper_klass
|
194
|
+
else
|
195
|
+
i.type_ns
|
196
|
+
end
|
197
|
+
name_ns = upper_klass if name_ns.nil?
|
198
|
+
|
199
|
+
i.name_ns = name_ns
|
200
|
+
i.gen_name = gen_name
|
201
|
+
i.name = "" if i.name.nil?
|
202
|
+
end
|
203
|
+
|
204
|
+
gen_attrs
|
205
|
+
end
|
206
|
+
|
207
|
+
def create_uml_generalization(klass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
208
|
+
uml_general_obj, next_general_node_id = get_uml_general(klass.id)
|
209
|
+
return uml_general_obj unless next_general_node_id
|
210
|
+
|
211
|
+
if uml_general_obj.general
|
212
|
+
inherited_props = []
|
213
|
+
inherited_assoc_props = []
|
214
|
+
level = 0
|
215
|
+
|
216
|
+
loop_general_item(
|
217
|
+
uml_general_obj.general,
|
218
|
+
level,
|
219
|
+
inherited_props,
|
220
|
+
inherited_assoc_props,
|
221
|
+
)
|
222
|
+
uml_general_obj.inherited_props = inherited_props.reverse
|
223
|
+
uml_general_obj.inherited_assoc_props = inherited_assoc_props.reverse
|
224
|
+
end
|
225
|
+
|
226
|
+
uml_general_obj
|
227
|
+
end
|
228
|
+
|
229
|
+
def get_uml_general(general_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
230
|
+
general_node = get_general_node(general_id)
|
231
|
+
return [] unless general_node
|
232
|
+
|
233
|
+
general_node_attrs = get_uml_general_attributes(general_node)
|
234
|
+
general_upper_klass = find_upper_level_packaged_element(general_id)
|
235
|
+
next_general_node_id = get_next_general_node_id(general_node)
|
236
|
+
|
237
|
+
uml_general = ::Lutaml::Uml::Generalization.new.tap do |gen|
|
238
|
+
gen.general_id = general_id
|
239
|
+
gen.general_name = general_node.name
|
240
|
+
gen.general_attributes = general_node_attrs
|
241
|
+
gen.general_upper_klass = general_upper_klass
|
242
|
+
gen.name = general_node.name
|
243
|
+
gen.type = general_node.type
|
244
|
+
gen.definition = lookup_general_documentation(general_id)
|
245
|
+
gen.stereotype = doc_node_attribute_value(general_id, "stereotype")
|
246
|
+
|
247
|
+
if next_general_node_id
|
248
|
+
gen.general = set_uml_generalization(
|
249
|
+
next_general_node_id,
|
250
|
+
)
|
251
|
+
gen.has_general = true
|
252
|
+
gen.general_id = general_node.id
|
253
|
+
gen.general_name = general_node.name
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
uml_general.attributes = create_uml_attributes(uml_general)
|
258
|
+
uml_general.owned_props = uml_general.attributes.select do |attr|
|
259
|
+
attr.association.nil?
|
260
|
+
end
|
261
|
+
uml_general.assoc_props = uml_general
|
262
|
+
.attributes.select(&:association)
|
263
|
+
|
264
|
+
[uml_general, next_general_node_id]
|
265
|
+
end
|
266
|
+
|
267
|
+
def get_uml_general_attributes(general_node) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
268
|
+
attrs = create_uml_class_attributes(general_node)
|
269
|
+
|
270
|
+
attrs.map do |attr|
|
271
|
+
::Lutaml::Uml::GeneralAttribute.new.tap do |gen_attr|
|
272
|
+
gen_attr.id = attr.id
|
273
|
+
gen_attr.name = attr.name
|
274
|
+
gen_attr.type = attr.type
|
275
|
+
gen_attr.xmi_id = attr.xmi_id
|
276
|
+
gen_attr.is_derived = !!attr.is_derived
|
277
|
+
gen_attr.cardinality = attr.cardinality
|
278
|
+
gen_attr.definition = attr.definition
|
279
|
+
gen_attr.association = attr.association
|
280
|
+
gen_attr.has_association = !!attr.association
|
281
|
+
gen_attr.type_ns = attr.type_ns
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def set_uml_generalization(general_id)
|
287
|
+
uml_general_obj, next_general_node_id = get_uml_general(general_id)
|
288
|
+
|
289
|
+
if next_general_node_id
|
290
|
+
uml_general_obj.general = set_uml_generalization(
|
291
|
+
next_general_node_id,
|
292
|
+
)
|
293
|
+
uml_general_obj.has_general = true
|
294
|
+
end
|
295
|
+
|
296
|
+
uml_general_obj
|
297
|
+
end
|
298
|
+
|
299
|
+
def loop_general_item( # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
|
300
|
+
general_item, level, inherited_props, inherited_assoc_props
|
301
|
+
)
|
302
|
+
gen_upper_klass = general_item.general_upper_klass
|
303
|
+
gen_name = general_item.general_name
|
304
|
+
|
305
|
+
# reverse the order to show super class first
|
306
|
+
general_item.attributes.reverse_each do |attr|
|
307
|
+
attr.upper_klass = gen_upper_klass
|
308
|
+
attr.gen_name = gen_name
|
309
|
+
attr.level = level
|
310
|
+
|
311
|
+
if attr.association
|
312
|
+
inherited_assoc_props << attr
|
313
|
+
else
|
314
|
+
inherited_props << attr
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
if general_item&.has_general && general_item.general
|
319
|
+
level += 1
|
320
|
+
loop_general_item(
|
321
|
+
general_item.general, level, inherited_props, inherited_assoc_props
|
322
|
+
)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def create_uml_assoc_generalizations(klass)
|
327
|
+
return [] if klass.generalization.nil? || klass.generalization.empty?
|
328
|
+
|
329
|
+
klass.generalization.map do |gen|
|
330
|
+
assoc_gen = ::Lutaml::Uml::AssociationGeneralization.new
|
331
|
+
assoc_gen.id = gen.id
|
332
|
+
assoc_gen.type = gen.type
|
333
|
+
assoc_gen.general = gen.general
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def create_uml_associations(xmi_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
338
|
+
matched_element = @xmi_root_model.extension.elements.element
|
339
|
+
.find { |e| e.idref == xmi_id }
|
340
|
+
|
341
|
+
return if !matched_element || !matched_element.links
|
342
|
+
|
343
|
+
links = []
|
344
|
+
matched_element.links.each do |link|
|
345
|
+
links << link.association if link.association.any?
|
346
|
+
end
|
347
|
+
|
348
|
+
links.flatten.compact.map do |assoc| # rubocop:disable Metrics/BlockLength
|
349
|
+
link_member = assoc.start == xmi_id ? "end" : "start"
|
350
|
+
link_owner = link_member == "start" ? "end" : "start"
|
351
|
+
|
352
|
+
member_end, member_end_type, member_end_cardinality,
|
353
|
+
member_end_attribute_name, member_end_xmi_id =
|
354
|
+
serialize_member_type(xmi_id, assoc, link_member)
|
355
|
+
|
356
|
+
owner_end = serialize_owned_type(xmi_id, assoc, link_owner)
|
357
|
+
doc_node = link_member == "start" ? "source" : "target"
|
358
|
+
definition = fetch_definition_node_value(assoc.id, doc_node)
|
359
|
+
|
360
|
+
if member_end &&
|
361
|
+
(
|
362
|
+
(member_end_type != "aggregation") ||
|
363
|
+
(member_end_type == "aggregation" && member_end_attribute_name)
|
364
|
+
)
|
365
|
+
|
366
|
+
::Lutaml::Uml::Association.new.tap do |association|
|
367
|
+
association.xmi_id = assoc.id
|
368
|
+
association.member_end = member_end
|
369
|
+
association.member_end_type = member_end_type
|
370
|
+
association.member_end_cardinality = create_uml_cardinality(
|
371
|
+
member_end_cardinality,
|
372
|
+
)
|
373
|
+
association.member_end_attribute_name = member_end_attribute_name
|
374
|
+
association.member_end_xmi_id = member_end_xmi_id
|
375
|
+
association.owner_end = owner_end
|
376
|
+
association.owner_end_xmi_id = xmi_id
|
377
|
+
association.definition = definition
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end.compact
|
381
|
+
end
|
382
|
+
|
383
|
+
def create_uml_operations(klass) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
384
|
+
return [] if klass.owned_operation.nil?
|
385
|
+
|
386
|
+
klass.owned_operation.map do |operation|
|
387
|
+
uml_type = operation.uml_type.first
|
388
|
+
uml_type_idref = uml_type.idref if uml_type
|
389
|
+
|
390
|
+
if operation.association.nil?
|
391
|
+
::Lutaml::Uml::Operation.new.tap do |op|
|
392
|
+
op.id = operation.id
|
393
|
+
op.xmi_id = uml_type_idref
|
394
|
+
op.name = operation.name
|
395
|
+
op.definition = lookup_attribute_documentation(operation.id)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end.compact
|
399
|
+
end
|
400
|
+
|
401
|
+
def create_uml_constraints(klass_id) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
402
|
+
connector_node = fetch_connector(klass_id)
|
403
|
+
return [] if connector_node.nil?
|
404
|
+
|
405
|
+
# In ea-xmi-2.5.1, constraints are moved to source/target under
|
406
|
+
# connectors
|
407
|
+
constraints = %i[source target].map do |st|
|
408
|
+
connector_node.send(st).constraints.constraint
|
409
|
+
end.flatten
|
410
|
+
|
411
|
+
constraints.map do |constraint|
|
412
|
+
::Lutaml::Uml::Constraint.new.tap do |con|
|
413
|
+
con.name = HTMLEntities.new.decode(constraint.name)
|
414
|
+
con.type = constraint.type
|
415
|
+
con.weight = constraint.weight
|
416
|
+
con.status = constraint.status
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def create_uml_values(enum) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize
|
422
|
+
return [] if enum.owned_literal.nil?
|
423
|
+
|
424
|
+
owned_literals = enum.owned_literal.select do |owned_literal|
|
425
|
+
owned_literal.type?("uml:EnumerationLiteral")
|
426
|
+
end
|
427
|
+
|
428
|
+
owned_literals.map do |owned_literal|
|
429
|
+
uml_type_id = owned_literal&.uml_type&.idref
|
430
|
+
|
431
|
+
::Lutaml::Uml::Value.new.tap do |value|
|
432
|
+
value.name = owned_literal.name
|
433
|
+
value.type = lookup_entity_name(uml_type_id) || uml_type_id
|
434
|
+
value.definition = lookup_attribute_documentation(owned_literal.id)
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Uml
|
5
|
+
class AssociationGeneralization < Lutaml::Model::Serializable
|
6
|
+
attribute :id, :string
|
7
|
+
attribute :type, :string
|
8
|
+
attribute :general, :string
|
9
|
+
|
10
|
+
yaml do
|
11
|
+
map "id", to: :id
|
12
|
+
map "type", to: :type
|
13
|
+
map "general", to: :general
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/lutaml/uml/class.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "lutaml/uml/package"
|
4
3
|
require "lutaml/uml/association"
|
5
4
|
require "lutaml/uml/constraint"
|
6
5
|
require "lutaml/uml/operation"
|
7
6
|
require "lutaml/uml/data_type"
|
7
|
+
require "lutaml/uml/generalization"
|
8
8
|
|
9
9
|
module Lutaml
|
10
10
|
module Uml
|
@@ -13,7 +13,6 @@ module Lutaml
|
|
13
13
|
default: -> { [] }
|
14
14
|
attribute :is_abstract, :boolean, default: false
|
15
15
|
attribute :type, :string
|
16
|
-
attribute :package, Package
|
17
16
|
attribute :attributes, TopElementAttribute, collection: true
|
18
17
|
attribute :modifier, :string
|
19
18
|
attribute :constraints, Constraint, collection: true
|
@@ -22,12 +21,12 @@ module Lutaml
|
|
22
21
|
attribute :methods, :string, collection: true, default: -> { [] }
|
23
22
|
|
24
23
|
attribute :associations, Association, collection: true
|
24
|
+
attribute :generalization, Generalization
|
25
25
|
|
26
26
|
yaml do
|
27
27
|
map "nested_classifier", to: :nested_classifier
|
28
28
|
map "is_abstract", to: :is_abstract
|
29
29
|
map "type", to: :type
|
30
|
-
map "package", to: :package
|
31
30
|
map "attributes", to: :attributes
|
32
31
|
map "modifier", to: :modifier
|
33
32
|
map "constraints", to: :constraints
|
@@ -3,10 +3,12 @@
|
|
3
3
|
module Lutaml
|
4
4
|
module Uml
|
5
5
|
class Classifier < TopElement
|
6
|
-
attribute :
|
6
|
+
attribute :association_generalization,
|
7
|
+
::Lutaml::Uml::AssociationGeneralization,
|
8
|
+
collection: true, default: -> { [] }
|
7
9
|
|
8
10
|
yaml do
|
9
|
-
map "generalization", to: :
|
11
|
+
map "generalization", to: :association_generalization
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/lutaml/uml/diagram.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Uml
|
5
|
+
class GeneralAttribute < Lutaml::Model::Serializable
|
6
|
+
attribute :id, :string
|
7
|
+
attribute :name, :string
|
8
|
+
attribute :type, :string
|
9
|
+
attribute :xmi_id, :string
|
10
|
+
attribute :is_derived, :boolean, default: false
|
11
|
+
attribute :cardinality, Cardinality
|
12
|
+
attribute :definition, :string
|
13
|
+
attribute :association, :string
|
14
|
+
attribute :has_association, :boolean, default: false
|
15
|
+
attribute :type_ns, :string
|
16
|
+
attribute :name_ns, :string
|
17
|
+
attribute :gen_name, :string
|
18
|
+
attribute :upper_klass, :string
|
19
|
+
attribute :level, :integer
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Uml
|
5
|
+
class Generalization < Lutaml::Model::Serializable
|
6
|
+
attribute :general_id, :string
|
7
|
+
attribute :general_name, :string
|
8
|
+
attribute :general_attributes,
|
9
|
+
::Lutaml::Uml::GeneralAttribute,
|
10
|
+
collection: true, default: -> { [] }
|
11
|
+
attribute :general_upper_klass, :string
|
12
|
+
attribute :has_general, :boolean, default: false
|
13
|
+
attribute :general, ::Lutaml::Uml::Generalization
|
14
|
+
attribute :name, :string
|
15
|
+
attribute :type, :string
|
16
|
+
attribute :definition, :string
|
17
|
+
attribute :stereotype, :string
|
18
|
+
attribute :attributes,
|
19
|
+
::Lutaml::Uml::GeneralAttribute,
|
20
|
+
collection: true, default: -> { [] }
|
21
|
+
attribute :owned_props,
|
22
|
+
::Lutaml::Uml::GeneralAttribute,
|
23
|
+
collection: true, default: -> { [] }
|
24
|
+
attribute :assoc_props,
|
25
|
+
::Lutaml::Uml::GeneralAttribute,
|
26
|
+
collection: true, default: -> { [] }
|
27
|
+
attribute :inherited_props,
|
28
|
+
::Lutaml::Uml::GeneralAttribute,
|
29
|
+
collection: true, default: -> { [] }
|
30
|
+
attribute :inherited_assoc_props,
|
31
|
+
::Lutaml::Uml::GeneralAttribute,
|
32
|
+
collection: true, default: -> { [] }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -15,6 +15,8 @@ module Lutaml
|
|
15
15
|
attribute :is_derived, :boolean, default: false
|
16
16
|
|
17
17
|
attribute :definition, :string
|
18
|
+
attribute :association, :string
|
19
|
+
attribute :type_ns, :string
|
18
20
|
|
19
21
|
yaml do
|
20
22
|
map "name", to: :name
|
@@ -31,6 +33,8 @@ module Lutaml
|
|
31
33
|
map "definition", to: :definition, with: {
|
32
34
|
to: :definition_to_yaml, from: :definition_from_yaml
|
33
35
|
}
|
36
|
+
map "association", to: :association
|
37
|
+
map "type_ns", to: :type_ns
|
34
38
|
end
|
35
39
|
|
36
40
|
def definition_to_yaml(model, doc)
|
data/lib/lutaml/uml.rb
CHANGED
@@ -10,6 +10,9 @@ require "lutaml/uml/fidelity"
|
|
10
10
|
require "lutaml/uml/top_element"
|
11
11
|
require "lutaml/uml/top_element_attribute"
|
12
12
|
require "lutaml/uml/value"
|
13
|
+
require "lutaml/uml/association_generalization"
|
14
|
+
require "lutaml/uml/general_attribute"
|
15
|
+
require "lutaml/uml/generalization"
|
13
16
|
require "lutaml/uml/action"
|
14
17
|
require "lutaml/uml/classifier"
|
15
18
|
require "lutaml/uml/dependency"
|
data/lib/lutaml/version.rb
CHANGED
@@ -151,7 +151,7 @@ module Lutaml
|
|
151
151
|
# @param with_gen: [Boolean]
|
152
152
|
# @param with_absolute_path: [Boolean]
|
153
153
|
# @return [Hash]
|
154
|
-
def build_klass_hash(klass, model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
154
|
+
def build_klass_hash(klass, model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
|
155
155
|
with_gen: false, with_absolute_path: false, absolute_path: "")
|
156
156
|
klass_hash = {
|
157
157
|
xmi_id: klass.id,
|
@@ -173,6 +173,18 @@ module Lutaml
|
|
173
173
|
klass_hash[:generalization] = serialize_generalization(klass)
|
174
174
|
end
|
175
175
|
|
176
|
+
if klass.generalization && !klass.generalization.empty?
|
177
|
+
klass_hash[:association_generalization] = []
|
178
|
+
klass.generalization.each do |gen|
|
179
|
+
association_generalization_hash = {}
|
180
|
+
association_generalization_hash[:id] = gen.id
|
181
|
+
association_generalization_hash[:type] = gen.type
|
182
|
+
association_generalization_hash[:general] = gen.general
|
183
|
+
klass_hash[:association_generalization] <<
|
184
|
+
association_generalization_hash
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
176
188
|
klass_hash
|
177
189
|
end
|
178
190
|
|
@@ -4,14 +4,14 @@ require "lutaml/xmi"
|
|
4
4
|
require "xmi"
|
5
5
|
require "lutaml/xmi/parsers/xmi_base"
|
6
6
|
require "lutaml/uml"
|
7
|
-
require "lutaml/converter/
|
7
|
+
require "lutaml/converter/xmi_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::
|
14
|
+
include Lutaml::Converter::XmiToUml
|
15
15
|
|
16
16
|
@id_name_mapping_static = {}
|
17
17
|
@xmi_root_model_cache_static = {}
|
@@ -99,8 +99,7 @@ module Lutaml
|
|
99
99
|
# @return [Lutaml::Uml::Document]
|
100
100
|
def parse(xmi_model)
|
101
101
|
set_xmi_model(xmi_model)
|
102
|
-
|
103
|
-
create_uml_document(serialized_hash)
|
102
|
+
create_uml_document(xmi_model)
|
104
103
|
end
|
105
104
|
|
106
105
|
# @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.42
|
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-
|
11
|
+
date: 2025-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expressir
|
@@ -217,7 +217,7 @@ files:
|
|
217
217
|
- lib/lutaml.rb
|
218
218
|
- lib/lutaml/command_line.rb
|
219
219
|
- lib/lutaml/converter/dsl_to_uml.rb
|
220
|
-
- lib/lutaml/converter/
|
220
|
+
- lib/lutaml/converter/xmi_to_uml.rb
|
221
221
|
- lib/lutaml/express.rb
|
222
222
|
- lib/lutaml/express/parsers/exp.rb
|
223
223
|
- lib/lutaml/formatter.rb
|
@@ -249,6 +249,7 @@ files:
|
|
249
249
|
- lib/lutaml/uml/activity.rb
|
250
250
|
- lib/lutaml/uml/actor.rb
|
251
251
|
- lib/lutaml/uml/association.rb
|
252
|
+
- lib/lutaml/uml/association_generalization.rb
|
252
253
|
- lib/lutaml/uml/behavior.rb
|
253
254
|
- lib/lutaml/uml/cardinality.rb
|
254
255
|
- lib/lutaml/uml/class.rb
|
@@ -264,6 +265,8 @@ files:
|
|
264
265
|
- lib/lutaml/uml/event.rb
|
265
266
|
- lib/lutaml/uml/fidelity.rb
|
266
267
|
- lib/lutaml/uml/final_state.rb
|
268
|
+
- lib/lutaml/uml/general_attribute.rb
|
269
|
+
- lib/lutaml/uml/generalization.rb
|
267
270
|
- lib/lutaml/uml/group.rb
|
268
271
|
- lib/lutaml/uml/has_attributes.rb
|
269
272
|
- lib/lutaml/uml/has_members.rb
|
@@ -1,196 +0,0 @@
|
|
1
|
-
module Lutaml
|
2
|
-
module Converter
|
3
|
-
module XmiHashToUml
|
4
|
-
def create_uml_document(hash)
|
5
|
-
::Lutaml::Uml::Document.new.tap do |doc|
|
6
|
-
doc.name = hash[:name]
|
7
|
-
hash[:packages]&.each do |package_hash|
|
8
|
-
pkg = create_uml_package(package_hash)
|
9
|
-
doc.packages = [] if doc.packages.nil?
|
10
|
-
doc.packages << pkg
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def create_uml_package(hash) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
16
|
-
package = ::Lutaml::Uml::Package.new
|
17
|
-
package.xmi_id = hash[:xmi_id]
|
18
|
-
package.name = hash[:name]
|
19
|
-
package.definition = hash[:definition]
|
20
|
-
package.stereotype = hash[:stereotype]
|
21
|
-
|
22
|
-
hash[:classes]&.each do |class_hash|
|
23
|
-
class_obj = create_uml_class(class_hash)
|
24
|
-
package.classes = [] if package.classes.nil?
|
25
|
-
package.classes << class_obj
|
26
|
-
end
|
27
|
-
hash[:enums]&.each do |enum_hash|
|
28
|
-
enum_obj = create_uml_enum(enum_hash)
|
29
|
-
package.enums = [] if package.enums.nil?
|
30
|
-
package.enums << enum_obj
|
31
|
-
end
|
32
|
-
hash[:data_types]&.each do |data_type_hash|
|
33
|
-
data_type_obj = create_uml_data_type(data_type_hash)
|
34
|
-
package.data_types = [] if package.data_types.nil?
|
35
|
-
package.data_types << data_type_obj
|
36
|
-
end
|
37
|
-
hash[:diagrams]&.each do |diagram_hash|
|
38
|
-
diagram_obj = create_uml_diagram(diagram_hash)
|
39
|
-
package.diagrams = [] if package.diagrams.nil?
|
40
|
-
package.diagrams << diagram_obj
|
41
|
-
end
|
42
|
-
hash[:packages]&.each do |package_hash|
|
43
|
-
pkg = create_uml_package(package_hash)
|
44
|
-
package.packages = [] if package.packages.nil?
|
45
|
-
package.packages << pkg
|
46
|
-
end
|
47
|
-
|
48
|
-
package
|
49
|
-
end
|
50
|
-
|
51
|
-
def create_uml_class(hash) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
52
|
-
::Lutaml::Uml::Class.new.tap do |klass| # rubocop:disable Metrics/BlockLength
|
53
|
-
klass.xmi_id = hash[:xmi_id]
|
54
|
-
klass.name = hash[:name]
|
55
|
-
klass.type = hash[:type]
|
56
|
-
klass.is_abstract = hash[:is_abstract]
|
57
|
-
klass.definition = hash[:definition]
|
58
|
-
klass.stereotype = hash[:stereotype]
|
59
|
-
hash[:attributes]&.each do |attr_hash|
|
60
|
-
attr = create_uml_attribute(attr_hash)
|
61
|
-
klass.attributes = [] if klass.attributes.nil?
|
62
|
-
klass.attributes << attr
|
63
|
-
end
|
64
|
-
hash[:associations]&.each do |assoc_hash|
|
65
|
-
assoc = create_uml_association(assoc_hash)
|
66
|
-
klass.associations = [] if klass.associations.nil?
|
67
|
-
klass.associations << assoc
|
68
|
-
end
|
69
|
-
hash[:operations]&.each do |op_hash|
|
70
|
-
op = create_uml_operation(op_hash)
|
71
|
-
klass.operations = [] if klass.operations.nil?
|
72
|
-
klass.operations << op
|
73
|
-
end
|
74
|
-
hash[:constraints]&.each do |constraint_hash|
|
75
|
-
constraint = create_uml_constraint(constraint_hash)
|
76
|
-
klass.constraints = [] if klass.constraints
|
77
|
-
klass.constraints << constraint
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def create_uml_enum(hash) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
83
|
-
::Lutaml::Uml::Enum.new.tap do |enum|
|
84
|
-
enum.xmi_id = hash[:xmi_id]
|
85
|
-
enum.name = hash[:name]
|
86
|
-
hash[:values]&.each do |value_hash|
|
87
|
-
value = create_uml_value(value_hash)
|
88
|
-
enum.values = [] if enum.values.nil?
|
89
|
-
enum.values << value
|
90
|
-
end
|
91
|
-
enum.definition = hash[:definition]
|
92
|
-
enum.stereotype = hash[:stereotype]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def create_uml_data_type(hash) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
97
|
-
::Lutaml::Uml::DataType.new.tap do |data_type|
|
98
|
-
data_type.xmi_id = hash[:xmi_id]
|
99
|
-
data_type.name = hash[:name]
|
100
|
-
data_type.is_abstract = hash[:is_abstract]
|
101
|
-
data_type.definition = hash[:definition]
|
102
|
-
data_type.stereotype = hash[:stereotype]
|
103
|
-
hash[:attributes]&.each do |attr_hash|
|
104
|
-
attr = create_uml_attribute(attr_hash)
|
105
|
-
data_type.attributes = [] if data_type.attributes.nil?
|
106
|
-
data_type.attributes << attr
|
107
|
-
end
|
108
|
-
hash[:operations]&.each do |op_hash|
|
109
|
-
op = create_uml_operation(op_hash)
|
110
|
-
data_type.operations = [] if data_type.operations.nil?
|
111
|
-
data_type.operations << op
|
112
|
-
end
|
113
|
-
hash[:associations]&.each do |assoc_hash|
|
114
|
-
assoc = create_uml_association(assoc_hash)
|
115
|
-
data_type.associations = [] if data_type.associations.nil?
|
116
|
-
data_type.associations << assoc
|
117
|
-
end
|
118
|
-
hash[:constraints]&.each do |constraint_hash|
|
119
|
-
constraint = create_uml_constraint(constraint_hash)
|
120
|
-
data_type.constraints = [] if data_type.constraints
|
121
|
-
data_type.constraints << constraint
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def create_uml_diagram(hash)
|
127
|
-
::Lutaml::Uml::Diagram.new.tap do |diagram|
|
128
|
-
diagram.xmi_id = hash[:xmi_id]
|
129
|
-
diagram.name = hash[:name]
|
130
|
-
diagram.definition = hash[:definition]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def create_uml_attribute(hash) # rubocop:disable Metrics/AbcSize
|
135
|
-
::Lutaml::Uml::TopElementAttribute.new.tap do |attr|
|
136
|
-
attr.id = hash[:id]
|
137
|
-
attr.name = hash[:name]
|
138
|
-
attr.type = hash[:type]
|
139
|
-
attr.xmi_id = hash[:xmi_id]
|
140
|
-
attr.is_derived = hash[:is_derived]
|
141
|
-
attr.cardinality = create_uml_cardinality(hash[:cardinality])
|
142
|
-
attr.definition = hash[:definition]
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def create_uml_cardinality(hash)
|
147
|
-
::Lutaml::Uml::Cardinality.new.tap do |cardinality|
|
148
|
-
cardinality.min = hash[:min]
|
149
|
-
cardinality.max = hash[:max]
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def create_uml_association(hash) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
154
|
-
::Lutaml::Uml::Association.new.tap do |assoc|
|
155
|
-
assoc.xmi_id = hash[:xmi_id]
|
156
|
-
assoc.member_end = hash[:member_end]
|
157
|
-
assoc.member_end_type = hash[:member_end_type]
|
158
|
-
assoc.member_end_cardinality = create_uml_cardinality(
|
159
|
-
hash[:member_end_cardinality],
|
160
|
-
)
|
161
|
-
assoc.member_end_attribute_name = hash[:member_end_attribute_name]
|
162
|
-
assoc.member_end_xmi_id = hash[:member_end_xmi_id]
|
163
|
-
assoc.owner_end = hash[:owner_end]
|
164
|
-
assoc.owner_end_xmi_id = hash[:owner_end_xmi_id]
|
165
|
-
assoc.definition = hash[:definition]
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def create_uml_operation(hash)
|
170
|
-
::Lutaml::Uml::Operation.new.tap do |op|
|
171
|
-
op.id = hash[:id]
|
172
|
-
op.xmi_id = hash[:xmi_id]
|
173
|
-
op.name = hash[:name]
|
174
|
-
op.definition = hash[:definition]
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def create_uml_constraint(hash)
|
179
|
-
::Lutaml::Uml::Constraint.new.tap do |constraint|
|
180
|
-
constraint.name = hash[:name]
|
181
|
-
constraint.type = hash[:type]
|
182
|
-
constraint.weight = hash[:weight]
|
183
|
-
constraint.status = hash[:status]
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def create_uml_value(hash)
|
188
|
-
::Lutaml::Uml::Value.new.tap do |value|
|
189
|
-
value.name = hash[:name]
|
190
|
-
value.type = hash[:type]
|
191
|
-
value.definition = hash[:definition]
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|