Class: JSI::Schema::Ref
- Inherits:
-
Object
- Object
- JSI::Schema::Ref
- Includes:
- Util::FingerprintHash
- Defined in:
- lib/jsi/schema/ref.rb
Overview
A JSI::Schema::Ref is a reference to a schema identified by a URI, typically from
a $ref
keyword of a schema.
Instance Attribute Summary collapse
- #ref ⇒ String readonly
- #ref_schema ⇒ Schema? readonly
- #ref_uri ⇒ Addressable::URI readonly
- #schema_registry ⇒ SchemaRegistry? readonly
Instance Method Summary collapse
-
#deref_schema ⇒ JSI::Schema
finds the schema this ref points to.
-
#initialize(ref, ref_schema: nil, schema_registry: nil) ⇒ Ref
constructor
A new instance of Ref.
- #inspect ⇒ String (also: #to_s)
- #jsi_fingerprint ⇒ Object private
-
#pretty_print(q)
pretty-prints a representation of self to the given printer.
Constructor Details
#initialize(ref, ref_schema: nil, schema_registry: nil) ⇒ Ref
Returns a new instance of Ref.
16 17 18 19 20 21 22 23 |
# File 'lib/jsi/schema/ref.rb', line 16 def initialize(ref, ref_schema: nil, schema_registry: nil) raise(ArgumentError, "ref is not a string") unless ref.respond_to?(:to_str) @ref = ref @ref_uri = Util.uri(ref) @ref_schema = ref_schema ? Schema.ensure_schema(ref_schema) : nil @schema_registry = schema_registry || (ref_schema ? ref_schema.jsi_schema_registry : JSI.schema_registry) @deref_schema = nil end |
Instance Attribute Details
#ref ⇒ String (readonly)
26 27 28 |
# File 'lib/jsi/schema/ref.rb', line 26 def ref @ref end |
#ref_schema ⇒ Schema? (readonly)
32 33 34 |
# File 'lib/jsi/schema/ref.rb', line 32 def ref_schema @ref_schema end |
#ref_uri ⇒ Addressable::URI (readonly)
29 30 31 |
# File 'lib/jsi/schema/ref.rb', line 29 def ref_uri @ref_uri end |
#schema_registry ⇒ SchemaRegistry? (readonly)
35 36 37 |
# File 'lib/jsi/schema/ref.rb', line 35 def schema_registry @schema_registry end |
Instance Method Details
#deref_schema ⇒ JSI::Schema
finds the schema this ref points to
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/jsi/schema/ref.rb', line 41 def deref_schema return @deref_schema if @deref_schema schema_resource_root = nil check_schema_resource_root = -> { unless schema_resource_root raise(Schema::ReferenceError, [ "cannot find schema by ref: #{ref}", ("from: #{ref_schema.pretty_inspect.chomp}" if ref_schema), ].compact.join("\n")) end } ref_uri_nofrag = ref_uri.merge(fragment: nil).freeze if ref_uri_nofrag.empty? unless ref_schema raise(Schema::ReferenceError, [ "cannot find schema by ref: #{ref}", "with no ref schema", ].join("\n")) end # the URI only consists of a fragment (or is empty). # for a fragment pointer, resolve using Schema#resource_root_subschema on the ref_schema. # for a fragment anchor, bootstrap does not support anchors; otherwise use the ref_schema's schema_resource_root. schema_resource_root = ref_schema.is_a?(MetaschemaNode::BootstrapSchema) ? nil : ref_schema.schema_resource_root resolve_fragment_ptr = ref_schema.method(:resource_root_subschema) else # find the schema_resource_root from the non-fragment URI. we will resolve any fragment, either pointer or anchor, from there. if ref_uri_nofrag.absolute? ref_abs_uri = ref_uri_nofrag elsif ref_schema && ref_schema.jsi_resource_ancestor_uri ref_abs_uri = ref_schema.jsi_resource_ancestor_uri.join(ref_uri_nofrag).freeze else ref_abs_uri = nil end if ref_abs_uri unless schema_registry raise(Schema::ReferenceError, [ "could not resolve remote ref with no schema_registry specified", "ref URI: #{ref_uri.to_s}", ("from: #{ref_schema.pretty_inspect.chomp}" if ref_schema), ].compact.join("\n")) end schema_resource_root = schema_registry.find(ref_abs_uri) end unless schema_resource_root # HAX for how google does refs and ids if ref_schema && ref_schema.jsi_document.respond_to?(:to_hash) && ref_schema.jsi_document['schemas'].respond_to?(:to_hash) ref_schema.jsi_document['schemas'].each do |k, v| if Addressable::URI.parse(v['id']) == ref_uri_nofrag schema_resource_root = ref_schema.resource_root_subschema(['schemas', k]) end end end end check_schema_resource_root.call if schema_resource_root.is_a?(Schema) resolve_fragment_ptr = schema_resource_root.method(:resource_root_subschema) else # Note: Schema#resource_root_subschema will reinstantiate nonschemas as schemas. # not implemented for remote refs when the schema_resource_root is not a schema. resolve_fragment_ptr = -> (ptr) { schema_resource_root.jsi_descendent_node(ptr) } end end fragment = ref_uri.fragment if fragment begin ptr_from_fragment = Ptr.from_fragment(fragment) rescue Ptr::PointerSyntaxError end end if ptr_from_fragment begin result_schema = resolve_fragment_ptr.call(ptr_from_fragment) rescue Ptr::ResolutionError raise(Schema::ReferenceError, [ "could not resolve pointer: #{ptr_from_fragment.pointer.inspect}", ("from: #{ref_schema.pretty_inspect.chomp}" if ref_schema), ("in schema resource root: #{schema_resource_root.pretty_inspect.chomp}" if schema_resource_root), ].compact.join("\n")) end elsif fragment.nil? check_schema_resource_root.call result_schema = schema_resource_root else check_schema_resource_root.call # find an anchor that resembles the fragment result_schemas = schema_resource_root.jsi_anchor_subschemas(fragment) if result_schemas.size == 1 result_schema = result_schemas.first elsif result_schemas.size == 0 raise(Schema::ReferenceError, [ "could not find schema by fragment: #{fragment.inspect}", "in schema resource root: #{schema_resource_root.pretty_inspect.chomp}", ].join("\n")) else raise(Schema::ReferenceError, [ "found multiple schemas for plain name fragment #{fragment.inspect}:", *result_schemas.map { |s| s.pretty_inspect.chomp }, ].join("\n")) end end Schema.ensure_schema(result_schema, msg: "object identified by uri #{ref} is not a schema:") return @deref_schema = result_schema end |
#inspect ⇒ String Also known as: to_s
160 161 162 |
# File 'lib/jsi/schema/ref.rb', line 160 def inspect -%Q(\#<#{self.class.name} #{ref}>) end |
#jsi_fingerprint ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
178 179 180 |
# File 'lib/jsi/schema/ref.rb', line 178 def jsi_fingerprint {class: self.class, ref: ref, ref_schema: ref_schema} end |
#pretty_print(q)
This method returns an undefined value.
pretty-prints a representation of self to the given printer
168 169 170 171 172 173 174 |
# File 'lib/jsi/schema/ref.rb', line 168 def pretty_print(q) q.text '#<' q.text self.class.name q.text ' ' q.text ref q.text '>' end |