lutaml 0.10.9 → 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 +10 -10
- data/lib/lutaml/cli/enhanced_formatter.rb +13 -22
- data/lib/lutaml/cli/interactive_shell/command_base.rb +2 -2
- data/lib/lutaml/cli/interactive_shell/query_commands.rb +2 -2
- data/lib/lutaml/cli/interactive_shell.rb +21 -18
- data/lib/lutaml/cli/output_formatter.rb +2 -2
- data/lib/lutaml/cli/resource_registry.rb +1 -1
- 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/cli/uml/inspect_command.rb +1 -1
- data/lib/lutaml/converter/dsl_to_uml.rb +8 -8
- data/lib/lutaml/converter/xmi_to_uml.rb +2 -2
- data/lib/lutaml/ea/diagram/configuration.rb +3 -3
- data/lib/lutaml/ea/diagram/style_parser.rb +15 -15
- data/lib/lutaml/ea/diagram/style_resolver.rb +13 -20
- data/lib/lutaml/formatter/graphviz.rb +1 -1
- 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 +5 -7
- data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +3 -8
- data/lib/lutaml/model_transformations/transformation_engine.rb +1 -1
- data/lib/lutaml/qea/factory/document_builder.rb +3 -3
- data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +2 -1
- data/lib/lutaml/qea/lookup_indexes.rb +2 -2
- data/lib/lutaml/qea/models/base_model.rb +1 -1
- data/lib/lutaml/qea/repositories/base_repository.rb +7 -7
- data/lib/lutaml/qea/validation/base_validator.rb +9 -4
- 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/element_comparator.rb +18 -47
- data/lib/lutaml/qea/verification/structure_matcher.rb +4 -4
- data/lib/lutaml/uml/association_generalization.rb +1 -0
- data/lib/lutaml/uml/class.rb +0 -1
- data/lib/lutaml/uml/classifier.rb +3 -0
- data/lib/lutaml/uml/data_type.rb +0 -1
- data/lib/lutaml/uml/has_attributes.rb +1 -1
- data/lib/lutaml/uml/has_members.rb +1 -1
- data/lib/lutaml/uml/inheritance_walker.rb +4 -4
- data/lib/lutaml/uml/model_helpers.rb +5 -62
- data/lib/lutaml/uml/operation.rb +6 -0
- data/lib/lutaml/uml/operation_parameter.rb +17 -0
- data/lib/lutaml/uml/qualified_name.rb +4 -5
- data/lib/lutaml/uml/top_element_attribute.rb +4 -0
- data/lib/lutaml/uml/validation/document_structure_validator.rb +4 -4
- data/lib/lutaml/uml_repository/class_lookup_index.rb +1 -1
- data/lib/lutaml/uml_repository/exporters/json_exporter.rb +1 -1
- data/lib/lutaml/uml_repository/exporters/markdown/class_page_builder.rb +2 -2
- data/lib/lutaml/uml_repository/index_builder.rb +15 -15
- data/lib/lutaml/uml_repository/index_builders/association_index.rb +6 -6
- data/lib/lutaml/uml_repository/package_exporter.rb +3 -5
- data/lib/lutaml/uml_repository/package_loader.rb +3 -3
- 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/association_query.rb +2 -2
- data/lib/lutaml/uml_repository/queries/diagram_query.rb +1 -1
- data/lib/lutaml/uml_repository/queries/inheritance_query.rb +9 -13
- data/lib/lutaml/uml_repository/queries/package_query.rb +4 -10
- data/lib/lutaml/uml_repository/queries/search_query.rb +9 -9
- data/lib/lutaml/uml_repository/query_dsl/conditions/hash_condition.rb +2 -2
- data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +2 -1
- data/lib/lutaml/uml_repository/query_dsl/order.rb +2 -2
- data/lib/lutaml/uml_repository/query_dsl/query_builder.rb +2 -2
- data/lib/lutaml/uml_repository/repository.rb +2 -2
- data/lib/lutaml/uml_repository/repository_enhanced.rb +1 -1
- data/lib/lutaml/uml_repository/static_site/association_serialization.rb +38 -86
- data/lib/lutaml/uml_repository/static_site/data_transformer.rb +13 -39
- data/lib/lutaml/uml_repository/static_site/models/spa_association.rb +32 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_association_end.rb +28 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_attribute.rb +42 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_base.rb +12 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_cardinality.rb +21 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_class.rb +64 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_diagram.rb +33 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_document.rb +42 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_inherited_association.rb +27 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_inherited_attribute.rb +28 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_literal.rb +21 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_metadata.rb +26 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_operation.rb +37 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_package.rb +37 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_package_tree_node.rb +35 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_parameter.rb +23 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_search_entry.rb +37 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_statistics.rb +27 -0
- data/lib/lutaml/uml_repository/static_site/models/spa_tree_class_ref.rb +23 -0
- data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +46 -131
- data/lib/lutaml/uml_repository/static_site/serializers/attribute_serializer.rb +11 -11
- data/lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb +17 -16
- data/lib/lutaml/uml_repository/static_site/serializers/diagram_serializer.rb +8 -12
- data/lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb +44 -51
- data/lib/lutaml/uml_repository/static_site/serializers/metadata_builder.rb +8 -5
- data/lib/lutaml/uml_repository/static_site/serializers/operation_serializer.rb +14 -11
- data/lib/lutaml/uml_repository/static_site/serializers/package_serializer.rb +15 -17
- data/lib/lutaml/uml_repository/static_site/serializers/package_tree_builder.rb +19 -31
- data/lib/lutaml/uml_repository/statistics_calculator.rb +2 -4
- data/lib/lutaml/uml_repository/validators/repository_validator.rb +9 -9
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +4 -4
- data/lib/lutaml/xmi/parsers/xmi_connector.rb +7 -7
- metadata +22 -2
|
@@ -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
|
|
@@ -301,12 +301,10 @@ module Lutaml
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
# Store metadata using various approaches
|
|
304
|
-
if document.
|
|
304
|
+
if document.class.method_defined?(:parsing_metadata=)
|
|
305
305
|
document.parsing_metadata = metadata
|
|
306
|
-
elsif document.
|
|
306
|
+
elsif document.class.method_defined?(:metadata=)
|
|
307
307
|
document.metadata = metadata
|
|
308
|
-
else
|
|
309
|
-
document.instance_variable_set(:@qea_metadata, metadata)
|
|
310
308
|
end
|
|
311
309
|
end
|
|
312
310
|
|
|
@@ -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
|
|
|
@@ -165,13 +165,8 @@ module Lutaml
|
|
|
165
165
|
options: @options,
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
if document.respond_to?(:parsing_metadata=)
|
|
168
|
+
if document.class.method_defined?(:parsing_metadata=)
|
|
170
169
|
document.parsing_metadata = metadata
|
|
171
|
-
elsif document.respond_to?(:instance_variable_set)
|
|
172
|
-
# Store in custom attribute if available
|
|
173
|
-
document.instance_variable_set(:@parsing_metadata,
|
|
174
|
-
metadata)
|
|
175
170
|
end
|
|
176
171
|
end
|
|
177
172
|
|
|
@@ -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 " \
|
|
@@ -238,7 +238,7 @@ module Lutaml
|
|
|
238
238
|
# @param valid_ids [Set<String>] Set of valid xmi_ids
|
|
239
239
|
# @return [Boolean] True if valid or nil
|
|
240
240
|
def check_association_end_valid?(assoc, attr, valid_ids)
|
|
241
|
-
value = assoc.
|
|
241
|
+
value = assoc.public_send(attr)
|
|
242
242
|
return true if value.nil?
|
|
243
243
|
|
|
244
244
|
valid_ids.include?(value)
|
|
@@ -250,14 +250,14 @@ module Lutaml
|
|
|
250
250
|
# @param valid_ids [Set<String>] Set of valid xmi_ids
|
|
251
251
|
# @param warnings [Array<String>] Warning accumulator
|
|
252
252
|
def add_invalid_end_warning(assoc, attr, valid_ids, warnings) # rubocop:disable Metrics/MethodLength
|
|
253
|
-
value = assoc.
|
|
253
|
+
value = assoc.public_send(attr)
|
|
254
254
|
return if value.nil?
|
|
255
255
|
|
|
256
256
|
unless valid_ids.include?(value)
|
|
257
257
|
# Get the corresponding name attribute for better error messages
|
|
258
258
|
name_attr = attr.to_s.gsub("_xmi_id", "").to_sym
|
|
259
259
|
name_value = begin
|
|
260
|
-
assoc.
|
|
260
|
+
assoc.public_send(name_attr)
|
|
261
261
|
rescue StandardError
|
|
262
262
|
nil
|
|
263
263
|
end
|
|
@@ -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
|
|
@@ -17,12 +17,12 @@ module Lutaml
|
|
|
17
17
|
def build_group_index(collection, method, single: false)
|
|
18
18
|
if single
|
|
19
19
|
collection.each_with_object({}) do |item, hash|
|
|
20
|
-
key = item.
|
|
20
|
+
key = item.public_send(method)
|
|
21
21
|
hash[key] = item if key
|
|
22
22
|
end
|
|
23
23
|
else
|
|
24
24
|
collection.each_with_object({}) do |item, hash|
|
|
25
|
-
key = item.
|
|
25
|
+
key = item.public_send(method)
|
|
26
26
|
(hash[key] ||= []) << item if key
|
|
27
27
|
end
|
|
28
28
|
end
|
|
@@ -25,7 +25,7 @@ module Lutaml
|
|
|
25
25
|
# Returns the primary key value for this instance
|
|
26
26
|
# @return [Object] the primary key value
|
|
27
27
|
def primary_key
|
|
28
|
-
|
|
28
|
+
public_send(self.class.primary_key_column)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Create instance from database row hash
|
|
@@ -57,7 +57,7 @@ module Lutaml
|
|
|
57
57
|
# @param id [Object] key value
|
|
58
58
|
# @return [Object, nil] The record or nil if not found
|
|
59
59
|
def find_by_key(key, id)
|
|
60
|
-
@records.find { |record| record.
|
|
60
|
+
@records.find { |record| record.public_send(key) == id }
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# Filter records by conditions
|
|
@@ -79,7 +79,7 @@ module Lutaml
|
|
|
79
79
|
elsif conditions.is_a?(Hash)
|
|
80
80
|
@records.select do |record|
|
|
81
81
|
conditions.all? do |attr, value|
|
|
82
|
-
record.
|
|
82
|
+
record.public_send(attr) == value
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
else
|
|
@@ -150,8 +150,8 @@ module Lutaml
|
|
|
150
150
|
# # => [{id: 1, name: "Test"}, {id: 2, name: "Other"}]
|
|
151
151
|
def pluck(*attributes)
|
|
152
152
|
@records.map do |record|
|
|
153
|
-
attributes.
|
|
154
|
-
|
|
153
|
+
attributes.to_h do |attr|
|
|
154
|
+
[attr, record.public_send(attr)]
|
|
155
155
|
end
|
|
156
156
|
end
|
|
157
157
|
end
|
|
@@ -165,7 +165,7 @@ module Lutaml
|
|
|
165
165
|
# repository.group_by(:type)
|
|
166
166
|
# # => {"Class" => [obj1, obj2], "Interface" => [obj3]}
|
|
167
167
|
def group_by(attribute)
|
|
168
|
-
@records.group_by { |record| record.
|
|
168
|
+
@records.group_by { |record| record.public_send(attribute) }
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
# Sort records by an attribute
|
|
@@ -178,7 +178,7 @@ module Lutaml
|
|
|
178
178
|
# repository.order_by(:name)
|
|
179
179
|
# repository.order_by(:created_at, :desc)
|
|
180
180
|
def order_by(attribute, order = :asc)
|
|
181
|
-
sorted = @records.sort_by { |record| record.
|
|
181
|
+
sorted = @records.sort_by { |record| record.public_send(attribute) }
|
|
182
182
|
order == :desc ? sorted.reverse : sorted
|
|
183
183
|
end
|
|
184
184
|
|
|
@@ -191,7 +191,7 @@ module Lutaml
|
|
|
191
191
|
# repository.distinct(:type)
|
|
192
192
|
# # => ["Class", "Interface", "Component"]
|
|
193
193
|
def distinct(attribute)
|
|
194
|
-
@records.map { |record| record.
|
|
194
|
+
@records.map { |record| record.public_send(attribute) }.uniq
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
# Check if repository is empty
|
|
@@ -122,7 +122,9 @@ module Lutaml
|
|
|
122
122
|
collection = get_collection_for_table(table)
|
|
123
123
|
return false unless collection
|
|
124
124
|
|
|
125
|
-
collection.any?
|
|
125
|
+
collection.any? do |record|
|
|
126
|
+
record.public_send(id_column) == reference_id
|
|
127
|
+
end
|
|
126
128
|
end
|
|
127
129
|
|
|
128
130
|
# Maps table names to their corresponding collections in Database
|
|
@@ -207,7 +209,10 @@ module Lutaml
|
|
|
207
209
|
# @param value [Object] Value to check
|
|
208
210
|
# @return [Boolean]
|
|
209
211
|
def present?(value)
|
|
210
|
-
|
|
212
|
+
return false if value.nil?
|
|
213
|
+
return !value.empty? if value.is_a?(String) || value.is_a?(Array)
|
|
214
|
+
|
|
215
|
+
true
|
|
211
216
|
end
|
|
212
217
|
|
|
213
218
|
# Finds entity name from database
|
|
@@ -223,8 +228,8 @@ module Lutaml
|
|
|
223
228
|
collection = get_collection_for_table(table)
|
|
224
229
|
return nil unless collection
|
|
225
230
|
|
|
226
|
-
record = collection.find { |r| r.
|
|
227
|
-
record&.
|
|
231
|
+
record = collection.find { |r| r.public_send(id_column) == id }
|
|
232
|
+
record&.public_send(name_column)
|
|
228
233
|
end
|
|
229
234
|
|
|
230
235
|
# Validates a collection of entities
|
|
@@ -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
|
|
|
@@ -52,25 +52,19 @@ module Lutaml
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# Compare is_abstract
|
|
55
|
-
if xmi_class.
|
|
56
|
-
qea_class.respond_to?(:is_abstract) &&
|
|
57
|
-
xmi_class.is_abstract != qea_class.is_abstract
|
|
55
|
+
if xmi_class.is_abstract != qea_class.is_abstract
|
|
58
56
|
differences << "is_abstract: #{xmi_class.is_abstract} " \
|
|
59
57
|
"vs #{qea_class.is_abstract}"
|
|
60
58
|
end
|
|
61
59
|
|
|
62
60
|
# Compare type
|
|
63
|
-
if xmi_class.
|
|
64
|
-
qea_class.respond_to?(:type) &&
|
|
65
|
-
normalize_value(xmi_class.type) != normalize_value(qea_class.type)
|
|
61
|
+
if normalize_value(xmi_class.type) != normalize_value(qea_class.type)
|
|
66
62
|
differences << "type: '#{xmi_class.type}' vs '#{qea_class.type}'"
|
|
67
63
|
end
|
|
68
64
|
|
|
69
65
|
# Compare modifier
|
|
70
|
-
if xmi_class.
|
|
71
|
-
qea_class.
|
|
72
|
-
normalize_value(xmi_class.modifier) !=
|
|
73
|
-
normalize_value(qea_class.modifier)
|
|
66
|
+
if normalize_value(xmi_class.modifier) !=
|
|
67
|
+
normalize_value(qea_class.modifier)
|
|
74
68
|
differences << "modifier: '#{xmi_class.modifier}' " \
|
|
75
69
|
"vs '#{qea_class.modifier}'"
|
|
76
70
|
end
|
|
@@ -105,27 +99,22 @@ module Lutaml
|
|
|
105
99
|
end
|
|
106
100
|
|
|
107
101
|
# Compare type
|
|
108
|
-
if xmi_attr.
|
|
109
|
-
qea_attr.
|
|
110
|
-
normalize_value(xmi_attr.type) !=
|
|
111
|
-
normalize_value(qea_attr.type)
|
|
102
|
+
if normalize_value(xmi_attr.type) !=
|
|
103
|
+
normalize_value(qea_attr.type)
|
|
112
104
|
differences << "type: '#{xmi_attr.type}' vs '#{qea_attr.type}'"
|
|
113
105
|
end
|
|
114
106
|
|
|
115
107
|
# Compare visibility
|
|
116
|
-
if xmi_attr.
|
|
117
|
-
qea_attr.
|
|
118
|
-
normalize_value(xmi_attr.visibility) !=
|
|
119
|
-
normalize_value(qea_attr.visibility)
|
|
108
|
+
if normalize_value(xmi_attr.visibility) !=
|
|
109
|
+
normalize_value(qea_attr.visibility)
|
|
120
110
|
differences << "visibility: '#{xmi_attr.visibility}' " \
|
|
121
111
|
"vs '#{qea_attr.visibility}'"
|
|
122
112
|
end
|
|
123
113
|
|
|
124
114
|
# Compare cardinality if present
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
qea_card = qea_attr.cardinality
|
|
115
|
+
xmi_card = xmi_attr.cardinality
|
|
116
|
+
qea_card = qea_attr.cardinality
|
|
117
|
+
if xmi_card || qea_card
|
|
129
118
|
if xmi_card && qea_card
|
|
130
119
|
unless cardinalities_equal?(xmi_card, qea_card)
|
|
131
120
|
differences << "cardinality: #{format_cardinality(xmi_card)} " \
|
|
@@ -157,19 +146,15 @@ module Lutaml
|
|
|
157
146
|
end
|
|
158
147
|
|
|
159
148
|
# Compare return type
|
|
160
|
-
if xmi_op.
|
|
161
|
-
qea_op.
|
|
162
|
-
normalize_value(xmi_op.return_type) !=
|
|
163
|
-
normalize_value(qea_op.return_type)
|
|
149
|
+
if normalize_value(xmi_op.return_type) !=
|
|
150
|
+
normalize_value(qea_op.return_type)
|
|
164
151
|
differences << "return_type: '#{xmi_op.return_type}' " \
|
|
165
152
|
"vs '#{qea_op.return_type}'"
|
|
166
153
|
end
|
|
167
154
|
|
|
168
155
|
# Compare visibility
|
|
169
|
-
if xmi_op.
|
|
170
|
-
qea_op.
|
|
171
|
-
normalize_value(xmi_op.visibility) !=
|
|
172
|
-
normalize_value(qea_op.visibility)
|
|
156
|
+
if normalize_value(xmi_op.visibility) !=
|
|
157
|
+
normalize_value(qea_op.visibility)
|
|
173
158
|
differences << "visibility: '#{xmi_op.visibility}' " \
|
|
174
159
|
"vs '#{qea_op.visibility}'"
|
|
175
160
|
end
|
|
@@ -273,32 +258,18 @@ module Lutaml
|
|
|
273
258
|
end
|
|
274
259
|
|
|
275
260
|
# Check if cardinalities are equal
|
|
276
|
-
def cardinalities_equal?(card1, card2)
|
|
261
|
+
def cardinalities_equal?(card1, card2)
|
|
277
262
|
return true if card1.nil? && card2.nil?
|
|
278
263
|
return false if card1.nil? || card2.nil?
|
|
279
264
|
|
|
280
|
-
|
|
281
|
-
card1.min || (card1.respond_to?(:min_value) && card1.min_value)
|
|
282
|
-
) == (
|
|
283
|
-
card2.min || (card2.respond_to?(:min_value) && card2.min_value)
|
|
284
|
-
)
|
|
285
|
-
max_equal = (
|
|
286
|
-
card1.max || (card1.respond_to?(:max_value) && card1.max_value)
|
|
287
|
-
) == (
|
|
288
|
-
card2.max || (card2.respond_to?(:max_value) && card2.max_value)
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
min_equal && max_equal
|
|
265
|
+
card1.min == card2.min && card1.max == card2.max
|
|
292
266
|
end
|
|
293
267
|
|
|
294
268
|
# Format cardinality for display
|
|
295
269
|
def format_cardinality(card)
|
|
296
270
|
return "nil" if card.nil?
|
|
297
271
|
|
|
298
|
-
|
|
299
|
-
max = card.max || (card.respond_to?(:max_value) && card.max_value)
|
|
300
|
-
|
|
301
|
-
"#{min}..#{max}"
|
|
272
|
+
"\#{card.min}..\#{card.max}"
|
|
302
273
|
end
|
|
303
274
|
end
|
|
304
275
|
end
|
|
@@ -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})"
|
data/lib/lutaml/uml/class.rb
CHANGED
|
@@ -13,7 +13,6 @@ module Lutaml
|
|
|
13
13
|
class Class < Classifier
|
|
14
14
|
attribute :nested_classifier, :string, collection: true,
|
|
15
15
|
default: -> { [] }
|
|
16
|
-
attribute :is_abstract, :boolean, default: false
|
|
17
16
|
attribute :stereotype, :string, collection: true, default: -> { [] }
|
|
18
17
|
attribute :type, :string
|
|
19
18
|
attribute :attributes, TopElementAttribute, collection: true
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "top_element"
|
|
4
4
|
require_relative "association_generalization"
|
|
5
|
+
require_relative "operation"
|
|
5
6
|
|
|
6
7
|
module Lutaml
|
|
7
8
|
module Uml
|
|
@@ -9,6 +10,8 @@ module Lutaml
|
|
|
9
10
|
attribute :association_generalization,
|
|
10
11
|
::Lutaml::Uml::AssociationGeneralization,
|
|
11
12
|
collection: true, default: -> { [] }
|
|
13
|
+
attribute :operations, Operation, collection: true, default: -> { [] }
|
|
14
|
+
attribute :is_abstract, :boolean, default: false
|
|
12
15
|
|
|
13
16
|
yaml do
|
|
14
17
|
map "generalization", to: :association_generalization
|
data/lib/lutaml/uml/data_type.rb
CHANGED
|
@@ -11,7 +11,6 @@ module Lutaml
|
|
|
11
11
|
class DataType < Classifier
|
|
12
12
|
attribute :nested_classifier, :string, collection: true,
|
|
13
13
|
default: -> { [] }
|
|
14
|
-
attribute :is_abstract, :boolean, default: false
|
|
15
14
|
attribute :type, :string
|
|
16
15
|
attribute :attributes, TopElementAttribute, collection: true
|
|
17
16
|
attribute :modifier, :string
|
|
@@ -31,7 +31,7 @@ module Lutaml
|
|
|
31
31
|
# puts "#{' ' * (level - 1)}Parent #{level}: #{parent.name}"
|
|
32
32
|
# end
|
|
33
33
|
def walk(klass)
|
|
34
|
-
return [] unless klass.
|
|
34
|
+
return [] unless klass.is_a?(Lutaml::Uml::Class) && klass.generalization
|
|
35
35
|
|
|
36
36
|
ancestors = []
|
|
37
37
|
@visited.clear
|
|
@@ -69,12 +69,12 @@ module Lutaml
|
|
|
69
69
|
# Uses a trail set for cycle detection (avoids Set mutation issues across calls).
|
|
70
70
|
def collect_ancestors(klass, result, trail = [])
|
|
71
71
|
return [] if trail.include?(klass.xmi_id) # cycle guard
|
|
72
|
-
return [] unless klass.
|
|
72
|
+
return [] unless klass.is_a?(Lutaml::Uml::Class) && klass.generalization
|
|
73
73
|
|
|
74
74
|
trail = trail.dup
|
|
75
75
|
trail << klass.xmi_id
|
|
76
76
|
|
|
77
|
-
general_id = klass.generalization.
|
|
77
|
+
general_id = klass.generalization.general_id
|
|
78
78
|
parent = general_id ? find_class_by_id(general_id) : nil
|
|
79
79
|
|
|
80
80
|
return [] unless parent
|
|
@@ -85,7 +85,7 @@ module Lutaml
|
|
|
85
85
|
|
|
86
86
|
def find_class_by_id(xmi_id)
|
|
87
87
|
@repository.indexes&.dig(:qualified_names, xmi_id) ||
|
|
88
|
-
@repository.
|
|
88
|
+
@repository.classes_index&.find { |c| c.xmi_id == xmi_id }
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|