Module: Lutaml::Model::Serialize::Initialization
- Included in:
- ClassMethods
- Defined in:
- lib/lutaml/model/serialize/initialization.rb
Overview
Handles initialization and namespace methods for Serialize::ClassMethods
Extracted from serialize.rb to improve code organization. Provides methods for class initialization and namespace handling.
Instance Method Summary collapse
-
#add_custom_handling_methods_to_model(klass) ⇒ Object
Add custom handling methods to a model class.
-
#add_format_specific_model_methods(_klass) ⇒ Object
Hook for format-specific model methods.
-
#allocate_for_deserialization(register = nil) ⇒ Object
Allocate an instance for deserialization without calling initialize.
-
#attributes(register = nil) ⇒ Hash
Get all attributes for this model.
-
#cast(value) ⇒ Object
Cast a value (pass-through implementation).
-
#choice(min: 1, max: 1, format: nil, &block) ⇒ Object
Define a choice constraint.
-
#choice_attributes(register = nil) ⇒ Array
Get all choice attributes for this model.
-
#clear_cache(register_id = nil) ⇒ Object
Clear all cached data for this model class.
-
#deep_duplicate_choice_attributes(source_class, register = nil) ⇒ Array
Deep duplicate choice attributes from a source class.
-
#ensure_format_mapping_imports!(_register = nil) ⇒ Object
Hook for format-specific mapping import resolution.
-
#ensure_imports!(register = nil) ⇒ Object
Ensure all imports are resolved.
-
#ensure_register_methods_defined(register_id) ⇒ Object
Define register-specific attribute methods on the class itself.
-
#included(base) ⇒ Object
Handle inclusion by extending with ClassMethods.
-
#inherited(subclass) ⇒ Object
Handle inheritance by copying parent’s configuration.
-
#initialize_attrs(source_class) ⇒ Object
Initialize class attributes from a source class.
-
#lutaml_default_register ⇒ Symbol?
Get or set the default register for this Model class.
-
#model(klass = nil) ⇒ Class
Get or set the model class.
-
#namespace(_ns_class = nil) ⇒ Class?
Class-level namespace getter/setter.
-
#namespace_prefix ⇒ String?
Get the default namespace prefix for this Model.
-
#namespace_uri ⇒ String?
Get the namespace URI for this Model.
-
#register(name) ⇒ Symbol?
Convert register parameter to symbol.
-
#register_record(register_id = nil) ⇒ Hash?
Get the register record for a specific register ID.
-
#set_register_context(register_id) ⇒ void
Set the register context for this Model class.
Instance Method Details
#add_custom_handling_methods_to_model(klass) ⇒ Object
Add custom handling methods to a model class
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 210 def add_custom_handling_methods_to_model(klass) Utils.add_method_if_not_defined(klass, :using_default_for) do |attribute_name| @using_default ||= {} @using_default[attribute_name] = true end Utils.add_method_if_not_defined(klass, :value_set_for) do |attribute_name| @using_default ||= {} @using_default[attribute_name] = false end Utils.add_method_if_not_defined(klass, :using_default?) do |attribute_name| @using_default ||= {} !!@using_default[attribute_name] end # Hook for format-specific model methods (e.g., XML adds ordered, mixed, element_order) add_format_specific_model_methods(klass) end |
#add_format_specific_model_methods(_klass) ⇒ Object
Hook for format-specific model methods. XML overrides via FormatConversion prepend to add XML accessors.
237 238 239 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 237 def add_format_specific_model_methods(_klass) # No-op by default end |
#allocate_for_deserialization(register = nil) ⇒ Object
Allocate an instance for deserialization without calling initialize.
Skips the expensive initialize_attributes pass (which iterates all attributes to set defaults). The XML mapping pipeline sets values directly via rule.deserialize instead. Uses Hash.new(true) as the default for @using_default so that using_default? returns true for all attributes until value_set_for is called.
287 288 289 290 291 292 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 287 def allocate_for_deserialization(register = nil) instance = allocate register_id = extract_register_id(register) instance.finalize_deserialization(register_id) instance end |
#attributes(register = nil) ⇒ Hash
Get all attributes for this model
Merges class-level attributes with register-specific attributes.
121 122 123 124 125 126 127 128 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 121 def attributes(register = nil) ensure_imports!(register) if finalized? if @register_records&.any? @attributes.merge(@register_records[extract_register_id(register)][:attributes]) else @attributes end end |
#cast(value) ⇒ Object
Cast a value (pass-through implementation)
245 246 247 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 245 def cast(value) value end |
#choice(min: 1, max: 1, format: nil, &block) ⇒ Object
Define a choice constraint
254 255 256 257 258 259 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 254 def choice(min: 1, max: 1, format: nil, &block) @choice_attributes << Choice.new(self, min, max, format: format).tap do |c| c.instance_eval(&block) end end |
#choice_attributes(register = nil) ⇒ Array
Get all choice attributes for this model
Merges class-level choice attributes with register-specific choice attributes.
136 137 138 139 140 141 142 143 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 136 def choice_attributes(register = nil) ensure_imports!(register) if finalized? if @register_records&.any? @choice_attributes + @register_records[extract_register_id(register)][:choice_attributes] else @choice_attributes end end |
#clear_cache(register_id = nil) ⇒ Object
Clear all cached data for this model class
Centralized caching (Phase 11.5):
-
Type caches: GlobalContext.resolver
-
Mapping caches: TransformationRegistry
-
Transformation caches: TransformationRegistry
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 173 def clear_cache(register_id = nil) # Clear centralized type cache in GlobalContext.resolver if defined?(Lutaml::Model::GlobalContext) GlobalContext.resolver.clear_cache(register_id) end # Clear centralized mapping and transformation caches # (Single Source of Truth - no longer uses instance variables) TransformationRegistry.instance.clear # Clear Transform cache (uses class identity as key) Transform.invalidate_for(self, register_id) # Clear import resolution guard flags so imports can be re-resolved instance_variables.each do |ivar| ivar_s = ivar.to_s remove_instance_variable(ivar) if ivar_s.start_with?("@_imports_resolved_") || ivar_s == "@_register_methods_defined" end end |
#deep_duplicate_choice_attributes(source_class, register = nil) ⇒ Array
Deep duplicate choice attributes from a source class
108 109 110 111 112 113 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 108 def deep_duplicate_choice_attributes(source_class, register = nil) choice_attrs = Array(source_class.instance_variable_get(:@choice_attributes)) choice_attrs.map do |choice_attr| choice_attr.deep_duplicate(self, register) end end |
#ensure_format_mapping_imports!(_register = nil) ⇒ Object
Hook for format-specific mapping import resolution. Override in format modules (e.g., XML prepends to resolve XML mapping imports).
161 162 163 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 161 def ensure_format_mapping_imports!(_register = nil) # No-op by default; XML overrides via prepend end |
#ensure_imports!(register = nil) ⇒ Object
Ensure all imports are resolved
148 149 150 151 152 153 154 155 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 148 def ensure_imports!(register = nil) ensure_model_imports!(register) ensure_choice_imports!(register) ensure_restrict_attributes!(register) # Hook for format-specific mapping import resolution. # XML overrides this to call mappings[:xml]&.ensure_mappings_imported!(register) ensure_format_mapping_imports!(register) end |
#ensure_register_methods_defined(register_id) ⇒ Object
Define register-specific attribute methods on the class itself.
Called once per (class, register) combination. Replaces per-instance singleton class allocation with class-level method definitions, preserving Ruby’s inline method cache optimization.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 301 def ensure_register_methods_defined(register_id) return if register_id == :default @_register_methods_defined ||= {} return if @_register_methods_defined[register_id] reg_record = register_records[register_id] return unless reg_record default_attrs = instance_variable_get(:@attributes) || {} reg_record_attrs = reg_record[:attributes] || {} reg_record_attrs.each do |name, attr| next if default_attrs.key?(name) next if method_defined?(name, false) if attr.collection? define_collection_register_methods(name) else define_scalar_register_methods(name) end end @_register_methods_defined[register_id] = true end |
#included(base) ⇒ Object
Handle inclusion by extending with ClassMethods
84 85 86 87 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 84 def included(base) base.extend(ClassMethods) base.initialize_attrs(self) end |
#inherited(subclass) ⇒ Object
Handle inheritance by copying parent’s configuration
76 77 78 79 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 76 def inherited(subclass) super subclass.initialize_attrs(self) end |
#initialize_attrs(source_class) ⇒ Object
Initialize class attributes from a source class
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 92 def initialize_attrs(source_class) @mappings = Utils.deep_dup(source_class.instance_variable_get(:@mappings)) || {} @attributes = Utils.deep_dup(source_class.instance_variable_get(:@attributes)) || {} @choice_attributes = deep_duplicate_choice_attributes(source_class) @register_records = Utils.deep_dup( source_class.instance_variable_get(:@register_records), ) || ::Hash.new do |hash, key| hash[key] = { attributes: {}, choice_attributes: [] } end instance_variable_set(:@model, self) end |
#lutaml_default_register ⇒ Symbol?
Get or set the default register for this Model class.
Override in subclasses to specify a preferred default register context. This allows versioned schemas (e.g., MML v2, v3) to use their own register by default when instances are created without explicit register.
69 70 71 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 69 def lutaml_default_register nil end |
#model(klass = nil) ⇒ Class
Get or set the model class
198 199 200 201 202 203 204 205 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 198 def model(klass = nil) if klass @model = klass add_custom_handling_methods_to_model(klass) else @model end end |
#namespace(_ns_class = nil) ⇒ Class?
Class-level namespace getter/setter.
No-op by default. When XML format is loaded, this is overridden via prepend to provide XML namespace handling.
18 19 20 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 18 def namespace(_ns_class = nil) @namespace_class end |
#namespace_prefix ⇒ String?
Get the default namespace prefix for this Model
32 33 34 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 32 def namespace_prefix nil end |
#namespace_uri ⇒ String?
Get the namespace URI for this Model
25 26 27 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 25 def namespace_uri nil end |
#register(name) ⇒ Symbol?
Convert register parameter to symbol
273 274 275 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 273 def register(name) name&.to_sym end |
#register_record(register_id = nil) ⇒ Hash?
Get the register record for a specific register ID
265 266 267 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 265 def register_record(register_id = nil) register_records[extract_register_id(register_id)] end |
#set_register_context(register_id) ⇒ void
This method returns an undefined value.
Set the register context for this Model class.
This is called by Register#register_model to ensure the class knows its register context for proper instance initialization.
43 44 45 46 47 |
# File 'lib/lutaml/model/serialize/initialization.rb', line 43 def set_register_context(register_id) return if instance_variable_defined?(:@register) @register = register_id end |