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.



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

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

Instance Method Details

#autoload_uri(uri, &block) ⇒ void

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 (Addressable::URI)

Yield Returns:

  • (JSI::Base)

    a JSI instance containing the resource identified by the given uri



78
79
80
81
82
83
# File 'lib/jsi/schema_registry.rb', line 78

def autoload_uri(uri, &block)
  uri = Addressable::URI.parse(uri)
  ensure_uri_absolute(uri)
  @autoload_uris[uri] = block
  nil
end

#dupObject



111
112
113
114
115
116
117
118
119
120
# File 'lib/jsi/schema_registry.rb', line 111

def dup
  self.class.new.tap do |reg|
    @resources.each do |uri, resource|
      reg.register_single(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:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/jsi/schema_registry.rb', line 88

def find(uri)
  uri = Addressable::URI.parse(uri)
  ensure_uri_absolute(uri)
  if @autoload_uris.key?(uri) && !@resources.key?(uri)
    autoloaded = @autoload_uris[uri].call
    register(autoloaded)
  end
  registered_uris = @resources.keys
  if !registered_uris.include?(uri)
    if @autoload_uris.key?(uri)
      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:", *registered_uris]
    end
    raise(ResourceNotFound, msg.join("\n"))
  end
  @resources[uri]
end

#register(resource) ⇒ void

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



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

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?
    register_single(resource.jsi_schema_base_uri, resource)
  end

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

  nil
end