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-site.git
The following commit(s) were added to refs/heads/main by this push:
new 74d2d8fbc Add ValidationListener documentation (#107)
74d2d8fbc is described below
commit 74d2d8fbcf32b0a999433cf643b3fc28f955b065
Author: Florian Kleedorfer <[email protected]>
AuthorDate: Thu Aug 25 11:16:35 2022 +0200
Add ValidationListener documentation (#107)
---
source/documentation/shacl/__index.md | 65 +++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/source/documentation/shacl/__index.md
b/source/documentation/shacl/__index.md
index 7030574b1..a83ead13f 100644
--- a/source/documentation/shacl/__index.md
+++ b/source/documentation/shacl/__index.md
@@ -170,3 +170,68 @@ ex:example
""" ;
] ;
```
+## ValidationListener
+
+When given a `ValidationListener` the SHACL validation code emits events at
each step of validation:
+* when validation of a shape starts or finishes
+* when the focus nodes of the shape have been identified
+* when validation of a constraint begins, ends and yields positive or negative
results
+
+For example, the following listener will just record all events in a List:
+```
+public class RecordingValidationListener implements ValidationListener {
+ private final List<ValidationEvent> events = new ArrayList<>();
+
+ @Override public void onValidationEvent(ValidationEvent e) {
+ events.add(e);
+ }
+
+ public List<ValidationEvent> getEvents() {
+ return events;
+ }
+ }
+```
+The listener must be passed to the constructor of the `ValidationContext`.
+The following example validates the `dataGraph` according to the `shapesGraph`
using the ValidationListener above:
+```
+ Graph shapesGraph = RDFDataMgr.loadGraph(shapesGraphUri); //assuming
shapesGraphUri points to an RDF file
+ Graph dataGraph = RDFDataMgr.loadGraph(dataGraphUri); //assuming
dataGraphUri points to an RDF file
+ RecordingValidationListener listener = new RecordingValidationListener();
// see above
+ Shapes shapes = Shapes.parse(shapesGraph);
+ ValidationContext vCtx = ValidationContext.create(shapes, dataGraph,
listener); // pass listener here
+ for (Shape shape : shapes.getTargetShapes()) {
+ Collection<Node> focusNodes = VLib.focusNodes(dataGraph, shape);
+ for (Node focusNode : focusNodes) {
+ VLib.validateShape(vCtx, dataGraph, shape, focusNode);
+ }
+ }
+ List<ValidationEvent> actualEvents = listener.getEvents(); // all events
have been recorded
+```
+
+The events thus generated might look like this (`event.toString()`, one per
line):
+```
+
FocusNodeValidationStartedEvent{focusNode=http://datashapes.org/sh/tests/core/node/class-001.test#Someone,
shape=NodeShape[http://datashapes.org/sh/tests/core/node/class-001.test#TestShape]}
+
ConstraintEvaluationForNodeShapeStartedEvent{constraint=ClassConstraint[<http://datashapes.org/sh/tests/core/node/class-001.test#Person>],
focusNode=http://datashapes.org/sh/tests/core/node/class-001.test#Someone,
shape=NodeShape[http://datashapes.org/sh/tests/core/node/class-001.test#TestShape]}
+
ConstraintEvaluatedOnFocusNodeEvent{constraint=ClassConstraint[<http://datashapes.org/sh/tests/core/node/class-001.test#Person>],
focusNode=http://datashapes.org/sh/tests/core/node/class-001.test#Someone,
shape=NodeShape[http://datashapes.org/sh/tests/core/node/class-001.test#TestShape],
valid=true}
+
ConstraintEvaluationForNodeShapeFinishedEvent{constraint=ClassConstraint[<http://datashapes.org/sh/tests/core/node/class-001.test#Person>],
focusNode=http://datashapes.org/sh/tests/core/node/class-001.test#Someone,
shape=NodeShape[http://datashapes.org/sh/tests/core/node/class-001.test#TestShape]}
+
FocusNodeValidationFinishedEvent{focusNode=http://datashapes.org/sh/tests/core/node/class-001.test#Someone,
shape=NodeShape[http://datashapes.org/sh/tests/core/node/class-001.test#TestShape]}
+[...]
+```
+Many use cases can be addressed with the `HandlerBasedValidationListener`,
which allows for registering event handlers on a per-event basis.
+For example:
+```
+ ValidationListener myListener = HandlerBasedValidationListener
+ .builder()
+ .forEventType(FocusNodeValidationStartedEvent.class)
+ .addSimpleHandler(e -> {
+ // ...
+ })
+ .forEventType(ConstraintEvaluatedEvent.class)
+ .addHandler(c -> c
+ .iff(EventPredicates.isValid()) // use a
Predicate<ValidationEvent> to select events
+ .handle(e -> {
+ // ...
+ })
+ )
+ .build();
+```