lutaml 0.9.8 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d1677e27d1216994f6619acc558721d9b2d6107dd30fd6776232965d6d1d219
4
- data.tar.gz: e8999116cdee14d6316f9bedaa781893ae2d27b88f93aef514fdda435e8d29b6
3
+ metadata.gz: 59f3f41813beaec8f6ffe17b8077aa9ad9d0a1a49861d12075b86e579e4d8287
4
+ data.tar.gz: f52b06e26ebecc5088248fa0d83696bfae5d26b6b2c31d32bca1d3210db5493d
5
5
  SHA512:
6
- metadata.gz: 37c0d7fb4a3676a45fc8ebbab3bfab3e993ad84e005a8a7d642a1af66c3600271d1a03b723a2b7ff8462a96a75605c5bce06425393047c9fcdcd16c38c1b603f
7
- data.tar.gz: e287823e6e238754223823ccabaebe31f13332b26efb67ac97d1c3f103cdf512f5a7be9276653f826983fe87e991b221772115b1c3d0bb09bb5745db1f2b0dd2
6
+ metadata.gz: f0b91cc8fcf077286165cb879a9896f401ccd45f72db55fb8a2ef0f89aca841f7d57bdf581194f3487f2f8edfc83103c68b174f36f95cdaa4710d2303ac01d64
7
+ data.tar.gz: e16c5a41385564b5e9c3c89850114daa5e8ff0ae1a0a4bac5ed5f12c40155d4164c087e74b1e80841ab8a5d58af305ab6caa621f93a321f97fe44fa0604960f2
@@ -1,3 +1,3 @@
1
1
  module Lutaml
2
- VERSION = "0.9.8".freeze
2
+ VERSION = "0.9.10".freeze
3
3
  end
@@ -16,20 +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
- sparx_root = Xmi::Sparx::SparxRoot
24
- xmi_doc = Nokogiri::XML(File.read(xml))
25
- namespace = xmi_doc.at_xpath("//xmi:XMI").namespaces
26
- if namespace["xmlns:uml"].split("/").last == "20131001"
27
- sparx_root = Xmi::Sparx::SparxRoot2013
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
- xml_content = File.read(xml)
31
- xmi_model = sparx_root.from_xml(xml_content)
32
- new.parse(xmi_model)
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
- ::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)
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.select do |con|
405
+ @xmi_root_model.extension.connectors.connector.find do |con|
237
406
  con.idref == link_id
238
- end.first
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.select do |a|
607
+ oa = owned_attributes.find do |a|
439
608
  !!a.association && a.uml_type && a.uml_type.idref == xmi_id
440
- end.first
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.select do |e|
625
+ @xmi_root_model.extension.elements.element.find do |e|
457
626
  e.idref == klass_id
458
- end.first
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
- uml_type = oa.uml_type
468
- uml_type_idref = uml_type.idref if uml_type
637
+ if with_assoc || oa.association.nil?
638
+ attrs = build_class_attributes(oa)
469
639
 
470
- if oa.association.nil?
471
- {
472
- id: oa.id,
473
- name: oa.name,
474
- type: lookup_entity_name(uml_type_idref) || uml_type_idref,
475
- xmi_id: uml_type_idref,
476
- is_derived: oa.is_derived,
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", ">= 0.3.8"
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.8
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-07-30 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
@@ -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.8
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.8
124
+ version: 0.3.10
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: byebug
127
127
  requirement: !ruby/object:Gem::Requirement