Module: Lutaml::Xmi::Parsers::XmiBase

Included in:
Xml, XmiLookupService
Defined in:
lib/lutaml/xmi/parsers/xmi_base.rb,
lib/lutaml/xmi/parsers/xmi_connector.rb,
lib/lutaml/xmi/parsers/xmi_class_members.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



14
15
16
# File 'lib/lutaml/xmi/parsers/xmi_base.rb', line 14

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#cardinality_min_max_value(min, max) ⇒ Hash

Parameters:

  • min (String)
  • max (String)

Returns:

  • (Hash)


36
37
38
39
40
41
# File 'lib/lutaml/xmi/parsers/xmi_class_members.rb', line 36

def cardinality_min_max_value(min, max)
  {
    min: min,
    max: max,
  }
end

#connector_labels(xmi_id, source_or_target) ⇒ String

Parameters:

  • xmi_id (String)
  • source_or_target (String)

Returns:

  • (String)


235
236
237
238
239
240
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 235

def connector_labels(xmi_id, source_or_target)
  node = connector_node_by_id(xmi_id, source_or_target)
  return if node.nil?

  node.labels&.rt || node.labels&.lt
end

#connector_lookupHash

Lazy-built hash index for O(1) connector lookups

Returns:

  • (Hash)

    Mapping of [direction, idref] => connector



204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 204

def connector_lookup
  @connector_lookup ||= begin
    lookup = {}
    connectors = @xmi_root_model.extension&.connectors&.connector || []
    connectors.each do |con|
      %i[source target].each do |dir|
        idref = con.send(dir)&.idref
        lookup[[dir, idref]] = con if idref
      end
    end
    lookup
  end
end

#connector_name_by_source_or_target(xmi_id, source_or_target) ⇒ String

Parameters:

  • xmi_id (String)
  • source_or_target (String)

Returns:

  • (String)


221
222
223
224
225
226
227
228
229
230
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 221

def connector_name_by_source_or_target(xmi_id, source_or_target) # rubocop:disable Metrics/AbcSize
  node = connector_node_by_id(xmi_id, source_or_target)
  return node.name if node&.name

  return if node.nil? ||
    node.send(source_or_target.to_sym).nil? ||
    node.send(source_or_target.to_sym).model.nil?

  node.send(source_or_target.to_sym).model.name
end

#connector_node_by_id(xmi_id, source_or_target) ⇒ String

Parameters:

  • xmi_id (String)
  • source_or_target (String)

Returns:

  • (String)


198
199
200
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 198

def connector_node_by_id(xmi_id, source_or_target)
  connector_lookup[[source_or_target.to_sym, xmi_id]]
end

#connector_source_name(xmi_id) ⇒ String

Note:

xpath %(//source/model)

Parameters:

  • xmi_id (String)

Returns:

  • (String)


245
246
247
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 245

def connector_source_name(xmi_id)
  connector_name_by_source_or_target(xmi_id, :source)
end

#fetch_assoc_connector(link_id, connector_type) ⇒ Array<Hash, String>

Note:

xpath %(//connector/#connector_type)

Parameters:

  • link_id (String)
  • connector_type (String)

Returns:

  • (Array<Hash, String>)


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 134

def fetch_assoc_connector(link_id, connector_type) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
  connector = fetch_connector(link_id)
  return [nil, nil] unless connector

  assoc_connector = connector.send(connector_type.to_sym)

  if assoc_connector
    assoc_connector_type = assoc_connector.type
    if assoc_connector_type&.multiplicity
      cardinality = assoc_connector_type.multiplicity.split("..")
      cardinality.unshift("1") if cardinality.length == 1
      min, max = cardinality
    end

    assoc_connector_role = assoc_connector.role
    attribute_name = assoc_connector.model.name if assoc_connector_role
    cardinality = cardinality_min_max_value(min, max)
  end

  [cardinality, attribute_name]
end

#fetch_connector(link_id) ⇒ Lutaml::Model::Serializable

Note:

xpath %(//connector)

Parameters:

  • link_id (String)

Returns:

  • (Lutaml::Model::Serializable)


12
13
14
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 12

def fetch_connector(link_id)
  xmi_index.find_connector(link_id)
end

#fetch_connector_name(link_id) ⇒ Object



125
126
127
128
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 125

def fetch_connector_name(link_id)
  connector = fetch_connector(link_id)
  connector&.name
end

#fetch_definition_node_value(link_id, node_name) ⇒ String

Note:

xpath %(//connector/#node_name/documentation)

Parameters:

  • link_id (String)
  • node_name (String)

    source or target

Returns:

  • (String)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 21

def fetch_definition_node_value(link_id, node_name)
  connector_node = fetch_connector(link_id)
  return nil unless connector_node

  node = connector_node.send(node_name.to_sym)
  return nil unless node

  documentation = node.documentation

  if documentation.is_a?(::Xmi::Sparx::Element::Documentation)
    documentation&.value
  else
    documentation
  end
end

#fetch_element(klass_id) ⇒ Lutaml::Model::Serializable

Note:

xpath %(//element)

Parameters:

  • klass_id (String)

Returns:

  • (Lutaml::Model::Serializable)


13
14
15
# File 'lib/lutaml/xmi/parsers/xmi_class_members.rb', line 13

def fetch_element(klass_id)
  xmi_index.find_element(klass_id)
end

#fetch_owned_attribute_node(xmi_id) ⇒ Array<Hash, String>

Note:

xpath %(//ownedAttribute/type[@xmi:id ref=“#xmi_id”])

Multiple items if search type is idref. Should search association?

Parameters:

  • xmi_id (String)

Returns:

  • (Array<Hash, String>)


181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 181

def fetch_owned_attribute_node(xmi_id)
  oa = xmi_index.find_owned_attrs_by_type(xmi_id)
    .find { |a| !!a.association }

  if oa
    cardinality = cardinality_min_max_value(
      oa.lower_value&.value, oa.upper_value&.value
    )
    oa_name = oa.name
  end

  [cardinality, oa_name]
end

#generalization_association(owner_xmi_id, link) ⇒ Array<String, String, Hash, String, String>

Note:

match return value of serialize_member_type

Parameters:

  • owner_xmi_id (String)
  • link (Lutaml::Model::Serializable)

Returns:

  • (Array<String, String, Hash, String, String>)


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 160

def generalization_association(owner_xmi_id, link) # rubocop:disable Metrics/MethodLength
  member_end_type = "generalization"
  xmi_id = link.start
  source_or_target = :source

  if link.start == owner_xmi_id
    member_end_type = "inheritance"
    xmi_id = link.end
    source_or_target = :target
  end

  member_end = member_end_name(xmi_id, source_or_target, link)

  [member_end, member_end_type, xmi_id]
end

#get_ns_by_xmi_id(xmi_id) ⇒ String

Parameters:

  • xmi_id (String)

Returns:

  • (String)


24
25
26
27
28
29
30
31
# File 'lib/lutaml/xmi/parsers/xmi_class_members.rb', line 24

def get_ns_by_xmi_id(xmi_id)
  return unless xmi_id

  p = find_packaged_element_by_id(xmi_id)
  return unless p

  find_upper_level_packaged_element(p.id)&.name
end

#loopup_assoc_def(association) ⇒ Object



17
18
19
20
# File 'lib/lutaml/xmi/parsers/xmi_class_members.rb', line 17

def loopup_assoc_def(association)
  connector = fetch_connector(association)
  connector&.documentation&.value
end

#member_end_name(xmi_id, source_or_target, link) ⇒ String

Parameters:

  • xmi_id (String)
  • source_or_target (Symbol)

Returns:

  • (String)


85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 85

def member_end_name(xmi_id, source_or_target, link) # rubocop:disable Metrics/MethodLength
  connector_label = connector_labels(xmi_id, source_or_target)
  entity_name = lookup_entity_name(xmi_id)
  connector_name = connector_name_by_source_or_target(
    xmi_id, source_or_target
  )

  case link
  when ::Xmi::Sparx::Element::Aggregation
    connector_label || entity_name || connector_name
  else
    entity_name || connector_name
  end
end

#serialize_member_end(owner_xmi_id, link) ⇒ Array<String, String>

Parameters:

  • owner_xmi_id (String)
  • link (Lutaml::Model::Serializable)

Returns:

  • (Array<String, String>)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 58

def serialize_member_end(owner_xmi_id, link) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
  case link.name
  when "NoteLink"
    return
  when "Generalization"
    return generalization_association(owner_xmi_id, link)
  end

  xmi_id = link.start
  source_or_target = :source

  if link.start == owner_xmi_id
    xmi_id = link.end
    source_or_target = :target
  end

  connector = fetch_connector(link.id)
  ea_type = connector&.properties&.ea_type
  member_end_type = ea_type&.downcase

  member_end = member_end_name(xmi_id, source_or_target, link)
  [member_end, member_end_type, xmi_id]
end

#serialize_member_type(owner_xmi_id, link, link_member_name) ⇒ Array<String, String, Hash, String, String>

Parameters:

  • owner_xmi_id (String)
  • link (Lutaml::Model::Serializable)
  • link_member_name (String)

Returns:

  • (Array<String, String, Hash, String, String>)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 104

def serialize_member_type(owner_xmi_id, link, link_member_name) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
  member_end, member_end_type, xmi_id =
    serialize_member_end(owner_xmi_id, link)

  if link.is_a?(::Xmi::Sparx::Element::Association)
    connector_type = link_member_name == "start" ? "source" : "target"
    member_end_cardinality, member_end_attribute_name =
      fetch_assoc_connector(link.id, connector_type)
  else
    member_end_cardinality, member_end_attribute_name =
      fetch_owned_attribute_node(xmi_id)
  end

  if fetch_connector_name(link.id)
    member_end = fetch_connector_name(link.id)
  end

  [member_end, member_end_type, member_end_cardinality,
   member_end_attribute_name, xmi_id]
end

#serialize_owned_type(owner_xmi_id, link, linke_owner_name) ⇒ String

Parameters:

  • owner_xmi_id (String)
  • link (Lutaml::Model::Serializable)
  • link_member_name (String)

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/lutaml/xmi/parsers/xmi_connector.rb', line 41

def serialize_owned_type(owner_xmi_id, link, linke_owner_name)
  case link
  when ::Xmi::Sparx::Element::NoteLink
    return
  when ::Xmi::Sparx::Element::Generalization
    owner_end, _owner_end_type, _owner_xmi_id =
      generalization_association(owner_xmi_id, link)
    return owner_end
  end

  xmi_id = link.send(linke_owner_name.to_sym)
  lookup_entity_name(xmi_id) || connector_source_name(xmi_id)
end

#set_xmi_model(xmi_model, id_name_mapping = nil) ⇒ Hash

Parameters:

  • xmi_model (Lutaml::Model::Serializable)
  • id_name_mapping (Hash) (defaults to: nil)

Returns:

  • (Hash)


31
32
33
34
35
36
37
38
# File 'lib/lutaml/xmi/parsers/xmi_base.rb', line 31

def set_xmi_model(xmi_model, id_name_mapping = nil)
  @xmi_root_model ||= xmi_model

  if @xmi_index.nil?
    @xmi_index = @xmi_root_model.index
    @id_name_mapping = id_name_mapping || @xmi_index.id_name_map
  end
end

#xmi_indexObject

Access the index, auto-initializing from @xmi_root_model if needed



41
42
43
44
45
46
47
# File 'lib/lutaml/xmi/parsers/xmi_base.rb', line 41

def xmi_index
  if @xmi_index.nil? && @xmi_root_model
    @xmi_index = @xmi_root_model.index
    @id_name_mapping ||= @xmi_index.id_name_map
  end
  @xmi_index
end