Class: JSI::SchemaRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/jsi/schema_registry.rb

Defined Under Namespace

Classes: Collision, NonAbsoluteURI, ResourceNotFound

Instance Method Summary collapse

Constructor Details

#initializeSchemaRegistry

Returns a new instance of SchemaRegistry.



20
21
22
23
24
# File 'lib/jsi/schema_registry.rb', line 20

def initialize
  @resources = {}
  @autoload_uris = {}
  @resources_mutex = Mutex.new
end

Instance Method Details

#autoload_uri(uri, &block)

This method returns an undefined value.

takes a URI identifying a resource to be loaded by the given block when a reference to the URI is followed.

for example:

JSI.schema_registry.autoload_uri('http://example.com/schema.json') do
  JSI.new_schema({
    '$schema' => 'http://json-schema.org/draft-07/schema#',
    '$id' => 'http://example.com/schema.json',
    'title' => 'my schema',
  })
end

the block would normally load JSON from the filesystem or similar.

Parameters:

  • uri (#to_str)

Yield Returns:

  • (JSI::Base)

    a JSI instance containing the resource identified by the given uri



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/jsi/schema_registry.rb', line 79

def autoload_uri(uri, &block)
  uri = registration_uri(uri)
  mutating
  unless block
    raise(ArgumentError, ["#{SchemaRegistry}#autoload_uri must be invoked with a block", "URI: #{uri}"].join("\n"))
  end
  if @autoload_uris.key?(uri)
    raise(Collision, ["already registered URI for autoload", "URI: #{uri}", "loader: #{@autoload_uris[uri]}"].join("\n"))
  end
  @autoload_uris[uri] = block
  nil
end

#dupObject



136
137
138
139
140
141
142
143
144
145
# File 'lib/jsi/schema_registry.rb', line 136

def dup
  self.class.new.tap do |reg|
    @resources.each do |uri, resource|
      reg.internal_store(uri, resource)
    end
    @autoload_uris.each do |uri, autoload|
      reg.autoload_uri(uri, &autoload)
    end
  end
end

#find(uri) ⇒ JSI::Base

Parameters:

  • uri (Addressable::URI, #to_str)

Returns:

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/jsi/schema_registry.rb', line 95

def find(uri)
  uri = registration_uri(uri)
  if @autoload_uris.key?(uri)
    autoloaded = @autoload_uris[uri].call
    register(autoloaded)
    @autoload_uris.delete(uri)
  end
  if !@resources.key?(uri)
    if autoloaded
      msg = [
        "URI #{uri} was registered with autoload_uri but the result did not contain a resource with that URI.",
        "the resource resulting from autoload_uri was:",
        autoloaded.pretty_inspect.chomp,
      ]
    else
      msg = ["URI #{uri} is not registered. registered URIs:", *(@resources.keys | @autoload_uris.keys)]
    end
    raise(ResourceNotFound.new(msg.join("\n")).tap { |e| e.uri = uri })
  end
  @resources[uri]
end

#freezeObject



147
148
149
150
151
152
# File 'lib/jsi/schema_registry.rb', line 147

def freeze
  @resources.freeze
  @autoload_uris.freeze
  @resources_mutex = nil
  super
end

#inspectObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/jsi/schema_registry.rb', line 117

def inspect
  [
    "#<#{self.class}",
    *[['resources', @resources.keys], ['autoload', @autoload_uris.keys]].map do |label, uris|
      [
        "  #{label} (#{uris.size})#{uris.empty? ? "" : ":"}",
        *uris.map do |uri|
          "    #{uri}"
        end,
      ]
    end.inject([], &:+),
    '>',
  ].join("\n").freeze
end

#register(resource)

This method returns an undefined value.

registers the given resource and/or schema resources it contains in the registry.

each descendent node of the resource (including the resource itself) is registered if it is a schema that has an absolute URI (generally defined by the '$id' keyword).

the given resource itself will be registered, whether or not it is a schema, if it is the root of its document and was instantiated with the option uri specified.

Parameters:

  • resource (JSI::Base)

    a JSI containing resources to register



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jsi/schema_registry.rb', line 36

def register(resource)
  unless resource.is_a?(JSI::Base)
    raise(ArgumentError, "resource must be a JSI::Base. got: #{resource.pretty_inspect.chomp}")
  end
  unless resource.is_a?(JSI::Schema) || resource.jsi_ptr.root?
    # unsure, should this be allowed? the given JSI is not a "resource" as we define it, but
    # if this check is removed it will just register any resources (schemas) below the given JSI.
    raise(ArgumentError, "undefined behavior: registration of a JSI which is not a schema and is not at the root of a document")
  end

  # allow for registration of resources at the root of a document whether or not they are schemas.
  # jsi_schema_base_uri at the root comes from the `uri` parameter to new_jsi / new_schema.
  if resource.jsi_schema_base_uri && resource.jsi_ptr.root?
    internal_store(resource.jsi_schema_base_uri, resource)
  end

  resource.jsi_each_descendent_node do |node|
    if node.is_a?(JSI::Schema) && node.schema_absolute_uri
      internal_store(node.schema_absolute_uri, node)
    end
  end

  nil
end

#to_sObject



132
133
134
# File 'lib/jsi/schema_registry.rb', line 132

def to_s
  inspect
end