lutaml-model 0.7.2 → 0.7.5
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/.envrc +1 -0
- data/.github/workflows/release.yml +3 -0
- data/.gitignore +6 -1
- data/.irbrc +1 -0
- data/.pryrc +1 -0
- data/.rubocop_todo.yml +25 -52
- data/README.adoc +2177 -192
- data/docs/custom_registers.adoc +228 -0
- data/docs/schema_generation.adoc +898 -0
- data/docs/schema_import.adoc +364 -0
- data/flake.lock +114 -0
- data/flake.nix +103 -0
- data/lib/lutaml/model/attribute.rb +230 -94
- data/lib/lutaml/model/choice.rb +30 -0
- data/lib/lutaml/model/collection.rb +194 -0
- data/lib/lutaml/model/comparable_model.rb +3 -3
- data/lib/lutaml/model/config.rb +26 -3
- data/lib/lutaml/model/constants.rb +2 -0
- data/lib/lutaml/model/error/element_count_out_of_range_error.rb +29 -0
- data/lib/lutaml/model/error/invalid_attribute_name_error.rb +15 -0
- data/lib/lutaml/model/error/invalid_attribute_options_error.rb +16 -0
- data/lib/lutaml/model/error/invalid_choice_range_error.rb +3 -5
- data/lib/lutaml/model/error/register/not_registrable_class_error.rb +11 -0
- data/lib/lutaml/model/error/type/invalid_value_error.rb +5 -3
- data/lib/lutaml/model/error/type/max_bound_error.rb +20 -0
- data/lib/lutaml/model/error/type/max_length_error.rb +20 -0
- data/lib/lutaml/model/error/type/min_bound_error.rb +20 -0
- data/lib/lutaml/model/error/type/min_length_error.rb +20 -0
- data/lib/lutaml/model/error/type/pattern_not_matched_error.rb +18 -0
- data/lib/lutaml/model/error/validation_failed_error.rb +9 -0
- data/lib/lutaml/model/error.rb +10 -0
- data/lib/lutaml/model/errors.rb +36 -0
- data/lib/lutaml/model/format_registry.rb +5 -2
- data/lib/lutaml/model/global_register.rb +41 -0
- data/lib/lutaml/model/{hash.rb → hash_adapter.rb} +5 -5
- data/lib/lutaml/model/jsonl/document.rb +14 -0
- data/lib/lutaml/model/jsonl/mapping.rb +19 -0
- data/lib/lutaml/model/jsonl/mapping_rule.rb +9 -0
- data/lib/lutaml/model/jsonl/standard_adapter.rb +33 -0
- data/lib/lutaml/model/jsonl/transform.rb +19 -0
- data/lib/lutaml/model/jsonl.rb +21 -0
- data/lib/lutaml/model/key_value_document.rb +3 -2
- data/lib/lutaml/model/mapping/key_value_mapping.rb +64 -4
- data/lib/lutaml/model/mapping/key_value_mapping_rule.rb +4 -0
- data/lib/lutaml/model/mapping/mapping_rule.rb +8 -3
- data/lib/lutaml/model/register.rb +105 -0
- data/lib/lutaml/model/registrable.rb +6 -0
- data/lib/lutaml/model/schema/base_schema.rb +64 -0
- data/lib/lutaml/model/schema/decorators/attribute.rb +114 -0
- data/lib/lutaml/model/schema/decorators/choices.rb +31 -0
- data/lib/lutaml/model/schema/decorators/class_definition.rb +85 -0
- data/lib/lutaml/model/schema/decorators/definition_collection.rb +97 -0
- data/lib/lutaml/model/schema/generator/definition.rb +53 -0
- data/lib/lutaml/model/schema/generator/definitions_collection.rb +81 -0
- data/lib/lutaml/model/schema/generator/properties_collection.rb +63 -0
- data/lib/lutaml/model/schema/generator/property.rb +110 -0
- data/lib/lutaml/model/schema/generator/ref.rb +24 -0
- data/lib/lutaml/model/schema/helpers/template_helper.rb +49 -0
- data/lib/lutaml/model/schema/json_schema.rb +42 -49
- data/lib/lutaml/model/schema/relaxng_schema.rb +14 -10
- data/lib/lutaml/model/schema/renderer.rb +36 -0
- data/lib/lutaml/model/schema/shared_methods.rb +24 -0
- data/lib/lutaml/model/schema/templates/model.erb +9 -0
- data/lib/lutaml/model/schema/xml_compiler/attribute.rb +85 -0
- data/lib/lutaml/model/schema/xml_compiler/attribute_group.rb +45 -0
- data/lib/lutaml/model/schema/xml_compiler/choice.rb +65 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_content.rb +27 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_content_restriction.rb +34 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_type.rb +136 -0
- data/lib/lutaml/model/schema/xml_compiler/element.rb +104 -0
- data/lib/lutaml/model/schema/xml_compiler/group.rb +97 -0
- data/lib/lutaml/model/schema/xml_compiler/restriction.rb +101 -0
- data/lib/lutaml/model/schema/xml_compiler/sequence.rb +50 -0
- data/lib/lutaml/model/schema/xml_compiler/simple_content.rb +36 -0
- data/lib/lutaml/model/schema/xml_compiler/simple_type.rb +189 -0
- data/lib/lutaml/model/schema/xml_compiler.rb +231 -587
- data/lib/lutaml/model/schema/xsd_schema.rb +12 -8
- data/lib/lutaml/model/schema/yaml_schema.rb +41 -35
- data/lib/lutaml/model/schema.rb +1 -0
- data/lib/lutaml/model/sequence.rb +60 -30
- data/lib/lutaml/model/serialize.rb +175 -53
- data/lib/lutaml/model/services/base.rb +11 -0
- data/lib/lutaml/model/services/logger.rb +2 -2
- data/lib/lutaml/model/services/rule_value_extractor.rb +92 -0
- data/lib/lutaml/model/services/type/validator/number.rb +25 -0
- data/lib/lutaml/model/services/type/validator/string.rb +52 -0
- data/lib/lutaml/model/services/type/validator.rb +43 -0
- data/lib/lutaml/model/services/validator.rb +145 -0
- data/lib/lutaml/model/services.rb +3 -0
- data/lib/lutaml/model/transform/key_value_transform.rb +60 -50
- data/lib/lutaml/model/transform/xml_transform.rb +46 -57
- data/lib/lutaml/model/transform.rb +22 -8
- data/lib/lutaml/model/type/boolean.rb +1 -1
- data/lib/lutaml/model/type/date.rb +1 -1
- data/lib/lutaml/model/type/date_time.rb +1 -1
- data/lib/lutaml/model/type/decimal.rb +11 -9
- data/lib/lutaml/model/type/float.rb +2 -1
- data/lib/lutaml/model/type/integer.rb +24 -21
- data/lib/lutaml/model/type/string.rb +4 -2
- data/lib/lutaml/model/type/time.rb +1 -1
- data/lib/lutaml/model/type/time_without_date.rb +1 -1
- data/lib/lutaml/model/type/value.rb +5 -1
- data/lib/lutaml/model/type.rb +5 -2
- data/lib/lutaml/model/utils.rb +30 -8
- data/lib/lutaml/model/validation.rb +6 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml/document.rb +37 -19
- data/lib/lutaml/model/xml/mapping.rb +74 -13
- data/lib/lutaml/model/xml/mapping_rule.rb +10 -2
- data/lib/lutaml/model/xml/nokogiri_adapter.rb +5 -3
- data/lib/lutaml/model/xml/oga/element.rb +4 -1
- data/lib/lutaml/model/xml/oga_adapter.rb +4 -3
- data/lib/lutaml/model/xml/ox_adapter.rb +20 -6
- data/lib/lutaml/model/xml/xml_element.rb +3 -28
- data/lib/lutaml/model/xml.rb +1 -1
- data/lib/lutaml/model/xml_adapter/element.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +1 -1
- data/lib/lutaml/model/yamls/document.rb +14 -0
- data/lib/lutaml/model/yamls/mapping.rb +19 -0
- data/lib/lutaml/model/yamls/mapping_rule.rb +9 -0
- data/lib/lutaml/model/yamls/standard_adapter.rb +34 -0
- data/lib/lutaml/model/yamls/transform.rb +19 -0
- data/lib/lutaml/model/yamls.rb +21 -0
- data/lib/lutaml/model.rb +7 -31
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +4 -5
- data/spec/fixtures/xml/advanced_test_schema.xsd +134 -0
- data/spec/fixtures/xml/examples/nested_categories.xml +55 -0
- data/spec/fixtures/xml/examples/valid_catalog.xml +43 -0
- data/spec/fixtures/xml/product_catalog.xsd +151 -0
- data/spec/fixtures/xml/specifications_schema.xsd +38 -0
- data/spec/lutaml/model/attribute_collection_spec.rb +101 -0
- data/spec/lutaml/model/attribute_spec.rb +41 -44
- data/spec/lutaml/model/choice_spec.rb +44 -0
- data/spec/lutaml/model/custom_collection_spec.rb +830 -0
- data/spec/lutaml/model/custom_model_spec.rb +15 -3
- data/spec/lutaml/model/custom_vobject_adapter_spec.rb +6 -6
- data/spec/lutaml/model/defaults_spec.rb +5 -1
- data/spec/lutaml/model/global_register_spec.rb +108 -0
- data/spec/lutaml/model/group_spec.rb +9 -3
- data/spec/lutaml/model/jsonl/standard_adapter_spec.rb +91 -0
- data/spec/lutaml/model/jsonl_spec.rb +229 -0
- data/spec/lutaml/model/multiple_mapping_spec.rb +1 -1
- data/spec/lutaml/model/register/key_value_spec.rb +275 -0
- data/spec/lutaml/model/register/xml_spec.rb +187 -0
- data/spec/lutaml/model/register_spec.rb +147 -0
- data/spec/lutaml/model/rule_value_extractor_spec.rb +162 -0
- data/spec/lutaml/model/schema/generator/definitions_collection_spec.rb +120 -0
- data/spec/lutaml/model/schema/json_schema_spec.rb +412 -51
- data/spec/lutaml/model/schema/json_schema_to_models_spec.rb +383 -0
- data/spec/lutaml/model/schema/xml_compiler/attribute_group_spec.rb +65 -0
- data/spec/lutaml/model/schema/xml_compiler/attribute_spec.rb +63 -0
- data/spec/lutaml/model/schema/xml_compiler/choice_spec.rb +71 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_content_restriction_spec.rb +55 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_content_spec.rb +37 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_type_spec.rb +173 -0
- data/spec/lutaml/model/schema/xml_compiler/element_spec.rb +63 -0
- data/spec/lutaml/model/schema/xml_compiler/group_spec.rb +86 -0
- data/spec/lutaml/model/schema/xml_compiler/restriction_spec.rb +76 -0
- data/spec/lutaml/model/schema/xml_compiler/sequence_spec.rb +59 -0
- data/spec/lutaml/model/schema/xml_compiler/simple_content_spec.rb +55 -0
- data/spec/lutaml/model/schema/xml_compiler/simple_type_spec.rb +181 -0
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +503 -1804
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +249 -26
- data/spec/lutaml/model/sequence_spec.rb +36 -0
- data/spec/lutaml/model/serializable_spec.rb +31 -0
- data/spec/lutaml/model/type_spec.rb +8 -4
- data/spec/lutaml/model/utils_spec.rb +3 -3
- data/spec/lutaml/model/xml/derived_attributes_spec.rb +1 -1
- data/spec/lutaml/model/xml/xml_element_spec.rb +7 -1
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +6 -6
- data/spec/lutaml/model/xml_adapter_spec.rb +24 -0
- data/spec/lutaml/model/xml_mapping_rule_spec.rb +11 -4
- data/spec/lutaml/model/xml_mapping_spec.rb +1 -1
- data/spec/lutaml/model/xml_spec.rb +6 -6
- data/spec/lutaml/model/yamls/standard_adapter_spec.rb +183 -0
- data/spec/lutaml/model/yamls_spec.rb +294 -0
- data/spec/spec_helper.rb +1 -0
- metadata +105 -9
- data/lib/lutaml/model/schema/templates/simple_type.rb +0 -247
- /data/lib/lutaml/model/{hash → hash_adapter}/document.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/mapping.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/mapping_rule.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/standard_adapter.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/transform.rb +0 -0
@@ -8,11 +8,12 @@ module Lutaml
|
|
8
8
|
module Model
|
9
9
|
module Xml
|
10
10
|
class Document
|
11
|
-
attr_reader :root, :encoding
|
11
|
+
attr_reader :root, :encoding, :register
|
12
12
|
|
13
|
-
def initialize(root, encoding = nil)
|
13
|
+
def initialize(root, encoding = nil, register: nil)
|
14
14
|
@root = root
|
15
15
|
@encoding = encoding
|
16
|
+
@register = setup_register(register)
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.parse(xml, _options = {})
|
@@ -79,7 +80,7 @@ module Lutaml
|
|
79
80
|
options[:mixed_content] = rule.mixed_content
|
80
81
|
options[:tag_name] = rule.name
|
81
82
|
|
82
|
-
options[:mapper_class] = attribute&.type if attribute
|
83
|
+
options[:mapper_class] = attribute&.type(register) if attribute
|
83
84
|
options[:set_namespace] = set_namespace?(rule)
|
84
85
|
|
85
86
|
options
|
@@ -107,7 +108,7 @@ module Lutaml
|
|
107
108
|
result["elements"] ||= Lutaml::Model::MappingHash.new
|
108
109
|
result["elements"].assign_or_append_value(
|
109
110
|
self.class.namespaced_name_of(child),
|
110
|
-
parse_element(child, attr&.type || klass, format),
|
111
|
+
parse_element(child, attr&.type(register) || klass, format),
|
111
112
|
)
|
112
113
|
end
|
113
114
|
|
@@ -127,9 +128,9 @@ module Lutaml
|
|
127
128
|
prefix: attr.namespace_prefix,
|
128
129
|
schema_location: attr.value,
|
129
130
|
}
|
131
|
+
else
|
132
|
+
result[attr.namespaced_name] = attr.value
|
130
133
|
end
|
131
|
-
|
132
|
-
result[attr.namespaced_name] = attr.value
|
133
134
|
end
|
134
135
|
|
135
136
|
result
|
@@ -148,17 +149,16 @@ module Lutaml
|
|
148
149
|
rule = options[:rule]
|
149
150
|
|
150
151
|
if rule.custom_methods[:to]
|
151
|
-
options[:mapper_class].new.send(rule.custom_methods[:to], element,
|
152
|
-
xml.parent, xml)
|
152
|
+
options[:mapper_class].new.send(rule.custom_methods[:to], element, xml.parent, xml)
|
153
153
|
return
|
154
154
|
end
|
155
155
|
|
156
156
|
# Only transform when recursion is not called
|
157
|
-
if !attribute.collection? ||
|
157
|
+
if !attribute.collection? || attribute.collection_instance?(value)
|
158
158
|
value = ExportTransformer.call(value, rule, attribute)
|
159
159
|
end
|
160
160
|
|
161
|
-
if
|
161
|
+
if attribute.collection_instance?(value) && !Utils.empty_collection?(value)
|
162
162
|
value.each do |item|
|
163
163
|
add_to_xml(xml, element, prefix, item, options)
|
164
164
|
end
|
@@ -170,7 +170,7 @@ module Lutaml
|
|
170
170
|
|
171
171
|
value = rule.render_value_for(value)
|
172
172
|
|
173
|
-
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
173
|
+
if value && (attribute&.type(register)&.<= Lutaml::Model::Serialize)
|
174
174
|
handle_nested_elements(
|
175
175
|
xml,
|
176
176
|
value,
|
@@ -195,10 +195,10 @@ module Lutaml
|
|
195
195
|
|
196
196
|
def add_value(xml, value, attribute, cdata: false)
|
197
197
|
if !value.nil?
|
198
|
-
serialized_value = attribute.serialize(value, :xml)
|
198
|
+
serialized_value = attribute.serialize(value, :xml, register)
|
199
199
|
if attribute.raw?
|
200
200
|
xml.add_xml_fragment(xml, value)
|
201
|
-
elsif attribute.type == Lutaml::Model::Type::Hash
|
201
|
+
elsif attribute.type(register) == Lutaml::Model::Type::Hash
|
202
202
|
serialized_value.each do |key, val|
|
203
203
|
xml.create_and_add_element(key) do |element|
|
204
204
|
element.text(val)
|
@@ -242,7 +242,7 @@ module Lutaml
|
|
242
242
|
|
243
243
|
next if !element_rule.render?(value, element)
|
244
244
|
|
245
|
-
value =
|
245
|
+
value = attribute_def.build_collection(value) if attribute_def.collection? && !attribute_def.collection_instance?(value)
|
246
246
|
end
|
247
247
|
|
248
248
|
add_to_xml(
|
@@ -264,8 +264,12 @@ module Lutaml
|
|
264
264
|
return unless content_rule
|
265
265
|
|
266
266
|
if content_rule.custom_methods[:to]
|
267
|
-
mapper_class.new.send(
|
268
|
-
|
267
|
+
mapper_class.new.send(
|
268
|
+
content_rule.custom_methods[:to],
|
269
|
+
element,
|
270
|
+
xml.parent,
|
271
|
+
xml,
|
272
|
+
)
|
269
273
|
else
|
270
274
|
text = content_rule.serialize(element)
|
271
275
|
text = text.join if text.is_a?(Array)
|
@@ -320,9 +324,10 @@ module Lutaml
|
|
320
324
|
processed[klass][mapping_rule.name] = true
|
321
325
|
|
322
326
|
type = if mapping_rule.delegate
|
323
|
-
attributes[mapping_rule.delegate].type
|
327
|
+
attributes[mapping_rule.delegate].type(register)
|
328
|
+
.attributes[mapping_rule.to].type(register)
|
324
329
|
else
|
325
|
-
attributes[mapping_rule.to]&.type
|
330
|
+
attributes[mapping_rule.to]&.type(register)
|
326
331
|
end
|
327
332
|
|
328
333
|
next unless type
|
@@ -363,7 +368,7 @@ module Lutaml
|
|
363
368
|
|
364
369
|
value = mapping_rule.to_value_for(element)
|
365
370
|
attr = attribute_definition_for(element, mapping_rule, mapper_class: options[:mapper_class])
|
366
|
-
value = attr.serialize(value, :xml) if attr
|
371
|
+
value = attr.serialize(value, :xml, register) if attr
|
367
372
|
|
368
373
|
value = ExportTransformer.call(value, mapping_rule, attr)
|
369
374
|
|
@@ -433,6 +438,19 @@ module Lutaml
|
|
433
438
|
|
434
439
|
private
|
435
440
|
|
441
|
+
def setup_register(register)
|
442
|
+
return register if register.is_a?(Symbol)
|
443
|
+
|
444
|
+
return_register = if register.is_a?(Lutaml::Model::Register)
|
445
|
+
register.id
|
446
|
+
elsif @root.respond_to?(:register)
|
447
|
+
@root.register
|
448
|
+
elsif @root.instance_variable_defined?(:@register)
|
449
|
+
@root.instance_variable_get(:@register)
|
450
|
+
end
|
451
|
+
return_register || Lutaml::Model::Config.default_register
|
452
|
+
end
|
453
|
+
|
436
454
|
def determine_mapper_class(element, options)
|
437
455
|
if options[:mapper_class] && element.is_a?(options[:mapper_class])
|
438
456
|
element.class
|
@@ -17,7 +17,8 @@ module Lutaml
|
|
17
17
|
:namespace_prefix,
|
18
18
|
:mixed_content,
|
19
19
|
:ordered,
|
20
|
-
:element_sequence
|
20
|
+
:element_sequence,
|
21
|
+
:mappings_imported
|
21
22
|
|
22
23
|
def initialize
|
23
24
|
super
|
@@ -29,12 +30,19 @@ module Lutaml
|
|
29
30
|
@raw_mapping = nil
|
30
31
|
@mixed_content = false
|
31
32
|
@format = :xml
|
33
|
+
@mappings_imported = true
|
34
|
+
@finalized = false
|
32
35
|
end
|
33
36
|
|
34
37
|
def finalize(mapper_class)
|
35
38
|
if !root_element && !no_root?
|
36
39
|
root(mapper_class.model.to_s)
|
37
40
|
end
|
41
|
+
@finalized = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def finalized?
|
45
|
+
@finalized
|
38
46
|
end
|
39
47
|
|
40
48
|
alias mixed_content? mixed_content
|
@@ -73,6 +81,10 @@ module Lutaml
|
|
73
81
|
@namespace_prefix = prefix
|
74
82
|
end
|
75
83
|
|
84
|
+
def map_instances(to:)
|
85
|
+
map_element(to, to: to)
|
86
|
+
end
|
87
|
+
|
76
88
|
# rubocop:disable Metrics/ParameterLists
|
77
89
|
def map_element(
|
78
90
|
name,
|
@@ -244,12 +256,11 @@ module Lutaml
|
|
244
256
|
alias map_all_content map_all
|
245
257
|
|
246
258
|
def sequence(&block)
|
247
|
-
@element_sequence << Sequence.new(self).tap
|
248
|
-
s.instance_eval(&block)
|
249
|
-
end
|
259
|
+
@element_sequence << Sequence.new(self).tap { |s| s.instance_eval(&block) }
|
250
260
|
end
|
251
261
|
|
252
262
|
def import_model_mappings(model)
|
263
|
+
return import_mappings_later(model) if model_importable?(model)
|
253
264
|
raise Lutaml::Model::ImportModelWithRootError.new(model) if model.root?
|
254
265
|
|
255
266
|
mappings = model.mappings_for(:xml)
|
@@ -258,6 +269,10 @@ module Lutaml
|
|
258
269
|
(@element_sequence << mappings.element_sequence).flatten!
|
259
270
|
end
|
260
271
|
|
272
|
+
def set_mappings_imported(value)
|
273
|
+
@mappings_imported = value
|
274
|
+
end
|
275
|
+
|
261
276
|
def validate!(key, to, with, render_nil, render_empty, type: nil)
|
262
277
|
validate_raw_mappings!(type)
|
263
278
|
validate_to_and_with_arguments!(key, to, with)
|
@@ -316,24 +331,49 @@ module Lutaml
|
|
316
331
|
@raw_mapping
|
317
332
|
end
|
318
333
|
|
319
|
-
def mappings
|
334
|
+
def mappings(register_id = nil)
|
335
|
+
ensure_mappings_imported!(register_id) if finalized?
|
320
336
|
elements + attributes + [content_mapping, raw_mapping].compact
|
321
337
|
end
|
322
338
|
|
323
|
-
def
|
324
|
-
|
325
|
-
|
339
|
+
def ensure_mappings_imported!(register_id = nil)
|
340
|
+
return if @mappings_imported
|
341
|
+
|
342
|
+
importable_mappings.each do |model|
|
343
|
+
import_model_mappings(
|
344
|
+
register(register_id).get_class_without_register(model),
|
345
|
+
)
|
346
|
+
end
|
347
|
+
|
348
|
+
sequence_importable_mappings.each do |sequence, models|
|
349
|
+
models.each do |model|
|
350
|
+
sequence.import_model_mappings(
|
351
|
+
register(register_id).get_class_without_register(model),
|
352
|
+
)
|
353
|
+
end
|
326
354
|
end
|
355
|
+
|
356
|
+
@mappings_imported = true
|
357
|
+
end
|
358
|
+
|
359
|
+
def importable_mappings
|
360
|
+
@importable_mappings ||= []
|
361
|
+
end
|
362
|
+
|
363
|
+
def sequence_importable_mappings
|
364
|
+
@sequence_importable_mappings ||= Hash.new { |h, k| h[k] = [] }
|
365
|
+
end
|
366
|
+
|
367
|
+
def element(name)
|
368
|
+
elements.detect { |rule| name == rule.to }
|
327
369
|
end
|
328
370
|
|
329
371
|
def attribute(name)
|
330
|
-
attributes.detect
|
331
|
-
name == rule.to
|
332
|
-
end
|
372
|
+
attributes.detect { |rule| name == rule.to }
|
333
373
|
end
|
334
374
|
|
335
|
-
def find_by_name(name)
|
336
|
-
if ["text", "#cdata-section"].include?(name.to_s)
|
375
|
+
def find_by_name(name, type: "Text")
|
376
|
+
if ["text", "#cdata-section"].include?(name.to_s) && type == "Text"
|
337
377
|
content_mapping
|
338
378
|
else
|
339
379
|
mappings.detect do |rule|
|
@@ -342,6 +382,10 @@ module Lutaml
|
|
342
382
|
end
|
343
383
|
end
|
344
384
|
|
385
|
+
def find_by_to(to)
|
386
|
+
mappings.detect { |rule| rule.to.to_s == to.to_s }
|
387
|
+
end
|
388
|
+
|
345
389
|
def mapping_attributes_hash
|
346
390
|
@attributes
|
347
391
|
end
|
@@ -378,6 +422,7 @@ module Lutaml
|
|
378
422
|
value = instance_variable_get(var_name)
|
379
423
|
xml_mapping.instance_variable_set(var_name, Utils.deep_dup(value))
|
380
424
|
end
|
425
|
+
xml_mapping.instance_variable_set(:@finalized, true)
|
381
426
|
end
|
382
427
|
end
|
383
428
|
|
@@ -404,6 +449,22 @@ module Lutaml
|
|
404
449
|
|
405
450
|
new_mappings
|
406
451
|
end
|
452
|
+
|
453
|
+
private
|
454
|
+
|
455
|
+
def register(register_id = nil)
|
456
|
+
register_id ||= Lutaml::Model::Config.default_register
|
457
|
+
Lutaml::Model::GlobalRegister.lookup(register_id)
|
458
|
+
end
|
459
|
+
|
460
|
+
def model_importable?(model)
|
461
|
+
model.is_a?(Symbol) || model.is_a?(String)
|
462
|
+
end
|
463
|
+
|
464
|
+
def import_mappings_later(model)
|
465
|
+
importable_mappings << model.to_sym
|
466
|
+
@mappings_imported = false
|
467
|
+
end
|
407
468
|
end
|
408
469
|
end
|
409
470
|
end
|
@@ -4,7 +4,11 @@ module Lutaml
|
|
4
4
|
module Model
|
5
5
|
module Xml
|
6
6
|
class MappingRule < MappingRule
|
7
|
-
attr_reader :namespace,
|
7
|
+
attr_reader :namespace,
|
8
|
+
:prefix,
|
9
|
+
:mixed_content,
|
10
|
+
:default_namespace,
|
11
|
+
:cdata
|
8
12
|
|
9
13
|
def initialize(
|
10
14
|
name,
|
@@ -80,6 +84,10 @@ module Lutaml
|
|
80
84
|
cdata ? "#cdata-section" : "text"
|
81
85
|
end
|
82
86
|
|
87
|
+
def castable?
|
88
|
+
!raw_mapping? && !content_mapping? && !custom_methods[:from]
|
89
|
+
end
|
90
|
+
|
83
91
|
def mixed_content?
|
84
92
|
!!@mixed_content
|
85
93
|
end
|
@@ -103,7 +111,7 @@ module Lutaml
|
|
103
111
|
|
104
112
|
def namespaced_name(parent_namespace = nil, name = self.name)
|
105
113
|
if name.to_s == "lang"
|
106
|
-
"#{prefix}:#{name}"
|
114
|
+
Utils.blank?(prefix) ? name.to_s : "#{prefix}:#{name}"
|
107
115
|
elsif namespace_set? || @attribute
|
108
116
|
[namespace, name].compact.join(":")
|
109
117
|
elsif default_namespace
|
@@ -72,10 +72,11 @@ module Lutaml
|
|
72
72
|
content = []
|
73
73
|
|
74
74
|
element.element_order.each do |object|
|
75
|
-
|
76
|
-
|
75
|
+
object_key = "#{object.name}-#{object.type}"
|
76
|
+
index_hash[object_key] ||= -1
|
77
|
+
curr_index = index_hash[object_key] += 1
|
77
78
|
|
78
|
-
element_rule = xml_mapping.find_by_name(object.name)
|
79
|
+
element_rule = xml_mapping.find_by_name(object.name, type: object.type)
|
79
80
|
next if element_rule.nil?
|
80
81
|
|
81
82
|
attribute_def = attribute_definition_for(element, element_rule,
|
@@ -153,6 +154,7 @@ module Lutaml
|
|
153
154
|
parse_all_children(node, root_node: root_node || self,
|
154
155
|
default_namespace: default_namespace),
|
155
156
|
node.text,
|
157
|
+
name: node.name,
|
156
158
|
parent_document: root_node,
|
157
159
|
namespace_prefix: node.namespace&.prefix,
|
158
160
|
default_namespace: default_namespace
|
@@ -19,11 +19,14 @@ module Lutaml
|
|
19
19
|
when Moxml::Text
|
20
20
|
node.content
|
21
21
|
end
|
22
|
+
|
23
|
+
name = OgaAdapter.name_of(node)
|
22
24
|
super(
|
23
|
-
|
25
|
+
name,
|
24
26
|
Hash(attributes),
|
25
27
|
Array(children),
|
26
28
|
text,
|
29
|
+
name: name,
|
27
30
|
parent_document: parent,
|
28
31
|
namespace_prefix: namespace_name,
|
29
32
|
)
|
@@ -126,10 +126,11 @@ module Lutaml
|
|
126
126
|
content = []
|
127
127
|
|
128
128
|
element.element_order.each do |object|
|
129
|
-
|
130
|
-
|
129
|
+
object_key = "#{object.name}-#{object.type}"
|
130
|
+
index_hash[object_key] ||= -1
|
131
|
+
curr_index = index_hash[object_key] += 1
|
131
132
|
|
132
|
-
element_rule = xml_mapping.find_by_name(object.name)
|
133
|
+
element_rule = xml_mapping.find_by_name(object.name, type: object.type)
|
133
134
|
next if element_rule.nil?
|
134
135
|
|
135
136
|
attribute_def = attribute_definition_for(element, element_rule,
|
@@ -59,10 +59,11 @@ module Lutaml
|
|
59
59
|
content = []
|
60
60
|
|
61
61
|
element.element_order.each do |object|
|
62
|
-
|
63
|
-
|
62
|
+
object_key = "#{object.name}-#{object.type}"
|
63
|
+
index_hash[object_key] ||= -1
|
64
|
+
curr_index = index_hash[object_key] += 1
|
64
65
|
|
65
|
-
element_rule = xml_mapping.find_by_name(object.name)
|
66
|
+
element_rule = xml_mapping.find_by_name(object.name, type: object.type)
|
66
67
|
next if element_rule.nil?
|
67
68
|
|
68
69
|
attribute_def = attribute_definition_for(element, element_rule,
|
@@ -103,11 +104,11 @@ module Lutaml
|
|
103
104
|
def initialize(node, root_node: nil)
|
104
105
|
case node
|
105
106
|
when String
|
106
|
-
super("text", {}, [], node, parent_document: root_node)
|
107
|
+
super("text", {}, [], node, parent_document: root_node, name: "text")
|
107
108
|
when Ox::Comment
|
108
|
-
super("comment", {}, [], node.value, parent_document: root_node)
|
109
|
+
super("comment", {}, [], node.value, parent_document: root_node, name: "comment")
|
109
110
|
when Ox::CData
|
110
|
-
super("#cdata-section", {}, [], node.value, parent_document: root_node)
|
111
|
+
super("#cdata-section", {}, [], node.value, parent_document: root_node, name: "#cdata-section")
|
111
112
|
else
|
112
113
|
namespace_attributes(node.attributes).each do |(name, value)|
|
113
114
|
if root_node
|
@@ -135,16 +136,29 @@ module Lutaml
|
|
135
136
|
)
|
136
137
|
end
|
137
138
|
|
139
|
+
prefix, name = separate_name_and_prefix(node)
|
140
|
+
|
138
141
|
super(
|
139
142
|
node,
|
140
143
|
attributes,
|
141
144
|
parse_children(node, root_node: root_node || self),
|
142
145
|
node.text,
|
143
146
|
parent_document: root_node,
|
147
|
+
name: name,
|
148
|
+
namespace_prefix: prefix,
|
144
149
|
)
|
145
150
|
end
|
146
151
|
end
|
147
152
|
|
153
|
+
def separate_name_and_prefix(node)
|
154
|
+
name = node.name.to_s
|
155
|
+
|
156
|
+
return [nil, name] unless name.include?(":")
|
157
|
+
|
158
|
+
prefix, _, name = name.partition(":")
|
159
|
+
[prefix, name]
|
160
|
+
end
|
161
|
+
|
148
162
|
def to_xml
|
149
163
|
return text if text?
|
150
164
|
|
@@ -19,12 +19,13 @@ module Lutaml
|
|
19
19
|
attributes = {},
|
20
20
|
children = [],
|
21
21
|
text = nil,
|
22
|
+
name: nil,
|
22
23
|
parent_document: nil,
|
23
24
|
namespace_prefix: nil,
|
24
25
|
default_namespace: nil
|
25
26
|
)
|
26
|
-
@name =
|
27
|
-
@namespace_prefix = namespace_prefix
|
27
|
+
@name = name
|
28
|
+
@namespace_prefix = namespace_prefix
|
28
29
|
@attributes = attributes
|
29
30
|
@children = children
|
30
31
|
@text = text
|
@@ -92,32 +93,6 @@ module Lutaml
|
|
92
93
|
namespaces[nil] || @parent_document&.namespaces&.dig(nil)
|
93
94
|
end
|
94
95
|
|
95
|
-
def extract_name(node)
|
96
|
-
name = name_from_node(node)
|
97
|
-
|
98
|
-
n = name.split(":")
|
99
|
-
return name if n.length <= 1
|
100
|
-
|
101
|
-
n[1..].join(":")
|
102
|
-
end
|
103
|
-
|
104
|
-
def extract_namespace_prefix(node)
|
105
|
-
name = name_from_node(node)
|
106
|
-
|
107
|
-
n = name.to_s.split(":")
|
108
|
-
return if n.length <= 1
|
109
|
-
|
110
|
-
n.first
|
111
|
-
end
|
112
|
-
|
113
|
-
def name_from_node(node)
|
114
|
-
if node.is_a?(String)
|
115
|
-
node
|
116
|
-
else
|
117
|
-
node.name.to_s
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
96
|
def order
|
122
97
|
children.map do |child|
|
123
98
|
type = child.text? ? "Text" : "Element"
|
data/lib/lutaml/model/xml.rb
CHANGED
@@ -8,7 +8,7 @@ module Lutaml
|
|
8
8
|
module Model
|
9
9
|
module XmlAdapter
|
10
10
|
class Element < ::Lutaml::Model::Xml::Element
|
11
|
-
Logger.
|
11
|
+
Logger.warn_future_deprecation(
|
12
12
|
old: "Lutaml::Model::XmlAdapter::Element",
|
13
13
|
replacement: "Lutaml::Model::Xml::Element",
|
14
14
|
)
|
@@ -5,7 +5,7 @@ module Lutaml
|
|
5
5
|
module Model
|
6
6
|
module XmlAdapter
|
7
7
|
class NokogiriAdapter < ::Lutaml::Model::Xml::NokogiriAdapter
|
8
|
-
Logger.
|
8
|
+
Logger.warn_future_deprecation(
|
9
9
|
old: "Lutaml::Model::XmlAdapter::NokogiriAdapter",
|
10
10
|
replacement: "Lutaml::Model::Xml::NokogiriAdapter",
|
11
11
|
)
|
@@ -11,7 +11,7 @@ module Lutaml
|
|
11
11
|
module Model
|
12
12
|
module XmlAdapter
|
13
13
|
class OgaAdapter < ::Lutaml::Model::Xml::OgaAdapter
|
14
|
-
Logger.
|
14
|
+
Logger.warn_future_deprecation(
|
15
15
|
old: "Lutaml::Model::XmlAdapter::OgaAdapter",
|
16
16
|
replacement: "Lutaml::Model::Xml::OgaAdapter",
|
17
17
|
)
|
@@ -8,7 +8,7 @@ module Lutaml
|
|
8
8
|
module Model
|
9
9
|
module XmlAdapter
|
10
10
|
class OxAdapter < ::Lutaml::Model::Xml::OxAdapter
|
11
|
-
Logger.
|
11
|
+
Logger.warn_future_deprecation(
|
12
12
|
old: "Lutaml::Model::XmlAdapter::OxAdapter",
|
13
13
|
replacement: "Lutaml::Model::Xml::OxAdapter",
|
14
14
|
)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Yamls
|
6
|
+
class Document
|
7
|
+
def initialize(yamls = [], register: nil)
|
8
|
+
@yamls = yamls
|
9
|
+
@register = register || Lutaml::Model::Config.default_register
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../mapping/key_value_mapping"
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Yamls
|
6
|
+
class Mapping < Lutaml::Model::KeyValueMapping
|
7
|
+
def initialize
|
8
|
+
super(:yaml)
|
9
|
+
end
|
10
|
+
|
11
|
+
def deep_dup
|
12
|
+
self.class.new.tap do |new_mapping|
|
13
|
+
new_mapping.instance_variable_set(:@mappings, duplicate_mappings)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require_relative "document"
|
3
|
+
|
4
|
+
module Lutaml
|
5
|
+
module Model
|
6
|
+
module Yamls
|
7
|
+
class StandardAdapter < Document
|
8
|
+
FORMAT_SYMBOL = :yaml
|
9
|
+
|
10
|
+
def self.parse(yamls, _options = {})
|
11
|
+
results = []
|
12
|
+
|
13
|
+
yamls.split(/^---\n/).each do |yaml|
|
14
|
+
next if yaml.strip.empty?
|
15
|
+
|
16
|
+
begin
|
17
|
+
results << YAML.safe_load(yaml, aliases: true)
|
18
|
+
rescue Psych::SyntaxError => e
|
19
|
+
warn "Skipping invalid yaml: #{e.message}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
results
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_yamls(*_args)
|
27
|
+
@yamls.map do |yaml|
|
28
|
+
YAML.dump(yaml).strip
|
29
|
+
end.join("\n")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Yamls
|
4
|
+
class Transform < Lutaml::Model::KeyValueTransform
|
5
|
+
def data_to_model(data, format, options = {})
|
6
|
+
mappings = defined_mappings_for(:yamls) || mappings_for(:yaml)
|
7
|
+
|
8
|
+
super(data, format, options.merge(mappings: mappings))
|
9
|
+
end
|
10
|
+
|
11
|
+
def model_to_data(instance, format, options = {})
|
12
|
+
mappings = defined_mappings_for(:yamls) || mappings_for(:yaml)
|
13
|
+
|
14
|
+
super(instance, format, options.merge(mappings: mappings))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|