Class: SHACL::Algebra::NodeShape
- Defined in:
- lib/shacl/algebra/node_shape.rb
Constant Summary collapse
- NAME =
:NodeShape
Constants inherited from Shape
Constants inherited from Operator
Instance Attribute Summary
Attributes inherited from Operator
Instance Method Summary collapse
-
#conforms(node, depth: 0, **options) ⇒ Array<SHACL::ValidationResult>
Validates the specified ‘node` within `graph`, a list of ValidationResult.
Methods inherited from Shape
#builtin_class, #builtin_datatype, #builtin_disjoint, #builtin_equals, #builtin_hasValue, #builtin_in, #builtin_languageIn, #builtin_maxExclusive, #builtin_maxInclusive, #builtin_maxLength, #builtin_minExclusive, #builtin_minInclusive, #builtin_minLength, #builtin_nodeKind, #builtin_pattern, #targetNodes
Methods inherited from Operator
apply_op, #comment, #deactivated?, from_expanded_value, from_json, #id, iri, #iri, #label, #not_satisfied, parse_path, #satisfy, to_rdf, #to_sxp_bin, #type
Instance Method Details
#conforms(node, depth: 0, **options) ⇒ Array<SHACL::ValidationResult>
Validates the specified ‘node` within `graph`, a list of ValidationResult.
A node conforms if it is not deactivated and all of its operands conform.
16 17 18 19 20 21 22 23 24 25 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 |
# File 'lib/shacl/algebra/node_shape.rb', line 16 def conforms(node, depth: 0, **) return [] if deactivated? = id ? .merge(shape: id) : = .merge(severity: RDF::Vocab::SHACL.Violation) log_debug(NAME, depth: depth) {SXP::Generator.string({id: id, node: node}.to_sxp_bin)} # Add some instance options to the argument = i{ flags qualifiedMinCount qualifiedMaxCount qualifiedValueShapesDisjoint severity }.inject() do |memo, sym| [sym] ? memo.merge(sym => [sym]) : memo end # Evaluate against builtins builtin_results = .map do |k, v| self.send("builtin_#{k}".to_sym, v, node, nil, [node], depth: depth + 1, **) if self.respond_to?("builtin_#{k}".to_sym) end.flatten.compact # Handle closed shapes # FIXME: this only considers URI paths, not property paths closed_results = [] if [:closed] shape_paths = operands.select {|o| o.is_a?(PropertyShape)}.map(&:path) shape_properties = shape_paths.select {|p| p.is_a?(RDF::URI)} shape_properties += Array([:ignoredProperties]) closed_results = graph.query({subject: node}).map do |statement| next if shape_properties.include?(statement.predicate) not_satisfied(focus: node, value: statement.object, path: statement.predicate, message: "closed node has extra property", resultSeverity: .fetch(:severity), component: RDF::Vocab::SHACL.ClosedConstraintComponent, **) end.compact end # Evaluate against operands op_results = operands.map do |op| res = op.conforms(node, focus: .fetch(:focusNode, node), depth: depth + 1, **) if op.is_a?(NodeShape) && !res.all?(&:conform?) # Special case for embedded NodeShape not_satisfied(focus: node, value: node, message: "node does not conform to #{op.id}", resultSeverity: .fetch(:severity), component: RDF::Vocab::SHACL.NodeConstraintComponent, **) else res end end.flatten.compact builtin_results + closed_results + op_results end |