lutaml 0.10.10 → 0.10.11
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/.rubocop_todo.yml +6 -40
- data/lib/lutaml/cli/enhanced_formatter.rb +13 -22
- data/lib/lutaml/cli/interactive_shell/query_commands.rb +1 -1
- data/lib/lutaml/cli/output_formatter.rb +2 -2
- data/lib/lutaml/cli/tree_view_formatter.rb +4 -8
- data/lib/lutaml/cli/uml/build_command.rb +2 -3
- data/lib/lutaml/cli/uml/diagram_command.rb +10 -14
- data/lib/lutaml/cli/uml/find_command.rb +1 -1
- data/lib/lutaml/ea/diagram/configuration.rb +3 -3
- data/lib/lutaml/ea/diagram/style_resolver.rb +9 -17
- data/lib/lutaml/model_transformations/format_registry.rb +2 -2
- data/lib/lutaml/model_transformations/parsers/base_parser.rb +1 -1
- data/lib/lutaml/model_transformations/parsers/qea_parser.rb +3 -3
- data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +2 -2
- data/lib/lutaml/model_transformations/transformation_engine.rb +1 -1
- data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +2 -1
- data/lib/lutaml/qea/validation/base_validator.rb +4 -1
- data/lib/lutaml/qea/validation/validation_engine.rb +1 -5
- data/lib/lutaml/qea/verification/document_normalizer.rb +11 -11
- data/lib/lutaml/qea/verification/structure_matcher.rb +4 -4
- data/lib/lutaml/uml_repository/index_builders/association_index.rb +6 -6
- data/lib/lutaml/uml_repository/presenters/association_presenter.rb +3 -7
- data/lib/lutaml/uml_repository/presenters/attribute_presenter.rb +6 -10
- data/lib/lutaml/uml_repository/presenters/class_presenter.rb +1 -1
- data/lib/lutaml/uml_repository/presenters/datatype_presenter.rb +12 -20
- data/lib/lutaml/uml_repository/presenters/diagram_presenter.rb +32 -61
- data/lib/lutaml/uml_repository/presenters/element_presenter.rb +4 -5
- data/lib/lutaml/uml_repository/presenters/enum_presenter.rb +7 -9
- data/lib/lutaml/uml_repository/presenters/package_presenter.rb +5 -2
- data/lib/lutaml/uml_repository/queries/diagram_query.rb +1 -1
- data/lib/lutaml/uml_repository/queries/package_query.rb +4 -10
- data/lib/lutaml/uml_repository/queries/search_query.rb +2 -2
- data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +2 -1
- data/lib/lutaml/uml_repository/validators/repository_validator.rb +9 -9
- data/lib/lutaml/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60815cadb4a74fcb9fcdc3b84a3f6c19b450e5a6f1670d918ffd4d2e66d4a3a5
|
|
4
|
+
data.tar.gz: 2e24af4ab233104a171c7cac58a7416e79e5248ce61831d45ba930e44d14685b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ebc0be5174ba5dafb1fbda8aa962936d9c8de3b3d909d66844a83f35cf0f353c8131af4d45f945cdd1e9bfdf4975a52b09bbe17a18cf09eae571cc5eb297a83
|
|
7
|
+
data.tar.gz: e41165b1694af4e86a4b2373643ec94d6bc6c0a84310c2573ba001ad5dbc278917ba796f9e2a95174fdd1b12607fb68b4fbd487f46032b2a92b8850ff301d3ae
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,45 +1,18 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-05-11
|
|
3
|
+
# on 2026-05-11 09:50:12 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
# Configuration parameters: IndentationWidth.
|
|
12
|
-
Layout/AssignmentIndentation:
|
|
13
|
-
Exclude:
|
|
14
|
-
- 'lib/lutaml/ea/diagram/style_resolver.rb'
|
|
15
|
-
|
|
16
|
-
# Offense count: 1
|
|
17
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
18
|
-
# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, DefLikeMacros, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
|
|
19
|
-
Layout/EmptyLineBetweenDefs:
|
|
20
|
-
Exclude:
|
|
21
|
-
- 'lib/lutaml/ea/diagram/style_parser.rb'
|
|
22
|
-
|
|
23
|
-
# Offense count: 1
|
|
24
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
25
|
-
Layout/EmptyLines:
|
|
26
|
-
Exclude:
|
|
27
|
-
- 'lib/lutaml/ea/diagram/style_parser.rb'
|
|
28
|
-
|
|
29
|
-
# Offense count: 159
|
|
9
|
+
# Offense count: 154
|
|
30
10
|
# This cop supports safe autocorrection (--autocorrect).
|
|
31
11
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
32
12
|
# URISchemes: http, https
|
|
33
13
|
Layout/LineLength:
|
|
34
14
|
Enabled: false
|
|
35
15
|
|
|
36
|
-
# Offense count: 1
|
|
37
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
38
|
-
# Configuration parameters: AllowInHeredoc.
|
|
39
|
-
Layout/TrailingWhitespace:
|
|
40
|
-
Exclude:
|
|
41
|
-
- 'lib/lutaml/ea/diagram/style_resolver.rb'
|
|
42
|
-
|
|
43
16
|
# Offense count: 1
|
|
44
17
|
Lint/BinaryOperatorWithIdenticalOperands:
|
|
45
18
|
Exclude:
|
|
@@ -115,7 +88,7 @@ Metrics/AbcSize:
|
|
|
115
88
|
Metrics/BlockLength:
|
|
116
89
|
Max: 53
|
|
117
90
|
|
|
118
|
-
# Offense count:
|
|
91
|
+
# Offense count: 35
|
|
119
92
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
120
93
|
Metrics/CyclomaticComplexity:
|
|
121
94
|
Enabled: false
|
|
@@ -125,7 +98,7 @@ Metrics/CyclomaticComplexity:
|
|
|
125
98
|
Metrics/MethodLength:
|
|
126
99
|
Max: 62
|
|
127
100
|
|
|
128
|
-
# Offense count:
|
|
101
|
+
# Offense count: 26
|
|
129
102
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
130
103
|
Metrics/PerceivedComplexity:
|
|
131
104
|
Enabled: false
|
|
@@ -253,12 +226,12 @@ RSpec/MessageSpies:
|
|
|
253
226
|
RSpec/MultipleExpectations:
|
|
254
227
|
Max: 7
|
|
255
228
|
|
|
256
|
-
# Offense count:
|
|
229
|
+
# Offense count: 149
|
|
257
230
|
# Configuration parameters: AllowSubject.
|
|
258
231
|
RSpec/MultipleMemoizedHelpers:
|
|
259
232
|
Max: 11
|
|
260
233
|
|
|
261
|
-
# Offense count:
|
|
234
|
+
# Offense count: 33
|
|
262
235
|
# Configuration parameters: AllowedGroups.
|
|
263
236
|
RSpec/NestedGroups:
|
|
264
237
|
Max: 4
|
|
@@ -334,10 +307,3 @@ Style/SafeNavigationChainLength:
|
|
|
334
307
|
Exclude:
|
|
335
308
|
- 'lib/lutaml/qea/validation/attribute_validator.rb'
|
|
336
309
|
- 'lib/lutaml/qea/validation/operation_validator.rb'
|
|
337
|
-
|
|
338
|
-
# Offense count: 3
|
|
339
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
340
|
-
# Configuration parameters: AllowSend.
|
|
341
|
-
Style/SendWithLiteralMethodName:
|
|
342
|
-
Exclude:
|
|
343
|
-
- 'lib/lutaml/ea/diagram/style_resolver.rb'
|
|
@@ -125,7 +125,7 @@ module Lutaml
|
|
|
125
125
|
# @param klass [Object] Class object to display
|
|
126
126
|
# @param path_formatter [Proc] Formatter for package paths
|
|
127
127
|
# @return [String] Enhanced class details
|
|
128
|
-
def self.format_class_details_enhanced(klass,
|
|
128
|
+
def self.format_class_details_enhanced(klass, _path_formatter = nil) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
129
129
|
lines = []
|
|
130
130
|
|
|
131
131
|
# Header box
|
|
@@ -137,25 +137,21 @@ module Lutaml
|
|
|
137
137
|
|
|
138
138
|
# Basic information
|
|
139
139
|
lines << colorize("Basic Information:", :cyan)
|
|
140
|
-
if klass.
|
|
140
|
+
if klass.is_a?(Lutaml::Uml::TopElement) && klass.xmi_id
|
|
141
141
|
lines << " XMI ID: #{klass.xmi_id}"
|
|
142
142
|
end
|
|
143
|
-
if klass.
|
|
143
|
+
if klass.is_a?(Lutaml::Uml::TopElement) && klass.stereotype && !klass.stereotype.empty?
|
|
144
144
|
st = klass.stereotype
|
|
145
145
|
st_str = st.is_a?(Array) ? st.join(", ") : st
|
|
146
146
|
lines << " Stereotype: #{st_str}"
|
|
147
147
|
end
|
|
148
|
-
if klass.
|
|
148
|
+
if klass.is_a?(Lutaml::Uml::Classifier)
|
|
149
149
|
lines << " Abstract: #{klass.is_abstract ? 'Yes' : 'No'}"
|
|
150
150
|
end
|
|
151
|
-
if path_formatter && klass.respond_to?(:package)
|
|
152
|
-
package_path = path_formatter.call(klass.package)
|
|
153
|
-
lines << " Package: #{ICONS[:package]} #{package_path}"
|
|
154
|
-
end
|
|
155
151
|
lines << ""
|
|
156
152
|
|
|
157
153
|
# Attributes
|
|
158
|
-
if klass.
|
|
154
|
+
if klass.is_a?(Lutaml::Uml::Classifier) && klass.attributes &&
|
|
159
155
|
!klass.attributes.empty?
|
|
160
156
|
lines << colorize(
|
|
161
157
|
"#{ICONS[:attribute]} Attributes (#{klass.attributes.size}):",
|
|
@@ -173,21 +169,21 @@ module Lutaml
|
|
|
173
169
|
end
|
|
174
170
|
|
|
175
171
|
# Operations
|
|
176
|
-
if klass.
|
|
172
|
+
if klass.is_a?(Lutaml::Uml::Classifier) && klass.operations &&
|
|
177
173
|
!klass.operations.empty?
|
|
178
174
|
lines << colorize(
|
|
179
175
|
"#{ICONS[:operation]} Operations (#{klass.operations.size}):",
|
|
180
176
|
:yellow,
|
|
181
177
|
)
|
|
182
178
|
klass.operations.each do |op|
|
|
183
|
-
params = if op.
|
|
184
|
-
op.
|
|
179
|
+
params = if op.owned_parameter
|
|
180
|
+
op.owned_parameter.map do |p|
|
|
185
181
|
"#{p.name}: #{p.type}"
|
|
186
182
|
end.join(", ")
|
|
187
183
|
else
|
|
188
184
|
""
|
|
189
185
|
end
|
|
190
|
-
return_type = if op.
|
|
186
|
+
return_type = if op.return_type
|
|
191
187
|
" : #{op.return_type}"
|
|
192
188
|
else
|
|
193
189
|
""
|
|
@@ -486,18 +482,13 @@ module Lutaml
|
|
|
486
482
|
#
|
|
487
483
|
# @param attr [Object] Attribute with cardinality
|
|
488
484
|
# @return [String] Formatted cardinality
|
|
489
|
-
def self.format_cardinality(attr)
|
|
490
|
-
return "" unless attr.respond_to?(:cardinality)
|
|
485
|
+
def self.format_cardinality(attr)
|
|
491
486
|
return "" unless attr.cardinality
|
|
492
487
|
|
|
493
488
|
card = attr.cardinality
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
"[#{min}..#{max}]"
|
|
498
|
-
else
|
|
499
|
-
""
|
|
500
|
-
end
|
|
489
|
+
min = card.min || "0"
|
|
490
|
+
max = card.max || "*"
|
|
491
|
+
"[#{min}..#{max}]"
|
|
501
492
|
end
|
|
502
493
|
end
|
|
503
494
|
end
|
|
@@ -99,7 +99,7 @@ module Lutaml
|
|
|
99
99
|
puts ""
|
|
100
100
|
puts "Name: #{cls.name}"
|
|
101
101
|
|
|
102
|
-
if cls.
|
|
102
|
+
if cls.is_a?(Lutaml::Uml::Classifier) && cls.attributes && !cls.attributes.empty?
|
|
103
103
|
puts ""
|
|
104
104
|
puts OutputFormatter.colorize("Attributes:", :yellow)
|
|
105
105
|
cls.attributes.each do |attr|
|
|
@@ -69,7 +69,7 @@ module Lutaml
|
|
|
69
69
|
data
|
|
70
70
|
else
|
|
71
71
|
# For complex objects, convert to string representation
|
|
72
|
-
data.
|
|
72
|
+
data.is_a?(Lutaml::Uml::TopElement) ? data.name : data.to_s
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -271,7 +271,7 @@ module Lutaml
|
|
|
271
271
|
stats[:most_complex_classes].first(5).each do |item|
|
|
272
272
|
klass = item[:class]
|
|
273
273
|
complexity = item[:complexity]
|
|
274
|
-
class_name = klass
|
|
274
|
+
class_name = klass&.name || klass.to_s
|
|
275
275
|
|
|
276
276
|
lines << " #{class_name} (complexity: #{complexity})"
|
|
277
277
|
end
|
|
@@ -163,7 +163,7 @@ module Lutaml
|
|
|
163
163
|
children = []
|
|
164
164
|
|
|
165
165
|
# Add attributes
|
|
166
|
-
if @show_attributes && klass.
|
|
166
|
+
if @show_attributes && klass.is_a?(Lutaml::Uml::Classifier) &&
|
|
167
167
|
klass.attributes
|
|
168
168
|
children.concat(klass.attributes.map do |a|
|
|
169
169
|
{ type: :attribute, obj: a }
|
|
@@ -171,7 +171,7 @@ module Lutaml
|
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
# Add operations
|
|
174
|
-
if @show_operations && klass.
|
|
174
|
+
if @show_operations && klass.is_a?(Lutaml::Uml::Classifier) &&
|
|
175
175
|
klass.operations
|
|
176
176
|
children.concat(klass.operations.map do |o|
|
|
177
177
|
{ type: :operation, obj: o }
|
|
@@ -239,11 +239,7 @@ module Lutaml
|
|
|
239
239
|
return "" if @max_depth && depth >= @max_depth
|
|
240
240
|
|
|
241
241
|
assoc_name = assoc.name || "(unnamed)"
|
|
242
|
-
target =
|
|
243
|
-
assoc.member_end.first.xmi_type || "Unknown"
|
|
244
|
-
else
|
|
245
|
-
"Unknown"
|
|
246
|
-
end
|
|
242
|
+
target = assoc.member_end || "Unknown"
|
|
247
243
|
|
|
248
244
|
connector = is_last ? TREE_CHARS[:last_branch] : TREE_CHARS[:branch]
|
|
249
245
|
icon = ICONS[:association]
|
|
@@ -280,7 +276,7 @@ module Lutaml
|
|
|
280
276
|
# Determine class type (class, interface, enumeration)
|
|
281
277
|
def determine_class_type(klass)
|
|
282
278
|
return :enumeration if klass.class.name&.include?("Enum")
|
|
283
|
-
return :interface if klass.
|
|
279
|
+
return :interface if klass.is_a?(Lutaml::Uml::TopElement) &&
|
|
284
280
|
Array(klass.stereotype).any? { |s| s&.downcase == "interface" }
|
|
285
281
|
|
|
286
282
|
:class
|
|
@@ -141,7 +141,7 @@ module Lutaml
|
|
|
141
141
|
OutputFormatter.progress_done
|
|
142
142
|
|
|
143
143
|
# Display verbose validation if requested
|
|
144
|
-
if options[:verbose] && result.
|
|
144
|
+
if options[:verbose] && result.validation_details
|
|
145
145
|
display_verbose_validation(result.validation_details)
|
|
146
146
|
end
|
|
147
147
|
|
|
@@ -149,8 +149,7 @@ module Lutaml
|
|
|
149
149
|
handle_validation_result(result)
|
|
150
150
|
|
|
151
151
|
# Display unique unresolved types if present
|
|
152
|
-
if result.
|
|
153
|
-
result.external_references.any?
|
|
152
|
+
if result.external_references&.any?
|
|
154
153
|
display_unresolved_types(result.external_references)
|
|
155
154
|
end
|
|
156
155
|
|
|
@@ -83,12 +83,12 @@ module Lutaml
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
# Add stereotype if available
|
|
86
|
-
if uml_element.
|
|
86
|
+
if uml_element.is_a?(Lutaml::Uml::TopElement) && uml_element.stereotype && !uml_element.stereotype.empty?
|
|
87
87
|
element_data[:stereotype] = uml_element.stereotype.first
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# Add attributes and operations for classes
|
|
91
|
-
if uml_element.
|
|
91
|
+
if uml_element.is_a?(Lutaml::Uml::Classifier) && uml_element.attributes
|
|
92
92
|
element_data[:attributes] = uml_element.attributes.map do |attr|
|
|
93
93
|
{
|
|
94
94
|
name: attr.name,
|
|
@@ -98,7 +98,7 @@ module Lutaml
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
if uml_element.
|
|
101
|
+
if uml_element.is_a?(Lutaml::Uml::Classifier) && uml_element.operations
|
|
102
102
|
element_data[:operations] = uml_element.operations.map do |op|
|
|
103
103
|
{
|
|
104
104
|
name: op.name,
|
|
@@ -131,30 +131,30 @@ module Lutaml
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
# Add role and multiplicity information if available
|
|
134
|
-
if connector.
|
|
134
|
+
if connector.is_a?(Lutaml::Uml::Association) &&
|
|
135
135
|
connector.owner_end_attribute_name
|
|
136
136
|
connector_data[:source_role] = connector.owner_end_attribute_name
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
if connector.
|
|
139
|
+
if connector.is_a?(Lutaml::Uml::Association) &&
|
|
140
140
|
connector.member_end_attribute_name
|
|
141
141
|
connector_data[:target_role] = connector.member_end_attribute_name
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
if connector.
|
|
144
|
+
if connector.is_a?(Lutaml::Uml::Association) &&
|
|
145
145
|
connector.owner_end_cardinality
|
|
146
146
|
connector_data[:source_multiplicity] =
|
|
147
147
|
format_cardinality(connector.owner_end_cardinality)
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
if connector.
|
|
150
|
+
if connector.is_a?(Lutaml::Uml::Association) &&
|
|
151
151
|
connector.member_end_cardinality
|
|
152
152
|
connector_data[:target_multiplicity] =
|
|
153
153
|
format_cardinality(connector.member_end_cardinality)
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
# Add source and target information if available
|
|
157
|
-
if connector.
|
|
157
|
+
if connector.is_a?(Lutaml::Uml::Association) && connector.owner_end
|
|
158
158
|
source_obj = find_diagram_object_for_element(
|
|
159
159
|
connector.source.xmi_id, diagram
|
|
160
160
|
)
|
|
@@ -166,7 +166,7 @@ module Lutaml
|
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
-
if connector.
|
|
169
|
+
if connector.is_a?(Lutaml::Uml::Association) && connector.member_end
|
|
170
170
|
target_obj = find_diagram_object_for_element(
|
|
171
171
|
connector.target.xmi_id, diagram
|
|
172
172
|
)
|
|
@@ -405,11 +405,7 @@ module Lutaml
|
|
|
405
405
|
def format_cardinality(cardinality)
|
|
406
406
|
return "" unless cardinality
|
|
407
407
|
|
|
408
|
-
|
|
409
|
-
cardinality.to_s
|
|
410
|
-
else
|
|
411
|
-
""
|
|
412
|
-
end
|
|
408
|
+
cardinality.to_s
|
|
413
409
|
end
|
|
414
410
|
end
|
|
415
411
|
end
|
|
@@ -47,14 +47,14 @@ module Lutaml
|
|
|
47
47
|
value = nil
|
|
48
48
|
|
|
49
49
|
# 1. Try class-specific override (highest priority)
|
|
50
|
-
if element.
|
|
50
|
+
if element.is_a?(Lutaml::Uml::TopElement) && element.name
|
|
51
51
|
class_config = dig_config("classes.#{element.name}.#{property}")
|
|
52
52
|
value = class_config if class_config
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# 2. Try package-based styling
|
|
56
56
|
if !value &&
|
|
57
|
-
element.
|
|
57
|
+
element.is_a?(Lutaml::Uml::Diagram) && element.package_name
|
|
58
58
|
# Support wildcards: "CityGML::*"
|
|
59
59
|
package_configs = config_data["packages"] || {}
|
|
60
60
|
package_configs.each do |pattern, pkg_config|
|
|
@@ -67,7 +67,7 @@ module Lutaml
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
# 3. Try stereotype-based styling
|
|
70
|
-
if !value && element.
|
|
70
|
+
if !value && element.is_a?(Lutaml::Uml::TopElement) && element.stereotype
|
|
71
71
|
stereotypes = Array(element.stereotype)
|
|
72
72
|
stereotypes.each do |stereo|
|
|
73
73
|
stereo_value = dig_config("stereotypes.#{stereo}.#{property}")
|
|
@@ -264,23 +264,15 @@ module Lutaml
|
|
|
264
264
|
#
|
|
265
265
|
# @param connector [Object] Association connector
|
|
266
266
|
# @return [String] Specific association type
|
|
267
|
-
def determine_association_type(connector)
|
|
268
|
-
return "association" unless connector.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
member_ends.each do |end_point|
|
|
277
|
-
if end_point.respond_to?(:aggregation)
|
|
278
|
-
case end_point.aggregation&.downcase
|
|
279
|
-
when "shared"
|
|
280
|
-
return "aggregation"
|
|
281
|
-
when "composite"
|
|
282
|
-
return "composition"
|
|
283
|
-
end
|
|
267
|
+
def determine_association_type(connector)
|
|
268
|
+
return "association" unless connector.is_a?(Lutaml::Uml::Association)
|
|
269
|
+
|
|
270
|
+
[connector.owner_end_type, connector.member_end_type].each do |type|
|
|
271
|
+
case type&.downcase
|
|
272
|
+
when "aggregation"
|
|
273
|
+
return "aggregation"
|
|
274
|
+
when "composition"
|
|
275
|
+
return "composition"
|
|
284
276
|
end
|
|
285
277
|
end
|
|
286
278
|
|
|
@@ -63,7 +63,7 @@ module Lutaml
|
|
|
63
63
|
# @return [void]
|
|
64
64
|
def auto_register_from_parser(parser_class)
|
|
65
65
|
supported_extensions = ""
|
|
66
|
-
if parser_class.
|
|
66
|
+
if parser_class.method_defined?(:supported_extensions)
|
|
67
67
|
supported_extensions = parser_class.new.supported_extensions
|
|
68
68
|
end
|
|
69
69
|
register(supported_extensions, parser_class)
|
|
@@ -255,7 +255,7 @@ module Lutaml
|
|
|
255
255
|
|
|
256
256
|
# Check header match for content patterns
|
|
257
257
|
@parsers.each do |ext, parser_class|
|
|
258
|
-
if parser_class.
|
|
258
|
+
if parser_class.method_defined?(:content_patterns)
|
|
259
259
|
parser_klass = parser_class.new
|
|
260
260
|
parser_klass.content_patterns.each do |pattern|
|
|
261
261
|
if header.match?(pattern)
|
|
@@ -107,7 +107,7 @@ module Lutaml
|
|
|
107
107
|
extension = File.extname(file_path).downcase
|
|
108
108
|
return true if supported_extensions.include?(extension)
|
|
109
109
|
|
|
110
|
-
if
|
|
110
|
+
if self.class.method_defined?(:content_patterns) && File.exist?(file_path)
|
|
111
111
|
File.open(file_path, "rb") do |file|
|
|
112
112
|
header = file.read(1024) # Read first 1KB
|
|
113
113
|
return false if header.nil? || header.empty?
|
|
@@ -269,16 +269,16 @@ module Lutaml
|
|
|
269
269
|
# @return [void]
|
|
270
270
|
def post_process_qea_document(document, file_path)
|
|
271
271
|
# Set QEA-specific source information
|
|
272
|
-
if document.
|
|
272
|
+
if document.class.method_defined?(:source_file=)
|
|
273
273
|
document.source_file = file_path
|
|
274
274
|
end
|
|
275
275
|
|
|
276
|
-
if document.
|
|
276
|
+
if document.class.method_defined?(:source_format=)
|
|
277
277
|
document.source_format = "QEA"
|
|
278
278
|
end
|
|
279
279
|
|
|
280
280
|
# Store database statistics
|
|
281
|
-
if document.
|
|
281
|
+
if document.class.method_defined?(:database_stats=)
|
|
282
282
|
document.database_stats = @database_stats
|
|
283
283
|
end
|
|
284
284
|
end
|
|
@@ -138,12 +138,12 @@ module Lutaml
|
|
|
138
138
|
# @return [void]
|
|
139
139
|
def post_process_xmi_document(document, file_path)
|
|
140
140
|
# Set source file information
|
|
141
|
-
if document.
|
|
141
|
+
if document.class.method_defined?(:source_file=)
|
|
142
142
|
document.source_file = file_path
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
# Add timestamp
|
|
146
|
-
if document.
|
|
146
|
+
if document.class.method_defined?(:parsed_at=)
|
|
147
147
|
document.parsed_at = Time.now
|
|
148
148
|
end
|
|
149
149
|
|
|
@@ -256,7 +256,7 @@ module Lutaml
|
|
|
256
256
|
@format_registry.all_parsers.each_value do |parser_class|
|
|
257
257
|
# Try to create instance to validate
|
|
258
258
|
parser = parser_class.new(configuration: @configuration)
|
|
259
|
-
if parser.
|
|
259
|
+
if parser.class.method_defined?(:parse)
|
|
260
260
|
results[:parsers_loaded] += 1
|
|
261
261
|
else
|
|
262
262
|
results[:parser_errors] << "Parser #{parser_class} does not " \
|
|
@@ -244,7 +244,8 @@ module Lutaml
|
|
|
244
244
|
def collect_package_associations(package, associations) # rubocop:disable Metrics/CyclomaticComplexity
|
|
245
245
|
# Collect from classes in this package
|
|
246
246
|
package.classes&.each do |klass|
|
|
247
|
-
if klass.
|
|
247
|
+
if (klass.is_a?(Lutaml::Uml::Class) ||
|
|
248
|
+
klass.is_a?(Lutaml::Uml::DataType)) && klass.associations
|
|
248
249
|
associations.concat(klass.associations)
|
|
249
250
|
end
|
|
250
251
|
end
|
|
@@ -209,7 +209,10 @@ module Lutaml
|
|
|
209
209
|
# @param value [Object] Value to check
|
|
210
210
|
# @return [Boolean]
|
|
211
211
|
def present?(value)
|
|
212
|
-
|
|
212
|
+
return false if value.nil?
|
|
213
|
+
return !value.empty? if value.is_a?(String) || value.is_a?(Array)
|
|
214
|
+
|
|
215
|
+
true
|
|
213
216
|
end
|
|
214
217
|
|
|
215
218
|
# Finds entity name from database
|
|
@@ -223,11 +223,7 @@ module Lutaml
|
|
|
223
223
|
# Note: Use document entities for primary validation
|
|
224
224
|
if @database
|
|
225
225
|
context[:db_packages] = @database.packages || []
|
|
226
|
-
context[:db_objects] =
|
|
227
|
-
@database.objects.all
|
|
228
|
-
else
|
|
229
|
-
@database.objects || []
|
|
230
|
-
end
|
|
226
|
+
context[:db_objects] = @database.objects.all
|
|
231
227
|
context[:attributes] = @database.attributes || []
|
|
232
228
|
context[:operations] = @database.operations || []
|
|
233
229
|
context[:connectors] = @database.connectors || []
|
|
@@ -73,7 +73,7 @@ module Lutaml
|
|
|
73
73
|
# Process packages recursively to remove XMI IDs
|
|
74
74
|
def process_packages(packages) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
|
75
75
|
packages.each do |package|
|
|
76
|
-
package.xmi_id = nil
|
|
76
|
+
package.xmi_id = nil
|
|
77
77
|
process_classes(package.classes) if package.classes
|
|
78
78
|
process_enums(package.enums) if package.enums
|
|
79
79
|
process_data_types(package.data_types) if package.data_types
|
|
@@ -84,23 +84,23 @@ module Lutaml
|
|
|
84
84
|
# Process classes to remove XMI IDs
|
|
85
85
|
def process_classes(classes) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
86
86
|
classes.each do |klass|
|
|
87
|
-
klass.xmi_id = nil
|
|
87
|
+
klass.xmi_id = nil
|
|
88
88
|
|
|
89
89
|
# Remove XMI IDs from attributes
|
|
90
90
|
klass.attributes&.each do |attr|
|
|
91
|
-
attr.xmi_id = nil
|
|
91
|
+
attr.xmi_id = nil
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
# Remove XMI IDs from operations
|
|
95
95
|
klass.operations&.each do |op|
|
|
96
|
-
op.xmi_id = nil
|
|
96
|
+
op.xmi_id = nil
|
|
97
97
|
op.parameters&.each do |param|
|
|
98
|
-
param.xmi_id = nil if param.
|
|
98
|
+
param.xmi_id = nil if param.class.attributes.key?(:xmi_id)
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
# Process nested classes
|
|
103
|
-
if klass.
|
|
103
|
+
if klass.is_a?(Lutaml::Uml::Package) && klass.classes
|
|
104
104
|
process_classes(klass.classes)
|
|
105
105
|
end
|
|
106
106
|
end
|
|
@@ -109,11 +109,11 @@ module Lutaml
|
|
|
109
109
|
# Process associations to remove XMI IDs
|
|
110
110
|
def process_associations(associations)
|
|
111
111
|
associations.each do |assoc|
|
|
112
|
-
assoc.xmi_id = nil
|
|
113
|
-
if assoc.
|
|
112
|
+
assoc.xmi_id = nil
|
|
113
|
+
if assoc.owner_end_xmi_id
|
|
114
114
|
assoc.owner_end_xmi_id = nil
|
|
115
115
|
end
|
|
116
|
-
if assoc.
|
|
116
|
+
if assoc.member_end_xmi_id
|
|
117
117
|
assoc.member_end_xmi_id = nil
|
|
118
118
|
end
|
|
119
119
|
end
|
|
@@ -122,14 +122,14 @@ module Lutaml
|
|
|
122
122
|
# Process enums to remove XMI IDs
|
|
123
123
|
def process_enums(enums)
|
|
124
124
|
enums.each do |enum|
|
|
125
|
-
enum.xmi_id = nil
|
|
125
|
+
enum.xmi_id = nil
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# Process data types to remove XMI IDs
|
|
130
130
|
def process_data_types(data_types)
|
|
131
131
|
data_types.each do |dt|
|
|
132
|
-
dt.xmi_id = nil
|
|
132
|
+
dt.xmi_id = nil
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
|
|
@@ -222,7 +222,7 @@ module Lutaml
|
|
|
222
222
|
def index_by_name(collection)
|
|
223
223
|
index = {}
|
|
224
224
|
collection.each do |element|
|
|
225
|
-
next unless element.
|
|
225
|
+
next unless element.name
|
|
226
226
|
|
|
227
227
|
index[element.name] = element
|
|
228
228
|
end
|
|
@@ -243,10 +243,10 @@ module Lutaml
|
|
|
243
243
|
|
|
244
244
|
# Build operation signature for matching
|
|
245
245
|
def build_operation_signature(operation)
|
|
246
|
-
return operation.name unless operation.
|
|
246
|
+
return operation.name unless operation.owned_parameter
|
|
247
247
|
|
|
248
|
-
param_types =
|
|
249
|
-
param.
|
|
248
|
+
param_types = operation.owned_parameter.map do |param|
|
|
249
|
+
param.type || "unknown"
|
|
250
250
|
end.join(",")
|
|
251
251
|
|
|
252
252
|
"#{operation.name}(#{param_types})"
|
|
@@ -14,7 +14,7 @@ module Lutaml
|
|
|
14
14
|
# Collect class-level associations (QEA/EA format)
|
|
15
15
|
# Note: This requires qualified_names index to be built first
|
|
16
16
|
@qualified_names.each_value do |klass|
|
|
17
|
-
next unless klass.
|
|
17
|
+
next unless (klass.is_a?(Lutaml::Uml::Class) || klass.is_a?(Lutaml::Uml::DataType)) && klass.associations
|
|
18
18
|
|
|
19
19
|
klass.associations.each do |assoc|
|
|
20
20
|
next unless assoc.xmi_id
|
|
@@ -73,13 +73,13 @@ module Lutaml
|
|
|
73
73
|
next unless klass.associations
|
|
74
74
|
|
|
75
75
|
klass.associations.each do |assoc|
|
|
76
|
-
next unless assoc.
|
|
76
|
+
next unless assoc.member_end_type
|
|
77
77
|
next unless assoc.member_end_type == "inheritance"
|
|
78
78
|
|
|
79
79
|
parent_name = assoc.member_end
|
|
80
80
|
next unless parent_name
|
|
81
81
|
|
|
82
|
-
parent_name = parent_name.name if parent_name.
|
|
82
|
+
parent_name = parent_name.name if parent_name.is_a?(Lutaml::Uml::Generalization)
|
|
83
83
|
next unless parent_name.is_a?(String) && !parent_name.empty?
|
|
84
84
|
|
|
85
85
|
parent_qname = resolve_qualified_name(parent_name, package_path)
|
|
@@ -101,14 +101,14 @@ module Lutaml
|
|
|
101
101
|
return nil unless generalization
|
|
102
102
|
|
|
103
103
|
# Check for general attribute (could be a string or object)
|
|
104
|
-
if generalization.
|
|
104
|
+
if generalization.general
|
|
105
105
|
parent = generalization.general
|
|
106
|
-
return parent.name if parent
|
|
106
|
+
return parent.name if parent
|
|
107
107
|
return parent.to_s if parent
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
# Check for name attribute directly
|
|
111
|
-
if generalization.
|
|
111
|
+
if generalization.name
|
|
112
112
|
return generalization.name
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -20,12 +20,9 @@ module Lutaml
|
|
|
20
20
|
lines << ("=" * 50)
|
|
21
21
|
lines << ""
|
|
22
22
|
lines << "Name: #{element.name || '(unnamed)'}"
|
|
23
|
-
if element.
|
|
23
|
+
if element.xmi_id
|
|
24
24
|
lines << "XMI ID: #{element.xmi_id}"
|
|
25
25
|
end
|
|
26
|
-
if element.respond_to?(:xmi_type)
|
|
27
|
-
lines << "Type: #{element.xmi_type}"
|
|
28
|
-
end
|
|
29
26
|
lines << ""
|
|
30
27
|
lines << "Source: #{source_display}"
|
|
31
28
|
lines << "Target: #{target_display}"
|
|
@@ -48,8 +45,7 @@ module Lutaml
|
|
|
48
45
|
target: target_display,
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
data[:xmi_id] = element.xmi_id if element.
|
|
52
|
-
data[:xmi_type] = element.xmi_type if element.respond_to?(:xmi_type)
|
|
48
|
+
data[:xmi_id] = element.xmi_id if element.xmi_id
|
|
53
49
|
|
|
54
50
|
data
|
|
55
51
|
end
|
|
@@ -66,7 +62,7 @@ module Lutaml
|
|
|
66
62
|
# then symbol key (from show command)
|
|
67
63
|
if @context["target"] || @context[:target]
|
|
68
64
|
@context["target"] || @context[:target]
|
|
69
|
-
elsif element.
|
|
65
|
+
elsif element.member_end
|
|
70
66
|
member_end = element.member_end.first
|
|
71
67
|
if member_end.is_a?(Hash)
|
|
72
68
|
member_end[:xmi_type] || "Unknown"
|
|
@@ -24,15 +24,13 @@ module Lutaml
|
|
|
24
24
|
lines << "Class: #{class_name}"
|
|
25
25
|
lines << "Type: #{element.type || 'Unknown'}"
|
|
26
26
|
lines << "Cardinality: #{format_cardinality(element)}"
|
|
27
|
-
if element.
|
|
27
|
+
if element.visibility
|
|
28
28
|
lines << "Visibility: #{element.visibility}"
|
|
29
29
|
end
|
|
30
|
-
if element.
|
|
30
|
+
if element.stereotype && !element.stereotype.empty?
|
|
31
31
|
lines << "Stereotype: #{element.stereotype}"
|
|
32
32
|
end
|
|
33
|
-
|
|
34
|
-
lines << "Is Derived: #{element.is_derived}"
|
|
35
|
-
end
|
|
33
|
+
lines << "Is Derived: #{element.is_derived}"
|
|
36
34
|
lines.join("\n")
|
|
37
35
|
end
|
|
38
36
|
|
|
@@ -53,15 +51,13 @@ module Lutaml
|
|
|
53
51
|
cardinality: format_cardinality(element),
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
if element.
|
|
54
|
+
if element.visibility
|
|
57
55
|
data[:visibility] = element.visibility
|
|
58
56
|
end
|
|
59
|
-
if element.
|
|
57
|
+
if element.stereotype
|
|
60
58
|
data[:stereotype] = element.stereotype
|
|
61
59
|
end
|
|
62
|
-
|
|
63
|
-
data[:is_derived] = element.is_derived
|
|
64
|
-
end
|
|
60
|
+
data[:is_derived] = element.is_derived
|
|
65
61
|
|
|
66
62
|
data
|
|
67
63
|
end
|
|
@@ -20,21 +20,19 @@ module Lutaml
|
|
|
20
20
|
lines << ("=" * 50)
|
|
21
21
|
lines << ""
|
|
22
22
|
lines << "Name: #{element.name}"
|
|
23
|
-
if element.
|
|
23
|
+
if element.xmi_id
|
|
24
24
|
lines << "XMI ID: #{element.xmi_id}"
|
|
25
25
|
end
|
|
26
|
-
if element.
|
|
26
|
+
if element.type
|
|
27
27
|
lines << "Type: #{element.type}"
|
|
28
28
|
end
|
|
29
|
-
if element.
|
|
29
|
+
if element.stereotype && !element.stereotype.empty?
|
|
30
30
|
lines << "Stereotype: #{element.stereotype}"
|
|
31
31
|
end
|
|
32
|
-
if element.
|
|
32
|
+
if element.visibility
|
|
33
33
|
lines << "Visibility: #{element.visibility}"
|
|
34
34
|
end
|
|
35
|
-
|
|
36
|
-
lines << "Abstract: #{element.is_abstract}"
|
|
37
|
-
end
|
|
35
|
+
lines << "Abstract: #{element.is_abstract}"
|
|
38
36
|
lines << ""
|
|
39
37
|
|
|
40
38
|
if element.attributes && !element.attributes.empty?
|
|
@@ -46,8 +44,7 @@ module Lutaml
|
|
|
46
44
|
lines << ""
|
|
47
45
|
end
|
|
48
46
|
|
|
49
|
-
if element.
|
|
50
|
-
!element.operations.empty?
|
|
47
|
+
if element.operations && !element.operations.empty?
|
|
51
48
|
lines << "Operations (#{element.operations.size}):"
|
|
52
49
|
element.operations.each do |op|
|
|
53
50
|
lines << " - #{op.name}()"
|
|
@@ -72,16 +69,12 @@ module Lutaml
|
|
|
72
69
|
name: element.name,
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
data[:xmi_id] = element.xmi_id if
|
|
76
|
-
|
|
77
|
-
data[:data_type] = element.type if
|
|
78
|
-
element.respond_to?(:type) && element.type
|
|
72
|
+
data[:xmi_id] = element.xmi_id if element.xmi_id
|
|
73
|
+
data[:data_type] = element.type if element.type
|
|
79
74
|
data[:stereotype] = element.stereotype if
|
|
80
|
-
element.
|
|
81
|
-
data[:visibility] = element.visibility if
|
|
82
|
-
|
|
83
|
-
data[:is_abstract] = element.is_abstract if
|
|
84
|
-
element.respond_to?(:is_abstract)
|
|
75
|
+
element.stereotype && !element.stereotype.empty?
|
|
76
|
+
data[:visibility] = element.visibility if element.visibility
|
|
77
|
+
data[:is_abstract] = element.is_abstract
|
|
85
78
|
|
|
86
79
|
if element.attributes && !element.attributes.empty?
|
|
87
80
|
data[:attributes] = element.attributes.map do |attr|
|
|
@@ -92,8 +85,7 @@ module Lutaml
|
|
|
92
85
|
end
|
|
93
86
|
end
|
|
94
87
|
|
|
95
|
-
if element.
|
|
96
|
-
!element.operations.empty?
|
|
88
|
+
if element.operations && !element.operations.empty?
|
|
97
89
|
data[:operations] = element.operations.map(&:name)
|
|
98
90
|
end
|
|
99
91
|
|
|
@@ -256,10 +256,10 @@ module Lutaml
|
|
|
256
256
|
# @param diagram_object [Object] Diagram object
|
|
257
257
|
# @return [String, nil] EA internal ID (DUID from style)
|
|
258
258
|
def extract_ea_id(diagram_object)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
return nil unless diagram_object.style
|
|
260
|
+
|
|
261
|
+
# Parse DUID from style string
|
|
262
|
+
# Style format: "NSL=0;LCol=-1;...;DUID=82C649C4;BCol=16764159;..."
|
|
263
263
|
|
|
264
264
|
# Parse DUID from style string
|
|
265
265
|
# Style format: "NSL=0;LCol=-1;...;DUID=82C649C4;BCol=16764159;..."
|
|
@@ -300,20 +300,17 @@ module Lutaml
|
|
|
300
300
|
return connector if connector
|
|
301
301
|
|
|
302
302
|
repository.classes_index.each do |klass|
|
|
303
|
-
if klass.
|
|
304
|
-
# Look in class-level generalizations
|
|
303
|
+
if klass.is_a?(Lutaml::Uml::Class) && klass.generalization
|
|
305
304
|
gen = klass.generalization
|
|
306
|
-
|
|
307
|
-
# Handle both single generalization and array of generalizations
|
|
308
305
|
generalizations = gen.is_a?(Array) ? gen : [gen]
|
|
309
|
-
|
|
310
306
|
generalizations.each do |g|
|
|
311
|
-
return g if g.
|
|
307
|
+
return g if g.xmi_id == xmi_id
|
|
312
308
|
end
|
|
313
|
-
elsif klass.
|
|
314
|
-
|
|
309
|
+
elsif (klass.is_a?(Lutaml::Uml::Class) ||
|
|
310
|
+
klass.is_a?(Lutaml::Uml::DataType)) &&
|
|
311
|
+
klass.associations
|
|
315
312
|
assoc = klass.associations.find do |a|
|
|
316
|
-
a.
|
|
313
|
+
a.xmi_id == xmi_id
|
|
317
314
|
end
|
|
318
315
|
return assoc if assoc
|
|
319
316
|
end
|
|
@@ -328,25 +325,15 @@ module Lutaml
|
|
|
328
325
|
# @param elements_map [Hash] Map of element ID to element data
|
|
329
326
|
# @return [Hash, nil] Target element data
|
|
330
327
|
def find_connector_target(connector, elements_map) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
331
|
-
target_id =
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
# For associations, use the second member_end
|
|
341
|
-
ends = if connector.member_end.is_a?(Array)
|
|
342
|
-
connector.member_end
|
|
343
|
-
else
|
|
344
|
-
[connector.member_end]
|
|
345
|
-
end
|
|
346
|
-
if ends.size > 1
|
|
347
|
-
target_id = ends[1]
|
|
348
|
-
end
|
|
349
|
-
end
|
|
328
|
+
target_id = case connector
|
|
329
|
+
when Lutaml::Uml::Generalization
|
|
330
|
+
connector.general
|
|
331
|
+
when Lutaml::Uml::Dependency
|
|
332
|
+
Array(connector.supplier).first
|
|
333
|
+
when Lutaml::Uml::Association
|
|
334
|
+
ends = Array(connector.member_end)
|
|
335
|
+
ends.size > 1 ? ends[1] : nil
|
|
336
|
+
end
|
|
350
337
|
|
|
351
338
|
elements_map[target_id]
|
|
352
339
|
end
|
|
@@ -357,27 +344,14 @@ module Lutaml
|
|
|
357
344
|
# @param elements_map [Hash] Map of element ID to element data
|
|
358
345
|
# @return [Hash, nil] Source element data
|
|
359
346
|
def find_connector_source(connector, elements_map) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
360
|
-
source_id =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
elsif connector.respond_to?(:owner_end) && connector.owner_end
|
|
369
|
-
source_id = connector.owner_end
|
|
370
|
-
elsif connector.respond_to?(:member_end) && connector.member_end
|
|
371
|
-
# For associations, use the first member_end
|
|
372
|
-
ends = if connector.member_end.is_a?(Array)
|
|
373
|
-
connector.member_end
|
|
374
|
-
else
|
|
375
|
-
[connector.member_end]
|
|
376
|
-
end
|
|
377
|
-
if ends.any?
|
|
378
|
-
source_id = ends[0]
|
|
379
|
-
end
|
|
380
|
-
end
|
|
347
|
+
source_id = case connector
|
|
348
|
+
when Lutaml::Uml::Generalization
|
|
349
|
+
nil
|
|
350
|
+
when Lutaml::Uml::Dependency
|
|
351
|
+
Array(connector.client).first
|
|
352
|
+
when Lutaml::Uml::Association
|
|
353
|
+
connector.owner_end || Array(connector.member_end).first
|
|
354
|
+
end
|
|
381
355
|
|
|
382
356
|
elements_map[source_id]
|
|
383
357
|
end
|
|
@@ -421,8 +395,6 @@ module Lutaml
|
|
|
421
395
|
# @param uml_element [Object] UML element
|
|
422
396
|
# @return [String, nil] Stereotype name
|
|
423
397
|
def extract_stereotype(uml_element)
|
|
424
|
-
return nil unless uml_element.respond_to?(:stereotype)
|
|
425
|
-
|
|
426
398
|
stereotype = uml_element.stereotype
|
|
427
399
|
return nil unless stereotype && !stereotype.empty?
|
|
428
400
|
|
|
@@ -434,14 +406,14 @@ module Lutaml
|
|
|
434
406
|
# @param uml_element [Object] UML element
|
|
435
407
|
# @return [Array<Hash>] Array of attribute data
|
|
436
408
|
def extract_attributes(uml_element)
|
|
437
|
-
return [] unless uml_element.
|
|
409
|
+
return [] unless uml_element.is_a?(Lutaml::Uml::Classifier)
|
|
438
410
|
return [] unless uml_element.attributes
|
|
439
411
|
|
|
440
412
|
uml_element.attributes.map do |attr|
|
|
441
413
|
{
|
|
442
414
|
name: attr.name,
|
|
443
415
|
type: attr.type,
|
|
444
|
-
visibility: attr.
|
|
416
|
+
visibility: attr.visibility,
|
|
445
417
|
}
|
|
446
418
|
end
|
|
447
419
|
end
|
|
@@ -451,14 +423,14 @@ module Lutaml
|
|
|
451
423
|
# @param uml_element [Object] UML element
|
|
452
424
|
# @return [Array<Hash>] Array of operation data
|
|
453
425
|
def extract_operations(uml_element)
|
|
454
|
-
return [] unless uml_element.
|
|
426
|
+
return [] unless uml_element.is_a?(Lutaml::Uml::Classifier)
|
|
455
427
|
return [] unless uml_element.operations
|
|
456
428
|
|
|
457
429
|
uml_element.operations.map do |op|
|
|
458
430
|
{
|
|
459
431
|
name: op.name,
|
|
460
|
-
visibility: op.
|
|
461
|
-
return_type: op.
|
|
432
|
+
visibility: op.visibility,
|
|
433
|
+
return_type: op.return_type,
|
|
462
434
|
parameters: extract_parameters(op),
|
|
463
435
|
}
|
|
464
436
|
end
|
|
@@ -469,7 +441,6 @@ module Lutaml
|
|
|
469
441
|
# @param operation [Object] UML operation
|
|
470
442
|
# @return [Array<Hash>] Array of parameter data
|
|
471
443
|
def extract_parameters(operation)
|
|
472
|
-
return [] unless operation.respond_to?(:owned_parameter)
|
|
473
444
|
return [] unless operation.owned_parameter
|
|
474
445
|
|
|
475
446
|
operation.owned_parameter.map do |param|
|
|
@@ -55,13 +55,12 @@ module Lutaml
|
|
|
55
55
|
#
|
|
56
56
|
# @param attr [Object] Attribute or property with cardinality
|
|
57
57
|
# @return [String] Formatted cardinality like "[1..1]" or "[0..*]"
|
|
58
|
-
def format_cardinality(attr)
|
|
59
|
-
return "" unless attr.
|
|
60
|
-
attr.cardinality
|
|
58
|
+
def format_cardinality(attr)
|
|
59
|
+
return "" unless attr.cardinality
|
|
61
60
|
|
|
62
61
|
card = attr.cardinality
|
|
63
|
-
min = card.
|
|
64
|
-
max = card.
|
|
62
|
+
min = card.min || "0"
|
|
63
|
+
max = card.max || "*"
|
|
65
64
|
|
|
66
65
|
"[#{min}..#{max}]"
|
|
67
66
|
end
|
|
@@ -20,13 +20,13 @@ module Lutaml
|
|
|
20
20
|
lines << ("=" * 50)
|
|
21
21
|
lines << ""
|
|
22
22
|
lines << "Name: #{element.name}"
|
|
23
|
-
if element.
|
|
23
|
+
if element.xmi_id
|
|
24
24
|
lines << "XMI ID: #{element.xmi_id}"
|
|
25
25
|
end
|
|
26
|
-
if element.
|
|
26
|
+
if element.stereotype && !element.stereotype.empty?
|
|
27
27
|
lines << "Stereotype: #{element.stereotype}"
|
|
28
28
|
end
|
|
29
|
-
if element.
|
|
29
|
+
if element.visibility
|
|
30
30
|
lines << "Visibility: #{element.visibility}"
|
|
31
31
|
end
|
|
32
32
|
lines << ""
|
|
@@ -59,16 +59,14 @@ module Lutaml
|
|
|
59
59
|
value_count: element.values ? element.values.size : 0,
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
data[:xmi_id] = element.xmi_id if
|
|
63
|
-
element.respond_to?(:xmi_id) && element.xmi_id
|
|
62
|
+
data[:xmi_id] = element.xmi_id if element.xmi_id
|
|
64
63
|
data[:stereotype] = element.stereotype if
|
|
65
|
-
element.
|
|
66
|
-
data[:visibility] = element.visibility if
|
|
67
|
-
element.respond_to?(:visibility) && element.visibility
|
|
64
|
+
element.stereotype && !element.stereotype.empty?
|
|
65
|
+
data[:visibility] = element.visibility if element.visibility
|
|
68
66
|
|
|
69
67
|
if element.values && !element.values.empty?
|
|
70
68
|
data[:values] = element.values.map do |v|
|
|
71
|
-
v.
|
|
69
|
+
v.name || v.to_s
|
|
72
70
|
end
|
|
73
71
|
end
|
|
74
72
|
|
|
@@ -20,7 +20,7 @@ module Lutaml
|
|
|
20
20
|
lines << ("=" * 50)
|
|
21
21
|
lines << ""
|
|
22
22
|
lines << "Name: #{element.name}"
|
|
23
|
-
if element.
|
|
23
|
+
if element.is_a?(Lutaml::Uml::TopElement) && element.xmi_id
|
|
24
24
|
lines << "XMI ID: #{element.xmi_id}"
|
|
25
25
|
end
|
|
26
26
|
lines.join("\n")
|
|
@@ -35,7 +35,10 @@ module Lutaml
|
|
|
35
35
|
name: element.name,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
if element.is_a?(Lutaml::Uml::TopElement) && element.xmi_id
|
|
39
|
+
data[:xmi_id] =
|
|
40
|
+
element.xmi_id
|
|
41
|
+
end
|
|
39
42
|
|
|
40
43
|
data
|
|
41
44
|
end
|
|
@@ -38,7 +38,7 @@ module Lutaml
|
|
|
38
38
|
package = indexes[:package_paths][package_path_string]
|
|
39
39
|
return [] unless package
|
|
40
40
|
|
|
41
|
-
package_id = package.
|
|
41
|
+
package_id = package.is_a?(Lutaml::Uml::Package) ? package.xmi_id : nil
|
|
42
42
|
return [] unless package_id
|
|
43
43
|
|
|
44
44
|
indexes[:diagram_index][package_id] || []
|
|
@@ -188,15 +188,9 @@ module Lutaml
|
|
|
188
188
|
# @return [Integer] Number of classes
|
|
189
189
|
def count_classes(package) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
|
|
190
190
|
count = 0
|
|
191
|
-
count +=
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
count += if package.respond_to?(:data_types) && package.data_types
|
|
195
|
-
package.data_types.size
|
|
196
|
-
end
|
|
197
|
-
count += if package.respond_to?(:enums) && package.enums
|
|
198
|
-
package.enums.size
|
|
199
|
-
end
|
|
191
|
+
count += package.classes&.size
|
|
192
|
+
count += package.data_types&.size
|
|
193
|
+
count += package.enums&.size
|
|
200
194
|
count
|
|
201
195
|
end
|
|
202
196
|
|
|
@@ -206,7 +200,7 @@ module Lutaml
|
|
|
206
200
|
# The package
|
|
207
201
|
# @return [Integer] Number of diagrams
|
|
208
202
|
def count_diagrams(package)
|
|
209
|
-
return 0 unless package.
|
|
203
|
+
return 0 unless package.diagrams
|
|
210
204
|
|
|
211
205
|
package.diagrams.size
|
|
212
206
|
end
|
|
@@ -260,13 +260,13 @@ module Lutaml
|
|
|
260
260
|
all_associations = []
|
|
261
261
|
|
|
262
262
|
# Get all associations defined at document level and
|
|
263
|
-
if document.
|
|
263
|
+
if document.is_a?(Lutaml::Uml::Document) && document.associations
|
|
264
264
|
all_associations << document.associations
|
|
265
265
|
end
|
|
266
266
|
|
|
267
267
|
# Get all associations defined within classes
|
|
268
268
|
indexes[:qualified_names].each_value do |entity|
|
|
269
|
-
next unless entity.
|
|
269
|
+
next unless (entity.is_a?(Lutaml::Uml::Class) || entity.is_a?(Lutaml::Uml::DataType)) && entity.associations
|
|
270
270
|
|
|
271
271
|
all_associations << entity.associations
|
|
272
272
|
end
|
|
@@ -68,7 +68,8 @@ module Lutaml
|
|
|
68
68
|
# @param obj [Object] The object to extract path from
|
|
69
69
|
# @return [PackagePath, nil] The object's package path
|
|
70
70
|
def extract_package_path(obj)
|
|
71
|
-
return nil unless obj.
|
|
71
|
+
return nil unless obj.is_a?(Lutaml::Model::Serializable) &&
|
|
72
|
+
obj.class.attributes&.key?(:package_path)
|
|
72
73
|
|
|
73
74
|
path = obj.package_path
|
|
74
75
|
return nil unless path
|
|
@@ -156,13 +156,13 @@ module Lutaml
|
|
|
156
156
|
|
|
157
157
|
klass.associations.each do |assoc|
|
|
158
158
|
# Check member_end references
|
|
159
|
-
if assoc.
|
|
159
|
+
if assoc.member_end
|
|
160
160
|
check_association_end_type(assoc.member_end, qname)
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
-
# Check
|
|
164
|
-
if assoc.
|
|
165
|
-
check_association_end_type(assoc.
|
|
163
|
+
# Check owner_end references
|
|
164
|
+
if assoc.owner_end
|
|
165
|
+
check_association_end_type(assoc.owner_end, qname)
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
168
|
end
|
|
@@ -176,11 +176,11 @@ module Lutaml
|
|
|
176
176
|
ends_array = ends.is_a?(Array) ? ends : [ends]
|
|
177
177
|
|
|
178
178
|
ends_array.each do |end_obj|
|
|
179
|
-
next unless end_obj.
|
|
179
|
+
next unless end_obj.is_a?(Lutaml::Uml::TopElementAttribute)
|
|
180
180
|
next unless end_obj.type
|
|
181
181
|
|
|
182
182
|
type_name = end_obj.type
|
|
183
|
-
type_name = type_name.name if type_name.
|
|
183
|
+
type_name = type_name.name if type_name.is_a?(Lutaml::Uml::TopElement)
|
|
184
184
|
|
|
185
185
|
next if @indexes[:qualified_names].key?(type_name)
|
|
186
186
|
|
|
@@ -196,7 +196,7 @@ module Lutaml
|
|
|
196
196
|
next unless klass.attributes
|
|
197
197
|
|
|
198
198
|
klass.attributes.each do |attr|
|
|
199
|
-
next unless attr.
|
|
199
|
+
next unless attr.cardinality
|
|
200
200
|
next unless attr.cardinality
|
|
201
201
|
|
|
202
202
|
cardinality = attr.cardinality
|
|
@@ -234,7 +234,7 @@ module Lutaml
|
|
|
234
234
|
# @param cardinality [Object] Cardinality object
|
|
235
235
|
# @return [Integer, nil] Min value
|
|
236
236
|
def extract_min_value(cardinality)
|
|
237
|
-
return nil unless cardinality.
|
|
237
|
+
return nil unless cardinality.min
|
|
238
238
|
|
|
239
239
|
min_val = cardinality.min
|
|
240
240
|
return nil unless min_val
|
|
@@ -247,7 +247,7 @@ module Lutaml
|
|
|
247
247
|
# @param cardinality [Object] Cardinality object
|
|
248
248
|
# @return [Integer, String, nil] Max value (could be "*" for unlimited)
|
|
249
249
|
def extract_max_value(cardinality)
|
|
250
|
-
return nil unless cardinality.
|
|
250
|
+
return nil unless cardinality.max
|
|
251
251
|
|
|
252
252
|
max_val = cardinality.max
|
|
253
253
|
return nil unless max_val
|
data/lib/lutaml/version.rb
CHANGED