lutaml-model 0.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +58 -21
- data/Gemfile +1 -0
- data/README.adoc +1112 -264
- data/lib/lutaml/model/attribute.rb +33 -10
- data/lib/lutaml/model/choice.rb +56 -0
- data/lib/lutaml/model/config.rb +1 -0
- data/lib/lutaml/model/error/choice_lower_bound_error.rb +9 -0
- data/lib/lutaml/model/error/choice_upper_bound_error.rb +9 -0
- data/lib/lutaml/model/error/import_model_with_root_error.rb +9 -0
- data/lib/lutaml/model/error/incorrect_sequence_error.rb +9 -0
- data/lib/lutaml/model/error/invalid_choice_range_error.rb +20 -0
- data/lib/lutaml/model/error/no_root_mapping_error.rb +9 -0
- data/lib/lutaml/model/error/no_root_namespace_error.rb +9 -0
- data/lib/lutaml/model/error/unknown_sequence_mapping_error.rb +9 -0
- data/lib/lutaml/model/error.rb +8 -0
- data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +6 -1
- data/lib/lutaml/model/key_value_mapping.rb +3 -1
- data/lib/lutaml/model/key_value_mapping_rule.rb +4 -2
- data/lib/lutaml/model/liquefiable.rb +59 -0
- data/lib/lutaml/model/mapping_hash.rb +1 -1
- data/lib/lutaml/model/mapping_rule.rb +15 -2
- data/lib/lutaml/model/schema/xml_compiler.rb +68 -26
- data/lib/lutaml/model/schema_location.rb +7 -0
- data/lib/lutaml/model/sequence.rb +71 -0
- data/lib/lutaml/model/serialize.rb +125 -35
- data/lib/lutaml/model/type/decimal.rb +0 -4
- data/lib/lutaml/model/type/time.rb +3 -3
- data/lib/lutaml/model/utils.rb +19 -15
- data/lib/lutaml/model/validation.rb +12 -1
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/oga.rb +10 -7
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +20 -13
- data/lib/lutaml/model/xml_adapter/element.rb +32 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +8 -8
- data/lib/lutaml/model/xml_adapter/oga/element.rb +14 -13
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +86 -19
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +19 -15
- data/lib/lutaml/model/xml_adapter/xml_document.rb +74 -13
- data/lib/lutaml/model/xml_adapter/xml_element.rb +57 -3
- data/lib/lutaml/model/xml_mapping.rb +49 -7
- data/lib/lutaml/model/xml_mapping_rule.rb +8 -3
- data/lib/lutaml/model.rb +1 -0
- data/lutaml-model.gemspec +5 -0
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +75 -0
- data/spec/ceramic_spec.rb +39 -0
- data/spec/fixtures/ceramic.rb +23 -0
- data/spec/fixtures/xml/address_example_260.xsd +9 -0
- data/spec/fixtures/xml/user.xsd +10 -0
- data/spec/lutaml/model/cdata_spec.rb +4 -5
- data/spec/lutaml/model/choice_spec.rb +168 -0
- data/spec/lutaml/model/collection_spec.rb +1 -1
- data/spec/lutaml/model/custom_model_spec.rb +6 -7
- data/spec/lutaml/model/custom_serialization_spec.rb +74 -2
- data/spec/lutaml/model/defaults_spec.rb +3 -1
- data/spec/lutaml/model/delegation_spec.rb +7 -5
- data/spec/lutaml/model/enum_spec.rb +35 -0
- data/spec/lutaml/model/group_spec.rb +160 -0
- data/spec/lutaml/model/inheritance_spec.rb +25 -0
- data/spec/lutaml/model/liquefiable_spec.rb +121 -0
- data/spec/lutaml/model/mixed_content_spec.rb +80 -41
- data/spec/lutaml/model/multiple_mapping_spec.rb +22 -10
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +218 -25
- data/spec/lutaml/model/sequence_spec.rb +216 -0
- data/spec/lutaml/model/transformation_spec.rb +230 -0
- data/spec/lutaml/model/type_spec.rb +138 -31
- data/spec/lutaml/model/utils_spec.rb +32 -0
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +11 -7
- data/spec/lutaml/model/xml_mapping_rule_spec.rb +51 -0
- data/spec/lutaml/model/xml_mapping_spec.rb +143 -112
- metadata +67 -2
@@ -10,6 +10,9 @@ module Lutaml
|
|
10
10
|
collection
|
11
11
|
values
|
12
12
|
pattern
|
13
|
+
transform
|
14
|
+
choice
|
15
|
+
sequence
|
13
16
|
].freeze
|
14
17
|
|
15
18
|
def initialize(name, type, options = {})
|
@@ -33,6 +36,10 @@ module Lutaml
|
|
33
36
|
@options[:delegate]
|
34
37
|
end
|
35
38
|
|
39
|
+
def transform
|
40
|
+
@options[:transform] || {}
|
41
|
+
end
|
42
|
+
|
36
43
|
def cast_type!(type)
|
37
44
|
case type
|
38
45
|
when Symbol
|
@@ -81,15 +88,17 @@ module Lutaml
|
|
81
88
|
end
|
82
89
|
|
83
90
|
def default
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
91
|
+
cast_value(default_value)
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_value
|
95
|
+
if delegate
|
96
|
+
type.attributes[to].default
|
97
|
+
elsif options[:default].is_a?(Proc)
|
98
|
+
options[:default].call
|
99
|
+
else
|
100
|
+
options[:default]
|
101
|
+
end
|
93
102
|
end
|
94
103
|
|
95
104
|
def pattern
|
@@ -100,8 +109,16 @@ module Lutaml
|
|
100
109
|
@options.key?(:values) ? @options[:values] : []
|
101
110
|
end
|
102
111
|
|
112
|
+
def transform_import_method
|
113
|
+
transform[:import]
|
114
|
+
end
|
115
|
+
|
116
|
+
def transform_export_method
|
117
|
+
transform[:export]
|
118
|
+
end
|
119
|
+
|
103
120
|
def valid_value!(value)
|
104
|
-
return true if value.nil? &&
|
121
|
+
return true if value.nil? && singular?
|
105
122
|
return true unless enum?
|
106
123
|
|
107
124
|
unless valid_value?(value)
|
@@ -153,6 +170,10 @@ module Lutaml
|
|
153
170
|
raise ArgumentError, "Invalid collection range: #{range}"
|
154
171
|
end
|
155
172
|
|
173
|
+
validate_range!(range)
|
174
|
+
end
|
175
|
+
|
176
|
+
def validate_range!(range)
|
156
177
|
if range.begin.nil?
|
157
178
|
raise ArgumentError,
|
158
179
|
"Invalid collection range: #{range}. Begin must be specified."
|
@@ -235,6 +256,8 @@ module Lutaml
|
|
235
256
|
end
|
236
257
|
elsif type <= Serialize && value.is_a?(Hash)
|
237
258
|
type.apply_mappings(value, format, options)
|
259
|
+
elsif !value.nil? && !value.is_a?(type)
|
260
|
+
type.send(:"from_#{format}", value)
|
238
261
|
else
|
239
262
|
type.cast(value)
|
240
263
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class Choice
|
4
|
+
attr_reader :attributes,
|
5
|
+
:model,
|
6
|
+
:min,
|
7
|
+
:max
|
8
|
+
|
9
|
+
def initialize(model, min, max)
|
10
|
+
@attributes = []
|
11
|
+
@model = model
|
12
|
+
@min = min
|
13
|
+
@max = max
|
14
|
+
|
15
|
+
raise Lutaml::Model::InvalidChoiceRangeError.new(@min, @max) if @min.negative? || @max.negative?
|
16
|
+
end
|
17
|
+
|
18
|
+
def attribute(name, type, options = {})
|
19
|
+
options[:choice] = self
|
20
|
+
@attributes << @model.attribute(name, type, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def choice(min: 1, max: 1, &block)
|
24
|
+
@attributes << Choice.new(@model, min, max).tap do |c|
|
25
|
+
c.instance_eval(&block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate_content!(object)
|
30
|
+
validated_attributes = []
|
31
|
+
valid = valid_attributes(object, validated_attributes)
|
32
|
+
|
33
|
+
raise Lutaml::Model::ChoiceUpperBoundError.new(validated_attributes, @max) if valid.count > @max
|
34
|
+
raise Lutaml::Model::ChoiceLowerBoundError.new(validated_attributes, @min) if valid.count < @min
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def valid_attributes(object, validated_attributes)
|
40
|
+
@attributes.each do |attribute|
|
41
|
+
if attribute.is_a?(Choice)
|
42
|
+
begin
|
43
|
+
attribute.validate_content!(object)
|
44
|
+
validated_attributes << attribute
|
45
|
+
rescue Lutaml::Model::ChoiceLowerBoundError
|
46
|
+
end
|
47
|
+
elsif Utils.present?(object.public_send(attribute.name))
|
48
|
+
validated_attributes << attribute.name
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
validated_attributes
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/lutaml/model/config.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class IncorrectSequenceError < Error
|
4
|
+
def initialize(defined_order_element, expected_order_element)
|
5
|
+
super("Element `#{expected_order_element}` does not match the expected sequence order element `#{defined_order_element}`")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class InvalidChoiceRangeError < Error
|
4
|
+
def initialize(min, max)
|
5
|
+
@min = min
|
6
|
+
@max = max
|
7
|
+
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
if @min.negative?
|
13
|
+
"Choice lower bound `#{@min}` must be positive"
|
14
|
+
else
|
15
|
+
"Choice upper bound `#{@max}` must be positive"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/lutaml/model/error.rb
CHANGED
@@ -17,3 +17,11 @@ require_relative "error/unknown_type_error"
|
|
17
17
|
require_relative "error/multiple_mappings_error"
|
18
18
|
require_relative "error/collection_true_missing_error"
|
19
19
|
require_relative "error/type/invalid_value_error"
|
20
|
+
require_relative "error/incorrect_sequence_error"
|
21
|
+
require_relative "error/choice_upper_bound_error"
|
22
|
+
require_relative "error/no_root_mapping_error"
|
23
|
+
require_relative "error/import_model_with_root_error"
|
24
|
+
require_relative "error/invalid_choice_range_error"
|
25
|
+
require_relative "error/unknown_sequence_mapping_error"
|
26
|
+
require_relative "error/choice_lower_bound_error"
|
27
|
+
require_relative "error/no_root_namespace_error"
|
@@ -10,7 +10,12 @@ module Lutaml
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def to_json(*args)
|
13
|
-
|
13
|
+
options = args.first || {}
|
14
|
+
if options[:pretty]
|
15
|
+
JSON.pretty_generate(@attributes, *args)
|
16
|
+
else
|
17
|
+
JSON.generate(@attributes, *args)
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -17,7 +17,8 @@ module Lutaml
|
|
17
17
|
with: {},
|
18
18
|
delegate: nil,
|
19
19
|
child_mappings: nil,
|
20
|
-
root_mappings: nil
|
20
|
+
root_mappings: nil,
|
21
|
+
transform: {}
|
21
22
|
)
|
22
23
|
mapping_name = name_for_mapping(root_mappings, name)
|
23
24
|
validate!(mapping_name, to, with)
|
@@ -31,6 +32,7 @@ module Lutaml
|
|
31
32
|
delegate: delegate,
|
32
33
|
child_mappings: child_mappings,
|
33
34
|
root_mappings: root_mappings,
|
35
|
+
transform: transform,
|
34
36
|
)
|
35
37
|
end
|
36
38
|
|
@@ -14,7 +14,8 @@ module Lutaml
|
|
14
14
|
with: {},
|
15
15
|
delegate: nil,
|
16
16
|
child_mappings: nil,
|
17
|
-
root_mappings: nil
|
17
|
+
root_mappings: nil,
|
18
|
+
transform: {}
|
18
19
|
)
|
19
20
|
super(
|
20
21
|
name,
|
@@ -22,7 +23,8 @@ module Lutaml
|
|
22
23
|
render_nil: render_nil,
|
23
24
|
render_default: render_default,
|
24
25
|
with: with,
|
25
|
-
delegate: delegate
|
26
|
+
delegate: delegate,
|
27
|
+
transform: transform
|
26
28
|
)
|
27
29
|
|
28
30
|
@child_mappings = child_mappings
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "liquid"
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Liquefiable
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def register_liquid_drop_class
|
12
|
+
if drop_class
|
13
|
+
raise "#{drop_class_name} Already exists!"
|
14
|
+
end
|
15
|
+
|
16
|
+
const_set(drop_class_name,
|
17
|
+
Class.new(Liquid::Drop) do
|
18
|
+
def initialize(object)
|
19
|
+
super()
|
20
|
+
@object = object
|
21
|
+
end
|
22
|
+
end)
|
23
|
+
end
|
24
|
+
|
25
|
+
def drop_class_name
|
26
|
+
@drop_class_name ||= if name
|
27
|
+
"#{to_s.split('::').last}Drop"
|
28
|
+
else
|
29
|
+
"Drop"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def drop_class
|
34
|
+
const_get(drop_class_name)
|
35
|
+
rescue StandardError
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def register_drop_method(method_name)
|
40
|
+
register_liquid_drop_class unless drop_class
|
41
|
+
|
42
|
+
drop_class.define_method(method_name) do
|
43
|
+
value = @object.public_send(method_name)
|
44
|
+
|
45
|
+
if value.is_a?(Array)
|
46
|
+
value.map(&:to_liquid)
|
47
|
+
else
|
48
|
+
value.to_liquid
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_liquid
|
55
|
+
self.class.drop_class.new(self)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -7,7 +7,8 @@ module Lutaml
|
|
7
7
|
:render_default,
|
8
8
|
:attribute,
|
9
9
|
:custom_methods,
|
10
|
-
:delegate
|
10
|
+
:delegate,
|
11
|
+
:transform
|
11
12
|
|
12
13
|
def initialize(
|
13
14
|
name,
|
@@ -17,7 +18,8 @@ module Lutaml
|
|
17
18
|
with: {},
|
18
19
|
attribute: false,
|
19
20
|
delegate: nil,
|
20
|
-
root_mappings: nil
|
21
|
+
root_mappings: nil,
|
22
|
+
transform: {}
|
21
23
|
)
|
22
24
|
@name = name
|
23
25
|
@to = to
|
@@ -27,6 +29,7 @@ module Lutaml
|
|
27
29
|
@attribute = attribute
|
28
30
|
@delegate = delegate
|
29
31
|
@root_mappings = root_mappings
|
32
|
+
@transform = transform
|
30
33
|
end
|
31
34
|
|
32
35
|
alias from name
|
@@ -71,6 +74,8 @@ module Lutaml
|
|
71
74
|
end
|
72
75
|
|
73
76
|
model.public_send(delegate).public_send(:"#{to}=", value)
|
77
|
+
elsif transform_method = transform[:import] || attributes[to].transform_import_method
|
78
|
+
model.public_send(:"#{to}=", transform_method.call(value))
|
74
79
|
else
|
75
80
|
model.public_send(:"#{to}=", value)
|
76
81
|
end
|
@@ -88,6 +93,14 @@ module Lutaml
|
|
88
93
|
name == Constants::RAW_MAPPING_KEY
|
89
94
|
end
|
90
95
|
|
96
|
+
def eql?(other)
|
97
|
+
other.class == self.class &&
|
98
|
+
instance_variables.all? do |var|
|
99
|
+
instance_variable_get(var) == other.instance_variable_get(var)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
alias == eql?
|
103
|
+
|
91
104
|
def deep_dup
|
92
105
|
raise NotImplementedError, "Subclasses must implement `deep_dup`."
|
93
106
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "erb"
|
4
|
+
require "tmpdir"
|
4
5
|
require "lutaml/xsd"
|
5
6
|
require_relative "templates/simple_type"
|
6
7
|
|
@@ -37,7 +38,7 @@ module Lutaml
|
|
37
38
|
if content&.key_exist?(:sequence) || content&.key_exist?(:choice) || content&.key_exist?(:group)
|
38
39
|
output = resolve_content(content).map do |element_name, element|
|
39
40
|
element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
|
40
|
-
" attribute :\#{Utils.snake_case(element_name)}, \#{
|
41
|
+
" attribute :\#{Utils.snake_case(element_name)}, \#{resolve_element_class(element)}\#{resolve_occurs(element.arguments) if element.key_exist?(:arguments)}"
|
41
42
|
end.join("\n")
|
42
43
|
output + "\n" if output && !output&.empty?
|
43
44
|
end
|
@@ -49,13 +50,13 @@ module Lutaml
|
|
49
50
|
element.map { |attribute| " attribute :\#{Utils.snake_case(attribute.name)}, \#{resolve_attribute_class(attribute)}\#{resolve_attribute_default(attribute.default) if attribute.key_exist?(:default)}" }.join("\n")
|
50
51
|
else
|
51
52
|
element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
|
52
|
-
" attribute :\#{Utils.snake_case(element_name)}, \#{
|
53
|
+
" attribute :\#{Utils.snake_case(element_name)}, \#{resolve_element_class(element)}\#{resolve_occurs(element.arguments) if element.key_exist?(:arguments)}"
|
53
54
|
end
|
54
55
|
end.join("\n")
|
55
56
|
output + "\n" if output && !output&.empty?
|
56
57
|
end
|
57
58
|
-%>
|
58
|
-
<%= " attribute :content, \#{content.simple_content.extension_base}" if content_exist = content.key_exist?(:simple_content) && content.simple_content.key_exist?(:extension_base) -%>
|
59
|
+
<%= " attribute :content, \#{content[:mixed] ? ':string' : content.simple_content.extension_base}" if content_exist = (content.key_exist?(:simple_content) && content.simple_content.key_exist?(:extension_base)) || content[:mixed] -%>
|
59
60
|
|
60
61
|
xml do
|
61
62
|
root "<%= name %>", mixed: true
|
@@ -107,13 +108,28 @@ module Lutaml
|
|
107
108
|
|
108
109
|
def to_models(schema, options = {})
|
109
110
|
as_models(schema, options: options)
|
110
|
-
dir = options.fetch(:output_dir, "lutaml_models_#{Time.now.to_i}")
|
111
|
-
FileUtils.mkdir_p(dir)
|
112
|
-
|
113
111
|
@data_types_classes = Templates::SimpleType.create_simple_types(@simple_types)
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
if options[:create_files]
|
113
|
+
dir = options.fetch(:output_dir, "lutaml_models_#{Time.now.to_i}")
|
114
|
+
FileUtils.mkdir_p(dir)
|
115
|
+
@data_types_classes.each do |name, content|
|
116
|
+
create_file(name, content, dir)
|
117
|
+
end
|
118
|
+
@complex_types.each do |name, content|
|
119
|
+
create_file(name, MODEL_TEMPLATE.result(binding), dir)
|
120
|
+
end
|
121
|
+
nil
|
122
|
+
else
|
123
|
+
simple_types = @data_types_classes.transform_keys do |key|
|
124
|
+
Utils.camel_case(key.to_s)
|
125
|
+
end
|
126
|
+
complex_types = @complex_types.to_h do |name, content|
|
127
|
+
[Utils.camel_case(name), MODEL_TEMPLATE.result(binding)]
|
128
|
+
end
|
129
|
+
classes_hash = simple_types.merge(complex_types)
|
130
|
+
require_classes(classes_hash) if options[:load_classes]
|
131
|
+
classes_hash
|
132
|
+
end
|
117
133
|
end
|
118
134
|
|
119
135
|
private
|
@@ -122,6 +138,15 @@ module Lutaml
|
|
122
138
|
File.write("#{dir}/#{Utils.snake_case(name)}.rb", content)
|
123
139
|
end
|
124
140
|
|
141
|
+
def require_classes(classes_hash)
|
142
|
+
Dir.mktmpdir do |dir|
|
143
|
+
classes_hash.each do |name, klass|
|
144
|
+
create_file(name, klass, dir)
|
145
|
+
require "#{dir}/#{Utils.snake_case(name)}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
125
150
|
# START: STRUCTURE SETUP METHODS
|
126
151
|
|
127
152
|
def as_models(schema, options: {})
|
@@ -136,7 +161,7 @@ module Lutaml
|
|
136
161
|
@complex_types = MappingHash.new
|
137
162
|
@attribute_groups = MappingHash.new
|
138
163
|
|
139
|
-
schema_to_models(
|
164
|
+
schema_to_models(Array(parsed_schema))
|
140
165
|
end
|
141
166
|
|
142
167
|
def schema_to_models(schemas)
|
@@ -196,6 +221,7 @@ module Lutaml
|
|
196
221
|
MappingHash.new.tap do |hash|
|
197
222
|
hash[:attributes] = [] if complex_type.attribute.any?
|
198
223
|
hash[:attribute_groups] = [] if complex_type.attribute_group.any?
|
224
|
+
hash[:mixed] = complex_type.mixed
|
199
225
|
resolved_element_order(complex_type).each do |element|
|
200
226
|
case element
|
201
227
|
when Xsd::Attribute
|
@@ -237,18 +263,18 @@ module Lutaml
|
|
237
263
|
hash[:sequences] << setup_sequence(instance)
|
238
264
|
when Xsd::Element
|
239
265
|
hash[:elements] << if instance.name
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
266
|
+
setup_element(instance)
|
267
|
+
else
|
268
|
+
create_mapping_hash(instance.ref, hash_key: :ref_class)
|
269
|
+
end
|
244
270
|
when Xsd::Choice
|
245
271
|
hash[:choice] << setup_choice(instance)
|
246
272
|
when Xsd::Group
|
247
273
|
hash[:groups] << if instance.name
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
274
|
+
setup_group_type(instance)
|
275
|
+
else
|
276
|
+
create_mapping_hash(instance.ref, hash_key: :ref_class)
|
277
|
+
end
|
252
278
|
when Xsd::Any
|
253
279
|
# No implementation yet!
|
254
280
|
end
|
@@ -363,7 +389,7 @@ module Lutaml
|
|
363
389
|
def restriction_patterns(patterns, hash)
|
364
390
|
return if patterns.empty?
|
365
391
|
|
366
|
-
hash[:pattern] = patterns.map { |
|
392
|
+
hash[:pattern] = patterns.map { |p| "(#{p.value})" }.join("|")
|
367
393
|
hash
|
368
394
|
end
|
369
395
|
|
@@ -404,22 +430,23 @@ module Lutaml
|
|
404
430
|
end
|
405
431
|
end
|
406
432
|
|
407
|
-
def resolved_element_order(object
|
433
|
+
def resolved_element_order(object)
|
408
434
|
return [] if object.element_order.nil?
|
409
435
|
|
410
|
-
object.element_order.each_with_object(object.element_order.dup) do |
|
411
|
-
next array.delete(
|
412
|
-
next array.delete(
|
436
|
+
object.element_order.each_with_object(object.element_order.dup) do |builder_instance, array|
|
437
|
+
next array.delete(builder_instance) if builder_instance.text?
|
438
|
+
next array.delete(builder_instance) if ELEMENT_ORDER_IGNORABLE.include?(builder_instance.name)
|
413
439
|
|
414
440
|
index = 0
|
415
441
|
array.each_with_index do |element, i|
|
416
|
-
next unless element ==
|
442
|
+
next unless element == builder_instance
|
417
443
|
|
418
|
-
array[i] = Array(object.send(Utils.snake_case(name)))[index]
|
444
|
+
array[i] = Array(object.send(Utils.snake_case(builder_instance.name)))[index]
|
419
445
|
index += 1
|
420
446
|
end
|
421
447
|
end
|
422
448
|
end
|
449
|
+
|
423
450
|
# END: STRUCTURE SETUP METHODS
|
424
451
|
|
425
452
|
# START: TEMPLATE RESOLVER METHODS
|
@@ -439,6 +466,16 @@ module Lutaml
|
|
439
466
|
end
|
440
467
|
end
|
441
468
|
|
469
|
+
def resolve_element_class(element)
|
470
|
+
element_class = element.type_name.split(":").last
|
471
|
+
case element_class
|
472
|
+
when *DEFAULT_CLASSES
|
473
|
+
":#{element_class}"
|
474
|
+
else
|
475
|
+
Utils.camel_case(element_class)
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
442
479
|
def resolve_occurs(arguments)
|
443
480
|
min_occurs = arguments[:min_occurs]
|
444
481
|
max_occurs = arguments[:max_occurs]
|
@@ -583,6 +620,7 @@ module Lutaml
|
|
583
620
|
end
|
584
621
|
@required_files.uniq.sort_by(&:length)
|
585
622
|
end
|
623
|
+
|
586
624
|
# END: TEMPLATE RESOLVER METHODS
|
587
625
|
|
588
626
|
# START: REQUIRED FILES LIST COMPILER METHODS
|
@@ -710,9 +748,13 @@ module Lutaml
|
|
710
748
|
def required_files_elements(elements)
|
711
749
|
elements.each do |element|
|
712
750
|
element = @elements[element.ref_class.split(":").last] if element.key_exist?(:ref_class)
|
713
|
-
|
751
|
+
element_class = element.type_name.split(":").last
|
752
|
+
next if DEFAULT_CLASSES.include?(element_class)
|
753
|
+
|
754
|
+
@required_files << Utils.snake_case(element_class)
|
714
755
|
end
|
715
756
|
end
|
757
|
+
|
716
758
|
# END: REQUIRED FILES LIST COMPILER METHODS
|
717
759
|
end
|
718
760
|
end
|
@@ -11,6 +11,13 @@ module Lutaml
|
|
11
11
|
def to_xml_attribute
|
12
12
|
"#{@namespace} #{@location}".strip
|
13
13
|
end
|
14
|
+
|
15
|
+
def eql?(other)
|
16
|
+
other.class == self.class &&
|
17
|
+
namespace == other.namespace &&
|
18
|
+
location == other.location
|
19
|
+
end
|
20
|
+
alias == eql?
|
14
21
|
end
|
15
22
|
|
16
23
|
class SchemaLocation
|