lutaml 0.8.1 → 0.9.1

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: b0a582c930c66da4590b8f707825f61e407bbe2492c95aa6f6a61725e95e62d4
4
- data.tar.gz: cb3045bd11c726aa0d9462f72216e783545c37e2a701c223c5dc335eb1fb8213
3
+ metadata.gz: c3bdc3f066879a36efeca4609e9aca838d50a6708a1112b403da3c67a2e1d4dc
4
+ data.tar.gz: '085cc25361b1aff8bd5ee4910230ceb5420a9830fbaeaa811b60c85b20de8f18'
5
5
  SHA512:
6
- metadata.gz: 57aecd47776c51bafead92eaa4a245639d5b38999b04b5a12343e23c0ee97141605e4b723eb0663e4b88e775d9aba6c7458a125f4d011495d26cb0e6d17e714c
7
- data.tar.gz: 6ae62810f1212d029efbc6829a29a7fee18306e8a672c5d8ab08d6907979dfaa6db2743763400d35f3f8d4c5551ab57db53dae8c88577703ddac7869e9adfc28
6
+ metadata.gz: a29744b9dabc937dd635e33b93270a3cdbd28c3735fd8975fd459b0193e98db38cc6e15ad499185135294f4a8fcb10ce0f52c8ecade9ed9ad81dffef23e8245a
7
+ data.tar.gz: bbb498bc86c6752dfdbde5a54737cd522d20c2e04e4a6a1a59737c95b2c3c7600d452049412c6338a7dc028b0d33314f606a0fd3af98623e962ef68193d21f00
@@ -10,5 +10,3 @@ on:
10
10
  jobs:
11
11
  rake:
12
12
  uses: metanorma/ci/.github/workflows/graphviz-rake.yml@main
13
- secrets:
14
- pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
@@ -1,3 +1,3 @@
1
1
  module Lutaml
2
- VERSION = "0.8.1".freeze
2
+ VERSION = "0.9.1".freeze
3
3
  end
@@ -20,8 +20,15 @@ module Lutaml
20
20
  # @param options [Hash] options for parsing
21
21
  # @return [Lutaml::Uml::Document]
22
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
28
+ end
29
+
23
30
  xml_content = File.read(xml)
24
- xmi_model = Xmi::Sparx::SparxRoot2013.from_xml(xml_content)
31
+ xmi_model = sparx_root.from_xml(xml_content)
25
32
  new.parse(xmi_model)
26
33
  end
27
34
 
@@ -42,7 +49,7 @@ module Lutaml
42
49
  model = xmi_model.model
43
50
  {
44
51
  name: model.name,
45
- packages: serialize_model_packages(model)
52
+ packages: serialize_model_packages(model),
46
53
  }
47
54
  end
48
55
 
@@ -50,30 +57,45 @@ module Lutaml
50
57
  # @return [Array<Hash>]
51
58
  # @note xpath ./packagedElement[@xmi:type="uml:Package"]
52
59
  def serialize_model_packages(model)
53
- model.packaged_element.map do |package|
60
+ model.packaged_element.select do |e|
61
+ e.type?("uml:Package")
62
+ end.map do |package|
54
63
  {
55
64
  xmi_id: package.id,
56
- name: package.name,
65
+ name: get_package_name(package),
57
66
  classes: serialize_model_classes(package, model),
58
67
  enums: serialize_model_enums(package),
59
68
  data_types: serialize_model_data_types(package),
60
69
  diagrams: serialize_model_diagrams(package.id),
61
70
  packages: serialize_model_packages(package),
62
71
  definition: doc_node_attribute_value(package.id, "documentation"),
63
- stereotype: doc_node_attribute_value(package.id, "stereotype")
72
+ stereotype: doc_node_attribute_value(package.id, "stereotype"),
64
73
  }
65
74
  end
66
75
  end
67
76
 
77
+ def get_package_name(package)
78
+ return package.name unless package.name.nil?
79
+
80
+ connector = fetch_connector(package.id)
81
+ if connector.target&.model && connector.target.model&.name
82
+ return "#{connector.target.model.name} " \
83
+ "(#{package.type.split(':').last})"
84
+ end
85
+
86
+ "unnamed"
87
+ end
88
+
68
89
  # @param package [Shale::Mapper]
69
90
  # @param model [Shale::Mapper]
70
91
  # @return [Array<Hash>]
71
92
  # @note xpath ./packagedElement[@xmi:type="uml:Class" or
72
93
  # @xmi:type="uml:AssociationClass"]
73
94
  def serialize_model_classes(package, model)
74
- package.packaged_element.select { |e|
75
- e.type?("uml:Class") || e.type?("uml:AssociationClass")
76
- }.map do |klass|
95
+ package.packaged_element.select do |e|
96
+ e.type?("uml:Class") || e.type?("uml:AssociationClass") ||
97
+ e.type?("uml:Interface")
98
+ end.map do |klass|
77
99
  {
78
100
  xmi_id: klass.id,
79
101
  name: klass.name,
@@ -84,7 +106,7 @@ module Lutaml
84
106
  constraints: serialize_class_constraints(klass.id),
85
107
  is_abstract: doc_node_attribute_value(klass.id, "isAbstract"),
86
108
  definition: doc_node_attribute_value(klass.id, "documentation"),
87
- stereotype: doc_node_attribute_value(klass.id, "stereotype")
109
+ stereotype: doc_node_attribute_value(klass.id, "stereotype"),
88
110
  }
89
111
  end
90
112
  end
@@ -93,12 +115,12 @@ module Lutaml
93
115
  # @return [Array<Hash>]
94
116
  # @note xpath ./packagedElement[@xmi:type="uml:Enumeration"]
95
117
  def serialize_model_enums(package)
96
- package.packaged_element
97
- .select { |e| e.type?("uml:Enumeration") }.map do |enum|
98
- # xpath .//ownedLiteral[@xmi:type="uml:EnumerationLiteral"]
99
- owned_literals = enum.owned_literal.map do |owned_literal|
100
- owned_literal.to_hash.transform_keys(&:to_sym)
101
- end
118
+ package.packaged_element.select { |e| e.type?("uml:Enumeration") }
119
+ .map do |enum|
120
+ # xpath .//ownedLiteral[@xmi:type="uml:EnumerationLiteral"]
121
+ owned_literals = enum.owned_literal.map do |owned_literal|
122
+ owned_literal.to_hash.transform_keys(&:to_sym)
123
+ end
102
124
 
103
125
  {
104
126
  xmi_id: enum.id,
@@ -116,7 +138,7 @@ module Lutaml
116
138
  def serialize_model_data_types(model)
117
139
  all_data_type_elements = []
118
140
  select_all_packaged_elements(all_data_type_elements, model,
119
- "uml:DataType")
141
+ "uml:DataType")
120
142
  all_data_type_elements.map do |klass|
121
143
  {
122
144
  xmi_id: klass.id,
@@ -144,7 +166,7 @@ module Lutaml
144
166
  {
145
167
  xmi_id: diagram.id,
146
168
  name: diagram.properties.name,
147
- definition: diagram.properties.documentation
169
+ definition: diagram.properties.documentation,
148
170
  }
149
171
  end
150
172
  end
@@ -156,26 +178,25 @@ module Lutaml
156
178
  matched_element = @xmi_root_model.extension.elements.element
157
179
  .find { |e| e.idref == xmi_id }
158
180
 
159
- return if !matched_element.links ||
181
+ return if !matched_element ||
182
+ !matched_element.links ||
160
183
  matched_element.links.association.empty?
161
184
 
162
185
  matched_element.links.association.map do |assoc|
163
- link_member_name = assoc.start == xmi_id ? "end" : "start"
164
- linke_owner_name = link_member_name == "start" ? "end" : "start"
186
+ link_member = assoc.start == xmi_id ? "end" : "start"
187
+ linke_owner_name = link_member == "start" ? "end" : "start"
165
188
 
166
189
  member_end, member_end_type, member_end_cardinality,
167
190
  member_end_attribute_name, member_end_xmi_id =
168
- serialize_member_type(xmi_id, assoc, link_member_name)
191
+ serialize_member_type(xmi_id, assoc, link_member)
169
192
 
170
193
  owner_end = serialize_owned_type(xmi_id, assoc, linke_owner_name)
171
194
 
172
- if member_end && ((member_end_type != 'aggregation') ||
173
- (member_end_type == 'aggregation' && member_end_attribute_name))
195
+ if member_end && ((member_end_type != "aggregation") ||
196
+ (member_end_type == "aggregation" && member_end_attribute_name))
174
197
 
175
- doc_node_name = (link_member_name == "start" ?
176
- "source" : "target")
177
- definition = fetch_definition_node_value(assoc.id,
178
- doc_node_name)
198
+ doc_node_name = (link_member == "start" ? "source" : "target")
199
+ definition = fetch_definition_node_value(assoc.id, doc_node_name)
179
200
 
180
201
  {
181
202
  xmi_id: assoc.id,
@@ -186,7 +207,7 @@ module Lutaml
186
207
  member_end_xmi_id: member_end_xmi_id,
187
208
  owner_end: owner_end,
188
209
  owner_end_xmi_id: xmi_id,
189
- definition: definition
210
+ definition: definition,
190
211
  }
191
212
  end
192
213
  end
@@ -239,7 +260,7 @@ module Lutaml
239
260
  if connector_node
240
261
  # In ea-xmi-2.5.1, constraints are moved to source/target under
241
262
  # connectors
242
- constraints = [:source, :target].map do |st|
263
+ constraints = %i[source target].map do |st|
243
264
  connector_node.send(st).constraints.constraint
244
265
  end.flatten
245
266
 
@@ -267,8 +288,7 @@ module Lutaml
267
288
  end
268
289
 
269
290
  xmi_id = link.send(linke_owner_name.to_sym)
270
- owner_end = lookup_entity_name(xmi_id) ||
271
- connector_source_name(xmi_id)
291
+ lookup_entity_name(xmi_id) || connector_source_name(xmi_id)
272
292
 
273
293
  # not necessary
274
294
  # if link.name == "Association"
@@ -279,14 +299,13 @@ module Lutaml
279
299
  # fetch_owned_attribute_node(xmi_id)
280
300
  # end
281
301
  # [owner_end, owned_cardinality, owned_attribute_name]
282
- owner_end
302
+ # owner_end
283
303
  end
284
304
 
285
305
  # @param owner_xmi_id [String]
286
306
  # @param link [Shale::Mapper]
287
- # @param link_member_name [String]
288
307
  # @return [Array<String, String>]
289
- def serialize_member_end(owner_xmi_id, link, link_member_name)
308
+ def serialize_member_end(owner_xmi_id, link)
290
309
  case link.name
291
310
  when "NoteLink"
292
311
  return
@@ -313,8 +332,7 @@ module Lutaml
313
332
  # @param link_member_name [String]
314
333
  # @return [Array<String, String, Hash, String, String>]
315
334
  def serialize_member_type(owner_xmi_id, link, link_member_name)
316
- member_end, xmi_id = serialize_member_end(
317
- owner_xmi_id, link, link_member_name)
335
+ member_end, xmi_id = serialize_member_end(owner_xmi_id, link)
318
336
 
319
337
  if link.name == "Association"
320
338
  connector_type = link_member_name == "start" ? "source" : "target"
@@ -326,7 +344,7 @@ module Lutaml
326
344
  end
327
345
 
328
346
  [member_end, "aggregation", member_end_cardinality,
329
- member_end_attribute_name, xmi_id]
347
+ member_end_attribute_name, xmi_id]
330
348
  end
331
349
 
332
350
  # @param link_id [String]
@@ -338,9 +356,9 @@ module Lutaml
338
356
 
339
357
  if assoc_connector
340
358
  assoc_connector_type = assoc_connector.type
341
- if assoc_connector_type && assoc_connector_type.multiplicity
342
- cardinality = assoc_connector_type.multiplicity.split('..')
343
- cardinality.unshift('1') if cardinality.length == 1
359
+ if assoc_connector_type&.multiplicity
360
+ cardinality = assoc_connector_type.multiplicity.split("..")
361
+ cardinality.unshift("1") if cardinality.length == 1
344
362
  min, max = cardinality
345
363
  end
346
364
  assoc_connector_role = assoc_connector.role
@@ -385,15 +403,14 @@ module Lutaml
385
403
  def fetch_owned_attribute_node(xmi_id)
386
404
  all_elements = all_packaged_elements
387
405
 
388
- owned_attributes = all_elements.map { |e| e.owned_attribute }.flatten
406
+ owned_attributes = all_elements.map(&:owned_attribute).flatten
389
407
  oa = owned_attributes.select do |a|
390
408
  !!a.association && a.uml_type && a.uml_type.idref == xmi_id
391
409
  end.first
392
410
 
393
411
  if oa
394
412
  cardinality = cardinality_min_max_value(
395
- oa.lower_value&.value,
396
- oa.upper_value&.value
413
+ oa.lower_value&.value, oa.upper_value&.value
397
414
  )
398
415
  oa_name = oa.name
399
416
  end
@@ -416,22 +433,23 @@ module Lutaml
416
433
  def serialize_class_attributes(klass)
417
434
  klass.owned_attribute.select { |attr| attr.type?("uml:Property") }
418
435
  .map do |oa|
419
- uml_type = oa.uml_type
420
- uml_type_idref = uml_type.idref if uml_type
421
-
422
- if oa.association.nil?
423
- {
424
- id: oa.id,
425
- name: oa.name,
426
- type: lookup_entity_name(uml_type_idref) || uml_type_idref,
427
- xmi_id: uml_type_idref,
428
- is_derived: oa.is_derived,
429
- cardinality: cardinality_min_max_value(
430
- oa.lower_value&.value,
431
- oa.upper_value&.value),
432
- definition: lookup_attribute_documentation(oa.id),
433
- }
434
- end
436
+ uml_type = oa.uml_type
437
+ uml_type_idref = uml_type.idref if uml_type
438
+
439
+ if oa.association.nil?
440
+ {
441
+ id: oa.id,
442
+ name: oa.name,
443
+ type: lookup_entity_name(uml_type_idref) || uml_type_idref,
444
+ xmi_id: uml_type_idref,
445
+ is_derived: oa.is_derived,
446
+ cardinality: cardinality_min_max_value(
447
+ oa.lower_value&.value,
448
+ oa.upper_value&.value,
449
+ ),
450
+ definition: lookup_attribute_documentation(oa.id),
451
+ }
452
+ end
435
453
  end.compact
436
454
  end
437
455
 
@@ -441,7 +459,7 @@ module Lutaml
441
459
  def cardinality_min_max_value(min, max)
442
460
  {
443
461
  "min" => cardinality_value(min, true),
444
- "max" => cardinality_value(max, false)
462
+ "max" => cardinality_value(max, false),
445
463
  }
446
464
  end
447
465
 
@@ -451,7 +469,7 @@ module Lutaml
451
469
  def cardinality_value(value, is_min = false)
452
470
  return unless value
453
471
 
454
- is_min ? LOWER_VALUE_MAPPINGS[value] : value
472
+ is_min ? LOWER_VALUE_MAPPINGS[value.to_s] : value
455
473
  end
456
474
 
457
475
  # @node [Shale::Mapper]
@@ -523,12 +541,11 @@ module Lutaml
523
541
  # @return [Array<Xmi::Uml::PackagedElement>]
524
542
  def all_packaged_elements
525
543
  all_elements = []
526
- [
527
- @xmi_root_model.model.packaged_element +
544
+ packaged_element_roots = @xmi_root_model.model.packaged_element +
528
545
  @xmi_root_model.extension.primitive_types.packaged_element +
529
- @xmi_root_model.extension.profiles.profile
530
- .map {|p| p.packaged_element }
531
- ].flatten.each do |e|
546
+ @xmi_root_model.extension.profiles.profile.map(&:packaged_element)
547
+
548
+ packaged_element_roots.flatten.each do |e|
532
549
  select_all_packaged_elements(all_elements, e, nil)
533
550
  end
534
551
 
@@ -589,7 +606,7 @@ module Lutaml
589
606
  result[node.id] = node.name
590
607
  end
591
608
 
592
- attrs.each_pair do |k, v|
609
+ attrs.each_pair do |k, _v|
593
610
  map_id_name(result, node.send(k))
594
611
  end
595
612
  end
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.0"
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.8.1
4
+ version: 0.9.1
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-06-19 00:00:00.000000000 Z
11
+ date: 2024-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expressir
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: 0.3.0
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'
124
+ version: 0.3.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: byebug
127
127
  requirement: !ruby/object:Gem::Requirement