diff --git a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java index c8225888b6..2623b94c14 100644 --- a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java +++ b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/AbstractParserHandlingTest.java @@ -11,6 +11,7 @@ package org.eclipse.rdf4j.rio; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -19,10 +20,12 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Locale; +import java.util.Map; import org.eclipse.rdf4j.model.BNode; import org.eclipse.rdf4j.model.IRI; @@ -115,7 +118,7 @@ public abstract class AbstractParserHandlingTest { private ParseErrorCollector testListener; - private Model testStatements; + private TestStatementCollector testStatements; /** * Returns an {@link InputStream} containing the given RDF statements in a format that is recognised by the @@ -211,6 +214,7 @@ protected RDFWriter createWriter(OutputStream output) { } /** + * */ @BeforeEach public void setUp() { @@ -218,13 +222,82 @@ public void setUp() { testParser.setValueFactory(vf); testListener = new ParseErrorCollector(); - testStatements = new LinkedHashModel(); + testStatements = new TestStatementCollector(new LinkedHashModel()); testParser.setParseErrorListener(testListener); - testParser.setRDFHandler(new StatementCollector(testStatements)); + testParser.setRDFHandler(testStatements); + } + + private class TestStatementCollector extends StatementCollector { + + private boolean start; + private boolean end; + + public TestStatementCollector(Model testStatements) { + super(testStatements); + } + + @Override + public void clear() { + super.clear(); + this.start = false; + this.end = false; + } + + @Override + public void startRDF() throws RDFHandlerException { + assertFalse(start, "startRDF was called twice"); + assertFalse(end, "startRDF was called after endRDF"); + this.start = true; + super.startRDF(); + } + + @Override + public void endRDF() throws RDFHandlerException { + assertTrue(start, "startRDF was not called before endRDF"); + assertFalse(end, "endRDF was called twice"); + this.end = true; + super.endRDF(); + } + + @Override + public void handleComment(String comment) throws RDFHandlerException { + assertTrue(start, "startRDF was not called before handleComment"); + assertFalse(end, "endRDF was called before handleComment"); + super.handleComment(comment); + } + + @Override + public void handleStatement(Statement st) { + assertTrue(start, "startRDF was not called before handleStatement"); + assertFalse(end, "endRDF was called before handleStatement"); + super.handleStatement(st); + } + + @Override + public void handleNamespace(String prefix, String uri) throws RDFHandlerException { + assertTrue(start, "startRDF was not called before handleNamespace"); + assertFalse(end, "endRDF was called before handleNamespace"); + super.handleNamespace(prefix, uri); + } + + @Override + public Collection getStatements() { + assertTrue(start, "startRDF was not called before getStatements"); + assertTrue(end, "endRDF was not called before getStatements"); + return super.getStatements(); + } + + @Override + public Map getNamespaces() { + assertTrue(start, "startRDF was not called before getStatements"); + assertTrue(end, "endRDF was not called before getStatements"); + return super.getNamespaces(); + } } /** + * */ @AfterEach public void tearDown() { @@ -390,6 +463,9 @@ public void testUnknownDatatypeWithMessageWithFailCase1() throws Exception { } assertErrorListener(0, 1, 0); + // Since the parser failed it would not have called endRdf(), so we just overwrite the end variable so that + // assertModel(...) doesn't fail + testStatements.end = true; assertModel(new LinkedHashModel()); } @@ -699,6 +775,9 @@ public void testUnknownLanguageWithMessageWithFailCase1() throws Exception { } assertErrorListener(0, 1, 0); + // Since the parser failed it would not have called endRdf(), so we just overwrite the end variable so that + // assertModel(...) doesn't fail + testStatements.end = true; assertModel(new LinkedHashModel()); } @@ -917,12 +996,13 @@ public void testSkolemization() throws Exception { assertErrorListener(0, 0, 0); // assertModel(expectedModel); // GH-2768 isomorphism is not maintained after skolemization - assertNotEquals(new HashSet<>(expectedModel), new HashSet<>(testStatements)); // blank nodes not preserved - assertTrue(Models.subjectBNodes(testStatements).isEmpty()); // skolemized + assertNotEquals(new HashSet<>(expectedModel), new HashSet<>(testStatements.getStatements())); // blank nodes not + // preserved + assertTrue(Models.subjectBNodes(testStatements.getStatements()).isEmpty()); // skolemized } @Test - public void testRDFStarCompatibility() throws Exception { + public void testRDFStarCompatibility1() throws Exception { Model expectedModel = new LinkedHashModel(); Triple t1 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"), vf.createLiteral("example", vf.createIRI("http://example.com/3"))); @@ -939,9 +1019,20 @@ public void testRDFStarCompatibility() throws Exception { testParser.parse(input1, BASE_URI); assertErrorListener(0, 0, 0); assertModel(expectedModel); + } - testListener.reset(); - testStatements.clear(); + @Test + public void testRDFStarCompatibility2() throws Exception { + Model expectedModel = new LinkedHashModel(); + Triple t1 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"), + vf.createLiteral("example", vf.createIRI("http://example.com/3"))); + expectedModel.add(vf.createStatement(t1, DC.SOURCE, vf.createIRI("http://example.com/4"))); + Triple t2 = vf.createTriple(t1, DC.DATE, vf.createLiteral(new Date())); + expectedModel.add(vf.createStatement(vf.createIRI("http://example.com/5"), DC.RELATION, t2)); + Triple t3 = vf.createTriple(vf.createTriple(vf.createTriple(vf.createIRI("urn:a"), RDF.TYPE, + vf.createIRI("urn:b")), vf.createIRI("urn:c"), vf.createIRI("urn:d")), vf.createIRI("urn:e"), + vf.createIRI("urn:f")); + expectedModel.add(vf.createStatement(t3, vf.createIRI("urn:same"), t3)); // Turn off compatibility on parsing: formats with RDF-star support will produce RDF-star triples, // non-RDF-star formats will produce IRIs of the kind urn:rdf4j:triple:xxx @@ -952,22 +1043,26 @@ public void testRDFStarCompatibility() throws Exception { if (testParser.getRDFFormat().supportsRDFStar()) { assertModel(expectedModel); } else { - assertTrue(testStatements.contains(RDFStarUtil.toRDFEncodedValue(t1), DC.SOURCE, - vf.createIRI("http://example.com/4"))); - assertTrue(testStatements.contains(vf.createIRI("http://example.com/5"), DC.RELATION, - RDFStarUtil.toRDFEncodedValue(t2))); - assertTrue(testStatements.contains(RDFStarUtil.toRDFEncodedValue(t3), vf.createIRI("urn:same"), - RDFStarUtil.toRDFEncodedValue(t3))); - assertEquals(3, testStatements.size()); + assertTrue(testStatements.getStatements() + .contains(vf.createStatement(RDFStarUtil.toRDFEncodedValue(t1), DC.SOURCE, + vf.createIRI("http://example.com/4")))); + assertTrue(testStatements.getStatements() + .contains(vf.createStatement(vf.createIRI("http://example.com/5"), DC.RELATION, + RDFStarUtil.toRDFEncodedValue(t2)))); + assertTrue(testStatements.getStatements() + .contains(vf.createStatement(RDFStarUtil.toRDFEncodedValue(t3), vf.createIRI("urn:same"), + RDFStarUtil.toRDFEncodedValue(t3)))); + assertEquals(3, testStatements.getStatements().size()); } } private void assertModel(Model expectedModel) { if (logger.isTraceEnabled()) { logger.trace("Expected: {}", expectedModel); - logger.trace("Actual: {}", testStatements); + logger.trace("Actual: {}", testStatements.getStatements()); } - assertTrue(Models.isomorphic(expectedModel, testStatements), "Did not find expected statements"); + assertTrue(Models.isomorphic(expectedModel, testStatements.getStatements()), + "Did not find expected statements"); } private void assertErrorListener(int expectedWarnings, int expectedErrors, int expectedFatalErrors) { diff --git a/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java b/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java index ab8eb98357..69c09c9290 100644 --- a/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java +++ b/core/rio/jsonld/src/main/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParser.java @@ -20,8 +20,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Collection; -import java.util.HashSet; -import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; @@ -44,9 +42,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - import jakarta.json.JsonObject; import jakarta.json.JsonString; import jakarta.json.JsonStructure; @@ -125,6 +120,10 @@ private void parse(InputStream in, Reader reader, String baseURI) throws RDFParseException, RDFHandlerException, IOException { clear(); + if (rdfHandler != null) { + rdfHandler.startRDF(); + } + try { Document document = getDocument(in, reader); @@ -179,6 +178,9 @@ private void parse(InputStream in, Reader reader, String baseURI) } RDFHandler rdfHandler = getRDFHandler(); + if (rdfHandler != null) { + extractPrefixes(document, rdfHandler::handleNamespace); + } JsonLd.toRdf(document).options(opts).base(baseURI).get(new RdfConsumer<>() { @Override @@ -242,7 +244,7 @@ public Literal createLangString(String value, String lang) { }); if (rdfHandler != null) { - extractPrefixes(document, rdfHandler::handleNamespace); + rdfHandler.endRDF(); } } catch (no.hasmac.jsonld.JsonLdError e) { diff --git a/scripts/release.sh b/scripts/release.sh index bc634902b5..311d4d7d33 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -167,7 +167,6 @@ mvn versions:set -DnewVersion="${MVN_VERSION_RELEASE}" mvn versions:commit - # delete old release branch if it exits if git show-ref --verify --quiet "refs/heads/${BRANCH}"; then git branch --delete --force "${BRANCH}" &>/dev/null @@ -180,20 +179,11 @@ git tag "${MVN_VERSION_RELEASE}" echo ""; echo "Pushing release branch to github" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; # push release branch and tag git push -u origin "${BRANCH}" git push origin "${MVN_VERSION_RELEASE}" -echo ""; -echo "You need to tell Jenkins to start the release deployment processes, for SDK and maven artifacts" -echo "- SDK deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-sdk/ " -echo "- Maven deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-ossrh/ " -echo "(if you are on linux or windows, remember to use CTRL+SHIFT+C to copy)." -echo "Log in, then choose 'Build with Parameters' and type in ${MVN_VERSION_RELEASE}" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; - # Cleanup mvn clean -Dmaven.clean.failOnError=false mvn clean -Dmaven.clean.failOnError=false @@ -219,15 +209,13 @@ git push echo ""; echo "About to create PR" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; echo ""; echo "Creating pull request to merge release branch back into main" -gh pr create --title "next development iteration: ${MVN_NEXT_SNAPSHOT_VERSION}" --body "Merge using merge commit rather than rebase" +gh pr create -B main --title "next development iteration: ${MVN_NEXT_SNAPSHOT_VERSION}" --body "Merge using merge commit rather than rebase" echo ""; echo "Preparing a merge-branch to merge into develop" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; @@ -241,7 +229,7 @@ git push --set-upstream origin "merge_main_into_develop_after_release_${MVN_VERS echo "Creating pull request to merge the merge-branch into develop" gh pr create -B develop --title "sync develop branch after release ${MVN_VERSION_RELEASE}" --body "Merge using merge commit rather than rebase" -echo "It's ok to merge this PR later, so wait for the Jenkins tests to finish." +echo "It's ok to merge this PR later, so wait for the CI tests to finish." read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; mvn clean -Dmaven.clean.failOnError=false @@ -255,7 +243,6 @@ mvn clean -Dmaven.clean.failOnError=false mvn clean -Dmaven.clean.failOnError=false echo "Build javadocs" -read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; git checkout "${MVN_VERSION_RELEASE}" @@ -277,7 +264,7 @@ cp -f "site/static/javadoc/${MVN_VERSION_RELEASE}.tgz" "site/static/javadoc/late git add --all git commit -s -a -m "javadocs for ${MVN_VERSION_RELEASE}" git push --set-upstream origin "${RELEASE_NOTES_BRANCH}" -gh pr create -B main --title "${RELEASE_NOTES_BRANCH}" --body "Javadocs, release-notes and news item for ${MVN_VERSION_RELEASE}" +gh pr create -B main --title "${RELEASE_NOTES_BRANCH}" --body "Javadocs, release-notes and news item for ${MVN_VERSION_RELEASE}.\n\n - [ ] check that [Jenkins](https://ci.eclipse.org/rdf4j/) finished publishing the release\n - [ ] remember to also [add the release here on GitHub](https://github.com/eclipse-rdf4j/rdf4j/releases/new?tag=${MVN_VERSION_RELEASE}&title=RDF4JRDF4J%20${MVN_VERSION_RELEASE}) (include announcement)" echo "Javadocs are in git branch ${RELEASE_NOTES_BRANCH}" @@ -289,7 +276,13 @@ cd scripts echo "" echo "DONE!" - +echo ""; +echo "You need to tell Jenkins to start the release deployment processes, for SDK and maven artifacts" +echo "- SDK deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-sdk/ " +echo "- Maven deployment: https://ci.eclipse.org/rdf4j/job/rdf4j-deploy-release-ossrh/ " +echo "(if you are on linux or windows, remember to use CTRL+SHIFT+C to copy)." +echo "Log in, then choose 'Build with Parameters' and type in ${MVN_VERSION_RELEASE}" +read -n 1 -srp "Press any key to continue (ctrl+c to cancel)"; printf "\n\n"; echo "" echo "You will now want to inform the community about the new release!" diff --git a/site/content/download.md b/site/content/download.md index 9e5587f1cd..018091c40a 100644 --- a/site/content/download.md +++ b/site/content/download.md @@ -5,15 +5,15 @@ toc: true You can either retrieve RDF4J via Apache Maven, or download the SDK or onejar directly. -## RDF4J 5.0.0 (latest) +## RDF4J 5.0.1 (latest) -RDF4J 5.0.0 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.0). +RDF4J 5.0.1 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.1). -- [RDF4J 5.0.0 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.0-sdk.zip)
+- [RDF4J 5.0.1 SDK (zip)](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.1-sdk.zip)
Full Eclipse RDF4J SDK, containing all libraries, RDF4J Server, Workbench, and Console applications, and Javadoc API. -- [RDF4J 5.0.0 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.0-onejar.jar)
+- [RDF4J 5.0.1 onejar](http://www.eclipse.org/downloads/download.php?file=/rdf4j/eclipse-rdf4j-5.0.1-onejar.jar)
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/) @@ -28,7 +28,7 @@ You can include RDF4J as a Maven dependency in your Java project by including th org.eclipse.rdf4j rdf4j-bom - 5.0.0 + 5.0.1 pom import diff --git a/site/content/news/rdf4j-501.md b/site/content/news/rdf4j-501.md new file mode 100644 index 0000000000..f538b48309 --- /dev/null +++ b/site/content/news/rdf4j-501.md @@ -0,0 +1,14 @@ +--- +title: "RDF4J 5.0.1 released" +date: 2024-07-09T17:08:30+0200 +layout: "single" +categories: ["news"] +--- +RDF4J 5.0.1 is now available. This is a patch release fixing 8 bugs. + +For more details, have a look at the [release notes](/release-notes/5.0.1). + +### Links + +- [Download RDF4J](/download/) +- [release notes](/release-notes/5.0.1). diff --git a/site/content/release-notes/5.0.1.md b/site/content/release-notes/5.0.1.md new file mode 100644 index 0000000000..2ff797a6c4 --- /dev/null +++ b/site/content/release-notes/5.0.1.md @@ -0,0 +1,24 @@ +--- +title: "5.0.1" +toc: true +--- +RDF4J 5.0.1 is a patch release that fixes 8 issues. + +For a complete overview, see [all issues fixed in 5.0.1](https://github.com/eclipse/rdf4j/milestone/108?closed=1). + +### Security + +The following dependencies and/or transitive dependencies have been updated to address security vulnerabilities: + - Upgraded spring to 5.3.37 + - Upgraded snappy-java to 1.1.10.5 + - Upgraded netty to 4.1.111 + +These upgrades fix several issues reported in various CVEs (more details can be found in the RDF4J github [issue list](https://github.com/eclipse-rdf4j/rdf4j/issues?q=is%3Aissue+label%3Asecurity+is%3Aclosed) ). +While these vulnerabilities may or may not affect the security of RDF4J itself in a real-world environment, +users are nevertheless recommended to consider upgrading to the latest version of RDF4J. + + +### Acknowledgements + +This release was made possible by contributions from Florian Kleedorfer, Håvard M. Ottestad, Matthew Nguyen, Bart Hanssens, +Pete Edwards and Jerven Bolleman. diff --git a/site/static/javadoc/5.0.1.tgz b/site/static/javadoc/5.0.1.tgz new file mode 100644 index 0000000000..8089a1aa8c Binary files /dev/null and b/site/static/javadoc/5.0.1.tgz differ diff --git a/site/static/javadoc/latest.tgz b/site/static/javadoc/latest.tgz index 5374065d23..8089a1aa8c 100644 Binary files a/site/static/javadoc/latest.tgz and b/site/static/javadoc/latest.tgz differ