lutaml 0.9.28 → 0.9.29
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/bin/plantuml2lutaml +11 -7
- data/bin/yaml2lutaml +1 -1
- data/exe/lutaml-sysml +4 -2
- data/exe/lutaml-wsd2uml +11 -7
- data/exe/lutaml-yaml2uml +1 -1
- data/lib/lutaml/express/parsers/exp.rb +4 -4
- data/lib/lutaml/formatter/graphviz.rb +7 -7
- data/lib/lutaml/sysml/allocate.rb +6 -7
- data/lib/lutaml/sysml/allocated.rb +6 -6
- data/lib/lutaml/sysml/binding_connector.rb +6 -6
- data/lib/lutaml/sysml/block.rb +28 -25
- data/lib/lutaml/sysml/constraint_block.rb +11 -11
- data/lib/lutaml/sysml/copy.rb +5 -5
- data/lib/lutaml/sysml/derive_requirement.rb +6 -6
- data/lib/lutaml/sysml/nested_connector_end.rb +9 -9
- data/lib/lutaml/sysml/refine.rb +6 -6
- data/lib/lutaml/sysml/requirement_related.rb +6 -6
- data/lib/lutaml/sysml/satisfy.rb +6 -6
- data/lib/lutaml/sysml/test_case.rb +20 -19
- data/lib/lutaml/sysml/trace.rb +6 -6
- data/lib/lutaml/sysml/verify.rb +5 -5
- data/lib/lutaml/sysml/version.rb +1 -1
- data/lib/lutaml/sysml/xmi_file.rb +455 -415
- data/lib/lutaml/sysml.rb +1 -1
- data/lib/lutaml/uml/association.rb +4 -3
- data/lib/lutaml/uml/data_type.rb +1 -0
- data/lib/lutaml/uml/document.rb +4 -1
- data/lib/lutaml/uml/formatter/graphviz.rb +11 -13
- data/lib/lutaml/uml/has_attributes.rb +2 -2
- data/lib/lutaml/uml/has_members.rb +4 -3
- data/lib/lutaml/uml/node/class_node.rb +5 -7
- data/lib/lutaml/uml/node/field.rb +1 -3
- data/lib/lutaml/uml/node/method.rb +1 -3
- data/lib/lutaml/uml/node/relationship.rb +1 -3
- data/lib/lutaml/uml/operation.rb +6 -6
- data/lib/lutaml/uml/package.rb +3 -1
- data/lib/lutaml/uml/parsers/attribute.rb +1 -3
- data/lib/lutaml/uml/parsers/dsl.rb +11 -10
- data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +7 -6
- data/lib/lutaml/uml/parsers/yaml.rb +2 -2
- data/lib/lutaml/uml/serializers/class.rb +1 -1
- data/lib/lutaml/uml/top_element.rb +9 -9
- data/lib/lutaml/uml/top_element_attribute.rb +6 -6
- data/lib/lutaml/uml/value.rb +6 -6
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/liquid_drops/association_drop.rb +31 -11
- data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +29 -11
- data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +8 -2
- data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +6 -4
- data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +76 -18
- data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +13 -6
- data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +16 -7
- data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +10 -4
- data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +2 -0
- data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +10 -3
- data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +98 -24
- data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +11 -5
- data/lib/lutaml/xmi/liquid_drops/package_drop.rb +61 -18
- data/lib/lutaml/xmi/liquid_drops/root_drop.rb +14 -4
- data/lib/lutaml/xmi/parsers/xmi_base.rb +1031 -0
- data/lib/lutaml/xmi/parsers/xml.rb +19 -1016
- data/lib/lutaml/xml/parsers/xml.rb +2 -2
- metadata +4 -3
@@ -0,0 +1,1031 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "htmlentities"
|
3
|
+
require "lutaml/uml/has_attributes"
|
4
|
+
require "lutaml/uml/document"
|
5
|
+
require "lutaml/xmi"
|
6
|
+
require "xmi"
|
7
|
+
|
8
|
+
module Lutaml
|
9
|
+
module XMI
|
10
|
+
module Parsers
|
11
|
+
module XMIBase
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
private
|
18
|
+
|
19
|
+
# @param xml [String]
|
20
|
+
# @return [Lutaml::Model::Serializable]
|
21
|
+
def get_xmi_model(xml)
|
22
|
+
Xmi::Sparx::SparxRoot.parse_xml(File.read(xml))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param xmi_model [Lutaml::Model::Serializable]
|
27
|
+
def set_xmi_model(xmi_model)
|
28
|
+
@xmi_cache = {}
|
29
|
+
@xmi_root_model = xmi_model
|
30
|
+
map_id_name(@xmi_cache, @xmi_root_model)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param yaml [String]
|
34
|
+
# @return [Hash]
|
35
|
+
def get_guidance(yaml)
|
36
|
+
return unless yaml
|
37
|
+
|
38
|
+
YAML.safe_load(File.read(yaml, encoding: "UTF-8"))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @param xmi_model [Lutaml::Model::Serializable]
|
44
|
+
# @param with_gen: [Boolean]
|
45
|
+
# @param with_absolute_path: [Boolean]
|
46
|
+
# @return [Hash]
|
47
|
+
# @note xpath: //uml:Model[@xmi:type="uml:Model"]
|
48
|
+
def serialize_to_hash(xmi_model,
|
49
|
+
with_gen: false, with_absolute_path: false)
|
50
|
+
model = xmi_model.model
|
51
|
+
{
|
52
|
+
name: model.name,
|
53
|
+
packages: serialize_model_packages(
|
54
|
+
model,
|
55
|
+
with_gen: with_gen,
|
56
|
+
with_absolute_path: with_absolute_path,
|
57
|
+
),
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param model [Lutaml::Model::Serializable]
|
62
|
+
# @param with_gen: [Boolean]
|
63
|
+
# @param with_absolute_path: [Boolean]
|
64
|
+
# @param absolute_path: [String]
|
65
|
+
# @return [Array<Hash>]
|
66
|
+
# @note xpath ./packagedElement[@xmi:type="uml:Package"]
|
67
|
+
def serialize_model_packages(model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
68
|
+
with_gen: false, with_absolute_path: false, absolute_path: "")
|
69
|
+
packages = model.packaged_element.select do |e|
|
70
|
+
e.type?("uml:Package")
|
71
|
+
end
|
72
|
+
|
73
|
+
if with_absolute_path
|
74
|
+
absolute_path = "#{absolute_path}::#{model.name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
packages.map do |package| # rubocop:disable Metrics/BlockLength
|
78
|
+
h = {
|
79
|
+
xmi_id: package.id,
|
80
|
+
name: get_package_name(package),
|
81
|
+
classes: serialize_model_classes(
|
82
|
+
package, model,
|
83
|
+
with_gen: with_gen,
|
84
|
+
with_absolute_path: with_absolute_path,
|
85
|
+
absolute_path: "#{absolute_path}::#{package.name}"
|
86
|
+
),
|
87
|
+
enums: serialize_model_enums(package),
|
88
|
+
data_types: serialize_model_data_types(package),
|
89
|
+
diagrams: serialize_model_diagrams(
|
90
|
+
package.id,
|
91
|
+
with_package: with_gen,
|
92
|
+
),
|
93
|
+
packages: serialize_model_packages(
|
94
|
+
package,
|
95
|
+
with_gen: with_gen,
|
96
|
+
with_absolute_path: with_absolute_path,
|
97
|
+
absolute_path: absolute_path,
|
98
|
+
),
|
99
|
+
definition: doc_node_attribute_value(package.id, "documentation"),
|
100
|
+
stereotype: doc_node_attribute_value(package.id, "stereotype"),
|
101
|
+
}
|
102
|
+
|
103
|
+
if with_absolute_path
|
104
|
+
h[:absolute_path] = "#{absolute_path}::#{package.name}"
|
105
|
+
end
|
106
|
+
|
107
|
+
h
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# @param package [Lutaml::Model::Serializable]
|
112
|
+
# @return [String]
|
113
|
+
def get_package_name(package) # rubocop:disable Metrics/AbcSize
|
114
|
+
return package.name unless package.name.nil?
|
115
|
+
|
116
|
+
connector = fetch_connector(package.id)
|
117
|
+
if connector.target&.model && connector.target.model&.name
|
118
|
+
return "#{connector.target.model.name} " \
|
119
|
+
"(#{package.type.split(':').last})"
|
120
|
+
end
|
121
|
+
|
122
|
+
"unnamed"
|
123
|
+
end
|
124
|
+
|
125
|
+
# @param package [Lutaml::Model::Serializable]
|
126
|
+
# @param model [Lutaml::Model::Serializable]
|
127
|
+
# @param with_gen: [Boolean]
|
128
|
+
# @param with_absolute_path: [Boolean]
|
129
|
+
# @return [Array<Hash>]
|
130
|
+
# @note xpath ./packagedElement[@xmi:type="uml:Class" or
|
131
|
+
# @xmi:type="uml:AssociationClass"]
|
132
|
+
def serialize_model_classes(package, model, # rubocop:disable Metrics/MethodLength
|
133
|
+
with_gen: false, with_absolute_path: false, absolute_path: "")
|
134
|
+
klasses = package.packaged_element.select do |e|
|
135
|
+
e.type?("uml:Class") || e.type?("uml:AssociationClass") ||
|
136
|
+
e.type?("uml:Interface")
|
137
|
+
end
|
138
|
+
|
139
|
+
klasses.map do |klass|
|
140
|
+
h = build_klass_hash(
|
141
|
+
klass, model,
|
142
|
+
with_gen: with_gen
|
143
|
+
)
|
144
|
+
|
145
|
+
h[:absolute_path] = absolute_path if with_absolute_path
|
146
|
+
|
147
|
+
h
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# @param klass [Lutaml::Model::Serializable]
|
152
|
+
# @param model [Lutaml::Model::Serializable]
|
153
|
+
# @param with_gen: [Boolean]
|
154
|
+
# @param with_absolute_path: [Boolean]
|
155
|
+
# @return [Hash]
|
156
|
+
def build_klass_hash(klass, model, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
157
|
+
with_gen: false, with_absolute_path: false, absolute_path: "")
|
158
|
+
klass_hash = {
|
159
|
+
xmi_id: klass.id,
|
160
|
+
name: klass.name,
|
161
|
+
package: model,
|
162
|
+
type: klass.type.split(":").last,
|
163
|
+
attributes: serialize_class_attributes(klass),
|
164
|
+
associations: serialize_model_associations(klass.id),
|
165
|
+
operations: serialize_class_operations(klass),
|
166
|
+
constraints: serialize_class_constraints(klass.id),
|
167
|
+
is_abstract: doc_node_attribute_value(klass.id, "isAbstract"),
|
168
|
+
definition: doc_node_attribute_value(klass.id, "documentation"),
|
169
|
+
stereotype: doc_node_attribute_value(klass.id, "stereotype"),
|
170
|
+
}
|
171
|
+
|
172
|
+
klass_hash[:absolute_path] = absolute_path if with_absolute_path
|
173
|
+
|
174
|
+
if with_gen && klass.type?("uml:Class")
|
175
|
+
klass_hash[:generalization] = serialize_generalization(klass)
|
176
|
+
end
|
177
|
+
|
178
|
+
klass_hash
|
179
|
+
end
|
180
|
+
|
181
|
+
# @param klass [Lutaml::Model::Serializable]
|
182
|
+
# # @return [Hash]
|
183
|
+
def serialize_generalization(klass)
|
184
|
+
general_hash, next_general_node_id = get_top_level_general_hash(klass)
|
185
|
+
return general_hash unless next_general_node_id
|
186
|
+
|
187
|
+
general_hash[:general] = serialize_generalization_attributes(
|
188
|
+
next_general_node_id,
|
189
|
+
)
|
190
|
+
|
191
|
+
general_hash
|
192
|
+
end
|
193
|
+
|
194
|
+
# @param klass [Lutaml::Model::Serializable]
|
195
|
+
# @return [Array<Hash>]
|
196
|
+
def get_top_level_general_hash(klass) # rubocop:disable Metrics/AbcSize
|
197
|
+
general_hash, next_general_node_id = get_general_hash(klass.id)
|
198
|
+
general_hash[:name] = klass.name
|
199
|
+
general_hash[:type] = klass.type
|
200
|
+
general_hash[:definition] = lookup_general_documentation(klass.id)
|
201
|
+
general_hash[:stereotype] = doc_node_attribute_value(
|
202
|
+
klass.id, "stereotype"
|
203
|
+
)
|
204
|
+
|
205
|
+
# update_inherited_attributes(general_hash)
|
206
|
+
# update_gen_attributes(general_hash)
|
207
|
+
|
208
|
+
[general_hash, next_general_node_id]
|
209
|
+
end
|
210
|
+
|
211
|
+
def lookup_general_documentation(klass_id)
|
212
|
+
# lookup_attribute_documentation(klass_id) ||
|
213
|
+
# lookup_element_prop_documentation(klass_id)
|
214
|
+
|
215
|
+
lookup_element_prop_documentation(klass_id)
|
216
|
+
end
|
217
|
+
|
218
|
+
def update_gen_attributes(general_hash)
|
219
|
+
general_hash[:gen_attributes] = serialize_gen_attributes
|
220
|
+
end
|
221
|
+
|
222
|
+
def update_inherited_attributes(general_hash)
|
223
|
+
general_hash[:gml_attributes] = serialize_gml_attributes
|
224
|
+
general_hash[:core_attributes] = serialize_core_attributes
|
225
|
+
end
|
226
|
+
|
227
|
+
# @param xmi_id [String]
|
228
|
+
# @param model [Lutaml::Model::Serializable]
|
229
|
+
# @return [Array<Hash>]
|
230
|
+
# @note get generalization node and its owned attributes
|
231
|
+
def serialize_generalization_attributes(general_id)
|
232
|
+
general_hash, next_general_node_id = get_general_hash(general_id)
|
233
|
+
|
234
|
+
if next_general_node_id
|
235
|
+
general_hash[:general] = serialize_generalization_attributes(
|
236
|
+
next_general_node_id,
|
237
|
+
)
|
238
|
+
end
|
239
|
+
|
240
|
+
general_hash
|
241
|
+
end
|
242
|
+
|
243
|
+
# @param xmi_id [String]
|
244
|
+
# @return [Lutaml::Model::Serializable]
|
245
|
+
def get_general_node(xmi_id)
|
246
|
+
find_packaged_element_by_id(xmi_id)
|
247
|
+
end
|
248
|
+
|
249
|
+
# @param general_node [Lutaml::Model::Serializable]
|
250
|
+
# @return [Hash]
|
251
|
+
def get_general_attributes(general_node)
|
252
|
+
serialize_class_attributes(general_node, with_assoc: true)
|
253
|
+
end
|
254
|
+
|
255
|
+
# @param general_node [Lutaml::Model::Serializable]
|
256
|
+
# @return [String]
|
257
|
+
def get_next_general_node_id(general_node)
|
258
|
+
general_node.generalization.first&.general
|
259
|
+
end
|
260
|
+
|
261
|
+
# @param general_id [String]
|
262
|
+
# @return [Array<Hash>]
|
263
|
+
def get_general_hash(general_id)
|
264
|
+
general_node = get_general_node(general_id)
|
265
|
+
return [] unless general_node
|
266
|
+
|
267
|
+
general_node_attrs = get_general_attributes(general_node)
|
268
|
+
general_upper_klass = find_upper_level_packaged_element(general_id)
|
269
|
+
next_general_node_id = get_next_general_node_id(general_node)
|
270
|
+
|
271
|
+
[
|
272
|
+
{
|
273
|
+
general_id: general_id,
|
274
|
+
general_name: general_node.name,
|
275
|
+
general_attributes: general_node_attrs,
|
276
|
+
general_upper_klass: general_upper_klass,
|
277
|
+
general: {},
|
278
|
+
},
|
279
|
+
next_general_node_id,
|
280
|
+
]
|
281
|
+
end
|
282
|
+
|
283
|
+
# @param id [String]
|
284
|
+
# @return [Lutaml::Model::Serializable]
|
285
|
+
def find_packaged_element_by_id(id)
|
286
|
+
all_packaged_elements.find { |e| e.id == id }
|
287
|
+
end
|
288
|
+
|
289
|
+
# @param id [String]
|
290
|
+
# @return [Lutaml::Model::Serializable]
|
291
|
+
def find_upper_level_packaged_element(klass_id)
|
292
|
+
upper_klass = all_packaged_elements.find do |e|
|
293
|
+
e.packaged_element.find { |pe| pe.id == klass_id }
|
294
|
+
end
|
295
|
+
upper_klass&.name
|
296
|
+
end
|
297
|
+
|
298
|
+
# @param path [String]
|
299
|
+
# @return [Lutaml::Model::Serializable]
|
300
|
+
def find_klass_packaged_element(path)
|
301
|
+
lutaml_path = Lutaml::Path.parse(path)
|
302
|
+
if lutaml_path.segments.count == 1
|
303
|
+
return find_klass_packaged_element_by_name(path)
|
304
|
+
end
|
305
|
+
|
306
|
+
find_klass_packaged_element_by_path(lutaml_path)
|
307
|
+
end
|
308
|
+
|
309
|
+
# @param path [Lutaml::Path::ElementPath]
|
310
|
+
# @return [Lutaml::Model::Serializable]
|
311
|
+
def find_klass_packaged_element_by_path(path)
|
312
|
+
if path.absolute?
|
313
|
+
iterate_packaged_element(
|
314
|
+
@xmi_root_model.model, path.segments.map(&:name)
|
315
|
+
)
|
316
|
+
else
|
317
|
+
iterate_relative_packaged_element(path.segments.map(&:name))
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# @param name_array [Array<String>]
|
322
|
+
# @return [Lutaml::Model::Serializable]
|
323
|
+
def iterate_relative_packaged_element(name_array)
|
324
|
+
# match the first element in the name_array
|
325
|
+
matched_elements = all_packaged_elements.select do |e|
|
326
|
+
e.type?("uml:Package") && e.name == name_array[0]
|
327
|
+
end
|
328
|
+
|
329
|
+
# match the rest elements in the name_array
|
330
|
+
result = matched_elements.map do |e|
|
331
|
+
iterate_packaged_element(e, name_array, type: "uml:Class")
|
332
|
+
end
|
333
|
+
|
334
|
+
result.compact.first
|
335
|
+
end
|
336
|
+
|
337
|
+
# @param model [Lutaml::Model::Serializable]
|
338
|
+
# @param name_array [Array<String>]
|
339
|
+
# @param index: [Integer]
|
340
|
+
# @param type: [String]
|
341
|
+
# @return [Lutaml::Model::Serializable]
|
342
|
+
def iterate_packaged_element(model, name_array,
|
343
|
+
index: 1, type: "uml:Package")
|
344
|
+
return model if index == name_array.count
|
345
|
+
|
346
|
+
model = model.packaged_element.find do |p|
|
347
|
+
p.name == name_array[index] && p.type?(type)
|
348
|
+
end
|
349
|
+
|
350
|
+
return nil if model.nil?
|
351
|
+
|
352
|
+
index += 1
|
353
|
+
type = index == name_array.count - 1 ? "uml:Class" : "uml:Package"
|
354
|
+
iterate_packaged_element(model, name_array, index: index, type: type)
|
355
|
+
end
|
356
|
+
|
357
|
+
# @param name [String]
|
358
|
+
# @return [Lutaml::Model::Serializable]
|
359
|
+
def find_klass_packaged_element_by_name(name)
|
360
|
+
all_packaged_elements.find do |e|
|
361
|
+
e.type?("uml:Class") && e.name == name
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# @param name [String]
|
366
|
+
# @return [Lutaml::Model::Serializable]
|
367
|
+
def find_packaged_element_by_name(name)
|
368
|
+
all_packaged_elements.find do |e|
|
369
|
+
e.name == name
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# @param package [Lutaml::Model::Serializable]
|
374
|
+
# @return [Array<Hash>]
|
375
|
+
# @note xpath ./packagedElement[@xmi:type="uml:Enumeration"]
|
376
|
+
def serialize_model_enums(package)
|
377
|
+
package.packaged_element.select { |e| e.type?("uml:Enumeration") }
|
378
|
+
.map do |enum|
|
379
|
+
{
|
380
|
+
xmi_id: enum.id,
|
381
|
+
name: enum.name,
|
382
|
+
values: serialize_enum_owned_literal(enum),
|
383
|
+
definition: doc_node_attribute_value(enum.id, "documentation"),
|
384
|
+
stereotype: doc_node_attribute_value(enum.id, "stereotype"),
|
385
|
+
}
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
# @param model [Lutaml::Model::Serializable]
|
390
|
+
# @return [Hash]
|
391
|
+
# @note xpath .//ownedLiteral[@xmi:type="uml:EnumerationLiteral"]
|
392
|
+
def serialize_enum_owned_literal(enum) # rubocop:disable Metrics/MethodLength
|
393
|
+
owned_literals = enum.owned_literal.select do |owned_literal|
|
394
|
+
owned_literal.type? "uml:EnumerationLiteral"
|
395
|
+
end
|
396
|
+
|
397
|
+
owned_literals.map do |owned_literal|
|
398
|
+
# xpath .//type
|
399
|
+
uml_type_id = owned_literal&.uml_type&.idref
|
400
|
+
|
401
|
+
{
|
402
|
+
name: owned_literal.name,
|
403
|
+
type: lookup_entity_name(uml_type_id) || uml_type_id,
|
404
|
+
definition: lookup_attribute_documentation(owned_literal.id),
|
405
|
+
}
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
# @param model [Lutaml::Model::Serializable]
|
410
|
+
# @return [Array<Hash>]
|
411
|
+
# @note xpath ./packagedElement[@xmi:type="uml:DataType"]
|
412
|
+
def serialize_model_data_types(model) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
413
|
+
all_data_type_elements = []
|
414
|
+
select_all_packaged_elements(all_data_type_elements, model,
|
415
|
+
"uml:DataType")
|
416
|
+
all_data_type_elements.map do |klass|
|
417
|
+
{
|
418
|
+
xmi_id: klass.id,
|
419
|
+
name: klass.name,
|
420
|
+
attributes: serialize_class_attributes(klass),
|
421
|
+
operations: serialize_class_operations(klass),
|
422
|
+
associations: serialize_model_associations(klass.id),
|
423
|
+
constraints: serialize_class_constraints(klass.id),
|
424
|
+
is_abstract: doc_node_attribute_value(klass.id, "isAbstract"),
|
425
|
+
definition: doc_node_attribute_value(klass.id, "documentation"),
|
426
|
+
stereotype: doc_node_attribute_value(klass.id, "stereotype"),
|
427
|
+
}
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
# @param node_id [String]
|
432
|
+
# @return [Array<Hash>]
|
433
|
+
# @note xpath %(//diagrams/diagram/model[@package="#{node['xmi:id']}"])
|
434
|
+
def serialize_model_diagrams(node_id, with_package: false) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
435
|
+
diagrams = @xmi_root_model.extension.diagrams.diagram.select do |d|
|
436
|
+
d.model.package == node_id
|
437
|
+
end
|
438
|
+
|
439
|
+
diagrams.map do |diagram|
|
440
|
+
h = {
|
441
|
+
xmi_id: diagram.id,
|
442
|
+
name: diagram.properties.name,
|
443
|
+
definition: diagram.properties.documentation,
|
444
|
+
}
|
445
|
+
|
446
|
+
if with_package
|
447
|
+
package_id = diagram.model.package
|
448
|
+
h[:package_id] = package_id
|
449
|
+
h[:package_name] = find_packaged_element_by_id(package_id)&.name
|
450
|
+
end
|
451
|
+
|
452
|
+
h
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# @param xmi_id [String]
|
457
|
+
# @return [Array<Hash>]
|
458
|
+
# @note xpath %(//element[@xmi:idref="#{xmi_id}"]/links/*)
|
459
|
+
def serialize_model_associations(xmi_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
460
|
+
matched_element = @xmi_root_model.extension.elements.element
|
461
|
+
.find { |e| e.idref == xmi_id }
|
462
|
+
|
463
|
+
return if !matched_element ||
|
464
|
+
!matched_element.links ||
|
465
|
+
matched_element.links.association.empty?
|
466
|
+
|
467
|
+
matched_element.links.association.map do |assoc|
|
468
|
+
link_member = assoc.start == xmi_id ? "end" : "start"
|
469
|
+
linke_owner_name = link_member == "start" ? "end" : "start"
|
470
|
+
|
471
|
+
member_end, member_end_type, member_end_cardinality,
|
472
|
+
member_end_attribute_name, member_end_xmi_id =
|
473
|
+
serialize_member_type(xmi_id, assoc, link_member)
|
474
|
+
|
475
|
+
owner_end = serialize_owned_type(xmi_id, assoc, linke_owner_name)
|
476
|
+
|
477
|
+
if member_end && ((member_end_type != "aggregation") ||
|
478
|
+
(member_end_type == "aggregation" && member_end_attribute_name))
|
479
|
+
|
480
|
+
doc_node_name = (link_member == "start" ? "source" : "target")
|
481
|
+
definition = fetch_definition_node_value(assoc.id, doc_node_name)
|
482
|
+
|
483
|
+
{
|
484
|
+
xmi_id: assoc.id,
|
485
|
+
member_end: member_end,
|
486
|
+
member_end_type: member_end_type,
|
487
|
+
member_end_cardinality: member_end_cardinality,
|
488
|
+
member_end_attribute_name: member_end_attribute_name,
|
489
|
+
member_end_xmi_id: member_end_xmi_id,
|
490
|
+
owner_end: owner_end,
|
491
|
+
owner_end_xmi_id: xmi_id,
|
492
|
+
definition: definition,
|
493
|
+
}
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
# @param link_id [String]
|
499
|
+
# @return [Lutaml::Model::Serializable]
|
500
|
+
# @note xpath %(//connector[@xmi:idref="#{link_id}"])
|
501
|
+
def fetch_connector(link_id)
|
502
|
+
@xmi_root_model.extension.connectors.connector.find do |con|
|
503
|
+
con.idref == link_id
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
# @param link_id [String]
|
508
|
+
# @param node_name [String] source or target
|
509
|
+
# @return [String]
|
510
|
+
# @note xpath
|
511
|
+
# %(//connector[@xmi:idref="#{link_id}"]/#{node_name}/documentation)
|
512
|
+
def fetch_definition_node_value(link_id, node_name)
|
513
|
+
connector_node = fetch_connector(link_id)
|
514
|
+
connector_node.send(node_name.to_sym).documentation
|
515
|
+
end
|
516
|
+
|
517
|
+
# @param klass [Lutaml::Model::Serializable]
|
518
|
+
# @return [Array<Hash>]
|
519
|
+
# @note xpath .//ownedOperation
|
520
|
+
def serialize_class_operations(klass) # rubocop:disable Metrics/MethodLength
|
521
|
+
klass.owned_operation.map do |operation|
|
522
|
+
uml_type = operation.uml_type.first
|
523
|
+
uml_type_idref = uml_type.idref if uml_type
|
524
|
+
|
525
|
+
if operation.association.nil?
|
526
|
+
{
|
527
|
+
id: operation.id,
|
528
|
+
xmi_id: uml_type_idref,
|
529
|
+
name: operation.name,
|
530
|
+
definition: lookup_attribute_documentation(operation.id),
|
531
|
+
}
|
532
|
+
end
|
533
|
+
end.compact
|
534
|
+
end
|
535
|
+
|
536
|
+
# @param klass_id [String]
|
537
|
+
# @return [Array<Hash>]
|
538
|
+
# @note xpath ./constraints/constraint
|
539
|
+
def serialize_class_constraints(klass_id) # rubocop:disable Metrics/MethodLength
|
540
|
+
connector_node = fetch_connector(klass_id)
|
541
|
+
|
542
|
+
if connector_node
|
543
|
+
# In ea-xmi-2.5.1, constraints are moved to source/target under
|
544
|
+
# connectors
|
545
|
+
constraints = %i[source target].map do |st|
|
546
|
+
connector_node.send(st).constraints.constraint
|
547
|
+
end.flatten
|
548
|
+
|
549
|
+
constraints.map do |constraint|
|
550
|
+
{
|
551
|
+
name: HTMLEntities.new.decode(constraint.name),
|
552
|
+
type: constraint.type,
|
553
|
+
weight: constraint.weight,
|
554
|
+
status: constraint.status,
|
555
|
+
}
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
# @param owner_xmi_id [String]
|
561
|
+
# @param link [Lutaml::Model::Serializable]
|
562
|
+
# @param link_member_name [String]
|
563
|
+
# @return [String]
|
564
|
+
def serialize_owned_type(owner_xmi_id, link, linke_owner_name)
|
565
|
+
case link.name
|
566
|
+
when "NoteLink"
|
567
|
+
return
|
568
|
+
when "Generalization"
|
569
|
+
return generalization_association(owner_xmi_id, link)
|
570
|
+
end
|
571
|
+
|
572
|
+
xmi_id = link.send(linke_owner_name.to_sym)
|
573
|
+
lookup_entity_name(xmi_id) || connector_source_name(xmi_id)
|
574
|
+
|
575
|
+
# not necessary
|
576
|
+
# if link.name == "Association"
|
577
|
+
# owned_cardinality, owned_attribute_name =
|
578
|
+
# fetch_assoc_connector(link.id, "source")
|
579
|
+
# else
|
580
|
+
# owned_cardinality, owned_attribute_name =
|
581
|
+
# fetch_owned_attribute_node(xmi_id)
|
582
|
+
# end
|
583
|
+
# [owner_end, owned_cardinality, owned_attribute_name]
|
584
|
+
# owner_end
|
585
|
+
end
|
586
|
+
|
587
|
+
# @param owner_xmi_id [String]
|
588
|
+
# @param link [Lutaml::Model::Serializable]
|
589
|
+
# @return [Array<String, String>]
|
590
|
+
def serialize_member_end(owner_xmi_id, link) # rubocop:disable Metrics/MethodLength
|
591
|
+
case link.name
|
592
|
+
when "NoteLink"
|
593
|
+
return
|
594
|
+
when "Generalization"
|
595
|
+
return generalization_association(owner_xmi_id, link)
|
596
|
+
end
|
597
|
+
|
598
|
+
xmi_id = link.start
|
599
|
+
source_or_target = :source
|
600
|
+
|
601
|
+
if link.start == owner_xmi_id
|
602
|
+
xmi_id = link.end
|
603
|
+
source_or_target = :target
|
604
|
+
end
|
605
|
+
|
606
|
+
member_end = member_end_name(xmi_id, source_or_target, link.name)
|
607
|
+
[member_end, xmi_id]
|
608
|
+
end
|
609
|
+
|
610
|
+
# @param xmi_id [String]
|
611
|
+
# @param source_or_target [Symbol]
|
612
|
+
# @return [String]
|
613
|
+
def member_end_name(xmi_id, source_or_target, link_name) # rubocop:disable Metrics/MethodLength
|
614
|
+
connector_label = connector_labels(xmi_id, source_or_target)
|
615
|
+
entity_name = lookup_entity_name(xmi_id)
|
616
|
+
connector_name = connector_name_by_source_or_target(
|
617
|
+
xmi_id, source_or_target
|
618
|
+
)
|
619
|
+
|
620
|
+
case link_name
|
621
|
+
when "Aggregation"
|
622
|
+
connector_label || entity_name || connector_name
|
623
|
+
else
|
624
|
+
entity_name || connector_name
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
# @param owner_xmi_id [String]
|
629
|
+
# @param link [Lutaml::Model::Serializable]
|
630
|
+
# @param link_member_name [String]
|
631
|
+
# @return [Array<String, String, Hash, String, String>]
|
632
|
+
def serialize_member_type(owner_xmi_id, link, link_member_name)
|
633
|
+
member_end, xmi_id = serialize_member_end(owner_xmi_id, link)
|
634
|
+
|
635
|
+
if link.name == "Association"
|
636
|
+
connector_type = link_member_name == "start" ? "source" : "target"
|
637
|
+
member_end_cardinality, member_end_attribute_name =
|
638
|
+
fetch_assoc_connector(link.id, connector_type)
|
639
|
+
else
|
640
|
+
member_end_cardinality, member_end_attribute_name =
|
641
|
+
fetch_owned_attribute_node(xmi_id)
|
642
|
+
end
|
643
|
+
|
644
|
+
[member_end, "aggregation", member_end_cardinality,
|
645
|
+
member_end_attribute_name, xmi_id]
|
646
|
+
end
|
647
|
+
|
648
|
+
# @param link_id [String]
|
649
|
+
# @param connector_type [String]
|
650
|
+
# @return [Array<Hash, String>]
|
651
|
+
# @note xpath %(//connector[@xmi:idref="#{link_id}"]/#{connector_type})
|
652
|
+
def fetch_assoc_connector(link_id, connector_type) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
653
|
+
assoc_connector = fetch_connector(link_id).send(connector_type.to_sym)
|
654
|
+
|
655
|
+
if assoc_connector
|
656
|
+
assoc_connector_type = assoc_connector.type
|
657
|
+
if assoc_connector_type&.multiplicity
|
658
|
+
cardinality = assoc_connector_type.multiplicity.split("..")
|
659
|
+
cardinality.unshift("1") if cardinality.length == 1
|
660
|
+
min, max = cardinality
|
661
|
+
end
|
662
|
+
assoc_connector_role = assoc_connector.role
|
663
|
+
# Does role has name attribute? Or get name from model?
|
664
|
+
# attribute_name = assoc_connector_role.name if assoc_connector_role
|
665
|
+
attribute_name = assoc_connector.model.name if assoc_connector_role
|
666
|
+
cardinality = cardinality_min_max_value(min, max)
|
667
|
+
end
|
668
|
+
|
669
|
+
[cardinality, attribute_name]
|
670
|
+
end
|
671
|
+
|
672
|
+
# @param owner_xmi_id [String]
|
673
|
+
# @param link [Lutaml::Model::Serializable]
|
674
|
+
# @return [Array<String, String, Hash, String, String>]
|
675
|
+
# @note match return value of serialize_member_type
|
676
|
+
def generalization_association(owner_xmi_id, link) # rubocop:disable Metrics/MethodLength
|
677
|
+
member_end_type = "generalization"
|
678
|
+
xmi_id = link.start
|
679
|
+
source_or_target = :source
|
680
|
+
|
681
|
+
if link.start == owner_xmi_id
|
682
|
+
member_end_type = "inheritance"
|
683
|
+
xmi_id = link.end
|
684
|
+
source_or_target = :target
|
685
|
+
end
|
686
|
+
|
687
|
+
member_end = member_end_name(xmi_id, source_or_target, link.name)
|
688
|
+
|
689
|
+
member_end_cardinality, _member_end_attribute_name =
|
690
|
+
fetch_owned_attribute_node(xmi_id)
|
691
|
+
|
692
|
+
[member_end, member_end_type, member_end_cardinality, nil, xmi_id]
|
693
|
+
end
|
694
|
+
|
695
|
+
# Multiple items if search type is idref. Should search association?
|
696
|
+
# @param xmi_id [String]
|
697
|
+
# @return [Array<Hash, String>]
|
698
|
+
# @note xpath
|
699
|
+
# %(//ownedAttribute[@association]/type[@xmi:idref="#{xmi_id}"])
|
700
|
+
def fetch_owned_attribute_node(xmi_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
701
|
+
all_elements = all_packaged_elements
|
702
|
+
|
703
|
+
owned_attributes = all_elements.map(&:owned_attribute).flatten
|
704
|
+
oa = owned_attributes.find do |a|
|
705
|
+
!!a.association && a.uml_type && a.uml_type.idref == xmi_id
|
706
|
+
end
|
707
|
+
|
708
|
+
if oa
|
709
|
+
cardinality = cardinality_min_max_value(
|
710
|
+
oa.lower_value&.value, oa.upper_value&.value
|
711
|
+
)
|
712
|
+
oa_name = oa.name
|
713
|
+
end
|
714
|
+
|
715
|
+
[cardinality, oa_name]
|
716
|
+
end
|
717
|
+
|
718
|
+
# @param klass_id [String]
|
719
|
+
# @return [Lutaml::Model::Serializable]
|
720
|
+
# @note xpath %(//element[@xmi:idref="#{klass['xmi:id']}"])
|
721
|
+
def fetch_element(klass_id)
|
722
|
+
@xmi_root_model.extension.elements.element.find do |e|
|
723
|
+
e.idref == klass_id
|
724
|
+
end
|
725
|
+
end
|
726
|
+
|
727
|
+
# @param klass [Lutaml::Model::Serializable]
|
728
|
+
# @param with_assoc [Boolean]
|
729
|
+
# @return [Array<Hash>]
|
730
|
+
# @note xpath .//ownedAttribute[@xmi:type="uml:Property"]
|
731
|
+
def serialize_class_attributes(klass, with_assoc: false) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
732
|
+
klass.owned_attribute.select { |attr| attr.type?("uml:Property") }
|
733
|
+
.map do |oa|
|
734
|
+
if with_assoc || oa.association.nil?
|
735
|
+
attrs = build_class_attributes(oa)
|
736
|
+
|
737
|
+
if with_assoc && oa.association
|
738
|
+
attrs[:association] = oa.association
|
739
|
+
attrs[:definition] = loopup_assoc_def(oa.association)
|
740
|
+
attrs[:type_ns] = get_ns_by_xmi_id(attrs[:xmi_id])
|
741
|
+
end
|
742
|
+
|
743
|
+
attrs
|
744
|
+
end
|
745
|
+
end.compact
|
746
|
+
end
|
747
|
+
|
748
|
+
def loopup_assoc_def(association)
|
749
|
+
connector = fetch_connector(association)
|
750
|
+
connector&.documentation&.value
|
751
|
+
end
|
752
|
+
|
753
|
+
# @return [Array<Hash>]
|
754
|
+
def serialize_gml_attributes
|
755
|
+
element = find_packaged_element_by_name("_Feature")
|
756
|
+
attrs = serialize_class_attributes(element, with_assoc: true)
|
757
|
+
attrs.each { |attr| attr[:upper_klass] = "gml" }
|
758
|
+
end
|
759
|
+
|
760
|
+
# @return [Array<Hash>]
|
761
|
+
def serialize_core_attributes
|
762
|
+
element = find_packaged_element_by_name("_CityObject")
|
763
|
+
attrs = serialize_class_attributes(element, with_assoc: false)
|
764
|
+
attrs.each { |attr| attr[:upper_klass] = "core" }
|
765
|
+
end
|
766
|
+
|
767
|
+
# @return [Array<Hash>]
|
768
|
+
def select_gen_attributes
|
769
|
+
element = find_packaged_element_by_name("gen")
|
770
|
+
gen_attr_element = find_packaged_element_by_name("_genericAttribute")
|
771
|
+
|
772
|
+
element.packaged_element.select do |e|
|
773
|
+
e.type?("uml:Class") &&
|
774
|
+
e.generalization&.first&.general == gen_attr_element.id
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
# @return [Array<Hash>]
|
779
|
+
def serialize_gen_attributes
|
780
|
+
klasses = select_gen_attributes
|
781
|
+
|
782
|
+
klasses.map do |klass|
|
783
|
+
attr = serialize_class_attributes(klass, with_assoc: false)
|
784
|
+
attr.first[:name] = klass.name
|
785
|
+
attr.first[:type] = "gen:#{klass.name}"
|
786
|
+
attr.first[:upper_klass] = "gen"
|
787
|
+
attr
|
788
|
+
end.flatten!
|
789
|
+
end
|
790
|
+
|
791
|
+
# @param type [String]
|
792
|
+
# @return [String]
|
793
|
+
def get_ns_by_type(type)
|
794
|
+
return unless type
|
795
|
+
|
796
|
+
p = find_klass_packaged_element_by_name(type)
|
797
|
+
return unless p
|
798
|
+
|
799
|
+
find_upper_level_packaged_element(p.id)
|
800
|
+
end
|
801
|
+
|
802
|
+
# @param xmi_id [String]
|
803
|
+
# @return [String]
|
804
|
+
def get_ns_by_xmi_id(xmi_id)
|
805
|
+
return unless xmi_id
|
806
|
+
|
807
|
+
p = find_packaged_element_by_id(xmi_id)
|
808
|
+
return unless p
|
809
|
+
|
810
|
+
find_upper_level_packaged_element(p.id)
|
811
|
+
end
|
812
|
+
|
813
|
+
# @param klass_id [String]
|
814
|
+
# @return [Array<Hash>]
|
815
|
+
def build_class_attributes(owned_attr) # rubocop:disable Metrics/MethodLength
|
816
|
+
uml_type = owned_attr.uml_type
|
817
|
+
uml_type_idref = uml_type.idref if uml_type
|
818
|
+
|
819
|
+
{
|
820
|
+
id: owned_attr.id,
|
821
|
+
name: owned_attr.name,
|
822
|
+
type: lookup_entity_name(uml_type_idref) || uml_type_idref,
|
823
|
+
xmi_id: uml_type_idref,
|
824
|
+
is_derived: owned_attr.is_derived,
|
825
|
+
cardinality: cardinality_min_max_value(
|
826
|
+
owned_attr.lower_value&.value,
|
827
|
+
owned_attr.upper_value&.value,
|
828
|
+
),
|
829
|
+
definition: lookup_attribute_documentation(owned_attr.id),
|
830
|
+
}
|
831
|
+
end
|
832
|
+
|
833
|
+
# @param min [String]
|
834
|
+
# @param max [String]
|
835
|
+
# @return [Hash]
|
836
|
+
def cardinality_min_max_value(min, max)
|
837
|
+
{
|
838
|
+
min: min,
|
839
|
+
max: max,
|
840
|
+
}
|
841
|
+
end
|
842
|
+
|
843
|
+
# @node [Lutaml::Model::Serializable]
|
844
|
+
# @attr_name [String]
|
845
|
+
# @return [String]
|
846
|
+
# @note xpath %(//element[@xmi:idref="#{xmi_id}"]/properties)
|
847
|
+
def doc_node_attribute_value(node_id, attr_name)
|
848
|
+
doc_node = fetch_element(node_id)
|
849
|
+
return unless doc_node
|
850
|
+
|
851
|
+
doc_node.properties&.send(
|
852
|
+
Lutaml::Model::Utils.snake_case(attr_name).to_sym,
|
853
|
+
)
|
854
|
+
end
|
855
|
+
|
856
|
+
# @param xmi_id [String]
|
857
|
+
# @return [Lutaml::Model::Serializable]
|
858
|
+
# @note xpath %(//attribute[@xmi:idref="#{xmi_id}"])
|
859
|
+
def fetch_attribute_node(xmi_id)
|
860
|
+
attribute_node = nil
|
861
|
+
@xmi_root_model.extension.elements.element.each do |e|
|
862
|
+
if e.attributes&.attribute
|
863
|
+
e.attributes.attribute.each do |a|
|
864
|
+
attribute_node = a if a.idref == xmi_id
|
865
|
+
end
|
866
|
+
end
|
867
|
+
end
|
868
|
+
attribute_node
|
869
|
+
end
|
870
|
+
|
871
|
+
# @param xmi_id [String]
|
872
|
+
# @return [String]
|
873
|
+
# @note xpath %(//attribute[@xmi:idref="#{xmi_id}"]/documentation)
|
874
|
+
def lookup_attribute_documentation(xmi_id)
|
875
|
+
attribute_node = fetch_attribute_node(xmi_id)
|
876
|
+
|
877
|
+
return unless attribute_node&.documentation
|
878
|
+
|
879
|
+
attribute_node&.documentation&.value
|
880
|
+
end
|
881
|
+
|
882
|
+
# @param xmi_id [String]
|
883
|
+
# @return [String]
|
884
|
+
def lookup_element_prop_documentation(xmi_id)
|
885
|
+
element_node = @xmi_root_model.extension.elements.element.find do |e|
|
886
|
+
e.idref == xmi_id
|
887
|
+
end
|
888
|
+
|
889
|
+
return unless element_node&.properties
|
890
|
+
|
891
|
+
element_node&.properties&.documentation
|
892
|
+
end
|
893
|
+
|
894
|
+
# @param xmi_id [String]
|
895
|
+
# @return [String]
|
896
|
+
def lookup_entity_name(xmi_id)
|
897
|
+
model_node_name_by_xmi_id(xmi_id) if @xmi_cache.empty?
|
898
|
+
@xmi_cache[xmi_id]
|
899
|
+
end
|
900
|
+
|
901
|
+
# @param xmi_id [String]
|
902
|
+
# @param source_or_target [String]
|
903
|
+
# @return [String]
|
904
|
+
def connector_node_by_id(xmi_id, source_or_target)
|
905
|
+
@xmi_root_model.extension.connectors.connector.find do |con|
|
906
|
+
con.send(source_or_target.to_sym).idref == xmi_id
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
# @param xmi_id [String]
|
911
|
+
# @param source_or_target [String]
|
912
|
+
# @return [String]
|
913
|
+
def connector_name_by_source_or_target(xmi_id, source_or_target)
|
914
|
+
node = connector_node_by_id(xmi_id, source_or_target)
|
915
|
+
return if node.nil? ||
|
916
|
+
node.send(source_or_target.to_sym).nil? ||
|
917
|
+
node.send(source_or_target.to_sym).model.nil?
|
918
|
+
|
919
|
+
node.send(source_or_target.to_sym).model.name
|
920
|
+
end
|
921
|
+
|
922
|
+
# @param xmi_id [String]
|
923
|
+
# @param source_or_target [String]
|
924
|
+
# @return [String]
|
925
|
+
def connector_labels(xmi_id, source_or_target)
|
926
|
+
node = connector_node_by_id(xmi_id, source_or_target)
|
927
|
+
return if node.nil?
|
928
|
+
|
929
|
+
node.labels&.rt || node.labels&.lt
|
930
|
+
end
|
931
|
+
|
932
|
+
# @param xmi_id [String]
|
933
|
+
# @return [String]
|
934
|
+
# @note xpath %(//source[@xmi:idref="#{xmi_id}"]/model)
|
935
|
+
def connector_source_name(xmi_id)
|
936
|
+
connector_name_by_source_or_target(xmi_id, :source)
|
937
|
+
end
|
938
|
+
|
939
|
+
# @param xmi_id [String]
|
940
|
+
# @return [String]
|
941
|
+
# @note xpath %(//target[@xmi:idref="#{xmi_id}"]/model)
|
942
|
+
def connector_target_name(xmi_id)
|
943
|
+
connector_name_by_source_or_target(xmi_id, :target)
|
944
|
+
end
|
945
|
+
|
946
|
+
# @param xmi_id [String]
|
947
|
+
# @return [String]
|
948
|
+
# @note xpath %(//*[@xmi:id="#{xmi_id}"])
|
949
|
+
def model_node_name_by_xmi_id(xmi_id)
|
950
|
+
id_name_mapping = Hash.new
|
951
|
+
map_id_name(id_name_mapping, @xmi_root_model)
|
952
|
+
@xmi_cache = id_name_mapping
|
953
|
+
@xmi_cache[xmi_id]
|
954
|
+
end
|
955
|
+
|
956
|
+
# @return [Array<Xmi::Uml::PackagedElement>]
|
957
|
+
def all_packaged_elements
|
958
|
+
all_elements = []
|
959
|
+
packaged_element_roots = @xmi_root_model.model.packaged_element +
|
960
|
+
@xmi_root_model.extension.primitive_types.packaged_element +
|
961
|
+
@xmi_root_model.extension.profiles.profile.map(&:packaged_element)
|
962
|
+
|
963
|
+
packaged_element_roots.flatten.each do |e|
|
964
|
+
select_all_packaged_elements(all_elements, e, nil)
|
965
|
+
end
|
966
|
+
|
967
|
+
all_elements
|
968
|
+
end
|
969
|
+
|
970
|
+
# @param items [Array<Lutaml::Model::Serializable>]
|
971
|
+
# @param model [Lutaml::Model::Serializable]
|
972
|
+
# @param type [String] nil for any
|
973
|
+
def select_all_items(items, model, type, method)
|
974
|
+
iterate_tree(items, model, type, method.to_sym)
|
975
|
+
end
|
976
|
+
|
977
|
+
# @param all_elements [Array<Lutaml::Model::Serializable>]
|
978
|
+
# @param model [Lutaml::Model::Serializable]
|
979
|
+
# @param type [String] nil for any
|
980
|
+
# @note xpath ./packagedElement[@xmi:type="#{type}"]
|
981
|
+
def select_all_packaged_elements(all_elements, model, type)
|
982
|
+
select_all_items(all_elements, model, type, :packaged_element)
|
983
|
+
all_elements.delete_if do |e|
|
984
|
+
!e.is_a?(Xmi::Uml::PackagedElement)
|
985
|
+
end
|
986
|
+
end
|
987
|
+
|
988
|
+
# @param result [Array<Lutaml::Model::Serializable>]
|
989
|
+
# @param node [Lutaml::Model::Serializable]
|
990
|
+
# @param type [String] nil for any
|
991
|
+
# @param children_method [String] method to determine children exist
|
992
|
+
def iterate_tree(result, node, type, children_method) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
993
|
+
result << node if type.nil? || node.type == type
|
994
|
+
return unless node.send(children_method.to_sym)
|
995
|
+
|
996
|
+
node.send(children_method.to_sym).each do |sub_node|
|
997
|
+
if sub_node.send(children_method.to_sym)
|
998
|
+
iterate_tree(result, sub_node, type, children_method)
|
999
|
+
elsif type.nil? || sub_node.type == type
|
1000
|
+
result << sub_node
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
# @param result [Hash]
|
1006
|
+
# @param node [Lutaml::Model::Serializable]
|
1007
|
+
# @note set id as key and name as value into result
|
1008
|
+
# if id and name are found
|
1009
|
+
def map_id_name(result, node) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
1010
|
+
return if node.nil?
|
1011
|
+
|
1012
|
+
if node.is_a?(Array)
|
1013
|
+
node.each do |arr_item|
|
1014
|
+
map_id_name(result, arr_item)
|
1015
|
+
end
|
1016
|
+
elsif node.class.methods.include?(:attributes)
|
1017
|
+
attrs = node.class.attributes
|
1018
|
+
|
1019
|
+
if attrs.has_key?(:id) && attrs.has_key?(:name)
|
1020
|
+
result[node.id] = node.name
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
attrs.each_pair do |k, _v|
|
1024
|
+
map_id_name(result, node.send(k))
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
end
|
1030
|
+
end
|
1031
|
+
end
|