Class: JSI::MetaSchemaNode
- Includes:
- Base::Immutable
- Defined in:
- lib/jsi/metaschema_node.rb
Overview
A MetaSchemaNode is a JSI instance representing a node in a document that contains a meta-schema, or contains a schema describing a meta-schema (e.g. a meta-schema vocabulary schema).
A meta-schema typically has the unique property that it is an instance of itself. It may also be an instance of a number of other schemas, each of which may be an instance of the meta-schema, itself, and/or other schemas.
This is not a configuration of schemas/instances that normal JSI::Base instantiation can accommodate. MetaSchemaNode instead bootstraps each node on initialization, computing and instantiating the schemas that describe it (other MetaSchemaNode instances) and their schema modules. This results in a node that is a meta-schema being an instance of its own schema module (as well as JSI::Schema and JSI::Schema::MetaSchema), and a node that is a schema being an instance of the meta-schema's schema module (and thereby JSI::Schema).
The meta-schema may be anywhere in a document, though it is rare to put it anywhere but at the root.
The root of the meta-schema is referenced by the configured
metaschema_root_ref.
The schema describing the root of the document is referenced by the configured
root_schema_ref.
Defined Under Namespace
Classes: BootstrapSchema, Conf
Instance Attribute Summary collapse
-
#jsi_schemas ⇒ JSI::SchemaSet
readonly
JSI Schemas describing this MetaSchemaNode.
Attributes included from Base::Immutable
Attributes inherited from Base
#jsi_conf, #jsi_document, #jsi_ptr, #jsi_root_node
Attributes included from Schema::SchemaAncestorNode
#jsi_base_uri, #jsi_schema_dynamic_anchor_map, #jsi_schema_resource_ancestors
Instance Method Summary collapse
-
#initialize(jsi_ptr: Ptr[], jsi_root_node: nil, **kw) ⇒ MetaSchemaNode
constructor
private
See new_metaschema_node to instantiate.
-
#jsi_child_node(token) ⇒ Object
see Base#jsi_child_node.
- #jsi_fingerprint ⇒ Object private
- #jsi_indicated_schemas ⇒ JSI::SchemaSet
- #jsi_initialize_finish ⇒ Object private
- #jsi_modified_copy ⇒ Object
Methods included from Base::Immutable
Methods inherited from Base
#/, #[], #[]=, #as_json, #described_by?, #dup, #encode_with, inspect, #jmespath_search, #jsi_ancestor_nodes, #jsi_array?, #jsi_as_child_default_as_jsi, #jsi_child_as_jsi_default, #jsi_child_ensure_present, #jsi_child_token_present?, #jsi_child_use_default_default, #jsi_descendent_node, #jsi_each_child_token, #jsi_each_descendent_node, #jsi_each_descendent_schema, #jsi_each_descendent_schema_same_resource, #jsi_hash?, #jsi_instance, #jsi_is_schema?, #jsi_mutable?, #jsi_node_content, #jsi_node_content_child, #jsi_parent_node, #jsi_parent_nodes, #jsi_registry, #jsi_resource_root, #jsi_select_descendents_leaf_first, #jsi_select_descendents_node_first, #jsi_valid!, #jsi_valid?, #jsi_validate, name, #pretty_print, #to_json, to_s
Methods included from Schema::SchemaAncestorNode
#jsi_anchor_subschemas, #jsi_is_resource_root?, #jsi_next_base_uri, #jsi_resource_root, #jsi_resource_uri, #jsi_resource_uris, #jsi_schema_base_uri, #jsi_schema_registry
Constructor Details
#initialize(jsi_ptr: Ptr[], jsi_root_node: nil, **kw) ⇒ MetaSchemaNode
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.
See JSI.new_metaschema_node to instantiate.
Note: when instantiating MetaSchemaNode directly, the caller must invoke #jsi_initialize_finish.
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 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 90 def initialize( jsi_ptr: Ptr[], jsi_root_node: nil, **kw ) super( jsi_ptr: jsi_ptr, jsi_indicated_schemas: SchemaSet[], # MSN doesn't track schema_resource_ancestors through descendents, but the root is included when appropriate jsi_schema_resource_ancestors: jsi_ptr.root? || !jsi_root_node.is_a?(Schema) ? Util::EMPTY_ARY : [jsi_root_node].freeze, jsi_root_node: jsi_root_node, **kw, ) @initialize_finish_started = false @initialize_finished = false @to_initialize_finish = [] if jsi_ptr.root? && jsi_base_uri raise(NotImplementedError, "unsupported jsi_base_uri on meta-schema document root") end #chkbug fail(Bug, 'MetaSchemaNode instance must be frozen') unless jsi_node_content.frozen? bootstrap_schema_from_ref = proc do |ref_uri| ref_uri_nofrag = ref_uri.merge(fragment: nil) if ref_uri_nofrag.empty? ptr = Ptr.from_fragment(ref_uri.fragment).resolve_against(jsi_document) # anchor not supported if jsi_conf.root_schema_ref == jsi_conf. # root is a schema jsi_conf.dialect.bootstrap_schema( jsi_document: jsi_document, jsi_base_uri: nil, # not supported jsi_registry: jsi_conf.bootstrap_registry, ).resource_root_subschema(ptr) else jsi_conf.dialect.bootstrap_schema( jsi_document: jsi_document, jsi_ptr: ptr, jsi_base_uri: nil, # not supported jsi_registry: jsi_conf.bootstrap_registry, ) end else # if not fragment-only, ref must be registered in the bootstrap_registry ref = Schema::Ref.new(ref_uri, registry: jsi_conf.bootstrap_registry) ref.resolve end end @bootstrap_metaschema = bootstrap_schema_from_ref[jsi_conf.] instance_for_schemas = jsi_document root_bootstrap_schema = bootstrap_schema_from_ref[jsi_conf.root_schema_ref] our_bootstrap_indicated_schemas = jsi_ptr.tokens.inject(SchemaSet[root_bootstrap_schema]) do |bootstrap_indicated_schemas, tok| child_indicated_schemas = bootstrap_indicated_schemas.each_yield_set do |is, y| is.each_inplace_child_applicator_schema(tok, instance_for_schemas, collect_evaluated_validate: jsi_conf.application_collect_evaluated_validate, &y ) end instance_for_schemas = instance_for_schemas[tok] child_indicated_schemas end @indicated_schemas_map = jsi_memomap do SchemaSet.new(our_bootstrap_indicated_schemas) { |s| bootstrap_schema_to_msn(s) } end @bootstrap_schemas = our_bootstrap_indicated_schemas.each_yield_set do |is, y| is.each_inplace_applicator_schema(instance_for_schemas, &y) # note: instance_for_schemas == jsi_node_content now end @jsi_schemas = @bootstrap_schemas @bootstrap_schemas.each do |bootstrap_schema| if instance_exec(bootstrap_schema, &jsi_conf.) # this is described by the meta-schema, i.e. this is a schema define_singleton_method(:dialect) { jsi_conf.dialect } extend(Schema) if jsi_registry && jsi_resource_uris.any? { |uri| !jsi_registry.registered?(uri) } jsi_registry.register_immediate(self) end end end end |
Instance Attribute Details
#jsi_schemas ⇒ JSI::SchemaSet (readonly)
JSI Schemas describing this MetaSchemaNode
221 222 223 |
# File 'lib/jsi/metaschema_node.rb', line 221 def jsi_schemas @jsi_schemas end |
Instance Method Details
#jsi_child_node(token) ⇒ Object
230 231 232 |
# File 'lib/jsi/metaschema_node.rb', line 230 def jsi_child_node(token) root_descendent_node(jsi_ptr[token]) 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.
256 257 258 259 260 261 262 263 264 265 |
# File 'lib/jsi/metaschema_node.rb', line 256 def jsi_fingerprint { class: self.class, jsi_document: jsi_document, jsi_ptr: jsi_ptr, jsi_base_uri: jsi_base_uri, jsi_schema_dynamic_anchor_map: jsi_schema_dynamic_anchor_map, **jsi_conf.for_fingerprint, }.freeze end |
#jsi_indicated_schemas ⇒ JSI::SchemaSet
225 226 227 |
# File 'lib/jsi/metaschema_node.rb', line 225 def jsi_indicated_schemas @indicated_schemas_map[] end |
#jsi_initialize_finish ⇒ 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.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/jsi/metaschema_node.rb', line 179 def jsi_initialize_finish return self if @initialize_finish_started @initialize_finish_started = true @jsi_schemas = SchemaSet.new(@bootstrap_schemas) { |s| bootstrap_schema_to_msn(s) } # note: jsi_schemas must already be set for jsi_schema_module to be used/extended if instance_exec(self, &jsi_conf.) describes_schema!(jsi_conf.dialect) end extends_for_instance = JSI::SchemaClasses.includes_for(jsi_node_content) conflicting_modules = Set[self.class] + extends_for_instance + @jsi_schemas.map(&:jsi_schema_module) reader_modules = @jsi_schemas.map do |schema| JSI::SchemaClasses.schema_property_reader_module(schema, conflicting_modules: conflicting_modules) end readers = reader_modules.map(&:jsi_property_readers).inject(Set[], &:merge).freeze define_singleton_method(:jsi_property_readers) { readers } reader_modules.each { |reader_module| extend reader_module } extends_for_instance.each do |m| extend m end @jsi_schemas.each do |schema| extend schema.jsi_schema_module end @initialize_finished = true while !@to_initialize_finish.empty? node = @to_initialize_finish.shift node.jsi_initialize_finish end jsi_initialized end |
#jsi_modified_copy ⇒ Object
241 242 243 244 245 246 |
# File 'lib/jsi/metaschema_node.rb', line 241 def jsi_modified_copy(**) # this had an implementation previously (see git history). but for 2020-12, support for multiple # mutually-descriptive schemas as well as dynamic scope makes instantiating a modified copy that # preserves self-descriptive/mutually-descriptive relationships generally infeasible. raise(NotImplementedError) end |