lutaml 0.9.8 → 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 +284 -37
- data/lutaml.gemspec +1 -1
- metadata +6 -6
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,20 +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
|
-
|
26
|
-
|
27
|
-
|
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)
|
28
41
|
end
|
29
42
|
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
33
50
|
end
|
34
51
|
|
35
52
|
# @param xmi_model [Shale::Mapper]
|
@@ -37,7 +54,27 @@ module Lutaml
|
|
37
54
|
def parse(xmi_model)
|
38
55
|
@xmi_cache = {}
|
39
56
|
@xmi_root_model = xmi_model
|
40
|
-
|
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)
|
41
78
|
end
|
42
79
|
|
43
80
|
private
|
@@ -112,6 +149,138 @@ module Lutaml
|
|
112
149
|
end
|
113
150
|
end
|
114
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
|
+
|
115
284
|
# @param package [Shale::Mapper]
|
116
285
|
# @return [Array<Hash>]
|
117
286
|
# @note xpath ./packagedElement[@xmi:type="uml:Enumeration"]
|
@@ -233,9 +402,9 @@ module Lutaml
|
|
233
402
|
# @return [Shale::Mapper]
|
234
403
|
# @note xpath %(//connector[@xmi:idref="#{link_id}"])
|
235
404
|
def fetch_connector(link_id)
|
236
|
-
@xmi_root_model.extension.connectors.connector.
|
405
|
+
@xmi_root_model.extension.connectors.connector.find do |con|
|
237
406
|
con.idref == link_id
|
238
|
-
end
|
407
|
+
end
|
239
408
|
end
|
240
409
|
|
241
410
|
# @param link_id [String]
|
@@ -435,9 +604,9 @@ module Lutaml
|
|
435
604
|
all_elements = all_packaged_elements
|
436
605
|
|
437
606
|
owned_attributes = all_elements.map(&:owned_attribute).flatten
|
438
|
-
oa = owned_attributes.
|
607
|
+
oa = owned_attributes.find do |a|
|
439
608
|
!!a.association && a.uml_type && a.uml_type.idref == xmi_id
|
440
|
-
end
|
609
|
+
end
|
441
610
|
|
442
611
|
if oa
|
443
612
|
cardinality = cardinality_min_max_value(
|
@@ -453,37 +622,104 @@ module Lutaml
|
|
453
622
|
# @return [Shale::Mapper]
|
454
623
|
# @note xpath %(//element[@xmi:idref="#{klass['xmi:id']}"])
|
455
624
|
def fetch_element(klass_id)
|
456
|
-
@xmi_root_model.extension.elements.element.
|
625
|
+
@xmi_root_model.extension.elements.element.find do |e|
|
457
626
|
e.idref == klass_id
|
458
|
-
end
|
627
|
+
end
|
459
628
|
end
|
460
629
|
|
461
630
|
# @param klass [Shale::Mapper]
|
631
|
+
# @param with_assoc [Boolean]
|
462
632
|
# @return [Array<Hash>]
|
463
633
|
# @note xpath .//ownedAttribute[@xmi:type="uml:Property"]
|
464
|
-
def serialize_class_attributes(klass)
|
634
|
+
def serialize_class_attributes(klass, with_assoc: false)
|
465
635
|
klass.owned_attribute.select { |attr| attr.type?("uml:Property") }
|
466
636
|
.map do |oa|
|
467
|
-
|
468
|
-
|
637
|
+
if with_assoc || oa.association.nil?
|
638
|
+
attrs = build_class_attributes(oa)
|
469
639
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
cardinality: cardinality_min_max_value(
|
478
|
-
oa.lower_value&.value,
|
479
|
-
oa.upper_value&.value,
|
480
|
-
),
|
481
|
-
definition: lookup_attribute_documentation(oa.id),
|
482
|
-
}
|
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
|
483
647
|
end
|
484
648
|
end.compact
|
485
649
|
end
|
486
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
|
+
|
487
723
|
# @param min [String]
|
488
724
|
# @param max [String]
|
489
725
|
# @return [Hash]
|
@@ -540,6 +776,18 @@ module Lutaml
|
|
540
776
|
attribute_node&.documentation&.value
|
541
777
|
end
|
542
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
|
+
|
543
791
|
# @param xmi_id [String]
|
544
792
|
# @return [String]
|
545
793
|
def lookup_entity_name(xmi_id)
|
@@ -630,8 +878,7 @@ module Lutaml
|
|
630
878
|
def select_all_packaged_elements(all_elements, model, type)
|
631
879
|
select_all_items(all_elements, model, type, :packaged_element)
|
632
880
|
all_elements.delete_if do |e|
|
633
|
-
!e.is_a?(Xmi::Uml::PackagedElement)
|
634
|
-
!e.is_a?(Xmi::Uml::PackagedElement2013)
|
881
|
+
!e.is_a?(Xmi::Uml::PackagedElement)
|
635
882
|
end
|
636
883
|
end
|
637
884
|
|
data/lutaml.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_runtime_dependency "parslet", "~> 2.0.0"
|
37
37
|
spec.add_runtime_dependency "ruby-graphviz", "~> 1.2"
|
38
38
|
spec.add_runtime_dependency "thor", "~> 1.0"
|
39
|
-
spec.add_runtime_dependency "xmi", "
|
39
|
+
spec.add_runtime_dependency "xmi", "~> 0.3.10"
|
40
40
|
|
41
41
|
spec.add_development_dependency "byebug"
|
42
42
|
spec.add_development_dependency "equivalent-xml", "~> 0.6.0"
|
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
|
@@ -112,16 +112,16 @@ dependencies:
|
|
112
112
|
name: xmi
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.3.
|
117
|
+
version: 0.3.10
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.3.
|
124
|
+
version: 0.3.10
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: byebug
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|