def __init__(self, constraint, shape, validator, param_bind_map):
        """

        :param constraint:
        :type constraint: SPARQLConstraintComponent
        :param shape:
        :type shape: pyshacl.shape.Shape
        :param validator:
        :type validator: AskConstraintValidator | SelectConstraintValidator
        :param param_bind_map:
        :type param_bind_map: dict
        """
        super(BoundShapeValidatorComponent, self).__init__(shape)
        self.constraint = constraint
        self.validator = validator
        self.param_bind_map = param_bind_map
        self.query_helper = SPARQLQueryHelper(self.shape,
                                              validator.node,
                                              validator.query_text,
                                              messages=validator.messages)
        self.query_helper.collect_prefixes()
        self.message_bind_map = {}
        message_var_finder = re.compile(r"([\s()\"\'])\{[\$\?](\w+)\}",
                                        flags=re.M)
        var_replacers = {}
        self.messages = set()
        for m in self.query_helper.messages:
            m_val = str(m.value)
            finds = message_var_finder.findall(m_val)
            if len(finds) < 1:
                self.messages.add(m)
                continue
            for f in finds:
                variable = f[1]
                if variable not in param_bind_map.keys():
                    continue
                try:
                    replacer = var_replacers[variable]
                except KeyError:
                    replacer = re.compile(r"([\s()\"\'])\{[\$\?]" + f[1] +
                                          r"\}",
                                          flags=re.M)
                    var_replacers[variable] = replacer
                m_val = replacer.sub(
                    r"\g<1>{}".format(param_bind_map[variable].value), m_val,
                    1)
            self.messages.add(
                rdflib.Literal(m_val, lang=m.language, datatype=m.datatype))
예제 #2
0
 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
     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()
예제 #3
0
class BoundShapeValidatorComponent(ConstraintComponent):
    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
        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()

    @classmethod
    def constraint_parameters(cls):
        # TODO:coverage: this is never used for this constraint?
        return [SH_validator, SH_nodeValidator, SH_propertyValidator]

    @classmethod
    def constraint_name(cls):
        return "ConstraintComponent"

    @classmethod
    def shacl_constraint_class(cls):
        # TODO:coverage: this is never used for this constraint?
        return SH_ConstraintComponent

    def evaluate(self, target_graph: GraphLike, focus_value_nodes: Dict,
                 _evaluation_path: List):
        """
        :type focus_value_nodes: dict
        :type target_graph: rdflib.Graph
        """
        reports = []
        non_conformant = False
        extra_messages = self.query_helper.messages or None
        rept_kwargs = {
            # TODO, determine if we need sourceConstraint here
            #  'source_constraint': self.validator.node,
            'constraint_component': self.constraint.node,
            'extra_messages': extra_messages,
        }
        for f, value_nodes in focus_value_nodes.items():
            # we don't use value_nodes in the sparql constraint
            # All queries are done on the corresponding focus node.
            try:
                violations = self.validator.validate(f, value_nodes,
                                                     target_graph,
                                                     self.query_helper)
            except ValidationFailure as e:
                raise e
            if not self.shape.is_property_shape:
                result_val = f
            else:
                result_val = None
            for v in violations:
                non_conformant = True
                if isinstance(v, bool) and v is True:
                    # TODO:coverage: No test for when violation is `True`
                    rept = self.make_v_result(target_graph,
                                              f,
                                              value_node=result_val,
                                              **rept_kwargs)
                elif isinstance(v, tuple):
                    t, p, v = v
                    if v is None:
                        v = result_val
                    rept = self.make_v_result(target_graph,
                                              t or f,
                                              value_node=v,
                                              result_path=p,
                                              **rept_kwargs)
                else:
                    rept = self.make_v_result(target_graph,
                                              f,
                                              value_node=v,
                                              **rept_kwargs)
                reports.append(rept)
        return (not non_conformant), reports
class BoundShapeValidatorComponent(ConstraintComponent):
    def __init__(self, constraint, shape, validator, param_bind_map):
        """

        :param constraint:
        :type constraint: SPARQLConstraintComponent
        :param shape:
        :type shape: pyshacl.shape.Shape
        :param validator:
        :type validator: AskConstraintValidator | SelectConstraintValidator
        :param param_bind_map:
        :type param_bind_map: dict
        """
        super(BoundShapeValidatorComponent, self).__init__(shape)
        self.constraint = constraint
        self.validator = validator
        self.param_bind_map = param_bind_map
        self.query_helper = SPARQLQueryHelper(self.shape,
                                              validator.node,
                                              validator.query_text,
                                              messages=validator.messages)
        self.query_helper.collect_prefixes()
        self.message_bind_map = {}
        message_var_finder = re.compile(r"([\s()\"\'])\{[\$\?](\w+)\}",
                                        flags=re.M)
        var_replacers = {}
        self.messages = set()
        for m in self.query_helper.messages:
            m_val = str(m.value)
            finds = message_var_finder.findall(m_val)
            if len(finds) < 1:
                self.messages.add(m)
                continue
            for f in finds:
                variable = f[1]
                if variable not in param_bind_map.keys():
                    continue
                try:
                    replacer = var_replacers[variable]
                except KeyError:
                    replacer = re.compile(r"([\s()\"\'])\{[\$\?]" + f[1] +
                                          "\}",
                                          flags=re.M)
                    var_replacers[variable] = replacer
                m_val = replacer.sub(
                    "\g<1>{}".format(param_bind_map[variable].value), m_val, 1)
            self.messages.add(
                rdflib.Literal(m_val, lang=m.language, datatype=m.datatype))

    @classmethod
    def constraint_parameters(cls):
        # TODO:coverage: this is never used for this constraint?
        return [
            SH_validator, SH_nodeValidator, SH_propertyValidator, SH_parameter
        ]

    @classmethod
    def constraint_name(cls):
        return "ConstraintComponent"

    @classmethod
    def shacl_constraint_class(cls):
        # TODO:coverage: this is never used for this constraint?
        return SH_ConstraintComponent

    def evaluate(self, target_graph, focus_value_nodes):
        """
        :type focus_value_nodes: dict
        :type target_graph: rdflib.Graph
        """
        reports = []
        non_conformant = False
        extra_messages = self.messages or None
        rept_kwargs = {
            # TODO, determine if we need sourceConstraint here
            #'source_constraint': self.validator.node,
            'constraint_component': self.constraint.node,
            'extra_messages': extra_messages
        }
        for f, value_nodes in focus_value_nodes.items():
            # we don't use value_nodes in the sparql constraint
            # All queries are done on the corresponding focus node.
            try:
                violations = self.validator.validate(f, value_nodes,
                                                     target_graph,
                                                     self.query_helper,
                                                     self.param_bind_map)
            except ValidationFailure as e:
                raise e
            if not self.shape.is_property_shape:
                result_val = f
            else:
                result_val = None
            for v in violations:
                non_conformant = True
                if isinstance(v, bool) and v is True:
                    # TODO:coverage: No test for when violation is `True`
                    rept = self.make_v_result(f,
                                              value_node=result_val,
                                              **rept_kwargs)
                elif isinstance(v, tuple):
                    t, p, v = v
                    if v is None:
                        v = result_val
                    rept = self.make_v_result(t or f,
                                              value_node=v,
                                              result_path=p,
                                              **rept_kwargs)
                else:
                    rept = self.make_v_result(f, value_node=v, **rept_kwargs)
                reports.append(rept)
        return (not non_conformant), reports