lutaml-model 0.7.3 → 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.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +1 -0
  3. data/.github/workflows/release.yml +3 -0
  4. data/.gitignore +6 -1
  5. data/.irbrc +1 -0
  6. data/.pryrc +1 -0
  7. data/.rubocop_todo.yml +25 -52
  8. data/README.adoc +2177 -192
  9. data/docs/custom_registers.adoc +228 -0
  10. data/docs/schema_generation.adoc +898 -0
  11. data/docs/schema_import.adoc +364 -0
  12. data/flake.lock +114 -0
  13. data/flake.nix +103 -0
  14. data/lib/lutaml/model/attribute.rb +230 -94
  15. data/lib/lutaml/model/choice.rb +30 -0
  16. data/lib/lutaml/model/collection.rb +194 -0
  17. data/lib/lutaml/model/comparable_model.rb +3 -3
  18. data/lib/lutaml/model/config.rb +26 -3
  19. data/lib/lutaml/model/constants.rb +2 -0
  20. data/lib/lutaml/model/error/element_count_out_of_range_error.rb +29 -0
  21. data/lib/lutaml/model/error/invalid_attribute_name_error.rb +15 -0
  22. data/lib/lutaml/model/error/invalid_attribute_options_error.rb +16 -0
  23. data/lib/lutaml/model/error/invalid_choice_range_error.rb +3 -5
  24. data/lib/lutaml/model/error/register/not_registrable_class_error.rb +11 -0
  25. data/lib/lutaml/model/error/type/invalid_value_error.rb +5 -3
  26. data/lib/lutaml/model/error/type/max_bound_error.rb +20 -0
  27. data/lib/lutaml/model/error/type/max_length_error.rb +20 -0
  28. data/lib/lutaml/model/error/type/min_bound_error.rb +20 -0
  29. data/lib/lutaml/model/error/type/min_length_error.rb +20 -0
  30. data/lib/lutaml/model/error/type/pattern_not_matched_error.rb +18 -0
  31. data/lib/lutaml/model/error/validation_failed_error.rb +9 -0
  32. data/lib/lutaml/model/error.rb +10 -0
  33. data/lib/lutaml/model/errors.rb +36 -0
  34. data/lib/lutaml/model/format_registry.rb +5 -2
  35. data/lib/lutaml/model/global_register.rb +41 -0
  36. data/lib/lutaml/model/{hash.rb → hash_adapter.rb} +5 -5
  37. data/lib/lutaml/model/jsonl/document.rb +14 -0
  38. data/lib/lutaml/model/jsonl/mapping.rb +19 -0
  39. data/lib/lutaml/model/jsonl/mapping_rule.rb +9 -0
  40. data/lib/lutaml/model/jsonl/standard_adapter.rb +33 -0
  41. data/lib/lutaml/model/jsonl/transform.rb +19 -0
  42. data/lib/lutaml/model/jsonl.rb +21 -0
  43. data/lib/lutaml/model/key_value_document.rb +3 -2
  44. data/lib/lutaml/model/mapping/key_value_mapping.rb +64 -4
  45. data/lib/lutaml/model/mapping/key_value_mapping_rule.rb +4 -0
  46. data/lib/lutaml/model/mapping/mapping_rule.rb +8 -3
  47. data/lib/lutaml/model/register.rb +105 -0
  48. data/lib/lutaml/model/registrable.rb +6 -0
  49. data/lib/lutaml/model/schema/base_schema.rb +64 -0
  50. data/lib/lutaml/model/schema/decorators/attribute.rb +114 -0
  51. data/lib/lutaml/model/schema/decorators/choices.rb +31 -0
  52. data/lib/lutaml/model/schema/decorators/class_definition.rb +85 -0
  53. data/lib/lutaml/model/schema/decorators/definition_collection.rb +97 -0
  54. data/lib/lutaml/model/schema/generator/definition.rb +53 -0
  55. data/lib/lutaml/model/schema/generator/definitions_collection.rb +81 -0
  56. data/lib/lutaml/model/schema/generator/properties_collection.rb +63 -0
  57. data/lib/lutaml/model/schema/generator/property.rb +110 -0
  58. data/lib/lutaml/model/schema/generator/ref.rb +24 -0
  59. data/lib/lutaml/model/schema/helpers/template_helper.rb +49 -0
  60. data/lib/lutaml/model/schema/json_schema.rb +42 -49
  61. data/lib/lutaml/model/schema/relaxng_schema.rb +14 -10
  62. data/lib/lutaml/model/schema/renderer.rb +36 -0
  63. data/lib/lutaml/model/schema/shared_methods.rb +24 -0
  64. data/lib/lutaml/model/schema/templates/model.erb +9 -0
  65. data/lib/lutaml/model/schema/xml_compiler/attribute.rb +85 -0
  66. data/lib/lutaml/model/schema/xml_compiler/attribute_group.rb +45 -0
  67. data/lib/lutaml/model/schema/xml_compiler/choice.rb +65 -0
  68. data/lib/lutaml/model/schema/xml_compiler/complex_content.rb +27 -0
  69. data/lib/lutaml/model/schema/xml_compiler/complex_content_restriction.rb +34 -0
  70. data/lib/lutaml/model/schema/xml_compiler/complex_type.rb +136 -0
  71. data/lib/lutaml/model/schema/xml_compiler/element.rb +104 -0
  72. data/lib/lutaml/model/schema/xml_compiler/group.rb +97 -0
  73. data/lib/lutaml/model/schema/xml_compiler/restriction.rb +101 -0
  74. data/lib/lutaml/model/schema/xml_compiler/sequence.rb +50 -0
  75. data/lib/lutaml/model/schema/xml_compiler/simple_content.rb +36 -0
  76. data/lib/lutaml/model/schema/xml_compiler/simple_type.rb +189 -0
  77. data/lib/lutaml/model/schema/xml_compiler.rb +231 -587
  78. data/lib/lutaml/model/schema/xsd_schema.rb +12 -8
  79. data/lib/lutaml/model/schema/yaml_schema.rb +41 -35
  80. data/lib/lutaml/model/schema.rb +1 -0
  81. data/lib/lutaml/model/sequence.rb +60 -30
  82. data/lib/lutaml/model/serialize.rb +175 -53
  83. data/lib/lutaml/model/services/base.rb +11 -0
  84. data/lib/lutaml/model/services/logger.rb +2 -2
  85. data/lib/lutaml/model/services/rule_value_extractor.rb +92 -0
  86. data/lib/lutaml/model/services/type/validator/number.rb +25 -0
  87. data/lib/lutaml/model/services/type/validator/string.rb +52 -0
  88. data/lib/lutaml/model/services/type/validator.rb +43 -0
  89. data/lib/lutaml/model/services/validator.rb +145 -0
  90. data/lib/lutaml/model/services.rb +3 -0
  91. data/lib/lutaml/model/transform/key_value_transform.rb +60 -50
  92. data/lib/lutaml/model/transform/xml_transform.rb +46 -57
  93. data/lib/lutaml/model/transform.rb +22 -8
  94. data/lib/lutaml/model/type/boolean.rb +1 -1
  95. data/lib/lutaml/model/type/date.rb +1 -1
  96. data/lib/lutaml/model/type/date_time.rb +1 -1
  97. data/lib/lutaml/model/type/decimal.rb +11 -9
  98. data/lib/lutaml/model/type/float.rb +2 -1
  99. data/lib/lutaml/model/type/integer.rb +24 -21
  100. data/lib/lutaml/model/type/string.rb +4 -2
  101. data/lib/lutaml/model/type/time.rb +1 -1
  102. data/lib/lutaml/model/type/time_without_date.rb +1 -1
  103. data/lib/lutaml/model/type/value.rb +5 -1
  104. data/lib/lutaml/model/type.rb +5 -2
  105. data/lib/lutaml/model/utils.rb +30 -8
  106. data/lib/lutaml/model/validation.rb +6 -4
  107. data/lib/lutaml/model/version.rb +1 -1
  108. data/lib/lutaml/model/xml/document.rb +37 -19
  109. data/lib/lutaml/model/xml/mapping.rb +74 -13
  110. data/lib/lutaml/model/xml/mapping_rule.rb +10 -2
  111. data/lib/lutaml/model/xml/nokogiri_adapter.rb +5 -3
  112. data/lib/lutaml/model/xml/oga/element.rb +4 -1
  113. data/lib/lutaml/model/xml/oga_adapter.rb +4 -3
  114. data/lib/lutaml/model/xml/ox_adapter.rb +20 -6
  115. data/lib/lutaml/model/xml/xml_element.rb +3 -28
  116. data/lib/lutaml/model/xml_adapter/element.rb +1 -1
  117. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +1 -1
  118. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +1 -1
  119. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +1 -1
  120. data/lib/lutaml/model/yamls/document.rb +14 -0
  121. data/lib/lutaml/model/yamls/mapping.rb +19 -0
  122. data/lib/lutaml/model/yamls/mapping_rule.rb +9 -0
  123. data/lib/lutaml/model/yamls/standard_adapter.rb +34 -0
  124. data/lib/lutaml/model/yamls/transform.rb +19 -0
  125. data/lib/lutaml/model/yamls.rb +21 -0
  126. data/lib/lutaml/model.rb +7 -31
  127. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +4 -5
  128. data/spec/fixtures/xml/advanced_test_schema.xsd +134 -0
  129. data/spec/fixtures/xml/examples/nested_categories.xml +55 -0
  130. data/spec/fixtures/xml/examples/valid_catalog.xml +43 -0
  131. data/spec/fixtures/xml/product_catalog.xsd +151 -0
  132. data/spec/fixtures/xml/specifications_schema.xsd +38 -0
  133. data/spec/lutaml/model/attribute_collection_spec.rb +101 -0
  134. data/spec/lutaml/model/attribute_spec.rb +41 -44
  135. data/spec/lutaml/model/choice_spec.rb +44 -0
  136. data/spec/lutaml/model/custom_collection_spec.rb +830 -0
  137. data/spec/lutaml/model/custom_model_spec.rb +15 -3
  138. data/spec/lutaml/model/defaults_spec.rb +5 -1
  139. data/spec/lutaml/model/global_register_spec.rb +108 -0
  140. data/spec/lutaml/model/group_spec.rb +9 -3
  141. data/spec/lutaml/model/jsonl/standard_adapter_spec.rb +91 -0
  142. data/spec/lutaml/model/jsonl_spec.rb +229 -0
  143. data/spec/lutaml/model/multiple_mapping_spec.rb +1 -1
  144. data/spec/lutaml/model/register/key_value_spec.rb +275 -0
  145. data/spec/lutaml/model/register/xml_spec.rb +187 -0
  146. data/spec/lutaml/model/register_spec.rb +147 -0
  147. data/spec/lutaml/model/rule_value_extractor_spec.rb +162 -0
  148. data/spec/lutaml/model/schema/generator/definitions_collection_spec.rb +120 -0
  149. data/spec/lutaml/model/schema/json_schema_spec.rb +412 -51
  150. data/spec/lutaml/model/schema/json_schema_to_models_spec.rb +383 -0
  151. data/spec/lutaml/model/schema/xml_compiler/attribute_group_spec.rb +65 -0
  152. data/spec/lutaml/model/schema/xml_compiler/attribute_spec.rb +63 -0
  153. data/spec/lutaml/model/schema/xml_compiler/choice_spec.rb +71 -0
  154. data/spec/lutaml/model/schema/xml_compiler/complex_content_restriction_spec.rb +55 -0
  155. data/spec/lutaml/model/schema/xml_compiler/complex_content_spec.rb +37 -0
  156. data/spec/lutaml/model/schema/xml_compiler/complex_type_spec.rb +173 -0
  157. data/spec/lutaml/model/schema/xml_compiler/element_spec.rb +63 -0
  158. data/spec/lutaml/model/schema/xml_compiler/group_spec.rb +86 -0
  159. data/spec/lutaml/model/schema/xml_compiler/restriction_spec.rb +76 -0
  160. data/spec/lutaml/model/schema/xml_compiler/sequence_spec.rb +59 -0
  161. data/spec/lutaml/model/schema/xml_compiler/simple_content_spec.rb +55 -0
  162. data/spec/lutaml/model/schema/xml_compiler/simple_type_spec.rb +181 -0
  163. data/spec/lutaml/model/schema/xml_compiler_spec.rb +503 -1804
  164. data/spec/lutaml/model/schema/yaml_schema_spec.rb +249 -26
  165. data/spec/lutaml/model/sequence_spec.rb +36 -0
  166. data/spec/lutaml/model/serializable_spec.rb +31 -0
  167. data/spec/lutaml/model/type_spec.rb +8 -4
  168. data/spec/lutaml/model/utils_spec.rb +3 -3
  169. data/spec/lutaml/model/xml/derived_attributes_spec.rb +1 -1
  170. data/spec/lutaml/model/xml/xml_element_spec.rb +7 -1
  171. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +6 -6
  172. data/spec/lutaml/model/xml_adapter_spec.rb +24 -0
  173. data/spec/lutaml/model/xml_mapping_rule_spec.rb +11 -4
  174. data/spec/lutaml/model/xml_mapping_spec.rb +1 -1
  175. data/spec/lutaml/model/yamls/standard_adapter_spec.rb +183 -0
  176. data/spec/lutaml/model/yamls_spec.rb +294 -0
  177. data/spec/spec_helper.rb +1 -0
  178. metadata +105 -9
  179. data/lib/lutaml/model/schema/templates/simple_type.rb +0 -247
  180. /data/lib/lutaml/model/{hash → hash_adapter}/document.rb +0 -0
  181. /data/lib/lutaml/model/{hash → hash_adapter}/mapping.rb +0 -0
  182. /data/lib/lutaml/model/{hash → hash_adapter}/mapping_rule.rb +0 -0
  183. /data/lib/lutaml/model/{hash → hash_adapter}/standard_adapter.rb +0 -0
  184. /data/lib/lutaml/model/{hash → hash_adapter}/transform.rb +0 -0
@@ -3,7 +3,18 @@
3
3
  require "erb"
4
4
  require "tmpdir"
5
5
  require "lutaml/xsd"
6
- require_relative "templates/simple_type"
6
+ require_relative "xml_compiler/complex_content_restriction"
7
+ require_relative "xml_compiler/attribute_group"
8
+ require_relative "xml_compiler/complex_content"
9
+ require_relative "xml_compiler/simple_content"
10
+ require_relative "xml_compiler/complex_type"
11
+ require_relative "xml_compiler/restriction"
12
+ require_relative "xml_compiler/simple_type"
13
+ require_relative "xml_compiler/attribute"
14
+ require_relative "xml_compiler/sequence"
15
+ require_relative "xml_compiler/element"
16
+ require_relative "xml_compiler/choice"
17
+ require_relative "xml_compiler/group"
7
18
 
8
19
  module Lutaml
9
20
  module Model
@@ -11,92 +22,14 @@ module Lutaml
11
22
  module XmlCompiler
12
23
  extend self
13
24
 
14
- DEFAULT_CLASSES = %w[string integer int boolean].freeze
15
- ELEMENT_ORDER_IGNORABLE = %w[import include].freeze
16
-
17
- MODEL_TEMPLATE = ERB.new(<<~TEMPLATE, trim_mode: "-")
18
- # frozen_string_literal: true
19
- require "lutaml/model"
20
- <%=
21
- requiring_files = resolve_required_files(content)
22
- if requiring_files&.any?
23
- requiring_files.map { |file| "require_relative \\\"\#{file}\\\"" }.join("\n") + "\n"
24
- end
25
- -%>
26
-
27
- class <%= Utils.camel_case(name) %> < <%= resolve_parent_class(content) %>
28
- <%=
29
- if content&.key_exist?(:attributes)
30
- output = content.attributes.map do |attribute|
31
- attribute = @attributes[attribute.ref_class.split(":").last] if attribute.key?(:ref_class)
32
- " attribute :\#{Utils.snake_case(attribute.name)}, \#{resolve_attribute_class(attribute)}\#{resolve_attribute_default(attribute) if attribute.key_exist?(:default)}"
33
- end.join("\n")
34
- output + "\n" if output && !output&.empty?
35
- end
36
- -%>
37
- <%=
38
- if content&.key_exist?(:sequence) || content&.key_exist?(:choice) || content&.key_exist?(:group)
39
- output = resolve_content(content).map do |element_name, element|
40
- element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
41
- " attribute :\#{Utils.snake_case(element_name)}, \#{resolve_element_class(element)}\#{resolve_occurs(element.arguments) if element.key_exist?(:arguments)}"
42
- end.join("\n")
43
- output + "\n" if output && !output&.empty?
44
- end
45
- -%>
46
- <%=
47
- if content&.key_exist?(:complex_content)
48
- resolve_complex_content(content.complex_content).map do |element_name, element|
49
- if element_name == :attributes
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")
51
- else
52
- element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
53
- " attribute :\#{Utils.snake_case(element_name)}, \#{resolve_element_class(element)}\#{resolve_occurs(element.arguments) if element.key_exist?(:arguments)}"
54
- end
55
- end.join("\n")
56
- output + "\n" if output && !output&.empty?
57
- end
58
- -%>
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] -%>
60
-
61
- xml do
62
- root "<%= name %>", mixed: true
63
- <%= resolve_namespace(options) %>
64
- <%= " map_content to: :content\n" if content_exist -%>
65
- <%=
66
- if content&.key_exist?(:attributes)
67
- output = content.attributes.map do |attribute|
68
- attribute = @attributes[attribute.ref_class.split(":").last] if attribute.key?(:ref_class)
69
- " map_attribute :\#{Utils.snake_case(attribute.name)}, to: :\#{Utils.snake_case(attribute.name)}"
70
- end.join("\n")
71
- output + "\n" if output && !output&.empty?
72
- end
73
- -%>
74
- <%=
75
- if content&.key_exist?(:sequence) || content&.key_exist?(:choice) || content&.key_exist?(:group)
76
- output = resolve_content(content).map do |element_name, element|
77
- element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
78
- " map_element :\#{element_name}, to: :\#{Utils.snake_case(element_name)}"
79
- end.join("\n")
80
- output + "\n" if output && !output&.empty?
81
- end
82
- -%>
83
- <%=
84
- if content&.key_exist?(:complex_content)
85
- output = resolve_complex_content(content.complex_content).map do |element_name, element|
86
- if element_name == :attributes
87
- element.map { |attribute| " map_attribute :\#{Utils.snake_case(attribute.name)}, to: :\#{Utils.snake_case(attribute.name)}" }.join("\n")
88
- else
89
- element = @elements[element.ref_class.split(":")&.last] if element&.key_exist?(:ref_class)
90
- " map_element :\#{element_name}, to: :\#{Utils.snake_case(element_name)}"
91
- end
92
- end.join("\n")
93
- output + "\n" if output && !output&.empty?
94
- end
95
- -%>
96
- end
97
- end
25
+ attr_reader :simple_types,
26
+ :group_types,
27
+ :complex_types,
28
+ :elements,
29
+ :attributes,
30
+ :attribute_groups
98
31
 
99
- TEMPLATE
32
+ ELEMENT_ORDER_IGNORABLE = %w[import include].freeze
100
33
 
101
34
  XML_ADAPTER_NOT_SET_MESSAGE = <<~MSG
102
35
  Nokogiri is not set as XML Adapter.
@@ -106,49 +39,43 @@ module Lutaml
106
39
  Lutaml::Model.xml_adapter = Lutaml::Model::Adapter::Nokogiri
107
40
  MSG
108
41
 
42
+ XML_DEFINED_ATTRIBUTES = {
43
+ "id" => "id",
44
+ "lang" => "language",
45
+ "space" => "NCName",
46
+ "base" => "anyURI",
47
+ }.freeze
48
+
109
49
  def to_models(schema, options = {})
110
50
  as_models(schema, options: options)
111
- @data_types_classes = Templates::SimpleType.create_simple_types(@simple_types)
51
+ options[:indent] = options[:indent] ? options[:indent].to_i : 2
52
+ @simple_types.merge!(XmlCompiler::SimpleType.setup_supported_types)
53
+ classes_list = @simple_types.merge(@complex_types).merge(@group_types)
54
+ classes_list = classes_list.transform_values { |type| type.to_class(options: options) }
112
55
  if options[:create_files]
113
56
  dir = options.fetch(:output_dir, "lutaml_models_#{Time.now.to_i}")
114
57
  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
58
+ classes_list.each { |name, klass| create_file(name, klass, dir) }
59
+ true
122
60
  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
61
+ require_classes(classes_list) if options[:load_classes]
62
+ classes_list
132
63
  end
133
64
  end
134
65
 
135
- private
136
-
137
66
  def create_file(name, content, dir)
67
+ name = name.split(":").last
138
68
  File.write("#{dir}/#{Utils.snake_case(name)}.rb", content)
139
69
  end
140
70
 
141
71
  def require_classes(classes_hash)
142
72
  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
73
+ classes_hash.each { |name, klass| create_file(name, klass, dir) }
74
+ # Some files are not created at the time of the require, so we need to require them after all the files are created.
75
+ classes_hash.each_key { |name| require "#{dir}/#{Utils.snake_case(name)}" }
147
76
  end
148
77
  end
149
78
 
150
- # START: STRUCTURE SETUP METHODS
151
-
152
79
  def as_models(schema, options: {})
153
80
  raise Error, XML_ADAPTER_NOT_SET_MESSAGE unless Config.xml_adapter.name.end_with?("NokogiriAdapter")
154
81
 
@@ -161,9 +88,17 @@ module Lutaml
161
88
  @complex_types = MappingHash.new
162
89
  @attribute_groups = MappingHash.new
163
90
 
91
+ populate_default_values
164
92
  schema_to_models(Array(parsed_schema))
165
93
  end
166
94
 
95
+ def populate_default_values
96
+ XML_DEFINED_ATTRIBUTES.each do |name, value|
97
+ @attributes[name] = Attribute.new(name: name)
98
+ @attributes[name].type = value
99
+ end
100
+ end
101
+
167
102
  def schema_to_models(schemas)
168
103
  return if schemas.empty?
169
104
 
@@ -171,12 +106,12 @@ module Lutaml
171
106
  schema_to_models(schema.include) if schema.include&.any?
172
107
  schema_to_models(schema.import) if schema.import&.any?
173
108
  resolved_element_order(schema).each do |order_item|
174
- item_name = order_item&.name
109
+ item_name = order_item.name if order_item.respond_to?(:name)
175
110
  case order_item
176
111
  when Xsd::SimpleType
177
112
  @simple_types[item_name] = setup_simple_type(order_item)
178
113
  when Xsd::Group
179
- @group_types[item_name] = setup_group_type(order_item)
114
+ @group_types[item_name] = setup_group_type(order_item, root_call: true)
180
115
  when Xsd::ComplexType
181
116
  @complex_types[item_name] = setup_complex_type(order_item)
182
117
  when Xsd::Element
@@ -192,20 +127,37 @@ module Lutaml
192
127
  end
193
128
 
194
129
  def setup_simple_type(simple_type)
195
- MappingHash.new.tap do |hash|
196
- setup_restriction(simple_type.restriction, hash) if simple_type&.restriction
197
- hash[:union] = setup_union(simple_type.union) if simple_type.union
130
+ SimpleType.new(simple_type.name).tap do |type_object|
131
+ if union = simple_type.union
132
+ type_object.unions = union.member_types.split
133
+ elsif restriction = simple_type.restriction
134
+ type_object.base_class = restriction.base&.split(":")&.last
135
+ type_object.instance = setup_restriction(restriction)
136
+ end
198
137
  end
199
138
  end
200
139
 
201
- def restriction_content(hash, restriction)
202
- return hash unless restriction.respond_to?(:max_length)
140
+ def restriction_content(instance, restriction)
141
+ return instance unless restriction.respond_to?(:max_length)
142
+
143
+ restriction_min_max(restriction, instance, field: :max_length, value_method: :min)
144
+ restriction_min_max(restriction, instance, field: :min_length, value_method: :max)
145
+ restriction_min_max(restriction, instance, field: :min_inclusive, value_method: :max)
146
+ restriction_min_max(restriction, instance, field: :max_inclusive, value_method: :min)
147
+ restriction_min_max(restriction, instance, field: :max_exclusive, value_method: :max)
148
+ restriction_min_max(restriction, instance, field: :min_exclusive, value_method: :min)
149
+ instance.length = restriction_length(restriction.length) if restriction.length&.any?
150
+ end
151
+
152
+ # Use min/max to get the value from the field_value array.
153
+ def restriction_min_max(restriction, instance, field:, value_method: :min)
154
+ field_value = restriction.public_send(field)
155
+ return unless field_value&.any?
203
156
 
204
- hash[:max_length] = restriction.max_length.map(&:value).min if restriction.max_length&.any?
205
- hash[:min_length] = restriction.min_length.map(&:value).max if restriction.min_length&.any?
206
- hash[:min_inclusive] = restriction.min_inclusive.map(&:value).max if restriction.min_inclusive&.any?
207
- hash[:max_inclusive] = restriction.max_inclusive.map(&:value).min if restriction.max_inclusive&.any?
208
- hash[:length] = restriction_length(restriction.length) if restriction.length&.any?
157
+ instance.public_send(
158
+ :"#{field}=",
159
+ field_value.map(&:value).send(value_method).to_s,
160
+ )
209
161
  end
210
162
 
211
163
  def restriction_length(lengths)
@@ -218,215 +170,220 @@ module Lutaml
218
170
  end
219
171
 
220
172
  def setup_complex_type(complex_type)
221
- MappingHash.new.tap do |hash|
222
- hash[:attributes] = [] if complex_type.attribute&.any?
223
- hash[:attribute_groups] = [] if complex_type.attribute_group&.any?
224
- hash[:mixed] = complex_type.mixed
173
+ ComplexType.new.tap do |instance|
174
+ instance.id = complex_type.id
175
+ instance.name = complex_type.name
176
+ instance.mixed = complex_type.mixed
225
177
  resolved_element_order(complex_type).each do |element|
226
178
  case element
227
179
  when Xsd::Attribute
228
- hash[:attributes] << setup_attribute(element)
180
+ instance << setup_attribute(element)
229
181
  when Xsd::Sequence
230
- hash[:sequence] = setup_sequence(element)
182
+ instance << setup_sequence(element)
231
183
  when Xsd::Choice
232
- hash[:choice] = setup_choice(element)
184
+ instance << setup_choice(element)
233
185
  when Xsd::ComplexContent
234
- hash[:complex_content] = setup_complex_content(element)
186
+ instance << setup_complex_content(element, instance.name, instance)
235
187
  when Xsd::AttributeGroup
236
- hash[:attribute_groups] << setup_attribute_groups(element)
188
+ instance << setup_attribute_groups(element)
237
189
  when Xsd::Group
238
- hash[:group] = setup_group_type(element)
190
+ instance << setup_group_type(element)
239
191
  when Xsd::SimpleContent
240
- hash[:simple_content] = setup_simple_content(element)
192
+ instance.simple_content = setup_simple_content(element)
241
193
  end
242
194
  end
243
195
  end
244
196
  end
245
197
 
246
198
  def setup_simple_content(simple_content)
247
- if simple_content.extension
248
- setup_extension(simple_content.extension)
249
- elsif simple_content.restriction
250
- setup_restriction(simple_content.restriction, {})
199
+ SimpleContent.new.tap do |instance|
200
+ if simple_content.extension
201
+ instance.base_class = simple_content.extension.base
202
+ setup_extension(simple_content.extension, instance)
203
+ elsif simple_content.restriction
204
+ instance.base_class = simple_content.restriction.base
205
+ instance << setup_restriction(simple_content.restriction)
206
+ end
251
207
  end
252
208
  end
253
209
 
254
210
  def setup_sequence(sequence)
255
- MappingHash.new.tap do |hash|
256
- hash[:sequences] = [] if sequence.sequence&.any?
257
- hash[:elements] = [] if sequence.element&.any?
258
- hash[:choice] = [] if sequence.choice&.any?
259
- hash[:groups] = [] if sequence.group&.any?
260
- resolved_element_order(sequence).each do |instance|
261
- case instance
262
- when Xsd::Sequence
263
- hash[:sequences] << setup_sequence(instance)
264
- when Xsd::Element
265
- hash[:elements] << if instance.name
266
- setup_element(instance)
267
- else
268
- create_mapping_hash(instance.ref, hash_key: :ref_class)
269
- end
270
- when Xsd::Choice
271
- hash[:choice] << setup_choice(instance)
272
- when Xsd::Group
273
- hash[:groups] << if instance.name
274
- setup_group_type(instance)
275
- else
276
- create_mapping_hash(instance.ref, hash_key: :ref_class)
277
- end
278
- when Xsd::Any
279
- # No implementation yet!
280
- end
211
+ Sequence.new.tap do |instance|
212
+ resolved_element_order(sequence).each do |object|
213
+ # No implementation yet for Xsd::Any!
214
+ next if object.is_a?(Xsd::Any)
215
+
216
+ instance << case object
217
+ when Xsd::Sequence
218
+ setup_sequence(object)
219
+ when Xsd::Element
220
+ setup_element(object)
221
+ when Xsd::Choice
222
+ setup_choice(object)
223
+ when Xsd::Group
224
+ setup_group_type(object)
225
+ end
281
226
  end
282
227
  end
283
228
  end
284
229
 
285
- def setup_group_type(group)
286
- MappingHash.new.tap do |hash|
287
- if group.ref
288
- hash[:ref_class] = group.ref
289
- else
290
- resolved_element_order(group).map do |instance|
291
- case instance
292
- when Xsd::Sequence
293
- hash[:sequence] = setup_sequence(instance)
294
- when Xsd::Choice
295
- hash[:choice] = setup_choice(instance)
296
- end
297
- end
298
- end
230
+ def setup_group_type(group, root_call: false)
231
+ object = Group.new(group.name, group.ref)
232
+ object.instance = setup_group_type_instance(group)
233
+ @group_types[group.name] = object if group.name && !root_call
234
+ object
235
+ end
236
+
237
+ def setup_group_type_instance(group)
238
+ if sequence = group.sequence
239
+ setup_sequence(sequence)
240
+ elsif choice = group.choice
241
+ setup_choice(choice)
299
242
  end
300
243
  end
301
244
 
302
245
  def setup_choice(choice)
303
- MappingHash.new.tap do |hash|
246
+ Choice.new.tap do |instance|
247
+ instance.min_occurs = choice.min_occurs
248
+ instance.max_occurs = choice.max_occurs
304
249
  resolved_element_order(choice).each do |element|
305
- case element
306
- when Xsd::Element
307
- element_name = element.name || @elements[element.ref.split(":").last]&.element_name
308
- hash[element_name] = setup_element(element)
309
- when Xsd::Sequence
310
- hash[:sequence] = setup_sequence(element)
311
- when Xsd::Group
312
- hash[:group] = setup_group_type(element)
313
- when Xsd::Choice
314
- hash[:choice] = setup_choice(element)
315
- end
250
+ instance << case element
251
+ when Xsd::Element
252
+ setup_element(element)
253
+ when Xsd::Sequence
254
+ setup_sequence(element)
255
+ when Xsd::Group
256
+ setup_group_type(element)
257
+ when Xsd::Choice
258
+ setup_choice(element)
259
+ end
316
260
  end
317
261
  end
318
262
  end
319
263
 
320
- def setup_union(union)
321
- union.member_types.split.map do |member_type|
322
- @simple_types[member_type]
323
- end.flatten
324
- end
325
-
326
264
  def setup_attribute(attribute)
327
- MappingHash.new.tap do |attr_hash|
328
- if attribute.ref
329
- attr_hash[:ref_class] = attribute.ref
330
- else
331
- attr_hash[:name] = attribute.name
332
- attr_hash[:base_class] = attribute.type
333
- attr_hash[:default] = attribute.default if attribute.default
334
- end
265
+ instance = Attribute.new(name: attribute.name, ref: attribute.ref)
266
+ if attribute.name
267
+ instance.type = setup_attribute_type(attribute)
268
+ instance.default = attribute.default
335
269
  end
270
+ instance
271
+ end
272
+
273
+ def setup_attribute_type(attribute)
274
+ return attribute.type if attribute.type
275
+
276
+ simple_type = attribute.simple_type
277
+ attr_name = "ST_#{attribute.name}"
278
+ simple_type.name = attr_name
279
+ @simple_types[attr_name] = setup_simple_type(simple_type)
280
+ attr_name
336
281
  end
337
282
 
338
283
  def setup_attribute_groups(attribute_group)
339
- MappingHash.new.tap do |hash|
340
- if attribute_group.ref
341
- hash[:ref_class] = attribute_group.ref
342
- else
343
- hash[:attributes] = [] if attribute_group.attribute&.any?
344
- hash[:attribute_groups] = [] if attribute_group.attribute_group&.any?
345
- resolved_element_order(attribute_group).each do |instance|
346
- case instance
347
- when Xsd::Attribute
348
- hash[:attributes] << setup_attribute(instance)
349
- when Xsd::AttributeGroup
350
- hash[:attribute_groups] << setup_attribute_groups(instance)
351
- end
352
- end
284
+ instance = AttributeGroup.new(name: attribute_group.name, ref: attribute_group.ref)
285
+ if attribute_group.name
286
+ resolved_element_order(attribute_group).each do |object|
287
+ group_attribute = case object
288
+ when Xsd::Attribute
289
+ setup_attribute(object)
290
+ when Xsd::AttributeGroup
291
+ setup_attribute_groups(object)
292
+ end
293
+ instance << group_attribute if group_attribute
353
294
  end
354
295
  end
296
+ instance
355
297
  end
356
298
 
357
- def create_mapping_hash(value, hash_key: :class_name)
358
- MappingHash.new.tap do |hash|
359
- hash[hash_key] = value
299
+ def setup_element(element)
300
+ element_name = element.name
301
+ instance = Element.new(name: element_name, ref: element.ref)
302
+ instance.min_occurs = element.min_occurs
303
+ instance.max_occurs = element.max_occurs
304
+ if element_name
305
+ instance.type = setup_element_type(element, instance)
306
+ instance.id = element.id
307
+ instance.fixed = element.fixed
308
+ instance.default = element.default
360
309
  end
310
+ instance
361
311
  end
362
312
 
363
- def setup_element(element)
364
- MappingHash.new.tap do |hash|
365
- if element.ref
366
- hash[:ref_class] = element.ref
367
- else
368
- hash[:type_name] = element.type
369
- hash[:element_name] = element.name
370
- element_arguments(element, hash)
371
- return hash unless complex_type = element.complex_type
372
-
373
- hash[:complex_type] = setup_complex_type(complex_type)
374
- @complex_types[complex_type.name] = hash[:complex_type]
313
+ # Populates @simple_types or @complex_types based on elements available value.
314
+ def setup_element_type(element, _instance)
315
+ return element.type if element.type
316
+
317
+ type, prefix = element.simple_type ? ["simple", "ST"] : ["complex", "CT"]
318
+ type_instance = element.public_send(:"#{type}_type")
319
+ type_instance.name = [prefix, element.name].join("_")
320
+ instance_variable_get(:"@#{type}_types")[type_instance.name] = public_send(:"setup_#{type}_type", type_instance)
321
+ type_instance.name
322
+ end
323
+
324
+ def setup_restriction(restriction)
325
+ Restriction.new.tap do |instance|
326
+ instance.base_class = restriction.base
327
+ restriction_patterns(restriction.pattern, instance) if restriction.respond_to?(:pattern)
328
+ restriction_content(instance, restriction)
329
+ if restriction.respond_to?(:enumeration) && restriction.enumeration&.any?
330
+ instance.enumerations = restriction.enumeration.map(&:value)
375
331
  end
376
332
  end
377
333
  end
378
334
 
379
- def setup_restriction(restriction, hash)
380
- hash[:base_class] = restriction.base
381
- restriction_patterns(restriction.pattern, hash) if restriction.respond_to?(:pattern)
382
- restriction_content(hash, restriction)
383
- return hash unless restriction.respond_to?(:enumeration) && restriction.enumeration&.any?
384
-
385
- hash[:values] = restriction.enumeration.map(&:value)
386
- hash
335
+ def setup_complex_content_restriction(restriction, compiler_complex_type)
336
+ ComplexContentRestriction.new.tap do |instance|
337
+ compiler_complex_type.base_class = restriction.base
338
+ resolved_element_order(restriction).each do |element|
339
+ instance << case element
340
+ when Xsd::Attribute
341
+ setup_attribute(element)
342
+ when Xsd::AttributeGroup
343
+ setup_attribute_groups(element)
344
+ when Xsd::Sequence
345
+ setup_sequence(element)
346
+ when Xsd::Choice
347
+ setup_choice(element)
348
+ when Xsd::Group
349
+ setup_group_type(element)
350
+ end
351
+ end
352
+ end
387
353
  end
388
354
 
389
- def restriction_patterns(patterns, hash)
355
+ def restriction_patterns(patterns, instance)
390
356
  return if Utils.blank?(patterns)
391
357
 
392
- hash[:pattern] = patterns.map { |p| "(#{p.value})" }.join("|")
393
- hash
358
+ instance.pattern = patterns.map { |p| "(#{p.value})" }.join("|")
394
359
  end
395
360
 
396
- def setup_complex_content(complex_content)
397
- MappingHash.new.tap do |hash|
398
- hash[:mixed] = true if complex_content.mixed
399
- if complex_content.extension
400
- hash[:extension] = setup_extension(complex_content.extension)
361
+ def setup_complex_content(complex_content, name, compiler_complex_type)
362
+ @complex_types[name] = ComplexContent.new.tap do |instance|
363
+ compiler_complex_type.mixed = complex_content.mixed
364
+ if extension = complex_content.extension
365
+ setup_extension(extension, compiler_complex_type)
401
366
  elsif restriction = complex_content.restriction
402
- setup_restriction(restriction, hash)
403
- end
404
- end
405
- end
406
-
407
- def setup_extension(extension)
408
- MappingHash.new.tap do |hash|
409
- hash[:extension_base] = extension.base
410
- hash[:attribute_groups] = [] if extension&.attribute_group&.any?
411
- hash[:attributes] = [] if extension&.attribute&.any?
412
- resolved_element_order(extension).each do |element|
413
- case element
414
- when Xsd::Attribute
415
- hash[:attributes] << setup_attribute(element)
416
- when Xsd::Sequence
417
- hash[:sequence] = setup_sequence(element)
418
- when Xsd::Choice
419
- hash[:choice] = setup_choice(element)
420
- end
367
+ instance.restriction = setup_complex_content_restriction(restriction, compiler_complex_type)
421
368
  end
422
369
  end
423
370
  end
424
371
 
425
- def element_arguments(element, element_hash)
426
- MappingHash.new.tap do |hash|
427
- hash[:min_occurs] = element.min_occurs if element.min_occurs
428
- hash[:max_occurs] = element.max_occurs if element.max_occurs
429
- element_hash[:arguments] = hash if hash&.any?
372
+ def setup_extension(extension, instance)
373
+ instance.base_class = extension.base
374
+ resolved_element_order(extension).each do |element|
375
+ instance << case element
376
+ when Xsd::Attribute
377
+ setup_attribute(element)
378
+ when Xsd::AttributeGroup
379
+ setup_attribute_groups(element)
380
+ when Xsd::Sequence
381
+ setup_sequence(element)
382
+ when Xsd::Choice
383
+ setup_choice(element)
384
+ when Xsd::Group
385
+ setup_group_type(element)
386
+ end
430
387
  end
431
388
  end
432
389
 
@@ -434,8 +391,7 @@ module Lutaml
434
391
  return [] if object.element_order.nil?
435
392
 
436
393
  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)
394
+ next array.delete(builder_instance) if builder_instance.text? || ELEMENT_ORDER_IGNORABLE.include?(builder_instance.name)
439
395
 
440
396
  index = 0
441
397
  array.each_with_index do |element, i|
@@ -446,318 +402,6 @@ module Lutaml
446
402
  end
447
403
  end
448
404
  end
449
-
450
- # END: STRUCTURE SETUP METHODS
451
-
452
- # START: TEMPLATE RESOLVER METHODS
453
- def resolve_parent_class(content)
454
- return "Lutaml::Model::Serializable" unless content.dig(:complex_content, :extension)
455
-
456
- Utils.camel_case(content.dig(:complex_content, :extension, :extension_base))
457
- end
458
-
459
- def resolve_attribute_class(attribute)
460
- attr_class = attribute.base_class.split(":")&.last
461
- case attr_class
462
- when *DEFAULT_CLASSES
463
- ":#{attr_class}"
464
- else
465
- Utils.camel_case(attr_class)
466
- end
467
- end
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
-
479
- def resolve_occurs(arguments)
480
- min_occurs = arguments[:min_occurs]
481
- max_occurs = arguments[:max_occurs]
482
- max_occurs = max_occurs.to_s&.match?(/[A-Za-z]+/) ? nil : max_occurs.to_i if max_occurs
483
- ", collection: #{max_occurs ? min_occurs.to_i..max_occurs : true}"
484
- end
485
-
486
- def resolve_content(content, hash = MappingHash.new)
487
- content.each do |key, value|
488
- case key
489
- when :sequence
490
- resolve_sequence(value, hash)
491
- when :choice
492
- resolve_choice(value, hash)
493
- when :group
494
- resolve_group(value, hash)
495
- end
496
- end
497
- hash
498
- end
499
-
500
- def resolve_elements(elements, hash = MappingHash.new)
501
- elements.each do |element|
502
- if element.key?(:ref_class)
503
- new_element = @elements[element.ref_class.split(":").last]
504
- hash[new_element.element_name] = new_element
505
- else
506
- hash[element.element_name] = element
507
- end
508
- end
509
- hash
510
- end
511
-
512
- def resolve_sequence(sequence, hash = MappingHash.new)
513
- sequence.each do |key, value|
514
- case key
515
- when :sequence
516
- resolve_sequence(value, hash)
517
- when :elements
518
- resolve_elements(value, hash)
519
- when :groups
520
- value.each { |group| resolve_group(group, hash) }
521
- when :choice
522
- value.each { |choice| resolve_choice(choice, hash) }
523
- end
524
- end
525
- hash
526
- end
527
-
528
- def resolve_choice(choice, hash = MappingHash.new)
529
- choice.each do |key, value|
530
- case key
531
- when :element
532
- [resolve_elements(value, hash)]
533
- when :group
534
- resolve_group(value, hash)
535
- when String
536
- hash[key] = value
537
- when :sequence
538
- resolve_sequence(value, hash)
539
- end
540
- end
541
- hash
542
- end
543
-
544
- def resolve_group(group, hash = MappingHash.new)
545
- group.each do |key, value|
546
- case key
547
- when :ref_class
548
- resolve_group(@group_types[value.split(":").last], hash)
549
- when :choice
550
- resolve_choice(value, hash)
551
- when :group
552
- resolve_group(value, hash)
553
- when :sequence
554
- resolve_sequence(value, hash)
555
- end
556
- end
557
- hash
558
- end
559
-
560
- def resolve_complex_content(complex_content, hash = MappingHash.new)
561
- complex_content.each do |key, value|
562
- case key
563
- when :extension
564
- resolve_extension(value, hash)
565
- when :restriction
566
- # TODO: No implementation yet!
567
- hash
568
- end
569
- end
570
- hash
571
- end
572
-
573
- def resolve_extension(extension, hash = MappingHash.new)
574
- hash[:attributes] = extension.attributes if extension.key?(:attributes)
575
- resolve_sequence(extension.sequence, hash) if extension.key?(:sequence)
576
- resolve_choice(extension.choice, hash) if extension.key?(:choice)
577
- hash
578
- end
579
-
580
- def resolve_attribute_default(attribute)
581
- klass = attribute.base_class.split(":").last
582
- default = attribute[:default]
583
- ", default: #{resolve_attribute_default_value(klass, default)}"
584
- end
585
-
586
- def resolve_attribute_default_value(klass, default)
587
- return default.inspect unless DEFAULT_CLASSES.include?(klass)
588
-
589
- klass = "integer" if klass == "int"
590
- type_klass = Lutaml::Model::Type.const_get(klass.capitalize)
591
- type_klass.cast(default)
592
- end
593
-
594
- def resolve_namespace(options)
595
- namespace_str = "namespace \"#{options[:namespace]}\"" if options.key?(:namespace)
596
- namespace_str += ", \"#{options[:prefix]}\"" if options.key?(:prefix) && options.key?(:namespace)
597
- namespace_str += "\n" if namespace_str
598
- namespace_str
599
- end
600
-
601
- def resolve_required_files(content)
602
- @required_files = []
603
- content.each do |key, value|
604
- case key
605
- when :sequence
606
- required_files_sequence(value)
607
- when :choice
608
- required_files_choice(value)
609
- when :group
610
- required_files_group(value)
611
- when :attributes
612
- required_files_attribute(value)
613
- when :attribute_groups
614
- value.each do |attribute_group|
615
- required_files_attribute_groups(attribute_group)
616
- end
617
- when :complex_content
618
- required_files_complex_content(value)
619
- when :simple_content
620
- required_files_simple_content(value)
621
- end
622
- end
623
- @required_files.uniq.sort_by(&:length)
624
- end
625
-
626
- # END: TEMPLATE RESOLVER METHODS
627
-
628
- # START: REQUIRED FILES LIST COMPILER METHODS
629
- def required_files_simple_content(simple_content)
630
- simple_content.each do |key, value|
631
- case key
632
- when :extension_base
633
- # Do nothing.
634
- when :attributes
635
- required_files_attribute(value)
636
- when :extension
637
- required_files_extension(value)
638
- when :restriction
639
- required_files_restriction(value)
640
- end
641
- end
642
- end
643
-
644
- def required_files_complex_content(complex_content)
645
- complex_content.each do |key, value|
646
- case key
647
- when :extension
648
- required_files_extension(value)
649
- when :restriction
650
- required_files_restriction(value)
651
- end
652
- end
653
- end
654
-
655
- def required_files_extension(extension)
656
- extension.each do |key, value|
657
- case key
658
- when :attribute_group
659
- required_files_attribute_groups(value)
660
- when :attribute, :attributes
661
- required_files_attribute(value)
662
- when :extension_base
663
- # Do nothing.
664
- when :sequence
665
- required_files_sequence(value)
666
- when :choice
667
- required_files_choice(value)
668
- end
669
- end
670
- end
671
-
672
- def required_files_restriction(restriction)
673
- restriction.each do |key, value|
674
- case key
675
- when :base
676
- @required_files << Utils.snake_case(value.split(":").last)
677
- end
678
- end
679
- end
680
-
681
- def required_files_attribute_groups(attr_groups)
682
- attr_groups.each do |key, value|
683
- case key
684
- when :ref_class
685
- required_files_attribute_groups(@attribute_groups[value.split(":").last])
686
- when :attribute, :attributes
687
- required_files_attribute(value)
688
- end
689
- end
690
- end
691
-
692
- def required_files_attribute(attributes)
693
- attributes.each do |attribute|
694
- next if attribute[:ref_class]&.start_with?("xml") || attribute[:base_class]&.start_with?("xml")
695
-
696
- attribute = @attributes[attribute.ref_class.split(":").last] if attribute.key_exist?(:ref_class)
697
- attr_class = attribute.base_class.split(":")&.last
698
- next if DEFAULT_CLASSES.include?(attr_class)
699
-
700
- @required_files << Utils.snake_case(attr_class)
701
- end
702
- end
703
-
704
- def required_files_choice(choice)
705
- choice.each do |key, value|
706
- case key
707
- when String
708
- value = @elements[value.ref_class.split(":").last] if value.key?(:ref_class)
709
- @required_files << Utils.snake_case(value.type_name.split(":").last)
710
- when :element
711
- required_files_elements(value)
712
- when :group
713
- required_files_group(value)
714
- when :choice
715
- required_files_choice(value)
716
- when :sequence
717
- required_files_sequence(value)
718
- end
719
- end
720
- end
721
-
722
- def required_files_group(group)
723
- group.each do |key, value|
724
- case key
725
- when :ref_class
726
- required_files_group(@group_types[value.split(":").last])
727
- when :choice
728
- required_files_choice(value)
729
- when :sequence
730
- required_files_sequence(value)
731
- end
732
- end
733
- end
734
-
735
- def required_files_sequence(sequence)
736
- sequence.each do |key, value|
737
- case key
738
- when :elements
739
- required_files_elements(value)
740
- when :sequence
741
- required_files_sequence(value)
742
- when :groups
743
- value.each { |group| required_files_group(group) }
744
- when :choice
745
- value.each { |choice| required_files_choice(choice) }
746
- end
747
- end
748
- end
749
-
750
- def required_files_elements(elements)
751
- elements.each do |element|
752
- element = @elements[element.ref_class.split(":").last] if element.key_exist?(:ref_class)
753
- element_class = element.type_name.split(":").last
754
- next if DEFAULT_CLASSES.include?(element_class)
755
-
756
- @required_files << Utils.snake_case(element_class)
757
- end
758
- end
759
-
760
- # END: REQUIRED FILES LIST COMPILER METHODS
761
405
  end
762
406
  end
763
407
  end