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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cdc354ae49059f9158e3bfb8d0e7813b6c61d0084fa42ed7071026a9e62d311
4
- data.tar.gz: 30c6683d8e22d2e1ded1b8ca53d3d63e5129025049314b036b678efb611f713e
3
+ metadata.gz: 59f3f41813beaec8f6ffe17b8077aa9ad9d0a1a49861d12075b86e579e4d8287
4
+ data.tar.gz: f52b06e26ebecc5088248fa0d83696bfae5d26b6b2c31d32bca1d3210db5493d
5
5
  SHA512:
6
- metadata.gz: 1578a3589e20f92586cf4a60a6585ce5b758262a1112e3e5598e33c3209de72d477bf66b0fefd017e4633bd065ef93ed3fe37e2b55f60aae50a78203f299bcfa
7
- data.tar.gz: 72883f24b869448ac32f8724cb05cd5d24acf88ecbaa066bf084724f57ac116567266257f317b0e284e8ab081519eae6d8a2108915fb4e680076990b43339576
6
+ metadata.gz: f0b91cc8fcf077286165cb879a9896f401ccd45f72db55fb8a2ef0f89aca841f7d57bdf581194f3487f2f8edfc83103c68b174f36f95cdaa4710d2303ac01d64
7
+ data.tar.gz: e16c5a41385564b5e9c3c89850114daa5e8ff0ae1a0a4bac5ed5f12c40155d4164c087e74b1e80841ab8a5d58af305ab6caa621f93a321f97fe44fa0604960f2
@@ -1,3 +1,3 @@
1
1
  module Lutaml
2
- VERSION = "0.9.9".freeze
2
+ VERSION = "0.9.10".freeze
3
3
  end
@@ -16,13 +16,37 @@ module Lutaml
16
16
  }.freeze
17
17
  attr_reader :xmi_cache, :xmi_root_model
18
18
 
19
- # @param xml [String] path to xml
20
- # @param options [Hash] options for parsing
21
- # @return [Lutaml::Uml::Document]
22
- def self.parse(xml, _options = {})
23
- xml_content = File.read(xml)
24
- xmi_model = Xmi::Sparx::SparxRoot.parse_xml(xml_content)
25
- new.parse(xmi_model)
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
- ::Lutaml::Uml::Document.new(serialize_to_hash(xmi_model))
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.select do |con|
405
+ @xmi_root_model.extension.connectors.connector.find do |con|
230
406
  con.idref == link_id
231
- end.first
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.select do |a|
607
+ oa = owned_attributes.find do |a|
432
608
  !!a.association && a.uml_type && a.uml_type.idref == xmi_id
433
- end.first
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.select do |e|
625
+ @xmi_root_model.extension.elements.element.find do |e|
450
626
  e.idref == klass_id
451
- end.first
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
- uml_type = oa.uml_type
461
- uml_type_idref = uml_type.idref if uml_type
637
+ if with_assoc || oa.association.nil?
638
+ attrs = build_class_attributes(oa)
462
639
 
463
- if oa.association.nil?
464
- {
465
- id: oa.id,
466
- name: oa.name,
467
- type: lookup_entity_name(uml_type_idref) || uml_type_idref,
468
- xmi_id: uml_type_idref,
469
- is_derived: oa.is_derived,
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.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-08-12 00:00:00.000000000 Z
11
+ date: 2024-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expressir