Class ShaclSail

java.lang.Object
All Implemented Interfaces:
FederatedServiceResolverClient, NotifyingSail, Sail, StackableSail

public class ShaclSail extends NotifyingSailWrapper
A Sail implementation that adds support for the Shapes Constraint Language (SHACL).

The ShaclSail looks for SHACL shape data in a special named graph RDF4J.SHACL_SHAPE_GRAPH.

Working example

 import java.io.IOException;
 import java.io.StringReader;

 import org.eclipse.rdf4j.common.exception.ValidationException;
 import org.eclipse.rdf4j.model.Model;
 import org.eclipse.rdf4j.model.vocabulary.RDF4J;
 import org.eclipse.rdf4j.repository.RepositoryException;
 import org.eclipse.rdf4j.repository.sail.SailRepository;
 import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
 import org.eclipse.rdf4j.rio.RDFFormat;
 import org.eclipse.rdf4j.rio.Rio;
 import org.eclipse.rdf4j.rio.WriterConfig;
 import org.eclipse.rdf4j.rio.helpers.BasicWriterSettings;
 import org.eclipse.rdf4j.sail.memory.MemoryStore;
 import org.eclipse.rdf4j.sail.shacl.ShaclSail;

 public class ShaclSampleCode {

     public static void main(String[] args) throws IOException {

         ShaclSail shaclSail = new ShaclSail(new MemoryStore());

         SailRepository sailRepository = new SailRepository(shaclSail);
         sailRepository.init();

         try (SailRepositoryConnection connection = sailRepository.getConnection()) {

             connection.begin();

             StringReader shaclRules = new StringReader(String.join("\n", "",
                     "@prefix ex: <http://example.com/ns#> .",
                     "@prefix sh: <http://www.w3.org/ns/shacl#> .",
                     "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .",
                     "@prefix foaf: <http://xmlns.com/foaf/0.1/>.",

                     "ex:PersonShape",
                     "    a sh:NodeShape  ;",
                     "    sh:targetClass foaf:Person ;",
                     "    sh:property ex:PersonShapeProperty .",

                     "ex:PersonShapeProperty ",
                     "    sh:path foaf:age ;",
                     "    sh:datatype xsd:int ;",
                     "    sh:maxCount 1 ;",
                     "    sh:minCount 1 ."
             ));

             connection.add(shaclRules, "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH);
             connection.commit();

             connection.begin();

             StringReader invalidSampleData = new StringReader(String.join("\n", "",
                     "@prefix ex: <http://example.com/ns#> .",
                     "@prefix foaf: <http://xmlns.com/foaf/0.1/>.",
                     "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .",

                     "ex:peter a foaf:Person ;",
                     "    foaf:age 20, \"30\"^^xsd:int  ."

             ));

             connection.add(invalidSampleData, "", RDFFormat.TURTLE);
             try {
                 connection.commit();
             } catch (RepositoryException exception) {
                 Throwable cause = exception.getCause();
                 if (cause instanceof ValidationException) {

                     // use the validationReportModel to understand validation violations
                     Model validationReportModel = ((ValidationException) cause).validationReportAsModel();

                     // Pretty print the validation report
                     WriterConfig writerConfig = new WriterConfig()
                             .set(BasicWriterSettings.PRETTY_PRINT, true)
                             .set(BasicWriterSettings.INLINE_BLANK_NODES, true);

                     Rio.write(validationReportModel, System.out, RDFFormat.TURTLE, writerConfig);
                     System.out.println();
                 }

                 throw exception;
             }
         }
     }
 }
 
Author:
Heshan Jayasinghe, HÃ¥vard Ottestad
See Also: