Class: Lutaml::Model::Xml::Mapping

Inherits:
Mapping
  • Object
show all
Defined in:
lib/lutaml/model/xml/mapping.rb

Constant Summary collapse

TYPES =
{
  attribute: :map_attribute,
  element: :map_element,
  content: :map_content,
  all_content: :map_all,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMapping



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/lutaml/model/xml/mapping.rb', line 23

def initialize
  super

  @elements = {}
  @attributes = {}
  @element_sequence = []
  @content_mapping = nil
  @raw_mapping = nil
  @mixed_content = false
  @format = :xml
  @mappings_imported = true
  @finalized = false
end

Instance Attribute Details

#element_sequenceObject (readonly)

Returns the value of attribute element_sequence.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def element_sequence
  @element_sequence
end

#mappings_importedObject (readonly)

Returns the value of attribute mappings_imported.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def mappings_imported
  @mappings_imported
end

#mixed_contentObject (readonly) Also known as: mixed_content?

Returns the value of attribute mixed_content.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def mixed_content
  @mixed_content
end

#namespace_prefixObject (readonly)

Returns the value of attribute namespace_prefix.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def namespace_prefix
  @namespace_prefix
end

#namespace_uriObject (readonly)

Returns the value of attribute namespace_uri.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def namespace_uri
  @namespace_uri
end

#orderedObject (readonly) Also known as: ordered?

Returns the value of attribute ordered.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def ordered
  @ordered
end

#root_elementObject (readonly)

Returns the value of attribute root_element.



15
16
17
# File 'lib/lutaml/model/xml/mapping.rb', line 15

def root_element
  @root_element
end

Instance Method Details

#attribute(name) ⇒ Object



371
372
373
# File 'lib/lutaml/model/xml/mapping.rb', line 371

def attribute(name)
  attributes.detect { |rule| name == rule.to }
end

#attributesObject



322
323
324
# File 'lib/lutaml/model/xml/mapping.rb', line 322

def attributes
  @attributes.values
end

#attributes_to_dupObject



433
434
435
436
437
438
439
440
441
# File 'lib/lutaml/model/xml/mapping.rb', line 433

def attributes_to_dup
  @attributes_to_dup ||= %i[
    @content_mapping
    @raw_mapping
    @element_sequence
    @attributes
    @elements
  ]
end

#content_mappingObject



326
327
328
# File 'lib/lutaml/model/xml/mapping.rb', line 326

def content_mapping
  @content_mapping
end

#deep_dupObject



415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/lutaml/model/xml/mapping.rb', line 415

def deep_dup
  self.class.new.tap do |xml_mapping|
    xml_mapping.root(@root_element.dup, mixed: @mixed_content,
                                        ordered: @ordered)
    xml_mapping.namespace(@namespace_uri.dup, @namespace_prefix.dup)

    attributes_to_dup.each do |var_name|
      value = instance_variable_get(var_name)
      xml_mapping.instance_variable_set(var_name, Utils.deep_dup(value))
    end
    xml_mapping.instance_variable_set(:@finalized, true)
  end
end

#dup_mappings(mappings) ⇒ Object



443
444
445
446
447
448
449
450
451
# File 'lib/lutaml/model/xml/mapping.rb', line 443

def dup_mappings(mappings)
  new_mappings = {}

  mappings.each do |key, mapping_rule|
    new_mappings[key] = mapping_rule.deep_dup
  end

  new_mappings
end

#element(name) ⇒ Object



367
368
369
# File 'lib/lutaml/model/xml/mapping.rb', line 367

def element(name)
  elements.detect { |rule| name == rule.to }
end

#elementsObject



318
319
320
# File 'lib/lutaml/model/xml/mapping.rb', line 318

def elements
  @elements.values
end

#ensure_mappings_imported!(register_id = nil) ⇒ Object



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/lutaml/model/xml/mapping.rb', line 339

def ensure_mappings_imported!(register_id = nil)
  return if @mappings_imported

  importable_mappings.each do |model|
    import_model_mappings(
      register(register_id).get_class_without_register(model),
    )
  end

  sequence_importable_mappings.each do |sequence, models|
    models.each do |model|
      sequence.import_model_mappings(
        register(register_id).get_class_without_register(model),
      )
    end
  end

  @mappings_imported = true
end

#finalize(mapper_class) ⇒ Object



37
38
39
40
41
42
# File 'lib/lutaml/model/xml/mapping.rb', line 37

def finalize(mapper_class)
  if !root_element && !no_root?
    root(mapper_class.model.to_s)
  end
  @finalized = true
end

#finalized?Boolean



44
45
46
# File 'lib/lutaml/model/xml/mapping.rb', line 44

def finalized?
  @finalized
end

#find_by_name(name, type: "Text") ⇒ Object



375
376
377
378
379
380
381
382
383
# File 'lib/lutaml/model/xml/mapping.rb', line 375

def find_by_name(name, type: "Text")
  if ["text", "#cdata-section"].include?(name.to_s) && type == "Text"
    content_mapping
  else
    mappings.detect do |rule|
      rule.name == name.to_s || rule.name == name.to_sym
    end
  end
end

#find_by_to(to) ⇒ Object



385
386
387
# File 'lib/lutaml/model/xml/mapping.rb', line 385

def find_by_to(to)
  mappings.detect { |rule| rule.to.to_s == to.to_s }
end

#import_model_mappings(model) ⇒ Object



262
263
264
265
266
267
268
269
270
# File 'lib/lutaml/model/xml/mapping.rb', line 262

def import_model_mappings(model)
  return import_mappings_later(model) if model_importable?(model)
  raise Lutaml::Model::ImportModelWithRootError.new(model) if model.root?

  mappings = model.mappings_for(:xml)
  @elements.merge!(mappings.instance_variable_get(:@elements))
  @attributes.merge!(mappings.instance_variable_get(:@attributes))
  (@element_sequence << mappings.element_sequence).flatten!
end

#importable_mappingsObject



359
360
361
# File 'lib/lutaml/model/xml/mapping.rb', line 359

def importable_mappings
  @importable_mappings ||= []
end

#map_all(to:, render_nil: false, render_default: false, delegate: nil, with: {}, namespace: (namespace_set = false nil), prefix: (prefix_set = false nil), render_empty: false) ⇒ Object Also known as: map_all_content



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/lutaml/model/xml/mapping.rb', line 218

def map_all(
  to:,
  render_nil: false,
  render_default: false,
  delegate: nil,
  with: {},
  namespace: (namespace_set = false
              nil),
  prefix: (prefix_set = false
           nil),
  render_empty: false
)
  validate!(
    Constants::RAW_MAPPING_KEY,
    to,
    with,
    render_nil,
    render_empty,
    type: TYPES[:all_content],
  )

  rule = MappingRule.new(
    Constants::RAW_MAPPING_KEY,
    to: to,
    render_nil: render_nil,
    render_default: render_default,
    with: with,
    delegate: delegate,
    namespace: namespace,
    prefix: prefix,
    default_namespace: namespace_uri,
    namespace_set: namespace_set != false,
    prefix_set: prefix_set != false,
  )

  @raw_mapping = rule
end

#map_attribute(name, to: nil, render_nil: false, render_default: false, render_empty: false, with: {}, delegate: nil, polymorphic_map: {}, namespace: (namespace_set = false nil), prefix: (prefix_set = false nil), transform: {}, value_map: {}) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/lutaml/model/xml/mapping.rb', line 137

def map_attribute(
  name,
  to: nil,
  render_nil: false,
  render_default: false,
  render_empty: false,
  with: {},
  delegate: nil,
  polymorphic_map: {},
  namespace: (namespace_set = false
              nil),
  prefix: (prefix_set = false
           nil),
  transform: {},
  value_map: {}
)
  validate!(
    name, to, with, render_nil, render_empty, type: TYPES[:attribute]
  )

  if name == "schemaLocation"
    Logger.warn_auto_handling(
      name: name,
      caller_file: File.basename(caller_locations(1, 1)[0].path),
      caller_line: caller_locations(1, 1)[0].lineno,
    )
  end

  rule = MappingRule.new(
    name,
    to: to,
    render_nil: render_nil,
    render_default: render_default,
    with: with,
    delegate: delegate,
    namespace: namespace,
    prefix: prefix,
    attribute: true,
    polymorphic_map: polymorphic_map,
    default_namespace: namespace_uri,
    namespace_set: namespace_set != false,
    prefix_set: prefix_set != false,
    transform: transform,
    value_map: value_map,
  )
  @attributes[rule.namespaced_name] = rule
end

#map_content(to: nil, render_nil: false, render_default: false, render_empty: false, with: {}, delegate: nil, mixed: false, cdata: false, transform: {}, value_map: {}) ⇒ Object

rubocop:enable Metrics/ParameterLists



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/lutaml/model/xml/mapping.rb', line 187

def map_content(
  to: nil,
  render_nil: false,
  render_default: false,
  render_empty: false,
  with: {},
  delegate: nil,
  mixed: false,
  cdata: false,
  transform: {},
  value_map: {}
)
  validate!(
    "content", to, with, render_nil, render_empty, type: TYPES[:content]
  )

  @content_mapping = MappingRule.new(
    nil,
    to: to,
    render_nil: render_nil,
    render_default: render_default,
    render_empty: render_empty,
    with: with,
    delegate: delegate,
    mixed_content: mixed,
    cdata: cdata,
    transform: transform,
    value_map: value_map,
  )
end

#map_element(name, to: nil, render_nil: false, render_default: false, render_empty: false, treat_nil: :nil, treat_empty: :empty, treat_omitted: :nil, with: {}, delegate: nil, cdata: false, polymorphic: {}, namespace: (namespace_set = false nil), prefix: (prefix_set = false nil), transform: {}, value_map: {}) ⇒ Object

rubocop:disable Metrics/ParameterLists



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lutaml/model/xml/mapping.rb', line 89

def map_element(
  name,
  to: nil,
  render_nil: false,
  render_default: false,
  render_empty: false,
  treat_nil: :nil,
  treat_empty: :empty,
  treat_omitted: :nil,
  with: {},
  delegate: nil,
  cdata: false,
  polymorphic: {},
  namespace: (namespace_set = false
              nil),
  prefix: (prefix_set = false
           nil),
  transform: {},
  value_map: {}
)
  validate!(
    name, to, with, render_nil, render_empty, type: TYPES[:element]
  )

  rule = MappingRule.new(
    name,
    to: to,
    render_nil: render_nil,
    render_default: render_default,
    render_empty: render_empty,
    treat_nil: treat_nil,
    treat_empty: treat_empty,
    treat_omitted: treat_omitted,
    with: with,
    delegate: delegate,
    cdata: cdata,
    namespace: namespace,
    default_namespace: namespace_uri,
    prefix: prefix,
    polymorphic: polymorphic,
    namespace_set: namespace_set != false,
    prefix_set: prefix_set != false,
    transform: transform,
    value_map: value_map,
  )
  @elements[rule.namespaced_name] = rule
end

#map_instances(to:) ⇒ Object



84
85
86
# File 'lib/lutaml/model/xml/mapping.rb', line 84

def map_instances(to:)
  map_element(to, to: to)
end

#mapping_attributes_hashObject



389
390
391
# File 'lib/lutaml/model/xml/mapping.rb', line 389

def mapping_attributes_hash
  @attributes
end

#mapping_elements_hashObject



393
394
395
# File 'lib/lutaml/model/xml/mapping.rb', line 393

def mapping_elements_hash
  @elements
end

#mappings(register_id = nil) ⇒ Object



334
335
336
337
# File 'lib/lutaml/model/xml/mapping.rb', line 334

def mappings(register_id = nil)
  ensure_mappings_imported!(register_id) if finalized?
  elements + attributes + [content_mapping, raw_mapping].compact
end

#merge_elements_sequence(mapping) ⇒ Object



405
406
407
408
409
410
411
412
413
# File 'lib/lutaml/model/xml/mapping.rb', line 405

def merge_elements_sequence(mapping)
  mapping.element_sequence.each do |sequence|
    element_sequence << Lutaml::Model::Sequence.new(self).tap do |instance|
      sequence.attributes.each do |attr|
        instance.attributes << attr.deep_dup
      end
    end
  end
end

#merge_mapping_attributes(mapping) ⇒ Object



397
398
399
# File 'lib/lutaml/model/xml/mapping.rb', line 397

def merge_mapping_attributes(mapping)
  mapping_attributes_hash.merge!(mapping.mapping_attributes_hash)
end

#merge_mapping_elements(mapping) ⇒ Object



401
402
403
# File 'lib/lutaml/model/xml/mapping.rb', line 401

def merge_mapping_elements(mapping)
  mapping_elements_hash.merge!(mapping.mapping_elements_hash)
end

#namespace(uri, prefix = nil) ⇒ Object



77
78
79
80
81
82
# File 'lib/lutaml/model/xml/mapping.rb', line 77

def namespace(uri, prefix = nil)
  raise Lutaml::Model::NoRootNamespaceError if no_root?

  @namespace_uri = uri
  @namespace_prefix = prefix
end

#no_rootObject



61
62
63
# File 'lib/lutaml/model/xml/mapping.rb', line 61

def no_root
  @no_root = true
end

#no_root?Boolean



65
66
67
# File 'lib/lutaml/model/xml/mapping.rb', line 65

def no_root?
  !!@no_root
end

#polymorphic_mappingObject



429
430
431
# File 'lib/lutaml/model/xml/mapping.rb', line 429

def polymorphic_mapping
  mappings.find(&:polymorphic_mapping?)
end

#prefixed_rootObject



69
70
71
72
73
74
75
# File 'lib/lutaml/model/xml/mapping.rb', line 69

def prefixed_root
  if namespace_uri && namespace_prefix
    "#{namespace_prefix}:#{root_element}"
  else
    root_element
  end
end

#raw_mappingObject



330
331
332
# File 'lib/lutaml/model/xml/mapping.rb', line 330

def raw_mapping
  @raw_mapping
end

#root(name, mixed: false, ordered: false) ⇒ Object



51
52
53
54
55
# File 'lib/lutaml/model/xml/mapping.rb', line 51

def root(name, mixed: false, ordered: false)
  @root_element = name
  @mixed_content = mixed
  @ordered = ordered || mixed # mixed contenet will always be ordered
end

#root?Boolean



57
58
59
# File 'lib/lutaml/model/xml/mapping.rb', line 57

def root?
  !!root_element
end

#sequence(&block) ⇒ Object



258
259
260
# File 'lib/lutaml/model/xml/mapping.rb', line 258

def sequence(&block)
  @element_sequence << Sequence.new(self).tap { |s| s.instance_eval(&block) }
end

#sequence_importable_mappingsObject



363
364
365
# File 'lib/lutaml/model/xml/mapping.rb', line 363

def sequence_importable_mappings
  @sequence_importable_mappings ||= Hash.new { |h, k| h[k] = [] }
end

#set_mappings_imported(value) ⇒ Object



272
273
274
# File 'lib/lutaml/model/xml/mapping.rb', line 272

def set_mappings_imported(value)
  @mappings_imported = value
end

#validate!(key, to, with, render_nil, render_empty, type: nil) ⇒ Object



276
277
278
279
280
281
282
283
284
285
# File 'lib/lutaml/model/xml/mapping.rb', line 276

def validate!(key, to, with, render_nil, render_empty, type: nil)
  validate_raw_mappings!(type)
  validate_to_and_with_arguments!(key, to, with)

  if render_nil == :as_empty || render_empty == :as_empty
    raise IncorrectMappingArgumentsError.new(
      ":as_empty is not supported for XML mappings",
    )
  end
end

#validate_raw_mappings!(type) ⇒ Object



307
308
309
310
311
312
313
314
315
316
# File 'lib/lutaml/model/xml/mapping.rb', line 307

def validate_raw_mappings!(type)
  if !@raw_mapping.nil? && type != TYPES[:attribute]
    raise StandardError, "#{type} is not allowed, only #{TYPES[:attribute]} " \
                         "is allowed with #{TYPES[:all_content]}"
  end

  if !(elements.empty? && content_mapping.nil?) && type == TYPES[:all_content]
    raise StandardError, "#{TYPES[:all_content]} is not allowed with other mappings"
  end
end

#validate_to_and_with_arguments!(key, to, with) ⇒ Object



287
288
289
290
291
292
293
294
295
# File 'lib/lutaml/model/xml/mapping.rb', line 287

def validate_to_and_with_arguments!(key, to, with)
  if to.nil? && with.empty?
    raise IncorrectMappingArgumentsError.new(
      ":to or :with argument is required for mapping '#{key}'",
    )
  end

  validate_with_options!(key, to, with)
end

#validate_with_options!(key, to, with) ⇒ Object



297
298
299
300
301
302
303
304
305
# File 'lib/lutaml/model/xml/mapping.rb', line 297

def validate_with_options!(key, to, with)
  return true if to

  if !with.empty? && (with[:from].nil? || with[:to].nil?)
    raise IncorrectMappingArgumentsError.new(
      ":with argument for mapping '#{key}' requires :to and :from keys",
    )
  end
end