metanorma-plugin-lutaml 0.7.45 → 0.7.46
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/.gitignore +1 -0
- data/.rubocop_todo.yml +11 -3
- data/lib/metanorma/plugin/lutaml/cache_registry.rb +22 -0
- data/lib/metanorma/plugin/lutaml/express_remark_adapter.rb +114 -0
- data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +6 -0
- data/lib/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro.rb +8 -3
- data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +5 -59
- data/lib/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor.rb +3 -2
- data/lib/metanorma/plugin/lutaml/lutaml_xsd_preprocessor.rb +1 -21
- data/lib/metanorma/plugin/lutaml/version.rb +1 -1
- data/lib/metanorma/plugin/lutaml/xmi_cache.rb +42 -65
- data/lib/metanorma/plugin/lutaml/xmi_parse_cache.rb +62 -0
- data/lib/metanorma-plugin-lutaml.rb +4 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a35215ee0b1f56e7a7b8896e512da9fb7aa190244988efa0b173bf72ed84202c
|
|
4
|
+
data.tar.gz: ee445b71760e111e26896f30559e35d4b8ea86a03cc20c0c000aebd7c43debb7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ff29f6c04bd2483e359b5bb3bc3e0e9bfbb1254df12aed87453ab05b7e6f329583d80be38113dedc9aa6e18e71871a1869fc74e85c0b236bf069176e81de886
|
|
7
|
+
data.tar.gz: 9027e9b86616da94c0cd7144858f6ae01de440fc20a18aeb4d2e2a600a19ac37464d1d8fae2a1244e398e96f0502a876e9e306334e0598c0b0e3d53160cc40b5
|
data/.gitignore
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-05-15
|
|
3
|
+
# on 2026-05-15 10:38:23 UTC using RuboCop version 1.86.2.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -37,7 +37,7 @@ Metrics/CyclomaticComplexity:
|
|
|
37
37
|
Exclude:
|
|
38
38
|
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
39
39
|
|
|
40
|
-
# Offense count:
|
|
40
|
+
# Offense count: 8
|
|
41
41
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
42
42
|
Metrics/MethodLength:
|
|
43
43
|
Max: 19
|
|
@@ -81,7 +81,7 @@ RSpec/ContextWording:
|
|
|
81
81
|
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
82
82
|
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
83
83
|
|
|
84
|
-
# Offense count:
|
|
84
|
+
# Offense count: 47
|
|
85
85
|
# Configuration parameters: CountAsOne.
|
|
86
86
|
RSpec/ExampleLength:
|
|
87
87
|
Max: 26
|
|
@@ -157,3 +157,11 @@ RSpec/SpecFilePathFormat:
|
|
|
157
157
|
RSpec/SubjectDeclaration:
|
|
158
158
|
Exclude:
|
|
159
159
|
- 'spec/metanorma/plugin/lutaml/config/root_spec.rb'
|
|
160
|
+
|
|
161
|
+
# Offense count: 2
|
|
162
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
163
|
+
# Configuration parameters: EnforcedStyleForMultiline.
|
|
164
|
+
# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
|
|
165
|
+
Style/TrailingCommaInArguments:
|
|
166
|
+
Exclude:
|
|
167
|
+
- 'spec/metanorma/plugin/lutaml/express_remark_adapter_spec.rb'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Plugin
|
|
5
|
+
module Lutaml
|
|
6
|
+
module CacheRegistry
|
|
7
|
+
def self.xmi_cache
|
|
8
|
+
XmiCache::XMI_PARSE_CACHE
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.xsd_cache
|
|
12
|
+
LutamlXsdPreprocessor::CACHE
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.clear_all
|
|
16
|
+
xmi_cache.clear
|
|
17
|
+
xsd_cache.clear
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "expressir"
|
|
4
|
+
|
|
5
|
+
module Metanorma
|
|
6
|
+
module Plugin
|
|
7
|
+
module Lutaml
|
|
8
|
+
module ExpressRemarkAdapter
|
|
9
|
+
def self.relative_path_prefix(options, model)
|
|
10
|
+
return if options.nil? || options["document"].nil?
|
|
11
|
+
|
|
12
|
+
document = options["document"]
|
|
13
|
+
file_path = File.dirname(model.file)
|
|
14
|
+
docfile_directory = File.dirname(
|
|
15
|
+
document.attributes["docfile"] || ".",
|
|
16
|
+
)
|
|
17
|
+
resolved = document.path_resolver
|
|
18
|
+
.system_path(file_path, docfile_directory)
|
|
19
|
+
File.expand_path(resolved, docfile_directory)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.for(model)
|
|
23
|
+
case model
|
|
24
|
+
when Expressir::Model::Cache
|
|
25
|
+
CachedRepoAdapter.new(model)
|
|
26
|
+
when Expressir::Model::Repository, Expressir::Model::ExpFile
|
|
27
|
+
RepoAdapter.new(model)
|
|
28
|
+
when Expressir::Model::ModelElement
|
|
29
|
+
ModelAdapter.new(model)
|
|
30
|
+
else
|
|
31
|
+
NullAdapter.new(model)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Base
|
|
36
|
+
def initialize(model)
|
|
37
|
+
@model = model
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unwrap
|
|
41
|
+
@model
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def decorate_remarks(options)
|
|
45
|
+
decorate_own_remarks(options)
|
|
46
|
+
decorate_child_remark_items(options)
|
|
47
|
+
traverse_children(options)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def decorate_own_remarks(options)
|
|
53
|
+
@model.remarks = ExpressRemarksDecorator.decorate_array(
|
|
54
|
+
@model.remarks, options
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def decorate_child_remark_items(options)
|
|
59
|
+
return unless @model.is_a?(Expressir::Model::HasRemarkItems)
|
|
60
|
+
|
|
61
|
+
@model.remark_items&.each do |ri|
|
|
62
|
+
ri.remarks = ExpressRemarksDecorator.decorate_array(
|
|
63
|
+
ri.remarks, options
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def traverse_children(options)
|
|
69
|
+
@model.children&.each do |child|
|
|
70
|
+
next unless traversable?(child)
|
|
71
|
+
|
|
72
|
+
ExpressRemarkAdapter.for(child).decorate_remarks(options)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def traversable?(child)
|
|
77
|
+
child.is_a?(Expressir::Model::ModelElement) &&
|
|
78
|
+
!child.is_a?(Expressir::Model::Declarations::RemarkItem)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class RepoAdapter < Base
|
|
83
|
+
def decorate_remarks(options)
|
|
84
|
+
@model.schemas.each do |schema|
|
|
85
|
+
options["relative_path_prefix"] =
|
|
86
|
+
ExpressRemarkAdapter.relative_path_prefix(options, schema)
|
|
87
|
+
ExpressRemarkAdapter.for(schema).decorate_remarks(options)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class CachedRepoAdapter < Base
|
|
93
|
+
def unwrap
|
|
94
|
+
@model.content
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def decorate_remarks(options)
|
|
98
|
+
ExpressRemarkAdapter.for(@model.content).decorate_remarks(options)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
class ModelAdapter < Base; end
|
|
103
|
+
|
|
104
|
+
class NullAdapter
|
|
105
|
+
def initialize(_model); end
|
|
106
|
+
|
|
107
|
+
def unwrap; end
|
|
108
|
+
|
|
109
|
+
def decorate_remarks(_options); end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -24,6 +24,12 @@ module Metanorma
|
|
|
24
24
|
new(remark, options).call
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def self.decorate_array(remarks, options)
|
|
28
|
+
return [] unless remarks
|
|
29
|
+
|
|
30
|
+
remarks.map { |remark| call(remark, options) }
|
|
31
|
+
end
|
|
32
|
+
|
|
27
33
|
def initialize(remark, options)
|
|
28
34
|
@remark = remark
|
|
29
35
|
@options = options
|
|
@@ -37,14 +37,19 @@ module Metanorma
|
|
|
37
37
|
path = get_path_from_index(parent, index) if index
|
|
38
38
|
|
|
39
39
|
if index && path
|
|
40
|
-
|
|
40
|
+
return lutaml_document_from_file_or_cache(
|
|
41
41
|
parent.document, path,
|
|
42
42
|
Metanorma::Plugin::Lutaml::Config::Root.new
|
|
43
43
|
)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
first_path = parent.document.attributes["lutaml_xmi_paths"]&.first
|
|
47
|
+
return unless first_path
|
|
48
|
+
|
|
49
|
+
lutaml_document_from_file_or_cache(
|
|
50
|
+
parent.document, first_path,
|
|
51
|
+
Metanorma::Plugin::Lutaml::Config::Root.new
|
|
52
|
+
)
|
|
48
53
|
end
|
|
49
54
|
|
|
50
55
|
def img_src_path(document, attrs, diagram)
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
module Metanorma
|
|
4
4
|
module Plugin
|
|
5
5
|
module Lutaml
|
|
6
|
-
# Preprocessor for EXPRESS schema formats (lutaml, lutaml_express,
|
|
7
|
-
# lutaml_express_liquid). Parses EXPRESS files via the lutaml/expressir
|
|
8
|
-
# gems, decorates remarks with relative path resolution, and renders
|
|
9
|
-
# Liquid templates with the EXPRESS-specific Liquid environment.
|
|
10
6
|
class LutamlPreprocessor < BasePreprocessor
|
|
11
7
|
EXPRESS_PREPROCESSOR_REGEX = %r{
|
|
12
8
|
^ # Start of line
|
|
@@ -22,30 +18,6 @@ module Metanorma
|
|
|
22
18
|
\] # Closing bracket
|
|
23
19
|
}x
|
|
24
20
|
|
|
25
|
-
def update_remarks(model, options)
|
|
26
|
-
model.remarks = decorate_remarks(options, model.remarks)
|
|
27
|
-
decorate_remark_items(model, options)
|
|
28
|
-
|
|
29
|
-
model.children.each do |child|
|
|
30
|
-
next unless traversable_model_element?(child)
|
|
31
|
-
|
|
32
|
-
update_remarks(child, options)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def traversable_model_element?(child)
|
|
37
|
-
child.is_a?(Expressir::Model::ModelElement) &&
|
|
38
|
-
!child.is_a?(Expressir::Model::Declarations::RemarkItem)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def decorate_remark_items(model, options)
|
|
42
|
-
return unless model.is_a?(Expressir::Model::HasRemarkItems)
|
|
43
|
-
|
|
44
|
-
model.remark_items&.each do |ri|
|
|
45
|
-
ri.remarks = decorate_remarks(options, ri.remarks)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
21
|
protected
|
|
50
22
|
|
|
51
23
|
def lutaml_liquid?(line)
|
|
@@ -74,17 +46,12 @@ module Metanorma
|
|
|
74
46
|
end
|
|
75
47
|
|
|
76
48
|
def update_repo(options, repo)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
49
|
+
adapter = ExpressRemarkAdapter.for(repo)
|
|
50
|
+
unwrapped = adapter.unwrap
|
|
51
|
+
return unwrapped unless unwrapped
|
|
80
52
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
relative_path_prefix(options, schema)
|
|
84
|
-
update_remarks(schema, options)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
repo
|
|
53
|
+
adapter.decorate_remarks(options)
|
|
54
|
+
unwrapped
|
|
88
55
|
end
|
|
89
56
|
|
|
90
57
|
def template(lines)
|
|
@@ -103,27 +70,6 @@ module Metanorma
|
|
|
103
70
|
end
|
|
104
71
|
end
|
|
105
72
|
end
|
|
106
|
-
|
|
107
|
-
def relative_path_prefix(options, model)
|
|
108
|
-
return if options.nil? || options["document"].nil?
|
|
109
|
-
|
|
110
|
-
document = options["document"]
|
|
111
|
-
file_path = File.dirname(model.file)
|
|
112
|
-
docfile_directory = File.dirname(
|
|
113
|
-
document.attributes["docfile"] || ".",
|
|
114
|
-
)
|
|
115
|
-
resolved = document.path_resolver
|
|
116
|
-
.system_path(file_path, docfile_directory)
|
|
117
|
-
File.expand_path(resolved, docfile_directory)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def decorate_remarks(options, remarks)
|
|
121
|
-
return [] unless remarks
|
|
122
|
-
|
|
123
|
-
remarks.map do |remark|
|
|
124
|
-
ExpressRemarksDecorator.call(remark, options)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
73
|
end
|
|
128
74
|
end
|
|
129
75
|
end
|
|
@@ -16,9 +16,10 @@ module Metanorma
|
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
-
def parse_result_document(full_path,
|
|
20
|
-
::Lutaml::Xmi::Parsers::Xml.
|
|
19
|
+
def parse_result_document(full_path, guidance)
|
|
20
|
+
::Lutaml::Xmi::Parsers::Xml.serialize_xmi_to_liquid(
|
|
21
21
|
File.new(full_path, encoding: "UTF-8"),
|
|
22
|
+
guidance,
|
|
22
23
|
)
|
|
23
24
|
end
|
|
24
25
|
|
|
@@ -12,11 +12,6 @@ module Metanorma
|
|
|
12
12
|
# Two syntaxes are supported:
|
|
13
13
|
# Block: [lutaml_xsd, path, context, options] .... ----
|
|
14
14
|
# Direct: lutaml_xsd::path[context, template, options]
|
|
15
|
-
#
|
|
16
|
-
# Caching: parsed XSD results are cached at two levels:
|
|
17
|
-
# - Class-level (CACHE) persists across document invocations
|
|
18
|
-
# - Document-level (document.attributes["lutaml_xsd_cache"]) within a
|
|
19
|
-
# single document's processing
|
|
20
15
|
class LutamlXsdPreprocessor < BasePreprocessor
|
|
21
16
|
CACHE = CacheStore.new
|
|
22
17
|
XSD_PREPROCESSOR_REGEX = %r{
|
|
@@ -59,15 +54,9 @@ module Metanorma
|
|
|
59
54
|
location = xsd_location(full_path, options)
|
|
60
55
|
cache_key = [full_path, location]
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
return cached if cached
|
|
64
|
-
|
|
65
|
-
result = CACHE.fetch_or_store(cache_key) do
|
|
57
|
+
CACHE.fetch_or_store(cache_key) do
|
|
66
58
|
parse_xsd_file(full_path, location)
|
|
67
59
|
end
|
|
68
|
-
|
|
69
|
-
set_document_cache_entry(document, cache_key, result)
|
|
70
|
-
result
|
|
71
60
|
end
|
|
72
61
|
|
|
73
62
|
def index_type_name
|
|
@@ -134,15 +123,6 @@ module Metanorma
|
|
|
134
123
|
def xsd_location(full_path, options)
|
|
135
124
|
options["location"] || File.dirname(full_path)
|
|
136
125
|
end
|
|
137
|
-
|
|
138
|
-
def document_cache_entry(document, cache_key)
|
|
139
|
-
document.attributes["lutaml_xsd_cache"]&.[](cache_key)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def set_document_cache_entry(document, cache_key, result)
|
|
143
|
-
document.attributes["lutaml_xsd_cache"] ||= {}
|
|
144
|
-
document.attributes["lutaml_xsd_cache"][cache_key] = result
|
|
145
|
-
end
|
|
146
126
|
end
|
|
147
127
|
end
|
|
148
128
|
end
|
|
@@ -1,41 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "lutaml"
|
|
4
|
-
require "lutaml/uml"
|
|
5
|
-
require "lutaml/formatter"
|
|
6
|
-
|
|
7
3
|
module Metanorma
|
|
8
4
|
module Plugin
|
|
9
5
|
module Lutaml
|
|
10
6
|
module XmiCache
|
|
11
|
-
|
|
12
|
-
UML_DOC_CACHE = CacheStore.new
|
|
7
|
+
XMI_PARSE_CACHE = XmiParseCache.new
|
|
13
8
|
|
|
14
|
-
def lutaml_document_from_file_or_cache(document, file_path, yaml_config,
|
|
9
|
+
def lutaml_document_from_file_or_cache(document, file_path, yaml_config,
|
|
10
|
+
yaml_config_path = nil)
|
|
15
11
|
full_path = Utils.relative_file_path(document, file_path)
|
|
16
|
-
cached = document.attributes.dig("lutaml_xmi_cache", full_path)
|
|
17
|
-
return cached if cached
|
|
18
|
-
|
|
19
12
|
load_ea_extensions(yaml_config, yaml_config_path)
|
|
20
|
-
|
|
21
13
|
guidance = get_guidance(document, yaml_config.guidance)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
parse_result_document(full_path, guidance)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
document.attributes["lutaml_xmi_cache"] ||= {}
|
|
29
|
-
document.attributes["lutaml_xmi_cache"][full_path] = result_document
|
|
30
|
-
result_document
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def build_uml_document(xmi_path, _document = nil)
|
|
34
|
-
UML_DOC_CACHE.fetch_or_store(xmi_path) do
|
|
35
|
-
xmi_model = ::Xmi::Sparx::Root.parse_xml(File.read(xmi_path))
|
|
36
|
-
parser = ::Lutaml::Xmi::Parsers::Xml.new
|
|
37
|
-
[parser, parser.parse(xmi_model)]
|
|
38
|
-
end
|
|
14
|
+
paths = (document.attributes["lutaml_xmi_paths"] ||= [])
|
|
15
|
+
paths << full_path unless paths.include?(full_path)
|
|
16
|
+
XMI_PARSE_CACHE.fetch_drop(full_path, guidance: guidance)
|
|
39
17
|
end
|
|
40
18
|
|
|
41
19
|
def load_ea_extensions(yaml_config, yaml_config_path)
|
|
@@ -49,29 +27,20 @@ module Metanorma
|
|
|
49
27
|
end
|
|
50
28
|
end
|
|
51
29
|
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
id_name_mapping: parser.id_name_mapping,
|
|
59
|
-
lookup: lookup,
|
|
60
|
-
with_gen: true,
|
|
61
|
-
with_absolute_path: true,
|
|
62
|
-
}
|
|
30
|
+
def find_class_by_xmi_id(container, xmi_id)
|
|
31
|
+
container.classes.find { |node| node.xmi_id == xmi_id } ||
|
|
32
|
+
container.packages
|
|
33
|
+
.lazy
|
|
34
|
+
.filter_map { |pkg| find_class_by_xmi_id(pkg, xmi_id) }
|
|
35
|
+
.first
|
|
63
36
|
end
|
|
64
37
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
nested = find_uml_node_by_xmi_id(pkg, xmi_id, collection)
|
|
72
|
-
return nested if nested
|
|
73
|
-
end
|
|
74
|
-
nil
|
|
38
|
+
def find_enum_by_xmi_id(container, xmi_id)
|
|
39
|
+
container.enums.find { |node| node.xmi_id == xmi_id } ||
|
|
40
|
+
container.packages
|
|
41
|
+
.lazy
|
|
42
|
+
.filter_map { |pkg| find_enum_by_xmi_id(pkg, xmi_id) }
|
|
43
|
+
.first
|
|
75
44
|
end
|
|
76
45
|
|
|
77
46
|
def find_packaged_klass(index, path, root_model_name: nil)
|
|
@@ -116,30 +85,38 @@ module Metanorma
|
|
|
116
85
|
.find { |e| e.name == name }
|
|
117
86
|
end
|
|
118
87
|
|
|
119
|
-
def serialize_klass_drop_by_name(xmi_path, name,
|
|
88
|
+
def serialize_klass_drop_by_name(xmi_path, name, _document = nil,
|
|
120
89
|
guidance = nil)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
root_model_name: root_model_name)
|
|
125
|
-
warn "Class not found for name: #{name}" if raw_klass.nil?
|
|
126
|
-
klass = raw_klass && find_uml_node_by_xmi_id(
|
|
127
|
-
uml_doc, raw_klass.id, :classes
|
|
128
|
-
)
|
|
90
|
+
parsed = XMI_PARSE_CACHE.fetch(xmi_path)
|
|
91
|
+
klass = resolve_packaged_klass(parsed, name)
|
|
92
|
+
warn "Class not found for name: #{name}" if klass.nil?
|
|
129
93
|
::Lutaml::Xmi::LiquidDrops::KlassDrop.new(
|
|
130
|
-
klass, guidance,
|
|
94
|
+
klass, guidance, parsed.drop_options
|
|
131
95
|
)
|
|
132
96
|
end
|
|
133
97
|
|
|
134
|
-
def serialize_enum_drop_by_name(xmi_path, name,
|
|
135
|
-
|
|
136
|
-
raw_enum = find_packaged_enum(parser.xmi_index, name)
|
|
98
|
+
def serialize_enum_drop_by_name(xmi_path, name, _document = nil)
|
|
99
|
+
parsed = XMI_PARSE_CACHE.fetch(xmi_path)
|
|
100
|
+
raw_enum = find_packaged_enum(parsed.parser.xmi_index, name)
|
|
137
101
|
warn "Enumeration not found for name: #{name}" if raw_enum.nil?
|
|
138
|
-
enum = raw_enum &&
|
|
139
|
-
|
|
102
|
+
enum = raw_enum && find_enum_by_xmi_id(
|
|
103
|
+
parsed.uml_document, raw_enum.id
|
|
140
104
|
)
|
|
141
105
|
::Lutaml::Xmi::LiquidDrops::EnumDrop.new(
|
|
142
|
-
enum,
|
|
106
|
+
enum, parsed.drop_options
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
def resolve_packaged_klass(parsed, name)
|
|
113
|
+
root_model_name = parsed.parser.xmi_root_model.model.name
|
|
114
|
+
raw_klass = find_packaged_klass(
|
|
115
|
+
parsed.parser.xmi_index, name,
|
|
116
|
+
root_model_name: root_model_name
|
|
117
|
+
)
|
|
118
|
+
raw_klass && find_class_by_xmi_id(
|
|
119
|
+
parsed.uml_document, raw_klass.id
|
|
143
120
|
)
|
|
144
121
|
end
|
|
145
122
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "xmi"
|
|
4
|
+
require "lutaml/xmi"
|
|
5
|
+
|
|
6
|
+
module Metanorma
|
|
7
|
+
module Plugin
|
|
8
|
+
module Lutaml
|
|
9
|
+
ParsedXmi = Struct.new(:parser, :uml_document, :drop_options,
|
|
10
|
+
keyword_init: true)
|
|
11
|
+
|
|
12
|
+
class XmiParseCache
|
|
13
|
+
def initialize(max_size: 50)
|
|
14
|
+
@parse_cache = CacheStore.new(max_size: max_size)
|
|
15
|
+
@drop_cache = CacheStore.new(max_size: max_size)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def fetch(full_path)
|
|
19
|
+
@parse_cache.fetch_or_store(full_path) do
|
|
20
|
+
xmi_model = ::Xmi::Sparx::Root.parse_xml(File.read(full_path))
|
|
21
|
+
parser = ::Lutaml::Xmi::Parsers::Xml.new
|
|
22
|
+
uml_document = parser.parse(xmi_model)
|
|
23
|
+
ParsedXmi.new(
|
|
24
|
+
parser: parser,
|
|
25
|
+
uml_document: uml_document,
|
|
26
|
+
drop_options: build_drop_options(parser),
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fetch_drop(full_path, guidance: nil)
|
|
32
|
+
parsed = fetch(full_path)
|
|
33
|
+
@drop_cache.fetch_or_store([full_path, guidance]) do
|
|
34
|
+
::Lutaml::Xmi::LiquidDrops::RootDrop.new(
|
|
35
|
+
parsed.uml_document, guidance, parsed.drop_options
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def clear
|
|
41
|
+
@parse_cache.clear
|
|
42
|
+
@drop_cache.clear
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def build_drop_options(parser)
|
|
48
|
+
lookup = ::Lutaml::Xmi::XmiLookupService.new(
|
|
49
|
+
parser.xmi_root_model, parser.id_name_mapping
|
|
50
|
+
)
|
|
51
|
+
{
|
|
52
|
+
xmi_root_model: parser.xmi_root_model,
|
|
53
|
+
id_name_mapping: parser.id_name_mapping,
|
|
54
|
+
lookup: lookup,
|
|
55
|
+
with_gen: true,
|
|
56
|
+
with_absolute_path: true,
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -11,12 +11,15 @@ module Metanorma
|
|
|
11
11
|
autoload :BaseStructuredTextPreprocessor,
|
|
12
12
|
"metanorma/plugin/lutaml/base_structured_text_preprocessor"
|
|
13
13
|
autoload :CacheStore, "metanorma/plugin/lutaml/cache_store"
|
|
14
|
+
autoload :CacheRegistry, "metanorma/plugin/lutaml/cache_registry"
|
|
14
15
|
autoload :Config, "metanorma/plugin/lutaml/config"
|
|
15
16
|
autoload :Content, "metanorma/plugin/lutaml/content"
|
|
16
17
|
autoload :Data2TextPreprocessor,
|
|
17
18
|
"metanorma/plugin/lutaml/data2_text_preprocessor"
|
|
18
19
|
autoload :ExpressRemarksDecorator,
|
|
19
20
|
"metanorma/plugin/lutaml/express_remarks_decorator"
|
|
21
|
+
autoload :ExpressRemarkAdapter,
|
|
22
|
+
"metanorma/plugin/lutaml/express_remark_adapter"
|
|
20
23
|
autoload :FileNotFoundError,
|
|
21
24
|
"metanorma/plugin/lutaml/file_not_found_error"
|
|
22
25
|
autoload :Json2TextPreprocessor,
|
|
@@ -55,6 +58,7 @@ module Metanorma
|
|
|
55
58
|
autoload :LutamlXsdPreprocessor,
|
|
56
59
|
"metanorma/plugin/lutaml/lutaml_xsd_preprocessor"
|
|
57
60
|
autoload :ParseError, "metanorma/plugin/lutaml/parse_error"
|
|
61
|
+
autoload :XmiParseCache, "metanorma/plugin/lutaml/xmi_parse_cache"
|
|
58
62
|
autoload :SourceExtractor, "metanorma/plugin/lutaml/source_extractor"
|
|
59
63
|
autoload :Utils, "metanorma/plugin/lutaml/utils"
|
|
60
64
|
autoload :Yaml2TextPreprocessor,
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metanorma-plugin-lutaml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.46
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: asciidoctor
|
|
@@ -182,6 +182,7 @@ files:
|
|
|
182
182
|
- lib/metanorma/plugin/lutaml/asciidoctor/preprocessor.rb
|
|
183
183
|
- lib/metanorma/plugin/lutaml/base_preprocessor.rb
|
|
184
184
|
- lib/metanorma/plugin/lutaml/base_structured_text_preprocessor.rb
|
|
185
|
+
- lib/metanorma/plugin/lutaml/cache_registry.rb
|
|
185
186
|
- lib/metanorma/plugin/lutaml/cache_store.rb
|
|
186
187
|
- lib/metanorma/plugin/lutaml/config.rb
|
|
187
188
|
- lib/metanorma/plugin/lutaml/config/guidance.rb
|
|
@@ -191,6 +192,7 @@ files:
|
|
|
191
192
|
- lib/metanorma/plugin/lutaml/config/root.rb
|
|
192
193
|
- lib/metanorma/plugin/lutaml/content.rb
|
|
193
194
|
- lib/metanorma/plugin/lutaml/data2_text_preprocessor.rb
|
|
195
|
+
- lib/metanorma/plugin/lutaml/express_remark_adapter.rb
|
|
194
196
|
- lib/metanorma/plugin/lutaml/express_remarks_decorator.rb
|
|
195
197
|
- lib/metanorma/plugin/lutaml/file_not_found_error.rb
|
|
196
198
|
- lib/metanorma/plugin/lutaml/json2_text_preprocessor.rb
|
|
@@ -244,6 +246,7 @@ files:
|
|
|
244
246
|
- lib/metanorma/plugin/lutaml/xmi_config.rb
|
|
245
247
|
- lib/metanorma/plugin/lutaml/xmi_context_builder.rb
|
|
246
248
|
- lib/metanorma/plugin/lutaml/xmi_package_filter.rb
|
|
249
|
+
- lib/metanorma/plugin/lutaml/xmi_parse_cache.rb
|
|
247
250
|
- lib/metanorma/plugin/lutaml/xmi_renderer.rb
|
|
248
251
|
- lib/metanorma/plugin/lutaml/yaml2_text_preprocessor.rb
|
|
249
252
|
- metanorma-plugin-lutaml.gemspec
|