xmi 0.5.4 → 0.5.6
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 +29 -47
- data/CLAUDE.md +166 -0
- data/README.adoc +9 -27
- data/TODO.perf/01-eliminate-duplicate-nokogiri-parse.md +33 -0
- data/TODO.perf/02-read-only-fast-mode.md +38 -0
- data/TODO.perf/03-register-fallback-idempotency.md +20 -0
- data/TODO.perf/04-pipeline-hash-mutation.md +31 -0
- data/TODO.perf/05-ea-root-single-parse.md +29 -0
- data/docs/migration.md +6 -6
- data/docs/versioning.md +1 -1
- data/lib/tasks/benchmark_runner.rb +1 -1
- data/lib/xmi/custom_profile/abstract.rb +16 -0
- data/lib/xmi/custom_profile/basic_doc.rb +16 -0
- data/lib/xmi/custom_profile/bibliography.rb +16 -0
- data/lib/xmi/custom_profile/edition.rb +18 -0
- data/lib/xmi/custom_profile/enumeration.rb +16 -0
- data/lib/xmi/custom_profile/informative.rb +16 -0
- data/lib/xmi/custom_profile/invariant.rb +16 -0
- data/lib/xmi/custom_profile/number.rb +18 -0
- data/lib/xmi/custom_profile/ocl.rb +16 -0
- data/lib/xmi/custom_profile/persistence.rb +20 -0
- data/lib/xmi/custom_profile/publication_date.rb +18 -0
- data/lib/xmi/custom_profile/year_version.rb +18 -0
- data/lib/xmi/custom_profile.rb +12 -143
- data/lib/xmi/ea_root/code_generation.rb +140 -0
- data/lib/xmi/ea_root/extension_lifecycle.rb +52 -0
- data/lib/xmi/ea_root/namespace_handling.rb +39 -0
- data/lib/xmi/ea_root/xml_parsing.rb +51 -0
- data/lib/xmi/ea_root.rb +14 -407
- data/lib/xmi/namespace_detector.rb +35 -3
- data/lib/xmi/parser_pipeline.rb +9 -9
- data/lib/xmi/sparx/index.rb +2 -2
- data/lib/xmi/sparx/mappings/base_mapping.rb +4 -4
- data/lib/xmi/sparx/mappings.rb +1 -1
- data/lib/xmi/sparx/root.rb +3 -3
- data/lib/xmi/sparx.rb +2 -2
- data/lib/xmi/version.rb +1 -1
- data/lib/xmi/version_registry.rb +11 -8
- metadata +24 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Bibliography < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_class, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "Bibliography"
|
|
10
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
11
|
+
|
|
12
|
+
map_attribute "base_Class", to: :base_class
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Edition < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_package, :string
|
|
7
|
+
attribute :edition, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
element "edition"
|
|
11
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
12
|
+
|
|
13
|
+
map_attribute "base_Package", to: :base_package
|
|
14
|
+
map_attribute "edition", to: :edition
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Enumeration < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_enumeration, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "enumeration"
|
|
10
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
11
|
+
|
|
12
|
+
map_attribute "base_Enumeration", to: :base_enumeration
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Informative < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_package, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "informative"
|
|
10
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
11
|
+
|
|
12
|
+
map_attribute "base_Package", to: :base_package
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Invariant < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_constraint, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "invariant"
|
|
10
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
11
|
+
|
|
12
|
+
map_attribute "base_Constraint", to: :base_constraint
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Number < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_package, :string
|
|
7
|
+
attribute :number, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
element "number"
|
|
11
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
12
|
+
|
|
13
|
+
map_attribute "base_Package", to: :base_package
|
|
14
|
+
map_attribute "number", to: :number
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Ocl < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_constraint, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "OCL"
|
|
10
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
11
|
+
|
|
12
|
+
map_attribute "base_Constraint", to: :base_constraint
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class Persistence < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_class, :string
|
|
7
|
+
attribute :base_enumeration, :string
|
|
8
|
+
attribute :persistence, :string
|
|
9
|
+
|
|
10
|
+
xml do
|
|
11
|
+
element "persistence"
|
|
12
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
13
|
+
|
|
14
|
+
map_attribute "base_Class", to: :base_class
|
|
15
|
+
map_attribute "base_Enumeration", to: :base_enumeration
|
|
16
|
+
map_attribute "persistence", to: :persistence
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class PublicationDate < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_package, :string
|
|
7
|
+
attribute :publication_date, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
element "publicationDate"
|
|
11
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
12
|
+
|
|
13
|
+
map_attribute "base_Package", to: :base_package
|
|
14
|
+
map_attribute "publicationDate", to: :publication_date
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module CustomProfile
|
|
5
|
+
class YearVersion < Lutaml::Model::Serializable
|
|
6
|
+
attribute :base_package, :string
|
|
7
|
+
attribute :year_version, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
element "yearVersion"
|
|
11
|
+
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
12
|
+
|
|
13
|
+
map_attribute "base_Package", to: :base_package
|
|
14
|
+
map_attribute "yearVersion", to: :year_version
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/xmi/custom_profile.rb
CHANGED
|
@@ -2,148 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Xmi
|
|
4
4
|
module CustomProfile
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
attribute :base_class, :string
|
|
18
|
-
|
|
19
|
-
xml do
|
|
20
|
-
element "BasicDoc"
|
|
21
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
22
|
-
|
|
23
|
-
map_attribute "base_Class", to: :base_class
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
class Enumeration < Lutaml::Model::Serializable
|
|
28
|
-
attribute :base_enumeration, :string
|
|
29
|
-
|
|
30
|
-
xml do
|
|
31
|
-
element "enumeration"
|
|
32
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
33
|
-
|
|
34
|
-
map_attribute "base_Enumeration", to: :base_enumeration
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
class Ocl < Lutaml::Model::Serializable
|
|
39
|
-
attribute :base_constraint, :string
|
|
40
|
-
|
|
41
|
-
xml do
|
|
42
|
-
element "OCL"
|
|
43
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
44
|
-
|
|
45
|
-
map_attribute "base_Constraint", to: :base_constraint
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
class Invariant < Lutaml::Model::Serializable
|
|
50
|
-
attribute :base_constraint, :string
|
|
51
|
-
|
|
52
|
-
xml do
|
|
53
|
-
element "invariant"
|
|
54
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
55
|
-
|
|
56
|
-
map_attribute "base_Constraint", to: :base_constraint
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
class PublicationDate < Lutaml::Model::Serializable
|
|
61
|
-
attribute :base_package, :string
|
|
62
|
-
attribute :publication_date, :string
|
|
63
|
-
|
|
64
|
-
xml do
|
|
65
|
-
element "publicationDate"
|
|
66
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
67
|
-
|
|
68
|
-
map_attribute "base_Package", to: :base_package
|
|
69
|
-
map_attribute "publicationDate", to: :publication_date
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
class Edition < Lutaml::Model::Serializable
|
|
74
|
-
attribute :base_package, :string
|
|
75
|
-
attribute :edition, :string
|
|
76
|
-
|
|
77
|
-
xml do
|
|
78
|
-
element "edition"
|
|
79
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
80
|
-
|
|
81
|
-
map_attribute "base_Package", to: :base_package
|
|
82
|
-
map_attribute "edition", to: :edition
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
class Number < Lutaml::Model::Serializable
|
|
87
|
-
attribute :base_package, :string
|
|
88
|
-
attribute :number, :string
|
|
89
|
-
|
|
90
|
-
xml do
|
|
91
|
-
element "number"
|
|
92
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
93
|
-
|
|
94
|
-
map_attribute "base_Package", to: :base_package
|
|
95
|
-
map_attribute "number", to: :number
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
class YearVersion < Lutaml::Model::Serializable
|
|
100
|
-
attribute :base_package, :string
|
|
101
|
-
attribute :year_version, :string
|
|
102
|
-
|
|
103
|
-
xml do
|
|
104
|
-
element "yearVersion"
|
|
105
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
106
|
-
|
|
107
|
-
map_attribute "base_Package", to: :base_package
|
|
108
|
-
map_attribute "yearVersion", to: :year_version
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
class Informative < Lutaml::Model::Serializable
|
|
113
|
-
attribute :base_package, :string
|
|
114
|
-
|
|
115
|
-
xml do
|
|
116
|
-
element "informative"
|
|
117
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
118
|
-
|
|
119
|
-
map_attribute "base_Package", to: :base_package
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
class Persistence < Lutaml::Model::Serializable
|
|
124
|
-
attribute :base_class, :string
|
|
125
|
-
attribute :base_enumeration, :string
|
|
126
|
-
attribute :persistence, :string
|
|
127
|
-
|
|
128
|
-
xml do
|
|
129
|
-
element "persistence"
|
|
130
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
131
|
-
|
|
132
|
-
map_attribute "base_Class", to: :base_class
|
|
133
|
-
map_attribute "base_Enumeration", to: :base_enumeration
|
|
134
|
-
map_attribute "persistence", to: :persistence
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
class Abstract < Lutaml::Model::Serializable
|
|
139
|
-
attribute :base_class, :string
|
|
140
|
-
|
|
141
|
-
xml do
|
|
142
|
-
element "Abstract"
|
|
143
|
-
namespace ::Xmi::Namespace::Sparx::CustomProfile
|
|
144
|
-
|
|
145
|
-
map_attribute "base_Class", to: :base_class
|
|
146
|
-
end
|
|
147
|
-
end
|
|
5
|
+
autoload :Bibliography, "xmi/custom_profile/bibliography"
|
|
6
|
+
autoload :BasicDoc, "xmi/custom_profile/basic_doc"
|
|
7
|
+
autoload :Enumeration, "xmi/custom_profile/enumeration"
|
|
8
|
+
autoload :Ocl, "xmi/custom_profile/ocl"
|
|
9
|
+
autoload :Invariant, "xmi/custom_profile/invariant"
|
|
10
|
+
autoload :PublicationDate, "xmi/custom_profile/publication_date"
|
|
11
|
+
autoload :Edition, "xmi/custom_profile/edition"
|
|
12
|
+
autoload :Number, "xmi/custom_profile/number"
|
|
13
|
+
autoload :YearVersion, "xmi/custom_profile/year_version"
|
|
14
|
+
autoload :Informative, "xmi/custom_profile/informative"
|
|
15
|
+
autoload :Persistence, "xmi/custom_profile/persistence"
|
|
16
|
+
autoload :Abstract, "xmi/custom_profile/abstract"
|
|
148
17
|
end
|
|
149
18
|
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
class EaRoot
|
|
5
|
+
module CodeGeneration
|
|
6
|
+
# Build extension classes directly via Class.new + const_set.
|
|
7
|
+
def build_extension(xmi_doc)
|
|
8
|
+
@module_name = get_module_name(xmi_doc)
|
|
9
|
+
@def_namespace = get_namespace_from_definition(xmi_doc)
|
|
10
|
+
|
|
11
|
+
# Resolve namespace class (returns class object)
|
|
12
|
+
ns_class = resolve_namespace_class
|
|
13
|
+
|
|
14
|
+
# Create the parent module Xmi::EaRoot::ModuleName
|
|
15
|
+
mod = Module.new
|
|
16
|
+
EaRoot.const_set(@module_name.to_sym, mod)
|
|
17
|
+
|
|
18
|
+
# Process abstract class
|
|
19
|
+
@abstract_klass_node = get_abstract_klass_node(xmi_doc)
|
|
20
|
+
@abstract_tags = []
|
|
21
|
+
abstract_klass = nil
|
|
22
|
+
if @abstract_klass_node
|
|
23
|
+
abstract_klass = build_abstract_class(mod, @abstract_klass_node)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Process non-abstract stereotypes
|
|
27
|
+
nodes = xmi_doc.xpath(
|
|
28
|
+
"//UMLProfiles//Stereotypes//Stereotype[not(contains(@isAbstract, 'true'))]",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Without baseStereotypes
|
|
32
|
+
nodes.select { |n| n.attributes["baseStereotypes"].nil? }.each do |node|
|
|
33
|
+
build_stereotype_class(mod, node, abstract_klass, ns_class)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# With baseStereotypes
|
|
37
|
+
nodes.reject { |n| n.attributes["baseStereotypes"].nil? }.each do |node|
|
|
38
|
+
base_name = node.attributes["baseStereotypes"].value
|
|
39
|
+
build_stereotype_class(mod, node, abstract_klass, ns_class,
|
|
40
|
+
parent_name: base_name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def build_abstract_class(parent_mod, abstract_node)
|
|
47
|
+
klass_name = Lutaml::Model::Utils.classify(
|
|
48
|
+
get_klass_name_from_node(abstract_node),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
klass = Class.new(Lutaml::Model::Serializable)
|
|
52
|
+
|
|
53
|
+
# Add tag attributes (NO xml mapping for abstract classes)
|
|
54
|
+
tags = abstract_node.search("Tag")
|
|
55
|
+
@abstract_tags = tags
|
|
56
|
+
tags.each do |tag|
|
|
57
|
+
tag_name = get_tag_name(tag)
|
|
58
|
+
attr_name = Lutaml::Model::Utils.snake_case(tag_name)
|
|
59
|
+
klass.attribute attr_name.to_sym, :string
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
parent_mod.const_set(klass_name.to_sym, klass)
|
|
63
|
+
klass
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def build_stereotype_class(parent_mod, node, abstract_klass, ns_class,
|
|
67
|
+
parent_name: nil)
|
|
68
|
+
node_name = get_klass_name_from_node(node)
|
|
69
|
+
klass_name = Lutaml::Model::Utils.classify(node_name)
|
|
70
|
+
|
|
71
|
+
# Determine parent class
|
|
72
|
+
parent_klass = if parent_name
|
|
73
|
+
parent_mod.const_get(Lutaml::Model::Utils.classify(parent_name).to_sym)
|
|
74
|
+
elsif abstract_klass
|
|
75
|
+
abstract_klass
|
|
76
|
+
else
|
|
77
|
+
Lutaml::Model::Serializable
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Collect tags and apply types
|
|
81
|
+
tags = node.search("Tag")
|
|
82
|
+
apply_nodes = node.search("Apply")
|
|
83
|
+
|
|
84
|
+
# Build the class
|
|
85
|
+
klass = Class.new(parent_klass) do
|
|
86
|
+
define_singleton_method(:root_tag) { node_name }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Add tag attributes
|
|
90
|
+
tags.each do |tag|
|
|
91
|
+
tag_name = get_tag_name(tag)
|
|
92
|
+
attr_name = Lutaml::Model::Utils.snake_case(tag_name)
|
|
93
|
+
klass.attribute attr_name.to_sym, :string
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Add apply type attributes
|
|
97
|
+
apply_nodes.each do |n|
|
|
98
|
+
apply_types = n.attribute_nodes.map(&:value)
|
|
99
|
+
apply_types.each do |apply_type|
|
|
100
|
+
attr_name = Lutaml::Model::Utils.snake_case("base_#{apply_type}")
|
|
101
|
+
klass.attribute attr_name.to_sym, :string
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Add XML mapping
|
|
106
|
+
# Pre-compute tag mapping pairs (xml block runs in Mapping context, not EaRoot)
|
|
107
|
+
all_tag_pairs = (@abstract_tags + tags).map do |tag|
|
|
108
|
+
tag_name = get_tag_name(tag)
|
|
109
|
+
[tag_name, Lutaml::Model::Utils.snake_case(tag_name).to_sym]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
apply_pairs = []
|
|
113
|
+
apply_nodes.each do |n|
|
|
114
|
+
n.attribute_nodes.map(&:value).each do |apply_type|
|
|
115
|
+
apply_pairs << [
|
|
116
|
+
"base_#{apply_type}",
|
|
117
|
+
Lutaml::Model::Utils.snake_case("base_#{apply_type}").to_sym,
|
|
118
|
+
]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
klass.xml do
|
|
123
|
+
root node_name
|
|
124
|
+
namespace ns_class
|
|
125
|
+
|
|
126
|
+
all_tag_pairs.each do |xml_name, attr_sym|
|
|
127
|
+
map_attribute xml_name, to: attr_sym
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
apply_pairs.each do |xml_name, attr_sym|
|
|
131
|
+
map_attribute xml_name, to: attr_sym
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
parent_mod.const_set(klass_name.to_sym, klass)
|
|
136
|
+
klass
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
class EaRoot
|
|
5
|
+
module ExtensionLifecycle
|
|
6
|
+
def update_mappings(module_name)
|
|
7
|
+
new_klasses = all_new_klasses(module_name)
|
|
8
|
+
inject_model_attributes(new_klasses, module_name)
|
|
9
|
+
inject_model_xml_mappings(new_klasses, module_name)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def inject_model_attributes(new_klasses, module_name)
|
|
15
|
+
sparx_root = Xmi::Sparx::Root
|
|
16
|
+
new_klasses.each do |klass_name|
|
|
17
|
+
method_name = Lutaml::Model::Utils.snake_case(klass_name)
|
|
18
|
+
full_klass = EaRoot.const_get(module_name).const_get(klass_name)
|
|
19
|
+
sparx_root.attribute method_name.to_sym, full_klass, collection: true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def inject_model_xml_mappings(new_klasses, module_name)
|
|
24
|
+
map_entries = []
|
|
25
|
+
new_klasses.each do |klass_name|
|
|
26
|
+
klass = EaRoot.const_get(module_name).const_get(klass_name)
|
|
27
|
+
next unless klass.respond_to?(:root_tag)
|
|
28
|
+
|
|
29
|
+
method_name = Lutaml::Model::Utils.snake_case(klass_name)
|
|
30
|
+
map_entries << [klass.root_tag, method_name.to_sym]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
return if map_entries.empty?
|
|
34
|
+
|
|
35
|
+
Xmi::Sparx::Root.class_eval do
|
|
36
|
+
xml do
|
|
37
|
+
map_entries.each do |element_name, method_sym|
|
|
38
|
+
map_element element_name, to: method_sym,
|
|
39
|
+
value_map: Xmi::VALUE_MAP
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def all_new_klasses(module_name)
|
|
46
|
+
EaRoot.const_get(module_name).constants.select do |c|
|
|
47
|
+
EaRoot.const_get(module_name).const_get(c).is_a? Class
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
class EaRoot
|
|
5
|
+
module NamespaceHandling
|
|
6
|
+
# Resolve the namespace class for the current extension.
|
|
7
|
+
# Returns the class object (not a name string) for direct use with
|
|
8
|
+
# the xml DSL's +namespace+ directive.
|
|
9
|
+
def resolve_namespace_class
|
|
10
|
+
uri = @def_namespace[:uri]
|
|
11
|
+
prefix = @def_namespace[:name]
|
|
12
|
+
|
|
13
|
+
existing = NamespaceRegistry.resolve(uri)
|
|
14
|
+
return existing if existing
|
|
15
|
+
|
|
16
|
+
module_name = @module_name
|
|
17
|
+
ns_class_name = "Xmi::Namespace::Dynamic::#{module_name}"
|
|
18
|
+
return Object.const_get(ns_class_name) if Object.const_defined?(ns_class_name)
|
|
19
|
+
|
|
20
|
+
Namespace.ensure_dynamic_namespace_module_exists!
|
|
21
|
+
ns_class = Class.new(Lutaml::Xml::Namespace) do
|
|
22
|
+
define_singleton_method(:uri) { uri }
|
|
23
|
+
define_singleton_method(:prefix_default) { prefix }
|
|
24
|
+
end
|
|
25
|
+
Namespace::Dynamic.const_set(module_name, ns_class)
|
|
26
|
+
|
|
27
|
+
NamespaceRegistry.register(uri, ns_class)
|
|
28
|
+
|
|
29
|
+
ns_class
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns the namespace class _name_ as a string.
|
|
33
|
+
def find_or_create_namespace_class
|
|
34
|
+
klass = resolve_namespace_class
|
|
35
|
+
klass.is_a?(String) ? klass : klass.name
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
class EaRoot
|
|
5
|
+
module XmlParsing
|
|
6
|
+
def get_abstract_klass_node(xmi_doc)
|
|
7
|
+
xmi_doc.at_xpath(
|
|
8
|
+
"//UMLProfiles//Stereotypes//Stereotype[@isAbstract='true']",
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_klass_name_from_node(node)
|
|
13
|
+
return Lutaml::Model::Serializable.to_s unless node
|
|
14
|
+
|
|
15
|
+
node.attribute_nodes.find { |attr| attr.name == "name" }.value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_module_name(xmi_doc)
|
|
19
|
+
get_module_name_from_definition(xmi_doc).capitalize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_module_name_from_definition(xmi_doc)
|
|
23
|
+
node = xmi_doc.at_xpath("//UMLProfile/Documentation")
|
|
24
|
+
node.attribute_nodes.find { |attr| attr.name == "name" }&.value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get_module_uri(xmi_doc)
|
|
28
|
+
node = xmi_doc.at_xpath("//UMLProfile/Documentation")
|
|
29
|
+
uri = node.attribute_nodes.find { |attr| attr.name == "URI" }&.value
|
|
30
|
+
return uri if uri
|
|
31
|
+
|
|
32
|
+
name = get_module_name_from_definition(xmi_doc)
|
|
33
|
+
ver = node.attribute_nodes.find { |attr| attr.name == "version" }&.value
|
|
34
|
+
|
|
35
|
+
"http://www.sparxsystems.com/profiles/#{name}/#{ver}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def get_namespace_from_definition(xmi_doc)
|
|
39
|
+
namespace_key = get_module_name_from_definition(xmi_doc)
|
|
40
|
+
namespace_uri = get_module_uri(xmi_doc)
|
|
41
|
+
|
|
42
|
+
{ name: namespace_key, uri: namespace_uri }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_tag_name(tag)
|
|
46
|
+
tag_name = tag.attribute_nodes.find { |attr| attr.name == "name" }.value
|
|
47
|
+
tag_name == "xmlns" ? "altered_xmlns" : tag_name
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|