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))
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()
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