lutaml 0.9.40 → 0.9.42
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/README.adoc +7 -1
- data/docs/lutaml-express.adoc +35 -0
- data/docs/lutaml-sysml.adoc +10 -0
- data/docs/lutaml-uml.adoc +111 -0
- data/docs/lutaml-xmi.adoc +33 -0
- data/exe/lutaml-yaml2uml +1 -1
- data/lib/lutaml/converter/xmi_to_uml.rb +440 -0
- data/lib/lutaml/express.rb +0 -1
- data/lib/lutaml/sysml/allocate.rb +1 -1
- data/lib/lutaml/sysml/allocated.rb +1 -1
- data/lib/lutaml/sysml/binding_connector.rb +1 -1
- data/lib/lutaml/sysml/block.rb +1 -1
- data/lib/lutaml/sysml/constraint_block.rb +1 -1
- data/lib/lutaml/sysml/copy.rb +1 -1
- data/lib/lutaml/sysml/derive_requirement.rb +1 -1
- data/lib/lutaml/sysml/nested_connector_end.rb +1 -1
- data/lib/lutaml/sysml/refine.rb +1 -1
- data/lib/lutaml/sysml/requirement_related.rb +1 -1
- data/lib/lutaml/sysml/satisfy.rb +1 -1
- data/lib/lutaml/sysml/test_case.rb +1 -1
- data/lib/lutaml/sysml/trace.rb +1 -1
- data/lib/lutaml/sysml/verify.rb +1 -1
- data/lib/lutaml/sysml/xmi_file.rb +1 -1
- data/lib/lutaml/sysml.rb +0 -1
- data/lib/lutaml/uml/association_generalization.rb +17 -0
- data/lib/lutaml/uml/class.rb +2 -3
- data/lib/lutaml/uml/classifier.rb +4 -2
- data/lib/lutaml/uml/diagram.rb +7 -0
- data/lib/lutaml/uml/general_attribute.rb +22 -0
- data/lib/lutaml/uml/generalization.rb +35 -0
- data/lib/lutaml/uml/top_element_attribute.rb +4 -0
- data/lib/lutaml/uml.rb +3 -0
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +13 -1
- data/lib/lutaml/xmi/parsers/xml.rb +3 -4
- metadata +11 -10
- data/docs/UML_README.adoc +0 -44
- data/lib/lutaml/converter/xmi_hash_to_uml.rb +0 -196
- data/lib/lutaml/express/README.adoc +0 -55
- data/lib/lutaml/express/version.rb +0 -7
- data/lib/lutaml/sysml/README.md +0 -40
- data/lib/lutaml/sysml/version.rb +0 -5
- data/lib/lutaml/xmi/README.adoc +0 -24
- /data/{LUTAML.adoc → docs/lutaml_syntax.adoc} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85b66d72112efe826e3e86d693b6710915c20df890036b2ce3085054a5227512
|
4
|
+
data.tar.gz: 4f255d33142b96347c7f8efcde22661ae8eff33a7bba7caecbff17f1a7f0362e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4d00853656f53a73d011ace7843d5443a6afd4e3447bdd8f9acfeb1d1a8f1dc6b9e40bfc94f8bdb441dc60ea7495b72d0a48ef203e292923b72c6be028fa4c1
|
7
|
+
data.tar.gz: 9426ded45a58f49d6b3de1b2279ca2bb64327d52dcb2d101314ad734caf70219421ebf00e0c23f59c662e0bbccc436ce47fba04bff666efa6899b0fecdb5f541
|
data/README.adoc
CHANGED
@@ -26,7 +26,7 @@ Directly:
|
|
26
26
|
$ gem install lutaml
|
27
27
|
----
|
28
28
|
|
29
|
-
==
|
29
|
+
== Usages
|
30
30
|
|
31
31
|
=== Parsing
|
32
32
|
|
@@ -100,6 +100,12 @@ $ lutaml -o assets -t png test.lutaml
|
|
100
100
|
|
101
101
|
For additional info refer to `lutaml --help output`.
|
102
102
|
|
103
|
+
== Other Usages
|
104
|
+
|
105
|
+
* link:docs/lutaml-uml.adoc[Usage with Lutaml::Uml]
|
106
|
+
* link:docs/lutaml-express.adoc[Usage with Lutaml::Express]
|
107
|
+
* link:docs/lutaml-xmi.adoc[Usage with Lutaml::XMI]
|
108
|
+
// * link:docs/lutaml-sysml.adoc[Usage with Lutaml::Sysml]
|
103
109
|
|
104
110
|
== Copyright and license
|
105
111
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
= Lutaml::Express
|
2
|
+
|
3
|
+
Lutaml::Express provides functionality to parse and manipulate EXPRESS files,
|
4
|
+
enabling seamless integration with the Lutaml framework.
|
5
|
+
|
6
|
+
== Usages
|
7
|
+
|
8
|
+
The parser `Lutaml::Express::Parsers::Exp` is used to parse EXPRESS schema file
|
9
|
+
`.exp` into `Expressir::Model::Repository` model.
|
10
|
+
|
11
|
+
=== Examples
|
12
|
+
|
13
|
+
.EXPRESS schema file parsing
|
14
|
+
[example]
|
15
|
+
====
|
16
|
+
|
17
|
+
When using the `Lutaml::Express::Parsers::Exp` parser, you can parse an EXPRESS
|
18
|
+
schema file as follows:
|
19
|
+
|
20
|
+
[source,ruby]
|
21
|
+
----
|
22
|
+
require "lutaml"
|
23
|
+
|
24
|
+
Lutaml::Express::Parsers::Exp.parse(File.new("path/to/example.exp"))
|
25
|
+
# => returns Expressir::Model::Repository model
|
26
|
+
----
|
27
|
+
|
28
|
+
|
29
|
+
`Expressir::Model::Repository` is a Lutaml model that can be further processed
|
30
|
+
or converted to other formats.
|
31
|
+
|
32
|
+
Please refer to https://github.com/lutaml/expressir[expressir] or
|
33
|
+
https://github.com/lutaml/lutaml-model[lutaml-model] for more details.
|
34
|
+
|
35
|
+
====
|
@@ -0,0 +1,10 @@
|
|
1
|
+
= Lutaml::Sysml
|
2
|
+
|
3
|
+
Lutaml::Sysml extends Lutaml::Uml by adding concepts relevant to systems
|
4
|
+
engineering, supporting a Model-Based Systems Engineering (MBSE) approach
|
5
|
+
throughout the entire system lifecycle.
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
Lutaml::Sysml provides specialized diagram types and elements for systems engineering modeling.
|
10
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
= Lutaml::Uml
|
2
|
+
|
3
|
+
Lutaml::Uml is a language for specifying UML class diagrams and a tool for
|
4
|
+
converting it into various different formats.
|
5
|
+
|
6
|
+
== Language
|
7
|
+
|
8
|
+
See link:lutaml_syntax.adoc[LutaML syntax]
|
9
|
+
|
10
|
+
== Usages
|
11
|
+
|
12
|
+
Converter executables are available:
|
13
|
+
|
14
|
+
* PlantUML WSD or PUML to LutaML UML: `lutaml-wsd2uml`
|
15
|
+
* LutaML YAML to LutaML UML: `lutaml-yaml2uml`
|
16
|
+
|
17
|
+
=== Examples
|
18
|
+
|
19
|
+
.PlantUML to LutaML UML
|
20
|
+
[example]
|
21
|
+
====
|
22
|
+
|
23
|
+
Given the following PlantUML PUML file `example.puml`:
|
24
|
+
|
25
|
+
[source,plantuml]
|
26
|
+
----
|
27
|
+
@startuml
|
28
|
+
Alice -> Bob: Authentication Request
|
29
|
+
Bob --> Alice: Authentication Response
|
30
|
+
@enduml
|
31
|
+
----
|
32
|
+
|
33
|
+
Running the command:
|
34
|
+
|
35
|
+
```
|
36
|
+
lutaml-wsd2uml example.puml
|
37
|
+
```
|
38
|
+
|
39
|
+
The following results will be produced:
|
40
|
+
|
41
|
+
[source,lutaml]
|
42
|
+
----
|
43
|
+
diagram plantuml-simple.puml {
|
44
|
+
association {
|
45
|
+
owner Alice
|
46
|
+
member Request
|
47
|
+
member_type direct
|
48
|
+
}
|
49
|
+
association {
|
50
|
+
owner Bob
|
51
|
+
member Response
|
52
|
+
member_type direct
|
53
|
+
}
|
54
|
+
}
|
55
|
+
----
|
56
|
+
====
|
57
|
+
|
58
|
+
.LutaML YAML to LutaML UML
|
59
|
+
[example]
|
60
|
+
====
|
61
|
+
|
62
|
+
Given the following LutaML YAML file `Address.yml`:
|
63
|
+
|
64
|
+
[source,yaml]
|
65
|
+
----
|
66
|
+
name: Address
|
67
|
+
modelType: class
|
68
|
+
relations:
|
69
|
+
- target: AddressComponent
|
70
|
+
relationship:
|
71
|
+
source:
|
72
|
+
type: aggregation
|
73
|
+
attributes:
|
74
|
+
address:
|
75
|
+
cardinality:
|
76
|
+
min: 1
|
77
|
+
max: "*"
|
78
|
+
target:
|
79
|
+
type: direct
|
80
|
+
attributes:
|
81
|
+
addressComponent:
|
82
|
+
cardinality:
|
83
|
+
min: 1
|
84
|
+
max: "*"
|
85
|
+
action:
|
86
|
+
verb: comprises
|
87
|
+
direction: target
|
88
|
+
----
|
89
|
+
|
90
|
+
Running the command:
|
91
|
+
|
92
|
+
```
|
93
|
+
lutaml-yaml2uml Address.yml
|
94
|
+
```
|
95
|
+
|
96
|
+
The following results will be produced:
|
97
|
+
|
98
|
+
[source,lutaml]
|
99
|
+
----
|
100
|
+
diagram Address {
|
101
|
+
title ''
|
102
|
+
caption ''
|
103
|
+
association {
|
104
|
+
owner_type aggregation
|
105
|
+
owner
|
106
|
+
member_type direct
|
107
|
+
member AddressComponent
|
108
|
+
}
|
109
|
+
}
|
110
|
+
----
|
111
|
+
====
|
@@ -0,0 +1,33 @@
|
|
1
|
+
= Lutaml::XMI
|
2
|
+
|
3
|
+
Lutaml::XMI provides functionality to parse and manipulate
|
4
|
+
Enterprise Architecture XMI files.
|
5
|
+
|
6
|
+
== Usages
|
7
|
+
|
8
|
+
The parser `Lutaml::XMI::Parsers::XML` is used to parse XMI files into
|
9
|
+
`Lutaml::Uml::Document` model.
|
10
|
+
|
11
|
+
=== Examples
|
12
|
+
|
13
|
+
.Parsing XMI file
|
14
|
+
[example]
|
15
|
+
====
|
16
|
+
|
17
|
+
When using the `Lutaml::XMI::Parsers::XML` parser, you can parse an XMI
|
18
|
+
file as follows:
|
19
|
+
|
20
|
+
[source,ruby]
|
21
|
+
----
|
22
|
+
require "lutaml"
|
23
|
+
|
24
|
+
Lutaml::XMI::Parsers::XML.parse(File.new("path/to/example.xmi"))
|
25
|
+
# => returns Lutaml::Uml::Document model
|
26
|
+
----
|
27
|
+
|
28
|
+
`Lutaml::Uml::Document` model is a Lutaml model that can be further processed or
|
29
|
+
converted to other formats.
|
30
|
+
|
31
|
+
Please refer to https://github.com/lutaml/lutaml-model[lutaml-model] for more details.
|
32
|
+
|
33
|
+
====
|
data/exe/lutaml-yaml2uml
CHANGED
@@ -84,7 +84,7 @@ view_yaml["relations"]&.each do |values|
|
|
84
84
|
process_association(values["source"], values, encountered_relations)
|
85
85
|
end
|
86
86
|
|
87
|
-
view_yaml["imports"]
|
87
|
+
view_yaml["imports"]&.each_key do |entry| # rubocop:disable Metrics/BlockLength
|
88
88
|
import = YAML.safe_load(File.read(File.join(models_path, "#{entry}.yml")))
|
89
89
|
import_name = import["name"] || File.basename(entry)
|
90
90
|
# Class notation
|
@@ -0,0 +1,440 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Converter
|
3
|
+
module XmiToUml
|
4
|
+
def create_uml_document(xmi_model)
|
5
|
+
::Lutaml::Uml::Document.new.tap do |doc|
|
6
|
+
doc.name = xmi_model.model.name
|
7
|
+
doc.packages = create_uml_packages(xmi_model.model)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_uml_packages(model)
|
12
|
+
return [] if model.packaged_element.nil?
|
13
|
+
|
14
|
+
packages = model.packaged_element.select do |e|
|
15
|
+
e.type?("uml:Package")
|
16
|
+
end
|
17
|
+
|
18
|
+
packages.map do |package|
|
19
|
+
create_uml_package(package)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_uml_package(package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
24
|
+
pkg = ::Lutaml::Uml::Package.new
|
25
|
+
pkg.xmi_id = package.id
|
26
|
+
pkg.name = get_package_name(package)
|
27
|
+
pkg.definition = doc_node_attribute_value(package.id, "documentation")
|
28
|
+
pkg.stereotype = doc_node_attribute_value(package.id, "stereotype")
|
29
|
+
|
30
|
+
pkg.packages = create_uml_packages(package)
|
31
|
+
pkg.classes = create_uml_classes(package)
|
32
|
+
pkg.enums = create_uml_enums(package)
|
33
|
+
pkg.data_types = create_uml_data_types(package)
|
34
|
+
pkg.diagrams = create_uml_diagrams(package.id)
|
35
|
+
|
36
|
+
pkg
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_uml_classes(package)
|
40
|
+
return [] if package.packaged_element.nil?
|
41
|
+
|
42
|
+
klasses = package.packaged_element.select do |e|
|
43
|
+
e.type?("uml:Class") || e.type?("uml:AssociationClass") ||
|
44
|
+
e.type?("uml:Interface")
|
45
|
+
end
|
46
|
+
|
47
|
+
klasses.map do |klass|
|
48
|
+
create_uml_class(klass)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_uml_class(klass) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
53
|
+
::Lutaml::Uml::Class.new.tap do |k| # rubocop:disable Metrics/BlockLength
|
54
|
+
k.xmi_id = klass.id
|
55
|
+
k.name = klass.name
|
56
|
+
k.type = klass.type.split(":").last
|
57
|
+
k.is_abstract = doc_node_attribute_value(klass.id, "isAbstract")
|
58
|
+
k.definition = doc_node_attribute_value(klass.id, "documentation")
|
59
|
+
k.stereotype = doc_node_attribute_value(klass.id, "stereotype")
|
60
|
+
|
61
|
+
k.attributes = create_uml_class_attributes(klass)
|
62
|
+
k.associations = create_uml_associations(klass.id)
|
63
|
+
k.operations = create_uml_operations(klass)
|
64
|
+
k.constraints = create_uml_constraints(klass.id)
|
65
|
+
k.association_generalization = create_uml_assoc_generalizations(klass)
|
66
|
+
|
67
|
+
if klass.type?("uml:Class")
|
68
|
+
k.generalization = create_uml_generalization(klass)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_uml_enums(package) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
74
|
+
return [] if package.packaged_element.nil?
|
75
|
+
|
76
|
+
enums = package.packaged_element.select do |e|
|
77
|
+
e.type?("uml:Enumeration")
|
78
|
+
end
|
79
|
+
|
80
|
+
enums.map do |enum|
|
81
|
+
::Lutaml::Uml::Enum.new.tap do |en|
|
82
|
+
en.xmi_id = enum.id
|
83
|
+
en.name = enum.name
|
84
|
+
en.values = create_uml_values(enum)
|
85
|
+
en.definition = doc_node_attribute_value(enum.id, "documentation")
|
86
|
+
en.stereotype = doc_node_attribute_value(enum.id, "stereotype")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_uml_data_types(package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
92
|
+
return [] if package.packaged_element.nil?
|
93
|
+
|
94
|
+
data_types = package.packaged_element.select do |e|
|
95
|
+
e.type?("uml:DataType")
|
96
|
+
end
|
97
|
+
|
98
|
+
data_types.map do |dt|
|
99
|
+
::Lutaml::Uml::DataType.new.tap do |data_type|
|
100
|
+
data_type.xmi_id = dt.id
|
101
|
+
data_type.name = dt.name
|
102
|
+
data_type.is_abstract = doc_node_attribute_value(
|
103
|
+
dt.id, "isAbstract"
|
104
|
+
)
|
105
|
+
data_type.definition = doc_node_attribute_value(
|
106
|
+
dt.id, "documentation"
|
107
|
+
)
|
108
|
+
data_type.stereotype = doc_node_attribute_value(
|
109
|
+
dt.id, "stereotype"
|
110
|
+
)
|
111
|
+
|
112
|
+
data_type.attributes = create_uml_class_attributes(dt)
|
113
|
+
data_type.operations = create_uml_operations(dt)
|
114
|
+
data_type.associations = create_uml_associations(dt.id)
|
115
|
+
data_type.constraints = create_uml_constraints(dt.id)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def create_uml_diagrams(node_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
121
|
+
return [] if @xmi_root_model.extension&.diagrams&.diagram.nil?
|
122
|
+
|
123
|
+
diagrams = @xmi_root_model.extension.diagrams.diagram.select do |d|
|
124
|
+
d.model.package == node_id
|
125
|
+
end
|
126
|
+
|
127
|
+
diagrams.map do |diagram|
|
128
|
+
::Lutaml::Uml::Diagram.new.tap do |dia|
|
129
|
+
dia.xmi_id = diagram.id
|
130
|
+
dia.name = diagram&.properties&.name
|
131
|
+
dia.definition = diagram&.properties&.documentation
|
132
|
+
|
133
|
+
package_id = diagram&.model&.package
|
134
|
+
if package_id
|
135
|
+
dia.package_id = package_id
|
136
|
+
dia.package_name = find_packaged_element_by_id(package_id)&.name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_uml_class_attributes(klass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
143
|
+
return [] if klass.owned_attribute.nil?
|
144
|
+
|
145
|
+
owned_attributes = klass.owned_attribute.select do |attr|
|
146
|
+
attr.type?("uml:Property")
|
147
|
+
end
|
148
|
+
|
149
|
+
owned_attributes.map do |oa|
|
150
|
+
create_uml_attribute(oa)
|
151
|
+
end.compact
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_uml_attribute(owned_attr) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
155
|
+
uml_type = owned_attr.uml_type
|
156
|
+
uml_type_idref = uml_type.idref if uml_type
|
157
|
+
|
158
|
+
::Lutaml::Uml::TopElementAttribute.new.tap do |attr|
|
159
|
+
attr.id = owned_attr.id
|
160
|
+
attr.name = owned_attr.name
|
161
|
+
attr.type = lookup_entity_name(uml_type_idref) || uml_type_idref
|
162
|
+
attr.xmi_id = uml_type_idref
|
163
|
+
attr.is_derived = owned_attr.is_derived
|
164
|
+
attr.cardinality = ::Lutaml::Uml::Cardinality.new.tap do |car|
|
165
|
+
car.min = owned_attr.lower_value&.value
|
166
|
+
car.max = owned_attr.upper_value&.value
|
167
|
+
end
|
168
|
+
attr.definition = lookup_attribute_documentation(owned_attr.id)
|
169
|
+
|
170
|
+
if owned_attr.association
|
171
|
+
attr.association = owned_attr.association
|
172
|
+
attr.definition = loopup_assoc_def(owned_attr.association)
|
173
|
+
attr.type_ns = get_ns_by_xmi_id(attr.xmi_id)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def create_uml_cardinality(hash)
|
179
|
+
::Lutaml::Uml::Cardinality.new.tap do |cardinality|
|
180
|
+
cardinality.min = hash[:min]
|
181
|
+
cardinality.max = hash[:max]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def create_uml_attributes(uml_general_obj) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
186
|
+
upper_klass = uml_general_obj.general_upper_klass
|
187
|
+
gen_attrs = uml_general_obj.general_attributes
|
188
|
+
gen_name = uml_general_obj.general_name
|
189
|
+
|
190
|
+
gen_attrs&.each do |i|
|
191
|
+
name_ns = case i.type_ns
|
192
|
+
when "core", "gml"
|
193
|
+
upper_klass
|
194
|
+
else
|
195
|
+
i.type_ns
|
196
|
+
end
|
197
|
+
name_ns = upper_klass if name_ns.nil?
|
198
|
+
|
199
|
+
i.name_ns = name_ns
|
200
|
+
i.gen_name = gen_name
|
201
|
+
i.name = "" if i.name.nil?
|
202
|
+
end
|
203
|
+
|
204
|
+
gen_attrs
|
205
|
+
end
|
206
|
+
|
207
|
+
def create_uml_generalization(klass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
208
|
+
uml_general_obj, next_general_node_id = get_uml_general(klass.id)
|
209
|
+
return uml_general_obj unless next_general_node_id
|
210
|
+
|
211
|
+
if uml_general_obj.general
|
212
|
+
inherited_props = []
|
213
|
+
inherited_assoc_props = []
|
214
|
+
level = 0
|
215
|
+
|
216
|
+
loop_general_item(
|
217
|
+
uml_general_obj.general,
|
218
|
+
level,
|
219
|
+
inherited_props,
|
220
|
+
inherited_assoc_props,
|
221
|
+
)
|
222
|
+
uml_general_obj.inherited_props = inherited_props.reverse
|
223
|
+
uml_general_obj.inherited_assoc_props = inherited_assoc_props.reverse
|
224
|
+
end
|
225
|
+
|
226
|
+
uml_general_obj
|
227
|
+
end
|
228
|
+
|
229
|
+
def get_uml_general(general_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
230
|
+
general_node = get_general_node(general_id)
|
231
|
+
return [] unless general_node
|
232
|
+
|
233
|
+
general_node_attrs = get_uml_general_attributes(general_node)
|
234
|
+
general_upper_klass = find_upper_level_packaged_element(general_id)
|
235
|
+
next_general_node_id = get_next_general_node_id(general_node)
|
236
|
+
|
237
|
+
uml_general = ::Lutaml::Uml::Generalization.new.tap do |gen|
|
238
|
+
gen.general_id = general_id
|
239
|
+
gen.general_name = general_node.name
|
240
|
+
gen.general_attributes = general_node_attrs
|
241
|
+
gen.general_upper_klass = general_upper_klass
|
242
|
+
gen.name = general_node.name
|
243
|
+
gen.type = general_node.type
|
244
|
+
gen.definition = lookup_general_documentation(general_id)
|
245
|
+
gen.stereotype = doc_node_attribute_value(general_id, "stereotype")
|
246
|
+
|
247
|
+
if next_general_node_id
|
248
|
+
gen.general = set_uml_generalization(
|
249
|
+
next_general_node_id,
|
250
|
+
)
|
251
|
+
gen.has_general = true
|
252
|
+
gen.general_id = general_node.id
|
253
|
+
gen.general_name = general_node.name
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
uml_general.attributes = create_uml_attributes(uml_general)
|
258
|
+
uml_general.owned_props = uml_general.attributes.select do |attr|
|
259
|
+
attr.association.nil?
|
260
|
+
end
|
261
|
+
uml_general.assoc_props = uml_general
|
262
|
+
.attributes.select(&:association)
|
263
|
+
|
264
|
+
[uml_general, next_general_node_id]
|
265
|
+
end
|
266
|
+
|
267
|
+
def get_uml_general_attributes(general_node) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
268
|
+
attrs = create_uml_class_attributes(general_node)
|
269
|
+
|
270
|
+
attrs.map do |attr|
|
271
|
+
::Lutaml::Uml::GeneralAttribute.new.tap do |gen_attr|
|
272
|
+
gen_attr.id = attr.id
|
273
|
+
gen_attr.name = attr.name
|
274
|
+
gen_attr.type = attr.type
|
275
|
+
gen_attr.xmi_id = attr.xmi_id
|
276
|
+
gen_attr.is_derived = !!attr.is_derived
|
277
|
+
gen_attr.cardinality = attr.cardinality
|
278
|
+
gen_attr.definition = attr.definition
|
279
|
+
gen_attr.association = attr.association
|
280
|
+
gen_attr.has_association = !!attr.association
|
281
|
+
gen_attr.type_ns = attr.type_ns
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def set_uml_generalization(general_id)
|
287
|
+
uml_general_obj, next_general_node_id = get_uml_general(general_id)
|
288
|
+
|
289
|
+
if next_general_node_id
|
290
|
+
uml_general_obj.general = set_uml_generalization(
|
291
|
+
next_general_node_id,
|
292
|
+
)
|
293
|
+
uml_general_obj.has_general = true
|
294
|
+
end
|
295
|
+
|
296
|
+
uml_general_obj
|
297
|
+
end
|
298
|
+
|
299
|
+
def loop_general_item( # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
|
300
|
+
general_item, level, inherited_props, inherited_assoc_props
|
301
|
+
)
|
302
|
+
gen_upper_klass = general_item.general_upper_klass
|
303
|
+
gen_name = general_item.general_name
|
304
|
+
|
305
|
+
# reverse the order to show super class first
|
306
|
+
general_item.attributes.reverse_each do |attr|
|
307
|
+
attr.upper_klass = gen_upper_klass
|
308
|
+
attr.gen_name = gen_name
|
309
|
+
attr.level = level
|
310
|
+
|
311
|
+
if attr.association
|
312
|
+
inherited_assoc_props << attr
|
313
|
+
else
|
314
|
+
inherited_props << attr
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
if general_item&.has_general && general_item.general
|
319
|
+
level += 1
|
320
|
+
loop_general_item(
|
321
|
+
general_item.general, level, inherited_props, inherited_assoc_props
|
322
|
+
)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def create_uml_assoc_generalizations(klass)
|
327
|
+
return [] if klass.generalization.nil? || klass.generalization.empty?
|
328
|
+
|
329
|
+
klass.generalization.map do |gen|
|
330
|
+
assoc_gen = ::Lutaml::Uml::AssociationGeneralization.new
|
331
|
+
assoc_gen.id = gen.id
|
332
|
+
assoc_gen.type = gen.type
|
333
|
+
assoc_gen.general = gen.general
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def create_uml_associations(xmi_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
338
|
+
matched_element = @xmi_root_model.extension.elements.element
|
339
|
+
.find { |e| e.idref == xmi_id }
|
340
|
+
|
341
|
+
return if !matched_element || !matched_element.links
|
342
|
+
|
343
|
+
links = []
|
344
|
+
matched_element.links.each do |link|
|
345
|
+
links << link.association if link.association.any?
|
346
|
+
end
|
347
|
+
|
348
|
+
links.flatten.compact.map do |assoc| # rubocop:disable Metrics/BlockLength
|
349
|
+
link_member = assoc.start == xmi_id ? "end" : "start"
|
350
|
+
link_owner = link_member == "start" ? "end" : "start"
|
351
|
+
|
352
|
+
member_end, member_end_type, member_end_cardinality,
|
353
|
+
member_end_attribute_name, member_end_xmi_id =
|
354
|
+
serialize_member_type(xmi_id, assoc, link_member)
|
355
|
+
|
356
|
+
owner_end = serialize_owned_type(xmi_id, assoc, link_owner)
|
357
|
+
doc_node = link_member == "start" ? "source" : "target"
|
358
|
+
definition = fetch_definition_node_value(assoc.id, doc_node)
|
359
|
+
|
360
|
+
if member_end &&
|
361
|
+
(
|
362
|
+
(member_end_type != "aggregation") ||
|
363
|
+
(member_end_type == "aggregation" && member_end_attribute_name)
|
364
|
+
)
|
365
|
+
|
366
|
+
::Lutaml::Uml::Association.new.tap do |association|
|
367
|
+
association.xmi_id = assoc.id
|
368
|
+
association.member_end = member_end
|
369
|
+
association.member_end_type = member_end_type
|
370
|
+
association.member_end_cardinality = create_uml_cardinality(
|
371
|
+
member_end_cardinality,
|
372
|
+
)
|
373
|
+
association.member_end_attribute_name = member_end_attribute_name
|
374
|
+
association.member_end_xmi_id = member_end_xmi_id
|
375
|
+
association.owner_end = owner_end
|
376
|
+
association.owner_end_xmi_id = xmi_id
|
377
|
+
association.definition = definition
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end.compact
|
381
|
+
end
|
382
|
+
|
383
|
+
def create_uml_operations(klass) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
384
|
+
return [] if klass.owned_operation.nil?
|
385
|
+
|
386
|
+
klass.owned_operation.map do |operation|
|
387
|
+
uml_type = operation.uml_type.first
|
388
|
+
uml_type_idref = uml_type.idref if uml_type
|
389
|
+
|
390
|
+
if operation.association.nil?
|
391
|
+
::Lutaml::Uml::Operation.new.tap do |op|
|
392
|
+
op.id = operation.id
|
393
|
+
op.xmi_id = uml_type_idref
|
394
|
+
op.name = operation.name
|
395
|
+
op.definition = lookup_attribute_documentation(operation.id)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end.compact
|
399
|
+
end
|
400
|
+
|
401
|
+
def create_uml_constraints(klass_id) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
402
|
+
connector_node = fetch_connector(klass_id)
|
403
|
+
return [] if connector_node.nil?
|
404
|
+
|
405
|
+
# In ea-xmi-2.5.1, constraints are moved to source/target under
|
406
|
+
# connectors
|
407
|
+
constraints = %i[source target].map do |st|
|
408
|
+
connector_node.send(st).constraints.constraint
|
409
|
+
end.flatten
|
410
|
+
|
411
|
+
constraints.map do |constraint|
|
412
|
+
::Lutaml::Uml::Constraint.new.tap do |con|
|
413
|
+
con.name = HTMLEntities.new.decode(constraint.name)
|
414
|
+
con.type = constraint.type
|
415
|
+
con.weight = constraint.weight
|
416
|
+
con.status = constraint.status
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def create_uml_values(enum) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize
|
422
|
+
return [] if enum.owned_literal.nil?
|
423
|
+
|
424
|
+
owned_literals = enum.owned_literal.select do |owned_literal|
|
425
|
+
owned_literal.type?("uml:EnumerationLiteral")
|
426
|
+
end
|
427
|
+
|
428
|
+
owned_literals.map do |owned_literal|
|
429
|
+
uml_type_id = owned_literal&.uml_type&.idref
|
430
|
+
|
431
|
+
::Lutaml::Uml::Value.new.tap do |value|
|
432
|
+
value.name = owned_literal.name
|
433
|
+
value.type = lookup_entity_name(uml_type_id) || uml_type_id
|
434
|
+
value.definition = lookup_attribute_documentation(owned_literal.id)
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
data/lib/lutaml/express.rb
CHANGED