1616import java .util .Collections ;
1717import java .util .HashSet ;
1818import java .util .List ;
19+ import java .util .Optional ;
1920import java .util .Set ;
21+ import java .util .function .Function ;
2022
2123import org .eclipse .rdf4j .model .Namespace ;
2224import org .eclipse .rdf4j .model .Resource ;
2325import org .eclipse .rdf4j .model .Value ;
26+ import org .eclipse .rdf4j .query .BindingSet ;
2427import org .eclipse .rdf4j .sail .SailConnection ;
2528import org .eclipse .rdf4j .sail .shacl .ast .StatementMatcher .Variable ;
2629import org .eclipse .rdf4j .sail .shacl .ast .constraintcomponents .ConstraintComponent ;
2730import org .eclipse .rdf4j .sail .shacl .ast .planNodes .EmptyNode ;
2831import org .eclipse .rdf4j .sail .shacl .ast .planNodes .PlanNode ;
2932import org .eclipse .rdf4j .sail .shacl .ast .planNodes .Select ;
30- import org .eclipse .rdf4j .sail .shacl .ast .planNodes .ValidationReportNode ;
3133import org .eclipse .rdf4j .sail .shacl .ast .planNodes .ValidationTuple ;
3234import org .eclipse .rdf4j .sail .shacl .results .ValidationResult ;
3335
3436public class ValidationQuery {
3537
3638 private final Set <Namespace > namespaces = new HashSet <>();
39+ private ValidationResultGenerator validationResultGenerator ;
3740 private String query ;
3841 private ConstraintComponent .Scope scope ;
3942 private ConstraintComponent .Scope scope_validationReport ;
@@ -54,6 +57,7 @@ public class ValidationQuery {
5457
5558 private Severity severity ;
5659 private Shape shape ;
60+ private List <Variable <?>> extraVariables = List .of ();
5761
5862 public ValidationQuery (Collection <Namespace > namespaces , String query , List <Variable <Value >> targets ,
5963 Variable <Value > value ,
@@ -90,6 +94,8 @@ public ValidationQuery(Collection<Namespace> namespaces, String query, List<Vari
9094 this .constraintComponent = constraintComponent ;
9195 this .severity = severity ;
9296 this .shape = shape ;
97+ this .validationResultGenerator = new ValidationResultGenerator ();
98+
9399 }
94100
95101 public ValidationQuery (Set <Namespace > namespaces , String query , ConstraintComponent .Scope scope ,
@@ -101,6 +107,7 @@ public ValidationQuery(Set<Namespace> namespaces, String query, ConstraintCompon
101107 this .variables = Collections .unmodifiableList (variables );
102108 this .targetIndex = targetIndex ;
103109 this .valueIndex = valueIndex ;
110+ this .validationResultGenerator = new ValidationResultGenerator ();
104111 }
105112
106113 /**
@@ -169,41 +176,78 @@ public PlanNode getValidationPlan(SailConnection baseConnection, Resource[] data
169176
170177 Select select = new Select (baseConnection , fullQueryString , bindings -> {
171178
179+ var validationResultFunction = validationResultGenerator .getValidationTupleValidationResultFunction (this ,
180+ shapesGraphs , bindings );
181+
182+ ValidationTuple validationTuple ;
183+
172184 if (scope_validationReport == ConstraintComponent .Scope .propertyShape ) {
173185 if (propertyShapeWithValue_validationReport ) {
174- return new ValidationTuple (bindings .getValue (getTargetVariable (true )),
186+ validationTuple = new ValidationTuple (bindings .getValue (getTargetVariable (true )),
175187 bindings .getValue (getValueVariable (true )),
176188 scope_validationReport , true , dataGraph );
177189 } else {
178- return new ValidationTuple (bindings .getValue (getTargetVariable (true )),
190+ validationTuple = new ValidationTuple (bindings .getValue (getTargetVariable (true )),
179191 scope_validationReport , false , dataGraph );
180192 }
181193
182194 } else {
183- return new ValidationTuple (bindings .getValue (getTargetVariable (true )),
195+ validationTuple = new ValidationTuple (bindings .getValue (getTargetVariable (true )),
184196 scope_validationReport , true , dataGraph );
185197 }
186198
199+ return validationTuple .addValidationResult (validationResultFunction );
200+
187201 }, dataGraph );
188202
189- return new ValidationReportNode (select , t -> {
190- return new ValidationResult (t .getActiveTarget (), t .getValue (), shape ,
191- constraintComponent_validationReport , severity , t .getScope (), t .getContexts (), shapesGraphs );
192- });
203+ return select ;
204+
205+ }
206+
207+ public static class ValidationResultGenerator {
208+
209+ public Function <ValidationTuple , ValidationResult > getValidationTupleValidationResultFunction (
210+ ValidationQuery validationQuery , Resource [] shapesGraphs , BindingSet bindings ) {
211+ return t -> new ValidationResult (t .getActiveTarget (), t .getValue (), validationQuery .shape ,
212+ validationQuery .constraintComponent_validationReport , validationQuery .severity , t .getScope (),
213+ t .getContexts (), shapesGraphs );
214+ }
215+
216+ }
193217
218+ public void setValidationResultGenerator (List <Variable <?>> extraVariables ,
219+ ValidationResultGenerator validationResultGenerator ) {
220+ this .validationResultGenerator = validationResultGenerator ;
221+ this .extraVariables = extraVariables ;
194222 }
195223
196224 private String getFullQueryString () {
225+ String extraVariablesString ;
226+ if (!extraVariables .isEmpty ()) {
227+ Optional <String > reduce = extraVariables .stream ()
228+ .map (Variable ::asSparqlVariable )
229+ .reduce ((a , b ) -> a + " " + b );
230+ if (reduce .isPresent ()) {
231+ extraVariablesString = reduce .get () + " " ;
232+ } else {
233+ extraVariablesString = "" ;
234+ }
235+ } else
236+ extraVariablesString = "" ;
237+
197238 if (scope_validationReport == ConstraintComponent .Scope .propertyShape
198239 && propertyShapeWithValue_validationReport ) {
240+
199241 return ShaclPrefixParser .toSparqlPrefixes (namespaces ) + "\n SELECT DISTINCT " +
200242 "?" + getTargetVariable (true ) + " " +
201243 "?" + getValueVariable (true ) + " " +
244+ extraVariablesString +
202245 "WHERE {\n " + query + "\n }" ;
203246
204247 } else {
205248 return ShaclPrefixParser .toSparqlPrefixes (namespaces ) + "\n SELECT DISTINCT " +
206249 "?" + getTargetVariable (true ) + " " +
250+ extraVariablesString +
207251 "WHERE {\n " + query + "\n }" ;
208252 }
209253 }
@@ -267,6 +311,18 @@ public void makeCurrentStateValidationReport() {
267311 propertyShapeWithValue_validationReport = propertyShapeWithValue ;
268312 }
269313
314+ public Shape getShape () {
315+ return shape ;
316+ }
317+
318+ public Severity getSeverity () {
319+ return severity ;
320+ }
321+
322+ public ConstraintComponent getConstraintComponent_validationReport () {
323+ return constraintComponent_validationReport ;
324+ }
325+
270326 // used for sh:deactivated
271327 public static class Deactivated extends ValidationQuery {
272328
0 commit comments