Skip to content

Commit

Permalink
merge main (#4812)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad authored Oct 16, 2023
2 parents 8e7c2c0 + 86cbf5b commit 7d1404b
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2023 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
******************************************************************************/

package org.eclipse.rdf4j.sail.shacl.ast;

import java.util.Arrays;

import org.eclipse.rdf4j.common.exception.RDF4JException;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.BindingSet;

/**
* An exception thrown when the ?failure var is true for a SPARQL constraint select query.
*/
public class ShaclSparqlConstraintFailureException extends RDF4JException {

private final Shape shape;
private final String query;
private final BindingSet resultBindingSet;
private final Value focusNode;
private final Resource[] dataGraph;

public ShaclSparqlConstraintFailureException(Shape shape, String query, BindingSet resultBindingSet,
Value focusNode, Resource[] dataGraph) {
super("The ?failure variable was true for " + valueToString(focusNode) + " in shape "
+ resourceToString(shape.getId()) + " with result resultBindingSet: " + resultBindingSet.toString()
+ " and dataGraph: " + Arrays.toString(dataGraph) + " and query:" + query);
this.shape = shape;
this.query = query;
this.resultBindingSet = resultBindingSet;
this.focusNode = focusNode;
this.dataGraph = dataGraph;
}

public String getShape() {
return shape.toString();
}

public String getQuery() {
return query;
}

public BindingSet getResultBindingSet() {
return resultBindingSet;
}

public Value getFocusNode() {
return focusNode;
}

public Resource[] getDataGraph() {
return dataGraph;
}

private static String resourceToString(Resource id) {
assert id != null;
if (id == null) {
return "null";
}
if (id.isIRI()) {
return "<" + id.stringValue() + ">";
}
if (id.isBNode()) {
return id.toString();
}
if (id.isTriple()) {
return "TRIPLE " + id;
}
return id.toString();
}

private static String valueToString(Value value) {
assert value != null;
if (value == null) {
return "null";
}
if (value.isResource()) {
return resourceToString((Resource) value);
}
if (value.isLiteral()) {
return value.toString();
}
return value.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ abstract public class Shape implements ConstraintComponent, Identifiable {
private static final Logger logger = LoggerFactory.getLogger(Shape.class);
protected boolean produceValidationReports;

Resource id;
private Resource id;
TargetChain targetChain;

List<Target> target = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.impl.BooleanLiteral;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.MalformedQueryException;
Expand All @@ -26,8 +27,10 @@
import org.eclipse.rdf4j.query.parser.QueryParserRegistry;
import org.eclipse.rdf4j.sail.SailConnection;
import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection;
import org.eclipse.rdf4j.sail.shacl.ast.ShaclSparqlConstraintFailureException;
import org.eclipse.rdf4j.sail.shacl.ast.Shape;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent;
import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.SparqlConstraintComponent;
import org.eclipse.rdf4j.sail.shacl.results.ValidationResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -45,7 +48,7 @@ public class SparqlConstraintSelect implements PlanNode {
private final String query;
private final Resource[] dataGraph;
private final boolean produceValidationReports;
private final ConstraintComponent constraintComponent;
private final SparqlConstraintComponent constraintComponent;
private final Shape shape;
private final String[] variables;
private final ConstraintComponent.Scope scope;
Expand All @@ -56,7 +59,7 @@ public class SparqlConstraintSelect implements PlanNode {

public SparqlConstraintSelect(SailConnection connection, PlanNode targets, String query,
ConstraintComponent.Scope scope,
Resource[] dataGraph, boolean produceValidationReports, ConstraintComponent constraintComponent,
Resource[] dataGraph, boolean produceValidationReports, SparqlConstraintComponent constraintComponent,
Shape shape) {
this.connection = connection;
this.targets = targets;
Expand Down Expand Up @@ -111,6 +114,13 @@ private void calculateNext() {

if (results.hasNext()) {
BindingSet bindingSet = results.next();
if (bindingSet.hasBinding("failure")) {
if (bindingSet.getValue("failure").equals(BooleanLiteral.TRUE)) {
throw new ShaclSparqlConstraintFailureException(shape, query, bindingSet,
nextTarget.getActiveTarget(), dataGraph);
}
}

Value value = bindingSet.getValue("value");
Value path = bindingSet.getValue("path");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*******************************************************************************
* Copyright (c) 2023 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
******************************************************************************/

package org.eclipse.rdf4j.sail.shacl;

import static org.junit.Assert.assertThrows;

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

import org.eclipse.rdf4j.query.Update;
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.sail.memory.MemoryStore;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class SparqlConstraintTest {

@Test
public void testFailureBinding() throws IOException {

SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore()));

try (SailRepositoryConnection connection = sailRepository.getConnection()) {
connection.add(new StringReader("" +
"@prefix : <http://example.com/data/> .\n" +
"@prefix ont: <http://example.com/ontology#> .\n" +
"@prefix vocsh: <http://example.org/shape/> .\n" +
"@prefix so: <http://www.ontotext.com/semantic-object/> .\n" +
"@prefix affected: <http://www.ontotext.com/semantic-object/affected> .\n" +
"@prefix res: <http://www.ontotext.com/semantic-object/result/> .\n" +
"@prefix dct: <http://purl.org/dc/terms/> .\n" +
"@prefix gn: <http://www.geonames.org/ontology#> .\n" +
"@prefix owl: <http://www.w3.org/2002/07/owl#> .\n" +
"@prefix puml: <http://plantuml.com/ontology#> .\n" +
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n" +
"@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n" +
"@prefix skos: <http://www.w3.org/2004/02/skos/core#> .\n" +
"@prefix void: <http://rdfs.org/ns/void#> .\n" +
"@prefix wgs84: <http://www.w3.org/2003/01/geo/wgs84_pos#> .\n" +
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n" +
"@prefix sh: <http://www.w3.org/ns/shacl#> .\n" +
"@prefix dash: <http://datashapes.org/dash#> .\n" +
"@prefix rsx: <http://rdf4j.org/shacl-extensions#> .\n" +
"@prefix ec: <http://www.ontotext.com/connectors/entity-change#> .\n" +
"@prefix ecinst: <http://www.ontotext.com/connectors/entity-change/instance#> .\n" +
"@prefix rdf4j: <http://rdf4j.org/schema/rdf4j#> .\n" +
"@prefix ex: <http://example.com/ns#> .\n" +
"\n" +
"rdf4j:SHACLShapeGraph {\n" +
"\n" +
"ex:\n" +
"\tsh:declare [\n" +
"\t\tsh:prefix \"ex\" ;\n" +
"\t\tsh:namespace \"http://example.com/ns#\"^^xsd:anyURI ;\n" +
"\t] ;\n" +
"\tsh:declare [\n" +
"\t\tsh:prefix \"schema\" ;\n" +
"\t\tsh:namespace \"http://schema.org/\"^^xsd:anyURI ;\n" +
"\t] .\n" +
"\n" +
" ex:LanguageExampleShape\n" +
" \ta sh:NodeShape ;\n" +
" \tsh:targetClass ex:Country ;\n" +
" \tsh:sparql [\n" +
" \t\ta sh:SPARQLConstraint ; # This triple is optional\n" +
" \t\tsh:message \"Values are literals with German language tag.\" ;\n" +
" \t\tsh:prefixes ex: ;\n" +
" \t\tsh:deactivated false ;\n" +
" \t\tsh:select \"\"\"\n" +
" \t\t\tSELECT $this (ex:germanLabel AS ?path) ?value ?failure\n" +
" \t\t\tWHERE {\n" +
" \t\t\t\t$this ex:germanLabel ?value .\n" +
" \t\t\t\tBIND(isIri(?value) as ?failure)\n" +
" \t\t\t}\n" +
" \t\t\t\"\"\" ;\n" +
" \t] .\n" +
"}\n"), RDFFormat.TRIG);

Update update = connection.prepareUpdate("PREFIX ex: <http://example.com/ns#>\n" +
"PREFIX owl: <http://www.w3.org/2002/07/owl#>\n" +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n" +
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
"PREFIX sh: <http://www.w3.org/ns/shacl#>\n" +
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" +
"\n" +
"INSERT DATA {\n" +
"ex:InvalidCountry a ex:Country .\n" +
"ex:InvalidCountry ex:germanLabel ex:invalidValue .\n" +
"}\n");

// assert exception is thrown
RepositoryException repositoryException = assertThrows(RepositoryException.class, update::execute);
Throwable cause = repositoryException.getCause().getCause();
Assertions.assertEquals(
"org.eclipse.rdf4j.sail.shacl.ast.ShaclSparqlConstraintFailureException: The ?failure variable was true for <http://example.com/ns#InvalidCountry> in shape <http://example.com/ns#LanguageExampleShape> with result resultBindingSet: [this=http://example.com/ns#InvalidCountry;value=http://example.com/ns#invalidValue;failure=\"true\"^^<http://www.w3.org/2001/XMLSchema#boolean>;path=http://example.com/ns#germanLabel] and dataGraph: [] and query:PREFIX schema: <http://schema.org/> \n"
+
"PREFIX ex: <http://example.com/ns#> \n" +
"\n" +
"\n" +
"\n" +
" \t\t\tSELECT $this (ex:germanLabel AS ?path) ?value ?failure\n" +
" \t\t\tWHERE {\n" +
" \t\t\t\t$this ex:germanLabel ?value .\n" +
" \t\t\t\tBIND(isIri(?value) as ?failure)\n" +
" \t\t\t}\n" +
" \t\t\t",
cause.toString());

}

}

}
12 changes: 6 additions & 6 deletions site/content/download.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ toc: true

You can either retrieve RDF4J via Apache Maven, or download the SDK or onejar directly.

## RDF4J 4.3.6 (latest)
## RDF4J 4.3.7 (latest)

RDF4J 4.3.6 is our latest stable release. It requires Java 11 minimally.
For details on what’s new and how to upgrade, see the [release and upgrade notes](/release-notes/4.3.6).
RDF4J 4.3.7 is our latest stable release. It requires Java 11 minimally.
For details on what’s new and how to upgrade, see the [release and upgrade notes](/release-notes/4.3.7).

- [RDF4J 4.3.6 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.6-sdk.zip)<br/>
- [RDF4J 4.3.7 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.7-sdk.zip)<br/>
Full Eclipse RDF4J SDK, containing all libraries, RDF4J Server, Workbench, and Console applications, and Javadoc API.

- [RDF4J 4.3.6 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.6-onejar.jar)<br/>
- [RDF4J 4.3.7 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-4.3.7-onejar.jar)<br/>
Single jar file for easy inclusion of the full RDF4J toolkit in your Java project.

- [RDF4J artifacts](https://search.maven.org/search?q=org.eclipse.rdf4j) on the [Maven Central Repository](http://search.maven.org/)
Expand All @@ -28,7 +28,7 @@ You can include RDF4J as a Maven dependency in your Java project by including th
<dependency>
<groupId>org.eclipse.rdf4j</groupId>
<artifactId>rdf4j-bom</artifactId>
<version>4.3.6</version>
<version>4.3.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
14 changes: 14 additions & 0 deletions site/content/news/rdf4j-437.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: "RDF4J 4.3.7 released"
date: 2023-10-06T14:56:45+0200
layout: "single"
categories: ["news"]
---
RDF4J 4.3.7 is now available. This is a patch release fixing 6 bugs.

For more details, have a look at the [release notes](/release-notes/4.3.7).
<!--more-->
### Links

- [Download RDF4J](/download/)
- [release notes](/release-notes/4.3.7).
11 changes: 11 additions & 0 deletions site/content/release-notes/4.3.7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: "4.3.7"
toc: true
---
RDF4J 4.3.7 is a patch release that fixes 6 issues.

For a complete overview, see [all issues fixed in 4.3.7](https://github.com/eclipse/rdf4j/milestone/100?closed=1).

### Security

Several dependencies have been [updated](https://github.com/eclipse-rdf4j/rdf4j/issues/4795) and some had vulnerabilities or transitive vulnerabilities.
Binary file added site/static/javadoc/4.3.7.tgz
Binary file not shown.
Binary file modified site/static/javadoc/latest.tgz
Binary file not shown.

0 comments on commit 7d1404b

Please sign in to comment.