Class: JSONSkooma::JSONSchema

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

Direct Known Subclasses

Metaschema

Instance Attribute Summary collapse

Attributes inherited from JSONNode

#key, #parent, #type

Instance Method Summary collapse

Methods inherited from JSONNode

#!=, #==, #[], #path, #root, #value

Constructor Details

#initialize(value, registry: Registry::DEFAULT_NAME, cache_id: "default", uri: nil, metaschema_uri: nil, parent: nil, key: nil) ⇒ JSONSchema

Returns a new instance of JSONSchema.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/json_skooma/json_schema.rb', line 8

def initialize(value, registry: Registry::DEFAULT_NAME, cache_id: "default", uri: nil, metaschema_uri: nil, parent: nil, key: nil)
  super(value, parent: parent, key: key)

  @keywords = {}

  @cache_id = cache_id
  @registry = Registry[registry]
  self.metaschema_uri = metaschema_uri.is_a?(String) ? URI.parse(metaschema_uri) : metaschema_uri
  self.uri = uri.is_a?(String) ? URI.parse(uri) : uri

  return if type != "object"

  self.uri ||= URI("urn:uuid:#{SecureRandom.uuid}") if parent.nil?
  resolve_keywords(value.transform_keys(&:to_s))
  resolve_references if parent.nil?
end

Instance Attribute Details

#cache_idObject (readonly)

Returns the value of attribute cache_id.



5
6
7
# File 'lib/json_skooma/json_schema.rb', line 5

def cache_id
  @cache_id
end

#metaschema_uriObject



95
96
97
# File 'lib/json_skooma/json_schema.rb', line 95

def metaschema_uri
  @metaschema_uri ||= parent_schema&.metaschema_uri
end

#registryObject (readonly)

Returns the value of attribute registry.



5
6
7
# File 'lib/json_skooma/json_schema.rb', line 5

def registry
  @registry
end

#uriObject

Returns the value of attribute uri.



5
6
7
# File 'lib/json_skooma/json_schema.rb', line 5

def uri
  @uri
end

Instance Method Details

#base_uriObject



99
100
101
102
103
# File 'lib/json_skooma/json_schema.rb', line 99

def base_uri
  return parent_schema&.base_uri unless uri

  @base_uri ||= uri.dup.tap { |u| u.fragment = nil }
end

#canonical_uriObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/json_skooma/json_schema.rb', line 105

def canonical_uri
  return uri if uri
  return @canonical_uri if instance_variable_defined?(:@canonical_uri)

  keys = []
  node = self
  while node.parent
    keys.unshift(node.key)
    node = node.parent

    if node.is_a?(JSONSchema) && node.uri
      fragment = JSONPointer.new(node.uri.fragment || "") << keys
      return @canonical_uri = node.uri.dup.tap { |u| u.fragment = fragment.to_s }
    end
  end
end

#evaluate(instance, result = nil, ref: nil) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/json_skooma/json_schema.rb', line 25

def evaluate(instance, result = nil, ref: nil)
  return resolve_ref(ref).evaluate(instance, result) if ref

  instance = JSONSkooma::JSONNode.new(instance) unless instance.is_a?(JSONNode)

  result ||= Result.new(self, instance)
  case value
  when true
    # do nothing
  when false
    result.failure("The instance is disallowed by a boolean false schema")
  else
    @keywords.each do |key, keyword|
      next if keyword.static || !keyword.instance_types.include?(instance.type)

      result.call(instance, key, self) do |subresult|
        keyword.evaluate(instance, subresult)
      end
    end

    if result.children[instance.path]&.any? { |_, child| !child.passed? }
      result.failure
    end
  end

  result
end

#metaschemaObject

Raises:



89
90
91
92
93
# File 'lib/json_skooma/json_schema.rb', line 89

def metaschema
  raise RegistryError, "The schema's metaschema URI has not been set" if metaschema_uri.nil?

  @metaschema ||= @registry.metaschema(metaschema_uri)
end

#parent_schemaObject



69
70
71
72
73
74
75
76
77
78
# File 'lib/json_skooma/json_schema.rb', line 69

def parent_schema
  return @parent_schema if instance_variable_defined?(:@parent_schema)

  node = parent
  while node
    return @parent_schema = node if node.is_a?(JSONSchema)

    node = node.parent
  end
end

#resolve_ref(uri) ⇒ Object



61
62
63
# File 'lib/json_skooma/json_schema.rb', line 61

def resolve_ref(uri)
  registry.schema(resolve_uri(uri), metaschema_uri: metaschema_uri, cache_id: cache_id)
end

#resolve_referencesObject



122
123
124
# File 'lib/json_skooma/json_schema.rb', line 122

def resolve_references
  @keywords.each_value(&:resolve)
end

#resolve_uri(uri) ⇒ Object

Raises:



53
54
55
56
57
58
59
# File 'lib/json_skooma/json_schema.rb', line 53

def resolve_uri(uri)
  uri = URI.parse(uri)
  return uri if uri.absolute?
  return base_uri + uri if base_uri

  raise Error, "No base URI against which to resolve uri `#{uri}`"
end

#validateObject



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

def validate
  metaschema.evaluate(self)
end