lutaml 0.9.41 → 0.9.43
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/liquid_drops/enum_drop.rb +2 -1
- data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +3 -3
- data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +14 -3
- data/lib/lutaml/xmi/liquid_drops/package_drop.rb +11 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +54 -97
- 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: 237ccb049aa43625e1ae6358777dbe0eace1ad3cb1ff787ba5b5f055746d8d96
|
4
|
+
data.tar.gz: 9158115470db6f478a7dd6a30e738ec388d4efa09b33531d3ed8093e93a024fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06a354ff8cf4d011b01b32df444c988a814c26cc6811dabccf394f5d05d1911a8c8e2cf9b31092c297ee9d9c1d2e602e8a5d4551dd8477752772b199a23f1d2c
|
7
|
+
data.tar.gz: 6fd0577fc2898d1ae1c2aba4fa6da813bf090799263645f45d6be0016b12e1ec7ad68a7674ebd5668a62ba128c7045d33338a862f3a4ff435099fdb15a090e74
|
@@ -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 = find_packaged_element_by_id(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&.name
|
242
|
+
gen.name = general_node.name
|
243
|
+
gen.type = general_node.type
|
244
|
+
gen.definition = lookup_element_prop_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
@@ -38,16 +38,16 @@ module Lutaml
|
|
38
38
|
!!@gen[:general]
|
39
39
|
end
|
40
40
|
|
41
|
-
def attributes # rubocop:disable Metrics/MethodLength
|
41
|
+
def attributes # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
|
42
42
|
attrs = @gen[:general_attributes]
|
43
43
|
attrs.each do |i|
|
44
44
|
name_ns = case i[:type_ns]
|
45
45
|
when "core", "gml"
|
46
|
-
upper_klass
|
46
|
+
upper_klass&.name
|
47
47
|
else
|
48
48
|
i[:type_ns]
|
49
49
|
end
|
50
|
-
name_ns = upper_klass if name_ns.nil?
|
50
|
+
name_ns = upper_klass&.name if name_ns.nil?
|
51
51
|
|
52
52
|
i[:name_ns] = name_ns
|
53
53
|
i[:name] = "" if i[:name].nil?
|
@@ -51,7 +51,17 @@ module Lutaml
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def absolute_path
|
54
|
-
|
54
|
+
absolute_path_arr = [@model.name]
|
55
|
+
e = find_upper_level_packaged_element(@model.id)
|
56
|
+
absolute_path_arr << e.name if e
|
57
|
+
|
58
|
+
while e
|
59
|
+
e = find_upper_level_packaged_element(e.id)
|
60
|
+
absolute_path_arr << e.name if e
|
61
|
+
end
|
62
|
+
|
63
|
+
absolute_path_arr << "::#{@xmi_root_model.model.name}"
|
64
|
+
absolute_path_arr.reverse.join("::")
|
55
65
|
end
|
56
66
|
|
57
67
|
def package
|
@@ -170,7 +180,7 @@ module Lutaml
|
|
170
180
|
|
171
181
|
def generalization
|
172
182
|
if @options[:with_gen] && @model.type?("uml:Class")
|
173
|
-
generalization = serialize_generalization(@model)
|
183
|
+
generalization = serialize_generalization(@model, @options)
|
174
184
|
return {} if generalization.nil?
|
175
185
|
|
176
186
|
::Lutaml::XMI::GeneralizationDrop.new(
|
@@ -181,7 +191,8 @@ module Lutaml
|
|
181
191
|
|
182
192
|
def upper_packaged_element
|
183
193
|
if @options[:with_gen]
|
184
|
-
find_upper_level_packaged_element(@model.id)
|
194
|
+
e = find_upper_level_packaged_element(@model.id)
|
195
|
+
e&.name
|
185
196
|
end
|
186
197
|
end
|
187
198
|
|
@@ -40,7 +40,17 @@ module Lutaml
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def absolute_path
|
43
|
-
|
43
|
+
absolute_path_arr = [@model.name]
|
44
|
+
e = find_upper_level_packaged_element(@model.id)
|
45
|
+
absolute_path_arr << e.name if e
|
46
|
+
|
47
|
+
while e
|
48
|
+
e = find_upper_level_packaged_element(e.id)
|
49
|
+
absolute_path_arr << e.name if e
|
50
|
+
end
|
51
|
+
|
52
|
+
absolute_path_arr << "::#{@xmi_root_model.model.name}"
|
53
|
+
absolute_path_arr.reverse.join("::")
|
44
54
|
end
|
45
55
|
|
46
56
|
def klasses # rubocop:disable Metrics/MethodLength
|
@@ -135,14 +135,12 @@ module Lutaml
|
|
135
135
|
end
|
136
136
|
|
137
137
|
klasses.map do |klass|
|
138
|
-
|
138
|
+
build_klass_hash(
|
139
139
|
klass, model,
|
140
|
-
with_gen: with_gen
|
140
|
+
with_gen: with_gen,
|
141
|
+
with_absolute_path: with_absolute_path,
|
142
|
+
absolute_path: absolute_path
|
141
143
|
)
|
142
|
-
|
143
|
-
h[:absolute_path] = absolute_path if with_absolute_path
|
144
|
-
|
145
|
-
h
|
146
144
|
end
|
147
145
|
end
|
148
146
|
|
@@ -151,7 +149,7 @@ module Lutaml
|
|
151
149
|
# @param with_gen: [Boolean]
|
152
150
|
# @param with_absolute_path: [Boolean]
|
153
151
|
# @return [Hash]
|
154
|
-
def build_klass_hash(klass, model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
152
|
+
def build_klass_hash(klass, model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
|
155
153
|
with_gen: false, with_absolute_path: false, absolute_path: "")
|
156
154
|
klass_hash = {
|
157
155
|
xmi_id: klass.id,
|
@@ -173,17 +171,30 @@ module Lutaml
|
|
173
171
|
klass_hash[:generalization] = serialize_generalization(klass)
|
174
172
|
end
|
175
173
|
|
174
|
+
if klass.generalization && !klass.generalization.empty?
|
175
|
+
klass_hash[:association_generalization] = []
|
176
|
+
klass.generalization.each do |gen|
|
177
|
+
klass_hash[:association_generalization] << {
|
178
|
+
id: gen.id,
|
179
|
+
type: gen.type,
|
180
|
+
general: gen.general,
|
181
|
+
}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
176
185
|
klass_hash
|
177
186
|
end
|
178
187
|
|
179
188
|
# @param klass [Lutaml::Model::Serializable]
|
180
189
|
# # @return [Hash]
|
181
|
-
def serialize_generalization(klass)
|
182
|
-
general_hash, next_general_node_id = get_top_level_general_hash(
|
190
|
+
def serialize_generalization(klass, options = {})
|
191
|
+
general_hash, next_general_node_id = get_top_level_general_hash(
|
192
|
+
klass, options
|
193
|
+
)
|
183
194
|
return general_hash unless next_general_node_id
|
184
195
|
|
185
196
|
general_hash[:general] = serialize_generalization_attributes(
|
186
|
-
next_general_node_id,
|
197
|
+
next_general_node_id, options
|
187
198
|
)
|
188
199
|
|
189
200
|
general_hash
|
@@ -191,59 +202,38 @@ module Lutaml
|
|
191
202
|
|
192
203
|
# @param klass [Lutaml::Model::Serializable]
|
193
204
|
# @return [Array<Hash>]
|
194
|
-
def get_top_level_general_hash(klass) # rubocop:disable Metrics/AbcSize
|
195
|
-
general_hash, next_general_node_id = get_general_hash(
|
205
|
+
def get_top_level_general_hash(klass, options = {}) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
206
|
+
general_hash, next_general_node_id = get_general_hash(
|
207
|
+
klass.id, options
|
208
|
+
)
|
196
209
|
general_hash[:name] = klass.name
|
197
210
|
general_hash[:type] = klass.type
|
198
|
-
general_hash[:definition] =
|
211
|
+
general_hash[:definition] =
|
212
|
+
lookup_element_prop_documentation(klass.id)
|
199
213
|
general_hash[:stereotype] = doc_node_attribute_value(
|
200
214
|
klass.id, "stereotype"
|
201
215
|
)
|
202
216
|
|
203
|
-
# update_inherited_attributes(general_hash)
|
204
|
-
# update_gen_attributes(general_hash)
|
205
|
-
|
206
217
|
[general_hash, next_general_node_id]
|
207
218
|
end
|
208
219
|
|
209
|
-
def lookup_general_documentation(klass_id)
|
210
|
-
# lookup_attribute_documentation(klass_id) ||
|
211
|
-
# lookup_element_prop_documentation(klass_id)
|
212
|
-
|
213
|
-
lookup_element_prop_documentation(klass_id)
|
214
|
-
end
|
215
|
-
|
216
|
-
def update_gen_attributes(general_hash)
|
217
|
-
general_hash[:gen_attributes] = serialize_gen_attributes
|
218
|
-
end
|
219
|
-
|
220
|
-
def update_inherited_attributes(general_hash)
|
221
|
-
general_hash[:gml_attributes] = serialize_gml_attributes
|
222
|
-
general_hash[:core_attributes] = serialize_core_attributes
|
223
|
-
end
|
224
|
-
|
225
220
|
# @param xmi_id [String]
|
226
221
|
# @param model [Lutaml::Model::Serializable]
|
227
222
|
# @return [Array<Hash>]
|
228
223
|
# @note get generalization node and its owned attributes
|
229
|
-
def serialize_generalization_attributes(general_id)
|
230
|
-
general_hash, next_general_node_id = get_general_hash(general_id
|
224
|
+
def serialize_generalization_attributes(general_id, options = {}) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
225
|
+
general_hash, next_general_node_id = get_general_hash(general_id,
|
226
|
+
options)
|
231
227
|
|
232
228
|
if next_general_node_id
|
233
229
|
general_hash[:general] = serialize_generalization_attributes(
|
234
|
-
next_general_node_id,
|
230
|
+
next_general_node_id, options
|
235
231
|
)
|
236
232
|
end
|
237
233
|
|
238
234
|
general_hash
|
239
235
|
end
|
240
236
|
|
241
|
-
# @param xmi_id [String]
|
242
|
-
# @return [Lutaml::Model::Serializable]
|
243
|
-
def get_general_node(xmi_id)
|
244
|
-
find_packaged_element_by_id(xmi_id)
|
245
|
-
end
|
246
|
-
|
247
237
|
# @param general_node [Lutaml::Model::Serializable]
|
248
238
|
# @return [Hash]
|
249
239
|
def get_general_attributes(general_node)
|
@@ -258,8 +248,8 @@ module Lutaml
|
|
258
248
|
|
259
249
|
# @param general_id [String]
|
260
250
|
# @return [Array<Hash>]
|
261
|
-
def get_general_hash(general_id)
|
262
|
-
general_node =
|
251
|
+
def get_general_hash(general_id, options = {}) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
252
|
+
general_node = find_packaged_element_by_id(general_id)
|
263
253
|
return [] unless general_node
|
264
254
|
|
265
255
|
general_node_attrs = get_general_attributes(general_node)
|
@@ -271,7 +261,8 @@ module Lutaml
|
|
271
261
|
general_id: general_id,
|
272
262
|
general_name: general_node.name,
|
273
263
|
general_attributes: general_node_attrs,
|
274
|
-
general_upper_klass:
|
264
|
+
general_upper_klass: ::Lutaml::XMI::PackageDrop
|
265
|
+
.new(general_upper_klass, nil, options),
|
275
266
|
general: {},
|
276
267
|
},
|
277
268
|
next_general_node_id,
|
@@ -338,7 +329,7 @@ module Lutaml
|
|
338
329
|
|
339
330
|
all_packaged_elements.each do |e|
|
340
331
|
e.packaged_element.each do |pe|
|
341
|
-
@upper_level_cache[pe.id] = e
|
332
|
+
@upper_level_cache[pe.id] = e
|
342
333
|
end
|
343
334
|
end
|
344
335
|
end
|
@@ -435,25 +426,25 @@ module Lutaml
|
|
435
426
|
# @return [Lutaml::Model::Serializable]
|
436
427
|
def select_dependencies_by_client(client_id)
|
437
428
|
all_packaged_elements.select do |e|
|
438
|
-
e.client == client_id &&
|
439
|
-
e.type?("uml:Dependency")
|
429
|
+
e.client == client_id && e.type?("uml:Dependency")
|
440
430
|
end
|
441
431
|
end
|
442
432
|
|
443
433
|
# @param name [String]
|
444
434
|
# @return [Lutaml::Model::Serializable]
|
445
435
|
def find_packaged_element_by_name(name)
|
446
|
-
all_packaged_elements.find
|
447
|
-
e.name == name
|
448
|
-
end
|
436
|
+
all_packaged_elements.find { |e| e.name == name }
|
449
437
|
end
|
450
438
|
|
451
439
|
# @param package [Lutaml::Model::Serializable]
|
452
440
|
# @return [Array<Hash>]
|
453
441
|
# @note xpath ./packagedElement[@xmi:type="uml:Enumeration"]
|
454
|
-
def serialize_model_enums(package)
|
455
|
-
package.packaged_element.select
|
456
|
-
.
|
442
|
+
def serialize_model_enums(package) # rubocop:disable Metrics/MethodLength
|
443
|
+
enums = package.packaged_element.select do |e|
|
444
|
+
e.type?("uml:Enumeration")
|
445
|
+
end
|
446
|
+
|
447
|
+
enums.map do |enum|
|
457
448
|
{
|
458
449
|
xmi_id: enum.id,
|
459
450
|
name: enum.name,
|
@@ -489,8 +480,9 @@ module Lutaml
|
|
489
480
|
# @note xpath ./packagedElement[@xmi:type="uml:DataType"]
|
490
481
|
def serialize_model_data_types(model) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
491
482
|
all_data_type_elements = []
|
492
|
-
select_all_packaged_elements(
|
493
|
-
|
483
|
+
select_all_packaged_elements(
|
484
|
+
all_data_type_elements, model, "uml:DataType"
|
485
|
+
)
|
494
486
|
all_data_type_elements.map do |klass|
|
495
487
|
{
|
496
488
|
xmi_id: klass.id,
|
@@ -828,8 +820,11 @@ module Lutaml
|
|
828
820
|
# @return [Array<Hash>]
|
829
821
|
# @note xpath .//ownedAttribute[@xmi:type="uml:Property"]
|
830
822
|
def serialize_class_attributes(klass, with_assoc: false) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
831
|
-
klass.owned_attribute.select
|
832
|
-
.
|
823
|
+
owned_attributes = klass.owned_attribute.select do |attr|
|
824
|
+
attr.type?("uml:Property")
|
825
|
+
end
|
826
|
+
|
827
|
+
owned_attributes.map do |oa|
|
833
828
|
if with_assoc || oa.association.nil?
|
834
829
|
attrs = build_class_attributes(oa)
|
835
830
|
|
@@ -849,44 +844,6 @@ module Lutaml
|
|
849
844
|
connector&.documentation&.value
|
850
845
|
end
|
851
846
|
|
852
|
-
# @return [Array<Hash>]
|
853
|
-
def serialize_gml_attributes
|
854
|
-
element = find_packaged_element_by_name("_Feature")
|
855
|
-
attrs = serialize_class_attributes(element, with_assoc: true)
|
856
|
-
attrs.each { |attr| attr[:upper_klass] = "gml" }
|
857
|
-
end
|
858
|
-
|
859
|
-
# @return [Array<Hash>]
|
860
|
-
def serialize_core_attributes
|
861
|
-
element = find_packaged_element_by_name("_CityObject")
|
862
|
-
attrs = serialize_class_attributes(element, with_assoc: false)
|
863
|
-
attrs.each { |attr| attr[:upper_klass] = "core" }
|
864
|
-
end
|
865
|
-
|
866
|
-
# @return [Array<Hash>]
|
867
|
-
def select_gen_attributes
|
868
|
-
element = find_packaged_element_by_name("gen")
|
869
|
-
gen_attr_element = find_packaged_element_by_name("_genericAttribute")
|
870
|
-
|
871
|
-
element.packaged_element.select do |e|
|
872
|
-
e.type?("uml:Class") &&
|
873
|
-
e.generalization&.first&.general == gen_attr_element.id
|
874
|
-
end
|
875
|
-
end
|
876
|
-
|
877
|
-
# @return [Array<Hash>]
|
878
|
-
def serialize_gen_attributes
|
879
|
-
klasses = select_gen_attributes
|
880
|
-
|
881
|
-
klasses.map do |klass|
|
882
|
-
attr = serialize_class_attributes(klass, with_assoc: false)
|
883
|
-
attr.first[:name] = klass.name
|
884
|
-
attr.first[:type] = "gen:#{klass.name}"
|
885
|
-
attr.first[:upper_klass] = "gen"
|
886
|
-
attr
|
887
|
-
end.flatten!
|
888
|
-
end
|
889
|
-
|
890
847
|
# @param type [String]
|
891
848
|
# @return [String]
|
892
849
|
def get_ns_by_type(type)
|
@@ -895,7 +852,7 @@ module Lutaml
|
|
895
852
|
p = find_klass_packaged_element_by_name(type)
|
896
853
|
return unless p
|
897
854
|
|
898
|
-
find_upper_level_packaged_element(p.id)
|
855
|
+
find_upper_level_packaged_element(p.id)&.name
|
899
856
|
end
|
900
857
|
|
901
858
|
# @param xmi_id [String]
|
@@ -906,7 +863,7 @@ module Lutaml
|
|
906
863
|
p = find_packaged_element_by_id(xmi_id)
|
907
864
|
return unless p
|
908
865
|
|
909
|
-
find_upper_level_packaged_element(p.id)
|
866
|
+
find_upper_level_packaged_element(p.id)&.name
|
910
867
|
end
|
911
868
|
|
912
869
|
# @param klass_id [String]
|
@@ -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.43
|
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-14 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
|