lutaml-model 0.3.9 → 0.3.11
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/.rubocop_todo.yml +43 -25
- data/Gemfile +1 -0
- data/LICENSE.md +33 -0
- data/README.adoc +384 -18
- data/lib/lutaml/model/attribute.rb +130 -5
- data/lib/lutaml/model/error/collection_count_out_of_range_error.rb +29 -0
- data/lib/lutaml/model/error/incorrect_mapping_argument_error.rb +6 -0
- data/lib/lutaml/model/error/type_not_enabled_error.rb +9 -0
- data/lib/lutaml/model/error/validation_error.rb +21 -0
- data/lib/lutaml/model/error.rb +4 -0
- data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +1 -2
- data/lib/lutaml/model/key_value_mapping.rb +15 -1
- data/lib/lutaml/model/mapping_hash.rb +14 -0
- data/lib/lutaml/model/mapping_rule.rb +30 -6
- data/lib/lutaml/model/schema_location.rb +59 -0
- data/lib/lutaml/model/serialize.rb +135 -86
- data/lib/lutaml/model/type.rb +8 -0
- data/lib/lutaml/model/utils.rb +16 -0
- data/lib/lutaml/model/validation.rb +24 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +12 -2
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +4 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +2 -1
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +1 -0
- data/lib/lutaml/model/xml_adapter/xml_document.rb +60 -30
- data/lib/lutaml/model/xml_adapter/xml_namespace.rb +1 -1
- data/lib/lutaml/model/xml_mapping.rb +27 -5
- data/lib/lutaml/model/xml_mapping_rule.rb +3 -1
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +10 -5
- data/lutaml-model.gemspec +1 -1
- metadata +11 -17
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Validation
|
4
|
+
def validate
|
5
|
+
errors = []
|
6
|
+
self.class.attributes.each do |name, attr|
|
7
|
+
value = instance_variable_get(:"@#{name}")
|
8
|
+
begin
|
9
|
+
attr.validate_value!(value)
|
10
|
+
rescue Lutaml::Model::InvalidValueError,
|
11
|
+
Lutaml::Model::CollectionCountOutOfRangeError => e
|
12
|
+
errors << e
|
13
|
+
end
|
14
|
+
end
|
15
|
+
errors
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate!
|
19
|
+
errors = validate
|
20
|
+
raise Lutaml::Model::ValidationError.new(errors) if errors.any?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -27,11 +27,21 @@ module Lutaml
|
|
27
27
|
element.add_child(child)
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
|
30
|
+
def add_attribute(element, name, value)
|
31
|
+
element[name] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_and_add_element(
|
35
|
+
element_name,
|
36
|
+
prefix: (prefix_unset = true
|
37
|
+
nil),
|
38
|
+
attributes: {}
|
39
|
+
)
|
40
|
+
add_namespace_prefix(prefix)
|
32
41
|
|
33
42
|
if block_given?
|
34
43
|
public_send(element_name, attributes) do
|
44
|
+
xml.parent.namespace = nil if prefix.nil? && !prefix_unset
|
35
45
|
yield(self)
|
36
46
|
end
|
37
47
|
else
|
@@ -68,7 +68,7 @@ module Lutaml
|
|
68
68
|
value = attribute_value_for(element, element_rule)
|
69
69
|
|
70
70
|
if element_rule == xml_mapping.content_mapping
|
71
|
-
text =
|
71
|
+
text = xml_mapping.content_mapping.serialize(element)
|
72
72
|
text = text[curr_index] if text.is_a?(Array)
|
73
73
|
|
74
74
|
prefixed_xml.text text
|
@@ -77,6 +77,7 @@ module Lutaml
|
|
77
77
|
|
78
78
|
add_to_xml(
|
79
79
|
xml,
|
80
|
+
element,
|
80
81
|
element_rule.prefix,
|
81
82
|
value,
|
82
83
|
options.merge(
|
@@ -77,16 +77,23 @@ module Lutaml
|
|
77
77
|
element.children.each_with_object(result) do |child, hash|
|
78
78
|
value = child.text? ? child.text : parse_element(child)
|
79
79
|
|
80
|
-
if hash[child.unprefixed_name]
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
80
|
+
hash[child.unprefixed_name] = if hash[child.unprefixed_name]
|
81
|
+
[hash[child.unprefixed_name], value].flatten
|
82
|
+
else
|
83
|
+
value
|
84
|
+
end
|
86
85
|
end
|
87
86
|
|
88
87
|
element.attributes.each_value do |attr|
|
89
|
-
|
88
|
+
if attr.unprefixed_name == "schemaLocation"
|
89
|
+
result["__schema_location"] = {
|
90
|
+
namespace: attr.namespace,
|
91
|
+
prefix: attr.namespace_prefix,
|
92
|
+
schema_location: attr.value,
|
93
|
+
}
|
94
|
+
else
|
95
|
+
result[attr.unprefixed_name] = attr.value
|
96
|
+
end
|
90
97
|
end
|
91
98
|
|
92
99
|
result
|
@@ -100,10 +107,10 @@ module Lutaml
|
|
100
107
|
end
|
101
108
|
end
|
102
109
|
|
103
|
-
def add_to_xml(xml, prefix, value, options = {})
|
110
|
+
def add_to_xml(xml, element, prefix, value, options = {})
|
104
111
|
if value.is_a?(Array)
|
105
112
|
value.each do |item|
|
106
|
-
add_to_xml(xml, prefix, item, options)
|
113
|
+
add_to_xml(xml, element, prefix, item, options)
|
107
114
|
end
|
108
115
|
|
109
116
|
return
|
@@ -113,7 +120,7 @@ module Lutaml
|
|
113
120
|
rule = options[:rule]
|
114
121
|
|
115
122
|
if rule.custom_methods[:to]
|
116
|
-
|
123
|
+
options[:mapper_class].new.send(rule.custom_methods[:to], element, xml.parent, xml)
|
117
124
|
return
|
118
125
|
end
|
119
126
|
|
@@ -123,21 +130,29 @@ module Lutaml
|
|
123
130
|
value,
|
124
131
|
options.merge({ rule: rule, attribute: attribute }),
|
125
132
|
)
|
126
|
-
|
133
|
+
elsif rule.prefix_set?
|
127
134
|
xml.create_and_add_element(rule.name, prefix: prefix) do
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
135
|
+
add_value(xml, value, attribute)
|
136
|
+
end
|
137
|
+
else
|
138
|
+
xml.create_and_add_element(rule.name) do
|
139
|
+
add_value(xml, value, attribute)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def add_value(xml, value, attribute)
|
145
|
+
if !value.nil?
|
146
|
+
serialized_value = attribute.type.serialize(value)
|
147
|
+
|
148
|
+
if attribute.type == Lutaml::Model::Type::Hash
|
149
|
+
serialized_value.each do |key, val|
|
150
|
+
xml.create_and_add_element(key) do |element|
|
151
|
+
element.text(val)
|
139
152
|
end
|
140
153
|
end
|
154
|
+
else
|
155
|
+
xml.add_text(xml, serialized_value)
|
141
156
|
end
|
142
157
|
end
|
143
158
|
end
|
@@ -150,6 +165,9 @@ module Lutaml
|
|
150
165
|
attributes = options[:xml_attributes] ||= {}
|
151
166
|
attributes = build_attributes(element,
|
152
167
|
xml_mapping, options).merge(attributes)&.compact
|
168
|
+
if element.respond_to?(:schema_location) && element.schema_location
|
169
|
+
attributes.merge!(element.schema_location.to_xml_attributes)
|
170
|
+
end
|
153
171
|
|
154
172
|
prefix = if options.key?(:namespace_prefix)
|
155
173
|
options[:namespace_prefix]
|
@@ -166,21 +184,28 @@ module Lutaml
|
|
166
184
|
prefixed_xml.add_namespace_prefix(nil)
|
167
185
|
end
|
168
186
|
|
187
|
+
xml_mapping.attributes.each do |attribute_rule|
|
188
|
+
attribute_rule.serialize_attribute(element, prefixed_xml.parent, xml)
|
189
|
+
end
|
190
|
+
|
169
191
|
xml_mapping.elements.each do |element_rule|
|
170
192
|
attribute_def = attribute_definition_for(element, element_rule,
|
171
193
|
mapper_class: mapper_class)
|
172
194
|
|
173
|
-
|
195
|
+
if attribute_def
|
196
|
+
value = attribute_value_for(element, element_rule)
|
174
197
|
|
175
|
-
|
198
|
+
next if value.nil? && !element_rule.render_nil?
|
176
199
|
|
177
|
-
|
200
|
+
value = [value] if attribute_def.collection? && !value.is_a?(Array)
|
201
|
+
end
|
178
202
|
|
179
203
|
add_to_xml(
|
180
204
|
prefixed_xml,
|
205
|
+
element,
|
181
206
|
element_rule.prefix,
|
182
207
|
value,
|
183
|
-
options.merge({ attribute: attribute_def, rule: element_rule }),
|
208
|
+
options.merge({ attribute: attribute_def, rule: element_rule, mapper_class: mapper_class }),
|
184
209
|
)
|
185
210
|
end
|
186
211
|
|
@@ -189,7 +214,7 @@ module Lutaml
|
|
189
214
|
@root.send(content_rule.custom_methods[:to], element,
|
190
215
|
prefixed_xml.parent, prefixed_xml)
|
191
216
|
else
|
192
|
-
text =
|
217
|
+
text = content_rule.serialize(element)
|
193
218
|
text = text.join if text.is_a?(Array)
|
194
219
|
prefixed_xml.add_text(xml, text)
|
195
220
|
end
|
@@ -213,8 +238,10 @@ module Lutaml
|
|
213
238
|
attrs = {}
|
214
239
|
|
215
240
|
if xml_mappings.namespace_uri
|
216
|
-
prefixed_name = [
|
217
|
-
|
241
|
+
prefixed_name = [
|
242
|
+
"xmlns",
|
243
|
+
xml_mappings.namespace_prefix,
|
244
|
+
].compact.join(":")
|
218
245
|
|
219
246
|
attrs[prefixed_name] = xml_mappings.namespace_uri
|
220
247
|
end
|
@@ -229,9 +256,11 @@ module Lutaml
|
|
229
256
|
type = if mapping_rule.delegate
|
230
257
|
attributes[mapping_rule.delegate].type.attributes[mapping_rule.to].type
|
231
258
|
else
|
232
|
-
attributes[mapping_rule.to]
|
259
|
+
attributes[mapping_rule.to]&.type
|
233
260
|
end
|
234
261
|
|
262
|
+
next unless type
|
263
|
+
|
235
264
|
if type <= Lutaml::Model::Serialize
|
236
265
|
attrs = attrs.merge(build_namespace_attributes(type, processed))
|
237
266
|
end
|
@@ -249,6 +278,7 @@ module Lutaml
|
|
249
278
|
|
250
279
|
xml_mapping.attributes.each_with_object(attrs) do |mapping_rule, hash|
|
251
280
|
next if options[:except]&.include?(mapping_rule.to)
|
281
|
+
next if mapping_rule.custom_methods[:to]
|
252
282
|
|
253
283
|
if mapping_rule.namespace
|
254
284
|
hash["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
@@ -38,14 +38,17 @@ module Lutaml
|
|
38
38
|
# rubocop:disable Metrics/ParameterLists
|
39
39
|
def map_element(
|
40
40
|
name,
|
41
|
-
to
|
41
|
+
to: nil,
|
42
42
|
render_nil: false,
|
43
43
|
with: {},
|
44
44
|
delegate: nil,
|
45
45
|
namespace: (namespace_set = false
|
46
46
|
nil),
|
47
|
-
prefix:
|
47
|
+
prefix: (prefix_set = false
|
48
|
+
nil)
|
48
49
|
)
|
50
|
+
validate!(name, to, with)
|
51
|
+
|
49
52
|
@elements[name] = XmlMappingRule.new(
|
50
53
|
name,
|
51
54
|
to: to,
|
@@ -55,19 +58,23 @@ module Lutaml
|
|
55
58
|
namespace: namespace,
|
56
59
|
prefix: prefix,
|
57
60
|
namespace_set: namespace_set != false,
|
61
|
+
prefix_set: prefix_set != false,
|
58
62
|
)
|
59
63
|
end
|
60
64
|
|
61
65
|
def map_attribute(
|
62
66
|
name,
|
63
|
-
to
|
67
|
+
to: nil,
|
64
68
|
render_nil: false,
|
65
69
|
with: {},
|
66
70
|
delegate: nil,
|
67
71
|
namespace: (namespace_set = false
|
68
72
|
nil),
|
69
|
-
prefix:
|
73
|
+
prefix: (prefix_set = false
|
74
|
+
nil)
|
70
75
|
)
|
76
|
+
validate!(name, to, with)
|
77
|
+
|
71
78
|
@attributes[name] = XmlMappingRule.new(
|
72
79
|
name,
|
73
80
|
to: to,
|
@@ -77,18 +84,21 @@ module Lutaml
|
|
77
84
|
namespace: namespace,
|
78
85
|
prefix: prefix,
|
79
86
|
namespace_set: namespace_set != false,
|
87
|
+
prefix_set: prefix_set != false,
|
80
88
|
)
|
81
89
|
end
|
82
90
|
|
83
91
|
# rubocop:enable Metrics/ParameterLists
|
84
92
|
|
85
93
|
def map_content(
|
86
|
-
to
|
94
|
+
to: nil,
|
87
95
|
render_nil: false,
|
88
96
|
with: {},
|
89
97
|
delegate: nil,
|
90
98
|
mixed: false
|
91
99
|
)
|
100
|
+
validate!("content", to, with)
|
101
|
+
|
92
102
|
@content_mapping = XmlMappingRule.new(
|
93
103
|
nil,
|
94
104
|
to: to,
|
@@ -99,6 +109,18 @@ module Lutaml
|
|
99
109
|
)
|
100
110
|
end
|
101
111
|
|
112
|
+
def validate!(key, to, with)
|
113
|
+
if to.nil? && with.empty?
|
114
|
+
msg = ":to or :with argument is required for mapping '#{key}'"
|
115
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
116
|
+
end
|
117
|
+
|
118
|
+
if !with.empty? && (with[:from].nil? || with[:to].nil?)
|
119
|
+
msg = ":with argument for mapping '#{key}' requires :to and :from keys"
|
120
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
102
124
|
def elements
|
103
125
|
@elements.values
|
104
126
|
end
|
@@ -14,7 +14,8 @@ module Lutaml
|
|
14
14
|
namespace: nil,
|
15
15
|
prefix: nil,
|
16
16
|
mixed_content: false,
|
17
|
-
namespace_set: false
|
17
|
+
namespace_set: false,
|
18
|
+
prefix_set: false
|
18
19
|
)
|
19
20
|
super(
|
20
21
|
name,
|
@@ -24,6 +25,7 @@ module Lutaml
|
|
24
25
|
delegate: delegate,
|
25
26
|
mixed_content: mixed_content,
|
26
27
|
namespace_set: namespace_set,
|
28
|
+
prefix_set: prefix_set,
|
27
29
|
)
|
28
30
|
|
29
31
|
@namespace = if namespace.to_s == "inherit"
|
@@ -5,12 +5,17 @@ module Lutaml
|
|
5
5
|
module Model
|
6
6
|
module YamlAdapter
|
7
7
|
class StandardYamlAdapter < YamlDocument
|
8
|
+
PERMITTED_CLASSES_BASE = [Date, Time, DateTime, Symbol, Hash,
|
9
|
+
Array].freeze
|
10
|
+
|
11
|
+
PERMITTED_CLASSES = if defined?(BigDecimal)
|
12
|
+
PERMITTED_CLASSES_BASE + [BigDecimal]
|
13
|
+
else
|
14
|
+
PERMITTED_CLASSES_BASE
|
15
|
+
end.freeze
|
16
|
+
|
8
17
|
def self.parse(yaml)
|
9
|
-
YAML.safe_load(
|
10
|
-
yaml,
|
11
|
-
permitted_classes: [Date, Time, DateTime, Symbol,
|
12
|
-
BigDecimal, Hash, Array],
|
13
|
-
)
|
18
|
+
YAML.safe_load(yaml, permitted_classes: PERMITTED_CLASSES)
|
14
19
|
end
|
15
20
|
|
16
21
|
def to_yaml(options = {})
|
data/lutaml-model.gemspec
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bigdecimal
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: thor
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,6 +42,7 @@ files:
|
|
56
42
|
- ".rubocop_todo.yml"
|
57
43
|
- CODE_OF_CONDUCT.md
|
58
44
|
- Gemfile
|
45
|
+
- LICENSE.md
|
59
46
|
- README.adoc
|
60
47
|
- Rakefile
|
61
48
|
- bin/console
|
@@ -69,8 +56,12 @@ files:
|
|
69
56
|
- lib/lutaml/model/comparison.rb
|
70
57
|
- lib/lutaml/model/config.rb
|
71
58
|
- lib/lutaml/model/error.rb
|
59
|
+
- lib/lutaml/model/error/collection_count_out_of_range_error.rb
|
60
|
+
- lib/lutaml/model/error/incorrect_mapping_argument_error.rb
|
72
61
|
- lib/lutaml/model/error/invalid_value_error.rb
|
62
|
+
- lib/lutaml/model/error/type_not_enabled_error.rb
|
73
63
|
- lib/lutaml/model/error/unknown_adapter_type_error.rb
|
64
|
+
- lib/lutaml/model/error/validation_error.rb
|
74
65
|
- lib/lutaml/model/json_adapter.rb
|
75
66
|
- lib/lutaml/model/json_adapter/json_document.rb
|
76
67
|
- lib/lutaml/model/json_adapter/json_object.rb
|
@@ -86,6 +77,7 @@ files:
|
|
86
77
|
- lib/lutaml/model/schema/relaxng_schema.rb
|
87
78
|
- lib/lutaml/model/schema/xsd_schema.rb
|
88
79
|
- lib/lutaml/model/schema/yaml_schema.rb
|
80
|
+
- lib/lutaml/model/schema_location.rb
|
89
81
|
- lib/lutaml/model/serializable.rb
|
90
82
|
- lib/lutaml/model/serialize.rb
|
91
83
|
- lib/lutaml/model/toml_adapter.rb
|
@@ -97,6 +89,7 @@ files:
|
|
97
89
|
- lib/lutaml/model/type/date_time.rb
|
98
90
|
- lib/lutaml/model/type/time_without_date.rb
|
99
91
|
- lib/lutaml/model/utils.rb
|
92
|
+
- lib/lutaml/model/validation.rb
|
100
93
|
- lib/lutaml/model/version.rb
|
101
94
|
- lib/lutaml/model/xml_adapter.rb
|
102
95
|
- lib/lutaml/model/xml_adapter/builder/nokogiri.rb
|
@@ -119,7 +112,8 @@ files:
|
|
119
112
|
homepage: https://github.com/lutaml/lutaml-model
|
120
113
|
licenses:
|
121
114
|
- BSD-2-Clause
|
122
|
-
metadata:
|
115
|
+
metadata:
|
116
|
+
rubygems_mfa_required: 'true'
|
123
117
|
post_install_message:
|
124
118
|
rdoc_options: []
|
125
119
|
require_paths:
|