Class ShaclSail

  • All Implemented Interfaces:
    FederatedServiceResolverClient, NotifyingSail, Sail, StackableSail

    public class ShaclSail
    extends ShaclSailBaseConfiguration
    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;
                 }
             }
         }
     }
     
    See Also:
    SHACL W3C Recommendation
    • Field Detail

      • AVAILABLE_PROCESSORS

        private static final int AVAILABLE_PROCESSORS
      • logger

        private static final org.slf4j.Logger logger
      • supportsSnapshotIsolation

        private boolean supportsSnapshotIsolation
      • singleConnectionCounter

        private final transient java.util.concurrent.atomic.AtomicLong singleConnectionCounter
      • singleConnectionMonitor

        final java.lang.Object singleConnectionMonitor
      • initialized

        private final java.util.concurrent.atomic.AtomicBoolean initialized
    • Constructor Detail

      • ShaclSail

        public ShaclSail()
    • Method Detail

      • closeConnection

        void closeConnection()
      • usesSingleConnection

        boolean usesSingleConnection()
      • getSupportedShaclPredicates

        public static java.util.List<IRI> getSupportedShaclPredicates()
        Lists the predicates that have been implemented in the ShaclSail. All of these, and all combinations, should work, please report any bugs. For sh:path, only single predicate paths, or single predicate inverse paths are supported. DASH and RSX features may need to be enabled.
        Returns:
        List of IRIs (SHACL predicates)
      • init

        public void init()
                  throws SailException
        Description copied from interface: Sail
        Initializes the Sail. Care should be taken that required initialization parameters have been set before this method is called. Please consult the specific Sail implementation for information about the relevant parameters.
        Specified by:
        init in interface Sail
        Overrides:
        init in class SailWrapper
        Throws:
        SailException - If the Sail could not be initialized.
      • shutDown

        public void shutDown()
                      throws SailException
        Description copied from interface: Sail
        Shuts down the Sail, giving it the opportunity to synchronize any stale data. Care should be taken that all initialized Sails are being shut down before an application exits to avoid potential loss of data. Once shut down, a Sail can no longer be used until it is re-initialized.
        Specified by:
        shutDown in interface Sail
        Overrides:
        shutDown in class SailWrapper
        Throws:
        SailException - If the Sail object encountered an error or unexpected situation internally.
      • shutdownExecutorService

        private boolean shutdownExecutorService​(boolean forced)
      • submitToExecutorService

        <T> java.util.concurrent.Future<T> submitToExecutorService​(java.util.concurrent.Callable<T> runnable)
      • isSerializableValidation

        public boolean isSerializableValidation()
        Description copied from class: ShaclSailBaseConfiguration
        On transactions using SNAPSHOT isolation the ShaclSail can run the validation serializably. This stops the sail from becoming inconsistent due to race conditions between two transactions. Serializable validation limits TPS (transactions per second), it is however considerably faster than actually using SERIALIZABLE isolation.
        Overrides:
        isSerializableValidation in class ShaclSailBaseConfiguration
        Returns:
        true if serializable validation is enabled, false otherwise.
      • convertToSailException

        static SailException convertToSailException​(java.lang.InterruptedException e)