Class: Lutaml::Model::GlobalContext

Inherits:
Object
  • Object
show all
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_context for scoped operations

Examples:

Test isolation

GlobalContext.reset!  # Clears ALL caches and non-default contexts

Thread-safe context switching

GlobalContext.with_context(:my_app) do
  # Code here uses :my_app as default context
end

See Also:

Constant Summary collapse

THREAD_CONTEXT_KEY =

Thread-local storage for context switching

:lutaml_model_context

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGlobalContext

Initialize the GlobalContext with default components.



59
60
61
62
63
64
65
66
67
# 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
end

Instance Attribute Details

#default_context_idSymbol



47
48
49
# File 'lib/lutaml/model/global_context.rb', line 47

def default_context_id
  @default_context_id
end

#format_registriesHash{Symbol => Object} (readonly)



53
54
55
# File 'lib/lutaml/model/global_context.rb', line 53

def format_registries
  @format_registries
end

#importsImportRegistry (readonly)



44
45
46
# File 'lib/lutaml/model/global_context.rb', line 44

def imports
  @imports
end

#namespace_register_mapHash{String => Symbol} (readonly)



50
51
52
# File 'lib/lutaml/model/global_context.rb', line 50

def namespace_register_map
  @namespace_register_map
end

#registryContextRegistry (readonly)



38
39
40
# File 'lib/lutaml/model/global_context.rb', line 38

def registry
  @registry
end

#resolverCachedTypeResolver (readonly)



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.



274
275
276
277
278
# File 'lib/lutaml/model/global_context.rb', line 274

def bind_register_to_namespace(register_id, namespace_uri)
  @mutex.synchronize do
    @namespace_register_map[namespace_uri] = register_id.to_sym
  end
end

#clear_cachesvoid

This method returns an undefined value.

Clear caches only (keep registrations).



194
195
196
197
198
# File 'lib/lutaml/model/global_context.rb', line 194

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.



228
229
230
231
# File 'lib/lutaml/model/global_context.rb', line 228

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.



244
245
246
# File 'lib/lutaml/model/global_context.rb', line 244

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.



91
92
93
94
95
96
97
# File 'lib/lutaml/model/global_context.rb', line 91

def context(id = nil)
  if id
    @registry.lookup(id.to_sym)
  else
    default_context
  end
end

#create_context(id:, registry: nil, fallback_to: [], substitutions: []) ⇒ TypeContext

Create and register a new context.



135
136
137
138
139
140
141
142
# File 'lib/lutaml/model/global_context.rb', line 135

def create_context(id:, registry: nil, fallback_to: [], substitutions: [])
  @registry.create(
    id: id,
    registry: registry,
    fallback_to: fallback_to,
    substitutions: substitutions,
  )
end

#default_contextTypeContext

Get the current default context.



72
73
74
75
# File 'lib/lutaml/model/global_context.rb', line 72

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.



220
221
222
# File 'lib/lutaml/model/global_context.rb', line 220

def format_registry_for(format)
  @format_registries[format]
end

#register_context(context) ⇒ void

This method returns an undefined value.

Register a context.



124
125
126
# File 'lib/lutaml/model/global_context.rb', line 124

def register_context(context)
  @registry.register(context)
end

#register_for_namespace(namespace_uri) ⇒ Register?

Get register for a namespace URI.



294
295
296
297
298
299
# File 'lib/lutaml/model/global_context.rb', line 294

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.



210
211
212
213
214
# File 'lib/lutaml/model/global_context.rb', line 210

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.



285
286
287
# File 'lib/lutaml/model/global_context.rb', line 285

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


178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/lutaml/model/global_context.rb', line 178

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
  end
end

#resolvable?(name, context_id = nil) ⇒ Boolean

Check if a type is resolvable.



115
116
117
118
# File 'lib/lutaml/model/global_context.rb', line 115

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.

Raises:



105
106
107
108
# File 'lib/lutaml/model/global_context.rb', line 105

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.



311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/lutaml/model/global_context.rb', line 311

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

#statsHash

Get statistics about the global context.



251
252
253
254
255
256
257
258
259
260
# File 'lib/lutaml/model/global_context.rb', line 251

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.



148
149
150
151
# File 'lib/lutaml/model/global_context.rb', line 148

def unregister_context(id)
  @resolver.clear_cache(id)
  @registry.unregister(id)
end

#with_context(context_id) { ... } ⇒ Object

Execute a block with a specific context as default.

Yields:

  • Block to execute with the context



158
159
160
161
162
163
164
165
166
# File 'lib/lutaml/model/global_context.rb', line 158

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_registryObject?

Backward-compatible accessor for XML namespace registry. Delegates to the generic format_registries hash.



237
238
239
# File 'lib/lutaml/model/global_context.rb', line 237

def xml_namespace_registry
  @format_registries[:xml]
end