Example #1
0
    def __init__(self, shape: 'Shape', rule_node: 'rdflib.term.Identifier', **kwargs):
        """

        :param shape:
        :type shape: Shape
        :param rule_node:
        :type rule_node: rdflib.term.Identifier
        """
        super(SPARQLRule, self).__init__(shape, rule_node, **kwargs)
        construct_nodes = set(self.shape.sg.objects(self.node, SH_construct))
        if len(construct_nodes) < 1:
            raise RuleLoadError("No sh:construct on SPARQLRule", "https://www.w3.org/TR/shacl-af/#SPARQLRule")
        self._constructs = []
        for c in construct_nodes:
            if not isinstance(c, Literal) or not (
                c.datatype == XSD_string or c.language is not None or isinstance(c.value, str)
            ):
                raise RuleLoadError(
                    "SPARQLRule sh:construct must be an xsd:string", "https://www.w3.org/TR/shacl-af/#SPARQLRule"
                )
            self._constructs.append(str(c.value))
        SPARQLQueryHelper = get_query_helper_cls()
        query_helper = SPARQLQueryHelper(self.shape, self.node, None, deactivated=self._deactivated)
        query_helper.collect_prefixes()
        self._qh = query_helper
 def __init__(self, shape):
     super(SPARQLBasedConstraint, self).__init__(shape)
     sg = self.shape.sg.graph
     sparql_node_list = set(self.shape.objects(SH_sparql))
     if len(sparql_node_list) < 1:
         raise ConstraintLoadError(
             "SPARQLConstraintComponent must have at least one sh:sparql predicate.",
             "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
         )
     sparql_constraints = set()
     for s in iter(sparql_node_list):
         select_node_list = set(sg.objects(s, SH_select))
         if len(select_node_list) < 1:
             raise ConstraintLoadError(
                 "SPARQLConstraintComponent value for sh:select must have at least one sh:select predicate.",
                 "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
             )
         elif len(select_node_list) > 1:
             raise ConstraintLoadError(
                 "SPARQLConstraintComponent value for sh:select must have at most one sh:select predicate.",
                 "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
             )
         select_node = next(iter(select_node_list))
         if not (isinstance(select_node, rdflib.Literal) and isinstance(select_node.value, str)):
             raise ConstraintLoadError(
                 "SPARQLConstraintComponent value for sh:select must be a Literal with type xsd:string.",
                 "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
             )
         message_node_list = set(sg.objects(s, SH_message))
         msgs = None
         if len(message_node_list) > 0:
             message = next(iter(message_node_list))
             if not (isinstance(message, rdflib.Literal) and isinstance(message.value, str)):
                 raise ConstraintLoadError(
                     "SPARQLConstraintComponent value for sh:message must be a Literal with type xsd:string.",
                     "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
                 )
             msgs = message_node_list
         deactivated_node_list = set(sg.objects(s, SH_deactivated))
         deact = False
         if len(deactivated_node_list) > 0:
             deactivated = next(iter(deactivated_node_list))
             if not (isinstance(deactivated, rdflib.Literal) and isinstance(deactivated.value, bool)):
                 raise ConstraintLoadError(
                     "SPARQLConstraintComponent value for sh:deactivated must be "
                     "a Literal with type xsd:boolean.",
                     "https://www.w3.org/TR/shacl/#SPARQLConstraintComponent",
                 )
             deact = bool(deactivated.value)
         SPARQLQueryHelper = get_query_helper_cls()
         query_helper = SPARQLQueryHelper(self.shape, s, select_node.value, messages=msgs, deactivated=deact)
         query_helper.collect_prefixes()
         sparql_constraints.add(query_helper)
     self.sparql_constraints = sparql_constraints
Example #3
0
 def apply(self, data_graph: 'GraphLike') -> int:
     focus_nodes = self.shape.focus_nodes(data_graph)  # uses target nodes to find focus nodes
     all_added = 0
     SPARQLQueryHelper = get_query_helper_cls()
     iterate_limit = 100
     while True:
         if iterate_limit < 1:
             raise ReportableRuntimeError("Local rule iteration exceeded iteration limit of 100.")
         iterate_limit -= 1
         added = 0
         applicable_nodes = self.filter_conditions(focus_nodes, data_graph)
         construct_graphs = set()
         for a in applicable_nodes:
             for c in self._constructs:
                 init_bindings = {}
                 found_this = SPARQLQueryHelper.bind_this_regex.search(c)
                 if found_this:
                     init_bindings['this'] = a
                 c = self._qh.apply_prefixes(c)
                 results = data_graph.query(c, initBindings=init_bindings)
                 if results.type != "CONSTRUCT":
                     raise ReportableRuntimeError("Query executed by a SHACL SPARQLRule must be CONSTRUCT query.")
                 this_added = False
                 for i in results.graph:
                     if not this_added and i not in data_graph:
                         this_added = True
                         # We only need to know at least one triple was added, then break!
                         break
                 if this_added:
                     added += 1
                     construct_graphs.add(results.graph)
         if added > 0:
             for g in construct_graphs:
                 data_graph = clone_graph(g, target_graph=data_graph)
             all_added += added
             if self.iterate:
                 continue  # Jump up to iterate
             else:
                 break  # Don't iterate
         break  # We've reached a local steady state
     return all_added
Example #4
0
 def apply(self, data_graph):
     focus_nodes = self.shape.focus_nodes(
         data_graph)  # uses target nodes to find focus nodes
     applicable_nodes = self.filter_conditions(focus_nodes, data_graph)
     construct_graphs = set()
     SPARQLQueryHelper = get_query_helper_cls()
     for a in applicable_nodes:
         for c in self._constructs:
             init_bindings = {}
             found_this = SPARQLQueryHelper.bind_this_regex.search(c)
             if found_this:
                 init_bindings['this'] = a
             c = self._qh.apply_prefixes(c)
             results = data_graph.query(c, initBindings=init_bindings)
             if results.type != "CONSTRUCT":
                 raise ReportableRuntimeError(
                     "Query executed by a SHACL SPARQLRule must be CONSTRUCT query."
                 )
             construct_graphs.add(results.graph)
     for g in construct_graphs:
         data_graph = clone_graph(g, target_graph=data_graph)
 def __init__(self, constraint, shape: 'Shape', validator):
     """
     Create a new custom constraint, by applying a ConstraintComponent and a Validator to a Shape
     :param constraint: The source ConstraintComponent, this is needed to bind the parameters in the query_helper
     :type constraint: SPARQLConstraintComponent
     :param shape:
     :type shape: Shape
     :param validator:
     :type validator: AskConstraintValidator | SelectConstraintValidator
     """
     super(BoundShapeValidatorComponent, self).__init__(shape)
     self.constraint = constraint
     self.validator = validator
     params = constraint.parameters
     SPARQLQueryHelper = get_query_helper_cls()
     self.query_helper = SPARQLQueryHelper(self.shape,
                                           validator.node,
                                           validator.query_text,
                                           params,
                                           messages=validator.messages)
     # Setting self.shape into QueryHelper automatically applies query_helper.bind_params and bind_messages
     self.query_helper.collect_prefixes()