1use indoc::formatdoc;
2use shacl_ast::compiled::component::CompiledComponent;
3use shacl_ast::compiled::property_shape::CompiledPropertyShape;
4use shacl_ast::compiled::shape::CompiledShape;
5use srdf::SHACLPath;
6use srdf::Sparql;
7use srdf::Term;
8
9use super::Engine;
10use crate::constraints::SparqlDeref;
11use crate::focus_nodes::FocusNodes;
12use crate::helpers::sparql::select;
13use crate::validate_error::ValidateError;
14use crate::validation_report::result::ValidationResult;
15use crate::value_nodes::ValueNodes;
16use std::fmt::Debug;
17
18pub struct SparqlEngine;
19
20impl<S: Sparql + Debug + 'static> Engine<S> for SparqlEngine {
21 fn evaluate(
22 &self,
23 store: &S,
24 shape: &CompiledShape<S>,
25 component: &CompiledComponent<S>,
26 value_nodes: &ValueNodes<S>,
27 source_shape: Option<&CompiledShape<S>>,
28 ) -> Result<Vec<ValidationResult>, ValidateError> {
29 let validator = component.deref();
30 Ok(validator.validate_sparql(component, shape, store, value_nodes, source_shape)?)
31 }
32
33 fn target_node(&self, store: &S, node: &S::Term) -> Result<FocusNodes<S>, ValidateError> {
36 if node.is_blank_node() {
37 return Err(ValidateError::TargetNodeBlankNode);
38 }
39
40 let query = formatdoc! {"
41 SELECT DISTINCT ?this
42 WHERE {{
43 BIND ({} AS ?this)
44 }}
45 ", node};
46
47 select(store, query, "this")?;
48
49 Err(ValidateError::NotImplemented {
50 msg: "target_node".to_string(),
51 })
52 }
53
54 fn target_class(&self, store: &S, class: &S::Term) -> Result<FocusNodes<S>, ValidateError> {
55 if !class.is_iri() {
56 return Err(ValidateError::TargetClassNotIri);
57 }
58
59 let query = formatdoc! {"
60 PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
61 PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
62
63 SELECT DISTINCT ?this
64 WHERE {{
65 ?this rdf:type/rdfs:subClassOf* {} .
66 }}
67 ", class};
68
69 select(store, query, "this")?;
70
71 Err(ValidateError::NotImplemented {
72 msg: "target_class".to_string(),
73 })
74 }
75
76 fn target_subject_of(
77 &self,
78 store: &S,
79 predicate: &S::IRI,
80 ) -> Result<FocusNodes<S>, ValidateError> {
81 let query = formatdoc! {"
82 SELECT DISTINCT ?this
83 WHERE {{
84 ?this {} ?any .
85 }}
86 ", predicate};
87
88 select(store, query, "this")?;
89
90 Err(ValidateError::NotImplemented {
91 msg: "target_subject_of".to_string(),
92 })
93 }
94
95 fn target_object_of(
96 &self,
97 store: &S,
98 predicate: &S::IRI,
99 ) -> Result<FocusNodes<S>, ValidateError> {
100 let query = formatdoc! {"
101 SELECT DISTINCT ?this
102 WHERE {{
103 ?any {} ?this .
104 }}
105 ", predicate};
106
107 select(store, query, "this")?;
108
109 Err(ValidateError::NotImplemented {
110 msg: "target_object_of".to_string(),
111 })
112 }
113
114 fn implicit_target_class(
115 &self,
116 _store: &S,
117 _shape: &S::Term,
118 ) -> Result<FocusNodes<S>, ValidateError> {
119 Err(ValidateError::NotImplemented {
120 msg: "implicit_target_class".to_string(),
121 })
122 }
123
124 fn predicate(
125 &self,
126 _store: &S,
127 _shape: &CompiledPropertyShape<S>,
128 _predicate: &S::IRI,
129 _focus_node: &S::Term,
130 ) -> Result<FocusNodes<S>, ValidateError> {
131 Err(ValidateError::NotImplemented {
132 msg: "predicate".to_string(),
133 })
134 }
135
136 fn alternative(
137 &self,
138 _store: &S,
139 _shape: &CompiledPropertyShape<S>,
140 _paths: &[SHACLPath],
141 _focus_node: &S::Term,
142 ) -> Result<FocusNodes<S>, ValidateError> {
143 Err(ValidateError::NotImplemented {
144 msg: "alternative".to_string(),
145 })
146 }
147
148 fn sequence(
149 &self,
150 _store: &S,
151 _shape: &CompiledPropertyShape<S>,
152 _paths: &[SHACLPath],
153 _focus_node: &S::Term,
154 ) -> Result<FocusNodes<S>, ValidateError> {
155 Err(ValidateError::NotImplemented {
156 msg: "sequence".to_string(),
157 })
158 }
159
160 fn inverse(
161 &self,
162 _store: &S,
163 _shape: &CompiledPropertyShape<S>,
164 _path: &SHACLPath,
165 _focus_node: &S::Term,
166 ) -> Result<FocusNodes<S>, ValidateError> {
167 Err(ValidateError::NotImplemented {
168 msg: "inverse".to_string(),
169 })
170 }
171
172 fn zero_or_more(
173 &self,
174 _store: &S,
175 _shape: &CompiledPropertyShape<S>,
176 _path: &SHACLPath,
177 _focus_node: &S::Term,
178 ) -> Result<FocusNodes<S>, ValidateError> {
179 Err(ValidateError::NotImplemented {
180 msg: "zero_or_more".to_string(),
181 })
182 }
183
184 fn one_or_more(
185 &self,
186 _store: &S,
187 _shape: &CompiledPropertyShape<S>,
188 _path: &SHACLPath,
189 _focus_node: &S::Term,
190 ) -> Result<FocusNodes<S>, ValidateError> {
191 Err(ValidateError::NotImplemented {
192 msg: "one_or_more".to_string(),
193 })
194 }
195
196 fn zero_or_one(
197 &self,
198 _store: &S,
199 _shape: &CompiledPropertyShape<S>,
200 _path: &SHACLPath,
201 _focus_node: &S::Term,
202 ) -> Result<FocusNodes<S>, ValidateError> {
203 Err(ValidateError::NotImplemented {
204 msg: "zero_or_one".to_string(),
205 })
206 }
207}