Skip to content

Commit

Permalink
Merge branch 'main' into retrieve-prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
blcham authored Aug 4, 2023
2 parents ea059e3 + 2e6a281 commit fd85b9f
Show file tree
Hide file tree
Showing 25 changed files with 686 additions and 39 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SPipes loads pipelines by recursive traversal of configured directories, searchi
SPipes script construction, execution, and execution history tracking is explained
in [Hello world example](doc/examples/hello-world/hello-world.md).
Script debugging is explained in [skosify example](doc/examples/skosify/skosify.md).
Working with RDF4J repository is explained in [rdf4j example](doc/examples/rdf4j-update/rdf4j-update.md).
Constraint validation is described in [constraint validation example](doc/examples/constraint-validation/constraint-validation.md).


Expand Down
74 changes: 74 additions & 0 deletions doc/examples/rdf4j-update/rdf4j-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# RDF4J update example

RDF4J update example explains how to update RDF4J repository.

## Introduction

This example explains script [rdf4j-update.sms.ttl](./rdf4j-update.sms.ttl]) that contain one pipeline. It creates RDF4J repository and performs update query. For more details about script construction and execution you can see [hello-world-example](../hello-world/hello-world.md).

## Script structure

Script performs following steps:
1) Creates RDF4J repository using `kbss:rdf4j-create-repository` module. Repository is specified by parameters `rdf4j:p-rdf4j-server-url` and `rdf4j:p-rdf4j-repository-name`. Parameter `rdf4j:p-rdf4j-ignore-if-exists` defines behavior of the module in case when defined repository already exists:
in case if it is set to be "true", module will not do anything if repository with given ID already exists on the server.


```
:create-repository
a kbss:rdf4j-create-repository ;
rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ;
rdf4j:p-rdf4j-repository-name "test-update" ;
rdf4j:p-rdf4j-ignore-if-exists "true" ;
sm:next :update ;
.
```

2) Perform an update on repository using `kbss:rdf4j-update` module. Repository is defined in the same way as in `:create-repository`. Update query is set by string in `sp:text` section.

```
:update-repository
a kbss:rdf4j-update ;
sm:next :update-repository_Return ;
sml:updateQuery [
a sp:Update ;
sp:text """
PREFIX ex-people: <http://example.org/people/>
DELETE {
ex-people:john ex-people:age ?oldAge .
}
INSERT {
ex-people:john ex-people:age ?newAge .
} WHERE {
OPTIONAL {
ex-people:john ex-people:age ?oldAge .
}
BIND(COALESCE(?oldAge+1, 1) as ?newAge)
}
""" ;
];
rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ;
rdf4j:p-rdf4j-repository-name "test-update" ;
.
```

## Script execution

Let's assume that SPipes web application is running at `http://localhost:8080/s-pipes`. We can call the *pipeline* with:

http://localhost:8080/s-pipes/service?_pId=update-repository

Note, that rdf4j server should be running on the URL that is specified in script (`http://localhost:8080/rdf4j-server/` for example).
You can see following logs while execution:

[http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### create-repository
...
[http-nio-8080-exec-1] INFO c.c.s.m.Rdf4jUpdateModule - Server url: http://localhost:8080/rdf4j-server/, Repsitory name: test-update, Ignore if repository exist: true
[http-nio-8080-exec-6] INFO c.c.s.m.Rdf4jUpdateModule - Repository "test-update" already exists
...
[http-nio-8080-exec-7] INFO c.c.s.e.ExecutionEngineImpl - ##### Make insert update
...
[http-nio-8080-exec-7] DEBUG c.c.s.m.Rdf4jUpdateModule - Connected to test-update
[http-nio-8080-exec-7] DEBUG c.c.s.m.Rdf4jUpdateModule - Update successful

This log will occur when Ignore flag is set to true and repository already exists:
`[http-nio-8080-exec-6] INFO c.c.s.m.Rdf4jUpdateModule - Repository "test-update" already exists`
69 changes: 69 additions & 0 deletions doc/examples/rdf4j-update/rdf4j-update.sms.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# baseURI: http://onto.fel.cvut.cz/ontologies/s-pipes/rdf-update-example
# imports: http://onto.fel.cvut.cz/ontologies/s-pipes-lib

@prefix : <http://onto.fel.cvut.cz/ontologies/s-pipes/rdf-update-example/> .
@prefix doc: <http://onto.fel.cvut.cz/ontologies/documentation/> .
@prefix kbss: <http://onto.fel.cvut.cz/ontologies/lib/module/> .
@prefix km-sesame: <http://onto.fel.cvut.cz/ontologies/lib/module/sesame/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sm: <http://topbraid.org/sparqlmotion#> .
@prefix sml: <http://topbraid.org/sparqlmotionlib#> .
@prefix sp: <http://spinrdf.org/sp#> .
@prefix spif: <http://spinrdf.org/spif#> .
@prefix spin: <http://spinrdf.org/spin#> .
@prefix spl: <http://spinrdf.org/spl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf4j: <http://onto.fel.cvut.cz/ontologies/lib/module/rdf4j/> .

<http://onto.fel.cvut.cz/ontologies/s-pipes/rdf-update-example>
a owl:Ontology ;
owl:imports <http://onto.fel.cvut.cz/ontologies/s-pipes-lib> ;
.

:create-repository
a kbss:rdf4j-create-repository ;
rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ;
rdf4j:p-rdf4j-repository-name "test-update" ;
rdf4j:p-rdf4j-ignore-if-exists "true" ;
sm:next :update-repository ;
.

:update-repository
a kbss:rdf4j-update ;
sm:next :update-repository_Return ;
sml:updateQuery [
a sp:Update ;
sp:text """
PREFIX ex-people: <http://example.org/people/>
DELETE {
ex-people:john ex-people:age ?oldAge .
}
INSERT {
ex-people:john ex-people:age ?newAge .
} WHERE {
OPTIONAL {
ex-people:john ex-people:age ?oldAge .
}
BIND(COALESCE(?oldAge+1, 1) as ?newAge)
}
""" ;
];
kbss:has-max-iteration-count 5 ;
kbss:only-if-triple-count-changes false;
rdf4j:p-rdf4j-server-url "http://localhost:8080/rdf4j-server/" ;
rdf4j:p-rdf4j-repository-name "test-update" ;
.

:update-repository_Return
a sml:ReturnRDF ;
sml:serialization sml:JSONLD ;
rdfs:label "Update repository" ;
.

:update-repository
a sm:Function ;
sm:returnModule :update-repository_Return ;
rdfs:subClassOf sm:Functions ;
.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protected static final Property property(String local )
public static final Property constructQuery = property("constructQuery");
public static final Property value = property("value");
public static final Property selectQuery = property("selectQuery");
public static final Property updateQuery = property("updateQuery");
public static final Property sourceFilePath = property("sourceFilePath");
public static final Property url = property("url");
public static final Property targetFilePath = property("targetFilePath");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cz.cvut.spipes.exception;

public class ContextNotFoundException extends RuntimeException {
public class ContextNotFoundException extends SPipesException {

public ContextNotFoundException(String contextId) {
super("Context identified by \"" + contextId + "\" was not found.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* Exception thrown when there is no context defined to search a resource.
**/
public class ContextsNotDefinedException extends RuntimeException {
public class ContextsNotDefinedException extends SPipesException {

public ContextsNotDefinedException(String message, Throwable cause) {
super(message, cause);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cz.cvut.spipes.exception;

/**
* Indicate that SPipes Module was incorrectly configured.
*/
public class ModuleConfigurationInconsistentException extends SPipesException {

public ModuleConfigurationInconsistentException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cz.cvut.spipes.exception;

public class ParseException extends RuntimeException {
public class ParseException extends SPipesException {

public ParseException() {
super("Could not parse input string");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
*
*/
public class ResourceNotFoundException extends RuntimeException {
public class ResourceNotFoundException extends SPipesException {

public ResourceNotFoundException(String entityId, Set<String> contextUris) {
super("Resource identified by \"" + entityId + "\" was not found in contexts " + contextUris + ".");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* Exception thrown when a resource found is not unique.
**/
public class ResourceNotUniqueException extends RuntimeException {
public class ResourceNotUniqueException extends SPipesException {

public ResourceNotUniqueException(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cz.cvut.spipes.exception;

/**
* Runtime exception that should be extended by any specific SPipes exception.
*/
public class SPipesException extends RuntimeException {

public SPipesException(String message) {
super(message);
}

public SPipesException(String message, Throwable cause) {
super(message, cause);
}

public SPipesException(Throwable cause) {
super(cause);
}

public SPipesException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package cz.cvut.spipes.exception;

import cz.cvut.spipes.modules.Module;
import java.util.Optional;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

public class ValidationConstraintFailed extends RuntimeException {
import java.util.Optional;

public class ValidationConstraintFailedException extends SPipesException {

public ValidationConstraintFailed(@NonNls String message, @NotNull Module module) {
public ValidationConstraintFailedException(@NonNls String message, @NotNull Module module) {
super(createModuleInfo(module) + " " + message);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import cz.cvut.spipes.engine.ExecutionContext;
import cz.cvut.spipes.engine.ExecutionContextFactory;
import cz.cvut.spipes.engine.VariablesBinding;
import cz.cvut.spipes.exception.ValidationConstraintFailed;
import cz.cvut.spipes.exception.ValidationConstraintFailedException;
import cz.cvut.spipes.util.JenaUtils;
import cz.cvut.spipes.util.QueryUtils;
import org.apache.jena.atlas.lib.NotImplemented;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.query.*;
Expand Down Expand Up @@ -293,7 +294,7 @@ private void checkConstraints(Model model, QuerySolution bindings, List<Resource
.toString();
LOG.error(mergedMsg);
if (ExecutionConfig.isExitOnError()) {
throw new ValidationConstraintFailed(mergedMsg, this);
throw new ValidationConstraintFailedException(mergedMsg, this);
}
} else {
LOG.debug("Constraint validated for exception \"{}\".", getQueryComment(spinQuery));
Expand All @@ -306,9 +307,9 @@ protected String getQueryComment(org.topbraid.spin.model.Query query) {
if (query.getComment() != null) {
return query.getComment();
}
String comment = query.toString().split(System.lineSeparator())[0];
if (comment.matches("\\s*#.*")) {
return comment.split("\\s*#\\s*", 2)[1];
String comment = QueryUtils.getQueryComment(query.toString());
if (comment != null) {
return comment;
}
// Resource obj = query.getPropertyResourceValue(RDFS.comment);
// if (obj == null) {
Expand Down
27 changes: 14 additions & 13 deletions s-pipes-core/src/main/java/cz/cvut/spipes/util/QueryUtils.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
package cz.cvut.spipes.util;


import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import org.apache.jena.query.ARQ;
import org.apache.jena.query.ParameterizedSparqlString;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.*;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.sparql.mgt.Explain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.stream.Collectors;

public class QueryUtils {

private static final Logger LOG = LoggerFactory.getLogger(QueryUtils.class);
Expand Down Expand Up @@ -176,4 +169,12 @@ private interface QueryExecutor<T> {
T execQuery(QueryExecution execution);
}

public static String getQueryComment(String query) {
String comment = query.split(System.lineSeparator())[0];
if (comment.matches("\\s*#.*")) {
return comment.split("\\s*#\\s*", 2)[1];
}
return null;
}

}
10 changes: 10 additions & 0 deletions s-pipes-modules/module-rdf4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>

<!-- TODO needed -->
<!--<dependency>-->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package cz.cvut.spipes.exceptions;

import cz.cvut.spipes.exception.SPipesException;

public class RepositoryAccessException extends SPipesException {

public RepositoryAccessException(String repositoryName, Throwable cause) {
super("Cannot connect to repository " + repositoryName + ".", cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cz.cvut.spipes.exceptions;

import cz.cvut.spipes.exception.SPipesException;

public class RepositoryAlreadyExistsException extends SPipesException {

public RepositoryAlreadyExistsException(String repositoryName) {
super("Repository " + repositoryName + " already exists.");
}

}
Loading

0 comments on commit fd85b9f

Please sign in to comment.