lutaml-model 0.7.1 → 0.7.3

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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.rubocop_todo.yml +49 -48
  4. data/Gemfile +4 -1
  5. data/README.adoc +791 -143
  6. data/RELEASE_NOTES.adoc +346 -0
  7. data/docs/custom_adapters.adoc +144 -0
  8. data/lib/lutaml/model/attribute.rb +17 -11
  9. data/lib/lutaml/model/config.rb +48 -42
  10. data/lib/lutaml/model/error/polymorphic_error.rb +7 -2
  11. data/lib/lutaml/model/format_registry.rb +41 -0
  12. data/lib/lutaml/model/hash/document.rb +11 -0
  13. data/lib/lutaml/model/hash/mapping.rb +19 -0
  14. data/lib/lutaml/model/hash/mapping_rule.rb +9 -0
  15. data/lib/lutaml/model/hash/standard_adapter.rb +17 -0
  16. data/lib/lutaml/model/hash/transform.rb +8 -0
  17. data/lib/lutaml/model/hash.rb +21 -0
  18. data/lib/lutaml/model/json/document.rb +11 -0
  19. data/lib/lutaml/model/json/mapping.rb +19 -0
  20. data/lib/lutaml/model/json/mapping_rule.rb +9 -0
  21. data/lib/lutaml/model/{json_adapter → json}/multi_json_adapter.rb +4 -5
  22. data/lib/lutaml/model/{json_adapter/standard_json_adapter.rb → json/standard_adapter.rb} +5 -3
  23. data/lib/lutaml/model/json/transform.rb +8 -0
  24. data/lib/lutaml/model/json.rb +21 -0
  25. data/lib/lutaml/model/key_value_document.rb +27 -0
  26. data/lib/lutaml/model/mapping/key_value_mapping.rb +8 -4
  27. data/lib/lutaml/model/mapping/mapping.rb +13 -0
  28. data/lib/lutaml/model/mapping/mapping_rule.rb +7 -6
  29. data/lib/lutaml/model/serialization_adapter.rb +22 -0
  30. data/lib/lutaml/model/serialize.rb +146 -521
  31. data/lib/lutaml/model/services/logger.rb +54 -0
  32. data/lib/lutaml/model/services/transformer.rb +48 -0
  33. data/lib/lutaml/model/services.rb +2 -0
  34. data/lib/lutaml/model/toml/document.rb +11 -0
  35. data/lib/lutaml/model/toml/mapping.rb +27 -0
  36. data/lib/lutaml/model/toml/mapping_rule.rb +9 -0
  37. data/lib/lutaml/model/{toml_adapter → toml}/toml_rb_adapter.rb +3 -3
  38. data/lib/lutaml/model/toml/tomlib_adapter.rb +19 -0
  39. data/lib/lutaml/model/toml/transform.rb +8 -0
  40. data/lib/lutaml/model/toml.rb +30 -0
  41. data/lib/lutaml/model/transform/key_value_transform.rb +291 -0
  42. data/lib/lutaml/model/transform/xml_transform.rb +239 -0
  43. data/lib/lutaml/model/transform.rb +78 -0
  44. data/lib/lutaml/model/type/value.rb +6 -9
  45. data/lib/lutaml/model/uninitialized_class.rb +1 -1
  46. data/lib/lutaml/model/utils.rb +30 -0
  47. data/lib/lutaml/model/version.rb +1 -1
  48. data/lib/lutaml/model/{xml_adapter → xml}/builder/nokogiri.rb +2 -2
  49. data/lib/lutaml/model/{xml_adapter → xml}/builder/oga.rb +10 -10
  50. data/lib/lutaml/model/{xml_adapter → xml}/builder/ox.rb +1 -1
  51. data/lib/lutaml/model/{xml_adapter/xml_document.rb → xml/document.rb} +6 -7
  52. data/lib/lutaml/model/xml/element.rb +32 -0
  53. data/lib/lutaml/model/xml/mapping.rb +410 -0
  54. data/lib/lutaml/model/xml/mapping_rule.rb +141 -0
  55. data/lib/lutaml/model/xml/nokogiri_adapter.rb +232 -0
  56. data/lib/lutaml/model/{xml_adapter → xml}/oga/document.rb +1 -1
  57. data/lib/lutaml/model/{xml_adapter → xml}/oga/element.rb +3 -1
  58. data/lib/lutaml/model/xml/oga_adapter.rb +171 -0
  59. data/lib/lutaml/model/xml/ox_adapter.rb +215 -0
  60. data/lib/lutaml/model/xml/transform.rb +8 -0
  61. data/lib/lutaml/model/{xml_adapter → xml}/xml_attribute.rb +1 -1
  62. data/lib/lutaml/model/{xml_adapter → xml}/xml_element.rb +6 -3
  63. data/lib/lutaml/model/{xml_adapter → xml}/xml_namespace.rb +1 -1
  64. data/lib/lutaml/model/xml.rb +31 -0
  65. data/lib/lutaml/model/xml_adapter/element.rb +11 -25
  66. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +6 -223
  67. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +13 -163
  68. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +10 -207
  69. data/lib/lutaml/model/yaml/document.rb +10 -0
  70. data/lib/lutaml/model/yaml/mapping.rb +19 -0
  71. data/lib/lutaml/model/yaml/mapping_rule.rb +9 -0
  72. data/lib/lutaml/model/{yaml_adapter/standard_yaml_adapter.rb → yaml/standard_adapter.rb} +4 -3
  73. data/lib/lutaml/model/yaml/transform.rb +8 -0
  74. data/lib/lutaml/model/yaml.rb +21 -0
  75. data/lib/lutaml/model.rb +39 -4
  76. data/lutaml-model.gemspec +0 -4
  77. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +4 -4
  78. data/spec/lutaml/model/cdata_spec.rb +7 -7
  79. data/spec/lutaml/model/custom_bibtex_adapter_spec.rb +598 -0
  80. data/spec/lutaml/model/custom_vobject_adapter_spec.rb +1226 -0
  81. data/spec/lutaml/model/group_spec.rb +18 -7
  82. data/spec/lutaml/model/hash/adapter_spec.rb +255 -0
  83. data/spec/lutaml/model/json_adapter_spec.rb +6 -6
  84. data/spec/lutaml/model/key_value_mapping_spec.rb +25 -1
  85. data/spec/lutaml/model/mixed_content_spec.rb +24 -24
  86. data/spec/lutaml/model/multiple_mapping_spec.rb +5 -5
  87. data/spec/lutaml/model/ordered_content_spec.rb +6 -6
  88. data/spec/lutaml/model/polymorphic_spec.rb +178 -0
  89. data/spec/lutaml/model/root_mappings_spec.rb +3 -3
  90. data/spec/lutaml/model/schema/xml_compiler_spec.rb +6 -6
  91. data/spec/lutaml/model/serializable_spec.rb +179 -103
  92. data/spec/lutaml/model/toml_adapter_spec.rb +6 -6
  93. data/spec/lutaml/model/toml_spec.rb +51 -0
  94. data/spec/lutaml/model/transformation_spec.rb +72 -15
  95. data/spec/lutaml/model/uninitialized_class_spec.rb +96 -0
  96. data/spec/lutaml/model/xml/namespace_spec.rb +57 -0
  97. data/spec/lutaml/model/xml/xml_element_spec.rb +1 -1
  98. data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +2 -2
  99. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
  100. data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
  101. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +6 -6
  102. data/spec/lutaml/model/xml_adapter_spec.rb +6 -6
  103. data/spec/lutaml/model/xml_mapping_rule_spec.rb +3 -3
  104. data/spec/lutaml/model/xml_mapping_spec.rb +26 -14
  105. data/spec/lutaml/model/xml_spec.rb +63 -0
  106. data/spec/lutaml/model/yaml_adapter_spec.rb +3 -5
  107. data/spec/spec_helper.rb +3 -3
  108. metadata +64 -59
  109. data/lib/lutaml/model/json_adapter/json_document.rb +0 -20
  110. data/lib/lutaml/model/json_adapter/json_object.rb +0 -28
  111. data/lib/lutaml/model/loggable.rb +0 -15
  112. data/lib/lutaml/model/mapping/json_mapping.rb +0 -17
  113. data/lib/lutaml/model/mapping/toml_mapping.rb +0 -25
  114. data/lib/lutaml/model/mapping/xml_mapping.rb +0 -389
  115. data/lib/lutaml/model/mapping/xml_mapping_rule.rb +0 -139
  116. data/lib/lutaml/model/mapping/yaml_mapping.rb +0 -17
  117. data/lib/lutaml/model/mapping.rb +0 -14
  118. data/lib/lutaml/model/toml_adapter/toml_document.rb +0 -20
  119. data/lib/lutaml/model/toml_adapter/toml_object.rb +0 -28
  120. data/lib/lutaml/model/toml_adapter/tomlib_adapter.rb +0 -20
  121. data/lib/lutaml/model/toml_adapter.rb +0 -6
  122. data/lib/lutaml/model/yaml_adapter/yaml_document.rb +0 -20
  123. data/lib/lutaml/model/yaml_adapter/yaml_object.rb +0 -28
  124. data/lib/lutaml/model/yaml_adapter.rb +0 -8
@@ -0,0 +1,410 @@
1
+ require_relative "../mapping/mapping"
2
+ require_relative "mapping_rule"
3
+
4
+ module Lutaml
5
+ module Model
6
+ module Xml
7
+ class Mapping < Mapping
8
+ TYPES = {
9
+ attribute: :map_attribute,
10
+ element: :map_element,
11
+ content: :map_content,
12
+ all_content: :map_all,
13
+ }.freeze
14
+
15
+ attr_reader :root_element,
16
+ :namespace_uri,
17
+ :namespace_prefix,
18
+ :mixed_content,
19
+ :ordered,
20
+ :element_sequence
21
+
22
+ def initialize
23
+ super
24
+
25
+ @elements = {}
26
+ @attributes = {}
27
+ @element_sequence = []
28
+ @content_mapping = nil
29
+ @raw_mapping = nil
30
+ @mixed_content = false
31
+ @format = :xml
32
+ end
33
+
34
+ def finalize(mapper_class)
35
+ if !root_element && !no_root?
36
+ root(mapper_class.model.to_s)
37
+ end
38
+ end
39
+
40
+ alias mixed_content? mixed_content
41
+ alias ordered? ordered
42
+
43
+ def root(name, mixed: false, ordered: false)
44
+ @root_element = name
45
+ @mixed_content = mixed
46
+ @ordered = ordered || mixed # mixed contenet will always be ordered
47
+ end
48
+
49
+ def root?
50
+ !!root_element
51
+ end
52
+
53
+ def no_root
54
+ @no_root = true
55
+ end
56
+
57
+ def no_root?
58
+ !!@no_root
59
+ end
60
+
61
+ def prefixed_root
62
+ if namespace_uri && namespace_prefix
63
+ "#{namespace_prefix}:#{root_element}"
64
+ else
65
+ root_element
66
+ end
67
+ end
68
+
69
+ def namespace(uri, prefix = nil)
70
+ raise Lutaml::Model::NoRootNamespaceError if no_root?
71
+
72
+ @namespace_uri = uri
73
+ @namespace_prefix = prefix
74
+ end
75
+
76
+ # rubocop:disable Metrics/ParameterLists
77
+ def map_element(
78
+ name,
79
+ to: nil,
80
+ render_nil: false,
81
+ render_default: false,
82
+ render_empty: false,
83
+ treat_nil: :nil,
84
+ treat_empty: :empty,
85
+ treat_omitted: :nil,
86
+ with: {},
87
+ delegate: nil,
88
+ cdata: false,
89
+ polymorphic: {},
90
+ namespace: (namespace_set = false
91
+ nil),
92
+ prefix: (prefix_set = false
93
+ nil),
94
+ transform: {},
95
+ value_map: {}
96
+ )
97
+ validate!(
98
+ name, to, with, render_nil, render_empty, type: TYPES[:element]
99
+ )
100
+
101
+ rule = MappingRule.new(
102
+ name,
103
+ to: to,
104
+ render_nil: render_nil,
105
+ render_default: render_default,
106
+ render_empty: render_empty,
107
+ treat_nil: treat_nil,
108
+ treat_empty: treat_empty,
109
+ treat_omitted: treat_omitted,
110
+ with: with,
111
+ delegate: delegate,
112
+ cdata: cdata,
113
+ namespace: namespace,
114
+ default_namespace: namespace_uri,
115
+ prefix: prefix,
116
+ polymorphic: polymorphic,
117
+ namespace_set: namespace_set != false,
118
+ prefix_set: prefix_set != false,
119
+ transform: transform,
120
+ value_map: value_map,
121
+ )
122
+ @elements[rule.namespaced_name] = rule
123
+ end
124
+
125
+ def map_attribute(
126
+ name,
127
+ to: nil,
128
+ render_nil: false,
129
+ render_default: false,
130
+ render_empty: false,
131
+ with: {},
132
+ delegate: nil,
133
+ polymorphic_map: {},
134
+ namespace: (namespace_set = false
135
+ nil),
136
+ prefix: (prefix_set = false
137
+ nil),
138
+ transform: {},
139
+ value_map: {}
140
+ )
141
+ validate!(
142
+ name, to, with, render_nil, render_empty, type: TYPES[:attribute]
143
+ )
144
+
145
+ if name == "schemaLocation"
146
+ Logger.warn_auto_handling(
147
+ name: name,
148
+ caller_file: File.basename(caller_locations(1, 1)[0].path),
149
+ caller_line: caller_locations(1, 1)[0].lineno,
150
+ )
151
+ end
152
+
153
+ rule = MappingRule.new(
154
+ name,
155
+ to: to,
156
+ render_nil: render_nil,
157
+ render_default: render_default,
158
+ with: with,
159
+ delegate: delegate,
160
+ namespace: namespace,
161
+ prefix: prefix,
162
+ attribute: true,
163
+ polymorphic_map: polymorphic_map,
164
+ default_namespace: namespace_uri,
165
+ namespace_set: namespace_set != false,
166
+ prefix_set: prefix_set != false,
167
+ transform: transform,
168
+ value_map: value_map,
169
+ )
170
+ @attributes[rule.namespaced_name] = rule
171
+ end
172
+
173
+ # rubocop:enable Metrics/ParameterLists
174
+
175
+ def map_content(
176
+ to: nil,
177
+ render_nil: false,
178
+ render_default: false,
179
+ render_empty: false,
180
+ with: {},
181
+ delegate: nil,
182
+ mixed: false,
183
+ cdata: false,
184
+ transform: {},
185
+ value_map: {}
186
+ )
187
+ validate!(
188
+ "content", to, with, render_nil, render_empty, type: TYPES[:content]
189
+ )
190
+
191
+ @content_mapping = MappingRule.new(
192
+ nil,
193
+ to: to,
194
+ render_nil: render_nil,
195
+ render_default: render_default,
196
+ render_empty: render_empty,
197
+ with: with,
198
+ delegate: delegate,
199
+ mixed_content: mixed,
200
+ cdata: cdata,
201
+ transform: transform,
202
+ value_map: value_map,
203
+ )
204
+ end
205
+
206
+ def map_all(
207
+ to:,
208
+ render_nil: false,
209
+ render_default: false,
210
+ delegate: nil,
211
+ with: {},
212
+ namespace: (namespace_set = false
213
+ nil),
214
+ prefix: (prefix_set = false
215
+ nil),
216
+ render_empty: false
217
+ )
218
+ validate!(
219
+ Constants::RAW_MAPPING_KEY,
220
+ to,
221
+ with,
222
+ render_nil,
223
+ render_empty,
224
+ type: TYPES[:all_content],
225
+ )
226
+
227
+ rule = MappingRule.new(
228
+ Constants::RAW_MAPPING_KEY,
229
+ to: to,
230
+ render_nil: render_nil,
231
+ render_default: render_default,
232
+ with: with,
233
+ delegate: delegate,
234
+ namespace: namespace,
235
+ prefix: prefix,
236
+ default_namespace: namespace_uri,
237
+ namespace_set: namespace_set != false,
238
+ prefix_set: prefix_set != false,
239
+ )
240
+
241
+ @raw_mapping = rule
242
+ end
243
+
244
+ alias map_all_content map_all
245
+
246
+ def sequence(&block)
247
+ @element_sequence << Sequence.new(self).tap do |s|
248
+ s.instance_eval(&block)
249
+ end
250
+ end
251
+
252
+ def import_model_mappings(model)
253
+ raise Lutaml::Model::ImportModelWithRootError.new(model) if model.root?
254
+
255
+ mappings = model.mappings_for(:xml)
256
+ @elements.merge!(mappings.instance_variable_get(:@elements))
257
+ @attributes.merge!(mappings.instance_variable_get(:@attributes))
258
+ (@element_sequence << mappings.element_sequence).flatten!
259
+ end
260
+
261
+ def validate!(key, to, with, render_nil, render_empty, type: nil)
262
+ validate_raw_mappings!(type)
263
+ validate_to_and_with_arguments!(key, to, with)
264
+
265
+ if render_nil == :as_empty || render_empty == :as_empty
266
+ raise IncorrectMappingArgumentsError.new(
267
+ ":as_empty is not supported for XML mappings",
268
+ )
269
+ end
270
+ end
271
+
272
+ def validate_to_and_with_arguments!(key, to, with)
273
+ if to.nil? && with.empty?
274
+ raise IncorrectMappingArgumentsError.new(
275
+ ":to or :with argument is required for mapping '#{key}'",
276
+ )
277
+ end
278
+
279
+ validate_with_options!(key, to, with)
280
+ end
281
+
282
+ def validate_with_options!(key, to, with)
283
+ return true if to
284
+
285
+ if !with.empty? && (with[:from].nil? || with[:to].nil?)
286
+ raise IncorrectMappingArgumentsError.new(
287
+ ":with argument for mapping '#{key}' requires :to and :from keys",
288
+ )
289
+ end
290
+ end
291
+
292
+ def validate_raw_mappings!(type)
293
+ if !@raw_mapping.nil? && type != TYPES[:attribute]
294
+ raise StandardError, "#{type} is not allowed, only #{TYPES[:attribute]} " \
295
+ "is allowed with #{TYPES[:all_content]}"
296
+ end
297
+
298
+ if !(elements.empty? && content_mapping.nil?) && type == TYPES[:all_content]
299
+ raise StandardError, "#{TYPES[:all_content]} is not allowed with other mappings"
300
+ end
301
+ end
302
+
303
+ def elements
304
+ @elements.values
305
+ end
306
+
307
+ def attributes
308
+ @attributes.values
309
+ end
310
+
311
+ def content_mapping
312
+ @content_mapping
313
+ end
314
+
315
+ def raw_mapping
316
+ @raw_mapping
317
+ end
318
+
319
+ def mappings
320
+ elements + attributes + [content_mapping, raw_mapping].compact
321
+ end
322
+
323
+ def element(name)
324
+ elements.detect do |rule|
325
+ name == rule.to
326
+ end
327
+ end
328
+
329
+ def attribute(name)
330
+ attributes.detect do |rule|
331
+ name == rule.to
332
+ end
333
+ end
334
+
335
+ def find_by_name(name)
336
+ if ["text", "#cdata-section"].include?(name.to_s)
337
+ content_mapping
338
+ else
339
+ mappings.detect do |rule|
340
+ rule.name == name.to_s || rule.name == name.to_sym
341
+ end
342
+ end
343
+ end
344
+
345
+ def mapping_attributes_hash
346
+ @attributes
347
+ end
348
+
349
+ def mapping_elements_hash
350
+ @elements
351
+ end
352
+
353
+ def merge_mapping_attributes(mapping)
354
+ mapping_attributes_hash.merge!(mapping.mapping_attributes_hash)
355
+ end
356
+
357
+ def merge_mapping_elements(mapping)
358
+ mapping_elements_hash.merge!(mapping.mapping_elements_hash)
359
+ end
360
+
361
+ def merge_elements_sequence(mapping)
362
+ mapping.element_sequence.each do |sequence|
363
+ element_sequence << Lutaml::Model::Sequence.new(self).tap do |instance|
364
+ sequence.attributes.each do |attr|
365
+ instance.attributes << attr.deep_dup
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ def deep_dup
372
+ self.class.new.tap do |xml_mapping|
373
+ xml_mapping.root(@root_element.dup, mixed: @mixed_content,
374
+ ordered: @ordered)
375
+ xml_mapping.namespace(@namespace_uri.dup, @namespace_prefix.dup)
376
+
377
+ attributes_to_dup.each do |var_name|
378
+ value = instance_variable_get(var_name)
379
+ xml_mapping.instance_variable_set(var_name, Utils.deep_dup(value))
380
+ end
381
+ end
382
+ end
383
+
384
+ def polymorphic_mapping
385
+ mappings.find(&:polymorphic_mapping?)
386
+ end
387
+
388
+ def attributes_to_dup
389
+ @attributes_to_dup ||= %i[
390
+ @content_mapping
391
+ @raw_mapping
392
+ @element_sequence
393
+ @attributes
394
+ @elements
395
+ ]
396
+ end
397
+
398
+ def dup_mappings(mappings)
399
+ new_mappings = {}
400
+
401
+ mappings.each do |key, mapping_rule|
402
+ new_mappings[key] = mapping_rule.deep_dup
403
+ end
404
+
405
+ new_mappings
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end
@@ -0,0 +1,141 @@
1
+ require_relative "../mapping/mapping_rule"
2
+
3
+ module Lutaml
4
+ module Model
5
+ module Xml
6
+ class MappingRule < MappingRule
7
+ attr_reader :namespace, :prefix, :mixed_content, :default_namespace, :cdata
8
+
9
+ def initialize(
10
+ name,
11
+ to:,
12
+ render_nil: false,
13
+ render_default: false,
14
+ render_empty: false,
15
+ treat_nil: nil,
16
+ treat_empty: nil,
17
+ treat_omitted: nil,
18
+ with: {},
19
+ delegate: nil,
20
+ namespace: nil,
21
+ prefix: nil,
22
+ mixed_content: false,
23
+ cdata: false,
24
+ namespace_set: false,
25
+ prefix_set: false,
26
+ attribute: false,
27
+ default_namespace: nil,
28
+ polymorphic: {},
29
+ polymorphic_map: {},
30
+ transform: {},
31
+ value_map: {}
32
+ )
33
+ super(
34
+ name,
35
+ to: to,
36
+ render_nil: render_nil,
37
+ render_default: render_default,
38
+ render_empty: render_empty,
39
+ treat_nil: treat_nil,
40
+ treat_empty: treat_empty,
41
+ treat_omitted: treat_omitted,
42
+ with: with,
43
+ delegate: delegate,
44
+ attribute: attribute,
45
+ polymorphic: polymorphic,
46
+ polymorphic_map: polymorphic_map,
47
+ transform: transform,
48
+ value_map: value_map,
49
+ )
50
+
51
+ @namespace = if namespace.to_s == "inherit"
52
+ # we are using inherit_namespace in xml builder by
53
+ # default so no need to do anything here.
54
+ else
55
+ namespace
56
+ end
57
+ @prefix = prefix
58
+ @mixed_content = mixed_content
59
+ @cdata = cdata
60
+
61
+ @default_namespace = default_namespace
62
+
63
+ @namespace_set = namespace_set
64
+ @prefix_set = prefix_set
65
+ end
66
+
67
+ def namespace_set?
68
+ !!@namespace_set
69
+ end
70
+
71
+ def prefix_set?
72
+ !!@prefix_set
73
+ end
74
+
75
+ def content_mapping?
76
+ name.nil?
77
+ end
78
+
79
+ def content_key
80
+ cdata ? "#cdata-section" : "text"
81
+ end
82
+
83
+ def mixed_content?
84
+ !!@mixed_content
85
+ end
86
+
87
+ def prefixed_name
88
+ rule_name = multiple_mappings? ? name.first : name
89
+ if prefix
90
+ "#{prefix}:#{rule_name}"
91
+ else
92
+ rule_name
93
+ end
94
+ end
95
+
96
+ def namespaced_names(parent_namespace = nil)
97
+ if multiple_mappings?
98
+ name.map { |rule_name| namespaced_name(parent_namespace, rule_name) }
99
+ else
100
+ [namespaced_name(parent_namespace)]
101
+ end
102
+ end
103
+
104
+ def namespaced_name(parent_namespace = nil, name = self.name)
105
+ if name.to_s == "lang"
106
+ "#{prefix}:#{name}"
107
+ elsif namespace_set? || @attribute
108
+ [namespace, name].compact.join(":")
109
+ elsif default_namespace
110
+ "#{default_namespace}:#{name}"
111
+ else
112
+ [parent_namespace, name].compact.join(":")
113
+ end
114
+ end
115
+
116
+ def deep_dup
117
+ self.class.new(
118
+ name.dup,
119
+ to: to,
120
+ render_nil: render_nil,
121
+ render_default: render_default,
122
+ with: Utils.deep_dup(custom_methods),
123
+ delegate: delegate,
124
+ namespace: namespace.dup,
125
+ prefix: prefix.dup,
126
+ mixed_content: mixed_content,
127
+ cdata: cdata,
128
+ namespace_set: namespace_set?,
129
+ prefix_set: prefix_set?,
130
+ attribute: attribute,
131
+ polymorphic: polymorphic.dup,
132
+ default_namespace: default_namespace.dup,
133
+ transform: transform.dup,
134
+ render_empty: render_empty.dup,
135
+ value_map: Utils.deep_dup(@value_map),
136
+ )
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end