Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync develop branch after release 5.1.0 #5206

Merged
merged 17 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions site/content/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,5 @@ The metaphactory platform is developed by [metaphacts GmbH](https://www.metaphac
an RDF service backend for Knowledge Management, used by thesaurus management platform [VocBench](http://vocbench.uniroma2.it/).
- [Sesame Tools](https://github.com/joshsh/sesametools)<br>
a collection of utility classes for use with Sesame/RDF4J.
- [Jelly](https://w3id.org/jelly/jelly-jvm)<br>
a high-performance binary RDF serialization format with an implementation for RDF4J. Can be used as a JAR plugin.
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 5.0.2 (latest)
## RDF4J 5.0.3 (latest)

RDF4J 5.0.2 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/5.0.2).
RDF4J 5.0.3 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/5.0.3).

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

- [RDF4J 5.0.2 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.2-onejar.jar)<br/>
- [RDF4J 5.0.3 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.3-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>5.0.2</version>
<version>5.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
14 changes: 14 additions & 0 deletions site/content/news/rdf4j-503.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: "RDF4J 5.0.3 released"
date: 2024-11-10T14:15:45+0100
layout: "single"
categories: ["news"]
---
RDF4J 5.0.3 is now available. This is a patch release fixing 11 bugs.

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

- [Download RDF4J](/download/)
- [release notes](/release-notes/5.0.3).
20 changes: 20 additions & 0 deletions site/content/news/rdf4j-510-M1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: "RDF4J 5.1.0 Milestone 1"
date: 2024-11-10T14:05:43+0100
layout: "single"
categories: ["news"]
---
Milestone number 1 of the upcoming 5.1.0 release of RDF4J is now available for download.

RDF4J 5.1.0 is a minor release focusing on ... .

This milestone build is not yet feature-complete, but we are putting it out to receive early feedback on all the improvements we have put in.

<!--more-->

- [issues fixed in 5.1.0 Milestone 1](https://github.com/eclipse/rdf4j/issues?q=is%3Aissue+label%3AM1+is%3Aclosed+milestone%3A5.1.0)
- [issues planned for 5.1.0](https://github.com/eclipse/rdf4j/milestone/107)

### Links

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

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

### Acknowledgements

This release was made possible by contributions from Hannes Ebner, Håvard M. Ottestad, Frens Jan Rumph and Andreas Schwarte.
Binary file added site/static/javadoc/5.0.3.tgz
Binary file not shown.
Binary file added site/static/javadoc/5.1.0-M1.tgz
Binary file not shown.
Binary file modified site/static/javadoc/latest.tgz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,38 @@

import java.io.StringWriter;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Namespace;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.*;
import org.eclipse.rdf4j.model.base.AbstractStatement;
import org.eclipse.rdf4j.model.impl.LinkedHashModel;
import org.eclipse.rdf4j.model.util.ModelBuilder;
import org.eclipse.rdf4j.query.Operation;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.eclipse.rdf4j.spring.support.RDF4JTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>
* An {@link Operation} that holds a {@link Model} internally and exposes a {@link ModelBuilder} for adding to it.
* Moreover it allows for deleting statements.
* </p>
* <p>
* Thus, the class provides a way of configuring an update to the repository incrementally, and no repository access
* happens until {@link #execute()} is called. (unless the client uses {@link #applyToConnection(Function)} and accesses
* the repository that way.)
* </p>
* Removing statements via {@link #remove} will remove them from the repository when {@link #execute()} is called;
* moreover, the statements will also be removed from the model at the time of the {@link #remove} call, such that a
* subsequent creation of some of the deleted statements to the model will result in those triples being first deleted
* and then added to the repository when {@link #execute()} is called.
*
* @author Florian Kleedorfer
* @since 4.0.0
*/
Expand All @@ -42,11 +53,55 @@ public class UpdateWithModelBuilder {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private final RepositoryConnection con;

/** the model builder being exposed to clients */
private final ModelBuilder modelBuilder;
/** the model being built by the modelBuilder, and that is going to be added to the repository eventually */
private final Model addModel;

/**
* Set of Statements to be removed from the repository eventually. The Statement implementation used here is the
* {@link WildcardAllowingStatement}, which allows for using wildcards for deletion
*/
private final Set<Statement> removeStatements;

public UpdateWithModelBuilder(RepositoryConnection con) {
this.con = con;
this.modelBuilder = new ModelBuilder();
this.addModel = new LinkedHashModel();
this.removeStatements = new HashSet<>();
this.modelBuilder = new ModelBuilder(addModel);
}

public static UpdateWithModelBuilder fromTemplate(RDF4JTemplate template) {
return template.applyToConnection(con -> new UpdateWithModelBuilder(con));
}

/**
* Will remove statements upon update execution, before processing any additions. Statements that are removed here
* are also removed from the #addModel at the time of this call (not upon update execution)
*
* <p>
* The semantics of {@link RepositoryConnection#remove(Iterable, Resource...)} apply, i.e. the resource(s) specified
* here are used there, if any.
*
* @param subject the subject, or null to match any resource
* @param predicate the predicate, or null to match any IRI
* @param object the object, or null to match any value
* @param resources the context(s), if any
* @return this builder
*/
public UpdateWithModelBuilder remove(
Resource subject, IRI predicate, Value object, Resource... resources) {
addModel.remove(subject, predicate, object, resources);
if (resources.length == 0) {
removeStatements.add(new WildcardAllowingStatement(subject, predicate, object, null));
} else {
for (int i = 0; i < resources.length; i++) {
removeStatements.add(
new WildcardAllowingStatement(subject, predicate, object, resources[i]));
}
}
return this;
}

public UpdateWithModelBuilder setNamespace(Namespace ns) {
Expand Down Expand Up @@ -171,9 +226,63 @@ public void execute() {
Model model = modelBuilder.build();
if (logger.isDebugEnabled()) {
StringWriter sw = new StringWriter();
Rio.write(this.removeStatements, sw, RDFFormat.TURTLE);
logger.debug("removing the following triples:\n{}", sw.toString());
sw = new StringWriter();
Rio.write(model, sw, RDFFormat.TURTLE);
logger.debug("adding the following triples:\n{}", sw.toString());
}
con.add(model);
con.remove(this.removeStatements);
con.add(this.addModel);
}

static class WildcardAllowingStatement extends AbstractStatement {
private static final long serialVersionUID = -4116676621136121342L;
private final Resource subject;
private final IRI predicate;
private final Value object;
private final Resource context;

WildcardAllowingStatement(Resource subject, IRI predicate, Value object, Resource context) {
this.subject = subject;
this.predicate = predicate;
this.object = object;
this.context = context;
}

public Resource getSubject() {
return this.subject;
}

public IRI getPredicate() {
return this.predicate;
}

public Value getObject() {
return this.object;
}

public Resource getContext() {
return this.context;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
WildcardAllowingStatement that = (WildcardAllowingStatement) o;
return Objects.equals(getSubject(), that.getSubject())
&& Objects.equals(getPredicate(), that.getPredicate())
&& Objects.equals(getObject(), that.getObject())
&& Objects.equals(getContext(), that.getContext());
}

@Override
public int hashCode() {
return Objects.hash(
super.hashCode(), getSubject(), getPredicate(), getObject(), getContext());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.eclipse.rdf4j.spring.RDF4JSpringTestBase;
import org.eclipse.rdf4j.spring.domain.model.Artist;
import org.eclipse.rdf4j.spring.domain.model.EX;
import org.eclipse.rdf4j.spring.domain.model.Painting;
import org.eclipse.rdf4j.spring.domain.service.ArtService;
import org.eclipse.rdf4j.spring.support.RDF4JTemplate;
Expand Down Expand Up @@ -63,6 +64,19 @@ public void testCreatePainting() {
assertTrue(painting.getId().toString().startsWith("urn:uuid"));
}

@Test
public void testChangeArtist() {
Artist artist = artService.createArtist("Jan", "Vermeer");
Painting painting = artService.createPainting("Cypresses", "oil on canvas", artist.getId());
assertNotNull(painting.getId());
assertTrue(painting.getId().toString().startsWith("urn:uuid"));
assertEquals(artist.getId(), painting.getArtistId());
artService.changeArtist(painting.getId(), EX.VanGogh);
painting = artService.getPainting(painting.getId());
assertNotNull(painting);
assertEquals(EX.VanGogh, painting.getArtistId());
}

@Test
public void testCreatePaintingWithoutArtist() {
assertThrows(NullPointerException.class, () -> artService.createPainting(
Expand All @@ -71,7 +85,6 @@ public void testCreatePaintingWithoutArtist() {
null));
}

// TODO
@Test
public void testRollbackOnException() {
transactionTemplate.execute(status -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.sparqlbuilder.core.query.Queries;
import org.eclipse.rdf4j.spring.dao.SimpleRDF4JCRUDDao;
import org.eclipse.rdf4j.spring.dao.support.UpdateWithModelBuilder;
import org.eclipse.rdf4j.spring.dao.support.bindingsBuilder.MutableBindings;
import org.eclipse.rdf4j.spring.dao.support.sparql.NamedSparqlSupplier;
import org.eclipse.rdf4j.spring.domain.model.EX;
Expand Down Expand Up @@ -97,4 +98,11 @@ protected IRI getInputId(Painting painting) {
}
return painting.getId();
}

public void changeArtist(IRI painting, IRI newArtist) {
UpdateWithModelBuilder update = getRdf4JTemplate().updateWithBuilder();
update.remove(null, EX.creatorOf, painting);
update.add(newArtist, EX.creatorOf, painting);
update.execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ public class ArtService {
@Autowired
private PaintingDao paintingDao;

@Transactional
public Artist getArtist(IRI id) {
return this.artistDao.getById(id);
}

@Transactional
public Painting getPainting(IRI id) {
return this.paintingDao.getById(id);
}

@Transactional(propagation = Propagation.REQUIRED)
public Artist createArtist(String firstName, String lastName) {
Artist artist = new Artist();
Expand All @@ -46,4 +56,9 @@ public Painting createPainting(String title, String technique, IRI artist) {
return paintingDao.save(painting);
}

@Transactional(propagation = Propagation.REQUIRED)
public void changeArtist(IRI painting, IRI newArtist) {
paintingDao.changeArtist(painting, newArtist);
}

}
Loading