Class: Lutaml::Model::GlobalContext
- Inherits:
-
Object
- Object
- Lutaml::Model::GlobalContext
- Includes:
- Singleton
- Defined in:
- lib/lutaml/model/global_context.rb
Overview
GlobalContext provides global state management and context coordination.
Architecture Overview:
- Register: User-facing API for type registration (primary user interface)
- GlobalRegister: User-facing API for register management
- GlobalContext: Internal coordinator for context management
Users typically interact with Register and GlobalRegister. GlobalContext is used internally and for advanced use cases.
This class:
- Manages named contexts via ContextRegistry
- Provides type resolution via CachedTypeResolver
- Manages imports via ImportRegistry
- Manages format-specific registries (e.g., XML namespace registry)
- Provides
reset!for test isolation - Provides
with_contextfor scoped operations
Constant Summary collapse
- THREAD_CONTEXT_KEY =
Thread-local storage for context switching
:lutaml_model_context
Instance Attribute Summary collapse
-
#default_context_id ⇒ Symbol
The current default context ID.
-
#format_registries ⇒ Hash{Symbol => Object}
readonly
Format-specific registries.
-
#imports ⇒ ImportRegistry
readonly
The import registry.
-
#namespace_register_map ⇒ Hash{String => Symbol}
readonly
Namespace URI to register ID mapping.
-
#registry ⇒ ContextRegistry
readonly
The context registry.
-
#resolver ⇒ CachedTypeResolver
readonly
The cached type resolver.
Instance Method Summary collapse
-
#bind_register_to_namespace(register_id, namespace_uri) ⇒ void
Bind a register to a namespace URI.
-
#clear_caches ⇒ void
Clear caches only (keep registrations).
-
#clear_format_registry!(format) ⇒ void
Clear a specific format registry.
-
#clear_xml_namespace_registry! ⇒ void
Backward-compatible clear for XML namespace registry.
-
#context(id = nil) ⇒ TypeContext
Get a context by ID, or the default if no ID provided.
-
#context_generation ⇒ Integer
Bumped whenever a named context is registered, replaced, unregistered, or the registry is reset.
-
#create_context(id:, registry: nil, fallback_to: [], substitutions: []) ⇒ TypeContext
Create and register a new context.
-
#default_context ⇒ TypeContext
Get the current default context.
-
#format_registry_for(format) ⇒ Object?
Get a format-specific registry.
-
#initialize ⇒ GlobalContext
constructor
Initialize the GlobalContext with default components.
-
#register_context(context) ⇒ void
Register a context.
-
#register_for_namespace(namespace_uri) ⇒ Register?
Get register for a namespace URI.
-
#register_format_registry(format, registry) ⇒ void
Register a format-specific registry.
-
#register_id_for_namespace(namespace_uri) ⇒ Symbol?
Get register ID for a namespace URI.
-
#reset! ⇒ void
Reset ALL global state (for testing).
-
#resolvable?(name, context_id = nil) ⇒ Boolean
Check if a type is resolvable.
-
#resolve_type(name, context_id = nil) ⇒ Class
Resolve a type name to a class using the default context.
-
#resolve_type_with_namespace(type_name, namespace_uri = nil, context_id = nil) ⇒ Class?
Resolve type using namespace-aware lookup.
-
#stats ⇒ Hash
Get statistics about the global context.
-
#unregister_context(id) ⇒ TypeContext?
Unregister a context and clear its caches.
-
#with_context(context_id) { ... } ⇒ Object
Execute a block with a specific context as default.
-
#xml_namespace_registry ⇒ Object?
Backward-compatible accessor for XML namespace registry.
Constructor Details
#initialize ⇒ GlobalContext
Initialize the GlobalContext with default components.
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/lutaml/model/global_context.rb', line 59 def initialize @registry = ContextRegistry.new @resolver = CachedTypeResolver.new(delegate: TypeResolver) @imports = ImportRegistry.new @format_registries = {} @default_context_id = :default @namespace_register_map = {} # namespace_uri => register_id @mutex = Mutex.new @context_generation = 0 end |
Instance Attribute Details
#default_context_id ⇒ Symbol
Returns The current default context ID.
47 48 49 |
# File 'lib/lutaml/model/global_context.rb', line 47 def default_context_id @default_context_id end |
#format_registries ⇒ Hash{Symbol => Object} (readonly)
Returns Format-specific registries.
53 54 55 |
# File 'lib/lutaml/model/global_context.rb', line 53 def format_registries @format_registries end |
#imports ⇒ ImportRegistry (readonly)
Returns The import registry.
44 45 46 |
# File 'lib/lutaml/model/global_context.rb', line 44 def imports @imports end |
#namespace_register_map ⇒ Hash{String => Symbol} (readonly)
Returns Namespace URI to register ID mapping.
50 51 52 |
# File 'lib/lutaml/model/global_context.rb', line 50 def namespace_register_map @namespace_register_map end |
#registry ⇒ ContextRegistry (readonly)
Returns The context registry.
38 39 40 |
# File 'lib/lutaml/model/global_context.rb', line 38 def registry @registry end |
#resolver ⇒ CachedTypeResolver (readonly)
Returns The cached type resolver.
41 42 43 |
# File 'lib/lutaml/model/global_context.rb', line 41 def resolver @resolver end |
Instance Method Details
#bind_register_to_namespace(register_id, namespace_uri) ⇒ void
This method returns an undefined value.
Bind a register to a namespace URI.
This enables reverse lookup: given a namespace URI, find the register.
294 295 296 297 298 |
# File 'lib/lutaml/model/global_context.rb', line 294 def bind_register_to_namespace(register_id, namespace_uri) @mutex.synchronize do @namespace_register_map[namespace_uri] = register_id.to_sym end end |
#clear_caches ⇒ void
This method returns an undefined value.
Clear caches only (keep registrations).
214 215 216 217 218 |
# File 'lib/lutaml/model/global_context.rb', line 214 def clear_caches @resolver.clear_all_caches Register.clear_resolve_cache Transform.clear_cache! end |
#clear_format_registry!(format) ⇒ void
This method returns an undefined value.
Clear a specific format registry.
248 249 250 251 |
# File 'lib/lutaml/model/global_context.rb', line 248 def clear_format_registry!(format) reg = @format_registries[format] reg&.clear! if reg.is_a?(FormatRegistry) end |
#clear_xml_namespace_registry! ⇒ void
This method returns an undefined value.
Backward-compatible clear for XML namespace registry.
264 265 266 |
# File 'lib/lutaml/model/global_context.rb', line 264 def clear_xml_namespace_registry! clear_format_registry!(:xml) end |
#context(id = nil) ⇒ TypeContext
Get a context by ID, or the default if no ID provided.
103 104 105 106 107 108 109 |
# File 'lib/lutaml/model/global_context.rb', line 103 def context(id = nil) if id @registry.lookup(id.to_sym) else default_context end end |
#context_generation ⇒ Integer
Bumped whenever a named context is registered, replaced, unregistered, or the registry is reset. Callers that cache a resolution keyed on a context ID compare this generation to invalidate — a replaced context under the same ID must not keep answering from a stale cache.
77 78 79 |
# File 'lib/lutaml/model/global_context.rb', line 77 def context_generation @context_generation end |
#create_context(id:, registry: nil, fallback_to: [], substitutions: []) ⇒ TypeContext
Create and register a new context.
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/lutaml/model/global_context.rb', line 151 def create_context(id:, registry: nil, fallback_to: [], substitutions: []) context = @registry.create( id: id, registry: registry, fallback_to: fallback_to, substitutions: substitutions, ) @context_generation += 1 context end |
#default_context ⇒ TypeContext
Get the current default context.
84 85 86 87 |
# File 'lib/lutaml/model/global_context.rb', line 84 def default_context context_id = Thread.current[THREAD_CONTEXT_KEY] || @default_context_id @registry.lookup(context_id) || @registry.lookup(:default) end |
#format_registry_for(format) ⇒ Object?
Get a format-specific registry.
240 241 242 |
# File 'lib/lutaml/model/global_context.rb', line 240 def format_registry_for(format) @format_registries[format] end |
#register_context(context) ⇒ void
This method returns an undefined value.
Register a context.
136 137 138 139 140 141 142 |
# File 'lib/lutaml/model/global_context.rb', line 136 def register_context(context) @registry.register(context) # A replacement under an existing id must not keep answering from # the resolver's [context.id, name]-keyed cache. @resolver.clear_cache(context.id) @context_generation += 1 end |
#register_for_namespace(namespace_uri) ⇒ Register?
Get register for a namespace URI.
314 315 316 317 318 319 |
# File 'lib/lutaml/model/global_context.rb', line 314 def register_for_namespace(namespace_uri) register_id = @namespace_register_map[namespace_uri] return nil unless register_id GlobalRegister.lookup(register_id) end |
#register_format_registry(format, registry) ⇒ void
This method returns an undefined value.
Register a format-specific registry. Format plugins call this at load time to register their registries.
230 231 232 233 234 |
# File 'lib/lutaml/model/global_context.rb', line 230 def register_format_registry(format, registry) @mutex.synchronize do @format_registries[format] = registry end end |
#register_id_for_namespace(namespace_uri) ⇒ Symbol?
Get register ID for a namespace URI.
305 306 307 |
# File 'lib/lutaml/model/global_context.rb', line 305 def register_id_for_namespace(namespace_uri) @namespace_register_map[namespace_uri] end |
#reset! ⇒ void
This method returns an undefined value.
Reset ALL global state (for testing).
This clears:
- All non-default contexts
- All type resolution caches
- All pending imports
- All format-specific registries
- All namespace-register mappings
197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/lutaml/model/global_context.rb', line 197 def reset! @mutex.synchronize do @registry.clear @resolver.clear_all_caches @imports.reset! @format_registries.each_value do |reg| reg.clear! if reg.is_a?(FormatRegistry) end @namespace_register_map.clear @default_context_id = :default @context_generation += 1 end end |
#resolvable?(name, context_id = nil) ⇒ Boolean
Check if a type is resolvable.
127 128 129 130 |
# File 'lib/lutaml/model/global_context.rb', line 127 def resolvable?(name, context_id = nil) ctx = context(context_id) @resolver.resolvable?(name, ctx) end |
#resolve_type(name, context_id = nil) ⇒ Class
Resolve a type name to a class using the default context.
117 118 119 120 |
# File 'lib/lutaml/model/global_context.rb', line 117 def resolve_type(name, context_id = nil) ctx = context(context_id) @resolver.resolve(name, ctx) end |
#resolve_type_with_namespace(type_name, namespace_uri = nil, context_id = nil) ⇒ Class?
Resolve type using namespace-aware lookup.
If a namespace is specified and a register is bound to that namespace, uses that register for type resolution. Falls back to standard resolution.
331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/lutaml/model/global_context.rb', line 331 def resolve_type_with_namespace(type_name, namespace_uri = nil, context_id = nil) # If namespace specified, try namespace-aware resolution if namespace_uri register = register_for_namespace(namespace_uri) if register result = register.resolve_in_namespace(type_name, namespace_uri) return result if result end end # Fallback to standard resolution resolve_type(type_name, context_id) end |
#stats ⇒ Hash
Get statistics about the global context.
271 272 273 274 275 276 277 278 279 280 |
# File 'lib/lutaml/model/global_context.rb', line 271 def stats { contexts: @registry.context_ids, default_context_id: @default_context_id, resolver_cache_size: @resolver.cache_stats[:size], imports: @imports.stats, format_registries: @format_registries.keys, namespace_register_map_size: @namespace_register_map.size, } end |
#unregister_context(id) ⇒ TypeContext?
Unregister a context and clear its caches.
166 167 168 169 170 |
# File 'lib/lutaml/model/global_context.rb', line 166 def unregister_context(id) @resolver.clear_cache(id) @registry.unregister(id) @context_generation += 1 end |
#with_context(context_id) { ... } ⇒ Object
Execute a block with a specific context as default.
177 178 179 180 181 182 183 184 185 |
# File 'lib/lutaml/model/global_context.rb', line 177 def with_context(context_id) previous = Thread.current[THREAD_CONTEXT_KEY] Thread.current[THREAD_CONTEXT_KEY] = context_id.to_sym begin yield ensure Thread.current[THREAD_CONTEXT_KEY] = previous end end |
#xml_namespace_registry ⇒ Object?
Backward-compatible accessor for XML namespace registry. Delegates to the generic format_registries hash.
257 258 259 |
# File 'lib/lutaml/model/global_context.rb', line 257 def xml_namespace_registry @format_registries[:xml] end |