This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 928598dded GH-3386: Include sh:sourceConstraint in SHACL SPARQL
violations
928598dded is described below
commit 928598dded85714e8cf63add9d90cdec613ce599
Author: Andy Seaborne <[email protected]>
AuthorDate: Wed Aug 20 09:40:00 2025 +0100
GH-3386: Include sh:sourceConstraint in SHACL SPARQL violations
---
.../org/apache/jena/shacl/ValidationReport.java | 9 ++++--
.../jena/shacl/engine/ValidationContext.java | 7 ++++-
.../shacl/engine/constraint/SparqlValidation.java | 2 +-
.../apache/jena/shacl/validation/ReportEntry.java | 35 +++++++++++-----------
.../files/local/other/sparql-vars-001-results.ttl | 1 +
.../jena/shacl/tests/std/TestShaclSparqlWG.java | 2 +-
6 files changed, 34 insertions(+), 22 deletions(-)
diff --git
a/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
b/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
index dc4e03905e..1df900373b 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
@@ -176,10 +176,14 @@ public class ValidationReport {
}
public void addReportEntry(String message, Shape shape, Node
focusNode, Path path, Node valueNode, Constraint constraint) {
- addReportEntryW(message, shape, null, focusNode, path, valueNode,
constraint);
+ addReportEntry(message, shape, focusNode, path, valueNode,
constraint, null);
}
- private void addReportEntryW(String message, Shape shape, Triple
triple, Node focusNode, Path path, Node valueNode, Constraint constraint) {
+ public void addReportEntry(String message, Shape shape, Node
focusNode, Path path, Node valueNode, Constraint constraint, Node
sourceConstraint) {
+ addReportEntryW(message, shape, null, focusNode, path, valueNode,
constraint, sourceConstraint);
+ }
+
+ private void addReportEntryW(String message, Shape shape, Triple
triple, Node focusNode, Path path, Node valueNode, Constraint constraint, Node
sourceConstraint) {
Collection<Node> messages;
if ( shape.getMessages() != null && !
shape.getMessages().isEmpty() )
@@ -193,6 +197,7 @@ public class ValidationReport {
.severity(shape.getSeverity())
.source(shape.getShapeNode())
.constraint(constraint)
+ .sourceConstraint(sourceConstraint)
//.detail(null)
.value(valueNode)
.triple(triple)
diff --git
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/ValidationContext.java
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/ValidationContext.java
index 359d234ac6..eaaba7cbee 100644
---
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/ValidationContext.java
+++
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/ValidationContext.java
@@ -99,10 +99,15 @@ public class ValidationContext {
}
public void reportEntry(String message, Shape shape, Node focusNode, Path
path, Node valueNode, Constraint constraint) {
+ reportEntry(message, shape, focusNode, path, valueNode, constraint,
null);
+ }
+
+ public void reportEntry(String message, Shape shape, Node focusNode, Path
path, Node valueNode, Constraint constraint, Node sourceConstraint) {
+ // SHACL 1.0 - sourceConstraint is SPARQL specific.
if ( verbose )
System.out.println("Validation report entry");
seenValidationReportEntry = true;
- validationReportBuilder.addReportEntry(message, shape, focusNode,
path, valueNode, constraint);
+ validationReportBuilder.addReportEntry(message, shape, focusNode,
path, valueNode, constraint, sourceConstraint);
}
public ValidationReport generateReport() {
diff --git
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
index 6f4a725010..1ceffdbcf2 100644
---
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
+++
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
@@ -184,7 +184,7 @@ import org.apache.jena.sparql.util.ModelUtils;
final Node finalValue = value;
vCxt.notifyValidationListener(() ->
new ConstraintEvaluatedOnSinglePathNodeEvent(vCxt, shape,
focusNode, reportConstraint, finalRPath, finalValue, false));
- vCxt.reportEntry(msg, shape, focusNode, rPath, value,
reportConstraint);
+ vCxt.reportEntry(msg, shape, focusNode, rPath, value,
reportConstraint, /*sh:sourceConstaint*/shape.getShapeNode());
}
return false;
}
diff --git
a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
index 6358225faf..73e7e05b73 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
@@ -80,24 +80,25 @@ public class ReportEntry {
return new ReportEntry();
}
-// sh:result [ a sh:ValidationResult ;
-// sh:focusNode ex:x ;
-// sh:resultMessage "Value does not have class
http://example/ns#T" ;
-// sh:resultSeverity sh:Violation ;
-// sh:sourceConstraintComponent sh:ClassConstraintComponent ;
-// sh:sourceShape shx:class_T ;
-// sh:value ex:x
-// ]
// sh:result [
-// a sh:ValidationResult ;
-// sh:resultSeverity sh:Violation ;
-// sh:focusNode ex:Bob ;
-// sh:resultPath ex:age ;
-// sh:value "twenty two" ;
-// sh:resultMessage "ex:age expects a literal of datatype
xsd:integer." ;
-// sh:sourceConstraintComponent sh:DatatypeConstraintComponent ;
-// sh:sourceShape ex:PersonShape-age ;
-// ]
+// a sh:ValidationResult ;
+// sh:focusNode ex:x ;
+// sh:resultMessage "Value does not have class
http://example/ns#T" ;
+// sh:resultSeverity sh:Violation ;
+// sh:sourceConstraintComponent sh:ClassConstraintComponent ;
+// sh:sourceShape shx:class_T ;
+// sh:value ex:x
+// ]
+// sh:result [
+// a sh:ValidationResult ;
+// sh:resultSeverity sh:Violation ;
+// sh:focusNode ex:Bob ;
+// sh:resultPath ex:age ;
+// sh:value "twenty two" ;
+// sh:resultMessage "ex:age expects a literal of datatype
xsd:integer." ;
+// sh:sourceConstraintComponent sh:DatatypeConstraintComponent ;
+// sh:sourceShape ex:PersonShape-age ;
+// ]
public Node focusNode() { return focusNode; }
diff --git a/jena-shacl/src/test/files/local/other/sparql-vars-001-results.ttl
b/jena-shacl/src/test/files/local/other/sparql-vars-001-results.ttl
index 88cd6fc18f..21a949fa1d 100644
--- a/jena-shacl/src/test/files/local/other/sparql-vars-001-results.ttl
+++ b/jena-shacl/src/test/files/local/other/sparql-vars-001-results.ttl
@@ -12,6 +12,7 @@ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
sh:resultMessage "Property-value pair
(<http://example/p1> 1) found";
sh:resultPath :p1;
sh:resultSeverity sh:Violation;
+ sh:sourceConstraint
<http://jena.apache.org/test/shape#PropertyValueShape>;
sh:sourceConstraintComponent sh:SPARQLConstraintComponent;
sh:sourceShape <shape#PropertyValueShape>;
sh:value 1
diff --git
a/jena-shacl/src/test/java/org/apache/jena/shacl/tests/std/TestShaclSparqlWG.java
b/jena-shacl/src/test/java/org/apache/jena/shacl/tests/std/TestShaclSparqlWG.java
index b0fe3300ea..9a2e0b9f5e 100644
---
a/jena-shacl/src/test/java/org/apache/jena/shacl/tests/std/TestShaclSparqlWG.java
+++
b/jena-shacl/src/test/java/org/apache/jena/shacl/tests/std/TestShaclSparqlWG.java
@@ -37,7 +37,7 @@ public class TestShaclSparqlWG {
public static Collection<Object[]> data() throws Exception {
String manifest = "src/test/files/std/sparql/manifest.ttl";
- // The W3C WG tests for SPARQL-based Constraints is made up of:
+ // The W3C WG tests for SPARQL-based Constraints is made up of:
//String manifest = "src/test/files/std/sparql/property/manifest.ttl";
//String manifest =
"src/test/files/std/sparql/pre-binding/manifest.ttl";
//String manifest = "src/test/files/std/sparql/node/manifest.ttl";