lutaml 0.9.9 → 0.9.10
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/version.rb +1 -1
- data/lib/lutaml/xmi/parsers/xml.rb +285 -30
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59f3f41813beaec8f6ffe17b8077aa9ad9d0a1a49861d12075b86e579e4d8287
|
4
|
+
data.tar.gz: f52b06e26ebecc5088248fa0d83696bfae5d26b6b2c31d32bca1d3210db5493d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0b91cc8fcf077286165cb879a9896f401ccd45f72db55fb8a2ef0f89aca841f7d57bdf581194f3487f2f8edfc83103c68b174f36f95cdaa4710d2303ac01d64
|
7
|
+
data.tar.gz: e16c5a41385564b5e9c3c89850114daa5e8ff0ae1a0a4bac5ed5f12c40155d4164c087e74b1e80841ab8a5d58af305ab6caa621f93a321f97fe44fa0604960f2
|
data/lib/lutaml/version.rb
CHANGED
@@ -16,13 +16,37 @@ module Lutaml
|
|
16
16
|
}.freeze
|
17
17
|
attr_reader :xmi_cache, :xmi_root_model
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
class << self
|
20
|
+
# @param xml [String] path to xml
|
21
|
+
# @param options [Hash] options for parsing
|
22
|
+
# @return [Lutaml::Uml::Document]
|
23
|
+
def parse(xml, _options = {})
|
24
|
+
xmi_model = get_xmi_model(xml)
|
25
|
+
new.parse(xmi_model)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param xml [String] path to xml
|
29
|
+
# @return [Hash]
|
30
|
+
def serialize_xmi(xml)
|
31
|
+
xmi_model = get_xmi_model(xml)
|
32
|
+
new.serialize_xmi(xmi_model)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param xml [String] path to xml
|
36
|
+
# @param name [String]
|
37
|
+
# @return [Hash]
|
38
|
+
def serialize_generalization_by_name(xml, name)
|
39
|
+
xmi_model = get_xmi_model(xml)
|
40
|
+
new.serialize_generalization_by_name(xmi_model, name)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# @param xml [String]
|
46
|
+
# @return [Shale::Mapper]
|
47
|
+
def get_xmi_model(xml)
|
48
|
+
Xmi::Sparx::SparxRoot.parse_xml(File.read(xml))
|
49
|
+
end
|
26
50
|
end
|
27
51
|
|
28
52
|
# @param xmi_model [Shale::Mapper]
|
@@ -30,7 +54,27 @@ module Lutaml
|
|
30
54
|
def parse(xmi_model)
|
31
55
|
@xmi_cache = {}
|
32
56
|
@xmi_root_model = xmi_model
|
33
|
-
|
57
|
+
serialized_hash = serialize_xmi(xmi_model)
|
58
|
+
|
59
|
+
::Lutaml::Uml::Document.new(serialized_hash)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param xmi_model [Shale::Mapper]
|
63
|
+
# return [Hash]
|
64
|
+
def serialize_xmi(xmi_model)
|
65
|
+
@xmi_cache = {}
|
66
|
+
@xmi_root_model = xmi_model
|
67
|
+
serialize_to_hash(xmi_model)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param xmi_model [Shale::Mapper]
|
71
|
+
# @param name [String]
|
72
|
+
# @return [Hash]
|
73
|
+
def serialize_generalization_by_name(xmi_model, name)
|
74
|
+
@xmi_cache = {}
|
75
|
+
@xmi_root_model = xmi_model
|
76
|
+
klass = find_klass_packaged_element_by_name(name)
|
77
|
+
serialize_generalization(klass)
|
34
78
|
end
|
35
79
|
|
36
80
|
private
|
@@ -105,6 +149,138 @@ module Lutaml
|
|
105
149
|
end
|
106
150
|
end
|
107
151
|
|
152
|
+
# @param klass [Shale::Mapper]
|
153
|
+
# # @return [Hash]
|
154
|
+
def serialize_generalization(klass)
|
155
|
+
general_hash, next_general_node_id = get_top_level_general_hash(klass)
|
156
|
+
return general_hash unless next_general_node_id
|
157
|
+
|
158
|
+
general_hash[:general] = serialize_generalization_attributes(
|
159
|
+
next_general_node_id,
|
160
|
+
)
|
161
|
+
|
162
|
+
general_hash
|
163
|
+
end
|
164
|
+
|
165
|
+
# @param klass [Shale::Mapper]
|
166
|
+
# @return [Array<Hash>]
|
167
|
+
def get_top_level_general_hash(klass) # rubocop:disable Metrics/AbcSize
|
168
|
+
general_hash, next_general_node_id = get_general_hash(klass.id)
|
169
|
+
general_hash[:name] = klass.name
|
170
|
+
general_hash[:type] = klass.type
|
171
|
+
general_hash[:definition] = lookup_general_documentation(klass.id)
|
172
|
+
general_hash[:stereotype] = doc_node_attribute_value(
|
173
|
+
klass.id, "stereotype"
|
174
|
+
)
|
175
|
+
|
176
|
+
# update_inherited_attributes(general_hash)
|
177
|
+
# update_gen_attributes(general_hash)
|
178
|
+
|
179
|
+
[general_hash, next_general_node_id]
|
180
|
+
end
|
181
|
+
|
182
|
+
def lookup_general_documentation(klass_id)
|
183
|
+
# lookup_attribute_documentation(klass_id) ||
|
184
|
+
# lookup_element_prop_documentation(klass_id)
|
185
|
+
|
186
|
+
lookup_element_prop_documentation(klass_id)
|
187
|
+
end
|
188
|
+
|
189
|
+
def update_gen_attributes(general_hash)
|
190
|
+
general_hash[:gen_attributes] = serialize_gen_attributes
|
191
|
+
end
|
192
|
+
|
193
|
+
def update_inherited_attributes(general_hash)
|
194
|
+
general_hash[:gml_attributes] = serialize_gml_attributes
|
195
|
+
general_hash[:core_attributes] = serialize_core_attributes
|
196
|
+
end
|
197
|
+
|
198
|
+
# @param xmi_id [String]
|
199
|
+
# @param model [Shale::Mapper]
|
200
|
+
# @return [Array<Hash>]
|
201
|
+
# @note get generalization node and its owned attributes
|
202
|
+
def serialize_generalization_attributes(general_id)
|
203
|
+
general_hash, next_general_node_id = get_general_hash(general_id)
|
204
|
+
|
205
|
+
if next_general_node_id
|
206
|
+
general_hash[:general] = serialize_generalization_attributes(
|
207
|
+
next_general_node_id,
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
general_hash
|
212
|
+
end
|
213
|
+
|
214
|
+
# @param xmi_id [String]
|
215
|
+
# @return [Shale::Mapper]
|
216
|
+
def get_general_node(xmi_id)
|
217
|
+
find_packaged_element_by_id(xmi_id)
|
218
|
+
end
|
219
|
+
|
220
|
+
# @param general_node [Shale::Mapper]
|
221
|
+
# # @return [Hash]
|
222
|
+
def get_general_attributes(general_node)
|
223
|
+
attrs = serialize_class_attributes(general_node, with_assoc: true)
|
224
|
+
attrs.sort_by { |i| i[:name] }
|
225
|
+
end
|
226
|
+
|
227
|
+
# @param general_node [Shale::Mapper]
|
228
|
+
# @return [String]
|
229
|
+
def get_next_general_node_id(general_node)
|
230
|
+
general_node.generalization.first&.general
|
231
|
+
end
|
232
|
+
|
233
|
+
# @param general_id [String]
|
234
|
+
# @return [Array<Hash>]
|
235
|
+
def get_general_hash(general_id)
|
236
|
+
general_node = get_general_node(general_id)
|
237
|
+
general_node_attrs = get_general_attributes(general_node)
|
238
|
+
general_upper_klass = find_upper_level_packaged_element(general_id)
|
239
|
+
next_general_node_id = get_next_general_node_id(general_node)
|
240
|
+
|
241
|
+
[
|
242
|
+
{
|
243
|
+
general_id: general_id,
|
244
|
+
general_name: general_node.name,
|
245
|
+
general_attributes: general_node_attrs,
|
246
|
+
general_upper_klass: general_upper_klass,
|
247
|
+
general: {},
|
248
|
+
},
|
249
|
+
next_general_node_id,
|
250
|
+
]
|
251
|
+
end
|
252
|
+
|
253
|
+
# @param id [String]
|
254
|
+
# @return [Shale::Mapper]
|
255
|
+
def find_packaged_element_by_id(id)
|
256
|
+
all_packaged_elements.find { |e| e.id == id }
|
257
|
+
end
|
258
|
+
|
259
|
+
# @param id [String]
|
260
|
+
# @return [Shale::Mapper]
|
261
|
+
def find_upper_level_packaged_element(klass_id)
|
262
|
+
upper_klass = all_packaged_elements.find do |e|
|
263
|
+
e.packaged_element.find { |pe| pe.id == klass_id }
|
264
|
+
end
|
265
|
+
upper_klass&.name
|
266
|
+
end
|
267
|
+
|
268
|
+
# @param name [String]
|
269
|
+
# @return [Shale::Mapper]
|
270
|
+
def find_klass_packaged_element_by_name(name)
|
271
|
+
all_packaged_elements.find do |e|
|
272
|
+
e.type?("uml:Class") && e.name == name
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# @param name [String]
|
277
|
+
# @return [Shale::Mapper]
|
278
|
+
def find_packaged_element_by_name(name)
|
279
|
+
all_packaged_elements.find do |e|
|
280
|
+
e.name == name
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
108
284
|
# @param package [Shale::Mapper]
|
109
285
|
# @return [Array<Hash>]
|
110
286
|
# @note xpath ./packagedElement[@xmi:type="uml:Enumeration"]
|
@@ -226,9 +402,9 @@ module Lutaml
|
|
226
402
|
# @return [Shale::Mapper]
|
227
403
|
# @note xpath %(//connector[@xmi:idref="#{link_id}"])
|
228
404
|
def fetch_connector(link_id)
|
229
|
-
@xmi_root_model.extension.connectors.connector.
|
405
|
+
@xmi_root_model.extension.connectors.connector.find do |con|
|
230
406
|
con.idref == link_id
|
231
|
-
end
|
407
|
+
end
|
232
408
|
end
|
233
409
|
|
234
410
|
# @param link_id [String]
|
@@ -428,9 +604,9 @@ module Lutaml
|
|
428
604
|
all_elements = all_packaged_elements
|
429
605
|
|
430
606
|
owned_attributes = all_elements.map(&:owned_attribute).flatten
|
431
|
-
oa = owned_attributes.
|
607
|
+
oa = owned_attributes.find do |a|
|
432
608
|
!!a.association && a.uml_type && a.uml_type.idref == xmi_id
|
433
|
-
end
|
609
|
+
end
|
434
610
|
|
435
611
|
if oa
|
436
612
|
cardinality = cardinality_min_max_value(
|
@@ -446,37 +622,104 @@ module Lutaml
|
|
446
622
|
# @return [Shale::Mapper]
|
447
623
|
# @note xpath %(//element[@xmi:idref="#{klass['xmi:id']}"])
|
448
624
|
def fetch_element(klass_id)
|
449
|
-
@xmi_root_model.extension.elements.element.
|
625
|
+
@xmi_root_model.extension.elements.element.find do |e|
|
450
626
|
e.idref == klass_id
|
451
|
-
end
|
627
|
+
end
|
452
628
|
end
|
453
629
|
|
454
630
|
# @param klass [Shale::Mapper]
|
631
|
+
# @param with_assoc [Boolean]
|
455
632
|
# @return [Array<Hash>]
|
456
633
|
# @note xpath .//ownedAttribute[@xmi:type="uml:Property"]
|
457
|
-
def serialize_class_attributes(klass)
|
634
|
+
def serialize_class_attributes(klass, with_assoc: false)
|
458
635
|
klass.owned_attribute.select { |attr| attr.type?("uml:Property") }
|
459
636
|
.map do |oa|
|
460
|
-
|
461
|
-
|
637
|
+
if with_assoc || oa.association.nil?
|
638
|
+
attrs = build_class_attributes(oa)
|
462
639
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
cardinality: cardinality_min_max_value(
|
471
|
-
oa.lower_value&.value,
|
472
|
-
oa.upper_value&.value,
|
473
|
-
),
|
474
|
-
definition: lookup_attribute_documentation(oa.id),
|
475
|
-
}
|
640
|
+
if with_assoc && oa.association
|
641
|
+
attrs[:association] = oa.association
|
642
|
+
attrs[:definition] = loopup_assoc_def(oa.association)
|
643
|
+
attrs[:type_ns] = get_ns_by_type(attrs[:type])
|
644
|
+
end
|
645
|
+
|
646
|
+
attrs
|
476
647
|
end
|
477
648
|
end.compact
|
478
649
|
end
|
479
650
|
|
651
|
+
def loopup_assoc_def(association)
|
652
|
+
connector = fetch_connector(association)
|
653
|
+
connector&.documentation&.value
|
654
|
+
end
|
655
|
+
|
656
|
+
# @return [Array<Hash>]
|
657
|
+
def serialize_gml_attributes
|
658
|
+
element = find_packaged_element_by_name("_Feature")
|
659
|
+
attrs = serialize_class_attributes(element, with_assoc: true)
|
660
|
+
attrs.each { |attr| attr[:upper_klass] = "gml" }
|
661
|
+
end
|
662
|
+
|
663
|
+
# @return [Array<Hash>]
|
664
|
+
def serialize_core_attributes
|
665
|
+
element = find_packaged_element_by_name("_CityObject")
|
666
|
+
attrs = serialize_class_attributes(element, with_assoc: false)
|
667
|
+
attrs.each { |attr| attr[:upper_klass] = "core" }
|
668
|
+
end
|
669
|
+
|
670
|
+
# @return [Array<Hash>]
|
671
|
+
def select_gen_attributes
|
672
|
+
element = find_packaged_element_by_name("gen")
|
673
|
+
gen_attr_element = find_packaged_element_by_name("_genericAttribute")
|
674
|
+
|
675
|
+
element.packaged_element.select do |e|
|
676
|
+
e.type?("uml:Class") &&
|
677
|
+
e.generalization&.first&.general == gen_attr_element.id
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
# @return [Array<Hash>]
|
682
|
+
def serialize_gen_attributes
|
683
|
+
klasses = select_gen_attributes
|
684
|
+
|
685
|
+
klasses.map do |klass|
|
686
|
+
attr = serialize_class_attributes(klass, with_assoc: false)
|
687
|
+
attr.first[:name] = klass.name
|
688
|
+
attr.first[:type] = "gen:#{klass.name}"
|
689
|
+
attr.first[:upper_klass] = "gen"
|
690
|
+
attr
|
691
|
+
end.flatten!
|
692
|
+
end
|
693
|
+
|
694
|
+
# @param type [String]
|
695
|
+
# @return [String]
|
696
|
+
def get_ns_by_type(type)
|
697
|
+
return unless type
|
698
|
+
|
699
|
+
p = find_klass_packaged_element_by_name(type)
|
700
|
+
find_upper_level_packaged_element(p.id)
|
701
|
+
end
|
702
|
+
|
703
|
+
# @param klass_id [String]
|
704
|
+
# @return [Array<Hash>]
|
705
|
+
def build_class_attributes(owned_attr) # rubocop:disable Metrics/MethodLength
|
706
|
+
uml_type = owned_attr.uml_type
|
707
|
+
uml_type_idref = uml_type.idref if uml_type
|
708
|
+
|
709
|
+
{
|
710
|
+
id: owned_attr.id,
|
711
|
+
name: owned_attr.name,
|
712
|
+
type: lookup_entity_name(uml_type_idref) || uml_type_idref,
|
713
|
+
xmi_id: uml_type_idref,
|
714
|
+
is_derived: owned_attr.is_derived,
|
715
|
+
cardinality: cardinality_min_max_value(
|
716
|
+
owned_attr.lower_value&.value,
|
717
|
+
owned_attr.upper_value&.value,
|
718
|
+
),
|
719
|
+
definition: lookup_attribute_documentation(owned_attr.id),
|
720
|
+
}
|
721
|
+
end
|
722
|
+
|
480
723
|
# @param min [String]
|
481
724
|
# @param max [String]
|
482
725
|
# @return [Hash]
|
@@ -533,6 +776,18 @@ module Lutaml
|
|
533
776
|
attribute_node&.documentation&.value
|
534
777
|
end
|
535
778
|
|
779
|
+
# @param xmi_id [String]
|
780
|
+
# @return [String]
|
781
|
+
def lookup_element_prop_documentation(xmi_id)
|
782
|
+
element_node = @xmi_root_model.extension.elements.element.find do |e|
|
783
|
+
e.idref == xmi_id
|
784
|
+
end
|
785
|
+
|
786
|
+
return unless element_node&.properties
|
787
|
+
|
788
|
+
element_node&.properties&.documentation
|
789
|
+
end
|
790
|
+
|
536
791
|
# @param xmi_id [String]
|
537
792
|
# @return [String]
|
538
793
|
def lookup_entity_name(xmi_id)
|
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.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expressir
|