Module: Metanorma::Plugin::Lutaml::XmiCache

Included in:
LutamlEaXmiBase
Defined in:
lib/metanorma/plugin/lutaml/xmi_cache.rb

Constant Summary collapse

XMI_PARSE_CACHE =
XmiParseCache.new

Instance Method Summary collapse

Instance Method Details

#find_class_by_xmi_id(container, xmi_id) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 30

def find_class_by_xmi_id(container, xmi_id)
  container.classes.find { |node| node.xmi_id == xmi_id } ||
    container.packages
      .lazy
      .filter_map { |pkg| find_class_by_xmi_id(pkg, xmi_id) }
      .first
end

#find_enum_by_xmi_id(container, xmi_id) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 38

def find_enum_by_xmi_id(container, xmi_id)
  container.enums.find { |node| node.xmi_id == xmi_id } ||
    container.packages
      .lazy
      .filter_map { |pkg| find_enum_by_xmi_id(pkg, xmi_id) }
      .first
end

#find_packaged_enum(index, name) ⇒ Object



83
84
85
86
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 83

def find_packaged_enum(index, name)
  index.packaged_elements_of_type("uml:Enumeration")
    .find { |e| e.name == name }
end

#find_packaged_klass(index, path, root_model_name: nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 46

def find_packaged_klass(index, path, root_model_name: nil)
  segments = path.split("::").reject(&:empty?)
  if root_model_name && segments.first == root_model_name
    segments.shift
  end
  if segments.one?
    index.find_packaged_by_name_and_types(
      segments.first, ["uml:Class", "uml:AssociationClass"]
    )
  else
    find_packaged_klass_by_path(index, segments)
  end
end

#find_packaged_klass_by_path(index, segments) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 60

def find_packaged_klass_by_path(index, segments)
  klass_name = segments.pop

  candidates = ["uml:Class", "uml:AssociationClass"]
    .flat_map { |t| index.packaged_elements_of_type(t) }
    .select { |e| e.name == klass_name }

  candidates.find do |klass|
    match_parent_chain?(index, klass, segments)
  end
end

#load_ea_extensions(yaml_config, yaml_config_path) ⇒ Object



19
20
21
22
23
24
25
26
27
28
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 19

def load_ea_extensions(yaml_config, yaml_config_path)
  yaml_config.ea_extension&.each do |ea_extension_path|
    ea_extension_full_path = File.expand_path(
      ea_extension_path, File.dirname(yaml_config_path)
    )
    unless Xmi::EaRoot.loaded_extensions.value?(ea_extension_full_path)
      Xmi::EaRoot.load_extension(ea_extension_full_path)
    end
  end
end

#lutaml_document_from_file_or_cache(document, file_path, yaml_config, yaml_config_path = nil) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 9

def lutaml_document_from_file_or_cache(document, file_path, yaml_config,
yaml_config_path = nil)
  full_path = Utils.relative_file_path(document, file_path)
  load_ea_extensions(yaml_config, yaml_config_path)
  guidance = get_guidance(document, yaml_config.guidance)
  paths = (document.attributes["lutaml_xmi_paths"] ||= [])
  paths << full_path unless paths.include?(full_path)
  XMI_PARSE_CACHE.fetch_drop(full_path, guidance: guidance)
end

#match_parent_chain?(index, element, parent_segments) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
81
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 72

def match_parent_chain?(index, element, parent_segments)
  current = element
  parent_segments.reverse_each do |pkg_name|
    parent = index.find_parent(current.id)
    return false unless parent && parent.name == pkg_name

    current = parent
  end
  true
end

#serialize_enum_drop_by_name(xmi_path, name, _document = nil) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 98

def serialize_enum_drop_by_name(xmi_path, name, _document = nil)
  parsed = XMI_PARSE_CACHE.fetch(xmi_path)
  raw_enum = find_packaged_enum(parsed.parser.xmi_index, name)
  warn "Enumeration not found for name: #{name}" if raw_enum.nil?
  enum = raw_enum && find_enum_by_xmi_id(
    parsed.uml_document, raw_enum.id
  )
  ::Lutaml::Xmi::LiquidDrops::EnumDrop.new(
    enum, parsed.drop_options
  )
end

#serialize_klass_drop_by_name(xmi_path, name, _document = nil, guidance = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/metanorma/plugin/lutaml/xmi_cache.rb', line 88

def serialize_klass_drop_by_name(xmi_path, name, _document = nil,
guidance = nil)
  parsed = XMI_PARSE_CACHE.fetch(xmi_path)
  klass = resolve_packaged_klass(parsed, name)
  warn "Class not found for name: #{name}" if klass.nil?
  ::Lutaml::Xmi::LiquidDrops::KlassDrop.new(
    klass, guidance, parsed.drop_options
  )
end