Class: JSI::MetaschemaNode
Overview
a MetaschemaNode is a JSI instance representing a node in a document which contains a metaschema. the root of the metaschema is pointed to by metaschema_root_ptr. the schema describing the root of the document is pointed to by root_schema_ptr.
like JSI::Base's normal subclasses, this class represents an instance of a schema set, an instance which may itself be a schema. unlike JSI::Base, the document containing the instance and its schemas is the same, and a schema (the metaschema) may be an instance of itself.
unlike JSI::Base's normal subclasses, the schemas describing the instance are not part of the class. since the metaschema describes itself, attempting to construct a class from the JSI Schema Module of a schema which is itself an instance of that class results in a causality loop. instead, a MetaschemaNode calculates its #jsi_schemas and extends itself with their JSI Schema modules during initialization. the MetaschemaNode of the metaschema is extended with its own JSI Schema Module.
if the MetaschemaNode's schemas include its self, it is extended with JSI::Metaschema.
a MetaschemaNode is extended with JSI::Schema when it represents a schema - this is the case when the metaschema is one of its schemas.
Defined Under Namespace
Classes: BootstrapSchema
Instance Attribute Summary collapse
-
#jsi_schemas ⇒ JSI::SchemaSet
readonly
JSI Schemas describing this MetaschemaNode.
-
#metaschema_root_ptr ⇒ JSI::Ptr
readonly
ptr to the root of the metaschema in the jsi_document.
-
#root_schema_ptr ⇒ JSI::Ptr
readonly
ptr to the schema of the root of the jsi_document.
-
#schema_implementation_modules ⇒ Set<Module>
readonly
Set of modules to apply to schemas which are instances of (described by) the metaschema.
Attributes inherited from Base
#jsi_document, #jsi_ptr, #jsi_root_node
Attributes included from Schema::SchemaAncestorNode
Instance Method Summary collapse
-
#[](token, as_jsi: :auto) ⇒ JSI::Base, Object
subscripts to return a child value identified by the given token.
-
#initialize(jsi_document, jsi_ptr: Ptr[], schema_implementation_modules:, metaschema_root_ptr: Ptr[], root_schema_ptr: Ptr[], jsi_schema_base_uri: nil, jsi_root_node: nil) ⇒ MetaschemaNode
constructor
A new instance of MetaschemaNode.
-
#jsi_fingerprint ⇒ Object
an opaque fingerprint of this MetaschemaNode for FingerprintHash.
-
#jsi_modified_copy {|Object| ... } ⇒ MetaschemaNode
instantiates a new MetaschemaNode whose instance is a modified copy of this MetaschemaNode's instance.
Methods inherited from Base
#[]=, #as_json, #dup, inspect, #inspect, #jmespath_search, #jsi_ancestor_nodes, #jsi_descendent_node, #jsi_each_descendent_node, #jsi_node_content, #jsi_parent_node, #jsi_parent_nodes, #jsi_schema_modules, #jsi_select_descendents_leaf_first, #jsi_select_descendents_node_first, #jsi_valid?, #jsi_validate, name, #pretty_print, to_s
Methods included from Schema::SchemaAncestorNode
#jsi_anchor_subschema, #jsi_anchor_subschemas, #jsi_resource_ancestor_uri, #jsi_schema_resource_ancestors
Constructor Details
#initialize(jsi_document, jsi_ptr: Ptr[], schema_implementation_modules:, metaschema_root_ptr: Ptr[], root_schema_ptr: Ptr[], jsi_schema_base_uri: nil, jsi_root_node: nil) ⇒ MetaschemaNode
Returns a new instance of MetaschemaNode.
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 |
# File 'lib/jsi/metaschema_node.rb', line 35 def initialize( jsi_document, jsi_ptr: Ptr[], schema_implementation_modules: , metaschema_root_ptr: Ptr[], root_schema_ptr: Ptr[], jsi_schema_base_uri: nil, jsi_root_node: nil ) jsi_initialize_memos self.jsi_document = jsi_document self.jsi_ptr = jsi_ptr @schema_implementation_modules = Util.ensure_module_set(schema_implementation_modules) @metaschema_root_ptr = @root_schema_ptr = root_schema_ptr raise(Bug, 'jsi_root_node') if jsi_ptr.root? ^ !jsi_root_node @jsi_root_node = jsi_ptr.root? ? self : jsi_root_node if jsi_ptr.root? && jsi_schema_base_uri raise(NotImplementedError, "unsupported jsi_schema_base_uri on metaschema document root") end self.jsi_schema_base_uri = jsi_schema_base_uri jsi_node_content = self.jsi_node_content if jsi_node_content.respond_to?(:to_hash) extend HashNode end if jsi_node_content.respond_to?(:to_ary) extend ArrayNode end instance_for_schemas = jsi_document bootstrap_schema_class = JSI::SchemaClasses.bootstrap_schema_class(schema_implementation_modules) root_bootstrap_schema = bootstrap_schema_class.new( jsi_document, jsi_ptr: root_schema_ptr, jsi_schema_base_uri: nil, # supplying jsi_schema_base_uri on root bootstrap schema is not supported ) our_bootstrap_schemas = jsi_ptr.tokens.inject(SchemaSet[root_bootstrap_schema]) do |bootstrap_schemas, tok| child_indicated_schemas = bootstrap_schemas.child_applicator_schemas(tok, instance_for_schemas) child_schemas = child_indicated_schemas.inplace_applicator_schemas(instance_for_schemas[tok]) instance_for_schemas = instance_for_schemas[tok] child_schemas end our_bootstrap_schemas.each do |bootstrap_schema| if bootstrap_schema.jsi_ptr == # this is described by the metaschema, i.e. this is a schema schema_implementation_modules.each do |schema_implementation_module| extend schema_implementation_module end end if bootstrap_schema.jsi_ptr == jsi_ptr # this is the metaschema (it is described by itself) extend Metaschema end end @jsi_schemas = SchemaSet.new(our_bootstrap_schemas) do |bootstrap_schema| if bootstrap_schema.jsi_ptr == jsi_ptr self elsif bootstrap_schema.jsi_ptr.root? @jsi_root_node else new_node( jsi_ptr: bootstrap_schema.jsi_ptr, jsi_schema_base_uri: bootstrap_schema.jsi_schema_base_uri, jsi_root_node: @jsi_root_node, ) end end # note: jsi_schemas must already be set for jsi_schema_module to be used/extended if is_a?(Metaschema) describes_schema!(schema_implementation_modules) end @jsi_schemas.each do |schema| extend schema.jsi_schema_module 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. # these still describe schemas, despite not being described by the metaschema. addtlPropsanyOf = ["properties"]["additionalProperties"]["anyOf"] addtlItemsanyOf = ["properties"]["additionalItems"]["anyOf"] if !jsi_ptr.root? && [addtlPropsanyOf, addtlItemsanyOf].include?(jsi_ptr.parent) describes_schema!(schema_implementation_modules) end end end |
Instance Attribute Details
#jsi_schemas ⇒ JSI::SchemaSet (readonly)
JSI Schemas describing this MetaschemaNode
146 147 148 |
# File 'lib/jsi/metaschema_node.rb', line 146 def jsi_schemas @jsi_schemas end |
#metaschema_root_ptr ⇒ JSI::Ptr (readonly)
ptr to the root of the metaschema in the jsi_document
138 139 140 |
# File 'lib/jsi/metaschema_node.rb', line 138 def @metaschema_root_ptr end |
#root_schema_ptr ⇒ JSI::Ptr (readonly)
ptr to the schema of the root of the jsi_document
142 143 144 |
# File 'lib/jsi/metaschema_node.rb', line 142 def root_schema_ptr @root_schema_ptr end |
#schema_implementation_modules ⇒ Set<Module> (readonly)
Set of modules to apply to schemas which are instances of (described by) the metaschema
134 135 136 |
# File 'lib/jsi/metaschema_node.rb', line 134 def schema_implementation_modules @schema_implementation_modules end |
Instance Method Details
#[](token, as_jsi: :auto) ⇒ JSI::Base, Object
subscripts to return a child value identified by the given token.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/jsi/metaschema_node.rb', line 153 def [](token, as_jsi: :auto) if respond_to?(:to_hash) token_in_range = jsi_node_content_hash_pubsend(:key?, token) value = jsi_node_content_hash_pubsend(:[], token) elsif respond_to?(:to_ary) token_in_range = jsi_node_content_ary_pubsend(:each_index).include?(token) value = jsi_node_content_ary_pubsend(:[], token) else raise(NoMethodError, "cannot subscript (using token: #{token.inspect}) from content: #{jsi_node_content.pretty_inspect.chomp}") end begin if token_in_range value_node = jsi_subinstance_memos[token: token] jsi_subinstance_as_jsi(value, value_node.jsi_schemas, as_jsi) do value_node end else # I think I will not support Hash#default/#default_proc in this case. nil end end end |
#jsi_fingerprint ⇒ Object
an opaque fingerprint of this MetaschemaNode for FingerprintHash
210 211 212 |
# File 'lib/jsi/metaschema_node.rb', line 210 def jsi_fingerprint {class: self.class, jsi_document: jsi_document}.merge(our_initialize_params) end |
#jsi_modified_copy {|Object| ... } ⇒ MetaschemaNode
instantiates a new MetaschemaNode whose instance is a modified copy of this MetaschemaNode's instance
182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/jsi/metaschema_node.rb', line 182 def jsi_modified_copy(&block) if jsi_ptr.root? modified_document = jsi_ptr.modified_document_copy(jsi_document, &block) MetaschemaNode.new(modified_document, **our_initialize_params) else modified_jsi_root_node = jsi_root_node.jsi_modified_copy do |root| jsi_ptr.modified_document_copy(root, &block) end modified_jsi_root_node.jsi_descendent_node(jsi_ptr) end end |