Class: JSI::Schema::Ref
- Inherits:
-
Object
- Object
- JSI::Schema::Ref
- Includes:
- Util::FingerprintHash
- Defined in:
- lib/jsi/schema/ref.rb
Overview
JSI::Schema::Ref is a reference to another schema (the result of #deref_schema), resolved using a ref URI from a ref schema (the ref URI typically the contents of the ref_schema's "$ref" keyword)
Instance Attribute Summary collapse
-
#ref ⇒ Object
readonly
Returns the value of attribute ref.
-
#ref_schema ⇒ Object
readonly
Returns the value of attribute ref_schema.
-
#ref_uri ⇒ Object
readonly
Returns the value of attribute ref_uri.
Instance Method Summary collapse
-
#deref_schema ⇒ JSI::Schema
finds the schema this ref points to.
-
#initialize(ref, ref_schema = nil) ⇒ Ref
constructor
A new instance of Ref.
- #inspect ⇒ String (also: #to_s)
-
#pretty_print(q) ⇒ void
pretty-prints a representation of self to the given printer.
Constructor Details
#initialize(ref, ref_schema = nil) ⇒ Ref
Returns a new instance of Ref.
9 10 11 12 13 14 |
# File 'lib/jsi/schema/ref.rb', line 9 def initialize(ref, ref_schema = nil) raise(ArgumentError, "ref is not a string") unless ref.respond_to?(:to_str) @ref = ref @ref_uri = Addressable::URI.parse(ref) @ref_schema = ref_schema ? Schema.ensure_schema(ref_schema) : nil end |
Instance Attribute Details
#ref ⇒ Object (readonly)
Returns the value of attribute ref.
16 17 18 |
# File 'lib/jsi/schema/ref.rb', line 16 def ref @ref end |
#ref_schema ⇒ Object (readonly)
Returns the value of attribute ref_schema.
20 21 22 |
# File 'lib/jsi/schema/ref.rb', line 20 def ref_schema @ref_schema end |
#ref_uri ⇒ Object (readonly)
Returns the value of attribute ref_uri.
18 19 20 |
# File 'lib/jsi/schema/ref.rb', line 18 def ref_uri @ref_uri end |
Instance Method Details
#deref_schema ⇒ JSI::Schema
finds the schema this ref points to
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 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 |
# File 'lib/jsi/schema/ref.rb', line 26 def deref_schema return @deref_schema if instance_variable_defined?(:@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) 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) else ref_abs_uri = nil end if ref_abs_uri schema_resource_root = JSI.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_key do |k| if Addressable::URI.parse(ref_schema.jsi_document['schemas'][k]['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
138 139 140 |
# File 'lib/jsi/schema/ref.rb', line 138 def inspect %Q(\#<#{self.class.name} #{ref}>) end |
#pretty_print(q) ⇒ void
This method returns an undefined value.
pretty-prints a representation of self to the given printer
146 147 148 149 150 151 152 |
# File 'lib/jsi/schema/ref.rb', line 146 def pretty_print(q) q.text '#<' q.text self.class.name q.text ' ' q.text ref q.text '>' end |