lutaml 0.10.13 → 0.10.14

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.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +58 -18
  3. data/lib/lutaml/cli/interactive_shell/export_handler.rb +9 -7
  4. data/lib/lutaml/cli/interactive_shell/help_display.rb +39 -45
  5. data/lib/lutaml/cli/interactive_shell/navigation_commands.rb +36 -21
  6. data/lib/lutaml/cli/interactive_shell/query_commands.rb +63 -47
  7. data/lib/lutaml/cli/interactive_shell.rb +43 -25
  8. data/lib/lutaml/qea/factory/association_builder.rb +114 -125
  9. data/lib/lutaml/qea/factory/class_transformer.rb +67 -43
  10. data/lib/lutaml/qea/factory/enum_transformer.rb +22 -23
  11. data/lib/lutaml/qea/factory/generalization_builder.rb +146 -116
  12. data/lib/lutaml/qea/factory/stereotype_loader.rb +13 -7
  13. data/lib/lutaml/qea/lookup_indexes.rb +8 -1
  14. data/lib/lutaml/uml_repository/exporters/markdown/class_page_builder.rb +33 -25
  15. data/lib/lutaml/uml_repository/index_builders/association_index.rb +49 -47
  16. data/lib/lutaml/uml_repository/index_builders/class_index.rb +30 -23
  17. data/lib/lutaml/uml_repository/queries/class_query.rb +74 -48
  18. data/lib/lutaml/uml_repository/queries/inheritance_query.rb +42 -32
  19. data/lib/lutaml/uml_repository/static_site/data_transformer.rb +55 -35
  20. data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +32 -19
  21. data/lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb +27 -17
  22. data/lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb +92 -68
  23. data/lib/lutaml/uml_repository/static_site/serializers/package_tree_builder.rb +32 -23
  24. data/lib/lutaml/version.rb +1 -1
  25. metadata +1 -1
@@ -22,17 +22,8 @@ module Lutaml
22
22
  end
23
23
 
24
24
  def find_generalizations(klass)
25
- parent_xmi_ids = @generalization_map[klass.xmi_id]
26
-
27
- if parent_xmi_ids && !parent_xmi_ids.empty?
28
- parents = parent_xmi_ids.filter_map do |parent_xmi_id|
29
- next if parent_xmi_id == klass.xmi_id
30
-
31
- parent = class_lookup.by_xmi_id(parent_xmi_id)
32
- parent ? @id_generator.class_id(parent) : nil
33
- end
34
- return parents unless parents.empty?
35
- end
25
+ map_parents = generalization_map_parents(klass)
26
+ return map_parents unless map_parents.nil?
36
27
 
37
28
  parent = @repository.supertype_of(klass)
38
29
  return [] if parent && parent.xmi_id == klass.xmi_id
@@ -66,22 +57,8 @@ module Lutaml
66
57
  break if visited.include?(parent_class.xmi_id)
67
58
 
68
59
  visited.add(parent_class.xmi_id)
69
-
70
- if parent_class.attributes
71
- sorted_attrs = parent_class.attributes.sort_by do |a|
72
- a.name || ""
73
- end
74
- sorted_attrs.each do |attr|
75
- attr_id = @id_generator.attribute_id(attr, parent_class)
76
- inherited << Models::SpaInheritedAttribute.new(
77
- attribute_id: attr_id,
78
- attribute: serialize_attribute(attr, parent_class, attr_id),
79
- inherited_from: @id_generator.class_id(parent_class),
80
- inherited_from_name: parent_class.name,
81
- parent_order: parent_order,
82
- )
83
- end
84
- end
60
+ inherited.concat(parent_inherited_attrs(parent_class,
61
+ parent_order))
85
62
 
86
63
  parent_order += 1
87
64
  current_gen = current_gen.general
@@ -108,33 +85,9 @@ module Lutaml
108
85
  break if visited.include?(parent_class.xmi_id)
109
86
 
110
87
  visited.add(parent_class.xmi_id)
111
- parent_associations = find_class_associations(parent_class)
112
-
113
- assoc_with_roles = parent_associations.filter_map do |assoc_id|
114
- assoc = @repository.associations_index.find do |a|
115
- @id_generator.association_id(a) == assoc_id
116
- end
117
- next unless assoc
118
-
119
- local_role = if assoc.owner_end_xmi_id == parent_class.xmi_id
120
- assoc.owner_end_attribute_name || assoc.owner_end || ""
121
- elsif assoc.member_end_xmi_id == parent_class.xmi_id
122
- assoc.member_end_attribute_name || assoc.member_end || ""
123
- else
124
- ""
125
- end
126
- { id: assoc_id, role: local_role }
127
- end
128
-
129
- assoc_with_roles.sort_by { |a| a[:role] }.each do |item|
130
- inherited << Models::SpaInheritedAssociation.new(
131
- association_id: item[:id],
132
- inherited_from: @id_generator.class_id(parent_class),
133
- inherited_from_name: parent_class.name,
134
- parent_order: parent_order,
135
- local_role: item[:role],
136
- )
137
- end
88
+ inherited.concat(
89
+ parent_inherited_assocs(parent_class, parent_order),
90
+ )
138
91
 
139
92
  parent_order += 1
140
93
  current_gen = current_gen.general
@@ -153,20 +106,7 @@ module Lutaml
153
106
  visited.add(klass.xmi_id)
154
107
  gen = klass.generalization
155
108
 
156
- {
157
- generalId: gen.general_id,
158
- generalName: gen.general_name,
159
- generalUpperKlass: gen.general_upper_klass,
160
- hasGeneral: gen.has_general,
161
- name: gen.name,
162
- type: gen.type,
163
- definition: format_definition(gen.definition),
164
- stereotype: gen.stereotype,
165
- ownedProps: serialize_general_collection(gen.owned_props),
166
- assocProps: serialize_general_collection(gen.assoc_props),
167
- inheritedProps: serialize_general_collection(gen.inherited_props),
168
- inheritedAssocProps: serialize_general_collection(gen.inherited_assoc_props),
169
- }
109
+ gen_basic_fields(gen).merge(gen_collection_fields(gen))
170
110
  rescue StandardError => e
171
111
  warn "Error serializing generalization: #{e.message}"
172
112
  nil
@@ -188,6 +128,68 @@ module Lutaml
188
128
 
189
129
  private
190
130
 
131
+ def generalization_map_parents(klass)
132
+ parent_xmi_ids = @generalization_map[klass.xmi_id]
133
+ return nil if parent_xmi_ids.nil? || parent_xmi_ids.empty?
134
+
135
+ parents = parent_xmi_ids.filter_map do |parent_xmi_id|
136
+ next if parent_xmi_id == klass.xmi_id
137
+
138
+ parent = class_lookup.by_xmi_id(parent_xmi_id)
139
+ parent ? @id_generator.class_id(parent) : nil
140
+ end
141
+ parents.empty? ? nil : parents
142
+ end
143
+
144
+ def parent_inherited_attrs(parent_class, parent_order)
145
+ return [] unless parent_class.attributes
146
+
147
+ parent_class.attributes.sort_by { |a| a.name || "" }
148
+ .map do |attr|
149
+ attr_id = @id_generator.attribute_id(attr, parent_class)
150
+ Models::SpaInheritedAttribute.new(
151
+ attribute_id: attr_id,
152
+ attribute: serialize_attribute(attr, parent_class, attr_id),
153
+ inherited_from: @id_generator.class_id(parent_class),
154
+ inherited_from_name: parent_class.name,
155
+ parent_order: parent_order,
156
+ )
157
+ end
158
+ end
159
+
160
+ def parent_inherited_assocs(parent_class, parent_order)
161
+ parent_associations = find_class_associations(parent_class)
162
+
163
+ assoc_with_roles = parent_associations.filter_map do |assoc_id|
164
+ assoc = @repository.associations_index.find do |a|
165
+ @id_generator.association_id(a) == assoc_id
166
+ end
167
+ next unless assoc
168
+
169
+ { id: assoc_id, role: resolve_local_role(assoc, parent_class) }
170
+ end
171
+
172
+ assoc_with_roles.sort_by { |a| a[:role] }.map do |item|
173
+ Models::SpaInheritedAssociation.new(
174
+ association_id: item[:id],
175
+ inherited_from: @id_generator.class_id(parent_class),
176
+ inherited_from_name: parent_class.name,
177
+ parent_order: parent_order,
178
+ local_role: item[:role],
179
+ )
180
+ end
181
+ end
182
+
183
+ def resolve_local_role(assoc, parent_class)
184
+ if assoc.owner_end_xmi_id == parent_class.xmi_id
185
+ assoc.owner_end_attribute_name || assoc.owner_end || ""
186
+ elsif assoc.member_end_xmi_id == parent_class.xmi_id
187
+ assoc.member_end_attribute_name || assoc.member_end || ""
188
+ else
189
+ ""
190
+ end
191
+ end
192
+
191
193
  def class_lookup
192
194
  @class_lookup ||= ClassLookupIndex.new(@repository.classes_index)
193
195
  end
@@ -231,6 +233,28 @@ module Lutaml
231
233
  )
232
234
  end
233
235
 
236
+ def gen_basic_fields(gen)
237
+ {
238
+ generalId: gen.general_id,
239
+ generalName: gen.general_name,
240
+ generalUpperKlass: gen.general_upper_klass,
241
+ hasGeneral: gen.has_general,
242
+ name: gen.name,
243
+ type: gen.type,
244
+ definition: format_definition(gen.definition),
245
+ stereotype: gen.stereotype,
246
+ }
247
+ end
248
+
249
+ def gen_collection_fields(gen)
250
+ {
251
+ ownedProps: serialize_general_collection(gen.owned_props),
252
+ assocProps: serialize_general_collection(gen.assoc_props),
253
+ inheritedProps: serialize_general_collection(gen.inherited_props),
254
+ inheritedAssocProps: serialize_general_collection(gen.inherited_assoc_props),
255
+ }
256
+ end
257
+
234
258
  def format_definition(definition)
235
259
  return nil if definition.nil? || definition.empty?
236
260
 
@@ -25,30 +25,27 @@ module Lutaml
25
25
  if root_packages.size == 1
26
26
  build_tree_node(root_packages.first)
27
27
  else
28
- Models::SpaPackageTreeNode.new(
29
- id: "root",
30
- name: "Model",
31
- path: "",
32
- class_count: 0,
33
- children: root_packages.map { |pkg| build_tree_node(pkg) },
34
- )
28
+ build_virtual_root(root_packages)
35
29
  end
36
30
  end
37
31
 
38
32
  private
39
33
 
34
+ def build_virtual_root(root_packages)
35
+ Models::SpaPackageTreeNode.new(
36
+ id: "root",
37
+ name: "Model",
38
+ path: "",
39
+ class_count: 0,
40
+ children: root_packages.map { |pkg| build_tree_node(pkg) },
41
+ )
42
+ end
43
+
40
44
  def build_tree_node(package)
41
45
  pkg_id = @id_generator.package_id(package)
42
-
43
- sorted_children = (package.packages || []).sort_by do |p|
44
- p.name || ""
45
- end
46
- sorted_classes = (package.classes || [])
47
- .reject { |c| c.name.nil? || c.name.empty? }
48
- .sort_by(&:name)
49
-
46
+ sorted_children = sort_by_name(package.packages || [])
47
+ sorted_classes = filter_valid_classes(package.classes || [])
50
48
  child_nodes = sorted_children.map { |child| build_tree_node(child) }
51
-
52
49
  total_class_count = sorted_classes.size + child_nodes.sum(&:class_count)
53
50
 
54
51
  Models::SpaPackageTreeNode.new(
@@ -57,17 +54,29 @@ module Lutaml
57
54
  path: package_path_for(package),
58
55
  stereotypes: normalize_stereotypes(package.stereotype),
59
56
  class_count: total_class_count,
60
- classes: sorted_classes.map do |c|
61
- Models::SpaTreeClassRef.new(
62
- id: @id_generator.class_id(c),
63
- name: c.name,
64
- stereotypes: normalize_stereotypes(c.stereotype),
65
- )
66
- end,
57
+ classes: build_class_refs(sorted_classes),
67
58
  children: child_nodes,
68
59
  )
69
60
  end
70
61
 
62
+ def sort_by_name(items)
63
+ items.sort_by { |p| p.name || "" }
64
+ end
65
+
66
+ def filter_valid_classes(classes)
67
+ classes.reject { |c| c.name.nil? || c.name.empty? }.sort_by(&:name)
68
+ end
69
+
70
+ def build_class_refs(classes)
71
+ classes.map do |c|
72
+ Models::SpaTreeClassRef.new(
73
+ id: @id_generator.class_id(c),
74
+ name: c.name,
75
+ stereotypes: normalize_stereotypes(c.stereotype),
76
+ )
77
+ end
78
+ end
79
+
71
80
  def package_path_for(package)
72
81
  return package.name unless package.namespace
73
82
  return package.name unless package.namespace.is_a?(Lutaml::Uml::Package)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lutaml
4
- VERSION = "0.10.13"
4
+ VERSION = "0.10.14"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.13
4
+ version: 0.10.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.