Class: JSI::MetaschemaNode
- Inherits:
-
Object
- Object
- JSI::MetaschemaNode
- Includes:
- Enumerable, PathedNode, Util::FingerprintHash, Util::Memoize
- Defined in:
- lib/jsi/metaschema_node.rb
Overview
a MetaschemaNode is a PathedNode whose node_document contains a metaschema. as with any PathedNode the node_ptr points to the content of a node. the root of the metaschema is pointed to by metaschema_root_ptr. the schema of the root of the document is pointed to by root_schema_ptr.
like JSI::Base, this class represents an instance of a schema, an instance which may itself be a schema. unlike JSI::Base, the document containing the schema and the instance is the same, and a schema may be an instance of itself.
the document containing the metaschema, its subschemas, and instances of those subschemas is the node_document.
the schema instance is the content in the document pointed to by the MetaschemaNode's node_ptr.
unlike with JSI::Base, the schema is not part of the class, since a metaschema needs the ability to have its schema be the instance itself.
if the MetaschemaNode's schema is its self, it will be extended with JSI::Metaschema.
a MetaschemaNode is extended with JSI::Schema when it represents a schema - this is the case when its schema is the metaschema.
Instance Attribute Summary collapse
-
#jsi_schemas ⇒ Object
readonly
JSI::Schemas describing this MetaschemaNode.
-
#metaschema_root_ptr ⇒ Object
readonly
ptr to the root of the metaschema in the node_document.
-
#node_document ⇒ Object
readonly
document containing the metaschema.
-
#node_ptr ⇒ Object
readonly
ptr to this metaschema node.
-
#root_schema_ptr ⇒ Object
readonly
ptr to the schema of the root of the node_document.
Instance Method Summary collapse
-
#[](token) ⇒ MetaschemaNode, Object
The node content's subscript value at the given token.
-
#deref(&block) ⇒ MetaschemaNode
if this MetaschemaNode is a $ref then the $ref is followed.
-
#document_root_node ⇒ MetaschemaNode
Document root MetaschemaNode.
-
#initialize(node_document, node_ptr: JSI::JSON::Pointer[], metaschema_root_ptr: JSI::JSON::Pointer[], root_schema_ptr: JSI::JSON::Pointer[]) ⇒ MetaschemaNode
constructor
A new instance of MetaschemaNode.
- #inspect ⇒ String
-
#jsi_fingerprint ⇒ Object
An opaque fingerprint of this MetaschemaNode for FingerprintHash.
-
#modified_copy {|Object| ... } ⇒ MetaschemaNode
Modified copy of self.
- #object_group_text ⇒ Array<String>
-
#parent_node ⇒ MetaschemaNode
Parent MetaschemaNode.
- #pretty_print(q) ⇒ Object
Methods included from Util::FingerprintHash
Methods included from Util::Memoize
Methods included from PathedNode
#node_content, #node_ptr_deref
Constructor Details
#initialize(node_document, node_ptr: JSI::JSON::Pointer[], metaschema_root_ptr: JSI::JSON::Pointer[], root_schema_ptr: JSI::JSON::Pointer[]) ⇒ MetaschemaNode
Returns a new instance of MetaschemaNode.
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 |
# File 'lib/jsi/metaschema_node.rb', line 37 def initialize(node_document, node_ptr: JSI::JSON::Pointer[], metaschema_root_ptr: JSI::JSON::Pointer[], root_schema_ptr: JSI::JSON::Pointer[]) @node_document = node_document @node_ptr = node_ptr = @root_schema_ptr = root_schema_ptr node_content = self.node_content if node_content.respond_to?(:to_hash) extend PathedHashNode elsif node_content.respond_to?(:to_ary) extend PathedArrayNode end instance_for_schema = node_document schema_ptrs = node_ptr.reference_tokens.inject(Set.new << root_schema_ptr) do |ptrs, tok| if instance_for_schema.respond_to?(:to_ary) subschema_ptrs_for_token = ptrs.map do |ptr| ptr.schema_subschema_ptrs_for_index(node_document, tok) end.inject(Set.new, &:|) else subschema_ptrs_for_token = ptrs.map do |ptr| ptr.schema_subschema_ptrs_for_property_name(node_document, tok) end.inject(Set.new, &:|) end instance_for_schema = instance_for_schema[tok] ptrs_for_instance = subschema_ptrs_for_token.map do |ptr| ptr.schema_match_ptrs_to_instance(node_document, instance_for_schema) end.inject(Set.new, &:|) ptrs_for_instance end @jsi_schemas = schema_ptrs.map do |schema_ptr| if schema_ptr == node_ptr self else new_node(node_ptr: schema_ptr) end end.to_set @jsi_schemas.each do |schema| if schema.node_ptr == extend JSI::Schema end if schema.node_ptr == node_ptr extend Metaschema end extend(JSI::SchemaClasses.accessor_module_for_schema(schema, conflicting_modules: [Metaschema, Schema, MetaschemaNode, PathedArrayNode, PathedHashNode])) end # workarounds begin # draft 4 boolean schema workaround # in draft 4, boolean schemas are not described in the root, but on anyOf schemas on # properties/additionalProperties and properties/additionalItems. # we need to extend those as DescribesSchema. addtlPropsanyOf = ["properties"]["additionalProperties"]["anyOf"] addtlItemsanyOf = ["properties"]["additionalItems"]["anyOf"] if !node_ptr.root? && [addtlPropsanyOf, addtlItemsanyOf].include?(node_ptr.parent) extend JSI::Schema::DescribesSchema end end end |
Instance Attribute Details
#jsi_schemas ⇒ Object (readonly)
JSI::Schemas describing this MetaschemaNode
110 111 112 |
# File 'lib/jsi/metaschema_node.rb', line 110 def jsi_schemas @jsi_schemas end |
#metaschema_root_ptr ⇒ Object (readonly)
ptr to the root of the metaschema in the node_document
106 107 108 |
# File 'lib/jsi/metaschema_node.rb', line 106 def end |
#node_document ⇒ Object (readonly)
document containing the metaschema. see PathedNode#node_document.
102 103 104 |
# File 'lib/jsi/metaschema_node.rb', line 102 def node_document @node_document end |
#node_ptr ⇒ Object (readonly)
ptr to this metaschema node. see PathedNode#node_ptr.
104 105 106 |
# File 'lib/jsi/metaschema_node.rb', line 104 def node_ptr @node_ptr end |
#root_schema_ptr ⇒ Object (readonly)
ptr to the schema of the root of the node_document
108 109 110 |
# File 'lib/jsi/metaschema_node.rb', line 108 def root_schema_ptr @root_schema_ptr end |
Instance Method Details
#[](token) ⇒ MetaschemaNode, Object
The node content's subscript value at the given token. if there is a subschema defined for that token on this MetaschemaNode's schema, returns that value as a MetaschemaNode instantiation of that subschema.
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 |
# File 'lib/jsi/metaschema_node.rb', line 126 def [](token) if respond_to?(:to_hash) token_in_range = node_content_hash_pubsend(:key?, token) value = node_content_hash_pubsend(:[], token) elsif respond_to?(:to_ary) token_in_range = node_content_ary_pubsend(:each_index).include?(token) value = node_content_ary_pubsend(:[], token) else raise(NoMethodError, "cannot subcript (using token: #{token.inspect}) from content: #{node_content.pretty_inspect.chomp}") end result = jsi_memoize(:[], token, value, token_in_range) do |token, value, token_in_range| if token_in_range value_node = new_node(node_ptr: node_ptr[token]) if value_node.is_a?(Schema) || value.respond_to?(:to_hash) || value.respond_to?(:to_ary) value_node else value end else # I think I will not support Hash#default/#default_proc in this case. nil end end result end |
#deref(&block) ⇒ MetaschemaNode
if this MetaschemaNode is a $ref then the $ref is followed. otherwise this MetaschemaNode is returned.
156 157 158 159 160 161 |
# File 'lib/jsi/metaschema_node.rb', line 156 def deref(&block) node_ptr_deref do |deref_ptr| return new_node(node_ptr: deref_ptr).tap(&(block || Util::NOOP)) end return self end |
#document_root_node ⇒ MetaschemaNode
Returns document root MetaschemaNode.
113 114 115 |
# File 'lib/jsi/metaschema_node.rb', line 113 def document_root_node new_node(node_ptr: JSI::JSON::Pointer[]) end |
#inspect ⇒ String
171 172 173 |
# File 'lib/jsi/metaschema_node.rb', line 171 def inspect "\#<#{object_group_text.join(' ')} #{node_content.inspect}>" end |
#jsi_fingerprint ⇒ Object
Returns an opaque fingerprint of this MetaschemaNode for FingerprintHash.
203 204 205 |
# File 'lib/jsi/metaschema_node.rb', line 203 def jsi_fingerprint {class: self.class, node_document: node_document}.merge(our_initialize_params) end |
#modified_copy {|Object| ... } ⇒ MetaschemaNode
Returns modified copy of self.
166 167 168 |
# File 'lib/jsi/metaschema_node.rb', line 166 def modified_copy(&block) MetaschemaNode.new(node_ptr.modified_document_copy(node_document, &block), our_initialize_params) end |
#object_group_text ⇒ Array<String>
189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/jsi/metaschema_node.rb', line 189 def object_group_text if jsi_schemas.any? class_n_schemas = "#{self.class} (#{jsi_schemas.map { |s| s.node_ptr.uri }.join(' ')})" else class_n_schemas = self.class.to_s end [ class_n_schemas, is_a?(Metaschema) ? "Metaschema" : is_a?(Schema) ? "Schema" : nil, *(node_content.respond_to?(:object_group_text) ? node_content.object_group_text : []), ].compact end |
#parent_node ⇒ MetaschemaNode
Returns parent MetaschemaNode.
118 119 120 |
# File 'lib/jsi/metaschema_node.rb', line 118 def parent_node new_node(node_ptr: node_ptr.parent) end |
#pretty_print(q) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/jsi/metaschema_node.rb', line 175 def pretty_print(q) q.text '#<' q.text object_group_text.join(' ') q.group_sub { q.nest(2) { q.breakable ' ' q.pp node_content } } q.breakable '' q.text '>' end |