Class: JSONSkooma::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/json_skooma/registry.rb

Constant Summary collapse

DEFAULT_NAME =
"registry"

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name: DEFAULT_NAME) ⇒ Registry

Returns a new instance of Registry.



36
37
38
39
40
41
42
43
# File 'lib/json_skooma/registry.rb', line 36

def initialize(name: DEFAULT_NAME)
  @uri_sources = {}
  @vocabularies = {}
  @schema_cache = {}
  @enabled_formats = Set.new

  self.class.registries[name] = self
end

Class Attribute Details

.registriesObject

Returns the value of attribute registries.



21
22
23
# File 'lib/json_skooma/registry.rb', line 21

def registries
  @registries
end

Class Method Details

.[](key) ⇒ Object

Raises:



23
24
25
26
27
28
29
# File 'lib/json_skooma/registry.rb', line 23

def [](key)
  return key if key.is_a?(Registry)

  raise RegistryError, "Registry `#{key}` not found" unless registries.key?(key)

  registries[key]
end

Instance Method Details

#add_format(key, validator = nil) ⇒ Object

Raises:



45
46
47
48
49
50
# File 'lib/json_skooma/registry.rb', line 45

def add_format(key, validator = nil)
  JSONSkooma::Validators.register(key, validator) if validator
  raise RegistryError, "Format validator `#{key}` not found" unless Validators.validators.key?(key)

  @enabled_formats << key
end

#add_metaschema(uri, default_core_vocabulary_uri = nil, *default_vocabulary_uris) ⇒ Object

Raises:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/json_skooma/registry.rb', line 98

def add_metaschema(uri, default_core_vocabulary_uri = nil, *default_vocabulary_uris)
  metaschema_doc = load_json(uri)
  default_core_vocabulary = vocabulary(default_core_vocabulary_uri) if default_core_vocabulary_uri
  default_vocabularies = default_vocabulary_uris.map { |vocabulary_uri| vocabulary(vocabulary_uri) }

  metaschema = Metaschema.new(
    metaschema_doc,
    default_core_vocabulary,
    *default_vocabularies,
    registry: self,
    uri: uri
  )

  return metaschema if metaschema.validate.valid?

  raise RegistryError, "The metaschema is invalid against its own metaschema #{metaschema_doc["$schema"]}"
end

#add_schema(uri, schema, cache_id: "default") ⇒ Object



64
65
66
67
# File 'lib/json_skooma/registry.rb', line 64

def add_schema(uri, schema, cache_id: "default")
  @schema_cache[cache_id] ||= {}
  @schema_cache[cache_id][uri.to_s] = schema
end

#add_source(uri, source) ⇒ Object

Raises:



123
124
125
126
127
# File 'lib/json_skooma/registry.rb', line 123

def add_source(uri, source)
  raise RegistryError, "uri must end with '/'" unless uri.end_with?("/")

  @uri_sources[uri] = source
end

#add_vocabulary(uri, *keywords) ⇒ Object



56
57
58
# File 'lib/json_skooma/registry.rb', line 56

def add_vocabulary(uri, *keywords)
  @vocabularies[uri.to_s] = Vocabulary.new(uri, *keywords)
end

#delete_schema(uri, cache_id: "default") ⇒ Object



69
70
71
# File 'lib/json_skooma/registry.rb', line 69

def delete_schema(uri, cache_id: "default")
  @schema_cache[cache_id].delete(uri.to_s)
end

#format_enabled?(key) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/json_skooma/registry.rb', line 52

def format_enabled?(key)
  @enabled_formats.include?(key)
end

#load_json(uri) ⇒ Object

Raises:



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/json_skooma/registry.rb', line 129

def load_json(uri)
  candidates = @uri_sources
    .select { |source_uri| uri.to_s.start_with?(source_uri) }
    .sort_by { |source_uri| -source_uri.length }

  raise RegistryError, "A source is not available for #{uri}" if candidates.empty?

  base_uri, candidate = candidates.first
  relative_path = uri.to_s.sub(base_uri, "")
  candidate.call(relative_path)
end

#metaschema(uri) ⇒ Object

Raises:



116
117
118
119
120
121
# File 'lib/json_skooma/registry.rb', line 116

def metaschema(uri)
  schema = @schema_cache.dig("__meta__", uri.to_s) || add_metaschema(uri.to_s)
  return schema if schema

  raise RegistryError, "The schema referenced by #{uri} is not a metaschema"
end

#schema(uri, metaschema_uri: nil, cache_id: "default", schema_class: JSONSchema, expected_class: JSONSchema) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/json_skooma/registry.rb', line 73

def schema(uri, metaschema_uri: nil, cache_id: "default", schema_class: JSONSchema, expected_class: JSONSchema)
  schema = @schema_cache.dig(cache_id, uri.to_s)
  return schema if schema

  base_uri = uri.dup.tap { |u| u.fragment = nil }
  schema = @schema_cache.dig(cache_id, base_uri.to_s) if uri.fragment

  if schema.nil?
    doc = load_json(base_uri)

    schema = schema_class.new(
      doc,
      registry: self,
      cache_id: cache_id,
      uri: base_uri,
      metaschema_uri: metaschema_uri
    )
    return @schema_cache.dig(cache_id, uri.to_s) if @schema_cache.dig(cache_id, uri.to_s)
  end
  schema = JSONPointer.new(uri.fragment).eval(schema) if uri.fragment
  return schema if schema.is_a?(expected_class)

  raise UnexpectedSchemaClassError.new(uri, expected_class)
end

#vocabulary(uri) ⇒ Object



60
61
62
# File 'lib/json_skooma/registry.rb', line 60

def vocabulary(uri)
  @vocabularies[uri.to_s] or raise RegistryError, "vocabulary #{uri} not found"
end