diff --git a/.github/workflows/develop-status.yml b/.github/workflows/develop-status.yml
index 7ad395a48b7..0e5abcf99a4 100644
--- a/.github/workflows/develop-status.yml
+++ b/.github/workflows/develop-status.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- jdk: [1.8, 11]
+ jdk: [1.8, 13]
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/master-status.yml b/.github/workflows/master-status.yml
index 529d89b41e6..e0aee8c89ff 100644
--- a/.github/workflows/master-status.yml
+++ b/.github/workflows/master-status.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- jdk: [1.8, 11]
+ jdk: [1.8, 13]
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/new-issue.yml b/.github/workflows/new-issue.yml
index 0b1eb2c8729..01fe3ee1785 100644
--- a/.github/workflows/new-issue.yml
+++ b/.github/workflows/new-issue.yml
@@ -10,5 +10,5 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PROJECT_URL: https://github.com/eclipse/rdf4j/projects/19
- GITHUB_PROJECT_COLUMN_NAME: Inbox
+ GITHUB_PROJECT_COLUMN_NAME: 📥 Inbox
diff --git a/.github/workflows/pr-verify.yml b/.github/workflows/pr-verify.yml
index c6307927115..473c6de8cd6 100644
--- a/.github/workflows/pr-verify.yml
+++ b/.github/workflows/pr-verify.yml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- jdk: [1.8, 11]
+ jdk: [1.8, 13]
steps:
- uses: actions/checkout@v1
diff --git a/README.md b/README.md
index 0b3c11dffd8..cc18d1dc3e4 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
This is the main code repository for the Eclipse RDF4J project.
-![](https://github.com/eclipse/rdf4j/workflows/master%20status/badge.svg)
-![](https://github.com/eclipse/rdf4j/workflows/develop%20status/badge.svg)
+[![master status](https://github.com/eclipse/rdf4j/workflows/master%20status/badge.svg)](https://github.com/eclipse/rdf4j/actions?query=workflow%3A%22master+status%22)
+[![develop status](https://github.com/eclipse/rdf4j/workflows/develop%20status/badge.svg)](https://github.com/eclipse/rdf4j/actions?query=workflow%3A%22develop+status%22)
Visit the [project website](https://rdf4j.org/) for news, documentation, and downloadable releases.
diff --git a/assembly/pom.xml b/assembly/pom.xml
index 12e63b65750..c17a4897b4e 100644
--- a/assembly/pom.xml
+++ b/assembly/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-assemblypom
diff --git a/bom/pom.xml b/bom/pom.xml
index 3cc54a438aa..896baebe17b 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-bompom
diff --git a/compliance/elasticsearch/pom.xml b/compliance/elasticsearch/pom.xml
index 0eb91f47ecf..b54c8f45bc5 100644
--- a/compliance/elasticsearch/pom.xml
+++ b/compliance/elasticsearch/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-elasticsearch-complianceRDF4J Elasticsearch Sail Tests
diff --git a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchIndexTest.java b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchIndexTest.java
index 04e39f0bcf7..7d55a6303b3 100644
--- a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchIndexTest.java
+++ b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchIndexTest.java
@@ -40,7 +40,6 @@
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
@ClusterScope(numDataNodes = 1)
@@ -443,15 +442,17 @@ public void testRejectedDatatypes() {
private void assertStatement(Statement statement) throws Exception {
SearchDocument document = index.getDocument(statement.getSubject(), statement.getContext());
- if (document == null)
+ if (document == null) {
fail("Missing document " + statement.getSubject());
+ }
assertStatement(statement, document);
}
private void assertNoStatement(Statement statement) throws Exception {
SearchDocument document = index.getDocument(statement.getSubject(), statement.getContext());
- if (document == null)
+ if (document == null) {
return;
+ }
assertNoStatement(statement, document);
}
@@ -463,8 +464,9 @@ private void assertStatement(Statement statement, SearchDocument document) {
List fields = document.getProperty(SearchFields.getPropertyField(statement.getPredicate()));
assertNotNull("field " + statement.getPredicate() + " not found in document " + document, fields);
for (String f : fields) {
- if (((Literal) statement.getObject()).getLabel().equals(f))
+ if (((Literal) statement.getObject()).getLabel().equals(f)) {
return;
+ }
}
fail("Statement not found in document " + statement);
}
@@ -475,11 +477,13 @@ private void assertStatement(Statement statement, SearchDocument document) {
*/
private void assertNoStatement(Statement statement, SearchDocument document) {
List fields = document.getProperty(SearchFields.getPropertyField(statement.getPredicate()));
- if (fields == null)
+ if (fields == null) {
return;
+ }
for (String f : fields) {
- if (((Literal) statement.getObject()).getLabel().equals(f))
+ if (((Literal) statement.getObject()).getLabel().equals(f)) {
fail("Statement should not be found in document " + statement);
+ }
}
}
diff --git a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailIndexedPropertiesTest.java b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailIndexedPropertiesTest.java
index f5bfa998c7b..d25f8ac2eb6 100644
--- a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailIndexedPropertiesTest.java
+++ b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailIndexedPropertiesTest.java
@@ -22,7 +22,6 @@
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
@ClusterScope(numDataNodes = 1)
diff --git a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailTest.java b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailTest.java
index 333dcd5eaac..1b8e349dff2 100644
--- a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailTest.java
+++ b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/ElasticsearchSailTest.java
@@ -22,7 +22,6 @@
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
@ClusterScope(numDataNodes = 1)
diff --git a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/examples/ElasticsearchSailExample.java b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/examples/ElasticsearchSailExample.java
index 992791312e3..0c2644e46e2 100644
--- a/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/examples/ElasticsearchSailExample.java
+++ b/compliance/elasticsearch/src/test/java/org/eclipse/rdf4j/sail/elasticsearch/examples/ElasticsearchSailExample.java
@@ -29,14 +29,14 @@
/**
* Example code showing how to use the LuceneSail
- *
+ *
* @author sauermann
*/
public class ElasticsearchSailExample {
/**
* Create a lucene sail and use it
- *
+ *
* @param args
*/
public static void main(String[] args) throws Exception {
diff --git a/compliance/elasticsearch/src/test/java/org/elasticsearch/bootstrap/JarHell.java b/compliance/elasticsearch/src/test/java/org/elasticsearch/bootstrap/JarHell.java
index e25d3501b6a..22a75373aca 100644
--- a/compliance/elasticsearch/src/test/java/org/elasticsearch/bootstrap/JarHell.java
+++ b/compliance/elasticsearch/src/test/java/org/elasticsearch/bootstrap/JarHell.java
@@ -4,7 +4,6 @@
import java.util.Collections;
import java.util.Set;
import java.util.function.Consumer;
-import java.util.logging.Logger;
/**
* test of elasticsearch pass. Thus as a workaround we deactivate this test. see
diff --git a/compliance/geosparql/pom.xml b/compliance/geosparql/pom.xml
index 69918115cb7..1c23c8e1335 100644
--- a/compliance/geosparql/pom.xml
+++ b/compliance/geosparql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-geosparql-complianceRDF4J GeoSPARQL compliance tests
diff --git a/compliance/lucene/pom.xml b/compliance/lucene/pom.xml
index 523adf33a28..4bc9c6ee523 100644
--- a/compliance/lucene/pom.xml
+++ b/compliance/lucene/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-lucene-complianceRDF4J Lucene Sail Tests
diff --git a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneGeoSPARQLTest.java b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneGeoSPARQLTest.java
index cd997eeadf5..e60b83616f2 100644
--- a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneGeoSPARQLTest.java
+++ b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneGeoSPARQLTest.java
@@ -4,7 +4,7 @@
* 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.
- *******************************************************************************/
+ *******************************************************************************/
package org.eclipse.rdf4j.sail.lucene;
import java.io.File;
diff --git a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailIndexedPropertiesTest.java b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailIndexedPropertiesTest.java
index 88718e90518..e3036f71499 100644
--- a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailIndexedPropertiesTest.java
+++ b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailIndexedPropertiesTest.java
@@ -15,7 +15,7 @@ public class LuceneSailIndexedPropertiesTest extends AbstractLuceneSailIndexedPr
/*
* (non-Javadoc)
- *
+ *
* @see
* org.eclipse.rdf4j.sail.lucene.AbstractLuceneSailIndexedPropertiesTest#configure(org.eclipse.rdf4j.sail.lucene.
* LuceneSail)
diff --git a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailTest.java b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailTest.java
index 768e1e04d3e..014c4f83416 100644
--- a/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailTest.java
+++ b/compliance/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/LuceneSailTest.java
@@ -17,7 +17,7 @@ public class LuceneSailTest extends AbstractLuceneSailTest {
/*
* (non-Javadoc)
- *
+ *
* @see org.eclipse.rdf4j.sail.lucene.AbstractLuceneSailTest#configure(org.eclipse.rdf4j.sail.lucene.LuceneSail)
*/
@Override
diff --git a/compliance/model/pom.xml b/compliance/model/pom.xml
index 47cf63a26e1..1aedf0cc7b1 100644
--- a/compliance/model/pom.xml
+++ b/compliance/model/pom.xml
@@ -3,7 +3,7 @@
rdf4j-complianceorg.eclipse.rdf4j
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOT4.0.0rdf4j-model-compliance
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelTest.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelTest.java
new file mode 100644
index 00000000000..79f9f92de5d
--- /dev/null
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.model;
+
+import org.eclipse.rdf4j.model.impl.DynamicModel;
+import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory;
+
+public class DynamicModelTest extends AbstractModelTest {
+
+ @Override
+ protected Model getNewModel() {
+ return new DynamicModel(new LinkedHashModelFactory());
+ }
+
+}
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/LinkedHashModelNamespacesTest.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/LinkedHashModelNamespacesTest.java
index ffdf9f62887..86e0fd8268f 100644
--- a/compliance/model/src/test/java/org/eclipse/rdf4j/model/LinkedHashModelNamespacesTest.java
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/LinkedHashModelNamespacesTest.java
@@ -12,7 +12,7 @@
/**
* Tests for {@link Namespace} support in {@link LinkedHashModel} using the abstract tests defined in
* {@link ModelNamespacesTest}.
- *
+ *
* @author Peter Ansell p_ansell@yahoo.com
*/
public class LinkedHashModelNamespacesTest extends ModelNamespacesTest {
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/TreeModelNamespacesTest.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/TreeModelNamespacesTest.java
index c35f467d50b..982dc0add2a 100644
--- a/compliance/model/src/test/java/org/eclipse/rdf4j/model/TreeModelNamespacesTest.java
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/TreeModelNamespacesTest.java
@@ -12,7 +12,7 @@
/**
* Tests for {@link Namespace} support in {@link TreeModel} using the abstract tests defined in
* {@link ModelNamespacesTest}.
- *
+ *
* @author Peter Ansell p_ansell@yahoo.com
*/
public class TreeModelNamespacesTest extends ModelNamespacesTest {
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicBenchmark.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicBenchmark.java
index acf4b30aac4..ba718403001 100644
--- a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicBenchmark.java
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicBenchmark.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 201 Eclipse RDF4J contributors.
+ * Copyright (c) 2019 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
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicTest.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicTest.java
index 4278dfd718c..0121eea91df 100644
--- a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicTest.java
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/IsomorphicTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 201 Eclipse RDF4J contributors.
+ * Copyright (c) 2019 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
diff --git a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/Main.java b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/Main.java
index 3fcc4fcb049..6f7edddd8be 100644
--- a/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/Main.java
+++ b/compliance/model/src/test/java/org/eclipse/rdf4j/model/util/Main.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 201 Eclipse RDF4J contributors.
+ * Copyright (c) 2019 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
diff --git a/compliance/pom.xml b/compliance/pom.xml
index 2560d0ce820..f863e4cc53e 100644
--- a/compliance/pom.xml
+++ b/compliance/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-compliancepom
diff --git a/compliance/repository/pom.xml b/compliance/repository/pom.xml
index f769929ebcf..912e51ae1fc 100644
--- a/compliance/repository/pom.xml
+++ b/compliance/repository/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-repository-compliancewar
@@ -56,18 +56,6 @@
${project.version}test
-
- ${project.groupId}
- rdf4j-repository-sail
- ${project.version}
- test
-
-
- ${project.groupId}
- rdf4j-sail-memory
- ${project.version}
- test
- org.eclipse.jettyjetty-server
diff --git a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/LocalRepositoryManagerIntegrationTest.java b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/LocalRepositoryManagerIntegrationTest.java
index 2726f8f046d..37844c1b83e 100644
--- a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/LocalRepositoryManagerIntegrationTest.java
+++ b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/LocalRepositoryManagerIntegrationTest.java
@@ -40,7 +40,7 @@
/**
* Integration tests for {@link LocalRepositoryManager}
- *
+ *
* @author Jeen Broekstra
*/
public class LocalRepositoryManagerIntegrationTest extends RepositoryManagerIntegrationTest {
diff --git a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/RepositoryManagerIntegrationTest.java b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/RepositoryManagerIntegrationTest.java
index 5e457c17674..e058e61e04b 100644
--- a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/RepositoryManagerIntegrationTest.java
+++ b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/manager/RepositoryManagerIntegrationTest.java
@@ -53,4 +53,4 @@ protected Repository createRepository(String id) throws RepositoryConfigExceptio
};
}
-}
\ No newline at end of file
+}
diff --git a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java
index 39d7f5e5297..1c81b8f9566 100644
--- a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java
+++ b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java
@@ -13,7 +13,6 @@
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
import java.util.List;
import org.eclipse.rdf4j.IsolationLevel;
@@ -91,73 +90,53 @@ public void testDuplicateFilter() throws Exception {
}
@Override
- @Ignore
+ @Ignore("relies on SPARQL update operation handled as part of txn")
public void testAddDelete() throws RDF4JException {
System.err.println("temporarily disabled testAddDelete() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("relies on SPARQL update operation handled as part of txn")
public void testAddRemoveInsert() throws RDF4JException {
System.err.println("temporarily disabled testAddRemoveInsert() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("relies on pending updates being visible in own connection")
public void testSizeRollback() throws Exception {
System.err.println("temporarily disabled testSizeRollback() for SPARQLRepository");
}
- @Test
- @Ignore
- @Override
- public void testURISerialization() throws Exception {
- System.err.println("temporarily disabled testURISerialization() for SPARQLRepository");
- }
-
- @Test
- @Ignore
- @Override
- public void testStatementSerialization() throws Exception {
- System.err.println("temporarily disabled testStatementSerialization() for SPARQLRepository");
- }
-
@Override
- @Ignore
+ @Ignore("relies on pending updates being visible in own connection")
public void testAutoCommit() throws Exception {
System.err.println("temporarily disabled testAutoCommit() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("relies on pending updates being visible in own connection")
public void testRollback() throws Exception {
System.err.println("temporarily disabled testRollback() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("relies on pending updates being visible in own connection")
public void testEmptyRollback() throws Exception {
System.err.println("temporarily disabled testEmptyRollback() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("relies on pending updates being visible in own connection")
public void testEmptyCommit() throws Exception {
System.err.println("temporarily disabled testEmptyCommit() for SPARQLRepository");
}
@Override
- @Ignore
+ @Ignore("SeRQL language not supported on SPARQL endpoints")
public void testPrepareSeRQLQuery() throws Exception {
System.err.println("disabled testPrepareSeRQLQuery() for SPARQLRepository");
}
- @Override
- @Ignore
- public void testLiteralSerialization() throws Exception {
- System.err.println("temporarily disabled testLiteralSerialization() for SPARQLRepository");
- }
-
@Override
@Ignore
public void testSizeCommit() throws Exception {
@@ -212,12 +191,6 @@ public void testGetStatementsContextHandling() throws Exception {
private void enableQuadModeOnConnection(SPARQLConnection con) throws Exception {
Field quadModeField = SPARQLConnection.class.getDeclaredField("quadMode");
quadModeField.setAccessible(true);
-
- // remove final modifier from field
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(quadModeField, quadModeField.getModifiers() & ~Modifier.FINAL);
-
quadModeField.set(con, true);
}
diff --git a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/federation/RepositoryFederatedServiceIntegrationTest.java b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/federation/RepositoryFederatedServiceIntegrationTest.java
index c954080ab6c..7f8eab07221 100644
--- a/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/federation/RepositoryFederatedServiceIntegrationTest.java
+++ b/compliance/repository/src/test/java/org/eclipse/rdf4j/repository/sparql/federation/RepositoryFederatedServiceIntegrationTest.java
@@ -33,7 +33,7 @@
/**
* Integration tests for {@link RepositoryFederatedService}
- *
+ *
* @author Andreas Schwarte
*
*/
@@ -101,7 +101,7 @@ public void test3() throws Exception {
vf.createStatement(iri("s2"), RDFS.LABEL, l("val2")),
vf.createStatement(iri("s3"), RDFS.LABEL, l("val3"))));
- String query = "SELECT ?var WHERE { VALUES ?var { 'val1' 'val2' } . SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 1000 } }";
+ String query = "SELECT ?var WHERE { VALUES ?var { 'val1' 'val2' } . SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 1000 } } order by ?var";
assertResultEquals(evaluateQuery(query), "var", Lists.newArrayList(l("val1"), l("val2")));
}
@@ -129,7 +129,7 @@ public void test4() throws Exception {
vf.createStatement(iri("s2"), RDFS.LABEL, l("val2")),
vf.createStatement(iri("s3"), RDFS.LABEL, l("val3"))));
- String query = "SELECT ?var WHERE { SERVICE { ?s ?p ?var } . SERVICE { ?s ?p ?var } }";
+ String query = "SELECT ?var WHERE { SERVICE { ?s ?p ?var } . SERVICE { ?s ?p ?var } } order by ?var";
assertResultEquals(evaluateQuery(query), "var", Lists.newArrayList(l("val1"), l("val2"), l("val3")));
}
@@ -143,7 +143,7 @@ public void test4a() throws Exception {
vf.createStatement(iri("s3"), RDFS.LABEL, l("val3"))));
// Note: here we apply a workaround and explicitly project "?__rowIdx"
- String query = "SELECT ?var WHERE { SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 3 } . SERVICE { SELECT ?s ?var ?__rowIdx { ?s ?p ?var } LIMIT 3 } }";
+ String query = "SELECT ?var WHERE { SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 3 } . SERVICE { SELECT ?s ?var ?__rowIdx { ?s ?p ?var } LIMIT 3 } } order by ?var";
assertResultEquals(evaluateQuery(query), "var", Lists.newArrayList(l("val1"), l("val2"), l("val3")));
}
@@ -156,7 +156,7 @@ public void test4b() throws Exception {
vf.createStatement(iri("s2"), RDFS.LABEL, l("val2")),
vf.createStatement(iri("s3"), RDFS.LABEL, l("val3"))));
- String query = "SELECT ?var WHERE { SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 3 } . SERVICE { SELECT ?s ?var { ?s ?p ?var } LIMIT 3 } }";
+ String query = "SELECT ?var WHERE { SERVICE { SELECT ?var { ?s ?p ?var } LIMIT 3 } . SERVICE { SELECT ?s ?var { ?s ?p ?var } LIMIT 3 } } order by ?var";
assertResultEquals(evaluateQuery(query), "var", Lists.newArrayList(l("val1"), l("val2"), l("val3")));
}
diff --git a/compliance/rio/pom.xml b/compliance/rio/pom.xml
index b732c4d6899..3b3bfa5d446 100644
--- a/compliance/rio/pom.xml
+++ b/compliance/rio/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-rio-complianceRDF4J Rio compliance tests
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java
index 429702080ae..1ac0ff3c415 100644
--- a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java
@@ -13,7 +13,7 @@
/**
* JUnit test for the N-Quads parser.
- *
+ *
* @author Arjohn Kampman
*/
public class NQuadsParserTest extends AbstractNQuadsParserTest {
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java
index 72b038ca07d..80ec12281aa 100644
--- a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java
@@ -13,7 +13,7 @@
/**
* JUnit test for the N-Triples parser.
- *
+ *
* @author Arjohn Kampman
*/
public class NTriplesParserTest extends AbstractNTriplesParserTest {
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java
index deedb7f37d9..b2f1d0db1d5 100644
--- a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java
@@ -11,7 +11,7 @@
/**
* JUnit test for the RDF/JSON parser.
- *
+ *
* @author Peter Ansell
*/
public class RDFJSONParserTest extends RDFJSONParserTestCase {
diff --git a/compliance/serql/pom.xml b/compliance/serql/pom.xml
index fcbcdc30539..1f83d1b7c68 100644
--- a/compliance/serql/pom.xml
+++ b/compliance/serql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-serql-complianceRDF4J SeRQL query parser compliance tests
diff --git a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/MemorySeRQLQueryTest.java b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/MemorySeRQLQueryTest.java
index 66f4cdf49bc..28ebd4b6511 100644
--- a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/MemorySeRQLQueryTest.java
+++ b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/MemorySeRQLQueryTest.java
@@ -10,7 +10,6 @@
import java.util.List;
import org.eclipse.rdf4j.query.QueryLanguage;
-import org.eclipse.rdf4j.query.parser.serql.SeRQLQueryTestCase;
import org.eclipse.rdf4j.sail.NotifyingSail;
import org.eclipse.rdf4j.sail.memory.MemoryStore;
diff --git a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/NativeSeRQLQueryTest.java b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/NativeSeRQLQueryTest.java
index f084bb765be..720c40782ec 100644
--- a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/NativeSeRQLQueryTest.java
+++ b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/NativeSeRQLQueryTest.java
@@ -13,7 +13,6 @@
import org.eclipse.rdf4j.common.io.FileUtil;
import org.eclipse.rdf4j.query.QueryLanguage;
-import org.eclipse.rdf4j.query.parser.serql.SeRQLQueryTestCase;
import org.eclipse.rdf4j.sail.NotifyingSail;
import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
diff --git a/compliance/shacl/pom.xml b/compliance/shacl/pom.xml
index 531c9069bb2..50c2786a6ce 100644
--- a/compliance/shacl/pom.xml
+++ b/compliance/shacl/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-shacl-complianceRDF4J SHACL compliance tests
diff --git a/compliance/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SHACLComplianceTest.java b/compliance/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SHACLComplianceTest.java
index c9454fb31da..1f89a92f40e 100644
--- a/compliance/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SHACLComplianceTest.java
+++ b/compliance/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SHACLComplianceTest.java
@@ -34,8 +34,9 @@ public class SHACLComplianceTest extends AbstractSHACLTest {
public static TestSuite suite() throws Exception {
String[] ignoredDirectories = { "targets", "sparql", "complex", "misc", "node", "path", "validation-reports",
"property" };
- if (RUN_ALL)
+ if (RUN_ALL) {
ignoredDirectories = new String[0];
+ }
return new SHACLManifestTestSuiteFactory().createTestSuite(new TestFactory() {
diff --git a/compliance/solr/pom.xml b/compliance/solr/pom.xml
index 3fd877c7623..46adfe15f24 100644
--- a/compliance/solr/pom.xml
+++ b/compliance/solr/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-solr-complianceRDF4J Solr Sail Tests
diff --git a/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/SolrIndexTest.java b/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/SolrIndexTest.java
index a89114efca7..5650225e130 100644
--- a/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/SolrIndexTest.java
+++ b/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/SolrIndexTest.java
@@ -391,8 +391,9 @@ private void assertStatement(Statement statement, SearchDocument document) {
List fields = document.getProperty(SearchFields.getPropertyField(statement.getPredicate()));
assertNotNull("field " + statement.getPredicate() + " not found in document " + document, fields);
for (String f : fields) {
- if (((Literal) statement.getObject()).getLabel().equals(f))
+ if (((Literal) statement.getObject()).getLabel().equals(f)) {
return;
+ }
}
fail("Statement not found in document " + statement);
}
diff --git a/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/examples/SolrSailExample.java b/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/examples/SolrSailExample.java
index 3c0125cd958..c1654f6c2e4 100644
--- a/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/examples/SolrSailExample.java
+++ b/compliance/solr/src/test/java/org/eclipse/rdf4j/sail/solr/examples/SolrSailExample.java
@@ -29,14 +29,14 @@
/**
* Example code showing how to use the LuceneSail
- *
+ *
* @author sauermann
*/
public class SolrSailExample {
/**
* Create a lucene sail and use it
- *
+ *
* @param args
*/
public static void main(String[] args) throws Exception {
diff --git a/compliance/sparql/pom.xml b/compliance/sparql/pom.xml
index 8ff52b54902..62cf9863506 100644
--- a/compliance/sparql/pom.xml
+++ b/compliance/sparql/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-compliance
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-sparql-compliancewar
@@ -119,6 +119,11 @@
rdf4j-sail-federation${project.version}
+
+ ${project.groupId}
+ rdf4j-tools-federation
+ ${project.version}
+ org.slf4jslf4j-api
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java
index eeb2ff0c0fd..e5ccbd2a466 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java
@@ -27,7 +27,7 @@
/**
* An embedded http server for SPARQL query testing. Initializes a memory store repository for each specified
* repositoryId.
- *
+ *
* @author Andreas Schwarte
*/
public class SPARQLEmbeddedServer {
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java
index 2981e7d0415..af09932d5e2 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java
@@ -23,7 +23,6 @@
import org.eclipse.rdf4j.common.iteration.Iterations;
import org.eclipse.rdf4j.common.text.StringUtil;
import org.eclipse.rdf4j.model.IRI;
-import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
@@ -47,7 +46,6 @@
import org.eclipse.rdf4j.query.impl.TupleQueryResultBuilder;
import org.eclipse.rdf4j.query.resultio.QueryResultFormat;
import org.eclipse.rdf4j.query.resultio.QueryResultIO;
-import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
import org.eclipse.rdf4j.query.resultio.TupleQueryResultParser;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
@@ -63,7 +61,6 @@
import org.eclipse.rdf4j.sail.memory.MemoryStore;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,7 +71,7 @@
* Test suite for evaluation of SPARQL queries involving SERVICE clauses. The test suite starts up an embedded Jetty
* server running RDF4J Server, which functions as the SPARQL endpoint to test against. The test is configured to
* execute the W3C service tests located in rdf4j-sparql-testsuite/src/main/resources/testcases-service
- *
+ *
* @author Jeen Broekstra
* @author Andreas Schwarte
*/
@@ -103,9 +100,10 @@ public SPARQLServiceEvaluationTest() {
@Before
public void setUp() throws Exception {
// set up the server: the maximal number of endpoints must be known
- List repositoryIds = new ArrayList(MAX_ENDPOINTS);
- for (int i = 1; i <= MAX_ENDPOINTS; i++)
+ List repositoryIds = new ArrayList<>(MAX_ENDPOINTS);
+ for (int i = 1; i <= MAX_ENDPOINTS; i++) {
repositoryIds.add("endpoint" + i);
+ }
server = new SPARQLEmbeddedServer(repositoryIds);
try {
@@ -115,7 +113,7 @@ public void setUp() throws Exception {
throw e;
}
- remoteRepositories = new ArrayList(MAX_ENDPOINTS);
+ remoteRepositories = new ArrayList<>(MAX_ENDPOINTS);
for (int i = 1; i <= MAX_ENDPOINTS; i++) {
HTTPRepository r = new HTTPRepository(getRepositoryUrl(i));
r.initialize();
@@ -128,7 +126,7 @@ public void setUp() throws Exception {
/**
* Get the repository url, initialized repositories are called endpoint1 endpoint2 .. endpoint%MAX_ENDPOINTS%
- *
+ *
* @param i the index of the repository, starting with 1
* @return
*/
@@ -138,7 +136,7 @@ protected String getRepositoryUrl(int i) {
/**
* Get the repository, initialized repositories are called endpoint1 endpoint2 .. endpoint%MAX_ENDPOINTS%
- *
+ *
* @param i the index of the repository, starting with 1
* @return
*/
@@ -148,7 +146,7 @@ public HTTPRepository getRepository(int i) {
/**
* Prepare a particular test, and load the specified data. Note: the repositories are cleared before loading data
- *
+ *
* @param localData a local data file that is added to local repository, use null if there is no local data
* @param endpointData a list of endpoint data files, dataFile at index is loaded to endpoint%i%, use empty list for
* no remote data
@@ -156,9 +154,10 @@ public HTTPRepository getRepository(int i) {
*/
protected void prepareTest(String localData, List endpointData) throws Exception {
- if (endpointData.size() > MAX_ENDPOINTS)
+ if (endpointData.size() > MAX_ENDPOINTS) {
throw new RuntimeException(
"MAX_ENDPOINTs to low, " + endpointData.size() + " repositories needed. Adjust configuration");
+ }
if (localData != null) {
loadDataSet(localRepository, localData);
@@ -173,7 +172,7 @@ protected void prepareTest(String localData, List endpointData) throws E
/**
* Load a dataset. Note: the repositories are cleared before loading data
- *
+ *
* @param rep
* @param datasetFile
* @throws RDFParseException
@@ -185,8 +184,9 @@ protected void loadDataSet(Repository rep, String datasetFile)
logger.debug("loading dataset...");
InputStream dataset = SPARQLServiceEvaluationTest.class.getResourceAsStream(datasetFile);
- if (dataset == null)
+ if (dataset == null) {
throw new IllegalArgumentException("Datasetfile " + datasetFile + " not found.");
+ }
RepositoryConnection con = rep.getConnection();
try {
@@ -214,7 +214,7 @@ public void tearDown() throws Exception {
/**
* Verify that BIND clause alias from the SERVICE clause gets added to the result set.
- *
+ *
* @see #646
*/
@Test
@@ -243,7 +243,7 @@ public void testValuesBindClauseHandling() throws Exception {
/**
* Verify that all relevant variable names from the SERVICE clause get added to the result set when a BIND clause is
* present.
- *
+ *
* @see #703
*/
@Test
@@ -456,7 +456,7 @@ public void testNonAsciiCharHandling() throws Exception {
/**
* Execute a testcase, both queryFile and expectedResultFile must be files located on the class path.
- *
+ *
* @param queryFile
* @param expectedResultFile
* @param checkOrder
@@ -497,7 +497,7 @@ private void execute(String queryFile, String expectedResultFile, boolean checkO
/**
* Read the query string from the specified resource
- *
+ *
* @param queryResource
* @return
* @throws RepositoryException
@@ -514,7 +514,7 @@ private String readQueryString(String queryResource) throws RepositoryException,
/**
* Read the expected tuple query result from the specified resource
- *
+ *
* @param queryResource
* @return
* @throws RepositoryException
@@ -545,7 +545,7 @@ private TupleQueryResult readExpectedTupleQueryResult(String resultFile) throws
/**
* Read the expected graph query result from the specified resource
- *
+ *
* @param resultFile
* @return
* @throws Exception
@@ -558,7 +558,7 @@ private Set readExpectedGraphQueryResult(String resultFile) throws Ex
parser.setPreserveBNodeIDs(true);
parser.setValueFactory(SimpleValueFactory.getInstance());
- Set result = new LinkedHashSet();
+ Set result = new LinkedHashSet<>();
parser.setRDFHandler(new StatementCollector(result));
InputStream in = SPARQLServiceEvaluationTest.class.getResourceAsStream(resultFile);
@@ -573,7 +573,7 @@ private Set readExpectedGraphQueryResult(String resultFile) throws Ex
/**
* Compare two tuple query results
- *
+ *
* @param queryResult
* @param expectedResult
* @param checkOrder
@@ -625,10 +625,10 @@ private void compareTupleQueryResults(TupleQueryResult queryResult, TupleQueryRe
List expectedBindings = Iterations.asList(expectedResultTable);
- List missingBindings = new ArrayList(expectedBindings);
+ List missingBindings = new ArrayList<>(expectedBindings);
missingBindings.removeAll(queryBindings);
- List unexpectedBindings = new ArrayList(queryBindings);
+ List unexpectedBindings = new ArrayList<>(queryBindings);
unexpectedBindings.removeAll(expectedBindings);
StringBuilder message = new StringBuilder(128);
@@ -694,7 +694,7 @@ private void compareTupleQueryResults(TupleQueryResult queryResult, TupleQueryRe
/**
* Compare two graphs
- *
+ *
* @param queryResult
* @param expectedResult
* @throws Exception
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java
index d9d62e047ea..f98bda3da8e 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java
@@ -21,9 +21,6 @@
import org.eclipse.rdf4j.model.vocabulary.EARL;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11SyntaxTest;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLUpdateConformanceTest;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.RepositoryException;
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/SPARQL12QueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/SPARQL12QueryTest.java
index c2ac46ecc7c..626e8a7fd7e 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/SPARQL12QueryTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/SPARQL12QueryTest.java
@@ -19,7 +19,7 @@
/**
* SPARQL Query tests using testcase from the SPARQL 1.2 Working Group
- *
+ *
* @author Jeen Broekstra
*
*/
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10QueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10QueryTest.java
index cf9654d665c..2ba2c926e6b 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10QueryTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10QueryTest.java
@@ -8,8 +8,6 @@
package org.eclipse.rdf4j.query.parser.sparql.manifest;
import org.eclipse.rdf4j.query.Dataset;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11ManifestTest;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
import org.eclipse.rdf4j.repository.sail.SailRepository;
@@ -19,7 +17,7 @@
/**
* Checks conformance of SPARQL query evaluation against the W3C-approved SPARQL 1.0 query test cases
- *
+ *
* @author Jeen Broekstra
*/
public class W3CApprovedSPARQL10QueryTest extends SPARQLQueryTest {
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10SyntaxTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10SyntaxTest.java
index 0667ca16927..06caaf5335a 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10SyntaxTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL10SyntaxTest.java
@@ -11,13 +11,12 @@
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.parser.ParsedOperation;
import org.eclipse.rdf4j.query.parser.QueryParserUtil;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11SyntaxTest;
import junit.framework.Test;
/**
* Checks conformance of SPARQL query parsing against the W3C-approved SPARQL 1.0 test cases
- *
+ *
* @author Jeen Broekstra
*/
public class W3CApprovedSPARQL10SyntaxTest extends SPARQL11SyntaxTest {
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java
index f2281611d5e..a197fcbedf3 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java
@@ -14,9 +14,11 @@
import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.Ignore;
import junit.framework.Test;
+@Ignore("replaced by org.eclipse.rdf4j.sail.memory.MemorySPARQL11QueryComplianceTest")
public class W3CApprovedSPARQL11QueryTest extends SPARQLQueryTest {
public static Test suite() throws Exception {
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java
index f5637f490c8..027dd1fa9ba 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java
@@ -11,7 +11,6 @@
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.parser.ParsedOperation;
import org.eclipse.rdf4j.query.parser.QueryParserUtil;
-import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11SyntaxTest;
import junit.framework.Test;
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FedXSPARQL11QueryComplianceTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FedXSPARQL11QueryComplianceTest.java
new file mode 100644
index 00000000000..833fb3ec6f2
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FedXSPARQL11QueryComplianceTest.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.federation;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.federated.FedXFactory;
+import org.eclipse.rdf4j.federated.repository.FedXRepository;
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11QueryComplianceTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.config.RepositoryConfig;
+import org.eclipse.rdf4j.repository.config.RepositoryConfigException;
+import org.eclipse.rdf4j.repository.config.RepositoryImplConfig;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.manager.RepositoryManager;
+import org.eclipse.rdf4j.repository.manager.RepositoryProvider;
+import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig;
+import org.eclipse.rdf4j.sail.memory.config.MemoryStoreConfig;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * @author jeen
+ *
+ */
+public class FedXSPARQL11QueryComplianceTest extends SPARQL11QueryComplianceTest {
+
+ @Rule
+ public TemporaryFolder tempFolder = new TemporaryFolder();
+
+ private static final String dirName = "testmanager";
+
+ private RepositoryManager manager;
+
+ public FedXSPARQL11QueryComplianceTest(String displayName, String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataset, boolean ordered) {
+ super(displayName, testURI, name, queryFileURL, resultFileURL, dataset, ordered);
+
+ // FIXME see https://github.com/eclipse/rdf4j/issues/2173
+ addIgnoredTest("sq04 - Subquery within graph pattern, default graph does not apply");
+ }
+
+ private void initManager() {
+ if (manager == null) {
+ try {
+ manager = RepositoryProvider.getRepositoryManager(tempFolder.newFolder(dirName));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ protected Repository newRepository() throws Exception {
+ initManager();
+
+ addMemoryStore("repo1");
+ addMemoryStore("repo2");
+ FedXRepository repo = FedXFactory.newFederation()
+ .withResolvableEndpoint("repo1", true)
+ .withResolvableEndpoint("repo2")
+ .withRepositoryResolver(manager)
+ .create();
+
+ // Use DatasetRepository to handle on-the-fly loading of local datasets, as specified in the test manifest
+ return new DatasetRepository(repo);
+ }
+
+ private void addMemoryStore(String repoId) throws RepositoryConfigException, RepositoryException, IOException {
+ RepositoryImplConfig implConfig = new SailRepositoryConfig(new MemoryStoreConfig());
+ RepositoryConfig config = new RepositoryConfig(repoId, implConfig);
+ manager.addRepositoryConfig(config);
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryComplexSPARQLQueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryComplexSPARQLQueryTest.java
index f309521dc7c..a96091f7c18 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryComplexSPARQLQueryTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryComplexSPARQLQueryTest.java
@@ -10,7 +10,6 @@
import org.eclipse.rdf4j.query.parser.sparql.ComplexSPARQLQueryTest;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.sail.SailRepository;
-import org.eclipse.rdf4j.sail.memory.MemoryStore;
/**
* @author jeen
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQL11QueryComplianceTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQL11QueryComplianceTest.java
new file mode 100644
index 00000000000..ec038081e7c
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQL11QueryComplianceTest.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11QueryComplianceTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+
+/**
+ * Run {@link SPARQL11QueryComplianceTest} on an in-memory store
+ *
+ * @author Jeen Broekstra
+ */
+public class MemorySPARQL11QueryComplianceTest extends SPARQL11QueryComplianceTest {
+
+ public MemorySPARQL11QueryComplianceTest(String displayName, String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataset, boolean ordered) {
+ super(displayName, testURI, name, queryFileURL, resultFileURL, dataset, ordered);
+ }
+
+ @Override
+ protected Repository newRepository() throws Exception {
+ return new DatasetRepository(new SailRepository(new MemoryStore()));
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQLUpdateTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQLUpdateTest.java
index 6a19cc296b4..bf8d3dc308d 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQLUpdateTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/memory/MemorySPARQLUpdateTest.java
@@ -10,11 +10,10 @@
import org.eclipse.rdf4j.query.parser.sparql.SPARQLUpdateTest;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.sail.SailRepository;
-import org.eclipse.rdf4j.sail.memory.MemoryStore;
/**
* Test SPARQL 1.1 Update functionality on an in-memory store.
- *
+ *
* @author Jeen Broekstra
*/
public class MemorySPARQLUpdateTest extends SPARQLUpdateTest {
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeComplexSPARQLQueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeComplexSPARQLQueryTest.java
index de746cc7b2e..b58b43be962 100644
--- a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeComplexSPARQLQueryTest.java
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeComplexSPARQLQueryTest.java
@@ -13,7 +13,6 @@
import org.eclipse.rdf4j.query.parser.sparql.ComplexSPARQLQueryTest;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.sail.SailRepository;
-import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
/**
* @author jeen
diff --git a/core/client/pom.xml b/core/client/pom.xml
index accfb619ceb..57fa76a9154 100644
--- a/core/client/pom.xml
+++ b/core/client/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-core
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-clientRDF4J: Client Libraries
diff --git a/core/http/client/pom.xml b/core/http/client/pom.xml
index b4db03916bf..c3db1e141ba 100644
--- a/core/http/client/pom.xml
+++ b/core/http/client/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-http
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-http-clientRDF4J: HTTP client
@@ -80,6 +80,24 @@
${project.version}test
+
+ ${project.groupId}
+ rdf4j-rio-nquads
+ ${project.version}
+ test
+
+
+ ${project.groupId}
+ rdf4j-rio-jsonld
+ ${project.version}
+ test
+
+
+ ${project.groupId}
+ rdf4j-rio-turtle
+ ${project.version}
+ test
+
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundGraphResult.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundGraphResult.java
index 845cc8e3468..a9d850a6cd6 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundGraphResult.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundGraphResult.java
@@ -15,14 +15,14 @@
/**
* Provides concurrent access to statements as they are being parsed.
- *
+ *
* @author James Leigh
* @deprecated Use {@link org.eclipse.rdf4j.query.impl.BackgroundGraphResult} instead.
*/
@Deprecated
public class BackgroundGraphResult extends org.eclipse.rdf4j.query.impl.BackgroundGraphResult {
public BackgroundGraphResult(RDFParser parser, InputStream in, Charset charset, String baseURI) {
- this(new QueueCursor(10), parser, in, charset, baseURI);
+ this(new QueueCursor<>(10), parser, in, charset, baseURI);
}
public BackgroundGraphResult(QueueCursor queue, RDFParser parser, InputStream in, Charset charset,
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundTupleResult.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundTupleResult.java
index b2ebe51a06c..00b59c387d7 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundTupleResult.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/BackgroundTupleResult.java
@@ -14,14 +14,14 @@
/**
* Provides concurrent access to tuple results as they are being parsed.
- *
+ *
* @author James Leigh
* @deprecated Use {@link org.eclipse.rdf4j.query.resultio.helpers.BackgroundTupleResult} instead.
*/
@Deprecated
public class BackgroundTupleResult extends org.eclipse.rdf4j.query.resultio.helpers.BackgroundTupleResult {
public BackgroundTupleResult(TupleQueryResultParser parser, InputStream in) {
- this(new QueueCursor(10), parser, in);
+ this(new QueueCursor<>(10), parser, in);
}
public BackgroundTupleResult(QueueCursor queue, TupleQueryResultParser parser, InputStream in) {
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientDependent.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientDependent.java
index e8193603430..29a6160dac7 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientDependent.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientDependent.java
@@ -11,7 +11,7 @@
/**
* Common interface for objects, such as Repository and RepositoryConnection, that are dependent on {@link HttpClient}.
- *
+ *
* @author James Leigh
*/
public interface HttpClientDependent {
@@ -20,7 +20,7 @@ public interface HttpClientDependent {
* {@link HttpClient} that has been assigned or has been used by this object. The life cycle might not be or might
* be tied to this object, depending on whether {@link HttpClient} was passed to or created by this object
* respectively.
- *
+ *
* @return an {@link HttpClient} instance or null
*/
HttpClient getHttpClient();
@@ -29,7 +29,7 @@ public interface HttpClientDependent {
* Assign an {@link HttpClient} that this object should use. The life cycle of the given {@link HttpClient} is
* independent of this object. Closing or shutting down this object does not have any impact on the given client.
* Callers must ensure that the given client is properly closed elsewhere.
- *
+ *
* @param client
*/
void setHttpClient(HttpClient client);
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientSessionManager.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientSessionManager.java
index 5051ed84f35..d97179f3b05 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientSessionManager.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/HttpClientSessionManager.java
@@ -11,7 +11,7 @@
/**
* Manager for remote HTTP sessions using a {@link HttpClient}.
- *
+ *
* @author James Leigh
*/
@SuppressWarnings("deprecation")
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/QueueCursor.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/QueueCursor.java
index 422f89d50de..269fab0d67e 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/QueueCursor.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/QueueCursor.java
@@ -12,7 +12,7 @@
/**
* Makes working with a queue easier by adding the methods {@link #done()} and {@link #toss(Exception)} and
* automatically converting the exception into a QueryEvaluationException with an appropriate stack trace.
- *
+ *
* @author James Leigh
* @deprecated Use {@link org.eclipse.rdf4j.query.impl.QueueCursor} instead
*/
@@ -21,7 +21,7 @@ public class QueueCursor extends org.eclipse.rdf4j.query.impl.QueueCursor
/**
* Creates an QueueCursor with the given (fixed) capacity and default access policy.
- *
+ *
* @param capacity the capacity of this queue
*/
public QueueCursor(int capacity) {
@@ -30,7 +30,7 @@ public QueueCursor(int capacity) {
/**
* Creates an QueueCursor with the given (fixed) capacity and the specified access policy.
- *
+ *
* @param capacity the capacity of this queue
* @param fair if true then queue accesses for threads blocked on insertion or removal, are processed
* in FIFO order; if false the access order is unspecified.
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSession.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSession.java
index 03d20ce19be..d11080eeb1f 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSession.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSession.java
@@ -90,7 +90,7 @@
/**
* A {@link SPARQLProtocolSession} subclass which extends the standard SPARQL 1.1 Protocol with additional
* functionality, as documented in the RDF4J REST API.
- *
+ *
* @author Andreas Schwarte
* @author Jeen Broekstra
* @see RDF4J REST API
@@ -298,7 +298,7 @@ public long size(Resource... contexts) throws IOException, RepositoryException,
/**
* Create a new repository.
- *
+ *
* @param config the repository configuration
* @throws IOException
* @throws RepositoryException
@@ -332,7 +332,7 @@ public void createRepository(RepositoryConfig config) throws IOException, Reposi
/**
* Update the config of an existing repository.
- *
+ *
* @param config the repository configuration
* @throws IOException
* @throws RepositoryException
@@ -389,7 +389,7 @@ public void deleteRepository(String repositoryID) throws IOException, Repository
* @throws RDFHandlerException
* @throws QueryInterruptedException
* @throws UnauthorizedException
- *
+ *
* @since 3.1.0
*/
public void getRepositoryConfig(StatementCollector statementCollector) throws UnauthorizedException,
@@ -758,7 +758,7 @@ void executeTransactionPing() {
/**
* Appends the action as a parameter to the supplied url
- *
+ *
* @param url a url on which to append the parameter. it is assumed the url has no parameters.
* @param action the action to add as a parameter
* @return the url parametrized with the supplied action
@@ -769,7 +769,7 @@ private String appendAction(String url, Action action) {
/**
* Sends a transaction list as serialized XML to the server.
- *
+ *
* @deprecated since 2.8.0
* @param txn
* @throws IOException
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SPARQLProtocolSession.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SPARQLProtocolSession.java
index c109458c24c..cf4ba06eb97 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SPARQLProtocolSession.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SPARQLProtocolSession.java
@@ -10,18 +10,24 @@
import static org.eclipse.rdf4j.http.protocol.Protocol.ACCEPT_PARAM_NAME;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
+import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
@@ -52,6 +58,7 @@
import org.apache.http.util.EntityUtils;
import org.eclipse.rdf4j.RDF4JConfigException;
import org.eclipse.rdf4j.RDF4JException;
+import org.eclipse.rdf4j.http.client.shacl.RemoteShaclValidationException;
import org.eclipse.rdf4j.http.protocol.Protocol;
import org.eclipse.rdf4j.http.protocol.UnauthorizedException;
import org.eclipse.rdf4j.http.protocol.error.ErrorInfo;
@@ -80,6 +87,7 @@
import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
import org.eclipse.rdf4j.query.resultio.TupleQueryResultParser;
import org.eclipse.rdf4j.query.resultio.TupleQueryResultParserRegistry;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultWriter;
import org.eclipse.rdf4j.query.resultio.helpers.BackgroundTupleResult;
import org.eclipse.rdf4j.query.resultio.helpers.QueryResultCollector;
import org.eclipse.rdf4j.repository.RepositoryException;
@@ -90,6 +98,7 @@
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.rio.RDFParser;
import org.eclipse.rdf4j.rio.RDFParserRegistry;
+import org.eclipse.rdf4j.rio.RDFWriter;
import org.eclipse.rdf4j.rio.Rio;
import org.eclipse.rdf4j.rio.UnsupportedRDFormatException;
import org.eclipse.rdf4j.rio.helpers.BasicParserSettings;
@@ -108,7 +117,7 @@
*
* Functionality specific to the RDF4J HTTP protocol can be found in {@link RDF4JProtocolSession} (which is used by
* HTTPRepository).
- *
+ *
* @author Herko ter Horst
* @author Arjohn Kampman
* @author Andreas Schwarte
@@ -148,7 +157,7 @@ public class SPARQLProtocolSession implements HttpClientDependent, AutoCloseable
*/
private final int maximumUrlLength;
- final Logger logger = LoggerFactory.getLogger(SPARQLProtocolSession.class);
+ final static Logger logger = LoggerFactory.getLogger(SPARQLProtocolSession.class);
/*-----------*
* Variables *
@@ -245,7 +254,7 @@ protected void setUpdateURL(String updateURL) {
/**
* Sets the preferred format for encoding tuple query results. The {@link TupleQueryResultFormat#BINARY binary}
* format is preferred by default.
- *
+ *
* @param format The preferred {@link TupleQueryResultFormat}, or null to indicate no specific format is
* preferred.
*/
@@ -255,7 +264,7 @@ public void setPreferredTupleQueryResultFormat(TupleQueryResultFormat format) {
/**
* Gets the preferred {@link TupleQueryResultFormat} for encoding tuple query results.
- *
+ *
* @return The preferred format, of null if no specific format is preferred.
*/
public TupleQueryResultFormat getPreferredTupleQueryResultFormat() {
@@ -265,7 +274,7 @@ public TupleQueryResultFormat getPreferredTupleQueryResultFormat() {
/**
* Sets the preferred format for encoding RDF documents. The {@link RDFFormat#TURTLE Turtle} format is preferred by
* default.
- *
+ *
* @param format The preferred {@link RDFFormat}, or null to indicate no specific format is preferred.
*/
public void setPreferredRDFFormat(RDFFormat format) {
@@ -274,7 +283,7 @@ public void setPreferredRDFFormat(RDFFormat format) {
/**
* Gets the preferred {@link RDFFormat} for encoding RDF documents.
- *
+ *
* @return The preferred format, of null if no specific format is preferred.
*/
public RDFFormat getPreferredRDFFormat() {
@@ -284,7 +293,7 @@ public RDFFormat getPreferredRDFFormat() {
/**
* Sets the preferred format for encoding boolean query results. The {@link BooleanQueryResultFormat#TEXT binary}
* format is preferred by default.
- *
+ *
* @param format The preferred {@link BooleanQueryResultFormat}, or null to indicate no specific format is
* preferred.
*/
@@ -294,7 +303,7 @@ public void setPreferredBooleanQueryResultFormat(BooleanQueryResultFormat format
/**
* Gets the preferred {@link BooleanQueryResultFormat} for encoding boolean query results.
- *
+ *
* @return The preferred format, of null if no specific format is preferred.
*/
public BooleanQueryResultFormat getPreferredBooleanQueryResultFormat() {
@@ -303,7 +312,7 @@ public BooleanQueryResultFormat getPreferredBooleanQueryResultFormat() {
/**
* Set the username and password for authentication with the remote server.
- *
+ *
* @param username the username
* @param password the password
*/
@@ -445,7 +454,7 @@ public boolean sendBooleanQuery(QueryLanguage ql, String query, String baseURI,
/**
* Get the additional HTTP headers which will be used
- *
+ *
* @return a read-only view of the additional HTTP headers which will be included in every request to the server.
*/
public Map getAdditionalHttpHeaders() {
@@ -455,7 +464,7 @@ public Map getAdditionalHttpHeaders() {
/**
* Set additional HTTP headers to be included in every request to the server, which may be required for certain
* unusual server configurations.
- *
+ *
* @param additionalHttpHeaders a map containing pairs of header names and values. May be null
*/
public void setAdditionalHttpHeaders(Map additionalHttpHeaders) {
@@ -474,8 +483,9 @@ protected HttpUriRequest getQueryMethod(QueryLanguage ql, String query, String b
String queryUrlWithParams;
try {
URIBuilder urib = new URIBuilder(getQueryURL());
- for (NameValuePair nvp : queryParams)
+ for (NameValuePair nvp : queryParams) {
urib.addParameter(nvp.getName(), nvp.getValue());
+ }
queryUrlWithParams = urib.toString();
} catch (URISyntaxException e) {
throw new AssertionError(e);
@@ -501,7 +511,7 @@ protected HttpUriRequest getQueryMethod(QueryLanguage ql, String query, String b
/**
* Return whether the provided query should use POST (otherwise use GET)
- *
+ *
* @param fullQueryUrl the complete URL, including hostname and all HTTP query parameters
*/
protected boolean shouldUsePost(String fullQueryUrl) {
@@ -525,8 +535,9 @@ protected HttpUriRequest getUpdateMethod(QueryLanguage ql, String update, String
method.setEntity(new UrlEncodedFormEntity(queryParams, UTF8));
if (this.additionalHttpHeaders != null) {
- for (Map.Entry additionalHeader : additionalHttpHeaders.entrySet())
+ for (Map.Entry additionalHeader : additionalHttpHeaders.entrySet()) {
method.addHeader(additionalHeader.getKey(), additionalHeader.getValue());
+ }
}
return method;
@@ -688,6 +699,21 @@ protected void getTupleQueryResult(HttpUriRequest method, TupleQueryResultHandle
QueryResultFormat format = TupleQueryResultFormat.matchMIMEType(mimeType, tqrFormats)
.orElseThrow(() -> new RepositoryException(
"Server responded with an unsupported file format: " + mimeType));
+
+ // Check if we can pass through to the output stream directly
+ if (handler instanceof TupleQueryResultWriter) {
+ TupleQueryResultWriter tqrWriter = (TupleQueryResultWriter) handler;
+ if (tqrWriter.getTupleQueryResultFormat().equals(format)) {
+ OutputStream out = tqrWriter.getOutputStream().orElse(null);
+ if (out != null) {
+ InputStream in = response.getEntity().getContent();
+ IOUtils.copy(in, out);
+ return;
+ }
+ }
+ }
+
+ // we need to parse the result and re-serialize.
TupleQueryResultParser parser = QueryResultIO.createTupleParser(format, getValueFactory());
parser.setQueryResultHandler(handler);
parser.parseQueryResult(response.getEntity().getContent());
@@ -709,7 +735,7 @@ protected void getTupleQueryResult(HttpUriRequest method, TupleQueryResultHandle
* Send the tuple query via HTTP and throws an exception in case anything goes wrong, i.e. only for HTTP 200 the
* method returns without exception. If HTTP status code is not equal to 200, the request is aborted, however pooled
* connections are not released.
- *
+ *
* @param method
* @throws RepositoryException
* @throws HttpException
@@ -842,6 +868,20 @@ protected void getRDF(HttpUriRequest method, RDFHandler handler, boolean require
RDFFormat format = RDFFormat.matchMIMEType(mimeType, rdfFormats)
.orElseThrow(() -> new RepositoryException(
"Server responded with an unsupported file format: " + mimeType));
+ // Check if we can pass through to the output stream directly
+ if (handler instanceof RDFWriter) {
+ RDFWriter rdfWriter = (RDFWriter) handler;
+ if (rdfWriter.getRDFFormat().equals(format)) {
+ OutputStream out = rdfWriter.getOutputStream().orElse(null);
+ if (out != null) {
+ InputStream in = response.getEntity().getContent();
+ IOUtils.copy(in, out);
+ return;
+ }
+ }
+ }
+
+ // we need to parse the result and re-serialize.
RDFParser parser = Rio.createParser(format, getValueFactory());
parser.setParserConfig(getParserConfig());
parser.setParseErrorListener(new ParseErrorLogger());
@@ -874,7 +914,7 @@ private HttpResponse sendGraphQueryViaHttp(HttpUriRequest method, boolean requir
/**
* Parse the response in this thread using a suitable {@link BooleanQueryResultParser}. All HTTP connections are
* closed and released in this method
- *
+ *
* @throws RDF4JException
*/
protected boolean getBoolean(HttpUriRequest method) throws IOException, RDF4JException {
@@ -941,7 +981,7 @@ private HttpResponse sendBooleanQueryViaHttp(HttpUriRequest method, Set 0) {
throw new RepositoryException(errInfo.toString());
} else {
@@ -1021,6 +1066,63 @@ protected HttpResponse execute(HttpUriRequest method) throws IOException, RDF4JE
}
}
+ static RDFFormat getContentTypeSerialisation(HttpResponse response) {
+ Header[] headers = response.getHeaders("Content-Type");
+
+ Set rdfFormats = RDFParserRegistry.getInstance().getKeys();
+ if (rdfFormats.isEmpty()) {
+ throw new RepositoryException("No tuple RDF parsers have been registered");
+ }
+
+ for (Header header : headers) {
+ for (HeaderElement element : header.getElements()) {
+ // SHACL Validation report Content-Type gets transformed from:
+ // application/shacl-validation-report+n-quads => application/n-quads
+ // application/shacl-validation-report+ld+json => application/ld+json
+ // text/shacl-validation-report+turtle => text/turtle
+
+ String[] split = element.getName().split("\\+");
+ StringBuilder serialisation = new StringBuilder(element.getName().split("/")[0] + "/");
+ for (int i = 1; i < split.length; i++) {
+ serialisation.append(split[i]);
+ if (i + 1 < split.length) {
+ serialisation.append("+");
+ }
+ }
+
+ logger.debug("SHACL validation report is serialised as: " + serialisation.toString());
+
+ Optional rdfFormat = RDFFormat.matchMIMEType(serialisation.toString(), rdfFormats);
+
+ if (rdfFormat.isPresent()) {
+ return rdfFormat.get();
+ }
+ }
+ }
+
+ throw new RepositoryException("Unsupported content-type for SHACL Validation Report: "
+ + Arrays.toString(response.getHeaders("Content-Type")));
+
+ }
+
+ private static boolean contentTypeIs(HttpResponse response, String contentType) {
+ Header[] headers = response.getHeaders("Content-Type");
+ if (headers.length == 0) {
+ return false;
+ }
+
+ for (Header header : headers) {
+ for (HeaderElement element : header.getElements()) {
+ String name = element.getName().split("\\+")[0];
+ if (contentType.equals(name)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
/*-------------------------*
* General utility methods *
*-------------------------*/
@@ -1029,7 +1131,7 @@ protected HttpResponse execute(HttpUriRequest method) throws IOException, RDF4JE
* Gets the MIME type specified in the response headers of the supplied method, if any. For example, if the response
* headers contain Content-Type: application/xml;charset=UTF-8, this method will return
* application/xml as the MIME type.
- *
+ *
* @param method The method to get the reponse MIME type from.
* @return The response MIME type, or null if not available.
*/
@@ -1042,7 +1144,7 @@ protected String getResponseMIMEType(HttpResponse method) throws IOException {
for (HeaderElement headerEl : headerElements) {
String mimeType = headerEl.getName();
if (mimeType != null) {
- logger.debug("reponse MIME type is {}", mimeType);
+ logger.debug("response MIME type is {}", mimeType);
return mimeType;
}
}
@@ -1064,7 +1166,7 @@ protected ErrorInfo getErrorInfo(HttpResponse response) throws RepositoryExcepti
/**
* Sets the parser configuration used to process HTTP response data.
- *
+ *
* @param parserConfig The parserConfig to set.
*/
public void setParserConfig(ParserConfig parserConfig) {
@@ -1085,12 +1187,12 @@ public long getConnectionTimeout() {
if (params == null) {
return 0;
}
- return (long) params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0);
+ return params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0);
}
/**
* Sets the http connection read timeout.
- *
+ *
* @param timeout timeout in milliseconds. Zero sets to infinity.
*/
public void setConnectionTimeout(long timeout) {
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SesameClientDependent.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SesameClientDependent.java
index b8a6569e038..0b409eafe1a 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SesameClientDependent.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SesameClientDependent.java
@@ -18,7 +18,7 @@ public interface SesameClientDependent {
* {@link HttpClientSessionManager} that has been assigned or has been used by this object. The life cycle might not
* be or might be tied to this object, depending on whether {@link HttpClientSessionManager} was passed to or
* created by this object respectively.
- *
+ *
* @return a {@link HttpClientSessionManager} instance or null
*/
HttpClientSessionManager getHttpClientSessionManager();
@@ -35,7 +35,7 @@ default HttpClientSessionManager getSesameClient() {
* Assign an {@link HttpClientSessionManager} that this object should use. The life cycle of the given
* {@link HttpClientSessionManager} is independent of this object. Closing or shutting down this object does not
* have any impact on the given client. Callers must ensure that the given client is properly closed elsewhere.
- *
+ *
* @param client
*/
void setHttpClientSessionManager(HttpClientSessionManager client);
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SessionManagerDependent.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SessionManagerDependent.java
index a5bbad7a520..190f34def0a 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SessionManagerDependent.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SessionManagerDependent.java
@@ -10,7 +10,7 @@
/**
* Common interface for objects, such as Repository and RepositoryConnection, that are dependent on
* {@link HttpClientSessionManager}.
- *
+ *
* @author James Leigh
*/
@SuppressWarnings("deprecation")
@@ -20,7 +20,7 @@ public interface SessionManagerDependent extends SesameClientDependent {
* {@link HttpClientSessionManager} that has been assigned or has been used by this object. The life cycle might not
* be or might be tied to this object, depending on whether {@link HttpClientSessionManager} was passed to or
* created by this object respectively.
- *
+ *
* @return a {@link HttpClientSessionManager} instance or null
*/
@Override
@@ -30,7 +30,7 @@ public interface SessionManagerDependent extends SesameClientDependent {
* Assign an {@link HttpClientSessionManager} that this object should use. The life cycle of the given
* {@link HttpClientSessionManager} is independent of this object. Closing or shutting down this object does not
* have any impact on the given client. Callers must ensure that the given client is properly closed elsewhere.
- *
+ *
* @param client
*/
@Override
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SharedHttpClientSessionManager.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SharedHttpClientSessionManager.java
index 09cbcf23f60..cedf5fbd32f 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SharedHttpClientSessionManager.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/SharedHttpClientSessionManager.java
@@ -28,18 +28,15 @@
/**
* A Manager for HTTP sessions that uses a shared {@link HttpClient} to manage HTTP connections.
- *
+ *
* @author James Leigh
*/
public class SharedHttpClientSessionManager implements HttpClientSessionManager, HttpClientDependent {
/**
- * FIXME: issue #1271, workaround for OpenJDK 8 bug. ScheduledThreadPoolExecutor with 0 core threads may cause 100%
- * CPU usage. Using 1 core thread instead of 0 (default) fixes the problem but wastes some resources.
- *
- * @see JDK-8129861
+ * Configurable system property {@code org.eclipse.rdf4j.client.executors.corePoolSize} for specifying the
+ * background executor core thread pool size.
*/
- private static final int cores = (System.getProperty("org.eclipse.rdf4j.client.executors.jdkbug") != null) ? 1 : 0;
- /**/
+ public static final String CORE_POOL_SIZE_PROPERTY = "org.eclipse.rdf4j.client.executors.corePoolSize";
private static final AtomicLong threadCount = new AtomicLong();
@@ -66,7 +63,8 @@ public class SharedHttpClientSessionManager implements HttpClientSessionManager,
public SharedHttpClientSessionManager() {
final ThreadFactory backingThreadFactory = Executors.defaultThreadFactory();
- this.executor = Executors.newScheduledThreadPool(cores, (Runnable runnable) -> {
+ final int corePoolSize = Integer.getInteger(CORE_POOL_SIZE_PROPERTY, 1);
+ this.executor = Executors.newScheduledThreadPool(corePoolSize, (Runnable runnable) -> {
Thread thread = backingThreadFactory.newThread(runnable);
thread.setName(String.format("rdf4j-sesameclientimpl-%d", threadCount.getAndIncrement()));
thread.setDaemon(true);
@@ -207,7 +205,7 @@ public void shutDown() {
/**
* No-op
- *
+ *
* @deprecated Create a new instance instead of trying to reactivate an old instance.
*/
@Deprecated
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPQuery.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPQuery.java
index 4c9ceb1363d..9c6b8f654ad 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPQuery.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPQuery.java
@@ -18,7 +18,7 @@
/**
* Base class for any {@link Query} operation over HTTP.
- *
+ *
* @author Andreas Schwarte
*/
public abstract class AbstractHTTPQuery extends AbstractQuery {
@@ -65,8 +65,8 @@ public Binding[] getBindingsArray() {
}
@Override
- public void setMaxExecutionTime(int maxExecutionTime) {
- super.setMaxExecutionTime(maxExecutionTime);
+ public void setMaxExecutionTime(int maxExecutionTimeSeconds) {
+ super.setMaxExecutionTime(maxExecutionTimeSeconds);
this.httpClient.setConnectionTimeout(1000L * this.getMaxExecutionTime());
}
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPUpdate.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPUpdate.java
index 6df08ee4684..da3e592428d 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPUpdate.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/query/AbstractHTTPUpdate.java
@@ -18,7 +18,7 @@
/**
* Base class for any {@link Update} operation over HTTP.
- *
+ *
* @author Andreas Schwarte
*/
public abstract class AbstractHTTPUpdate extends AbstractUpdate {
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteShaclValidationException.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteShaclValidationException.java
new file mode 100644
index 00000000000..e04108eb8f7
--- /dev/null
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteShaclValidationException.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.http.client.shacl;
+
+import java.io.StringReader;
+
+import org.eclipse.rdf4j.RDF4JException;
+import org.eclipse.rdf4j.common.annotation.Experimental;
+import org.eclipse.rdf4j.exceptions.ValidationException;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.vocabulary.SHACL;
+import org.eclipse.rdf4j.rio.RDFFormat;
+
+/**
+ * Experimental support for handling SHACL violations against a remote RDF4J server.
+ */
+@Experimental
+public class RemoteShaclValidationException extends RDF4JException implements ValidationException {
+
+ private final RemoteValidation remoteValidation;
+
+ public RemoteShaclValidationException(StringReader stringReader, String s, RDFFormat format) {
+ remoteValidation = new RemoteValidation(stringReader, s, format);
+ }
+
+ /**
+ * @return A Model containing the validation report as specified by the SHACL Recommendation
+ */
+ @Override
+ public Model validationReportAsModel() {
+ Model model = remoteValidation.asModel();
+ model.setNamespace(SHACL.PREFIX, SHACL.NAMESPACE);
+ return model;
+
+ }
+
+}
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteValidation.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteValidation.java
new file mode 100644
index 00000000000..2fb431516e3
--- /dev/null
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/shacl/RemoteValidation.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.http.client.shacl;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.eclipse.rdf4j.common.annotation.InternalUseOnly;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.Rio;
+
+@InternalUseOnly
+class RemoteValidation {
+
+ StringReader stringReader;
+ String baseUri;
+ RDFFormat format;
+
+ Model model;
+
+ RemoteValidation(StringReader stringReader, String baseUri, RDFFormat format) {
+ this.stringReader = stringReader;
+ this.baseUri = baseUri;
+ this.format = format;
+ }
+
+ Model asModel() {
+ if (model == null) {
+ try {
+ model = Rio.parse(stringReader, baseUri, format);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return model;
+ }
+
+}
diff --git a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/util/HttpClientBuilders.java b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/util/HttpClientBuilders.java
index 91dee10ffc1..b907c390d11 100644
--- a/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/util/HttpClientBuilders.java
+++ b/core/http/client/src/main/java/org/eclipse/rdf4j/http/client/util/HttpClientBuilders.java
@@ -7,7 +7,6 @@
*******************************************************************************/
package org.eclipse.rdf4j.http.client.util;
-import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
@@ -18,12 +17,11 @@
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.ssl.TrustStrategy;
import org.eclipse.rdf4j.http.client.HttpClientDependent;
/**
* Convenience utility class offering helper methods to configure {@link HttpClient}s and {@link HttpClientBuilders}.
- *
+ *
* @author Andreas Schwarte
* @see HttpClientDependent
*/
@@ -32,7 +30,7 @@ public class HttpClientBuilders {
/**
* Return an {@link HttpClientBuilder} that can be used to build an {@link HttpClient} which trusts all certificates
* (particularly including self-signed certificates).
- *
+ *
* @return a {@link HttpClientBuilder} for SSL trust all
*/
public static HttpClientBuilder getSSLTrustAllHttpClientBuilder() {
diff --git a/core/http/client/src/test/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSessionTest.java b/core/http/client/src/test/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSessionTest.java
index ca3ab20c674..d0c86447af2 100644
--- a/core/http/client/src/test/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSessionTest.java
+++ b/core/http/client/src/test/java/org/eclipse/rdf4j/http/client/RDF4JProtocolSessionTest.java
@@ -25,10 +25,20 @@
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
+import java.util.Locale;
import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HeaderIterator;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.ParseException;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicHeader;
+import org.apache.http.params.HttpParams;
import org.eclipse.rdf4j.IsolationLevels;
import org.eclipse.rdf4j.http.protocol.Protocol;
import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
@@ -154,6 +164,220 @@ public void testClose() throws Exception {
postRequestedFor(urlEqualTo("/rdf4j-server/repositories/test/transactions/1?action=PING")));
}
+ @Test
+ public void getContentTypeSerialisationTest() {
+
+ {
+ HttpResponse httpResponse = withContentType("application/shacl-validation-report+n-quads");
+ RDFFormat format = SPARQLProtocolSession.getContentTypeSerialisation(httpResponse);
+
+ assertThat(format).isEqualTo(RDFFormat.NQUADS);
+ }
+
+ {
+ HttpResponse httpResponse = withContentType("application/shacl-validation-report+ld+json");
+ RDFFormat format = SPARQLProtocolSession.getContentTypeSerialisation(httpResponse);
+
+ assertThat(format).isEqualTo(RDFFormat.JSONLD);
+ }
+
+ {
+ HttpResponse httpResponse = withContentType("text/shacl-validation-report+turtle");
+ RDFFormat format = SPARQLProtocolSession.getContentTypeSerialisation(httpResponse);
+
+ assertThat(format).isEqualTo(RDFFormat.TURTLE);
+ }
+ }
+
+ private HttpResponse withContentType(String contentType) {
+ Header header = new Header() {
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public String getValue() {
+ return null;
+ }
+
+ @Override
+ public HeaderElement[] getElements() throws ParseException {
+
+ HeaderElement[] elements = { new HeaderElement() {
+ @Override
+ public String getName() {
+ return contentType;
+ }
+
+ @Override
+ public String getValue() {
+ return null;
+ }
+
+ @Override
+ public NameValuePair[] getParameters() {
+ return new NameValuePair[0];
+ }
+
+ @Override
+ public NameValuePair getParameterByName(String name) {
+ return null;
+ }
+
+ @Override
+ public int getParameterCount() {
+ return 0;
+ }
+
+ @Override
+ public NameValuePair getParameter(int index) {
+ return null;
+ }
+ } };
+ return elements;
+ }
+ };
+
+ return new HttpResponse() {
+ @Override
+ public ProtocolVersion getProtocolVersion() {
+ return null;
+ }
+
+ @Override
+ public boolean containsHeader(String name) {
+ return false;
+ }
+
+ @Override
+ public Header[] getHeaders(String name) {
+ Header[] headers = { header };
+ return headers;
+ }
+
+ @Override
+ public Header getFirstHeader(String name) {
+ return null;
+ }
+
+ @Override
+ public Header getLastHeader(String name) {
+ return null;
+ }
+
+ @Override
+ public Header[] getAllHeaders() {
+ return new Header[0];
+ }
+
+ @Override
+ public void addHeader(Header header1) {
+
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+
+ }
+
+ @Override
+ public void setHeader(Header header1) {
+
+ }
+
+ @Override
+ public void setHeader(String name, String value) {
+
+ }
+
+ @Override
+ public void setHeaders(Header[] headers) {
+
+ }
+
+ @Override
+ public void removeHeader(Header header1) {
+
+ }
+
+ @Override
+ public void removeHeaders(String name) {
+
+ }
+
+ @Override
+ public HeaderIterator headerIterator() {
+ return null;
+ }
+
+ @Override
+ public HeaderIterator headerIterator(String name) {
+ return null;
+ }
+
+ @Override
+ public HttpParams getParams() {
+ return null;
+ }
+
+ @Override
+ public void setParams(HttpParams params) {
+
+ }
+
+ @Override
+ public StatusLine getStatusLine() {
+ return null;
+ }
+
+ @Override
+ public void setStatusLine(StatusLine statusline) {
+
+ }
+
+ @Override
+ public void setStatusLine(ProtocolVersion ver, int code) {
+
+ }
+
+ @Override
+ public void setStatusLine(ProtocolVersion ver, int code, String reason) {
+
+ }
+
+ @Override
+ public void setStatusCode(int code) throws IllegalStateException {
+
+ }
+
+ @Override
+ public void setReasonPhrase(String reason) throws IllegalStateException {
+
+ }
+
+ @Override
+ public HttpEntity getEntity() {
+ return null;
+ }
+
+ @Override
+ public void setEntity(HttpEntity entity) {
+
+ }
+
+ @Override
+ public Locale getLocale() {
+ return null;
+ }
+
+ @Override
+ public void setLocale(Locale loc) {
+
+ }
+ };
+ }
+
private void verifyHeader(String path) {
verify(anyRequestedFor(urlEqualTo(path)).withHeader(testHeader, containing(testValue)));
}
diff --git a/core/http/pom.xml b/core/http/pom.xml
index b4f863434bc..54cc94a9aca 100644
--- a/core/http/pom.xml
+++ b/core/http/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-core
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-httppom
diff --git a/core/http/protocol/pom.xml b/core/http/protocol/pom.xml
index ba2e6358478..fcb780914c8 100644
--- a/core/http/protocol/pom.xml
+++ b/core/http/protocol/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-http
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-http-protocolRDF4J: HTTP protocol
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/Protocol.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/Protocol.java
index 795ced003b2..d0b134ae263 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/Protocol.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/Protocol.java
@@ -8,12 +8,12 @@
package org.eclipse.rdf4j.http.protocol;
import org.eclipse.rdf4j.OpenRDFUtil;
-import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
-import org.eclipse.rdf4j.rio.ntriples.NTriplesUtil;
+import org.eclipse.rdf4j.rio.helpers.NTriplesUtil;
public abstract class Protocol {
@@ -76,7 +76,7 @@ public static enum TIMEOUT {
/**
* Protocol version.
- *
+ *
*
*
10: since RDF4J 3.1.0
*
9: since RDF4J 3.0.0
@@ -275,7 +275,7 @@ private static String getServerDir(String serverLocation) {
/**
* Get the location of the protocol resource on the specified server.
- *
+ *
* @param serverLocation the base location of a server implementing this REST protocol.
* @return the location of the protocol resource on the specified server
*/
@@ -285,7 +285,7 @@ public static final String getProtocolLocation(String serverLocation) {
/**
* Get the location of the server configuration resource on the specified server.
- *
+ *
* @param serverLocation the base location of a server implementing this REST protocol.
* @return the location of the server configuration resource on the specified server
*/
@@ -295,7 +295,7 @@ public static final String getConfigLocation(String serverLocation) {
/**
* Get the location of the repository list resource on the specified server.
- *
+ *
* @param serverLocation the base location of a server implementing this REST protocol.
* @return the location of the repository list resource on the specified server
*/
@@ -305,7 +305,7 @@ public static final String getRepositoriesLocation(String serverLocation) {
/**
* Get the location of a specific repository resource on the specified server.
- *
+ *
* @param serverLocation the base location of a server implementing this REST protocol.
* @param repositoryID the ID of the repository
* @return the location of a specific repository resource on the specified server
@@ -316,10 +316,10 @@ public static final String getRepositoryLocation(String serverLocation, String r
/**
* Get the location of the config of a specific repository resource.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the configuration resource for the specified repository
- *
+ *
*/
public static final String getRepositoryConfigLocation(String repositoryLocation) {
return repositoryLocation + "/" + CONFIG;
@@ -327,7 +327,7 @@ public static final String getRepositoryConfigLocation(String repositoryLocation
/**
* Get the location of the statements resource for a specific repository.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the statements resource for the specified repository
*/
@@ -337,7 +337,7 @@ public static final String getStatementsLocation(String repositoryLocation) {
/**
* Get the location of the transaction resources for a specific repository.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the transaction resources for the specified repository
*/
@@ -347,7 +347,7 @@ public static final String getTransactionsLocation(String repositoryLocation) {
/**
* Extracts the server location from the repository location.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the server resource for the specified repository.
*/
@@ -359,7 +359,7 @@ public static final String getServerLocation(String repositoryLocation) {
/**
* Extracts the repository ID from the repository location.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the ID of the repository.
*/
@@ -370,7 +370,7 @@ public static final String getRepositoryID(String repositoryLocation) {
/**
* Get the location of the contexts lists resource for a specific repository.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the contexts lists resource for the specified repository
*/
@@ -380,7 +380,7 @@ public static final String getContextsLocation(String repositoryLocation) {
/**
* Get the location of the namespaces lists resource for a specific repository on the specified server.
- *
+ *
* @param repositoryLocation the base location of a server implementing this REST protocol.
* @return the location of the namespaces lists resource for a specific repository on the specified server
*/
@@ -390,7 +390,7 @@ public static final String getNamespacesLocation(String repositoryLocation) {
/**
* Get the location of the namespace with the specified prefix for a specific repository on the specified server.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @param prefix the namespace prefix
* @return the location of the the namespace with the specified prefix for a specific repository on the specified
@@ -402,7 +402,7 @@ public static final String getNamespacePrefixLocation(String repositoryLocation,
/**
* Get the location of the 'size' resource for a specific repository on the specified server.
- *
+ *
* @param repositoryLocation the location of a repository implementing this REST protocol.
* @return the location of the 'size' resource for a specific repository on the specified server
*/
@@ -412,24 +412,18 @@ public static final String getSizeLocation(String repositoryLocation) {
/**
* Encodes a value in a canonical serialized string format, for use in a URL query parameter.
- *
+ *
* @param value The value to encode, possibly null.
* @return The protocol-serialized representation of the supplied value, or {@link #NULL_PARAM_VALUE} if the
* supplied value was null.
*/
public static String encodeValue(Value value) {
- if (value instanceof BNode) {
- // SES-2129 special treatment of blank node names to avoid problems with round-tripping.
- return "_:" + ((BNode) value).getID();
- }
-
- // for everything else we just use N-Triples serialization.
return NTriplesUtil.toNTriplesString(value);
}
/**
* Decode a previously encoded value.
- *
+ *
* @param encodedValue the encoded value
* @param valueFactory the factory to use for constructing the Value
* @return the decoded Value
@@ -445,7 +439,7 @@ public static Value decodeValue(String encodedValue, ValueFactory valueFactory)
/**
* Decode a previously encoded Resource.
- *
+ *
* @param encodedValue the encoded value
* @param valueFactory the factory to use for constructing the Resource
* @return the decoded Resource
@@ -461,7 +455,7 @@ public static Resource decodeResource(String encodedValue, ValueFactory valueFac
/**
* Decode a previously encoded URI.
- *
+ *
* @param encodedValue the encoded value
* @param valueFactory the factory to use for constructing the URI
* @return the decoded URI
@@ -477,7 +471,7 @@ public static IRI decodeURI(String encodedValue, ValueFactory valueFactory) {
/**
* Encodes a context resource for use in a URL.
- *
+ *
* @param context The context to encode, possibly null.
* @return The protocol-serialized representation of the supplied context, or {@link #NULL_PARAM_VALUE} if the
* supplied value was null.
@@ -492,7 +486,7 @@ public static String encodeContext(Resource context) {
/**
* Decode a previously encoded context Resource.
- *
+ *
* @param encodedValue the encoded value
* @param valueFactory the factory to use for constructing the Resource
* @return the decoded Resource, or null if the encoded values was null or equal to {@link #NULL_PARAM_VALUE}
@@ -503,13 +497,18 @@ public static Resource decodeContext(String encodedValue, ValueFactory valueFact
} else if (NULL_PARAM_VALUE.equals(encodedValue)) {
return null;
} else {
- return decodeResource(encodedValue, valueFactory);
+ Resource context = decodeResource(encodedValue, valueFactory);
+ // Context must be an IRI or BNode but never Triple
+ if (context instanceof Triple) {
+ throw new IllegalArgumentException("Invalid context value: " + encodedValue);
+ }
+ return context;
}
}
/**
* Encode context resources for use in a URL.
- *
+ *
* @param contexts the contexts to encode, must not be null.
* @return the encoded contexts
* @throws IllegalArgumentException If the contexts is null.
@@ -527,7 +526,7 @@ public static String[] encodeContexts(Resource... contexts) {
/**
* Decode previously encoded contexts.
- *
+ *
* @param encodedValues the encoded values
* @param valueFactory the factory to use for constructing the Resources
* @return the decoded Resources, or an empty array if the supplied encodedValues was null.
@@ -546,4 +545,4 @@ public static Resource[] decodeContexts(String[] encodedValues, ValueFactory val
return result;
}
-}
\ No newline at end of file
+}
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/error/ErrorType.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/error/ErrorType.java
index 57d4c16cd1e..6f81ca1c6e3 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/error/ErrorType.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/error/ErrorType.java
@@ -15,7 +15,7 @@
*/
public class ErrorType {
- private static final Map registry = new HashMap();
+ private static final Map registry = new HashMap<>();
public static final ErrorType MALFORMED_QUERY = register("MALFORMED QUERY");
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionReader.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionReader.java
index 09f031787a5..88b8ec22af1 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionReader.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionReader.java
@@ -20,7 +20,7 @@ public class TransactionReader {
/**
* parse the transaction from the serialization
- *
+ *
* @throws SAXException If the SimpleSAXParser was unable to create an XMLReader or if the XML is faulty.
* @throws IOException If IO problems during parsing.
*/
@@ -36,7 +36,7 @@ public Collection parse(InputStream in) throws SAXExceptio
/**
* parse the transaction from the serialization
- *
+ *
* @throws SAXException If the SimpleSAXParser was unable to create an XMLReader or if the XML is faulty.
* @throws IOException If IO problems during parsing.
*/
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionSAXParser.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionSAXParser.java
index 38d7e922033..c178d9e6be1 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionSAXParser.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionSAXParser.java
@@ -34,7 +34,7 @@
/**
* Parses an RDF transaction document into a collection of {@link TransactionOperation} objects.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
@@ -62,7 +62,7 @@ public TransactionSAXParser(ValueFactory valueFactory) {
/**
* get the parsed transaction
- *
+ *
* @return the parsed transaction
*/
public Collection getTxn() {
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionWriter.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionWriter.java
index 580279d6210..6cd716ae278 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionWriter.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionWriter.java
@@ -35,7 +35,7 @@
/**
* Serializes of an RDF transaction.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
@@ -46,7 +46,7 @@ public TransactionWriter() {
/**
* serialize the passed list of operations to the passed writer.
- *
+ *
* @param txn the operations
* @param out the output stream to write to
* @throws IOException
@@ -72,7 +72,7 @@ public void serialize(Iterable extends TransactionOperation> txn, OutputStream
/**
* Serializes the supplied operation.
- *
+ *
* @param op The operation to serialize
* @param xmlWriter
* @throws IOException
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionXMLConstants.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionXMLConstants.java
index c446c34e5b5..b40099d54f7 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionXMLConstants.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/TransactionXMLConstants.java
@@ -9,7 +9,7 @@
/**
* Interface defining tags and attribute names for the XML serialization of transactions.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/AddStatementOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/AddStatementOperation.java
index 474a8ab415b..e0bf3d783c1 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/AddStatementOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/AddStatementOperation.java
@@ -17,14 +17,14 @@
/**
* Operation to add a statement.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class AddStatementOperation extends StatementOperation implements Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 7055177153036638975L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearNamespacesOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearNamespacesOperation.java
index 5a91a14451c..720c7c00cc8 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearNamespacesOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearNamespacesOperation.java
@@ -14,14 +14,14 @@
/**
* Operation that removes all namespace declarations.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class ClearNamespacesOperation implements TransactionOperation, Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 804163331093326031L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearOperation.java
index 6e3b7ce8de2..85117a8ef8b 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ClearOperation.java
@@ -15,14 +15,14 @@
/**
* Operation that clears the whole repository.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class ClearOperation extends ContextOperation implements Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = -1570893715836564121L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ContextOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ContextOperation.java
index 623a0a2642b..e2e51786fa6 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ContextOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/ContextOperation.java
@@ -14,7 +14,7 @@
/**
* A TransactionOperation that operates on a specific (set of) contexts.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveNamespaceOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveNamespaceOperation.java
index a4261c09840..fc78a3f6870 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveNamespaceOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveNamespaceOperation.java
@@ -15,14 +15,14 @@
/**
* Operation that removes the namespace for a specific prefix.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class RemoveNamespaceOperation implements TransactionOperation, Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 3227597422508894927L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveStatementsOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveStatementsOperation.java
index bc65c11ee1e..5222befe0f2 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveStatementsOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/RemoveStatementsOperation.java
@@ -17,14 +17,14 @@
/**
* Operation to remove statements matching specific pattern of subject, predicate and object.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class RemoveStatementsOperation extends StatementOperation implements Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 1497684375399016153L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SPARQLUpdateOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SPARQLUpdateOperation.java
index af005dde485..e4bfde60525 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SPARQLUpdateOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SPARQLUpdateOperation.java
@@ -20,13 +20,13 @@
/**
* Encapsulation of a SPARQL 1.1 update operation executed as part of a transaction.
- *
+ *
* @author Jeen Broekstra
*/
public class SPARQLUpdateOperation implements TransactionOperation, Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 4432275498318918582L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SetNamespaceOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SetNamespaceOperation.java
index d0f40f5e4f5..2353232997e 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SetNamespaceOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/SetNamespaceOperation.java
@@ -15,14 +15,14 @@
/**
* Operation that sets the namespace for a specific prefix.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
public class SetNamespaceOperation implements TransactionOperation, Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 7197096029612751574L;
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/StatementOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/StatementOperation.java
index fe0d9b160f4..7d5d5083210 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/StatementOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/StatementOperation.java
@@ -14,7 +14,7 @@
/**
* A context operation with (optional) subject, predicate, object.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
diff --git a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/TransactionOperation.java b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/TransactionOperation.java
index aa5906b1eb6..04dd2e50ebe 100644
--- a/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/TransactionOperation.java
+++ b/core/http/protocol/src/main/java/org/eclipse/rdf4j/http/protocol/transaction/operations/TransactionOperation.java
@@ -12,7 +12,7 @@
/**
* An update operation that is part of a transaction.
- *
+ *
* @author Arjohn Kampman
* @author Leo Sauermann
*/
@@ -20,7 +20,7 @@ public interface TransactionOperation {
/**
* Executes this operation on the supplied connection.
- *
+ *
* @param con The connection the operation should be performed on.
* @throws RepositoryException If such an exception is thrown by the connection while executing the operation.
*/
diff --git a/core/http/protocol/src/test/java/org/eclipse/rdf4j/http/protocol/ProtocolTest.java b/core/http/protocol/src/test/java/org/eclipse/rdf4j/http/protocol/ProtocolTest.java
index 3dee208eb63..8620041f9cf 100644
--- a/core/http/protocol/src/test/java/org/eclipse/rdf4j/http/protocol/ProtocolTest.java
+++ b/core/http/protocol/src/test/java/org/eclipse/rdf4j/http/protocol/ProtocolTest.java
@@ -24,9 +24,11 @@
import static org.eclipse.rdf4j.http.protocol.Protocol.getRepositoryLocation;
import static org.eclipse.rdf4j.http.protocol.Protocol.getServerLocation;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.junit.Test;
@@ -113,5 +115,35 @@ public void testEncodeValueRoundtrip() {
BNode decodedNode = (BNode) Protocol.decodeValue(encodedBnode, vf);
assertEquals(bnode, decodedNode);
+ Triple triple1 = vf.createTriple(bnode, uri, vf.createLiteral(16));
+ String encodedTriple1 = Protocol.encodeValue(triple1);
+ Triple decodedTriple1 = (Triple) Protocol.decodeValue(encodedTriple1, vf);
+ assertEquals(triple1, decodedTriple1);
+
+ Triple triple2 = vf.createTriple(bnode, uri, triple1);
+ String encodedTriple2 = Protocol.encodeValue(triple2);
+ Triple decodedTriple2 = (Triple) Protocol.decodeValue(encodedTriple2, vf);
+ assertEquals(triple2, decodedTriple2);
+ }
+
+ @Test
+ public void testDecodeContext() {
+ ValueFactory vf = SimpleValueFactory.getInstance();
+
+ assertEquals(vf.createBNode("bnode1"), Protocol.decodeContext("_:bnode1", vf));
+ assertEquals(vf.createIRI("urn:test"), Protocol.decodeContext("", vf));
+
+ // RDF* triples are resources but they can't be used as context values
+ try {
+ Protocol.decodeContext("<<>>", SimpleValueFactory.getInstance());
+ fail("Must fail with exception");
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testParseIRIvsTriple() {
+ Protocol.decodeURI("<<>>", SimpleValueFactory.getInstance());
}
}
diff --git a/core/model/pom.xml b/core/model/pom.xml
index 94463ab5582..36d6603d07a 100644
--- a/core/model/pom.xml
+++ b/core/model/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-core
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-modelRDF4J: Model
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevel.java b/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevel.java
index 3d70850c08c..b6dd177bbed 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevel.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevel.java
@@ -13,7 +13,7 @@
* A Transaction Isolation Level. Defaul levels supported by Sesame are provided by {@link IsolationLevels}, third-party
* triplestore implementors may choose to add additional IsolationLevel implementations if their triplestore's isolation
* contract is different from what is provided by default.
- *
+ *
* @author Jeen Broekstra
*/
public interface IsolationLevel {
@@ -22,7 +22,7 @@ public interface IsolationLevel {
* Verifies if this transaction isolation level is compatible with the supplied other isolation level - that is, if
* this transaction isolation level offers at least the same guarantees as the other level. By definition, every
* transaction isolation level is compatible with itself.
- *
+ *
* @param otherLevel an other isolation level to check compatibility against.
* @return true iff this isolation level is compatible with the supplied other isolation level, false otherwise.
*/
@@ -30,7 +30,7 @@ public interface IsolationLevel {
/**
* Get a URI uniquely representing this isolation level.
- *
+ *
* @return a URI that uniquely represents this isolation level.
*/
IRI getURI();
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevels.java b/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevels.java
index 52308173ed7..35a2e67f8c9 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevels.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/IsolationLevels.java
@@ -19,7 +19,7 @@
* Enumeration of Transaction {@link IsolationLevel}s supported by Sesame. Note that Sesame stores are not required to
* support all levels, consult the documentatation for the specific SAIL implementation you are using to find out which
* levels are supported.
- *
+ *
* @author Jeen Broekstra
* @author James Leigh
*/
@@ -78,7 +78,7 @@ public boolean isCompatibleWith(IsolationLevel otherLevel) {
/**
* Determines the first compatible isolation level in the list of supported levels, for the given level. Returns the
* level itself if it is in the list of supported levels. Returns null if no compatible level can be found.
- *
+ *
* @param level the {@link IsolationLevel} for which to determine a compatible level.
* @param supportedLevels a list of supported isolation levels from which to select the closest compatible level.
* @return the given level if it occurs in the list of supported levels. Otherwise, the first compatible level in
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFException.java b/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFException.java
index 44bcce7d0df..e8248c57647 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFException.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFException.java
@@ -9,7 +9,7 @@
/**
* abstract superclass of all OpenRDF Sesame exceptions
- *
+ *
* @author Jeen Broekstra
* @deprecated use {@link RDF4JException} instead.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFUtil.java b/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFUtil.java
index df8b43ec415..090ebfc7a28 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFUtil.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/OpenRDFUtil.java
@@ -11,7 +11,7 @@
/**
* General utility methods for OpenRDF/Sesame modules.
- *
+ *
* @author Arjohn Kampman
*/
public class OpenRDFUtil {
@@ -25,7 +25,7 @@ public class OpenRDFUtil {
* supplying a null-Resource value (e.g.: matching all statements with no associated context). As we so far
* haven't been able to prefer one over the other, methods operating on contexts currently throw
* {@link IllegalArgumentException}s.
- *
+ *
* @param contexts The parameter to check.
* @throws IllegalArgumentException If the supplied contexts parameter is null.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/RDF4JConfigException.java b/core/model/src/main/java/org/eclipse/rdf4j/RDF4JConfigException.java
index ecdf3ff9fd5..31cc577f6bd 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/RDF4JConfigException.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/RDF4JConfigException.java
@@ -9,7 +9,7 @@
/**
* Exception indicating a configuration problem in an RDF4J component.
- *
+ *
* @author Jeen Broekstra
*/
public class RDF4JConfigException extends RDF4JException {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/RDF4JException.java b/core/model/src/main/java/org/eclipse/rdf4j/RDF4JException.java
index 9020c1a0ae2..32adba08ace 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/RDF4JException.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/RDF4JException.java
@@ -9,7 +9,7 @@
/**
* General superclass of all unchecked exceptions that parts of RDF4J can throw.
- *
+ *
* @author Jeen Broekstra
*/
@SuppressWarnings("deprecation")
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/exceptions/ValidationException.java b/core/model/src/main/java/org/eclipse/rdf4j/exceptions/ValidationException.java
new file mode 100644
index 00000000000..afa3585e1c2
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/exceptions/ValidationException.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.exceptions;
+
+import org.eclipse.rdf4j.common.annotation.Experimental;
+import org.eclipse.rdf4j.model.Model;
+
+/**
+ * MAY BE MOVED IN THE FUTURE!
+ */
+@Experimental
+public interface ValidationException {
+
+ /**
+ * @return A Model containing the validation report as specified by the SHACL Recommendation
+ */
+ Model validationReportAsModel();
+
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/BNode.java b/core/model/src/main/java/org/eclipse/rdf4j/model/BNode.java
index 0278323c826..2b9b8023988 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/BNode.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/BNode.java
@@ -11,7 +11,7 @@
* An RDF-1.1 blank node (aka bnode, aka anonymous node). A blank node has an identifier to be able to
* compare it to other blank nodes internally. Please note that, conceptually, blank node equality can only be
* determined by examining the statements that refer to them.
- *
+ *
* @see RDF-1.1 Concepts and Abstract Syntax
*/
public interface BNode extends Resource {
@@ -35,7 +35,7 @@ public interface BNode extends Resource {
/**
* The hash code of a blank node is defined as the hash code of its identifier: id.hashCode().
- *
+ *
* @return A hash code for the blank node.
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/IRI.java b/core/model/src/main/java/org/eclipse/rdf4j/model/IRI.java
index 536b3e08c17..60777708113 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/IRI.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/IRI.java
@@ -22,7 +22,7 @@
*
* The last step should never fail as every legal (full) IRI contains at least one ':' character to seperate the scheme
* from the rest of the IRI. The implementation should check this upon object creation.
- *
+ *
* @see RFC 3987
* @author Jeen Broekstra
*/
@@ -31,7 +31,7 @@ public interface IRI extends URI, Resource {
/**
* Returns the String-representation of this IRI.
- *
+ *
* @return The String-representation of this IRI.
*/
@Override
@@ -40,7 +40,7 @@ public interface IRI extends URI, Resource {
/**
* Gets the namespace part of this IRI. The namespace is defined as per the algorithm described in the class
* documentation.
- *
+ *
* @return The IRI's namespace.
*/
@Override
@@ -49,7 +49,7 @@ public interface IRI extends URI, Resource {
/**
* Gets the local name part of this IRI. The local name is defined as per the algorithm described in the class
* documentation.
- *
+ *
* @return The IRI's local name.
*/
@Override
@@ -57,7 +57,7 @@ public interface IRI extends URI, Resource {
/**
* Compares a IRI object to another object.
- *
+ *
* @param o The object to compare this IRI to.
* @return true if the other object is an instance of {@link IRI} and their String-representations are
* equal, false otherwise.
@@ -67,7 +67,7 @@ public interface IRI extends URI, Resource {
/**
* The hash code of an IRI is defined as the hash code of its String-representation: toString().hashCode.
- *
+ *
* @return A hash code for the IRI.
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/Literal.java b/core/model/src/main/java/org/eclipse/rdf4j/model/Literal.java
index 6b4a1ea6595..a408ed2d6d5 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/Literal.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/Literal.java
@@ -18,7 +18,7 @@
/**
* An RDF-1.1 literal consisting of a label (the lexical value), a datatype, and optionally a language tag.
- *
+ *
* @author Arjohn Kampman
* @see RDF-1.1 Concepts and Abstract Syntax
*/
@@ -26,14 +26,14 @@ public interface Literal extends Value {
/**
* Gets the label (the lexical value) of this literal.
- *
+ *
* @return The literal's label.
*/
public String getLabel();
/**
* Gets the language tag for this literal, normalized to lower case.
- *
+ *
* @return The language tag for this literal, or {@link Optional#empty()} if it doesn't have one.
*/
public Optional getLanguage();
@@ -42,14 +42,14 @@ public interface Literal extends Value {
* Gets the datatype for this literal. If {@link #getLanguage()} returns a non-empty value than this must return
* {@link RDF#LANGSTRING}. If no datatype was assigned to this literal by the creator, then this method must return
* {@link XMLSchema#STRING}.
- *
+ *
* @return The datatype for this literal.
*/
public IRI getDatatype();
/**
* Compares a literal object to another object.
- *
+ *
* @param other The object to compare this literal to.
* @return true if the other object is an instance of {@link Literal} and if their labels, language tags
* and datatypes are equal.
@@ -60,7 +60,7 @@ public interface Literal extends Value {
/**
* Returns the literal's hash code. The hash code of a literal is defined as the hash code of its label:
* label.hashCode().
- *
+ *
* @return A hash code for the literal.
*/
@Override
@@ -68,7 +68,7 @@ public interface Literal extends Value {
/**
* Returns the byte value of this literal.
- *
+ *
* @return The byte value of the literal.
* @throws NumberFormatException
* If the literal cannot be represented by a byte.
@@ -77,7 +77,7 @@ public interface Literal extends Value {
/**
* Returns the short value of this literal.
- *
+ *
* @return The short value of the literal.
* @throws NumberFormatException If the literal's label cannot be represented by a short.
*/
@@ -85,7 +85,7 @@ public interface Literal extends Value {
/**
* Returns the int value of this literal.
- *
+ *
* @return The int value of the literal.
* @throws NumberFormatException If the literal's label cannot be represented by a int.
*/
@@ -93,7 +93,7 @@ public interface Literal extends Value {
/**
* Returns the long value of this literal.
- *
+ *
* @return The long value of the literal.
* @throws NumberFormatException If the literal's label cannot be represented by to a long .
*/
@@ -101,7 +101,7 @@ public interface Literal extends Value {
/**
* Returns the integer value of this literal.
- *
+ *
* @return The integer value of the literal.
* @throws NumberFormatException If the literal's label is not a valid integer.
*/
@@ -109,7 +109,7 @@ public interface Literal extends Value {
/**
* Returns the decimal value of this literal.
- *
+ *
* @return The decimal value of the literal.
* @throws NumberFormatException If the literal's label is not a valid decimal.
*/
@@ -117,7 +117,7 @@ public interface Literal extends Value {
/**
* Returns the float value of this literal.
- *
+ *
* @return The float value of the literal.
* @throws NumberFormatException If the literal's label cannot be represented by a float.
*/
@@ -125,7 +125,7 @@ public interface Literal extends Value {
/**
* Returns the double value of this literal.
- *
+ *
* @return The double value of the literal.
* @throws NumberFormatException If the literal's label cannot be represented by a double.
*/
@@ -133,7 +133,7 @@ public interface Literal extends Value {
/**
* Returns the boolean value of this literal.
- *
+ *
* @return The long value of the literal.
* @throws IllegalArgumentException If the literal's label cannot be represented by a boolean .
*/
@@ -144,7 +144,7 @@ public interface Literal extends Value {
* literals whose label conforms to the syntax of the following XML
* Schema datatypes: dateTime, time, date, gYearMonth, gMonthDay,
* gYear, gMonth or gDay.
- *
+ *
* @return The calendar value of the literal.
* @throws IllegalArgumentException If the literal cannot be represented by a {@link XMLGregorianCalendar}.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/Model.java b/core/model/src/main/java/org/eclipse/rdf4j/model/Model.java
index 8c9022a5365..0ac76199e29 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/Model.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/Model.java
@@ -19,7 +19,7 @@
*
* Additional utility functionality for working with Model objects is available in the
* {@link org.eclipse.rdf4j.model.util.Models Models} utility class.
- *
+ *
* @author James Leigh
* @author Jeen Broekstra
* @see org.eclipse.rdf4j.model.util.Models the Models utility class
@@ -31,14 +31,14 @@ public interface Model extends Set, Serializable, NamespaceAware {
* operations on the returned model "read through" to this model, and attempts to modify the returned model, whether
* direct or via its iterator, result in an {@link UnsupportedOperationException}.
*
- *
+ *
* @return an unmodifiable view of the specified set.
*/
public Model unmodifiable();
/**
* Sets the prefix for a namespace. This will replace any existing namespace associated to the prefix.
- *
+ *
* @param prefix The new prefix.
* @param name The namespace name that the prefix maps to.
* @return The {@link Namespace} object for the given namespace.
@@ -54,14 +54,14 @@ public default Namespace setNamespace(String prefix, String name) {
/**
* Sets the prefix for a namespace. This will replace any existing namespace associated to the prefix.
- *
+ *
* @param namespace A {@link Namespace} object to use in this Model.
*/
public void setNamespace(Namespace namespace);
/**
* Removes a namespace declaration by removing the association between a prefix and a namespace name.
- *
+ *
* @param prefix The namespace prefix of which the assocation with a namespace name is to be removed.
* @return the previous namespace bound to the prefix or {@link Optional#empty()}
*/
@@ -82,7 +82,7 @@ public default Namespace setNamespace(String prefix, String name) {
* associated context,
* {@code model.contains(null, null, null, c1, c2, c3)} is true if any statements in this model have context
* {@code c1}, {@code c2} or {@code c3} .
- *
+ *
* @param subj The subject of the statements to match, {@code null} to match statements with any subject.
* @param pred The predicate of the statements to match, {@code null} to match statements with any predicate.
* @param obj The object of the statements to match, {@code null} to match statements with any object.
@@ -106,7 +106,7 @@ public default boolean contains(Resource subj, URI pred, Value obj, Resource...
* those to the model. If no contexts are specified, a single statement with no associated context is added. If this
* Model is a filtered Model then null (if context empty) values are permitted and will use the corresponding
* filtered values.
- *
+ *
* @param subj The statement's subject.
* @param pred The statement's predicate.
* @param obj The statement's object.
@@ -128,7 +128,7 @@ public default boolean add(Resource subj, URI pred, Value obj, Resource... conte
/**
* Removes statements with the specified context exist in this model.
- *
+ *
* @param context The context of the statements to remove.
* @return true if one or more statements have been removed.
*/
@@ -148,7 +148,7 @@ public default boolean add(Resource subj, URI pred, Value obj, Resource... conte
* context,
* {@code model.remove(null, null, null, c1, c2, c3)} removes any statements in this model have context {@code c1},
* {@code c2} or {@code c3}.
- *
+ *
* @param subj The subject of the statements to remove, {@code null} to remove statements with any subject.
* @param pred The predicate of the statements to remove, {@code null} to remove statements with any predicate.
* @param obj The object of the statements to remove, {@code null} to remove statements with any object.
@@ -167,12 +167,43 @@ public default boolean remove(Resource subj, URI pred, Value obj, Resource... co
return remove(subj, (IRI) pred, obj, contexts);
}
- // Views
+ /**
+ * Returns an {@link Iterable} over all {@link Statement}s in this Model that match the supplied criteria.
+ *
+ * Examples:
+ *
+ *
{@code model.getStatements(s1, null, null)} matches all statements that have subject {@code s1}
+ *
{@code model.getStatements(s1, p1, null)} matches all statements that have subject {@code s1} and predicate
+ * {@code p1}
+ *
{@code model.getStatements(null, null, null, c1)} matches all statements that have context {@code c1}
+ *
{@code model.getStatements(null, null, null, (Resource)null)} matches all statements that have no associated
+ * context
+ *
{@code model.getStatements(null, null, null, c1, c2, c3)} matches all statements that have context
+ * {@code c1}, {@code c2} or {@code c3}
+ *
+ *
+ * @param subject The subject of the statements to match, {@code null} to match statements with any subject.
+ * @param predicate The predicate of the statements to match, {@code null} to match statements with any predicate.
+ * @param object The object of the statements to match, {@code null} to match statements with any object.
+ * @param contexts The contexts of the statements to match. If no contexts are specified, statements will match
+ * disregarding their context. If one or more contexts are specified, statements with a context
+ * matching any one of these will match. To match statements without an associated context, specify
+ * the value {@code null} and explicitly cast it to type {@code Resource}.
+ * @return an {@link Iterable} over the statements in this Model that match the specified pattern.
+ *
+ * @since 3.2.0
+ *
+ * @see #filter(Resource, IRI, Value, Resource...)
+ */
+ public default Iterable getStatements(Resource subject, IRI predicate, Value object,
+ Resource... contexts) {
+ return () -> filter(subject, predicate, object, contexts).iterator();
+ }
/**
- * Returns a view of the statements with the specified subject, predicate, object and (optionally) context. The
- * {@code subject}, {@code predicate} and {@code object} parameters can be {@code null} to indicate wildcards. The
- * {@code contexts} parameter is a wildcard and accepts zero or more values. If no contexts are specified,
+ * Returns a filtered view of the statements with the specified subject, predicate, object and (optionally) context.
+ * The {@code subject}, {@code predicate} and {@code object} parameters can be {@code null} to indicate wildcards.
+ * The {@code contexts} parameter is a wildcard and accepts zero or more values. If no contexts are specified,
* statements will match disregarding their context. If one or more contexts are specified, statements with a
* context matching one of these will match. Note: to match statements without an associated context, specify the
* value {@code null} and explicitly cast it to type {@code Resource}.
@@ -190,7 +221,7 @@ public default boolean remove(Resource subj, URI pred, Value obj, Resource... co
* context,
* {@code model.filter(null, null, null, c1, c2, c3)} matches all statements that have context {@code c1},
* {@code c2} or {@code c3}.
- *
+ *
* @param subj The subject of the statements to match, {@code null} to match statements with any subject.
* @param pred The predicate of the statements to match, {@code null} to match statements with any predicate.
* @param obj The object of the statements to match, {@code null} to match statements with any object.
@@ -198,6 +229,8 @@ public default boolean remove(Resource subj, URI pred, Value obj, Resource... co
* disregarding their context. If one or more contexts are specified, statements with a context
* matching one of these will match.
* @return The statements that match the specified pattern.
+ *
+ * @see #getStatements(Resource, IRI, Value, Resource...)
*/
public Model filter(Resource subj, IRI pred, Value obj, Resource... contexts);
@@ -214,7 +247,7 @@ public default Model filter(Resource subj, URI pred, Value obj, Resource... cont
* is a subject value, via the {@code Iterator.remove}, {@code Set.remove}, {@code removeAll}, {@code retainAll},
* and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations if the parameters
* {@code pred} or {@code obj} are null.
- *
+ *
* @return a set view of the subjects contained in this model
*/
public Set subjects();
@@ -227,7 +260,7 @@ public default Model filter(Resource subj, URI pred, Value obj, Resource... cont
* is a predicate value, via the {@code Iterator.remove}, {@code Set.remove}, {@code removeAll}, {@code retainAll},
* and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations if the parameters
* {@code subj} or {@code obj} are null.
- *
+ *
* @return a set view of the predicates contained in this model
*/
public Set predicates();
@@ -240,7 +273,7 @@ public default Model filter(Resource subj, URI pred, Value obj, Resource... cont
* is an object value, via the {@code Iterator.remove}, {@code Set.remove}, {@code removeAll}, {@code retainAll},
* and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations if the parameters
* {@code subj} or {@code pred} are null.
- *
+ *
* @return a set view of the objects contained in this model
*/
public Set objects();
@@ -253,12 +286,14 @@ public default Model filter(Resource subj, URI pred, Value obj, Resource... cont
* is a context value, via the {@code Iterator.remove}, {@code Set.remove}, {@code removeAll}, {@code retainAll},
* and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations if the parameters
* {@code subj} , {@code pred} or {@code obj} are null.
- *
+ *
* @return a set view of the contexts contained in this model
*/
public default Set contexts() {
Set subjects = stream().map(st -> st.getContext()).collect(Collectors.toSet());
return subjects;
- };
+ }
+
+ ;
}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/ModelFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/ModelFactory.java
index 0335a044d7e..99a9c96a880 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/ModelFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/ModelFactory.java
@@ -9,7 +9,7 @@
/**
* Factory to create empty {@link Model} implementations.
- *
+ *
* @author James Leigh
*/
public interface ModelFactory {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/Namespace.java b/core/model/src/main/java/org/eclipse/rdf4j/model/Namespace.java
index b04f18563b5..3f7c37c5945 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/Namespace.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/Namespace.java
@@ -16,14 +16,14 @@ public interface Namespace extends Serializable, Comparable {
/**
* Gets the name of the current namespace (i.e. its IRI).
- *
+ *
* @return name of namespace
*/
public String getName();
/**
* Gets the prefix of the current namespace. The default namespace is represented by an empty prefix string.
- *
+ *
* @return prefix of namespace, or an empty string in case of the default namespace.
*/
public String getPrefix();
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/NamespaceAware.java b/core/model/src/main/java/org/eclipse/rdf4j/model/NamespaceAware.java
index 1000aa136e7..02886223b00 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/NamespaceAware.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/NamespaceAware.java
@@ -13,7 +13,7 @@
/**
* An interface that is used to signify that something is able to provide {@link Namespace} information, in addition to
* {@link Statement}s.
- *
+ *
* @author Peter Ansell
*/
@FunctionalInterface
@@ -21,7 +21,7 @@ public interface NamespaceAware {
/**
* Gets the set that contains the assigned namespaces.
- *
+ *
* @return A {@link Set} containing the {@link Namespace} objects that are available.
*/
public Set getNamespaces();
@@ -29,7 +29,7 @@ public interface NamespaceAware {
/**
* Gets the namespace that is associated with the specified prefix, if any. If multiple namespaces match the given
* prefix, the result may not be consistent over successive calls to this method.
- *
+ *
* @param prefix A namespace prefix.
* @return The namespace name that is associated with the specified prefix, or {@link Optional#empty()} if there is
* no such namespace.
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/Statement.java b/core/model/src/main/java/org/eclipse/rdf4j/model/Statement.java
index 04accff7d0b..1828e927ffd 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/Statement.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/Statement.java
@@ -18,35 +18,35 @@ public interface Statement extends Serializable {
/**
* Gets the subject of this statement.
- *
+ *
* @return The statement's subject.
*/
public Resource getSubject();
/**
* Gets the predicate of this statement.
- *
+ *
* @return The statement's predicate.
*/
public IRI getPredicate();
/**
* Gets the object of this statement.
- *
+ *
* @return The statement's object.
*/
public Value getObject();
/**
* Gets the context of this statement.
- *
+ *
* @return The statement's context, or null in case of the null context or if not applicable.
*/
public Resource getContext();
/**
* Compares a statement object to another object.
- *
+ *
* @param other The object to compare this statement to.
* @return true if the other object is an instance of {@link Statement} and if their subjects, predicates,
* objects and contexts are equal.
@@ -56,7 +56,7 @@ public interface Statement extends Serializable {
/**
* The hash code of a statement.
- *
+ *
* @return A hash code for the statement.
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/Triple.java b/core/model/src/main/java/org/eclipse/rdf4j/model/Triple.java
new file mode 100644
index 00000000000..4875299e8a9
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/Triple.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.model;
+
+import org.eclipse.rdf4j.common.annotation.Experimental;
+
+/**
+ * An RDF* triple. Triples have a subject, predicate and object. Unlike {@link Statement}, a triple never has an
+ * associated context.
+ *
+ * @author Pavel Mihaylov
+ */
+@Experimental
+public interface Triple extends Resource {
+
+ /**
+ * Gets the subject of this triple.
+ *
+ * @return The triple's subject.
+ */
+ Resource getSubject();
+
+ /**
+ * Gets the predicate of this triple.
+ *
+ * @return The triple's predicate.
+ */
+ IRI getPredicate();
+
+ /**
+ * Gets the object of this triple.
+ *
+ * @return The triple's object.
+ */
+ Value getObject();
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/URI.java b/core/model/src/main/java/org/eclipse/rdf4j/model/URI.java
index 554c8b071f1..05742624a6d 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/URI.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/URI.java
@@ -9,7 +9,7 @@
/**
* A Uniform Resource Identifier (URI).
- *
+ *
* @deprecated since 2.0. Use {@link IRI} instead.
* @author Jeen Broekstra
* @author Arjohn Kampman
@@ -20,7 +20,7 @@ public interface URI extends Resource {
/**
* Returns the String-representation of this URI.
- *
+ *
* @return The String-representation of this URI.
*/
@Override
@@ -29,7 +29,7 @@ public interface URI extends Resource {
/**
* Gets the namespace part of this URI. The namespace is defined as per the algorithm described in the class
* documentation.
- *
+ *
* @return The URI's namespace.
*/
public String getNamespace();
@@ -37,14 +37,14 @@ public interface URI extends Resource {
/**
* Gets the local name part of this URI. The local name is defined as per the algorithm described in the class
* documentation.
- *
+ *
* @return The URI's local name.
*/
public String getLocalName();
/**
* Compares a URI object to another object.
- *
+ *
* @param o The object to compare this URI to.
* @return true if the other object is an instance of {@link URI} and their String-representations are
* equal, false otherwise.
@@ -54,7 +54,7 @@ public interface URI extends Resource {
/**
* The hash code of an URI is defined as the hash code of its String-representation: toString().hashCode.
- *
+ *
* @return A hash code for the URI.
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/ValueFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/ValueFactory.java
index f8ed4ed7fe0..d399931c474 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/ValueFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/ValueFactory.java
@@ -19,7 +19,7 @@
/**
* A factory for creating {@link IRI IRIs}, {@link BNode blank nodes}, {@link Literal literals} and {@link Statement
* statements} based on the RDF-1.1 Concepts and Abstract Syntax, a W3C Recommendation.
- *
+ *
* @author Arjohn Kampman
* @see RDF-1.1 Concepts and Abstract Syntax
*/
@@ -27,7 +27,7 @@ public interface ValueFactory {
/**
* Creates a new IRI from the supplied string-representation.
- *
+ *
* @param iri A string-representation of a IRI.
* @return An object representing the IRI.
* @throws IlllegalArgumentException If the supplied string does not resolve to a legal (absolute) IRI.
@@ -36,7 +36,7 @@ public interface ValueFactory {
/**
* Creates a new URI from the supplied string-representation.
- *
+ *
* @param uri A string-representation of a URI.
* @return An object representing the URI.
* @throws IlllegalArgumentException If the supplied string does not resolve to a legal (absolute) URI.
@@ -52,7 +52,7 @@ public default URI createURI(String uri) {
* calling {@link #createIRI(String) createIRI(namespace+localName)}, but allows the ValueFactory to reuse supplied
* namespace and local name strings whenever possible. Note that the values returned by {@link IRI#getNamespace()}
* and {@link IRI#getLocalName()} are not necessarily the same as the values that are supplied to this method.
- *
+ *
* @param namespace The IRI's namespace.
* @param localName The IRI's local name.
* @throws IllegalArgumentException If the supplied namespace and localname do not resolve to a legal (absolute)
@@ -62,7 +62,7 @@ public default URI createURI(String uri) {
/**
* Creates a new URI from the supplied namespace and local name.
- *
+ *
* @param namespace The IRI's namespace.
* @param localName The IRI's local name.
* @return An object representing the URI.
@@ -76,14 +76,14 @@ public default URI createURI(String namespace, String localName) {
/**
* Creates a new bNode.
- *
+ *
* @return An object representing the bNode.
*/
public BNode createBNode();
/**
* Creates a new blank node with the given node identifier.
- *
+ *
* @param nodeID The blank node identifier.
* @return An object representing the blank node.
*/
@@ -92,7 +92,7 @@ public default URI createURI(String namespace, String localName) {
/**
* Creates a new literal with the supplied label. The return value of {@link Literal#getDatatype()} for the returned
* object must be {@link XMLSchema#STRING}.
- *
+ *
* @param label The literal's label, must not be null.
*/
public Literal createLiteral(String label);
@@ -100,7 +100,7 @@ public default URI createURI(String namespace, String localName) {
/**
* Creates a new literal with the supplied label and language attribute. The return value of
* {@link Literal#getDatatype()} for the returned object must be {@link RDF#LANGSTRING}.
- *
+ *
* @param label The literal's label, must not be null.
* @param language The literal's language attribute, must not be null.
*/
@@ -108,7 +108,7 @@ public default URI createURI(String namespace, String localName) {
/**
* Creates a new literal with the supplied label and datatype.
- *
+ *
* @param label The literal's label, must not be null.
* @param datatype The literal's datatype. If it is null, the datatype {@link XMLSchema#STRING} will be assigned to
* this literal.
@@ -117,7 +117,7 @@ public default URI createURI(String namespace, String localName) {
/**
* Creates a new literal with the supplied label and datatype.
- *
+ *
* @param label The literal's label.
* @param datatype The literal's datatype. If it is null, the datatype {@link XMLSchema#STRING} will be assigned to
* this literal.
@@ -130,7 +130,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:boolean-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:boolean-typed literal for the specified value.
*/
@@ -138,7 +138,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:byte-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:byte-typed literal for the specified value.
*/
@@ -146,7 +146,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:short-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:short-typed literal for the specified value.
*/
@@ -154,7 +154,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:int-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:int-typed literal for the specified value.
*/
@@ -162,7 +162,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:long-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:long-typed literal for the specified value.
*/
@@ -170,7 +170,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:float-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:float-typed literal for the specified value.
*/
@@ -178,7 +178,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new xsd:double-typed literal representing the specified value.
- *
+ *
* @param value The value for the literal.
* @return An xsd:double-typed literal for the specified value.
*/
@@ -199,7 +199,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new literal representing the specified calendar that is typed using the appropriate XML Schema
* date/time datatype.
- *
+ *
* @param calendar The value for the literal.
* @return An typed literal for the specified calendar.
*/
@@ -213,7 +213,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new statement with the supplied subject, predicate and object.
- *
+ *
* @param subject The statement's subject.
* @param predicate The statement's predicate.
* @param object The statement's object.
@@ -223,7 +223,7 @@ public default Literal createLiteral(String label, URI datatype) {
/**
* Creates a new statement with the supplied subject, predicate and object.
- *
+ *
* @param subject The statement's subject.
* @param predicate The statement's predicate.
* @param object The statement's object.
@@ -237,7 +237,7 @@ public default Statement createStatement(Resource subject, URI predicate, Value
/**
* Creates a new statement with the supplied subject, predicate and object and associated context.
- *
+ *
* @param subject The statement's subject.
* @param predicate The statement's predicate.
* @param object The statement's object.
@@ -248,7 +248,7 @@ public default Statement createStatement(Resource subject, URI predicate, Value
/**
* Creates a new statement with the supplied subject, predicate and object and associated context.
- *
+ *
* @param subject The statement's subject.
* @param predicate The statement's predicate.
* @param object The statement's object.
@@ -259,4 +259,19 @@ public default Statement createStatement(Resource subject, URI predicate, Value
public default Statement createStatement(Resource subject, URI predicate, Value object, Resource context) {
return createStatement(subject, (IRI) predicate, object, context);
}
+
+ /**
+ * Creates a new RDF* triple with the supplied subject, predicate and object.
+ *
+ * @param subject The statement's subject.
+ * @param predicate The statement's predicate.
+ * @param object The statement's object.
+ * @return The created triple.
+ * @implNote This temporary default method is only supplied as a stop-gap for backward compatibility, but throws an
+ * {@link UnsupportedOperationException}. Concrete implementations are expected to override.
+ * @since 3.2.0
+ */
+ default Triple createTriple(Resource subject, IRI predicate, Value object) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtil.java b/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtil.java
index a303db90ea3..7b68d1108b8 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtil.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtil.java
@@ -28,7 +28,7 @@
/**
* Provides methods for handling the standard XML Schema datatypes.
- *
+ *
* @author Arjohn Kampman
*/
public class XMLDatatypeUtil {
@@ -69,7 +69,7 @@ public class XMLDatatypeUtil {
/**
* Checks whether the supplied datatype is a primitive XML Schema datatype.
- *
+ *
* @param datatype
* @return true if the datatype is a primitive type
*/
@@ -88,7 +88,7 @@ public static boolean isPrimitiveDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is a derived XML Schema datatype.
- *
+ *
* @param datatype
* @return true if the datatype is a derived type
*/
@@ -111,7 +111,7 @@ public static boolean isDerivedDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is a built-in XML Schema datatype.
- *
+ *
* @param datatype
* @return true if it is a primitive or derived XML Schema type
*/
@@ -122,7 +122,7 @@ public static boolean isBuiltInDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is a numeric datatype, i.e.if it is equal to xsd:float, xsd:double,
* xsd:decimal or one of the datatypes derived from xsd:decimal.
- *
+ *
* @param datatype
* @return true of it is a decimal or floating point type
*/
@@ -133,7 +133,7 @@ public static boolean isNumericDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is equal to xsd:decimal or one of the built-in datatypes that is derived
* from xsd:decimal.
- *
+ *
* @param datatype
* @return true if it is a decimal datatype
*/
@@ -144,7 +144,7 @@ public static boolean isDecimalDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is equal to xsd:integer or one of the built-in datatypes that is derived
* from xsd:integer.
- *
+ *
* @param datatype
* @return true if it is an integer type
*/
@@ -159,7 +159,7 @@ public static boolean isIntegerDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is equal to xsd:float or xsd:double.
- *
+ *
* @param datatype
* @return true if it is a floating point type
*/
@@ -170,7 +170,7 @@ public static boolean isFloatingPointDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is equal to xsd:dateTime, xsd:date, xsd:time, xsd:gYearMonth, xsd:gMonthDay,
* xsd:gYear, xsd:gMonth or xsd:gDay.These are the primitive datatypes that represent dates and/or times.
- *
+ *
* @see XMLGregorianCalendar
* @param datatype
* @return true if it is a calendar type
@@ -199,7 +199,7 @@ public static boolean isDurationDatatype(IRI datatype) {
/**
* Checks whether the supplied datatype is ordered.The values of an ordered datatype can be compared to each other
* using operators like < and >.
- *
+ *
* @param datatype
* @return true if the datatype is ordered
*/
@@ -213,7 +213,7 @@ public static boolean isOrderedDatatype(IRI datatype) {
/**
* Verifies if the supplied lexical value is valid for the given datatype.
- *
+ *
* @param value a lexical value
* @param datatype an XML Schema datatatype.
* @return true if the supplied lexical value is valid, false otherwise.
@@ -292,7 +292,7 @@ public static boolean isValidValue(String value, IRI datatype) {
/**
* Verifies if the supplied lexical value is a valid decimal or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -307,7 +307,7 @@ public static boolean isValidDecimal(String value) {
/**
* Verifies if the supplied lexical value is a valid integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -322,7 +322,7 @@ public static boolean isValidInteger(String value) {
/**
* Verifies if the supplied lexical value is a valid negative integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -337,7 +337,7 @@ public static boolean isValidNegativeInteger(String value) {
/**
* Verifies if the supplied lexical value is a valid non-positive integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -352,7 +352,7 @@ public static boolean isValidNonPositiveInteger(String value) {
/**
* Verifies if the supplied lexical value is a valid non-negative integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -367,7 +367,7 @@ public static boolean isValidNonNegativeInteger(String value) {
/**
* Verifies if the supplied lexical value is a valid positive integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -382,7 +382,7 @@ public static boolean isValidPositiveInteger(String value) {
/**
* Verifies if the supplied lexical value is a valid long or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -397,7 +397,7 @@ public static boolean isValidLong(String value) {
/**
* Verifies if the supplied lexical value is a valid integer or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -412,7 +412,7 @@ public static boolean isValidInt(String value) {
/**
* Verifies if the supplied lexical value is a valid short or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -427,7 +427,7 @@ public static boolean isValidShort(String value) {
/**
* Verifies if the supplied lexical value is a valid byte or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -442,7 +442,7 @@ public static boolean isValidByte(String value) {
/**
* Verifies if the supplied lexical value is a valid unsigned long or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -457,7 +457,7 @@ public static boolean isValidUnsignedLong(String value) {
/**
* Verifies if the supplied lexical value is a valid unsigned int.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -472,7 +472,7 @@ public static boolean isValidUnsignedInt(String value) {
/**
* Verifies if the supplied lexical value is a valid unsigned short or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -487,7 +487,7 @@ public static boolean isValidUnsignedShort(String value) {
/**
* Verifies if the supplied lexical value is a valid unsigned byte or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -502,7 +502,7 @@ public static boolean isValidUnsignedByte(String value) {
/**
* Verifies if the supplied lexical value is a valid float or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -517,7 +517,7 @@ public static boolean isValidFloat(String value) {
/**
* Verifies if the supplied lexical value is a valid double or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -532,7 +532,7 @@ public static boolean isValidDouble(String value) {
/**
* Verifies if the supplied lexical value is a valid boolean or not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -547,7 +547,7 @@ public static boolean isValidBoolean(String value) {
/**
* Verifies if the supplied lexical value is a valid duration.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -559,7 +559,7 @@ public static boolean isValidDuration(String value) {
/**
* Verifies if the supplied lexical value is a valid day-time duration ot not.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -569,7 +569,7 @@ public static boolean isValidDayTimeDuration(String value) {
/**
* Verifies if the supplied lexical value is a valid year-month duration.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -579,7 +579,7 @@ public static boolean isValidYearMonthDuration(String value) {
/**
* Verifies if the supplied lexical value is a valid date-time.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -595,7 +595,7 @@ public static boolean isValidDateTime(String value) {
/**
* Verifies if the supplied lexical value is a valid date-timestamp.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -611,7 +611,7 @@ public static boolean isValidDateTimeStamp(String value) {
/**
* Determines if the supplied value is a valid xsd:date string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -621,7 +621,7 @@ public static boolean isValidDate(String value) {
/**
* Determines if the supplied value is a valid xsd:time string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -631,7 +631,7 @@ public static boolean isValidTime(String value) {
/**
* Determines if the supplied value is a valid xsd:gDay string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -641,7 +641,7 @@ public static boolean isValidGDay(String value) {
/**
* Determines if the supplied value is a valid xsd:gMonth string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -651,7 +651,7 @@ public static boolean isValidGMonth(String value) {
/**
* Determines if the supplied value is a valid xsd:gMonthDay string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -661,7 +661,7 @@ public static boolean isValidGMonthDay(String value) {
/**
* Determines if the supplied value is a valid xsd:gYear string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -671,7 +671,7 @@ public static boolean isValidGYear(String value) {
/**
* Determines if the supplied value is a valid xsd:gYearMonth string.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -682,7 +682,7 @@ public static boolean isValidGYearMonth(String value) {
/**
* Determines if the supplied value is a valid xsd:QName string. Note that this method only checks for syntax errors
* in the supplied string itself. It does not validate that the prefix is a declared and in-scope namespace prefix.
- *
+ *
* @param value
* @return true if valid, false otherwise
*/
@@ -763,7 +763,7 @@ private static boolean isNameChar(int c) {
/**
* Determines if the supplied string can be parsed to a valid XMLGregorianCalendar value.
- *
+ *
* @param value
* @return true if the supplied string is a parsable calendar value, false otherwise.
*/
@@ -782,7 +782,7 @@ private static boolean isValidCalendarValue(String value) {
/**
* Normalizes the supplied value according to the normalization rules for the supplied datatype.
- *
+ *
* @param value The value to normalize.
* @param datatype The value's datatype.
* @return The normalized value if there are any (supported) normalization rules for the supplied datatype, or the
@@ -839,7 +839,7 @@ public static String normalize(String value, IRI datatype) {
* Normalizes a boolean value to its canonical representation. More specifically, the values 1 and
* 0 will be normalized to the canonical values true and false, respectively. Supplied
* canonical values will remain as is.
- *
+ *
* @param value The boolean value to normalize.
* @return The normalized value.
* @throws IllegalArgumentException If the supplied value is not a legal boolean.
@@ -862,7 +862,7 @@ public static String normalizeBoolean(String value) {
* Normalizes a decimal to its canonical representation. For example: 120 becomes 120.0,
* +.3 becomes 0.3, 00012.45000 becomes 12.45 and -.0 becomes
* 0.0.
- *
+ *
* @param decimal The decimal to normalize.
* @return The canonical representation of decimal.
* @throws IllegalArgumentException If one of the supplied strings is not a legal decimal.
@@ -964,7 +964,7 @@ public static String normalizeDecimal(String decimal) {
/**
* Normalizes an integer to its canonical representation. For example: +120 becomes 120 and
* 00012 becomes 12.
- *
+ *
* @param value The value to normalize.
* @return The canonical representation of value.
* @throws IllegalArgumentException If the supplied value is not a legal integer.
@@ -1124,7 +1124,7 @@ private static String normalizeIntegerValue(String integer, String minValue, Str
/**
* Normalizes a float to its canonical representation.
- *
+ *
* @param value The value to normalize.
* @return The canonical representation of value.
* @throws IllegalArgumentException If the supplied value is not a legal float.
@@ -1135,7 +1135,7 @@ public static String normalizeFloat(String value) {
/**
* Normalizes a double to its canonical representation.
- *
+ *
* @param value The value to normalize.
* @return The canonical representation of value.
* @throws IllegalArgumentException If the supplied value is not a legal double.
@@ -1146,7 +1146,7 @@ public static String normalizeDouble(String value) {
/**
* Normalizes a floating point number to its canonical representation.
- *
+ *
* @param value The value to normalize.
* @return The canonical representation of value.
* @throws IllegalArgumentException If the supplied value is not a legal floating point number.
@@ -1157,7 +1157,7 @@ public static String normalizeFPNumber(String value) {
/**
* Normalizes a floating point lexical value to its canonical representation.
- *
+ *
* @param value The lexical value to normalize.
* @param minMantissa A normalized decimal indicating the lowest value that the mantissa may have.
* @param maxMantissa A normalized decimal indicating the highest value that the mantissa may have.
@@ -1311,7 +1311,7 @@ private static String normalizeFPNumber(String value, String minMantissa, String
/**
* Normalizes an xsd:dateTime.
- *
+ *
* @param value The value to normalize.
* @return The normalized value.
* @throws IllegalArgumentException If the supplied value is not a legal xsd:dateTime value.
@@ -1337,7 +1337,7 @@ public static String normalizeDateTime(String value) {
* Replaces all contiguous sequences of #x9 (tab), #xA (line feed) and #xD (carriage return) with a single #x20
* (space) character, and removes any leading and trailing whitespace characters, as specified for whiteSpace facet
* collapse.
- *
+ *
* @param s
* @return new string
*/
@@ -1403,7 +1403,7 @@ public static int compare(String value1, String value2, IRI datatype) {
/**
* Compares two decimals to eachother.
- *
+ *
* @param dec1
* @param dec2
* @return A negative number if dec1 is smaller than dec2, 0 if they are equal, or
@@ -1419,7 +1419,7 @@ public static int compareDecimals(String dec1, String dec2) {
/**
* Compares two canonical decimals to each other.
- *
+ *
* @param dec1
* @param dec2
* @return A negative number if dec1 is smaller than dec2, 0 if they are equal, or
@@ -1479,7 +1479,7 @@ public static int compareCanonicalDecimals(String dec1, String dec2) {
/**
* Compares two integers to each other.
- *
+ *
* @param int1
* @param int2
* @return A negative number if int1 is smaller than int2, 0 if they are equal, or
@@ -1495,7 +1495,7 @@ public static int compareIntegers(String int1, String int2) {
/**
* Compares two canonical integers to each other.
- *
+ *
* @param int1
* @param int2
* @return A negative number if int1 is smaller than int2, 0 if they are equal, or
@@ -1622,7 +1622,7 @@ public static int compareUnsignedBytes(String int1, String int2) {
/**
* Compares two floats to each other.
- *
+ *
* @param float1
* @param float2
* @return A negative number if float1 is smaller than float2, 0 if they are equal, or
@@ -1639,7 +1639,7 @@ public static int compareFloats(String float1, String float2) {
/**
* Compares two canonical floats to each other.
- *
+ *
* @param float1
* @param float2
* @return A negative number if float1 is smaller than float2, 0 if they are equal, or
@@ -1654,7 +1654,7 @@ public static int compareCanonicalFloats(String float1, String float2) {
/**
* Compares two doubles to each other.
- *
+ *
* @param double1
* @param double2
* @return A negative number if double1 is smaller than double2, 0 if they are equal, or
@@ -1671,7 +1671,7 @@ public static int compareDoubles(String double1, String double2) {
/**
* Compares two canonical doubles to eachother.
- *
+ *
* @param double1
* @param double2
* @return A negative number if double1 is smaller than double2, 0 if they are equal, or
@@ -1686,7 +1686,7 @@ public static int compareCanonicalDoubles(String double1, String double2) {
/**
* Compares two floating point numbers to eachother.
- *
+ *
* @param fp1
* @param fp2
* @return A negative number if float1 is smaller than float2, 0 if they are equal, or
@@ -1703,7 +1703,7 @@ public static int compareFPNumbers(String fp1, String fp2) {
/**
* Compares two canonical floating point numbers to each other.
- *
+ *
* @param float1
* @param float2
* @return A negative number if float1 is smaller than float2, 0 if they are equal, or
@@ -1774,7 +1774,7 @@ public static int compareCanonicalFPNumbers(String float1, String float2) {
/**
* Compares two dateTime objects. Important: The comparison only works if both values have, or both values
* don't have specified a valid value for the timezone.
- *
+ *
* @param value1 An xsd:dateTime value.
* @param value2 An xsd:dateTime value.
* @return -1 if value1 is before value2 (i.e. if the dateTime object represented by
@@ -1798,7 +1798,7 @@ public static int compareDateTime(String value1, String value2) {
/**
* Parses the supplied xsd:boolean string and returns its value.
- *
+ *
* @param s A string representation of an xsd:boolean value.
* @return The boolean value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:boolean value.
@@ -1809,7 +1809,7 @@ public static boolean parseBoolean(String s) {
/**
* Parses the supplied xsd:byte string and returns its value.
- *
+ *
* @param s A string representation of an xsd:byte value.
* @return The byte value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:byte value.
@@ -1821,7 +1821,7 @@ public static byte parseByte(String s) {
/**
* Parses the supplied xsd:short string and returns its value.
- *
+ *
* @param s A string representation of an xsd:short value.
* @return The short value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:short value.
@@ -1833,7 +1833,7 @@ public static short parseShort(String s) {
/**
* Parses the supplied xsd:int strings and returns its value.
- *
+ *
* @param s A string representation of an xsd:int value.
* @return The int value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:int value.
@@ -1845,7 +1845,7 @@ public static int parseInt(String s) {
/**
* Parses the supplied xsd:long string and returns its value.
- *
+ *
* @param s A string representation of an xsd:long value.
* @return The long value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:long value.
@@ -1857,7 +1857,7 @@ public static long parseLong(String s) {
/**
* Parses the supplied xsd:float string and returns its value.
- *
+ *
* @param s A string representation of an xsd:float value.
* @return The float value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:float value.
@@ -1877,7 +1877,7 @@ public static float parseFloat(String s) {
/**
* Parses the supplied xsd:double string and returns its value.
- *
+ *
* @param s A string representation of an xsd:double value.
* @return The double value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:double value.
@@ -1897,7 +1897,7 @@ public static double parseDouble(String s) {
/**
* Parses the supplied xsd:integer string and returns its value.
- *
+ *
* @param s A string representation of an xsd:integer value.
* @return The integer value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:integer value.
@@ -1909,7 +1909,7 @@ public static BigInteger parseInteger(String s) {
/**
* Parses the supplied decimal/floating point string and returns its value.
- *
+ *
* @param s A string representation of an xsd:decimal or xsd:double value.
* @return The decimal/floating point value represented by the supplied string argument.
* @throws NumberFormatException If the supplied string is not a valid xsd:decimal or xsd:double value.
@@ -1921,7 +1921,7 @@ public static BigDecimal parseDecimal(String s) {
/**
* Parses the supplied calendar value string and returns its value.
- *
+ *
* @param s A string representation of an xsd:dateTime, xsd:time, xsd:date, xsd:gYearMonth, xsd:gMonthDay,
* xsd:gYear, xsd:gMonth or xsd:gDay value.
* @return The calendar value represented by the supplied string argument.
@@ -1933,7 +1933,7 @@ public static XMLGregorianCalendar parseCalendar(String s) {
/**
* Parses the supplied xsd:duration value string and returns its value.
- *
+ *
* @param s A string representation of an xsd:duration value.
* @return The {@link Duration} value represented by the supplied string argument.
* @throws IllegalArgumentException If the supplied string is not a valid xsd:duration value.
@@ -1963,9 +1963,9 @@ private static String trimPlusSign(String s) {
/**
* Maps a datatype QName from the javax.xml.namespace package to an XML Schema 1.0 URI for the corresponding
* datatype. This method recognizes the XML Schema qname mentioned in {@link DatatypeConstants}.
- *
+ *
* Note that Java 8 / 11 do not have constants for XML Schema 1.1 datatypes like xsd:dateTimeStamp.
- *
+ *
* @param qname One of the XML Schema qnames from {@link DatatypeConstants}.
* @return A URI for the specified datatype.
* @throws IllegalArgumentException If the supplied qname was not recognized by this method.
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDateTime.java b/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDateTime.java
index fc0aa69b295..2fd97008320 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDateTime.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/datatypes/XMLDateTime.java
@@ -19,7 +19,7 @@
*
* Known deviations from the standard: - the range of years in this implementation is limited to Integer.MIN_VALUE to
* Integer.MAX_VALUE for practical reasons.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
* @see W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes
@@ -102,7 +102,7 @@ public class XMLDateTime implements Cloneable, Comparable {
/**
* Creates a new XMLDateTime object for the supplied xsd:dateTime string value.
- *
+ *
* @param dateTimeString An xsd:dateTime lexical value, for example 1999-05-31T13:20:00-05:00.
* @throws IllegalArgumentException if the supplied lexical value does not constitute a valid xsd:dateTime.
*/
@@ -276,7 +276,7 @@ private void validateFieldValues() {
/**
* Checks if the supplied month is a month with exactly 30 days.
- *
+ *
* @param month the month
* @return {@code true} iff the supplied month has exactly 30 days.
*/
@@ -287,7 +287,7 @@ private boolean is30DayMonth(int month) {
/**
* Checks if the supplied year is a leap year (one in which February 29 occurs) according to the definition in
* the XML Schema XSD definition
- *
+ *
* @param year the year.
* @return {@code true} if the supplied year is a leap year according to the XSD definition.
*/
@@ -399,7 +399,7 @@ private String int2string(int iValue, int minDigits) {
/**
* Returns the xsd:dateTime string-representation of this object.
- *
+ *
* @return An xsd:dateTime value, e.g. 1999-05-31T13:20:00-05:00.
*/
@Override
@@ -446,7 +446,7 @@ public String toString() {
/**
* Compares this DateTime object to another DateTime object.
- *
+ *
* @throws ClassCastException If other is not a DateTime object.
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractModel.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractModel.java
index 7b6de428601..2377fcfc590 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractModel.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractModel.java
@@ -49,9 +49,11 @@ public boolean isEmpty() {
public boolean containsAll(Collection> c) {
Iterator> e = c.iterator();
try {
- while (e.hasNext())
- if (!contains(e.next()))
+ while (e.hasNext()) {
+ if (!contains(e.next())) {
return false;
+ }
+ }
return true;
} finally {
closeIterator(c, e);
@@ -64,8 +66,9 @@ public boolean removeAll(Collection> c) {
if (size() > c.size()) {
Iterator> i = c.iterator();
try {
- while (i.hasNext())
+ while (i.hasNext()) {
modified |= remove(i.next());
+ }
} finally {
closeIterator(c, i);
}
@@ -121,8 +124,9 @@ public boolean addAll(Collection extends Statement> c) {
try {
boolean modified = false;
while (e.hasNext()) {
- if (add(e.next()))
+ if (add(e.next())) {
modified = true;
+ }
}
return modified;
} finally {
@@ -451,8 +455,9 @@ public boolean removeAll(Collection> c) {
boolean modified = false;
Iterator> i = c.iterator();
try {
- while (i.hasNext())
+ while (i.hasNext()) {
modified |= remove(i.next());
+ }
} finally {
closeIterator(c, i);
}
@@ -491,9 +496,11 @@ public T[] toArray(T[] a) {
public boolean containsAll(Collection> c) {
Iterator> e = c.iterator();
try {
- while (e.hasNext())
- if (!contains(e.next()))
+ while (e.hasNext()) {
+ if (!contains(e.next())) {
return false;
+ }
+ }
return true;
} finally {
closeIterator(c, e);
@@ -506,8 +513,9 @@ public boolean addAll(Collection extends V> c) {
try {
boolean modified = false;
while (e.hasNext()) {
- if (add(e.next()))
+ if (add(e.next())) {
modified = true;
+ }
}
return modified;
} finally {
@@ -555,7 +563,7 @@ private void closeIterator(Collection> c, Iterator> e) {
/**
* Called by aggregate sets when a term has been removed from a term iterator. Exactly one of the last four terms
* will be non-empty.
- *
+ *
* @param iter The iterator used to navigate the live set (never null)
* @param subj the subject term to be removed or null
* @param pred the predicate term to be removed or null
@@ -567,7 +575,7 @@ public abstract void removeTermIteration(Iterator iter, Resource subj
/**
* Cleans up any resources used by this iterator. After this call the given iterator should not be used.
- *
+ *
* @param iter Iterator to clean up
*/
protected void closeIterator(Iterator> iter) {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractValueFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractValueFactory.java
index eb79b6e33ed..01de3c91664 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractValueFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/AbstractValueFactory.java
@@ -21,6 +21,7 @@
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
@@ -30,7 +31,7 @@
* Abstract base class for {@link ValueFactory} implementations. It implements all basic {@link Value} creation methods
* by using the default implementations ({@link SimpleBNode}, {@link SimpleIRI}, etc), and type-optimized subclasses
* (e.g. {@link BooleanLiteral}, {@link NumericLiteral}) where possible.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
@@ -126,6 +127,11 @@ public Statement createStatement(Resource subject, IRI predicate, Value object,
return new ContextStatement(subject, predicate, object, context);
}
+ @Override
+ public Triple createTriple(Resource subject, IRI predicate, Value object) {
+ return new SimpleTriple(subject, predicate, object);
+ }
+
/**
* Generates a new bnode prefix and resets nextBNodeID to 1 .
*/
@@ -241,7 +247,7 @@ protected Literal createNumericLiteral(Number number, IRI datatype) {
/**
* Calls {@link ValueFactory#createLiteral(String, IRI)} with the String-value of the supplied calendar and the
* appropriate datatype as parameters.
- *
+ *
* @see XMLGregorianCalendar#toXMLFormat()
* @see XMLGregorianCalendar#getXMLSchemaType()
* @see XMLDatatypeUtil#qnameToURI(javax.xml.namespace.QName)
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/BooleanLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/BooleanLiteral.java
index 324e75500e3..ee5044f3427 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/BooleanLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/BooleanLiteral.java
@@ -11,7 +11,7 @@
/**
* An extension of {@link SimpleLiteral} that stores a boolean value to avoid parsing.
- *
+ *
* @author David Huynh
* @author Arjohn Kampman
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/CalendarLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/CalendarLiteral.java
index 0062c71fb01..2afaf23c54d 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/CalendarLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/CalendarLiteral.java
@@ -13,7 +13,7 @@
/**
* An extension of {@link SimpleLiteral} that stores a calendar value to avoid parsing.
- *
+ *
* @author David Huynh
* @author Arjohn Kampman
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ContextStatement.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ContextStatement.java
index f2f06afb79c..3e49059dfe5 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ContextStatement.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ContextStatement.java
@@ -33,7 +33,7 @@ public class ContextStatement extends SimpleStatement {
/**
* Creates a new Statement with the supplied subject, predicate and object for the specified associated context.
- *
+ *
* @param subject The statement's subject, must not be null.
* @param predicate The statement's predicate, must not be null.
* @param object The statement's object, must not be null.
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DecimalLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DecimalLiteral.java
index 1716d47d44a..6f139e755ed 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DecimalLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DecimalLiteral.java
@@ -15,7 +15,7 @@
/**
* An extension of {@link SimpleLiteral} that stores an integer value using a {@link BigDecimal} object.
- *
+ *
* @author Arjohn Kampman
*/
public class DecimalLiteral extends SimpleLiteral {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModel.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModel.java
new file mode 100644
index 00000000000..2275af5763c
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModel.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.model.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.ModelFactory;
+import org.eclipse.rdf4j.model.Namespace;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.util.Models;
+import org.eclipse.rdf4j.util.iterators.EmptyIterator;
+import org.eclipse.rdf4j.util.iterators.SingletonIterator;
+
+/**
+ * A LinkedHashModel or a TreeModel achieves fast data access at the cost of higher indexing time. The DynamicModel
+ * postpones this cost until such access is actually needed. It stores all data in a LinkedHashMap and supports adding,
+ * retrieving and removing data. The model will upgrade to a full model (provided by the modelFactory) if more complex
+ * operations are called, for instance removing data according to a pattern (eg. all statements with rdf:type as
+ * predicate).
+ *
+ * DynamicModel is thread safe to the extent that the underlying LinkedHashMap or Model is. The upgrade path is
+ * protected by the actual upgrade method being synchronized. The LinkedHashMap storage is not removed once upgraded, so
+ * concurrent reads that have started reading from the LinkedHashMap can continue to read even during an upgrade. We do
+ * make the LinkedHashMap unmodifiable to reduce the chance of there being a bug.
+ *
+ * @author HÃ¥vard Mikkelsen Ottestad
+ */
+public class DynamicModel implements Model {
+
+ private static final long serialVersionUID = -9162104133818983614L;
+
+ private static final Resource[] NULL_CTX = new Resource[] { null };
+
+ private Map statements = new LinkedHashMap<>();
+ final Set namespaces = new LinkedHashSet<>();
+
+ volatile private Model model = null;
+
+ private final ModelFactory modelFactory;
+
+ public DynamicModel(ModelFactory modelFactory) {
+ this.modelFactory = modelFactory;
+ }
+
+ @Override
+ public Model unmodifiable() {
+ upgrade();
+ return model.unmodifiable();
+ }
+
+ @Override
+ public Optional getNamespace(String prefix) {
+ for (Namespace nextNamespace : namespaces) {
+ if (prefix.equals(nextNamespace.getPrefix())) {
+ return Optional.of(nextNamespace);
+ }
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public Set getNamespaces() {
+ return namespaces;
+ }
+
+ @Override
+ public Namespace setNamespace(String prefix, String name) {
+ removeNamespace(prefix);
+ Namespace result = new SimpleNamespace(prefix, name);
+ namespaces.add(result);
+ return result;
+ }
+
+ @Override
+ public void setNamespace(Namespace namespace) {
+ removeNamespace(namespace.getPrefix());
+ namespaces.add(namespace);
+ }
+
+ @Override
+ public Optional removeNamespace(String prefix) {
+ Optional result = getNamespace(prefix);
+ result.ifPresent(namespaces::remove);
+ return result;
+ }
+
+ @Override
+ public boolean contains(Resource subj, IRI pred, Value obj, Resource... contexts) {
+ upgrade();
+ return model.contains(subj, pred, obj, contexts);
+ }
+
+ @Override
+ public boolean add(Resource subj, IRI pred, Value obj, Resource... contexts) {
+ if (contexts.length == 0) {
+ contexts = NULL_CTX;
+ }
+
+ if (model == null) {
+ boolean added = false;
+ for (Resource context : contexts) {
+ Statement statement = SimpleValueFactory.getInstance().createStatement(subj, pred, obj, context);
+ added = added
+ | statements.put(statement, statement) == null;
+ }
+ return added;
+ } else {
+ return model.add(subj, pred, obj, contexts);
+ }
+ }
+
+ @Override
+ public boolean clear(Resource... context) {
+ upgrade();
+ return model.clear(context);
+ }
+
+ @Override
+ public boolean remove(Resource subj, IRI pred, Value obj, Resource... contexts) {
+ if (subj == null || pred == null || obj == null || contexts.length == 0) {
+ upgrade();
+ }
+
+ if (model == null) {
+ boolean removed = false;
+ for (Resource context : contexts) {
+ removed = removed
+ | statements.remove(
+ SimpleValueFactory.getInstance().createStatement(subj, pred, obj, context)) != null;
+ }
+ return removed;
+ } else {
+ return model.remove(subj, pred, obj, contexts);
+ }
+ }
+
+ @Override
+ public Model filter(Resource subj, IRI pred, Value obj, Resource... contexts) {
+ upgrade();
+ return model.filter(subj, pred, obj, contexts);
+ }
+
+ @Override
+ public Set subjects() {
+ upgrade();
+ return model.subjects();
+ }
+
+ @Override
+ public Set predicates() {
+ upgrade();
+ return model.predicates();
+ }
+
+ @Override
+ public Set objects() {
+ upgrade();
+ return model.objects();
+ }
+
+ @Override
+ public Set contexts() {
+ upgrade();
+ return model.contexts();
+ }
+
+ @Override
+ public int size() {
+ if (model == null) {
+ return statements.size();
+ }
+ return model.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ if (model == null) {
+ return statements.isEmpty();
+ }
+ return model.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ if (model == null) {
+ return statements.containsKey(o);
+ }
+ return model.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ if (model == null) {
+ return statements.values().iterator();
+ }
+
+ return model.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ if (model == null) {
+ return statements.values().toArray();
+ }
+ return model.toArray();
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ if (model == null) {
+ return statements.values().toArray(a);
+ }
+ return model.toArray(a);
+ }
+
+ @Override
+ public boolean add(Statement statement) {
+ Objects.requireNonNull(statement);
+ if (model == null) {
+ return statements.put(statement, statement) == null;
+ }
+ return model.add(statement);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ Objects.requireNonNull(o);
+ if (model == null) {
+ return statements.remove(o) != null;
+ }
+ return model.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ Objects.requireNonNull(c);
+ if (model == null) {
+ return statements.keySet().containsAll(c);
+ }
+ return model.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection extends Statement> c) {
+ Objects.requireNonNull(c);
+ if (model == null) {
+ return c.stream()
+ .map(s -> {
+ Objects.requireNonNull(s);
+ return statements.put(s, s) == null;
+ })
+ .reduce((a, b) -> a || b)
+ .orElse(false);
+ }
+ return model.addAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ if (model == null) {
+ return statements.keySet().retainAll(c);
+ }
+ return model.retainAll(c);
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ if (model == null) {
+ return c
+ .stream()
+ .map(statements::remove)
+ .map(Objects::nonNull)
+ .reduce((a, b) -> a || b)
+ .orElse(false);
+ }
+ return model.removeAll(c);
+ }
+
+ @Override
+ public void clear() {
+ if (model == null) {
+ statements.clear();
+ } else {
+ model.clear();
+ }
+ }
+
+ @Override
+ public Iterable getStatements(Resource subject, IRI predicate, Value object, Resource... contexts) {
+ if (model == null && subject != null && predicate != null && object != null && contexts != null
+ && contexts.length == 1) {
+ Statement statement = SimpleValueFactory.getInstance()
+ .createStatement(subject, predicate, object, contexts[0]);
+ Statement foundStatement = statements.get(statement);
+ if (foundStatement == null) {
+ return EmptyIterator::new;
+ }
+ return () -> new SingletonIterator<>(foundStatement);
+ } else if (model == null && subject == null && predicate == null && object == null && contexts != null
+ && contexts.length == 0) {
+ return this;
+ } else {
+ upgrade();
+ return model.getStatements(subject, predicate, object, contexts);
+ }
+ }
+
+ private void upgrade() {
+ if (model == null) {
+ synchronizedUpgrade();
+ }
+ }
+
+ synchronized private void synchronizedUpgrade() {
+ if (model == null) {
+ // make statements unmodifiable first, to increase chance of an early failure if the user is doing
+ // concurrent write with reads
+ statements = Collections.unmodifiableMap(statements);
+ Model tempModel = modelFactory.createEmptyModel();
+ tempModel.addAll(statements.values());
+ model = tempModel;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof Model) {
+ Model model = (Model) o;
+ return Models.isomorphic(this, model);
+ } else if (o instanceof Set) {
+ if (this.size() != ((Set>) o).size()) {
+ return false;
+ }
+ try {
+ return Models.isomorphic(this, (Iterable extends Statement>) o);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ return false;
+
+ }
+
+ @Override
+ public int hashCode() {
+ if (model != null) {
+ return model.hashCode();
+ } else {
+ int h = 0;
+ for (Statement obj : this) {
+ if (obj != null) {
+ h += obj.hashCode();
+ }
+ }
+ return h;
+
+ }
+
+ }
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModelFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModelFactory.java
new file mode 100644
index 00000000000..86fc4f3c399
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/DynamicModelFactory.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.model.impl;
+
+import org.eclipse.rdf4j.model.ModelFactory;
+
+/**
+ * Creates {@link DynamicModel}.
+ *
+ */
+public class DynamicModelFactory implements ModelFactory {
+
+ @Override
+ public DynamicModel createEmptyModel() {
+ return new DynamicModel(new LinkedHashModelFactory());
+ }
+
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/EmptyModel.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/EmptyModel.java
index a37567b93a1..1cb86e586a4 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/EmptyModel.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/EmptyModel.java
@@ -21,7 +21,7 @@
/**
* Blocks access to the statements of the model, allowing only changes to the model's namespaces.
- *
+ *
* @author James Leigh
*/
public class EmptyModel extends AbstractModel {
@@ -97,4 +97,4 @@ public void removeTermIteration(Iterator iter, Resource subj, IRI pre
// remove nothing
}
-}
\ No newline at end of file
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/FilteredModel.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/FilteredModel.java
index 1556987efca..32a45b69834 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/FilteredModel.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/FilteredModel.java
@@ -189,7 +189,7 @@ public final void removeTermIteration(Iterator iter, Resource s, IRI
/**
* Called by aggregate sets when a term has been removed from a term iterator. At least one of the last four terms
* will be non-empty.
- *
+ *
* @param iter The iterator used to navigate the live set (never null)
* @param subj the subject term to be removed or null
* @param pred the predicate term to be removed or null
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/IntegerLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/IntegerLiteral.java
index 5ef75ae0dc6..be0c91caa74 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/IntegerLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/IntegerLiteral.java
@@ -15,7 +15,7 @@
/**
* An extension of {@link SimpleLiteral} that stores an integer value using a {@link BigInteger} object.
- *
+ *
* @author Arjohn Kampman
*/
public class IntegerLiteral extends SimpleLiteral {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModelFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModelFactory.java
index 4a08b49b622..c1da27f4dc0 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModelFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModelFactory.java
@@ -7,14 +7,18 @@
*******************************************************************************/
package org.eclipse.rdf4j.model.impl;
+import java.io.Serializable;
+
import org.eclipse.rdf4j.model.ModelFactory;
/**
* Creates {@link LinkedHashModel}.
- *
+ *
* @author James Leigh
*/
-public class LinkedHashModelFactory implements ModelFactory {
+public class LinkedHashModelFactory implements ModelFactory, Serializable {
+
+ private static final long serialVersionUID = -9152104133818783614L;
@Override
public LinkedHashModel createEmptyModel() {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/NumericLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/NumericLiteral.java
index 17327a90097..58f3f7cd3f3 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/NumericLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/NumericLiteral.java
@@ -13,7 +13,7 @@
/**
* An extension of {@link SimpleLiteral} that stores a numeric value to avoid parsing.
- *
+ *
* @author David Huynh
*/
public class NumericLiteral extends SimpleLiteral {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleLiteral.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleLiteral.java
index 8f4fb11f6b0..8240cead350 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleLiteral.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleLiteral.java
@@ -23,7 +23,7 @@
/**
* A simple default implementation of the {@link Literal} interface.
- *
+ *
* @author Arjohn Kampman
* @author David Huynh
*/
@@ -63,7 +63,7 @@ protected SimpleLiteral() {
/**
* Creates a new plain literal with the supplied label.
- *
+ *
* @param label The label for the literal, must not be null.
*/
protected SimpleLiteral(String label) {
@@ -73,7 +73,7 @@ protected SimpleLiteral(String label) {
/**
* Creates a new plain literal with the supplied label and language tag.
- *
+ *
* @param label The label for the literal, must not be null.
* @param language The language tag for the literal, must not be null and not be empty.
*/
@@ -84,7 +84,7 @@ protected SimpleLiteral(String label, String language) {
/**
* Creates a new datatyped literal with the supplied label and datatype.
- *
+ *
* @param label The label for the literal, must not be null.
* @param datatype The datatype for the literal.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleNamespace.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleNamespace.java
index 0598575ef92..6fa68a0e300 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleNamespace.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleNamespace.java
@@ -36,7 +36,7 @@ public class SimpleNamespace implements Namespace {
/**
* Creates a new Namespace object.
- *
+ *
* @param prefix The namespace's prefix.
* @param name The namespace's name.
*/
@@ -51,7 +51,7 @@ public SimpleNamespace(String prefix, String name) {
/**
* Gets the prefix of the namespace.
- *
+ *
* @return prefix of the namespace
*/
@Override
@@ -61,7 +61,7 @@ public String getPrefix() {
/**
* Sets the prefix of the namespace.
- *
+ *
* @param prefix The (new) prefix for this namespace.
*/
public void setPrefix(String prefix) {
@@ -70,7 +70,7 @@ public void setPrefix(String prefix) {
/**
* Gets the name of the namespace.
- *
+ *
* @return name of the namespace
*/
@Override
@@ -80,7 +80,7 @@ public String getName() {
/**
* Sets the name of the namespace.
- *
+ *
* @param name The (new) name for this namespace.
*/
public void setName(String name) {
@@ -89,7 +89,7 @@ public void setName(String name) {
/**
* Returns a string representation of the object.
- *
+ *
* @return String representation of the namespace
*/
@Override
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleStatement.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleStatement.java
index 51322ebf6a6..34118020fdd 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleStatement.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleStatement.java
@@ -17,7 +17,7 @@
/**
* A simple default implementation of the {@link Statement} interface for statements that don't have an associated
* context. For statements that do have an associated context, {@link ContextStatement} can be used.
- *
+ *
* @see org.eclipse.rdf4j.model.impl.SimpleValueFactory
*/
public class SimpleStatement implements Statement {
@@ -53,7 +53,7 @@ public class SimpleStatement implements Statement {
* Note that creating SimpleStatement objects directly via this constructor is not the recommended approach.
* Instead, use a {@link org.eclipse.rdf4j.model.ValueFactory ValueFactory} (obtained from your repository or by
* using {@link org.eclipse.rdf4j.model.impl.SimpleValueFactory#getInstance()}) to create new Statement objects.
- *
+ *
* @param subject The statement's subject, must not be null.
* @param predicate The statement's predicate, must not be null.
* @param object The statement's object, must not be null.
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleTriple.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleTriple.java
new file mode 100644
index 00000000000..f2faeb461fc
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleTriple.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.model.impl;
+
+import java.util.Objects;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+
+/**
+ * A simple default implementation of the {@link Triple} interface.
+ *
+ * @author Pavel Mihaylov
+ * @see SimpleValueFactory
+ */
+public class SimpleTriple implements Triple {
+
+ /**
+ * The triple's subject.
+ */
+ private Resource subject;
+
+ /**
+ * The triple's predicate.
+ */
+ private IRI predicate;
+
+ /**
+ * The triple's object.
+ */
+ private Value object;
+
+ /**
+ * Creates a new Triple with the supplied subject, predicate and object.
+ *
+ * Note that creating SimpleStatement objects directly via this constructor is not the recommended approach.
+ * Instead, use an instance of {@link org.eclipse.rdf4j.model.ValueFactory} to create new Triple objects.
+ *
+ * @param subject The triple's subject, must not be null.
+ * @param predicate The triple's predicate, must not be null.
+ * @param object The triple's object, must not be null.
+ * @see {@link SimpleValueFactory#createTriple(Resource, IRI, Value)
+ */
+ protected SimpleTriple(Resource subject, IRI predicate, Value object) {
+ this.subject = Objects.requireNonNull(subject, "subject must not be null");
+ this.predicate = Objects.requireNonNull(predicate, "predicate must not be null");
+ this.object = Objects.requireNonNull(object, "object must not be null");
+ }
+
+ @Override
+ public Resource getSubject() {
+ return subject;
+ }
+
+ @Override
+ public IRI getPredicate() {
+ return predicate;
+ }
+
+ @Override
+ public Value getObject() {
+ return object;
+ }
+
+ @Override
+ public String stringValue() {
+ StringBuilder sb = new StringBuilder(256);
+
+ sb.append("<<");
+ sb.append(getSubject());
+ sb.append(" ");
+ sb.append(getPredicate());
+ sb.append(" ");
+ sb.append(getObject());
+ sb.append(">>");
+
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ return stringValue();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o instanceof Triple) {
+ Triple that = (Triple) o;
+ return Objects.equals(subject, that.getSubject()) && Objects.equals(predicate, that.getPredicate())
+ && Objects.equals(object, that.getObject());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(subject, predicate, object);
+ }
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleValueFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleValueFactory.java
index a503357b1a6..3e51e499d28 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleValueFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/SimpleValueFactory.java
@@ -11,7 +11,7 @@
/**
* Default implementation of the {@link ValueFactory} interface.
- *
+ *
* @author Arjohn Kampman
*/
public class SimpleValueFactory extends AbstractValueFactory {
@@ -24,7 +24,7 @@ public class SimpleValueFactory extends AbstractValueFactory {
/**
* Provide a single shared instance of a SimpleValueFactory.
- *
+ *
* @return a singleton instance of SimpleValueFactory.
*/
public static SimpleValueFactory getInstance() {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/TreeModelFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/TreeModelFactory.java
index 5d9be840e71..28c494badf3 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/TreeModelFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/TreeModelFactory.java
@@ -11,7 +11,7 @@
/**
* Creates {@link TreeModel}.
- *
+ *
* @author James Leigh
*/
public class TreeModelFactory implements ModelFactory {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValidatingValueFactory.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValidatingValueFactory.java
index 4f408144669..abe45595a16 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValidatingValueFactory.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValidatingValueFactory.java
@@ -20,6 +20,7 @@
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.URI;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
@@ -222,6 +223,11 @@ public Statement createStatement(Resource subject, URI predicate, Value object,
return delegate.createStatement(subject, predicate, object, context);
}
+ @Override
+ public Triple createTriple(Resource subject, IRI predicate, Value object) {
+ return delegate.createTriple(subject, predicate, object);
+ }
+
private boolean isMember(int[][] set, int cp) {
for (int i = 0; i < set.length; i++) {
if (set[i][0] <= cp && cp <= set[i][1]) {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValueFactoryBase.java b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValueFactoryBase.java
index 684f97dd134..92b9a2af493 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValueFactoryBase.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/impl/ValueFactoryBase.java
@@ -9,7 +9,7 @@
/**
* Provided for backward compatility purposes only
- *
+ *
* @deprecated since 2.0. Use {@link AbstractValueFactory} instead.
* @author Jeen Broekstra
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/package-info.java b/core/model/src/main/java/org/eclipse/rdf4j/model/package-info.java
index c1593feba95..5a80f28f496 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/package-info.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/package-info.java
@@ -3,7 +3,7 @@
*
* The core RDF model interfaces are organized in the following hierarchy:
*
- *
+ *
*
* Value Statement Model
* / \
@@ -23,7 +23,7 @@
* Literal}, {@link org.eclipse.rdf4j.model.BNode BNode}, {@link org.eclipse.rdf4j.model.Statement Statement}) is done
* by means of a {@link org.eclipse.rdf4j.model.ValueFactory ValueFactory}.
*
- *
+ *
* @see rdf4j model documentation
*/
-package org.eclipse.rdf4j.model;
\ No newline at end of file
+package org.eclipse.rdf4j.model;
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/GetStatementOptional.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/GetStatementOptional.java
index 75637293f3d..71cb378d912 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/GetStatementOptional.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/GetStatementOptional.java
@@ -16,7 +16,7 @@
/**
* Either supplies a statement matching the given pattern, or {@link Optional#empty()} otherwise.
- *
+ *
* @author Peter Ansell
*/
@FunctionalInterface
@@ -24,7 +24,7 @@ public interface GetStatementOptional {
/**
* Either supplies a statement matching the given pattern, or {@link Optional#empty()} otherwise.
- *
+ *
* @param subject A {@link Resource} to be used to match to statements.
* @param predicate An {@link IRI} to be used to match to statements.
* @param object A {@link Value} to be used to match to statements.
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/LexicalValueComparator.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/LexicalValueComparator.java
index 6bfdbd26271..ef7c944aa20 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/LexicalValueComparator.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/LexicalValueComparator.java
@@ -15,13 +15,14 @@
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
/**
* A lexical rdf term Comparator, this class does not compare numerically and is therefore a bit faster than a SPARQL
* compliant comparator.
- *
+ *
* @author james
* @author Arjohn Kampman
*/
@@ -71,7 +72,20 @@ public int compare(Value o1, Value o2) {
}
// 4. RDF literals
- return compareLiterals((Literal) o1, (Literal) o2);
+ boolean l1 = o1 instanceof Literal;
+ boolean l2 = o2 instanceof Literal;
+ if (l1 && l2) {
+ return compareLiterals((Literal) o1, (Literal) o2);
+ }
+ if (l1) {
+ return -1;
+ }
+ if (l2) {
+ return 1;
+ }
+
+ // 5. RDF* triples
+ return compareTriples((Triple) o1, (Triple) o2);
}
private int compareBNodes(BNode leftBNode, BNode rightBNode) {
@@ -158,4 +172,15 @@ private int compareDatatypes(IRI leftDatatype, IRI rightDatatype) {
return compareURIs(leftDatatype, rightDatatype);
}
}
-}
\ No newline at end of file
+
+ private int compareTriples(Triple leftTriple, Triple rightTriple) {
+ int c = compare(leftTriple.getSubject(), rightTriple.getSubject());
+ if (c == 0) {
+ c = compare(leftTriple.getPredicate(), rightTriple.getPredicate());
+ if (c == 0) {
+ c = compare(leftTriple.getObject(), rightTriple.getObject());
+ }
+ }
+ return c;
+ }
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/LiteralUtilException.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/LiteralUtilException.java
index 9a058023d24..2306094be76 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/LiteralUtilException.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/LiteralUtilException.java
@@ -11,7 +11,7 @@
/**
* An exception thrown by {@link Literals} when specific conditions are not met.
- *
+ *
* @author Peter Ansell
*/
public class LiteralUtilException extends RDF4JException {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Literals.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Literals.java
index 550a62a9576..2d4d1e8f6ef 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Literals.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Literals.java
@@ -25,7 +25,7 @@
/**
* Various utility methods related to {@link Literal}.
- *
+ *
* @author Arjohn Kampman
* @author Peter Ansell
*/
@@ -34,7 +34,7 @@ public class Literals {
/**
* Gets the label of the supplied literal. The fallback value is returned in case the supplied literal is
* null.
- *
+ *
* @param l The literal to get the label for.
* @param fallback The value to fall back to in case the supplied literal is null.
* @return Either the literal's label, or the fallback value.
@@ -54,7 +54,7 @@ public static String getLabel(Value v, String fallback) {
/**
* Gets the byte value of the supplied literal. The fallback value is returned in case {@link Literal#byteValue()}
* throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the byte value for.
* @param fallback The value to fall back to in case no byte value could gotten from the literal.
* @return Either the literal's byte value, or the fallback value.
@@ -82,7 +82,7 @@ public static byte getByteValue(Value v, byte fallback) {
/**
* Gets the short value of the supplied literal. The fallback value is returned in case {@link Literal#shortValue()}
* throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the short value for.
* @param fallback The value to fall back to in case no short value could gotten from the literal.
* @return Either the literal's short value, or the fallback value.
@@ -110,7 +110,7 @@ public static short getShortValue(Value v, short fallback) {
/**
* Gets the int value of the supplied literal. The fallback value is returned in case {@link Literal#intValue()}
* throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the int value for.
* @param fallback The value to fall back to in case no int value could gotten from the literal.
* @return Either the literal's int value, or the fallback value.
@@ -138,7 +138,7 @@ public static int getIntValue(Value v, int fallback) {
/**
* Gets the long value of the supplied literal. The fallback value is returned in case {@link Literal#longValue()}
* throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the long value for.
* @param fallback The value to fall back to in case no long value could gotten from the literal.
* @return Either the literal's long value, or the fallback value.
@@ -166,7 +166,7 @@ public static long getLongValue(Value v, long fallback) {
/**
* Gets the integer value of the supplied literal. The fallback value is returned in case
* {@link Literal#integerValue()} throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the integer value for.
* @param fallback The value to fall back to in case no integer value could gotten from the literal.
* @return Either the literal's integer value, or the fallback value.
@@ -194,7 +194,7 @@ public static BigInteger getIntegerValue(Value v, BigInteger fallback) {
/**
* Gets the decimal value of the supplied literal. The fallback value is returned in case
* {@link Literal#decimalValue()} throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the decimal value for.
* @param fallback The value to fall back to in case no decimal value could gotten from the literal.
* @return Either the literal's decimal value, or the fallback value.
@@ -222,7 +222,7 @@ public static BigDecimal getDecimalValue(Value v, BigDecimal fallback) {
/**
* Gets the float value of the supplied literal. The fallback value is returned in case {@link Literal#floatValue()}
* throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the float value for.
* @param fallback The value to fall back to in case no float value could gotten from the literal.
* @return Either the literal's float value, or the fallback value.
@@ -250,7 +250,7 @@ public static float getFloatValue(Value v, float fallback) {
/**
* Gets the double value of the supplied literal. The fallback value is returned in case
* {@link Literal#doubleValue()} throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the double value for.
* @param fallback The value to fall back to in case no double value could gotten from the literal.
* @return Either the literal's double value, or the fallback value.
@@ -278,7 +278,7 @@ public static double getDoubleValue(Value v, double fallback) {
/**
* Gets the boolean value of the supplied literal. The fallback value is returned in case
* {@link Literal#booleanValue()} throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the boolean value for.
* @param fallback The value to fall back to in case no boolean value could gotten from the literal.
* @return Either the literal's boolean value, or the fallback value.
@@ -306,7 +306,7 @@ public static boolean getBooleanValue(Value v, boolean fallback) {
/**
* Gets the calendar value of the supplied literal. The fallback value is returned in case
* {@link Literal#calendarValue()} throws a {@link NumberFormatException}.
- *
+ *
* @param l The literal to get the calendar value for.
* @param fallback The value to fall back to in case no calendar value could gotten from the literal.
* @return Either the literal's calendar value, or the fallback value.
@@ -322,7 +322,7 @@ public static XMLGregorianCalendar getCalendarValue(Literal l, XMLGregorianCalen
/**
* Gets the {@link Duration} value of the supplied literal. The fallback value is returned in case
* {@link XMLDatatypeUtil#parseDuration(String)} throws an exception.
- *
+ *
* @param l The literal to get the {@link Duration} value for.
* @param fallback The value to fall back to in case no Duration value could gotten from the literal.
* @return Either the literal's Duration value, or the fallback value.
@@ -353,7 +353,7 @@ public static XMLGregorianCalendar getCalendarValue(Value v, XMLGregorianCalenda
* representation of the supplied object as the value, and {@link XMLSchema#STRING} as the datatype. Recognized
* types are {@link Boolean}, {@link Byte}, {@link Double}, {@link Float}, {@link Integer}, {@link Long},
* {@link Short}, {@link XMLGregorianCalendar } , and {@link Date}.
- *
+ *
* @param valueFactory
* @param object an object to be converted to a typed literal.
* @return a typed literal representation of the supplied object.
@@ -373,7 +373,7 @@ public static Literal createLiteral(ValueFactory valueFactory, Object object) {
* appropriate XML Schema type. If no mapping is available, the method throws a {@link LiteralUtilException}.
* Recognized types are {@link Boolean}, {@link Byte}, {@link Double}, {@link Float}, {@link Integer}, {@link Long},
* {@link Short}, {@link XMLGregorianCalendar } , and {@link Date}.
- *
+ *
* @param valueFactory
* @param object an object to be converted to a typed literal.
* @return a typed literal representation of the supplied object.
@@ -391,7 +391,7 @@ public static Literal createLiteralOrFail(ValueFactory valueFactory, Object obje
* value, and {@link XMLSchema#STRING} as the datatype. Recognized types are {@link Boolean}, {@link Byte},
* {@link Double}, {@link Float}, {@link Integer}, {@link Long}, {@link Short}, {@link XMLGregorianCalendar } , and
* {@link Date}.
- *
+ *
* @param valueFactory The {@link ValueFactory} to use when creating the result.
* @param object an object to be converted to a typed literal.
* @param throwExceptionOnFailure If true throws a {@link LiteralUtilException} when the object is not recognised.
@@ -436,7 +436,7 @@ private static Literal createLiteral(ValueFactory valueFactory, Object object, b
/**
* Helper method for determining whether a literal could be created from an object using a {@link ValueFactory}.
- *
+ *
* @param object an object to check for the possibility of being converted to a typed literal.
* @return True if a literal could be created from the given object, based solely on its type and the methods
* available on the {@link ValueFactory} interface and false otherwise. Returns false if the object is null.
@@ -461,7 +461,7 @@ public static boolean canCreateLiteral(Object object) {
/**
* Helper method to determine whether a literal is a language literal, and not a typed literal.
- *
+ *
* @param literal The literal to check
* @return True if the literal has a language tag attached to it and false otherwise.
*/
@@ -472,7 +472,7 @@ public static boolean isLanguageLiteral(Literal literal) {
/**
* Normalizes the given BCP47 language tag according to the rules
* defined by the JDK in the {@link Locale} API.
- *
+ *
* @param languageTag An unnormalized, valid, language tag
* @return A normalized version of the given language tag
* @throws IllformedLocaleException If the given language tag is ill-formed according to the rules specified in
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelBuilder.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelBuilder.java
index edfd312c4bd..3337c90446c 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelBuilder.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelBuilder.java
@@ -36,14 +36,14 @@
* a {@link ModelBuilder} return an immutable reference to the current object, allowing method chaining.
*
* Usage example:
- *
+ *
*
*
* ModelBuilder builder = new ModelBuilder();
- *
+ *
* // set some namespaces
* builder.setNamespace("ex", "http://example.org/").setNamespace(FOAF.NS);
- *
+ *
* // add a new named graph to the model
* builder.namedGraph("ex:graph1")
* // add statements about resource ex:john
@@ -51,15 +51,15 @@
* .add(FOAF.NAME, "John") // add the triple (ex:john, foaf:name "John") to the named graph
* .add(FOAF.AGE, 42)
* .add(FOAF.MBOX, "john@example.org");
- *
+ *
* // add a triple to the default graph
* builder.defaultGraph().subject("ex:graph1").add(RDF.TYPE, "ex:Graph");
- *
+ *
* // return the Model object
* Model m = builder.build();
*
*
- *
+ *
* @author Jeen Broekstra
*/
public class ModelBuilder {
@@ -86,7 +86,7 @@ public ModelBuilder(Model model) {
/**
* Set the supplied {@link Namespace} mapping.
- *
+ *
* @param ns a {@link Namespace} to add to the model
* @return the {@link ModelBuilder}
*/
@@ -97,7 +97,7 @@ public ModelBuilder setNamespace(Namespace ns) {
/**
* Set the namespace mapping defined by the supplied prefix and name
- *
+ *
* @param prefix prefix of the namespace to add to the model.
* @param namespace namespace name to add to the model.
* @return the {@link ModelBuilder}
@@ -109,7 +109,7 @@ public ModelBuilder setNamespace(String prefix, String namespace) {
/**
* Set the subject resource about which statements are to be added to the model.
- *
+ *
* @param subject the subject resource about which statements are to be added.
* @return the {@link ModelBuilder}
*/
@@ -121,7 +121,7 @@ public ModelBuilder subject(Resource subject) {
/**
* Set the subject about which statements are to be added to the model, defined by a prefixed name or an IRI
* reference.
- *
+ *
* @param prefixedNameOrIri the subject resource about which statements are to be added. This can be defined either
* as a prefixed name string (e.g. "ex:john"), or as a full IRI (e.g.
* "http://example.org/john"). If supplied as a prefixed name, the {@link ModelBuilder}
@@ -135,7 +135,7 @@ public ModelBuilder subject(String prefixedNameOrIri) {
/**
* Set the current graph in which to add new statements to the supplied named graph. This method resets the current
* subject.
- *
+ *
* @param namedGraph a named graph identifier
* @return this {@link ModelBuilder}
*/
@@ -148,7 +148,7 @@ public ModelBuilder namedGraph(Resource namedGraph) {
/**
* Set the current graph in which to add new statements to the supplied named graph. This method clears the current
* subject.
- *
+ *
* @param prefixedNameOrIRI a named graph identifier. This can be defined either as a prefixed name string (e.g.
* "ex:john"), or as a full IRI (e.g. "http://example.org/john"). If supplied as a prefixed
* name, the {@link ModelBuilder} will need to have a namespace mapping for the prefix.
@@ -161,7 +161,7 @@ public ModelBuilder namedGraph(String prefixedNameOrIRI) {
/**
* Set the current graph in which to add new statements to the default graph. This method clears the current
* subject.
- *
+ *
* @return this {@link ModelBuilder}
*/
public ModelBuilder defaultGraph() {
@@ -173,7 +173,7 @@ public ModelBuilder defaultGraph() {
/**
* Add an RDF statement with the given subject, predicate and object to the model, using the current graph (either
* named or default).
- *
+ *
* @param subject the statement's subject
* @param predicate the statement's predicate
* @param object the statement's object. If the supplied object is a {@link BNode}, {@link IRI}, or
@@ -214,7 +214,7 @@ public ModelBuilder add(Resource subject, IRI predicate, Object object) {
/**
* Add an RDF statement with the given subject, predicate and object to the model, using the current graph (either
* named or default).
- *
+ *
* @param subject the statement's subject. This can be defined either as a prefixed name string (e.g. "ex:john"),
* or as a full IRI (e.g. "http://example.org/john"). If supplied as a prefixed name, the
* {@link ModelBuilder} will need to have a namespace mapping for the prefix.
@@ -239,7 +239,7 @@ public ModelBuilder add(String subject, IRI predicate, Object object) {
/**
* Add an RDF statement with the given subject, predicate and object to the model, using the current graph (either
* named or default).
- *
+ *
* @param subject the statement's subject. This can be defined either as a prefixed name string (e.g. "ex:john"),
* or as a full IRI (e.g. "http://example.org/john"). If supplied as a prefixed name, the
* {@link ModelBuilder} will need to have a namespace mapping for the prefix.
@@ -266,7 +266,7 @@ public ModelBuilder add(String subject, String predicate, Object object) {
/**
* Add an RDF statement with the predicate and object to the model, using the current subject and graph (either
* named or default).
- *
+ *
* @param predicate the statement's predicate.
* @param object the statement's object. If the supplied object is a {@link BNode}, {@link IRI}, or
* {@link Literal}, the object is used directly. If it is a prefixed name String with a known
@@ -290,7 +290,7 @@ public ModelBuilder add(IRI predicate, Object object) {
/**
* Add an RDF statement with the predicate and object to the model, using the current subject and graph (either
* named or default).
- *
+ *
* @param predicate the statement's predicate. This can be defined either as a prefixed name string (e.g.
* "ex:john"), or as a full IRI (e.g. "http://example.org/john"). If supplied as a prefixed name,
* the {@link ModelBuilder} will need to have a namespace mapping for the prefix.
@@ -312,7 +312,7 @@ public ModelBuilder add(String predicate, Object object) {
/**
* Return the created {@link Model}
- *
+ *
* @return the {@link Model}
*/
public Model build() {
@@ -321,7 +321,7 @@ public Model build() {
/**
* Convert the given prefixed name string to an IRI if possible.
- *
+ *
* @param prefixedName a prefixed name string, e.g. "rdf:type"
* @return the IRI corresponding to the prefixed name, or {@code null} if the supplied string couldn't be converted.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelCollector.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelCollector.java
index 0973c4e0133..740cda090ad 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelCollector.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelCollector.java
@@ -18,13 +18,13 @@
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.ModelFactory;
import org.eclipse.rdf4j.model.Statement;
-import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory;
+import org.eclipse.rdf4j.model.impl.DynamicModelFactory;
import org.eclipse.rdf4j.model.impl.TreeModelFactory;
/**
* Collects a stream of Statements into a Model. By default a {@link org.eclipse.rdf4j.model.impl.LinkedHashModel
* LinkedHashModel} will be returned.
- *
+ *
* @author Bart Hanssens
*/
public class ModelCollector implements Collector {
@@ -34,12 +34,12 @@ public class ModelCollector implements Collector {
* Constructor
*/
public ModelCollector() {
- this.factory = new LinkedHashModelFactory();
+ this.factory = new DynamicModelFactory();
}
/**
* Constructor
- *
+ *
* @param factory
*/
public ModelCollector(ModelFactory factory) {
@@ -48,7 +48,7 @@ public ModelCollector(ModelFactory factory) {
/**
* Convenience method to obtain a ModelCollector.
- *
+ *
* @return a ModelCollector
*/
public static ModelCollector toModel() {
@@ -57,7 +57,7 @@ public static ModelCollector toModel() {
/**
* Convenience method to obtain a ModelCollector, which will return a TreeModel.
- *
+ *
* @return a ModelCollector
*/
public static ModelCollector toTreeModel() {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelException.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelException.java
index b22336f0afd..0c2d10c4227 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelException.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/ModelException.java
@@ -13,7 +13,7 @@
/**
* An exception thrown by {@link org.eclipse.rdf4j.model.Model Model} and {@link org.eclipse.rdf4j.model.util.Models
* Models} when specific conditions are not met.
- *
+ *
* @author Arjohn Kampman
*/
public class ModelException extends RDF4JException {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java
index b847ea5c4e9..cfcfc237ae3 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java
@@ -20,18 +20,26 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
+import org.eclipse.rdf4j.common.annotation.Experimental;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.ModelFactory;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.DynamicModelFactory;
import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
/**
* Utility functions for working with {@link Model}s and other {@link Statement} collections.
@@ -49,44 +57,111 @@ public class Models {
protected Models() {
}
+ /**
+ * Retrieves an object {@link Value} from the supplied statements. If more than one possible object value exists,
+ * any one value is picked and returned.
+ *
+ * @param statements the {@link Statement } {@link Iterable} from which to retrieve an object value.
+ * @return an object value from the given statement collection, or {@link Optional#empty()} if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #object(Model)}.
+ */
+ public static Optional object(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false).map(st -> st.getObject()).findAny();
+ }
+
/**
* Retrieves an object {@link Value} from the statements in the given model. If more than one possible object value
* exists, any one value is picked and returned.
*
* @param m the model from which to retrieve an object value.
* @return an object value from the given model, or {@link Optional#empty()} if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #object(Iterable)}. This method signature kept for binary
+ * compatibility.
+ *
*/
public static Optional object(Model m) {
- return m.stream().map(st -> st.getObject()).findAny();
+ return object((Iterable) m);
+ }
+
+ /**
+ * Retrieves an object {@link Literal} value from the supplied statements. If more than one possible Literal value
+ * exists, any one Literal value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve an object Literal value.
+ * @return an object Literal value from the given model, or {@link Optional#empty()} if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectLiteral(Model)}.
+ */
+ public static Optional objectLiteral(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getObject())
+ .filter(o -> o instanceof Literal)
+ .map(l -> (Literal) l)
+ .findAny();
}
/**
* Retrieves an object {@link Literal} value from the statements in the given model. If more than one possible
* Literal value exists, any one Literal value is picked and returned.
*
- * @param m the model from which to retrieve an object Literal value.
+ * @param m the {@link Model} from which to retrieve an object Literal value.
* @return an object Literal value from the given model, or {@link Optional#empty()} if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectLiteral(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional objectLiteral(Model m) {
- return m.stream().map(st -> st.getObject()).filter(o -> o instanceof Literal).map(l -> (Literal) l).findAny();
+ return objectLiteral((Iterable) m);
}
/**
- * Retrieves all object {@link Literal} values from the statements in the given model.
+ * Retrieves all object {@link Literal} values from the supplied statements.
*
- * @param m the model from which to retrieve all object {@link Literal} values.
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve all object {@link Literal}
+ * values.
* @return a {@link Set} containing object {@link Literal} values from the given model, which will be empty if no
* such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectLiterals(Model)}.
* @see Model#objects()
*/
- public static Set objectLiterals(Model m) {
- return m.stream()
+ public static Set objectLiterals(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
.map(st -> st.getObject())
.filter(o -> o instanceof Literal)
.map(l -> (Literal) l)
.collect(Collectors.toSet());
}
+ /**
+ * Retrieves all object {@link Literal} values from the statements in the given model.
+ *
+ * @param m the model from which to retrieve all object {@link Literal} values.
+ * @return a {@link Set} containing object {@link Literal} values from the given model, which will be empty if no
+ * such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectLiterals(Iterable)}. This method signature kept
+ * for binary compatibility.
+ *
+ * @see Model#objects()
+ */
+ public static Set objectLiterals(Model m) {
+ return objectLiterals((Iterable) m);
+ }
+
+ /**
+ * Retrieves an object {@link Resource} value from the supplied statements. If more than one possible Resource value
+ * exists, any one Resource value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve an object Resource value.
+ * @return an {@link Optional} object Resource value from the given model, which will be {@link Optional#empty()
+ * empty} if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectResource(Model)}.
+ */
+ public static Optional objectResource(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getObject())
+ .filter(o -> o instanceof Resource)
+ .map(r -> (Resource) r)
+ .findAny();
+ }
+
/**
* Retrieves an object {@link Resource} value from the statements in the given model. If more than one possible
* Resource value exists, any one Resource value is picked and returned.
@@ -94,21 +169,25 @@ public static Set objectLiterals(Model m) {
* @param m the model from which to retrieve an object Resource value.
* @return an {@link Optional} object Resource value from the given model, which will be {@link Optional#empty()
* empty} if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectResource(Iterable)}. This method signature kept
+ * for binary compatibility.
*/
public static Optional objectResource(Model m) {
- return m.stream().map(st -> st.getObject()).filter(o -> o instanceof Resource).map(r -> (Resource) r).findAny();
+ return objectResource((Iterable) m);
}
/**
- * Retrieves all object {@link Resource} values from the statements in the given model.
+ * Retrieves all object {@link Resource} values from the supplied statements.
*
- * @param m the model from which to retrieve all object {@link Resource} values.
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve all object {@link Resource}
+ * values.
* @return a {@link Set} containing object {@link Resource} values from the given model, which will be empty if no
* such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectResources(Model)}.
* @see Model#objects()
*/
- public static Set objectResources(Model m) {
- return m.stream()
+ public static Set objectResources(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
.map(st -> st.getObject())
.filter(o -> o instanceof Resource)
.map(r -> (Resource) r)
@@ -116,33 +195,94 @@ public static Set objectResources(Model m) {
}
/**
- * Retrieves an object {@link IRI} value from the statements in the given model. If more than one possible IRI value
- * exists, any one value is picked and returned.
+ * Retrieves all object {@link Resource} values from the supplied model.
+ *
+ * @param m the {@link Model} from which to retrieve all object {@link Resource} values.
+ * @return a {@link Set} containing object {@link Resource} values from the given model, which will be empty if no
+ * such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectResources(Iterable)}. This method signature kept
+ * for binary compatibility.
+ * @see Model#objects()
+ */
+ public static Set objectResources(Model m) {
+ return objectResources((Iterable) m);
+ }
+
+ /**
+ * Retrieves an object {@link IRI} value from the supplied statements. If more than one possible IRI value exists,
+ * any one value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve an object IRI value.
+ * @return an {@link Optional} object IRI value from the given model, which will be {@link Optional#empty() empty}
+ * if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectIRI(Model)}.
+ */
+ public static Optional objectIRI(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getObject())
+ .filter(o -> o instanceof IRI)
+ .map(r -> (IRI) r)
+ .findAny();
+ }
+
+ /**
+ * Retrieves an object {@link IRI} value from the supplied statements in the given model. If more than one possible
+ * IRI value exists, any one value is picked and returned.
*
* @param m the model from which to retrieve an object IRI value.
* @return an {@link Optional} object IRI value from the given model, which will be {@link Optional#empty() empty}
* if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectIRI(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional objectIRI(Model m) {
- return m.stream().map(st -> st.getObject()).filter(o -> o instanceof IRI).map(r -> (IRI) r).findAny();
+ return objectIRI((Iterable) m);
}
/**
- * Retrieves all object {@link IRI} values from the statements in the given model.
+ * Retrieves all object {@link IRI} values from the supplied statements.
*
- * @param m the model from which to retrieve all object IRI values.
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve all object IRI values.
* @return a {@link Set} containing object IRI values from the given model, which will be empty if no such value
* exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectIRIs(Model)}.
* @see Model#objects()
*/
- public static Set objectIRIs(Model m) {
- return m.stream()
+ public static Set objectIRIs(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
.map(st -> st.getObject())
.filter(o -> o instanceof IRI)
.map(r -> (IRI) r)
.collect(Collectors.toSet());
}
+ /**
+ * Retrieves all object {@link IRI} values from the statements in the given model.
+ *
+ * @param m the {@link Model} from which to retrieve all object IRI values.
+ * @return a {@link Set} containing object IRI values from the given model, which will be empty if no such value
+ * exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectIRIs(Iterable)}. This method signature kept for
+ * binary compatibility.
+ * @see Model#objects()
+ */
+ public static Set objectIRIs(Model m) {
+ return objectIRIs((Iterable) m);
+ }
+
+ /**
+ * Retrieves an object value as a String from the supplied statements. If more than one possible object value
+ * exists, any one value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve an object String value.
+ * @return an {@link Optional} object String value from the given model, which will be {@link Optional#empty()
+ * empty} if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectString(Model)}.
+ */
+ public static Optional objectString(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false).map(st -> st.getObject().stringValue()).findAny();
+ }
+
/**
* Retrieves an object value as a String from the statements in the given model. If more than one possible object
* value exists, any one value is picked and returned.
@@ -150,9 +290,26 @@ public static Set objectIRIs(Model m) {
* @param m the model from which to retrieve an object String value.
* @return an {@link Optional} object String value from the given model, which will be {@link Optional#empty()
* empty} if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectString(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional objectString(Model m) {
- return m.stream().map(st -> st.getObject().stringValue()).findAny();
+ return objectString((Iterable) m);
+ }
+
+ /**
+ * Retrieves all object String values from the supplied statements.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve all object String values.
+ * @return a {@link Set} containing object String values from the given model, which will be empty if no such value
+ * exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #objectStrings(Model)}.
+ * @see Model#objects()
+ */
+ public static Set objectStrings(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getObject().stringValue())
+ .collect(Collectors.toSet());
}
/**
@@ -161,10 +318,25 @@ public static Optional objectString(Model m) {
* @param m the model from which to retrieve all object String values.
* @return a {@link Set} containing object String values from the given model, which will be empty if no such value
* exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #objectStrings(Iterable)}. This method signature kept for
+ * binary compatibility.
* @see Model#objects()
*/
public static Set objectStrings(Model m) {
- return m.stream().map(st -> st.getObject().stringValue()).collect(Collectors.toSet());
+ return objectStrings((Iterable) m);
+ }
+
+ /**
+ * Retrieves a subject {@link Resource} from the supplied statements. If more than one possible resource value
+ * exists, any one resource value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a subject Resource.
+ * @return an {@link Optional} subject resource from the given model, which will be {@link Optional#empty() empty}
+ * if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #subject(Model)}.
+ */
+ public static Optional subject(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false).map(st -> st.getSubject()).findAny();
}
/**
@@ -174,9 +346,28 @@ public static Set objectStrings(Model m) {
* @param m the model from which to retrieve a subject Resource.
* @return an {@link Optional} subject resource from the given model, which will be {@link Optional#empty() empty}
* if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #subject(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional subject(Model m) {
- return m.stream().map(st -> st.getSubject()).findAny();
+ return subject((Iterable) m);
+ }
+
+ /**
+ * Retrieves a subject {@link IRI} from the supplied statements. If more than one possible IRI value exists, any one
+ * IRI value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a subject IRI value.
+ * @return an {@link Optional} subject IRI value from the given model, which will be {@link Optional#empty() empty}
+ * if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #subjectIRI(Model)}.
+ */
+ public static Optional subjectIRI(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getSubject())
+ .filter(s -> s instanceof IRI)
+ .map(s -> (IRI) s)
+ .findAny();
}
/**
@@ -186,9 +377,26 @@ public static Optional subject(Model m) {
* @param m the model from which to retrieve a subject IRI value.
* @return an {@link Optional} subject IRI value from the given model, which will be {@link Optional#empty() empty}
* if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #subjectIRI(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional subjectIRI(Model m) {
- return m.stream().map(st -> st.getSubject()).filter(s -> s instanceof IRI).map(s -> (IRI) s).findAny();
+ return subjectIRI((Iterable) m);
+ }
+
+ /**
+ * Retrieves all subject {@link IRI}s from the supplied statements.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a subject IRI value.
+ * @return a {@link Set} of subject IRI values from the given model. The returned Set may be empty.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #subjectIRIs(Model)}.
+ */
+ public static Set subjectIRIs(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getSubject())
+ .filter(o -> o instanceof IRI)
+ .map(r -> (IRI) r)
+ .collect(Collectors.toSet());
}
/**
@@ -196,9 +404,28 @@ public static Optional subjectIRI(Model m) {
*
* @param m the model from which to retrieve a subject IRI value.
* @return a {@link Set} of subject IRI values from the given model. The returned Set may be empty.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #subjectIRIs(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Set subjectIRIs(Model m) {
- return m.subjects().stream().filter(s -> s instanceof IRI).map(s -> (IRI) s).collect(Collectors.toSet());
+ return subjectIRIs((Iterable) m);
+ }
+
+ /**
+ * Retrieves a subject {@link BNode} from the supplied statements. If more than one possible blank node value
+ * exists, any one blank node value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a subject BNode value.
+ * @return an {@link Optional} subject BNode value from the given model, which will be {@link Optional#empty()
+ * empty} if no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #subjectBNode(Model)}.
+ */
+ public static Optional subjectBNode(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getSubject())
+ .filter(s -> s instanceof BNode)
+ .map(s -> (BNode) s)
+ .findAny();
}
/**
@@ -208,9 +435,26 @@ public static Set subjectIRIs(Model m) {
* @param m the model from which to retrieve a subject BNode value.
* @return an {@link Optional} subject BNode value from the given model, which will be {@link Optional#empty()
* empty} if no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #subjectBNode(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional subjectBNode(Model m) {
- return m.stream().map(st -> st.getSubject()).filter(s -> s instanceof BNode).map(s -> (BNode) s).findAny();
+ return subjectBNode((Iterable) m);
+ }
+
+ /**
+ * Retrieves all subject {@link BNode}s from the supplied statements.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a subject IRI value.
+ * @return a {@link Set} of subject {@link BNode} values from the given model. The returned Set may be empty.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #subjectBNodes(Model)}.
+ */
+ public static Set subjectBNodes(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false)
+ .map(st -> st.getSubject())
+ .filter(o -> o instanceof BNode)
+ .map(r -> (BNode) r)
+ .collect(Collectors.toSet());
}
/**
@@ -218,9 +462,24 @@ public static Optional subjectBNode(Model m) {
*
* @param m the model from which to retrieve a subject IRI value.
* @return a {@link Set} of subject {@link BNode} values from the given model. The returned Set may be empty.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #subjectBNodes(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Set subjectBNodes(Model m) {
- return m.subjects().stream().filter(s -> s instanceof BNode).map(s -> (BNode) s).collect(Collectors.toSet());
+ return subjectBNodes((Iterable) m);
+ }
+
+ /**
+ * Retrieves a predicate from the supplied statements. If more than one possible predicate value exists, any one
+ * value is picked and returned.
+ *
+ * @param statements the {@link Statement} {@link Iterable} from which to retrieve a predicate value.
+ * @return an {@link Optional} predicate value from the given model, which will be {@link Optional#empty() empty} if
+ * no such value exists.
+ * @apiNote this method signature is new in 3.2.0, and is a generalization of {@link #predicate(Model)}.
+ */
+ public static Optional predicate(Iterable statements) {
+ return StreamSupport.stream(statements.spliterator(), false).map(st -> st.getPredicate()).findAny();
}
/**
@@ -230,9 +489,11 @@ public static Set subjectBNodes(Model m) {
* @param m the model from which to retrieve a predicate value.
* @return an {@link Optional} predicate value from the given model, which will be {@link Optional#empty() empty} if
* no such value exists.
+ * @apiNote replaced in 3.2.0 with the more generic {@link #predicate(Iterable)}. This method signature kept for
+ * binary compatibility.
*/
public static Optional predicate(Model m) {
- return m.stream().map(st -> st.getPredicate()).findAny();
+ return predicate((Iterable) m);
}
/**
@@ -275,7 +536,7 @@ public static Optional getProperty(Model m, Resource subject, IRI propert
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return object(m.filter(subject, property, null, contexts));
+ return object(m.getStatements(subject, property, null, contexts));
}
/**
@@ -311,7 +572,7 @@ public static Optional getPropertyResource(Model m, Resource subject,
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectResource(m.filter(subject, property, null, contexts));
+ return objectResource(m.getStatements(subject, property, null, contexts));
}
/**
@@ -328,7 +589,7 @@ public static Set getPropertyResources(Model m, Resource subject, IRI
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectResources(m.filter(subject, property, null, contexts));
+ return objectResources(m.getStatements(subject, property, null, contexts));
}
/**
@@ -346,7 +607,7 @@ public static Optional getPropertyIRI(Model m, Resource subject, IRI proper
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectIRI(m.filter(subject, property, null, contexts));
+ return objectIRI(m.getStatements(subject, property, null, contexts));
}
/**
@@ -363,7 +624,7 @@ public static Set getPropertyIRIs(Model m, Resource subject, IRI property,
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectIRIs(m.filter(subject, property, null, contexts));
+ return objectIRIs(m.getStatements(subject, property, null, contexts));
}
/**
@@ -381,7 +642,7 @@ public static Optional getPropertyLiteral(Model m, Resource subject, IR
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectLiteral(m.filter(subject, property, null, contexts));
+ return objectLiteral(m.getStatements(subject, property, null, contexts));
}
/**
@@ -398,7 +659,7 @@ public static Set getPropertyLiterals(Model m, Resource subject, IRI pr
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectLiterals(m.filter(subject, property, null, contexts));
+ return objectLiterals(m.getStatements(subject, property, null, contexts));
}
/**
@@ -416,7 +677,7 @@ public static Optional getPropertyString(Model m, Resource subject, IRI
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectString(m.filter(subject, property, null, contexts));
+ return objectString(m.getStatements(subject, property, null, contexts));
}
/**
@@ -433,7 +694,7 @@ public static Set getPropertyStrings(Model m, Resource subject, IRI prop
Objects.requireNonNull(m, "model may not be null");
Objects.requireNonNull(subject, "subject may not be null");
Objects.requireNonNull(property, "property may not be null");
- return objectStrings(m.filter(subject, property, null, contexts));
+ return objectStrings(m.getStatements(subject, property, null, contexts));
}
/**
@@ -507,7 +768,216 @@ public static Model stripContexts(Model model, Resource... contexts) {
} else {
return st;
}
- }).collect(Collectors.toCollection(LinkedHashModel::new));
+ }).collect(ModelCollector.toModel());
+ }
+
+ /**
+ * Creates a {@link Supplier} of {@link ModelException} objects that be passed to
+ * {@link Optional#orElseThrow(Supplier)} to generate exceptions as necessary.
+ *
+ * @param message The message to be used for the exception
+ * @return A {@link Supplier} that will create {@link ModelException} objects with the given message.
+ */
+ public static Supplier modelException(String message) {
+ return () -> new ModelException(message);
+ }
+
+ /**
+ * Make a model thread-safe by synchronizing all its methods. Iterators will still not be thread-safe!
+ *
+ * @param toSynchronize the model that should be synchronized
+ * @return Synchronized Model
+ */
+ public static Model synchronizedModel(Model toSynchronize) {
+ return new SynchronizedModel(toSynchronize);
+ }
+
+ /**
+ * Converts the supplied RDF* model to RDF reification statements. The converted statements are sent to the supplied
+ * consumer function.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertRDFStarToReification(ValueFactory vf, Model model, Consumer consumer) {
+ model.forEach(st -> Statements.convertRDFStarToReification(vf, st, consumer));
+ }
+
+ /**
+ * Converts the supplied RDF* model to RDF reification statements. The converted statements are sent to the supplied
+ * consumer function.
+ *
+ * @param model the {@link Model} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertRDFStarToReification(Model model, Consumer consumer) {
+ convertRDFStarToReification(SimpleValueFactory.getInstance(), model, consumer);
+ }
+
+ /**
+ * Converts the statements in supplied RDF* model to a new RDF model using reificiation.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @return a new {@link Model} with RDF* statements converted to reified triples.
+ */
+ @Experimental
+ public static Model convertRDFStarToReification(ValueFactory vf, Model model) {
+ Model reificationModel = new LinkedHashModel();
+ convertRDFStarToReification(vf, model, (Consumer) reificationModel::add);
+ return reificationModel;
+ }
+
+ /**
+ * Converts the statements in supplied RDF* model to a new RDF model using reificiation.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @param modelFactory the {@link ModelFactory} used to create the new output {@link Model}.
+ * @return a new {@link Model} with RDF* statements converted to reified triples.
+ */
+ @Experimental
+ public static Model convertRDFStarToReification(ValueFactory vf, Model model, ModelFactory modelFactory) {
+ Model reificationModel = modelFactory.createEmptyModel();
+ convertRDFStarToReification(vf, model, (Consumer) reificationModel::add);
+ return reificationModel;
+ }
+
+ /**
+ * Converts the statements in the supplied RDF* model to a new RDF model using reification.
+ *
+ * @param model the {@link Model} to convert.
+ * @return a new {@link Model} with RDF* statements converted to reified triples.
+ */
+ @Experimental
+ public static Model convertRDFStarToReification(Model model) {
+ return convertRDFStarToReification(SimpleValueFactory.getInstance(), model);
+ }
+
+ /**
+ * Converts the supplied RDF reification model to RDF* statements. The converted statements are sent to the supplied
+ * consumer function.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertReificationToRDFStar(ValueFactory vf, Model model, Consumer consumer) {
+ Map convertedStatements = new HashMap<>();
+ model.filter(null, RDF.TYPE, RDF.STATEMENT).forEach((s) -> {
+ Value subject = object(model.filter(s.getSubject(), RDF.SUBJECT, null)).orElse(null);
+ if (!(subject instanceof IRI) && !(subject instanceof BNode)) {
+ return;
+ }
+ Value predicate = object(model.filter(s.getSubject(), RDF.PREDICATE, null)).orElse(null);
+ if (!(predicate instanceof IRI)) {
+ return;
+ }
+ Value object = object(model.filter(s.getSubject(), RDF.OBJECT, null)).orElse(null);
+ if (!(object instanceof Value)) {
+ return;
+ }
+ Triple t = vf.createTriple((Resource) subject, (IRI) predicate, object);
+ convertedStatements.put(s.getSubject(), t);
+ });
+
+ for (Map.Entry e : convertedStatements.entrySet()) {
+ Triple t = e.getValue();
+ Resource subject = convertedStatements.get(t.getSubject());
+ Resource object = convertedStatements.get(t.getObject());
+ if (subject != null || object != null) {
+ // Triples within triples, replace them in the map
+ Triple nt = vf.createTriple(subject != null ? subject : t.getSubject(), t.getPredicate(),
+ object != null ? object : t.getObject());
+ e.setValue(nt);
+ }
+ }
+
+ model.forEach((s) -> {
+ Resource subject = s.getSubject();
+ IRI predicate = s.getPredicate();
+ Value object = s.getObject();
+ Triple subjectTriple = convertedStatements.get(subject);
+ Triple objectTriple = convertedStatements.get(object);
+
+ if (subjectTriple == null && objectTriple == null) {
+ // Statement not part of detected reification, add it as is
+ consumer.accept(s);
+ } else if (subjectTriple == null || ((!RDF.TYPE.equals(predicate) || !RDF.STATEMENT.equals(object))
+ && !RDF.SUBJECT.equals(predicate) && !RDF.PREDICATE.equals(predicate)
+ && !RDF.OBJECT.equals(predicate))) {
+ // Statement uses reified data and needs to be converted
+ Statement ns = vf.createStatement(subjectTriple != null ? subjectTriple : s.getSubject(),
+ s.getPredicate(), objectTriple != null ? objectTriple : s.getObject(), s.getContext());
+ consumer.accept(ns);
+ } // else: Statement part of reification and needs to be removed (skipped)
+ });
+ }
+
+ /**
+ * Converts the supplied RDF reification model to RDF* statements. The converted statements are sent to the supplied
+ * consumer function.
+ *
+ * @param model the {@link Model} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertReificationToRDFStar(Model model, Consumer consumer) {
+ convertReificationToRDFStar(SimpleValueFactory.getInstance(), model, consumer);
+ }
+
+ /**
+ * Converts the statements in supplied RDF reification model to a new RDF* model.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @param modelFactory the {@link ModelFactory} to use for creating a new Model object for the output.
+ * @return a new {@link Model} with reification statements converted to RDF* {@link Triple}s.
+ */
+ @Experimental
+ public static Model convertReificationToRDFStar(ValueFactory vf, Model model, ModelFactory modelFactory) {
+ Model rdfStarModel = modelFactory.createEmptyModel();
+ convertReificationToRDFStar(vf, model, (Consumer) rdfStarModel::add);
+ return rdfStarModel;
+ }
+
+ /**
+ * Converts the statements in supplied RDF reification model to a new RDF* model.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param model the {@link Model} to convert.
+ * @return a new {@link Model} with reification statements converted to RDF* {@link Triple}s.
+ */
+ @Experimental
+ public static Model convertReificationToRDFStar(ValueFactory vf, Model model) {
+ return convertReificationToRDFStar(vf, model, new DynamicModelFactory());
+ }
+
+ /**
+ * Converts the supplied RDF reification model to a new RDF* model.
+ *
+ * @param model the {@link Model} to convert.
+ * @return a new {@link Model} with reification statements converted to RDF* {@link Triple}s.
+ */
+ @Experimental
+ public static Model convertReificationToRDFStar(Model model) {
+ return convertReificationToRDFStar(SimpleValueFactory.getInstance(), model);
}
private static boolean isSubsetInternal(Set model1, Model model2) {
@@ -733,24 +1203,4 @@ private static Set toSet(Iterable extends Statement> iterable) {
}
- /**
- * Creates a {@link Supplier} of {@link ModelException} objects that be passed to
- * {@link Optional#orElseThrow(Supplier)} to generate exceptions as necessary.
- *
- * @param message The message to be used for the exception
- * @return A {@link Supplier} that will create {@link ModelException} objects with the given message.
- */
- public static Supplier modelException(String message) {
- return () -> new ModelException(message);
- }
-
- /**
- * Make a model thread-safe by synchronizing all its methods. Iterators will still not be thread-safe!
- *
- * @param toSynchronize the model that should be synchronized
- * @return Synchronized Model
- */
- public static Model synchronizedModel(Model toSynchronize) {
- return new SynchronizedModel(toSynchronize);
- }
-}
\ No newline at end of file
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Namespaces.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Namespaces.java
index ad3ce64b4b0..27124aeb0f3 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Namespaces.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Namespaces.java
@@ -23,7 +23,7 @@
/**
* A utility class to perform operations on {@link Namespace}s.
- *
+ *
* @author Peter Ansell
*/
public class Namespaces {
@@ -31,7 +31,7 @@ public class Namespaces {
/**
* Converts a set of {@link Namespace}s into a map containing the {@link Namespace#getPrefix()} strings as keys,
* with the {@link Namespace#getName()} strings as values in the map for each namespace in the given set.
- *
+ *
* @param namespaces The {@link Set} of {@link Namespace}s to transform.
* @return A {@link Map} of {@link String} to {@link String} where the key/value combinations are created based on
* the prefix and names from {@link Namespace}s in the input set.
@@ -50,7 +50,7 @@ public static Map asMap(Set namespaces) {
* Wraps the given {@link Set} of {@link Namespace}s as a {@link Map} of prefix to URI mappings, so that it can be
* used where a {@link Map} is required by the API.
* NOTE: The Map returned by this method is not synchronized.
- *
+ *
* @param namespaces The Set to wrap.
* @return A Map of prefix to URI mappings which is backed by the given Set of {@link Namespace}s.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/PatternIterator.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/PatternIterator.java
index b7f2c41b5a8..272e5c70c6c 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/PatternIterator.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/PatternIterator.java
@@ -75,15 +75,16 @@ private void findNextElement() {
@Override
public void remove() {
- if (!nextCalled)
+ if (!nextCalled) {
throw new IllegalStateException();
+ }
filteredIter.remove();
}
/**
* Tests whether or not the specified statement should be returned by this iterator. All objects from the wrapped
* iterator pass through this method in the same order as they are coming from the wrapped iterator.
- *
+ *
* @param st The statement to be tested.
* @return true if the object should be returned, false otherwise.
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/RDFCollections.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/RDFCollections.java
index 430e05be809..6fa6aa22c9f 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/RDFCollections.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/RDFCollections.java
@@ -36,7 +36,7 @@
* using the {@link RDF#NIL} node.
*
* As an example, a list containing three literal values "A", "B", and "C" looks like this as an RDF Collection:
- *
+ *
*
* _:n1 -rdf:type--> rdf:List
* |
@@ -51,7 +51,7 @@
*
* Here, {@code _:n1} is the head resource of the list. Note that in this example it is declared an instance of
* {@link RDF#LIST}, however this is not required for the collection to be considered well-formed.
- *
+ *
* @author Jeen Broekstra
* @see RDF Schema 1.1 section on Collection
* vocabulary.
@@ -62,7 +62,7 @@ public class RDFCollections {
* Converts the supplied {@link Iterable} to an RDF
* Collection, using the supplied {@code head} resource as the starting resource of the RDF Collection. The
* statements making up the new RDF Collection will be added to the supplied statement collection.
- *
+ *
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Collection. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
@@ -92,7 +92,7 @@ public static > C asRDF(Iterable> values, Reso
* Converts the supplied {@link Iterable} to an RDF
* Collection, using the supplied {@code head} resource as the starting resource of the RDF Collection. The
* statements making up the new RDF Collection will be added to the supplied statement collection.
- *
+ *
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted
* to an RDF Collection. May not be {@code null}. The method attempts to convert each value that
* is not already an instance of {@link Value} to a {@link Literal}. This conversion will fail
@@ -113,7 +113,7 @@ public static > C asRDF(Iterable> values, Reso
* @throws LiteralUtilException if one of the supplied values can not be converted to a Literal.
* @see RDF Schema 1.1 section on Collection
* vocabulary.
- *
+ *
* @since 3.0
*/
public static > C asRDF(Iterable> values, Resource head, C sink,
@@ -128,7 +128,7 @@ public static > C asRDF(Iterable> values, Reso
* the supplied {@link Model} and {@code head}. This method expects the RDF Collection to be well-formed. If the
* collection is not well-formed the method may return part of the collection, or may throw a
* {@link ModelException}.
- *
+ *
* @param m the Model containing the collection to read.
* @param head the {@link Resource} that represents the list head, that is the start resource of the RDF
* Collection to be read. May not be {@code null}.
@@ -154,7 +154,7 @@ public static > C asValues(final Model m, Resource h
* Converts the supplied {@link Iterable} to an RDF
* Collection, using the supplied {@code head} resource as the starting resource of the RDF Collection. The
* statements making up the new RDF Collection will be reported to the supplied {@link Consumer} function.
- *
+ *
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Collection. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
@@ -180,7 +180,7 @@ public static void consumeCollection(Iterable> values, Resource head, Consumer
* Converts the supplied {@link Iterable} to an RDF
* Collection, using the supplied {@code head} resource as the starting resource of the RDF Collection. The
* statements making up the new RDF Collection will be reported to the supplied {@link Consumer} function.
- *
+ *
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Collection. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
@@ -197,7 +197,7 @@ public static void consumeCollection(Iterable> values, Resource head, Consumer
* @see RDF Schema 1.1 section on Collection
* vocabulary.
* @see Literals#createLiteralOrFail(ValueFactory, Object)
- *
+ *
* @since 3.0
*/
public static void consumeCollection(Iterable> values, Resource head, Consumer consumer,
@@ -231,7 +231,7 @@ public static void consumeCollection(Iterable> values, Resource head, Consumer
* collection member {@link Value} to the supplied {@link Consumer} function. This method expects the RDF Collection
* to be well-formed. If the collection is not well-formed the method may report only part of the collection, or may
* throw a {@link ModelException}.
- *
+ *
* @param m the Model containing the collection to read.
* @param head the {@link Resource} that represents the list head, that is the start resource of the RDF
* Collection to be read. May not be {@code null}.
@@ -262,7 +262,7 @@ public static void consumeValues(final Model m, Resource head, Consumer c
* Extracts the RDF Collection starting with the
* supplied {@code head} resource from the supplied source {@link Model}. The statements making up the RDF
* Collection will be added to the supplied statement collection, which will also be returned.
- *
+ *
* @param sourceModel the source model, containing the RDF Collection to be read.
* @param head the {@link Resource} that represents the list head, that is the start resource of the RDF
* Collection to be read. May not be {@code null}. a {@link Collection} of {@link Statement}
@@ -286,7 +286,7 @@ public static > C getCollection(Model sourceMode
* Extracts the RDF Collection starting with
* supplied {@code head} resource from the supplied source {@link Model} and sends the statements that make up the
* collection to the supplied {@link Consumer}.
- *
+ *
* @param sourceModel the source model, containing the RDF Collection to be read.
* @param head the {@link Resource} that represents the list head, that is the start resource of the RDF
* Collection to be read. May not be {@code null}. a {@link Collection} of {@link Statement}
@@ -309,7 +309,7 @@ public static void extract(Model sourceModel, Resource head, Consumer
* statements that make up the collection to the supplied {@link Consumer} function. This method expects the RDF
* Collection to be well-formed. If the collection is not well-formed the method may report only part of the
* collection, or may throw an exception.
- *
+ *
* @param statementSupplier the source of the statements from which the RDF collection is to be read, specified as
* a functional interface.
* @param head the {@link Resource} that represents the list head, that is the start resource of the
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Statements.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Statements.java
index 14066cf3d68..42029755330 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Statements.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Statements.java
@@ -7,17 +7,23 @@
*******************************************************************************/
package org.eclipse.rdf4j.model.util;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer;
+import java.util.function.Function;
import org.eclipse.rdf4j.OpenRDFUtil;
+import org.eclipse.rdf4j.common.annotation.Experimental;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
/**
* Utility methods for {@link Statement} objects.
@@ -26,11 +32,22 @@
*/
public class Statements {
+ /**
+ * A {@link Function} that maps {@link Triple} to {@link org.eclipse.rdf4j.model.BNode} consistently. Multiple
+ * invocations for the same {@link Triple} will return the same {@link org.eclipse.rdf4j.model.BNode}.
+ *
+ * The current implementation creates a {@link org.eclipse.rdf4j.model.BNode} by encoding the string representation
+ * of the {@link Triple} using base64 URL-safe encoding.
+ */
+ @Experimental
+ public static Function TRIPLE_BNODE_MAPPER = (t) -> SimpleValueFactory.getInstance()
+ .createBNode(Base64.getUrlEncoder().encodeToString(t.stringValue().getBytes(StandardCharsets.UTF_8)));
+
/**
* Creates one or more {@link Statement} objects with the given subject, predicate and object, one for each given
* context, and sends each created statement to the supplied {@link Consumer}. If no context is supplied, only a
* single statement (without any assigned context) is created.
- *
+ *
* @param vf the {@link ValueFactory} to use for creating statements.
* @param subject the subject of each statement. May not be null.
* @param predicate the predicate of each statement. May not be null.
@@ -56,7 +73,7 @@ public static void consume(ValueFactory vf, Resource subject, IRI predicate, Val
/**
* Creates one or more {@link Statement} objects with the given subject, predicate and object, one for each given
* context. If no context is supplied, only a single statement (without any assigned context) is created.
- *
+ *
* @param vf the {@link ValueFactory} to use for creating statements.
* @param subject the subject of each statement. May not be null.
* @param predicate the predicate of each statement. May not be null.
@@ -77,10 +94,10 @@ public static > C create(ValueFactory vf, Resour
/**
* Strips the context (if any) from the supplied statement and returns a statement with the same subject, predicate
* and object, but with no assigned context.
- *
+ *
* @param statement the statement to strip the context from
* @return a statement without context
- *
+ *
* @since 3.1.0
*/
public static Statement stripContext(Statement statement) {
@@ -90,11 +107,11 @@ public static Statement stripContext(Statement statement) {
/**
* Strips the context (if any) from the supplied statement and returns a statement with the same subject, predicate
* and object, but with no assigned context.
- *
+ *
* @param vf the {@link ValueFactory} to use for creating a new {@link Statement}.
* @param statement the statement to strip the context from.
* @return a statement without context
- *
+ *
* @since 3.1.0
*/
public static Statement stripContext(ValueFactory vf, Statement statement) {
@@ -107,7 +124,7 @@ public static Statement stripContext(ValueFactory vf, Statement statement) {
/**
* Checks if the two statements represent the same triple (that is, they have equal subject, predicate, and object).
* Context information is disregarded.
- *
+ *
* @param st1 the first statement to compare. May not be null.
* @param st2 the second statement to compare. May not be null.
* @return {@code true} iff the subject, predicate and object of {@code st1} and {@code st2} are equal,
@@ -121,4 +138,96 @@ public static boolean isSameTriple(Statement st1, Statement st2) {
return st1.getPredicate().equals(st2.getPredicate()) && st1.getSubject().equals(st2.getSubject())
&& st1.getObject().equals(st2.getObject());
}
+
+ /**
+ * Converts the supplied RDF* statement to RDF reification statements, and sends the resultant statements to the
+ * supplied consumer. If the supplied statement is not RDF* it will be sent to the consumer as is.
+ *
+ * The statements needed to represent reification will use blank nodes.
+ *
+ * @param st the {@link Statement} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertRDFStarToReification(Statement st, Consumer consumer) {
+ convertRDFStarToReification(SimpleValueFactory.getInstance(), st, consumer);
+ }
+
+ /**
+ * Converts the supplied RDF* statement to RDF reification statements, and sends the resultant statements to the
+ * supplied consumer. If the supplied statement is not RDF* it will be sent to the consumer as is.
+ *
+ * The statements needed to represent reification will use blank nodes.
+ *
+ * The supplied value factory is used to create all new statements and blank nodes.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param st the {@link Statement} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertRDFStarToReification(ValueFactory vf, Statement st, Consumer consumer) {
+ convertRDFStarToReification(vf, TRIPLE_BNODE_MAPPER, st, consumer);
+ }
+
+ /**
+ * Converts the supplied RDF* statement to RDF reification statements, and sends the resultant statements to the
+ * supplied consumer. If the supplied statement is not RDF* it will be sent to the consumer as is.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * The supplied mapper function maps a {@link Triple} to a {@link Resource} and is used to create the ID of the RDF
+ * reification statement corresponding to the converted triple. The function must return the same value for
+ * identical triples in order to produce consistent results between invocations. See {@link #TRIPLE_BNODE_MAPPER}.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param reifiedIdMapper the mapper {@link Function} from {@link Triple} to {@link Resource}.
+ * @param st the {@link Statement} to convert,
+ * @param consumer the {@link Consumer} function for the produced statements.
+ */
+ @Experimental
+ public static void convertRDFStarToReification(ValueFactory vf, Function reifiedIdMapper,
+ Statement st, Consumer consumer) {
+ Resource subject = st.getSubject();
+ Value object = st.getObject();
+ if (subject instanceof Triple || object instanceof Triple) {
+ if (subject instanceof Triple) {
+ subject = createReifiedStatement(vf, reifiedIdMapper, (Triple) subject, st.getContext(), consumer);
+ }
+ if (object instanceof Triple) {
+ object = createReifiedStatement(vf, reifiedIdMapper, (Triple) object, st.getContext(), consumer);
+ }
+ st = vf.createStatement(subject, st.getPredicate(), object, st.getContext());
+ }
+ consumer.accept(st);
+ }
+
+ /**
+ * Converts the supplied RDF* triple to a series of RDF reification statements and sends the statements to the
+ * supplied consumer. The subject of the created statements is returned.
+ *
+ * The supplied value factory is used to create all new statements.
+ *
+ * The supplied mapper function maps a {@link Triple} to a {@link Resource} and is used to create the ID of the RDF
+ * reification statement corresponding to the converted triple.
+ *
+ * @param vf the {@link ValueFactory} to use for creating statements.
+ * @param reifiedIdMapper the mapper {@link Function} from {@link Triple} to {@link Resource}.
+ * @param triple the {@link Triple} to convert.
+ * @param consumer the {@link Consumer} function for the produced statements.
+ * @return the {@link Resource} that was used as the subject of the created RDF reification statements.
+ */
+ private static Resource createReifiedStatement(ValueFactory vf, Function reifiedIdMapper,
+ Triple triple, Resource context, Consumer consumer) {
+ Resource stId = reifiedIdMapper.apply(triple);
+ Statement reifiedSt = vf.createStatement(stId, RDF.TYPE, RDF.STATEMENT, context);
+ consumer.accept(reifiedSt);
+ Statement reifiedStSubject = vf.createStatement(stId, RDF.SUBJECT, triple.getSubject(), context);
+ convertRDFStarToReification(vf, reifiedIdMapper, reifiedStSubject, consumer);
+ Statement reifiedStPredicate = vf.createStatement(stId, RDF.PREDICATE, triple.getPredicate(), context);
+ consumer.accept(reifiedStPredicate);
+ Statement reifiedStObject = vf.createStatement(stId, RDF.OBJECT, triple.getObject(), context);
+ convertRDFStarToReification(vf, reifiedIdMapper, reifiedStObject, consumer);
+ return stId;
+ }
}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/SynchronizedModel.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/SynchronizedModel.java
index ecdb1bdc35f..d5044dee922 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/SynchronizedModel.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/SynchronizedModel.java
@@ -14,7 +14,6 @@
import java.util.Set;
import java.util.Spliterator;
import java.util.function.Consumer;
-import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.stream.Stream;
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/URIUtil.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/URIUtil.java
index 4da3cc21dc4..27eab8aa213 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/URIUtil.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/URIUtil.java
@@ -17,7 +17,7 @@
/**
* Utility functions for working with {@link URI URIs}.
- *
+ *
* @author Arjohn Kampman
*/
public class URIUtil {
@@ -27,14 +27,14 @@ public class URIUtil {
* URI component would conflict with the reserved purpose, then the conflicting data must be escaped before forming
* the URI. http://www.isi.edu/in-notes/rfc2396.txt section 2.2.
*/
- private static final Set reserved = new HashSet(
+ private static final Set reserved = new HashSet<>(
Arrays.asList(new Character[] { ';', '/', '?', ':', '@', '&', '=', '+', '$', ',' }));
/**
* Punctuation mark characters, which are part of the set of unreserved chars and therefore allowed to occur in
* unescaped form. See http://www.isi.edu/in-notes/rfc2396.txt
*/
- private static final Set mark = new HashSet(
+ private static final Set mark = new HashSet<>(
Arrays.asList(new Character[] { '-', '_', '.', '!', '~', '*', '\'', '(', ')' }));
/**
@@ -54,7 +54,7 @@ public class URIUtil {
* Note that the third step should never fail as every legal (non-relative) URI contains at least one ':' character
* to seperate the scheme from the rest of the URI. If this fails anyway, the method will throw an
* {@link IllegalArgumentException}.
- *
+ *
* @param uri A URI string.
* @return The index of the first local name character in the URI string. Note that this index does not reference an
* actual character if the algorithm determines that there is not local name. In that case, the return index
@@ -84,7 +84,7 @@ public static int getLocalNameIndex(String uri) {
/**
* Checks whether the URI consisting of the specified namespace and local name has been split correctly according to
* the URI splitting rules specified in {@link URI}.
- *
+ *
* @param namespace The URI's namespace, must not be null.
* @param localName The URI's local name, must not be null.
* @return true if the specified URI has been correctly split into a namespace and local name,
@@ -135,7 +135,7 @@ public static boolean isCorrectURISplit(String namespace, String localName) {
*
encoding the Unicode string as UTF-8, giving a sequence of octet values.
*
%-escaping octets that do not correspond to permitted US-ASCII characters.
*
- *
+ *
* @param uriRef a string representing an RDF URI reference.
* @return true iff the supplied string is a syntactically valid RDF URI reference, false
* otherwise.
@@ -170,7 +170,7 @@ public static boolean isValidURIReference(String uriRef) {
/**
* Escapes any character that is not either reserved or in the legal range of unreserved characters, according to
* RFC 2396.
- *
+ *
* @param unescaped a (relative or absolute) uri reference.
* @return a (relative or absolute) uri reference with all characters that can not appear as-is in a URI %-escaped.
* @see RFC 2396
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Vocabularies.java b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Vocabularies.java
index c971332b86b..4f1fdb8a978 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/util/Vocabularies.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/util/Vocabularies.java
@@ -15,7 +15,7 @@
/**
* Utility functions for working with vocabularies.
- *
+ *
* @author Bart Hanssens
*/
public class Vocabularies {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DC.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DC.java
index 6bb5cd47e69..f89c4481006 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DC.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DC.java
@@ -15,7 +15,7 @@
/**
* Vocabulary constants for the Dublin Core Metadata Element Set, version 1.1
- *
+ *
* @see Dublin Core Metadata Element Set, Version 1.1
* @author Jeen Broekstra
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DCTERMS.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DCTERMS.java
index 45260a9caa5..163838e65bc 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DCTERMS.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/DCTERMS.java
@@ -15,7 +15,7 @@
/**
* Vocabulary constants for the Dublin Core Metadata Initiative Metadata Terms.
- *
+ *
* @see DCMI Metadata Terms
* @author Peter Ansell
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/FN.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/FN.java
index 66b40f2b018..1f4d96f1864 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/FN.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/FN.java
@@ -15,7 +15,7 @@
/**
* Defines constants for the standard XPath functions.
- *
+ *
* @see XPath functions
* @author Jeen Broekstra
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/ORG.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/ORG.java
index c13302fbf68..c0d02edb71c 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/ORG.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/ORG.java
@@ -15,9 +15,9 @@
/**
* Constants for the W3C Organization Ontology.
- *
+ *
* @see Organization Ontology
- *
+ *
* @author Bart.Hanssens
*/
public class ORG {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/OWL.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/OWL.java
index 46f2e3d8b50..f960b6fbc1c 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/OWL.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/OWL.java
@@ -15,7 +15,7 @@
/**
* Constants for OWL / OWL 2 primitives and for the OWL / OWL 2 namespace.
- *
+ *
* @see OWL Web Ontology Language Reference
* @see OWL 2 Web Ontology Language Document Overview
*/
@@ -365,4 +365,4 @@ public class OWL {
TOPOBJECTPROPERTY = factory.createIRI(OWL.NAMESPACE, "topObjectProperty");
WITHRESTRICTIONS = factory.createIRI(OWL.NAMESPACE, "withRestrictions");
}
-}
\ No newline at end of file
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF.java
index c32c2007ac7..2040ca9bc30 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF.java
@@ -15,7 +15,7 @@
/**
* Constants for RDF primitives and for the RDF namespace.
- *
+ *
* @see RDF/XML Syntax Specification (Revised)
*/
public class RDF {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF4J.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF4J.java
index e209c3fcba6..f950921bd2d 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF4J.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDF4J.java
@@ -15,7 +15,7 @@
/**
* Defines constants for the RDF4J namespace. These constants include things like implementation-specific named graph
* identifiers or properties.
- *
+ *
* @author Jeen Broekstra
*/
public class RDF4J {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDFS.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDFS.java
index dad36294176..6502fada434 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDFS.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/RDFS.java
@@ -16,7 +16,7 @@
/**
* Constants for the RDF Vocabulary Description Language 1.0: RDF Schema
* (RDFS)
- *
+ *
* @see RDF Vocabulary Description Language 1.0: RDF Schema (RDFS)
*/
public class RDFS {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SD.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SD.java
index 4ae418b9721..b47dc81c946 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SD.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SD.java
@@ -15,7 +15,7 @@
/**
* Namespace Sparql-service-description. Prefix: {@code }
- *
+ *
* @see SPARQL 1.1 Service Description
* @author Peter Ansell
*/
@@ -44,7 +44,7 @@ public class SD {
* An instance of sd:Aggregate represents an aggregate that may be used in a SPARQL aggregate query (for instance in
* a HAVING clause or SELECT expression) besides the standard list of supported aggregates COUNT, SUM, MIN, MAX,
* AVG, GROUP_CONCAT, and SAMPLE.
- *
+ *
* @see Aggregate
*/
public static final IRI AGGREGATE;
@@ -57,7 +57,7 @@ public class SD {
* Relates an instance of sd:Service to a description of the graphs which are allowed in the construction of a
* dataset either via the SPARQL Protocol, with FROM/FROM NAMED clauses in a query, or with USING/USING NAMED in an
* update request, if the service limits the scope of dataset construction.
- *
+ *
* @see availableGraphs
*/
public static final IRI AVAILBLE_GRAPHS;
@@ -69,7 +69,7 @@ public class SD {
*
* sd:BasicFederatedQuery, when used as the object of the sd:feature property, indicates that the SPARQL service
* supports basic federated query using the SERVICE keyword as defined by SPARQL 1.1 Federation Extensions.
- *
+ *
* @see BasicFederatedQuery
*/
public static final IRI BASIC_FEDERATED_QUERY;
@@ -80,7 +80,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#Dataset}.
*
* An instance of sd:Dataset represents a RDF Dataset comprised of a default graph and zero or more named graphs.
- *
+ *
* @see Dataset
*/
public static final IRI DATASET;
@@ -92,7 +92,7 @@ public class SD {
*
* Relates an instance of sd:Service to a description of the default dataset available when no explicit dataset is
* specified in the query, update request or via protocol parameters.
- *
+ *
* @see defaultDataset
*/
public static final IRI DEFAULT_DATASET;
@@ -107,7 +107,7 @@ public class SD {
* the default dataset of the service. In situations where a different entailment regime applies to a specific graph
* in the dataset, the sd:entailmentRegime property should be used to indicate this fact in the description of that
* graph.
- *
+ *
* @see
* defaultEntailmentRegime
*/
@@ -119,7 +119,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#defaultGraph}.
*
* Relates an instance of sd:Dataset to the description of its default graph.
- *
+ *
* @see defaultGraph
*/
public static final IRI DEFAULT_GRAPH;
@@ -131,7 +131,7 @@ public class SD {
*
* Relates an instance of sd:Service with a resource representing a supported profile of the default entailment
* regime (as declared by sd:defaultEntailmentRegime).
- *
+ *
* @see
* defaultSupportedEntailmentProfile
*/
@@ -145,7 +145,7 @@ public class SD {
* sd:DereferencesURIs, when used as the object of the sd:feature property, indicates that a SPARQL service will
* dereference URIs used in FROM/FROM NAMED and USING/USING NAMED clauses and use the resulting RDF in the dataset
* during query evaluation.
- *
+ *
* @see DereferencesURIs
*/
public static final IRI DEREFERENCES_URIS;
@@ -158,7 +158,7 @@ public class SD {
* sd:EmptyGraphs, when used as the object of the sd:feature property, indicates that the underlying graph store
* supports empty graphs. A graph store that supports empty graphs MUST NOT remove graphs that are left empty after
* triples are removed from them.
- *
+ *
* @see EmptyGraphs
*/
public static final IRI EMPTY_GRAPHS;
@@ -170,7 +170,7 @@ public class SD {
*
* The SPARQL endpoint of an sd:Service that implements the SPARQL Protocol service. The object of the sd:endpoint
* property is an IRI.
- *
+ *
* @see endpoint
*/
public static final IRI ENDPOINT;
@@ -182,7 +182,7 @@ public class SD {
*
* An instance of sd:EntailmentProfile represents a profile of an entailment regime. An entailment profile MAY
* impose restrictions on what constitutes valid RDF with respect to entailment.
- *
+ *
* @see EntailmentProfile
*/
public static final IRI ENTAILMENT_PROFILE;
@@ -194,7 +194,7 @@ public class SD {
*
* An instance of sd:EntailmentRegime represents an entailment regime used in basic graph pattern matching (as
* described by SPARQL 1.1 Query Language).
- *
+ *
* @see EntailmentRegime
*/
public static final IRI ENTAILMENT_REGIME_CLASS;
@@ -206,7 +206,7 @@ public class SD {
*
* Relates a named graph description with a resource representing an entailment regime used for basic graph pattern
* matching over that graph.
- *
+ *
* @see entailmentRegime
*/
public static final IRI ENTAILMENT_REGIME_PROPERTY;
@@ -219,7 +219,7 @@ public class SD {
* Relates an instance of sd:Service to an aggregate that may be used in a SPARQL aggregate query (for instance in a
* HAVING clause or SELECT expression) besides the standard list of supported aggregates COUNT, SUM, MIN, MAX, AVG,
* GROUP_CONCAT, and SAMPLE
- *
+ *
* @see extensionAggregate
*/
public static final IRI EXTENSION_AGGREGATE;
@@ -231,7 +231,7 @@ public class SD {
*
* Relates an instance of sd:Service to a function that may be used in a SPARQL SELECT expression or a FILTER,
* HAVING, GROUP BY, ORDER BY, or BIND clause.
- *
+ *
* @see extensionFunction
*/
public static final IRI EXTENSION_FUNCTION;
@@ -244,7 +244,7 @@ public class SD {
* An instance of sd:Feature represents a feature of a SPARQL service. Specific types of features include functions,
* aggregates, languages, and entailment regimes and profiles. This document defines five instances of sd:Feature:
* sd:DereferencesURIs, sd:UnionDefaultGraph, sd:RequiresDataset, sd:EmptyGraphs, and sd:BasicFederatedQuery.
- *
+ *
* @see Feature
*/
public static final IRI FEATURE_CLASS;
@@ -255,7 +255,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#feature}.
*
* Relates an instance of sd:Service with a resource representing a supported feature.
- *
+ *
* @see feature
*/
public static final IRI FEATURE_PROPERTY;
@@ -267,7 +267,7 @@ public class SD {
*
* An instance of sd:Function represents a function that may be used in a SPARQL SELECT expression or a FILTER,
* HAVING, GROUP BY, ORDER BY, or BIND clause.
- *
+ *
* @see Function
*/
public static final IRI FUNCTION;
@@ -278,7 +278,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#graph}.
*
* Relates a named graph to its graph description.
- *
+ *
* @see graph
*/
public static final IRI GRAPH_PROPERTY;
@@ -289,7 +289,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#Graph}.
*
* An instance of sd:Graph represents the description of an RDF graph.
- *
+ *
* @see Graph
*/
public static final IRI GRAPH_CLASS;
@@ -301,7 +301,7 @@ public class SD {
*
* An instance of sd:GraphCollection represents a collection of zero or more named graph descriptions. Each named
* graph description belonging to an sd:GraphCollection MUST be linked with the sd:namedGraph predicate.
- *
+ *
* @see GraphCollection
*/
public static final IRI GRAPH_COLLECTION;
@@ -313,7 +313,7 @@ public class SD {
*
* Relates an instance of sd:Service to a format that is supported for parsing RDF input; for example, via a SPARQL
* 1.1 Update LOAD statement, or when URIs are dereferenced in FROM/FROM NAMED/USING/USING NAMED clauses.
- *
+ *
* @see inputFormat
*/
public static final IRI INPUT_FORMAT;
@@ -326,7 +326,7 @@ public class SD {
* An instance of sd:Language represents one of the SPARQL languages, including specific configurations providing
* particular features or extensions. This document defines three instances of sd:Language: sd:SPARQL10Query,
* sd:SPARQL11Query, and sd:SPARQL11Update.
- *
+ *
* @see Language
*/
public static final IRI LANGUAGE;
@@ -338,7 +338,7 @@ public class SD {
*
* Relates an instance of sd:Service to a resource representing an implemented extension to the SPARQL Query or
* Update language.
- *
+ *
* @see languageExtension
*/
public static final IRI LANGUAGE_EXTENSION;
@@ -350,7 +350,7 @@ public class SD {
*
* Relates a named graph to the name by which it may be referenced in a FROM/FROM NAMED clause. The object of the
* sd:name property is an IRI.
- *
+ *
* @see name
*/
public static final IRI NAME;
@@ -363,7 +363,7 @@ public class SD {
* Relates an instance of sd:GraphCollection (or its subclass sd:Dataset) to the description of one of its named
* graphs. The description of such a named graph MUST include the sd:name property and MAY include the sd:graph
* property.
- *
+ *
* @see namedGraph
*/
public static final IRI NAMED_GRAPH_PROPERTY;
@@ -375,7 +375,7 @@ public class SD {
*
* An instance of sd:NamedGraph represents a named graph having a name (via sd:name) and an optional graph
* description (via sd:graph).
- *
+ *
* @see NamedGraph
*/
public static final IRI NAMED_GRAPH_CLASS;
@@ -387,7 +387,7 @@ public class SD {
*
* Relates an instance of sd:Service to a resource representing an implemented feature that extends the SPARQL Query
* or Update language and that is accessed by using the named property.
- *
+ *
* @see propertyFeature
*/
public static final IRI PROPERTY_FEATURE;
@@ -400,7 +400,7 @@ public class SD {
* sd:RequiresDataset, when used as the object of the sd:feature property, indicates that the SPARQL service
* requires an explicit dataset declaration (based on either FROM/FROM NAMED clauses in a query, USING/USING NAMED
* clauses in an update, or the appropriate SPARQL Protocol parameters).
- *
+ *
* @see RequiresDataset
*/
public static final IRI REQUIRES_DATASET;
@@ -411,7 +411,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#resultFormat}.
*
* Relates an instance of sd:Service to a format that is supported for serializing query results.
- *
+ *
* @see resultFormat
*/
public static final IRI RESULT_FORMAT;
@@ -422,7 +422,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#Service}.
*
* An instance of sd:Service represents a SPARQL service made available via the SPARQL Protocol.
- *
+ *
* @see Service
*/
public static final IRI SERVICE;
@@ -433,7 +433,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#SPARQL10Query}.
*
* sd:SPARQL10Query is an sd:Language representing the SPARQL 1.0 Query language.
- *
+ *
* @see SPARQL10Query
*/
public static final IRI SPARQL_10_QUERY;
@@ -444,7 +444,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#SPARQL11Query}.
*
* sd:SPARQL11Query is an sd:Language representing the SPARQL 1.1 Query language.
- *
+ *
* @see SPARQL11Query
*/
public static final IRI SPARQL_11_QUERY;
@@ -455,7 +455,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#SPARQL11Update}.
*
* sd:SPARQLUpdate is an sd:Language representing the SPARQL 1.1 Update language.
- *
+ *
* @see SPARQL11Update
*/
public static final IRI SPARQL_11_UPDATE;
@@ -467,7 +467,7 @@ public class SD {
*
* Relates a named graph description with a resource representing a supported profile of the entailment regime (as
* declared by sd:entailmentRegime) used for basic graph pattern matching over that graph.
- *
+ *
* @see
* supportedEntailmentProfile
*/
@@ -479,7 +479,7 @@ public class SD {
* {@code http://www.w3.org/ns/sparql-service-description#supportedLanguage}.
*
* Relates an instance of sd:Service to a SPARQL language (e.g. Query and Update) that it implements.
- *
+ *
* @see supportedLanguage
*/
public static final IRI SUPPORTED_LANGUAGE;
@@ -492,7 +492,7 @@ public class SD {
* sd:UnionDefaultGraph, when used as the object of the sd:feature property, indicates that the default graph of the
* dataset used during query and update evaluation (when an explicit dataset is not specified) is comprised of the
* union of all the named graphs in that dataset.
- *
+ *
* @see UnionDefaultGraph
*/
public static final IRI UNION_DEFAULT_GRAPH;
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SESAMEQNAME.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SESAMEQNAME.java
index 7acf95fa096..5fc1c7627cf 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SESAMEQNAME.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SESAMEQNAME.java
@@ -15,7 +15,7 @@
/**
* Defines constants for the Sesame QName schema namespace.
- *
+ *
* @author Peter Ansell
*/
public class SESAMEQNAME {
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOS.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOS.java
index 03d508f13c4..83348e3b45a 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOS.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOS.java
@@ -16,7 +16,7 @@
/**
* Vocabulary constants for the Simple Knowledge Organization System
* (SKOS).
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference
* @author Jeen Broekstra
*/
@@ -41,28 +41,28 @@ public class SKOS {
/**
* The skos:Concept class
- *
+ *
* @see The skos:Concept Class
*/
public static final IRI CONCEPT;
/**
* The skos:ConceptScheme class
- *
+ *
* @see Concept Schemes
*/
public static final IRI CONCEPT_SCHEME;
/**
* The skos:Collection class
- *
+ *
* @see Concept Collections
*/
public static final IRI COLLECTION;
/**
* The skos:OrderedCollection class
- *
+ *
* @see Concept Collections
*/
public static final IRI ORDERED_COLLECTION;
@@ -71,21 +71,21 @@ public class SKOS {
/**
* The skos:prefLabel lexical label property.
- *
+ *
* @see Lexical Labels
*/
public static final IRI PREF_LABEL;
/**
* The skos:altLabel lexical label property.
- *
+ *
* @see Lexical Labels
*/
public static final IRI ALT_LABEL;
/**
* The skos:hiddenLabel lexical label property.
- *
+ *
* @see Lexical Labels
*/
public static final IRI HIDDEN_LABEL;
@@ -94,21 +94,21 @@ public class SKOS {
/**
* The skos:inScheme relation.
- *
+ *
* @see Concept Schemes
*/
public static final IRI IN_SCHEME;
/**
* The skos:hasTopConcept relation.
- *
+ *
* @see Concept Schemes
*/
public static final IRI HAS_TOP_CONCEPT;
/**
* The skos:topConceptOf relation.
- *
+ *
* @see Concept Schemes
*/
public static final IRI TOP_CONCEPT_OF;
@@ -117,14 +117,14 @@ public class SKOS {
/**
* The skos:member relation.
- *
+ *
* @see Concept Collections
*/
public static final IRI MEMBER;
/**
* The skos:memberList relation.
- *
+ *
* @see Concept Collections
*/
public static final IRI MEMBER_LIST;
@@ -133,7 +133,7 @@ public class SKOS {
/**
* The skos:notation property.
- *
+ *
* @see Notations
*/
public static final IRI NOTATION;
@@ -142,28 +142,28 @@ public class SKOS {
/**
* The skos:changeNote property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI CHANGE_NOTE;
/**
* The skos:definition property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI DEFINITION;
/**
* The skos:editorialNote property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI EDITORIAL_NOTE;
/**
* The skos:example property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
@@ -171,21 +171,21 @@ public class SKOS {
/**
* The skos:historyNote property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI HISTORY_NOTE;
/**
* The skos:note property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI NOTE;
/**
* The skos:scopeNote property.
- *
+ *
* @see Documentation Properties (Note Properties)
*/
public static final IRI SCOPE_NOTE;
@@ -194,7 +194,7 @@ public class SKOS {
/**
* The skos:broader relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -202,7 +202,7 @@ public class SKOS {
/**
* The skos:broaderTransitive relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -210,7 +210,7 @@ public class SKOS {
/**
* The skos:narrower relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -218,7 +218,7 @@ public class SKOS {
/**
* The skos:narrowerTransitive relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -226,7 +226,7 @@ public class SKOS {
/**
* The skos:related relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -234,7 +234,7 @@ public class SKOS {
/**
* The skos:semanticRelation relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System
* Reference - Semantic Relations Section
*/
@@ -244,7 +244,7 @@ public class SKOS {
/**
* The skos:broadMatch relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
@@ -252,7 +252,7 @@ public class SKOS {
/**
* The skos:closeMatch relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
@@ -260,7 +260,7 @@ public class SKOS {
/**
* The skos:exactMatch relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
@@ -268,7 +268,7 @@ public class SKOS {
/**
* The skos:mappingRelation relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
@@ -276,7 +276,7 @@ public class SKOS {
/**
* The skos:narrowMatch relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
@@ -284,7 +284,7 @@ public class SKOS {
/**
* The skos:relatedMatch relation.
- *
+ *
* @see SKOS Simple Knowledge Organization System Reference -
* Mapping Properties Section
*/
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOSXL.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOSXL.java
index fc64ce20df2..6ebc1a36a1c 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOSXL.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/SKOSXL.java
@@ -16,7 +16,7 @@
/**
* Vocabulary constants for the SKOS eXtension for Labels
* (SKOS-XL).
- *
+ *
* @see Appendix B of SKOS Simple Knowledge Organization System
* Reference
* @author Manuel Fiorelli
@@ -42,7 +42,7 @@ public class SKOSXL {
/**
* The skosxl:Label class.
- *
+ *
* @see The skosxl:Label Class
*/
public static final IRI LABEL;
@@ -51,7 +51,7 @@ public class SKOSXL {
/**
* The skosxl:literalForm property.
- *
+ *
* @see The skosxl:Label Class
*/
public static final IRI LITERAL_FORM;
@@ -60,21 +60,21 @@ public class SKOSXL {
/**
* The skosxl:prefLabel property.
- *
+ *
* @see Preferred, Alternate and Hidden skosxl:Labels
*/
public static final IRI PREF_LABEL;
/**
* The skosxl:altLabel property.
- *
+ *
* @see Preferred, Alternate and Hidden skosxl:Labels
*/
public static final IRI ALT_LABEL;
/**
* The skosxl:hiddenLabel property.
- *
+ *
* @see Preferred, Alternate and Hidden skosxl:Labels
*/
public static final IRI HIDDEN_LABEL;
@@ -83,7 +83,7 @@ public class SKOSXL {
/**
* The skosxl:labelRelation relation.
- *
+ *
* @see Links Between skosxl:Labels
*/
public static final IRI LABEL_RELATION;
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/WGS84.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/WGS84.java
new file mode 100644
index 00000000000..95ec0abc4c0
--- /dev/null
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/WGS84.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.model.vocabulary;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Namespace;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleNamespace;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+
+/**
+ * Constants for the Basic Geo (WGS84 lat/long) Vocabulary.
+ *
+ * @author Alessandro Bollini
+ * @see Basic Geo (WGS84 lat/long) Vocabulary
+ */
+public class WGS84 {
+
+ /**
+ * The WGS84 namespace ({@value}).
+ */
+ public static final String NAMESPACE = "http://www.w3.org/2003/01/geo/wgs84_pos#";
+
+ /**
+ * Recommended prefix for the RDF Schema namespace ({@value}).
+ */
+ public static final String PREFIX = "wgs84";
+
+ /**
+ * An immutable {@link Namespace} constant that represents the WGS84 namespace.
+ */
+ public static final Namespace NS = new SimpleNamespace(PREFIX, NAMESPACE);
+
+ /** The {@code wgs84:SpatialThing} class. */
+ public static final IRI SPATIAL_THING;
+
+ /** The {@code wgs84:TemporalThing} class. */
+ public static final IRI TEMPORAL_THING;
+
+ /** The {@code wgs84:Event} class. */
+ public static final IRI EVENT;
+
+ /** The {@code wgs84:Point} relation. */
+ public static final IRI POINT;
+
+ /** The {@code wgs84:location} relation. */
+ public static final IRI LOCATION;
+
+ /** The {@code wgs84:lat} relation. */
+ public static final IRI LAT;
+
+ /** The {@code wgs84:long} relation. */
+ public static final IRI LONG;
+
+ /** The {@code wgs84:alt} relation. */
+ public static final IRI ALT;
+
+ /** The {@code wgs84:lat_long} relation. */
+ public static final IRI LAT_LONG;
+
+ static {
+
+ final ValueFactory factory = SimpleValueFactory.getInstance();
+
+ SPATIAL_THING = factory.createIRI(NAMESPACE, "SpatialThing");
+ TEMPORAL_THING = factory.createIRI(NAMESPACE, "TemporalThing");
+ EVENT = factory.createIRI(NAMESPACE, "Event");
+
+ POINT = factory.createIRI(NAMESPACE, "Point");
+ LOCATION = factory.createIRI(NAMESPACE, "location");
+ LAT = factory.createIRI(NAMESPACE, "lat");
+ LONG = factory.createIRI(NAMESPACE, "long");
+ ALT = factory.createIRI(NAMESPACE, "alt");
+ LAT_LONG = factory.createIRI(NAMESPACE, "lat_long");
+
+ }
+
+}
diff --git a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/XMLSchema.java b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/XMLSchema.java
index e616833d6a4..1ed9be4ccb2 100644
--- a/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/XMLSchema.java
+++ b/core/model/src/main/java/org/eclipse/rdf4j/model/vocabulary/XMLSchema.java
@@ -15,7 +15,7 @@
/**
* Constants for the standard XML Schema 1.1 datatypes.
- *
+ *
* @see XML Schema 1.1 Part 2: Datatypes
*/
public class XMLSchema {
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelConcurrentModificationAndUpgradeTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelConcurrentModificationAndUpgradeTest.java
new file mode 100644
index 00000000000..b7df88048c6
--- /dev/null
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/DynamicModelConcurrentModificationAndUpgradeTest.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+import org.eclipse.rdf4j.model.impl.DynamicModel;
+import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.RDFS;
+import org.junit.Test;
+
+public class DynamicModelConcurrentModificationAndUpgradeTest {
+
+ /**
+ * Add multiple statements while forcing an upgrade to make sure we then get an exception because the underlying
+ * storage was upgraded
+ *
+ * @throws InterruptedException
+ */
+ @Test
+ public void testConcurrentAddAndUpgrade() throws InterruptedException {
+
+ for (int i = 0; i < 100; i++) {
+ Exception exception = runTest();
+
+ if (exception != null) {
+ assertThat(exception).isInstanceOf(UnsupportedOperationException.class);
+ return;
+ }
+ }
+
+ fail("There should have been an UnsupportedOperationException earlier");
+
+ }
+
+ private Exception runTest() throws InterruptedException {
+ SimpleValueFactory vf = SimpleValueFactory.getInstance();
+ List statements = Arrays.asList(
+ vf.createStatement(vf.createBNode(), RDF.TYPE, RDFS.RESOURCE),
+ vf.createStatement(vf.createBNode(), RDF.TYPE, RDFS.RESOURCE),
+ vf.createStatement(vf.createBNode(), RDF.TYPE, RDFS.RESOURCE),
+ vf.createStatement(vf.createBNode(), RDF.TYPE, RDFS.RESOURCE),
+ vf.createStatement(vf.createBNode(), RDF.TYPE, RDFS.RESOURCE));
+
+ DynamicModel model = new DynamicModel(new LinkedHashModelFactory());
+
+ CountDownLatch countDownLatch2 = new CountDownLatch(1);
+ CountDownLatch countDownLatch1 = new CountDownLatch(1);
+
+ final Exception[] exception = new Exception[1];
+
+ Runnable addAll = () -> {
+ try {
+ model.addAll(new Collection() {
+ @Override
+ public int size() {
+ return statements.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return statements.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return statements.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new Iterator() {
+
+ final Iterator iterator = statements.iterator();
+
+ @Override
+ public boolean hasNext() {
+ try {
+ countDownLatch1.countDown();
+ countDownLatch2.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Thread.yield();
+ return iterator.hasNext();
+ }
+
+ @Override
+ public Statement next() {
+ try {
+ countDownLatch2.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Thread.yield();
+ return iterator.next();
+ }
+ };
+ }
+
+ @Override
+ public Object[] toArray() {
+ return statements.toArray();
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ return statements.toArray(a);
+ }
+
+ @Override
+ public boolean add(Statement statement) {
+ return false;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ return statements.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection extends Statement> c) {
+ return false;
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ System.out.println();
+ }
+ });
+ } catch (Exception e) {
+ exception[0] = e;
+ }
+ };
+
+ Runnable upgrade = () -> {
+ try {
+ countDownLatch1.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ model.filter(null, RDF.TYPE, null);
+ countDownLatch2.countDown();
+ };
+
+ Thread addAllThread = new Thread(addAll);
+ Thread upgradeThread = new Thread(upgrade);
+
+ addAllThread.start();
+ upgradeThread.start();
+
+ addAllThread.join();
+ upgradeThread.join();
+
+ return exception[0];
+ }
+
+}
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/ModelCollectionTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/ModelCollectionTest.java
index cb2fb2ed4e0..6d45675214e 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/ModelCollectionTest.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/ModelCollectionTest.java
@@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.rdf4j.model;
+import org.eclipse.rdf4j.model.impl.DynamicModelFactory;
import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory;
import org.eclipse.rdf4j.model.impl.TreeModelFactory;
@@ -20,7 +21,7 @@
/**
* Unit tests for {@link Model} implementations to check conformance with Java Collection Framework.
- *
+ *
* @author Jeen Broekstra
*
*/
@@ -33,6 +34,7 @@ public Test allTests() {
TestSuite suite = new TestSuite("org.eclipse.rdf4j.model.ModelCollectionTest");
suite.addTest(testModelImpl("LinkedHashModel", new LinkedHashModelFactory()));
suite.addTest(testModelImpl("TreeModel", new TreeModelFactory()));
+ suite.addTest(testModelImpl("DynamicModel", new DynamicModelFactory()));
return suite;
}
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/TestModelGenerator.java b/core/model/src/test/java/org/eclipse/rdf4j/model/TestModelGenerator.java
index 6d608e468e1..8fb51618f85 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/TestModelGenerator.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/TestModelGenerator.java
@@ -17,7 +17,7 @@
/**
* Creates Models, containing sample {@link Statement}s, for use in Java Collection Framework conformance testing.
- *
+ *
* @author Jeen Broekstra
* @see ModelCollectionTest
*/
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtilTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtilTest.java
index 79782d4b0d2..3b82e69daa3 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtilTest.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/datatypes/XMLDatatypeUtilTest.java
@@ -17,7 +17,7 @@
/**
* Unit tests on {@link org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil}
- *
+ *
* @author Jeen Broekstra
*/
public class XMLDatatypeUtilTest {
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/util/LiteralsTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/util/LiteralsTest.java
index 2684fb3bedf..e7f3f1d08d4 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/util/LiteralsTest.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/util/LiteralsTest.java
@@ -29,7 +29,7 @@
/**
* Tests for {@link Literals}.
- *
+ *
* @author Peter Ansell
*/
public class LiteralsTest {
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/util/ModelsTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/util/ModelsTest.java
index 0e252e1eee4..1f24bef9c42 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/util/ModelsTest.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/util/ModelsTest.java
@@ -15,16 +15,19 @@
import java.util.Optional;
import java.util.Set;
+import java.util.function.Consumer;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.LinkedHashModel;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.impl.TreeModel;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.junit.Assert;
@@ -445,4 +448,77 @@ public void testStripContextsSpecificContext() {
assertThat(graph2Stripped.size()).isEqualTo(model1.size());
}
+ @Test
+ public void testConvertReificationToRDFStar() {
+ Model reificationModel = RDFStarTestHelper.createRDFReificationModel();
+ Model referenceRDFStarModel = RDFStarTestHelper.createRDFStarModel();
+
+ Model rdfStarModel1 = Models.convertReificationToRDFStar(VF, reificationModel);
+ assertTrue("RDF reification conversion to RDF* with explicit VF, model-to-model",
+ Models.isomorphic(rdfStarModel1, referenceRDFStarModel));
+
+ Model rdfStarModel2 = Models.convertReificationToRDFStar(reificationModel);
+ assertTrue("RDF reification conversion to RDF* with implicit VF, model-to-model",
+ Models.isomorphic(rdfStarModel2, referenceRDFStarModel));
+
+ Model rdfStarModel3 = new TreeModel();
+ Models.convertReificationToRDFStar(VF, reificationModel, (Consumer) rdfStarModel3::add);
+ assertTrue("RDF reification conversion to RDF* with explicit VF, model-to-consumer",
+ Models.isomorphic(rdfStarModel3, referenceRDFStarModel));
+
+ Model rdfStarModel4 = new TreeModel();
+ Models.convertReificationToRDFStar(reificationModel, rdfStarModel4::add);
+ assertTrue("RDF reification conversion to RDF* with implicit VF, model-to-consumer",
+ Models.isomorphic(rdfStarModel4, referenceRDFStarModel));
+ }
+
+ @Test
+ public void testConvertIncompleteReificationToRDFStar() {
+ // Incomplete RDF reification (missing type, subject, predicate or object) should not add statements
+ // and should not remove any of the existing incomplete reification statements.
+ Model incompleteReificationModel = RDFStarTestHelper.createIncompleteRDFReificationModel();
+
+ Model rdfStarModel1 = Models.convertReificationToRDFStar(VF, incompleteReificationModel);
+ assertTrue("Incomplete RDF reification conversion to RDF* with explicit VF, model-to-model",
+ Models.isomorphic(rdfStarModel1, incompleteReificationModel));
+
+ Model rdfStarModel2 = Models.convertReificationToRDFStar(incompleteReificationModel);
+ assertTrue("Incomplete RDF reification conversion to RDF* with implicit VF, model-to-model",
+ Models.isomorphic(rdfStarModel2, incompleteReificationModel));
+
+ Model rdfStarModel3 = new TreeModel();
+ Models.convertReificationToRDFStar(VF, incompleteReificationModel, (Consumer) rdfStarModel3::add);
+ assertTrue("Incomplete RDF reification conversion to RDF* with explicit VF, model-to-consumer",
+ Models.isomorphic(rdfStarModel3, incompleteReificationModel));
+
+ Model rdfStarModel4 = new TreeModel();
+ Models.convertReificationToRDFStar(incompleteReificationModel, rdfStarModel4::add);
+ assertTrue("Incomplete RDF reification conversion to RDF* with implicit VF, model-to-consumer",
+ Models.isomorphic(rdfStarModel4, incompleteReificationModel));
+ }
+
+ @Test
+ public void testConvertRDFStarToReification() {
+ Model rdfStarModel = RDFStarTestHelper.createRDFStarModel();
+ Model referenceModel = RDFStarTestHelper.createRDFReificationModel();
+
+ Model reificationModel1 = Models.convertRDFStarToReification(VF, rdfStarModel);
+ assertTrue("RDF* conversion to reification with explicit VF, model-to-model",
+ Models.isomorphic(reificationModel1, referenceModel));
+
+ Model reificationModel2 = Models.convertRDFStarToReification(rdfStarModel);
+ assertTrue("RDF* conversion to reification with implicit VF, model-to-model",
+ Models.isomorphic(reificationModel2, referenceModel));
+
+ Model reificationModel3 = new TreeModel();
+ Models.convertRDFStarToReification(VF, rdfStarModel, (Consumer) reificationModel3::add);
+ assertTrue("RDF* conversion to reification with explicit VF, model-to-consumer",
+ Models.isomorphic(reificationModel3, referenceModel));
+
+ Model reificationModel4 = new TreeModel();
+ Models.convertRDFStarToReification(rdfStarModel, reificationModel4::add);
+ assertTrue("RDF* conversion to reification with explicit VF, model-to-consumer",
+ Models.isomorphic(reificationModel4, referenceModel));
+ }
+
}
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/util/RDFStarTestHelper.java b/core/model/src/test/java/org/eclipse/rdf4j/model/util/RDFStarTestHelper.java
new file mode 100644
index 00000000000..6fe090df11f
--- /dev/null
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/util/RDFStarTestHelper.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.model.util;
+
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+
+public class RDFStarTestHelper {
+ private final static ValueFactory VF = SimpleValueFactory.getInstance();
+
+ private final static IRI GRAPH_NULL = null;
+ private final static IRI GRAPH_1 = VF.createIRI("urn:graph1");
+ private final static IRI GRAPH_2 = VF.createIRI("urn:graph2");
+ private final static IRI IRI_1 = VF.createIRI("urn:a");
+ private final static IRI IRI_2 = VF.createIRI("urn:b");
+ private final static IRI IRI_3 = VF.createIRI("urn:c");
+ private final static IRI IRI_4 = VF.createIRI("urn:d");
+ private final static IRI IRI_5 = VF.createIRI("urn:e");
+ private final static IRI IRI_6 = VF.createIRI("urn:f");
+ private final static Literal LITERAL_1 = VF.createLiteral("literal 1");
+ private final static Literal LITERAL_2 = VF.createLiteral("literal 2");
+ private final static BNode BNODE_1 = VF.createBNode("bnode1");
+ private final static BNode BNODE_2 = VF.createBNode("bnode2");
+
+ public static Model createRDFStarModel() {
+ Model rdfStarModel = new LinkedHashModel();
+ Statements.create(VF, IRI_1, IRI_2, IRI_3, rdfStarModel, GRAPH_NULL);
+ // The same triple repeated twice
+ Statements.create(VF, IRI_1, IRI_2, VF.createTriple(IRI_4, IRI_5, LITERAL_1), rdfStarModel, GRAPH_1);
+ Statements.create(VF, IRI_1, IRI_3, VF.createTriple(IRI_4, IRI_5, LITERAL_1), rdfStarModel, GRAPH_1);
+ Statements.create(VF, VF.createTriple(IRI_5, IRI_6, IRI_4), IRI_3, BNODE_1, rdfStarModel, GRAPH_2);
+ Statements.create(VF, VF.createTriple(VF.createTriple(IRI_1, IRI_2, LITERAL_2),
+ IRI_3, VF.createTriple(IRI_4, IRI_5, IRI_6)),
+ IRI_2, VF.createTriple(VF.createTriple(BNODE_2, IRI_3, LITERAL_2),
+ IRI_4, VF.createTriple(IRI_3, IRI_6, IRI_1)),
+ rdfStarModel, GRAPH_2);
+
+ return rdfStarModel;
+ }
+
+ public static Model createRDFReificationModel() {
+ Model reifiedModel = new LinkedHashModel();
+ Statements.create(VF, IRI_1, IRI_2, IRI_3, reifiedModel, GRAPH_NULL);
+
+ // maps iri1 iri2 <> to reification
+ BNode t1 = VF.createBNode();
+ Statements.create(VF, IRI_1, IRI_2, t1, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.SUBJECT, IRI_4, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.PREDICATE, IRI_5, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.OBJECT, LITERAL_1, reifiedModel, GRAPH_1);
+
+ // maps iri1 iri2 <> to reification
+ // same triple/reification statements as previous entry
+ Statements.create(VF, IRI_1, IRI_3, t1, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.SUBJECT, IRI_4, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.PREDICATE, IRI_5, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.OBJECT, LITERAL_1, reifiedModel, GRAPH_1);
+
+ // maps <> iri3 _:bnode1 to reification
+ BNode t2 = VF.createBNode();
+ Statements.create(VF, t2, IRI_3, BNODE_1, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.SUBJECT, IRI_5, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.PREDICATE, IRI_6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.OBJECT, IRI_4, reifiedModel, GRAPH_2);
+
+ // maps a complex nested statement to reification
+ // t3
+ // t5 t6
+ // subj: << <> iri3 <> >>
+ // pred: iri2
+ // obj: << <<_:bnode2 iri3 "literal2">> iri4 <> >>
+ // t7 t8
+ // t4
+ BNode t3 = VF.createBNode();
+ BNode t4 = VF.createBNode();
+ BNode t5 = VF.createBNode();
+ BNode t6 = VF.createBNode();
+ BNode t7 = VF.createBNode();
+ BNode t8 = VF.createBNode();
+ Statements.create(VF, t3, IRI_2, t4, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.SUBJECT, t5, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.PREDICATE, IRI_3, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.OBJECT, t6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t5, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t5, RDF.SUBJECT, IRI_1, reifiedModel, GRAPH_2);
+ Statements.create(VF, t5, RDF.PREDICATE, IRI_2, reifiedModel, GRAPH_2);
+ Statements.create(VF, t5, RDF.OBJECT, LITERAL_2, reifiedModel, GRAPH_2);
+ Statements.create(VF, t6, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t6, RDF.SUBJECT, IRI_4, reifiedModel, GRAPH_2);
+ Statements.create(VF, t6, RDF.PREDICATE, IRI_5, reifiedModel, GRAPH_2);
+ Statements.create(VF, t6, RDF.OBJECT, IRI_6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.SUBJECT, t7, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.PREDICATE, IRI_4, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.OBJECT, t8, reifiedModel, GRAPH_2);
+ Statements.create(VF, t7, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t7, RDF.SUBJECT, BNODE_2, reifiedModel, GRAPH_2);
+ Statements.create(VF, t7, RDF.PREDICATE, IRI_3, reifiedModel, GRAPH_2);
+ Statements.create(VF, t7, RDF.OBJECT, LITERAL_2, reifiedModel, GRAPH_2);
+ Statements.create(VF, t8, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t8, RDF.SUBJECT, IRI_3, reifiedModel, GRAPH_2);
+ Statements.create(VF, t8, RDF.PREDICATE, IRI_6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t8, RDF.OBJECT, IRI_1, reifiedModel, GRAPH_2);
+
+ return reifiedModel;
+ }
+
+ public static Model createIncompleteRDFReificationModel() {
+ Model reifiedModel = new LinkedHashModel();
+ Statements.create(VF, IRI_1, IRI_2, IRI_3, reifiedModel, GRAPH_NULL);
+
+ // maps iri1 iri2 <> to reification
+ BNode t1 = VF.createBNode();
+ Statements.create(VF, IRI_1, IRI_2, t1, reifiedModel, GRAPH_1);
+ // Incomplete reification: missing t1 RDF.TYPE RDF.STATEMENT
+ Statements.create(VF, t1, RDF.SUBJECT, IRI_4, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.PREDICATE, IRI_5, reifiedModel, GRAPH_1);
+ Statements.create(VF, t1, RDF.OBJECT, LITERAL_1, reifiedModel, GRAPH_1);
+
+ // maps <> iri3 _:bnode1 to reification
+ BNode t2 = VF.createBNode();
+ Statements.create(VF, t2, IRI_3, BNODE_1, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ // Incomplete reification: missing t2 RDF.SUBJECT iri5
+ Statements.create(VF, t2, RDF.PREDICATE, IRI_6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t2, RDF.OBJECT, IRI_4, reifiedModel, GRAPH_2);
+
+ // maps <> iri3 iri6 to reification
+ BNode t3 = VF.createBNode();
+ Statements.create(VF, t3, IRI_3, IRI_6, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t3, RDF.SUBJECT, IRI_1, reifiedModel, GRAPH_2);
+ // Incomplete reification: missing t3 RDF.PREDICATE iri2
+ Statements.create(VF, t3, RDF.OBJECT, IRI_4, reifiedModel, GRAPH_2);
+
+ // maps iri6 iri3 <> to reification
+ BNode t4 = VF.createBNode();
+ Statements.create(VF, IRI_6, IRI_3, t4, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.TYPE, RDF.STATEMENT, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.SUBJECT, IRI_1, reifiedModel, GRAPH_2);
+ Statements.create(VF, t4, RDF.PREDICATE, IRI_2, reifiedModel, GRAPH_2);
+ // Incomplete reification: missing t4 RDF.OBJECT "literal2"
+
+ return reifiedModel;
+ }
+}
diff --git a/core/model/src/test/java/org/eclipse/rdf4j/model/util/StatementsTest.java b/core/model/src/test/java/org/eclipse/rdf4j/model/util/StatementsTest.java
index 67fc89a800a..5de39467b8a 100644
--- a/core/model/src/test/java/org/eclipse/rdf4j/model/util/StatementsTest.java
+++ b/core/model/src/test/java/org/eclipse/rdf4j/model/util/StatementsTest.java
@@ -8,6 +8,7 @@
package org.eclipse.rdf4j.model.util;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -15,7 +16,9 @@
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.impl.TreeModel;
import org.eclipse.rdf4j.model.vocabulary.FOAF;
@@ -77,4 +80,37 @@ public void testInvalidInput() {
// fall through.
}
}
+
+ @Test
+ public void testRDFStarReification() {
+ Model rdfStarModel = RDFStarTestHelper.createRDFStarModel();
+
+ Model reifiedModel = RDFStarTestHelper.createRDFReificationModel();
+
+ Model convertedModel1 = new LinkedHashModel();
+ rdfStarModel.forEach((s) -> Statements.convertRDFStarToReification(s, convertedModel1::add));
+ assertTrue("RDF* conversion to reification with implicit VF",
+ Models.isomorphic(reifiedModel, convertedModel1));
+
+ Model convertedModel2 = new LinkedHashModel();
+ rdfStarModel.forEach((s) -> Statements.convertRDFStarToReification(vf, s, convertedModel2::add));
+ assertTrue("RDF* conversion to reification with explicit VF",
+ Models.isomorphic(reifiedModel, convertedModel2));
+
+ Model convertedModel3 = new LinkedHashModel();
+ rdfStarModel.forEach((s) -> Statements.convertRDFStarToReification(vf, (t) -> vf.createBNode(t.stringValue()),
+ s, convertedModel3::add));
+ assertTrue("RDF* conversion to reification with explicit VF and custom BNode mapping",
+ Models.isomorphic(reifiedModel, convertedModel3));
+ }
+
+ @Test
+ public void testTripleToResourceMapper() {
+ Triple t1 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"),
+ vf.createLiteral("data"));
+ Triple t2 = vf.createTriple(vf.createIRI("http://example.com/1"), vf.createIRI("http://example.com/2"),
+ vf.createLiteral("data"));
+ assertEquals("Identical triples must produce the same blank node",
+ Statements.TRIPLE_BNODE_MAPPER.apply(t1), Statements.TRIPLE_BNODE_MAPPER.apply(t2));
+ }
}
diff --git a/core/pom.xml b/core/pom.xml
index 7af1182c0e1..f27040fa510 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-corepom
diff --git a/core/query/pom.xml b/core/query/pom.xml
index cfa92d1b3ec..567a23ea15d 100644
--- a/core/query/pom.xml
+++ b/core/query/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-core
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-queryRDF4J: Query
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/Binding.java b/core/query/src/main/java/org/eclipse/rdf4j/query/Binding.java
index cdd4103389e..79e6c30705a 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/Binding.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/Binding.java
@@ -18,40 +18,40 @@ public interface Binding extends Serializable {
/**
* Gets the name of the binding (e.g. the variable name).
- *
+ *
* @return The name of the binding.
*/
- public String getName();
+ String getName();
/**
* Gets the value of the binding. The returned value is never equal to null, such a "binding" is considered
* to be unbound.
- *
+ *
* @return The value of the binding, never null.
*/
- public Value getValue();
+ Value getValue();
/**
* Compares a binding object to another object.
- *
+ *
* @param o The object to compare this binding to.
* @return true if the other object is an instance of {@link Binding} and both their names and values are
* equal, false otherwise.
*/
@Override
- public boolean equals(Object o);
+ boolean equals(Object o);
/**
* The hash code of a binding is defined as the bit-wise XOR of the hash codes of its name and value:
- *
+ *
*
* name.hashCode() ˆ value.hashCode()
*
- *
+ *
* .
- *
+ *
* @return A hash code for the binding.
*/
@Override
- public int hashCode();
+ int hashCode();
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/BindingSet.java b/core/query/src/main/java/org/eclipse/rdf4j/query/BindingSet.java
index e68a35ef690..2f247ae2bf8 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/BindingSet.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/BindingSet.java
@@ -25,60 +25,60 @@ public interface BindingSet extends Iterable, Serializable {
* implementation is free to return the bindings in arbitrary order.
*/
@Override
- public Iterator iterator();
+ Iterator iterator();
/**
* Gets the names of the bindings in this BindingSet.
- *
+ *
* @return A set of binding names.
*/
- public Set getBindingNames();
+ Set getBindingNames();
/**
* Gets the binding with the specified name from this BindingSet.
- *
+ *
* @param bindingName The name of the binding.
* @return The binding with the specified name, or null if there is no such binding in this BindingSet.
*/
- public Binding getBinding(String bindingName);
+ Binding getBinding(String bindingName);
/**
* Checks whether this BindingSet has a binding with the specified name.
- *
+ *
* @param bindingName The name of the binding.
* @return true if this BindingSet has a binding with the specified name, false otherwise.
*/
- public boolean hasBinding(String bindingName);
+ boolean hasBinding(String bindingName);
/**
* Gets the value of the binding with the specified name from this BindingSet.
- *
+ *
* @param bindingName The name of the binding.
* @return The value of the binding with the specified name, or null if there is no such binding in this
* BindingSet.
*/
- public Value getValue(String bindingName);
+ Value getValue(String bindingName);
/**
* Returns the number of bindings in this BindingSet.
- *
+ *
* @return The number of bindings in this BindingSet.
*/
- public int size();
+ int size();
/**
* Compares a BindingSet object to another object.
- *
+ *
* @param o The object to compare this binding to.
* @return true if the other object is an instance of {@link BindingSet} and it contains the same set of
* bindings (disregarding order), false otherwise.
*/
@Override
- public boolean equals(Object o);
+ boolean equals(Object o);
/**
* The hash code of a binding is defined as the bit-wise XOR of the hash codes of its bindings:
- *
+ *
*
- *
+ *
* Note: the calculated hash code intentionally does not depend on the order in which the bindings are iterated
* over.
- *
+ *
* @return A hash code for the BindingSet.
*/
@Override
- public int hashCode();
+ int hashCode();
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQuery.java b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQuery.java
index 7d181787795..a29fea95d7d 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQuery.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQuery.java
@@ -12,5 +12,5 @@
*/
public interface BooleanQuery extends Query {
- public boolean evaluate() throws QueryEvaluationException;
+ boolean evaluate() throws QueryEvaluationException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandler.java b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandler.java
index 81fa41fa946..6e3e9e7aeee 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandler.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandler.java
@@ -10,7 +10,7 @@
/**
* An interface that indicates that this QueryResultHandler is capable of handling boolean results using the
* {@link #handleBoolean(boolean)} method.
- *
+ *
* @author Peter Ansell
*/
public interface BooleanQueryResultHandler extends QueryResultHandler {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandlerException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandlerException.java
index 31d1d03193f..40f5a9a2b35 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandlerException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/BooleanQueryResultHandlerException.java
@@ -9,7 +9,7 @@
/**
* An exception that can be thrown by an BooleanQueryResultHandler when it encounters an unrecoverable error.
- *
+ *
* @author Peter Ansell
*/
public class BooleanQueryResultHandlerException extends QueryResultHandlerException {
@@ -18,7 +18,7 @@ public class BooleanQueryResultHandlerException extends QueryResultHandlerExcept
/**
* Creates a new BooleanQueryResultHandlerException.
- *
+ *
* @param msg An error message.
*/
public BooleanQueryResultHandlerException(String msg) {
@@ -27,7 +27,7 @@ public BooleanQueryResultHandlerException(String msg) {
/**
* Creates a new BooleanQueryResultHandlerException wrapping another exception.
- *
+ *
* @param cause The cause of the exception.
*/
public BooleanQueryResultHandlerException(Throwable cause) {
@@ -36,7 +36,7 @@ public BooleanQueryResultHandlerException(Throwable cause) {
/**
* Creates a new BooleanQueryResultHandlerException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param cause The cause of the exception.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/Dataset.java b/core/query/src/main/java/org/eclipse/rdf4j/query/Dataset.java
index b6424dcaf36..cf62f1fa3d9 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/Dataset.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/Dataset.java
@@ -16,7 +16,7 @@
* using operations, which is the RDF merge of one or more graphs, a
* set of named graphs, and a single update graph for INSERT and DELETE. See
* SPARQL Query Language for RDF for more info.
- *
+ *
* @author Simon Schenk
* @author Arjohn Kampman
* @author James Leigh
@@ -27,25 +27,25 @@ public interface Dataset {
* Gets the default remove graph URIs of this dataset. An empty set indicates the the store's default behaviour
* should be used, if not otherwise indicated in the operation.
*/
- public Set getDefaultRemoveGraphs();
+ Set getDefaultRemoveGraphs();
/**
* Gets the default insert graph URI of this dataset. An null value indicates that the store's default behaviour
* should be used, if not otherwise indicated in the operation.
*/
- public IRI getDefaultInsertGraph();
+ IRI getDefaultInsertGraph();
/**
* Gets the default graph URIs of this dataset. An empty default graph set and a non-empty named graph set indicates
* that the default graph is an empty graph. However, if both the default graph set and the named graph set are
* empty, that indicates that the store's default behaviour should be used.
*/
- public Set getDefaultGraphs();
+ Set getDefaultGraphs();
/**
* Gets the named graph URIs of this dataset. An empty named graph set and a non-empty default graph set indicates
* that there are no named graphs. However, if both the default graph set and the named graph set are empty, that
* indicates that the store's default behaviour should be used.
*/
- public Set getNamedGraphs();
+ Set getNamedGraphs();
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQuery.java b/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQuery.java
index e7574301e0f..b463ac8d3b1 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQuery.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQuery.java
@@ -12,7 +12,7 @@
public interface GraphQuery extends Query {
- public GraphQueryResult evaluate() throws QueryEvaluationException;
+ GraphQueryResult evaluate() throws QueryEvaluationException;
- public void evaluate(RDFHandler handler) throws QueryEvaluationException, RDFHandlerException;
+ void evaluate(RDFHandler handler) throws QueryEvaluationException, RDFHandlerException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQueryResult.java
index 3d86678a0c3..c0c66dd612b 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/GraphQueryResult.java
@@ -15,7 +15,7 @@
* A representation of a query result as a sequence of {@link Statement} objects. Each query result consists of zero or
* more Statements and additionaly carries information about relevant namespace declarations. Note: take care to always
* close a GraphQueryResult after use to free any resources it keeps hold of.
- *
+ *
* @author Jeen Broekstra
*/
public interface GraphQueryResult extends QueryResult {
@@ -24,10 +24,10 @@ public interface GraphQueryResult extends QueryResult {
* Retrieves relevant namespaces from the query result.
* The contents of the Map may be modified after it is returned, as the initial return may be performed when the
* first RDF Statement is encountered.
- *
+ *
* @return a Map<String, String> object containing (prefix, namespace) pairs.
* @throws QueryEvaluationException
*/
- public Map getNamespaces() throws QueryEvaluationException;
+ Map getNamespaces() throws QueryEvaluationException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/IncompatibleOperationException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/IncompatibleOperationException.java
index 6994c5c3afb..d04d41c46c3 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/IncompatibleOperationException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/IncompatibleOperationException.java
@@ -9,13 +9,13 @@
/**
* An exception indicating that a string could not be parsed into an operation of the expected type by the parser.
- *
+ *
* @author jeen
*/
public class IncompatibleOperationException extends MalformedQueryException {
/**
- *
+ *
*/
private static final long serialVersionUID = -4926665776729656410L;
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/MalformedQueryException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/MalformedQueryException.java
index d1bc7c3bfa2..12074ad8fe8 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/MalformedQueryException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/MalformedQueryException.java
@@ -11,7 +11,7 @@
/**
* An exception indicating that a query could not be processed by the query parser, typically due to syntax errors.
- *
+ *
* @author jeen
* @author Herko ter Horst
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/Operation.java b/core/query/src/main/java/org/eclipse/rdf4j/query/Operation.java
index 56f994777b5..448a1c5aaf9 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/Operation.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/Operation.java
@@ -13,7 +13,7 @@
* An operation (e.g. a query or an update) on a repository that can be formulated in one of the supported query
* languages (for example SeRQL or SPARQL). It allows one to predefine bindings in the operation to be able to reuse the
* same operation with different bindings.
- *
+ *
* @author Jeen
*/
public interface Operation {
@@ -21,75 +21,75 @@ public interface Operation {
/**
* Binds the specified variable to the supplied value. Any value that was previously bound to the specified value
* will be overwritten.
- *
+ *
* @param name The name of the variable that should be bound.
* @param value The (new) value for the specified variable.
*/
- public void setBinding(String name, Value value);
+ void setBinding(String name, Value value);
/**
* Removes a previously set binding on the supplied variable. Calling this method with an unbound variable name has
* no effect.
- *
+ *
* @param name The name of the variable from which the binding is to be removed.
*/
- public void removeBinding(String name);
+ void removeBinding(String name);
/**
* Removes all previously set bindings.
*/
- public void clearBindings();
+ void clearBindings();
/**
* Retrieves the bindings that have been set on this operation.
- *
+ *
* @return A (possibly empty) set of operation variable bindings.
* @see #setBinding(String, Value)
*/
- public BindingSet getBindings();
+ BindingSet getBindings();
/**
* Specifies the dataset against which to execute an operation, overriding any dataset that is specified in the
* operation itself.
*/
- public void setDataset(Dataset dataset);
+ void setDataset(Dataset dataset);
/**
* Gets the dataset that has been set using {@link #setDataset(Dataset)}, if any.
*/
- public Dataset getDataset();
+ Dataset getDataset();
/**
* Determine whether evaluation results of this operation should include inferred statements (if any inferred
* statements are present in the repository). The default setting is 'true'.
- *
+ *
* @param includeInferred indicates whether inferred statements should be included in the result.
*/
- public void setIncludeInferred(boolean includeInferred);
+ void setIncludeInferred(boolean includeInferred);
/**
* Returns whether or not this operation will return inferred statements (if any are present in the repository).
- *
+ *
* @return true if inferred statements will be returned, false otherwise.
*/
- public boolean getIncludeInferred();
+ boolean getIncludeInferred();
/**
* Specifies the maximum time that an operation is allowed to run. The operation will be interrupted when it exceeds
* the time limit. Any consecutive requests to fetch query results will result in {@link QueryInterruptedException}s
* or {@link UpdateExecutionException}s (depending on whether the operation is a query or an update).
- *
- * @param maxExecTime The maximum query time, measured in seconds. A negative or zero value indicates an unlimited
- * execution time (which is the default).
+ *
+ * @param maxExecutionTimeSeconds The maximum query time, measured in seconds. A negative or zero value indicates an
+ * unlimited execution time (which is the default).
*/
- public void setMaxExecutionTime(int maxExecTime);
+ void setMaxExecutionTime(int maxExecutionTimeSeconds);
/**
* Returns the maximum operation execution time.
- *
+ *
* @return The maximum operation execution time, measured in seconds.
* @see #setMaxExecutionTime(int)
*/
- public int getMaxExecutionTime();
+ int getMaxExecutionTime();
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/Query.java b/core/query/src/main/java/org/eclipse/rdf4j/query/Query.java
index b38dd33225d..641a390cf4a 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/Query.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/Query.java
@@ -7,33 +7,97 @@
*******************************************************************************/
package org.eclipse.rdf4j.query;
+import org.eclipse.rdf4j.common.annotation.Experimental;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.query.explanation.Explanation;
+
/**
* A query on a repository that can be formulated in one of the supported query languages (for example SeRQL or SPARQL).
* It allows one to predefine bindings in the query to be able to reuse the same query with different bindings.
- *
+ *
* @author Arjohn Kampman
* @author jeen
*/
public interface Query extends Operation {
+ /**
+ * The different types of queries that RDF4J recognizes: boolean queries, graph queries, and tuple queries.
+ *
+ * @since 3.2.0
+ */
+ enum QueryType {
+ /**
+ * Boolean queries (such as the SPARQL ASK query form) return either {@code true} or {@code false} as the
+ * result.
+ */
+ BOOLEAN,
+ /**
+ * Graph queries (such as the SPARQL CONSTRUCT and DESCRIBE query form) return a sequence of RDF
+ * {@link Statement statements} as the result.
+ */
+ GRAPH,
+ /**
+ * Tuple queries (such as the SPARQL SELECT query form) return a sequence of {@link BindingSet sets of variable
+ * bindings} as the result.
+ */
+ TUPLE
+ }
+
/**
* Specifies the maximum time that a query is allowed to run. The query will be interrupted when it exceeds the time
* limit. Any consecutive requests to fetch query results will result in {@link QueryInterruptedException}s.
- *
+ *
* @param maxQueryTime The maximum query time, measured in seconds. A negative or zero value indicates an unlimited
* query time (which is the default).
* @deprecated since 2.0. Use {@link Operation#setMaxExecutionTime(int)} instead.
*/
@Deprecated
- public void setMaxQueryTime(int maxQueryTime);
+ void setMaxQueryTime(int maxQueryTime);
/**
* Returns the maximum query evaluation time.
- *
+ *
* @return The maximum query evaluation time, measured in seconds.
* @see #setMaxQueryTime(int)
* @deprecated since 2.0. Use {@link Operation#getMaxExecutionTime()} instead.
*/
@Deprecated
- public int getMaxQueryTime();
+ int getMaxQueryTime();
+
+ /**
+ *
+ * Explain how the query will be (or has been) executed/evaluated by returning an explanation of the query plan.
+ *
+ *
+ *
+ * This method is useful for understanding why a particular query is slow. The most useful level is Executed, but
+ * this takes as long as it takes to execute/evaluate the query.
+ *
+ *
+ *
+ * When timing a query you should keep in mind that the query performance will vary based on how much the JIT
+ * compiler has compiled the code (C1 vs C2) and based on what is or isn't cached in memory. If Timed explanations
+ * are considerably slower than Executed explanations the overhead with timing the query may be large on your system
+ * and should not be trusted.
+ *
+ *
+ *
+ * WARNING: This method is experimental and is subject to change or removal without warning. Same goes for the
+ * returned explanation. There is currently only partial support for this method in RDF4J and and
+ * UnsupportedOperationException where support is lacking.
+ *
+ *
+ * @param level The explanation level that should be used to create the explanation. Choose between: Unoptimized (as
+ * parsed without optimizations) , Optimized (as is actually going to be used), Executed (as was
+ * executed/evaluated, including some real performance metrics), Timed (as was executed/evaluated
+ * including all real performance metrics). Executed and Timed level can potentially be slow.
+ * @return The explanation that we generated, which can be viewed in a human readable format with toString(), as
+ * JSON or as a simplified query plan object structure.
+ */
+ @Experimental
+ default Explanation explain(Explanation.Level level) {
+ // with default implementation for backwards compatibility
+ throw new UnsupportedOperationException();
+ }
+
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryEvaluationException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryEvaluationException.java
index f6c84dd4660..b31af12a341 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryEvaluationException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryEvaluationException.java
@@ -11,7 +11,7 @@
/**
* An exception indicating that the evaluation of a query failed.
- *
+ *
* @author Arjohn Kampman
*/
public class QueryEvaluationException extends RDF4JException {
@@ -24,7 +24,7 @@ public QueryEvaluationException() {
/**
* Creates a new TupleQueryResultHandlerException.
- *
+ *
* @param msg An error message.
*/
public QueryEvaluationException(String msg) {
@@ -33,7 +33,7 @@ public QueryEvaluationException(String msg) {
/**
* Creates a new TupleQueryResultHandlerException wrapping another exception.
- *
+ *
* @param cause The cause of the exception.
*/
public QueryEvaluationException(Throwable cause) {
@@ -42,7 +42,7 @@ public QueryEvaluationException(Throwable cause) {
/**
* Creates a new TupleQueryResultHandlerException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param cause The cause of the exception.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryInterruptedException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryInterruptedException.java
index 2c32b82a610..60977054bcc 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryInterruptedException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryInterruptedException.java
@@ -10,7 +10,7 @@
/**
* An exception indicating that the evaluation of a query has been interrupted, for example because it took too long to
* complete.
- *
+ *
* @author Arjohn Kampman
*/
public class QueryInterruptedException extends QueryEvaluationException {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryLanguage.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryLanguage.java
index 28466035760..b16b421f11e 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryLanguage.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryLanguage.java
@@ -25,14 +25,14 @@ public class QueryLanguage {
/**
* SeRQL (Sesame RDF Query Language) is a Sesame-specific query language for RDF, which predates SPARQL.
- *
+ *
* @see The SeRQL user manual
*/
public static final QueryLanguage SERQL = new QueryLanguage("SeRQL");
/**
* SPARQL (Simple Protocol and RDF Query Language) is a W3C Recommendation for querying and updating RDF data.
- *
+ *
* @see SPARQL 1.1 Overview
*/
public static final QueryLanguage SPARQL = new QueryLanguage("SPARQL");
@@ -40,7 +40,7 @@ public class QueryLanguage {
/**
* SeRQO (Sesame RDF Query Language - Objects) is a Sesame-specific query language using a syntax suited less for
* human editing but for easy transfer over the wire.
- *
+ *
* @deprecated since 2.0. This language is no longer actively supported.
*/
@Deprecated
@@ -53,7 +53,7 @@ public class QueryLanguage {
/**
* List of known query languages.
*/
- private static List QUERY_LANGUAGES = new ArrayList(4);
+ private static List QUERY_LANGUAGES = new ArrayList<>(4);
/*--------------------*
* Static initializer *
@@ -78,7 +78,7 @@ public static Collection values() {
/**
* Registers the specified query language.
- *
+ *
* @param name The name of the query language, e.g. "SPARQL".
*/
public static QueryLanguage register(String name) {
@@ -96,7 +96,7 @@ public static void register(QueryLanguage ql) {
/**
* Returns the query language whose name matches the specified name.
- *
+ *
* @param qlName A query language name.
* @return The query language whose name matches the specified name, or null if there is no such query
* language.
@@ -126,7 +126,7 @@ public static QueryLanguage valueOf(String qlName) {
/**
* Creates a new QueryLanguage object.
- *
+ *
* @param name The (case-insensitive) name of the query language, e.g. "SPARQL".
*/
public QueryLanguage(String name) {
@@ -141,7 +141,7 @@ public QueryLanguage(String name) {
/**
* Gets the name of this query language.
- *
+ *
* @return A human-readable format name, e.g. "SPARQL".
*/
public String getName() {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResult.java
index ee869bd378d..bf6134444cd 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResult.java
@@ -8,10 +8,8 @@
package org.eclipse.rdf4j.query;
import java.util.Iterator;
-import java.util.stream.Stream;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
-import org.eclipse.rdf4j.common.iteration.Iterations;
import org.eclipse.rdf4j.common.iterator.CloseableIterationIterator;
/**
@@ -24,7 +22,7 @@ public interface QueryResult extends CloseableIteration iterator() {
- return new CloseableIterationIterator(this);
+ return new CloseableIterationIterator<>(this);
}
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandler.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandler.java
index ba9ee1c8694..7f3faa20d11 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandler.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandler.java
@@ -21,14 +21,14 @@
* If both boolean and tuple results are supported but they are not able to to be processed simultaneously, then a
* checked exception, either {@link BooleanQueryResultHandlerException} or {@link TupleQueryResultHandlerException},
* will be thrown to indicate this failure when the relevant methods are called.
- *
+ *
* @author Peter Ansell
*/
public interface QueryResultHandler {
/**
* Handles the specified boolean value.
- *
+ *
* @param value The boolean value to handle.
* @throws QueryResultHandlerException If there was an error during the handling of this value. This exception may
* be thrown if the {@link #startQueryResult(List)},
@@ -46,7 +46,7 @@ public interface QueryResultHandler {
* NOTE: If the format does not support links, it must silently ignore a call to this method.
*
* An accumulating handler should accumulate these links.
- *
+ *
* @see "link"
* @param linkUrls The URLs of the links to handle.
* @throws QueryResultHandlerException If there was an error handling the set of link URLs. This error is not thrown
@@ -58,7 +58,7 @@ public interface QueryResultHandler {
* Indicates the start of a sequence of Solutions. The supplied bindingNames are an indication of the values that
* are in the Solutions. For example, a SeRQL query like select X, Y from {X} P {Y} will have binding
* names X and Y.
- *
+ *
* @param bindingNames An ordered set of binding names.
* @throws TupleQueryResultHandlerException If there was an error during the starting of the query result handler.
* This exception may be thrown if the {@link #handleBoolean(boolean)}
@@ -69,11 +69,11 @@ public interface QueryResultHandler {
* methods were called before this method and the handler cannot process
* multiple sets of tuple results simultaneously.
*/
- public void startQueryResult(List bindingNames) throws TupleQueryResultHandlerException;
+ void startQueryResult(List bindingNames) throws TupleQueryResultHandlerException;
/**
* Indicates the end of a sequence of solutions.
- *
+ *
* @throws TupleQueryResultHandlerException If there was an error during the ending of the query result handler.
* This exception may be thrown if the {@link #handleBoolean(boolean)}
* method was called before this method and the handler cannot process both
@@ -82,11 +82,11 @@ public interface QueryResultHandler {
* @throws IllegalStateException If the {@link #endQueryResult()} was previously called for this handler
* or {@link #startQueryResult(List)} was NOT called before this method.
*/
- public void endQueryResult() throws TupleQueryResultHandlerException;
+ void endQueryResult() throws TupleQueryResultHandlerException;
/**
* Handles a solution.
- *
+ *
* @param bindingSet A single set of tuple results, with binding names bound to values. Each of the binding names in
* the solution must have previously been registered with the {@link #startQueryResult(List)}
* method.
@@ -98,5 +98,5 @@ public interface QueryResultHandler {
* @throws IllegalStateException If the {@link #endQueryResult()} method was called before this method or
* {@link #startQueryResult(List)} was NOT called before this method.
*/
- public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException;
+ void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandlerException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandlerException.java
index 036b36af458..57e152c5636 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandlerException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResultHandlerException.java
@@ -11,7 +11,7 @@
/**
* The super class of exceptions originating from {@link QueryResultHandler} implementations.
- *
+ *
* @author Peter Ansell
*/
public class QueryResultHandlerException extends RDF4JException {
@@ -20,7 +20,7 @@ public class QueryResultHandlerException extends RDF4JException {
/**
* Creates a new QueryResultHandlerException.
- *
+ *
* @param msg An error message.
*/
public QueryResultHandlerException(String msg) {
@@ -29,7 +29,7 @@ public QueryResultHandlerException(String msg) {
/**
* Creates a new QueryResultHandlerException wrapping another exception.
- *
+ *
* @param t The cause of the exception.
*/
public QueryResultHandlerException(Throwable t) {
@@ -38,7 +38,7 @@ public QueryResultHandlerException(Throwable t) {
/**
* Creates a new QueryResultHandlerException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param t The cause of the exception.
*/
@@ -46,4 +46,4 @@ public QueryResultHandlerException(String msg, Throwable t) {
super(msg, t);
}
-}
\ No newline at end of file
+}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResults.java b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResults.java
index d66102cab36..9f7690f56f5 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResults.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/QueryResults.java
@@ -32,10 +32,11 @@
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.ModelFactory;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
-import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.impl.DynamicModelFactory;
import org.eclipse.rdf4j.model.util.Models;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import org.eclipse.rdf4j.query.impl.BackgroundGraphResult;
@@ -66,7 +67,22 @@ public class QueryResults extends Iterations {
*/
public static Model asModel(CloseableIteration extends Statement, ? extends RDF4JException> iteration)
throws QueryEvaluationException {
- Model model = new LinkedHashModel();
+ return asModel(iteration, new DynamicModelFactory());
+ }
+
+ /**
+ * Get a {@link Model} containing all elements obtained from the specified query result.
+ *
+ * @param iteration the source iteration to get the statements from. This can be a {@link GraphQueryResult}, a
+ * {@link RepositoryResult<Statement>}, or any other instance of {@link CloseableIteration
+ * <Statement>}
+ * @param modelFactory the ModelFactory used to instantiate the model that gets returned.
+ * @return a {@link Model} containing all statements obtained from the specified source iteration.
+ */
+ public static Model asModel(CloseableIteration extends Statement, ? extends RDF4JException> iteration,
+ ModelFactory modelFactory)
+ throws QueryEvaluationException {
+ Model model = modelFactory.createEmptyModel();
addAll(iteration, model);
return model;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQuery.java b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQuery.java
index 644cbb20d30..b8725c60b09 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQuery.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQuery.java
@@ -9,8 +9,8 @@
public interface TupleQuery extends Query {
- public TupleQueryResult evaluate() throws QueryEvaluationException;
+ TupleQueryResult evaluate() throws QueryEvaluationException;
- public void evaluate(TupleQueryResultHandler handler)
+ void evaluate(TupleQueryResultHandler handler)
throws QueryEvaluationException, TupleQueryResultHandlerException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResult.java
index d8a569f90ef..3f50a2297e2 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResult.java
@@ -13,16 +13,16 @@
* A representation of a variable-binding query result as a sequence of {@link BindingSet} objects. Each query result
* consists of zero or more solutions, each of which represents a single query solution as a set of bindings. Note: take
* care to always close a TupleQueryResult after use to free any resources it keeps hold of.
- *
+ *
* @author jeen
*/
public interface TupleQueryResult extends QueryResult {
/**
* Gets the names of the bindings, in order of projection.
- *
+ *
* @return The binding names, in order of projection.
* @throws QueryEvaluationException
*/
- public List getBindingNames() throws QueryEvaluationException;
+ List getBindingNames() throws QueryEvaluationException;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResultHandlerException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResultHandlerException.java
index 42035b3544b..0344f63509d 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResultHandlerException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/TupleQueryResultHandlerException.java
@@ -18,7 +18,7 @@ public class TupleQueryResultHandlerException extends QueryResultHandlerExceptio
/**
* Creates a new TupleQueryResultHandlerException.
- *
+ *
* @param msg An error message.
*/
public TupleQueryResultHandlerException(String msg) {
@@ -27,7 +27,7 @@ public TupleQueryResultHandlerException(String msg) {
/**
* Creates a new TupleQueryResultHandlerException wrapping another exception.
- *
+ *
* @param cause The cause of the exception.
*/
public TupleQueryResultHandlerException(Throwable cause) {
@@ -36,7 +36,7 @@ public TupleQueryResultHandlerException(Throwable cause) {
/**
* Creates a new TupleQueryResultHandlerException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param cause The cause of the exception.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/UnsupportedQueryLanguageException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/UnsupportedQueryLanguageException.java
index 39d7cb2c7d0..9e215f868af 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/UnsupportedQueryLanguageException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/UnsupportedQueryLanguageException.java
@@ -17,7 +17,7 @@ public class UnsupportedQueryLanguageException extends RuntimeException {
/**
* Creates a new UnsupportedRDFormatException.
- *
+ *
* @param msg An error message.
*/
public UnsupportedQueryLanguageException(String msg) {
@@ -26,7 +26,7 @@ public UnsupportedQueryLanguageException(String msg) {
/**
* Creates a new UnsupportedRDFormatException.
- *
+ *
* @param cause The cause of the exception.
*/
public UnsupportedQueryLanguageException(Throwable cause) {
@@ -35,7 +35,7 @@ public UnsupportedQueryLanguageException(Throwable cause) {
/**
* Creates a new UnsupportedRDFormatException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param cause The cause of the exception.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/Update.java b/core/query/src/main/java/org/eclipse/rdf4j/query/Update.java
index dc0b9e6d46f..d2304682436 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/Update.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/Update.java
@@ -10,14 +10,14 @@
/**
* An update operation on a repository that can be formulated in one of the supported query languages (for example
* SPARQL).
- *
+ *
* @author Jeen
*/
public interface Update extends Operation {
/**
* Execute this update on the repository.
- *
+ *
* @throws UpdateExecutionException if the update could not be successfully completed.
*/
void execute() throws UpdateExecutionException;
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/UpdateExecutionException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/UpdateExecutionException.java
index 997c8e17f83..f91489f8962 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/UpdateExecutionException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/UpdateExecutionException.java
@@ -11,13 +11,13 @@
/**
* An exception indicating that the execution of an update failed.
- *
+ *
* @author Jeen
*/
public class UpdateExecutionException extends RDF4JException {
/**
- *
+ *
*/
private static final long serialVersionUID = 7969399526232927434L;
@@ -27,7 +27,7 @@ public UpdateExecutionException() {
/**
* Creates a new UpdateExecutionException.
- *
+ *
* @param msg An error message.
*/
public UpdateExecutionException(String msg) {
@@ -36,7 +36,7 @@ public UpdateExecutionException(String msg) {
/**
* Creates a new {@link UpdateExecutionException} wrapping another exception.
- *
+ *
* @param cause the cause of the exception
*/
public UpdateExecutionException(Throwable cause) {
@@ -45,7 +45,7 @@ public UpdateExecutionException(Throwable cause) {
/**
* Creates a new {@link UpdateExecutionException} wrapping another exception.
- *
+ *
* @param msg and error message.
* @param cause the cause of the exception
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/dawg/DAWGTestResultSetParseException.java b/core/query/src/main/java/org/eclipse/rdf4j/query/dawg/DAWGTestResultSetParseException.java
index a7554cbc130..06e32501ed3 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/dawg/DAWGTestResultSetParseException.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/dawg/DAWGTestResultSetParseException.java
@@ -19,7 +19,7 @@ public class DAWGTestResultSetParseException extends RDF4JException {
/**
* Creates a new DAWGTestResultSetParseException.
- *
+ *
* @param msg An error message.
*/
public DAWGTestResultSetParseException(String msg) {
@@ -28,7 +28,7 @@ public DAWGTestResultSetParseException(String msg) {
/**
* Creates a new DAWGTestResultSetParseException wrapping another exception.
- *
+ *
* @param cause The cause of the exception.
*/
public DAWGTestResultSetParseException(Throwable cause) {
@@ -37,7 +37,7 @@ public DAWGTestResultSetParseException(Throwable cause) {
/**
* Creates a new DAWGTestResultSetParseException wrapping another exception.
- *
+ *
* @param msg An error message.
* @param cause The cause of the exception.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/Explanation.java b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/Explanation.java
new file mode 100644
index 00000000000..7089be2dc20
--- /dev/null
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/Explanation.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.explanation;
+
+import org.eclipse.rdf4j.common.annotation.Experimental;
+
+/**
+ * This is an experimental feature. The interface may be changed, moved or potentially removed in a future release.
+ *
+ * The interface is used to implement query explanations (query plan)
+ *
+ * @since 3.2.0
+ */
+@Experimental
+public interface Explanation {
+
+ /**
+ * The different levels that the query explanation can be at.
+ *
+ * @since 3.2.0
+ */
+ @Experimental
+ enum Level {
+ Unoptimized, // simple parsed
+ Optimized, // parsed and optimized, which includes cost estimated
+ Executed, // plan as it was executed, which includes resultSizeActual
+ Timed, // plan as it was executed, including resultSizeActual and where each node has been timed
+ }
+
+ // location in maven hierarchy prevents us from using TupleExpr here
+ // TupleExpr asTupleExpr();
+
+ GenericPlanNode toGenericPlanNode();
+
+ String toJson();
+
+}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/ExplanationImpl.java b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/ExplanationImpl.java
new file mode 100644
index 00000000000..d3bc83645e6
--- /dev/null
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/ExplanationImpl.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.explanation;
+
+import org.eclipse.rdf4j.common.annotation.Experimental;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * This is an experimental feature. It may be changed, moved or potentially removed in a future release.
+ *
+ * @since 3.2.0
+ */
+@Experimental
+public class ExplanationImpl implements Explanation {
+
+ private final GenericPlanNode genericPlanNode;
+
+ public ExplanationImpl(GenericPlanNode genericPlanNode, boolean timedOut) {
+ this.genericPlanNode = genericPlanNode;
+ if (timedOut) {
+ genericPlanNode.setTimedOut(timedOut);
+ }
+ }
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ @Override
+ public GenericPlanNode toGenericPlanNode() {
+ return genericPlanNode;
+ }
+
+ @Override
+ public String toJson() {
+ try {
+ // TODO: Consider removing pretty printer
+ return this.objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.PUBLIC_ONLY)
+ .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.NONE)
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL)
+ .writerWithDefaultPrettyPrinter()
+ .writeValueAsString(toGenericPlanNode());
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return toGenericPlanNode().toString();
+ }
+
+}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/GenericPlanNode.java b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/GenericPlanNode.java
new file mode 100644
index 00000000000..90aab4f4b00
--- /dev/null
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/explanation/GenericPlanNode.java
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.explanation;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import org.eclipse.rdf4j.common.annotation.Experimental;
+
+/**
+ * This is an experimental feature. The interface may be changed, moved or potentially removed in a future release.
+ *
+ * The interface is used to implement query explanations (query plan)
+ *
+ * @since 3.2.0
+ */
+@Experimental
+public class GenericPlanNode {
+
+ public static final String UNKNOWN = "UNKNOWN";
+
+ // The name of the node, eg. "Join" or "Join (HashJoinIteration)".
+ private String type;
+
+ // Retrieving the explanation timed out while the query was executed.
+ private Boolean timedOut;
+
+ // The cost estimate that the query planner calculated for this node. Value has no meaning outside of this
+ // explanation and is only used to compare and order the nodes in the query plan.
+ private Double costEstimate;
+
+ // The number of results that this node was estimated to produce.
+ private Double resultSizeEstimate;
+
+ // The actual number of results that this node produced while the query was executed.
+ private Long resultSizeActual;
+
+ // The total time in milliseconds that this node-tree (all children and so on) used while the query was executed.
+ // selfTimeActual is the amount of time that this node used by itself (eg. totalTimeActual - sum of
+ // plans[0..n].totalTimeActual)
+ private Double totalTimeActual;
+
+ // true if this node introduces a new scope
+ private Boolean newScope;
+
+ // the name of the algorithm used as an annotation to the node type
+ private String algorithm;
+
+ // Child plans for this node
+ private List plans = new ArrayList<>();
+
+ public GenericPlanNode() {
+ }
+
+ public GenericPlanNode(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getPlans() {
+ return plans.isEmpty() ? null : plans; // for simplified json
+ }
+
+ public void setPlans(List plans) {
+ this.plans = plans;
+ }
+
+ public void addPlans(GenericPlanNode... children) {
+ this.plans.addAll(Arrays.asList(children));
+ }
+
+ /**
+ * The cost estimate that the query planner calculated for this node. Value has no meaning outside of this
+ * explanation and is only used to compare and order the nodes in the query plan.
+ *
+ * @return
+ */
+ public Double getCostEstimate() {
+ return costEstimate;
+ }
+
+ public void setCostEstimate(Double costEstimate) {
+ if (costEstimate >= 0) {
+ this.costEstimate = costEstimate;
+ }
+ }
+
+ /**
+ * The number of results that this node was estimated to produce.
+ *
+ * @return
+ */
+ public Double getResultSizeEstimate() {
+ return resultSizeEstimate;
+ }
+
+ public void setResultSizeEstimate(Double resultSizeEstimate) {
+ if (resultSizeEstimate >= 0) {
+ this.resultSizeEstimate = resultSizeEstimate;
+ }
+ }
+
+ /**
+ * The actual number of results that this node produced while the query was executed.
+ *
+ * @return
+ */
+ public Long getResultSizeActual() {
+ return resultSizeActual;
+ }
+
+ public void setResultSizeActual(Long resultSizeActual) {
+ if (resultSizeActual >= 0) {
+ this.resultSizeActual = resultSizeActual;
+ }
+ }
+
+ /**
+ * The total time in milliseconds that this node-tree (all children and so on) used while the query was executed.
+ *
+ * @return
+ */
+ public Double getTotalTimeActual() {
+ // Not all nodes have their own totalTimeActual, but it can easily be calculated by looking that the child plans
+ // (recursively). We need this value to calculate the selfTimeActual.
+ if (totalTimeActual == null) {
+ double sum = plans.stream()
+ .map(GenericPlanNode::getTotalTimeActual)
+ .filter(Objects::nonNull)
+ .mapToDouble(d -> d)
+ .sum();
+
+ if (sum > 0) {
+ return sum;
+ }
+ }
+ return totalTimeActual;
+ }
+
+ public void setTotalTimeActual(Double totalTimeActual) {
+ if (totalTimeActual >= 0) {
+ this.totalTimeActual = totalTimeActual;
+ }
+ }
+
+ public void setTimedOut(Boolean timedOut) {
+ this.timedOut = timedOut;
+ }
+
+ public Boolean getTimedOut() {
+ return timedOut;
+ }
+
+ /**
+ * The time that this node used by itself (eg. totalTimeActual - sum of plans[0..n].totalTimeActual)
+ *
+ * @return
+ */
+ public Double getSelfTimeActual() {
+
+ if (totalTimeActual == null) {
+ return null;
+ }
+
+ double childTime = plans
+ .stream()
+ .map(GenericPlanNode::getTotalTimeActual)
+ .filter(Objects::nonNull)
+ .mapToDouble(t -> t)
+ .sum();
+
+ return totalTimeActual - childTime;
+
+ }
+
+ /**
+ *
+ * @return true if this node introduces a new scope
+ */
+ public Boolean isNewScope() {
+ return newScope;
+ }
+
+ public void setNewScope(boolean newScope) {
+ if (newScope) {
+ this.newScope = true;
+ } else {
+ this.newScope = null;
+ }
+ }
+
+ /**
+ * Join nodes can use various algorithms for joining data.
+ *
+ * @return the name of the algorithm.
+ */
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Human readable string. Do not attempt to parse this.
+ *
+ * @return
+ */
+ @Override
+ public String toString() {
+
+ StringBuilder sb = new StringBuilder();
+
+ String newLine = System.getProperty("line.separator");
+
+ if (timedOut != null && timedOut) {
+ sb.append("Timed out while retrieving explanation! Explanation may be incomplete!").append(newLine);
+ sb.append("You can change the timeout by setting .setMaxExecutionTime(...) on your query.")
+ .append(newLine)
+ .append(newLine);
+ }
+
+ sb.append(type);
+ if (newScope != null && newScope) {
+ sb.append(" (new scope)");
+ }
+
+ if (algorithm != null) {
+ sb.append(" (").append(algorithm).append(")");
+ }
+ appendCostAnnotation(sb);
+ sb.append(newLine);
+ plans.forEach(child -> sb.append(Arrays.stream(child.toString().split(newLine))
+ .map(c -> " " + c)
+ .reduce((a, b) -> a + newLine + b)
+ .orElse("") + newLine));
+
+ return sb.toString();
+ }
+
+ /**
+ *
+ * @return Human readable number. Eg. 12.1M for 1212213.4 and UNKNOWN for -1.
+ */
+ static private String toHumanReadableNumber(Double number) {
+ String humanReadbleString;
+ if (number == null) {
+ humanReadbleString = UNKNOWN;
+ } else if (number == Double.POSITIVE_INFINITY) {
+ humanReadbleString = "∞";
+ } else if (number > 1_000_000) {
+ humanReadbleString = Math.round(number / 100_000) / 10.0 + "M";
+ } else if (number > 1_000) {
+ humanReadbleString = Math.round(number / 100) / 10.0 + "K";
+ } else if (number >= 0) {
+ humanReadbleString = Math.round(number) + "";
+ } else {
+ humanReadbleString = UNKNOWN;
+ }
+
+ return humanReadbleString;
+ }
+
+ /**
+ *
+ * @return Human readable number. Eg. 12.1M for 1212213.4 and UNKNOWN for -1.
+ */
+ static private String toHumanReadableNumber(Long number) {
+ String humanReadbleString;
+ if (number == null) {
+ humanReadbleString = UNKNOWN;
+ } else if (number == Double.POSITIVE_INFINITY) {
+ humanReadbleString = "∞";
+ } else if (number > 1_000_000) {
+ humanReadbleString = number / 100_000 / 10.0 + "M";
+ } else if (number > 1_000) {
+ humanReadbleString = number / 100 / 10.0 + "K";
+ } else if (number >= 0) {
+ humanReadbleString = number + "";
+ } else {
+ humanReadbleString = UNKNOWN;
+ }
+
+ return humanReadbleString;
+ }
+
+ /**
+ *
+ * @return Human readable time.
+ */
+ static private String toHumanReadableTime(Double millis) {
+ String humanReadbleString;
+
+ if (millis == null) {
+ humanReadbleString = UNKNOWN;
+ } else if (millis > 1_000) {
+ humanReadbleString = Math.round(millis / 100) / 10.0 + "s";
+ } else if (millis >= 100) {
+ humanReadbleString = Math.round(millis) + "ms";
+ } else if (millis >= 10) {
+ humanReadbleString = Math.round(millis * 10) / 10.0 + "ms";
+ } else if (millis >= 1) {
+ humanReadbleString = Math.round(millis * 100) / 100.0 + "ms";
+ } else if (millis >= 0) {
+ humanReadbleString = Math.round(millis * 1000) / 1000.0 + "ms";
+ } else {
+ humanReadbleString = UNKNOWN;
+ }
+
+ return humanReadbleString;
+ }
+
+ private void appendCostAnnotation(StringBuilder sb) {
+ String costs = Stream.of(
+ "costEstimate=" + toHumanReadableNumber(getCostEstimate()),
+ "resultSizeEstimate=" + toHumanReadableNumber(getResultSizeEstimate()),
+ "resultSizeActual=" + toHumanReadableNumber(getResultSizeActual()),
+ "totalTimeActual=" + toHumanReadableTime(getTotalTimeActual()),
+ "selfTimeActual=" + toHumanReadableTime(getSelfTimeActual()))
+ .filter(s -> !s.endsWith(UNKNOWN)) // simple but hacky way of removing essentially null values
+ .reduce((a, b) -> a + ", " + b)
+ .orElse("");
+
+ if (!costs.isEmpty()) {
+ sb.append(" (").append(costs).append(")");
+ }
+ }
+
+}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractOperation.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractOperation.java
index a4cbf31a6a3..7854da1f53c 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractOperation.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractOperation.java
@@ -14,7 +14,7 @@
/**
* Abstract super class of all operation types.
- *
+ *
* @author Jeen Broekstra
*/
public abstract class AbstractOperation implements Operation {
@@ -29,7 +29,7 @@ public abstract class AbstractOperation implements Operation {
protected boolean includeInferred = true;
- private int maxExecutionTime = 0;
+ private int maxExecutionTimeSeconds = 0;
/*--------------*
* Constructors *
@@ -86,12 +86,12 @@ public boolean getIncludeInferred() {
}
@Override
- public void setMaxExecutionTime(int maxExecutionTime) {
- this.maxExecutionTime = maxExecutionTime;
+ public void setMaxExecutionTime(int maxExecutionTimeSeconds) {
+ this.maxExecutionTimeSeconds = maxExecutionTimeSeconds;
}
@Override
public int getMaxExecutionTime() {
- return maxExecutionTime;
+ return maxExecutionTimeSeconds;
}
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractQuery.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractQuery.java
index 28497eb04df..b5c94f25611 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractQuery.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/AbstractQuery.java
@@ -31,8 +31,8 @@ protected AbstractQuery() {
@Deprecated
@Override
- public void setMaxQueryTime(int maxQueryTime) {
- setMaxExecutionTime(maxQueryTime);
+ public void setMaxQueryTime(int maxQueryTimeSeconds) {
+ setMaxExecutionTime(maxQueryTimeSeconds);
}
@@ -41,4 +41,5 @@ public void setMaxQueryTime(int maxQueryTime) {
public int getMaxQueryTime() {
return getMaxExecutionTime();
}
+
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/BackgroundGraphResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/BackgroundGraphResult.java
index f88e005fbd6..43c9247a27f 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/BackgroundGraphResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/BackgroundGraphResult.java
@@ -25,7 +25,7 @@
/**
* Provides concurrent access to statements as they are being parsed when instances of this class are run as Threads.
- *
+ *
* @author James Leigh
*/
public class BackgroundGraphResult extends IterationWrapper
@@ -48,7 +48,7 @@ public class BackgroundGraphResult extends IterationWrapper queue;
public BackgroundGraphResult(RDFParser parser, InputStream in, Charset charset, String baseURI) {
- this(new QueueCursor(10), parser, in, charset, baseURI);
+ this(new QueueCursor<>(10), parser, in, charset, baseURI);
}
public BackgroundGraphResult(QueueCursor queue, RDFParser parser, InputStream in, Charset charset,
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/EmptyBindingSet.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/EmptyBindingSet.java
index 5b53de8686c..882f3c73c9a 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/EmptyBindingSet.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/EmptyBindingSet.java
@@ -18,7 +18,7 @@
/**
* An immutable empty BindingSet.
- *
+ *
* @author Arjohn Kampman
*/
public class EmptyBindingSet implements BindingSet {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/FallbackDataset.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/FallbackDataset.java
index 43be28d275a..88d53f90b9f 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/FallbackDataset.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/FallbackDataset.java
@@ -19,15 +19,17 @@
public class FallbackDataset implements Dataset, Serializable {
/**
- *
+ *
*/
private static final long serialVersionUID = 5866540736738270376L;
public static Dataset fallback(Dataset primary, Dataset fallback) {
- if (primary == null)
+ if (primary == null) {
return fallback;
- if (fallback == null)
+ }
+ if (fallback == null) {
return primary;
+ }
return new FallbackDataset(primary, fallback);
}
@@ -45,32 +47,36 @@ private FallbackDataset(Dataset primary, Dataset secondary) {
@Override
public Set getDefaultGraphs() {
Set set = primary.getDefaultGraphs();
- if (set == null || set.isEmpty())
+ if (set == null || set.isEmpty()) {
return fallback.getDefaultGraphs();
+ }
return set;
}
@Override
public Set getNamedGraphs() {
Set set = primary.getNamedGraphs();
- if (set == null || set.isEmpty())
+ if (set == null || set.isEmpty()) {
return fallback.getNamedGraphs();
+ }
return set;
}
@Override
public IRI getDefaultInsertGraph() {
IRI graph = primary.getDefaultInsertGraph();
- if (graph == null)
+ if (graph == null) {
return fallback.getDefaultInsertGraph();
+ }
return graph;
}
@Override
public Set getDefaultRemoveGraphs() {
Set set = primary.getDefaultRemoveGraphs();
- if (set == null || set.isEmpty())
+ if (set == null || set.isEmpty()) {
return fallback.getDefaultRemoveGraphs();
+ }
return set;
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingGraphQueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingGraphQueryResult.java
index ccc396468e6..0bac2cc0dac 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingGraphQueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingGraphQueryResult.java
@@ -20,7 +20,7 @@
/**
* An iterating implementation of the {@link GraphQueryResult} interface.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingTupleQueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingTupleQueryResult.java
index 59ff27c4b49..a1238310a21 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingTupleQueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/IteratingTupleQueryResult.java
@@ -38,7 +38,7 @@ public class IteratingTupleQueryResult extends IterationWrapperThe supplied list of binding names is assumed
* to be constant; care should be taken that the contents of this list doesn't change after supplying it to
* this solution.
- *
+ *
* @param bindingNames The binding names, in order of projection.
*/
public IteratingTupleQueryResult(List bindingNames, Iterable extends BindingSet> bindingSets) {
@@ -53,7 +53,7 @@ public IteratingTupleQueryResult(List bindingNames, Iterator extends B
* Creates a query result object with the supplied binding names. The supplied list of binding names is assumed
* to be constant; care should be taken that the contents of this list doesn't change after supplying it to
* this solution.
- *
+ *
* @param bindingNames The binding names, in order of projection.
*/
public IteratingTupleQueryResult(List bindingNames,
@@ -72,5 +72,4 @@ public IteratingTupleQueryResult(List bindingNames,
public List getBindingNames() throws QueryEvaluationException {
return bindingNames;
}
-
}
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/ListBindingSet.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/ListBindingSet.java
index 25f0952d7ae..11d1a1bc196 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/ListBindingSet.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/ListBindingSet.java
@@ -20,7 +20,7 @@
/**
* A List-based implementation of the {@link BindingSet} interface.
- *
+ *
* @author Arjohn Kampman
*/
public class ListBindingSet extends AbstractBindingSet {
@@ -35,7 +35,7 @@ public class ListBindingSet extends AbstractBindingSet {
* Creates a new List-based BindingSet containing the supplied bindings. The supplied list of binding names is
* assumed to be constant; care should be taken that the contents of this list doesn't change after supplying
* it to this solution. The number of supplied values must be equal to the number of the binding names.
- *
+ *
* @param names The binding names.
* @param values The binding values.
*/
@@ -47,7 +47,7 @@ public ListBindingSet(List names, Value... values) {
* Creates a new List-based BindingSet containing the supplied bindings. The supplied lists are assumed to be
* constant; care should be taken that the contents of these lists don't change after supplying them to this
* solution. The number of supplied values must be equal to the number of the binding names.
- *
+ *
* @param bindingNames The binding names.
* @param values The binding values.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MapBindingSet.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MapBindingSet.java
index 4bf4934e6a5..d441123c0b2 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MapBindingSet.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MapBindingSet.java
@@ -33,7 +33,7 @@ public MapBindingSet() {
/**
* Creates a new Map-based BindingSet with the specified initial capacity. Bindings can be added to this binding set
* using the {@link #addBinding} methods.
- *
+ *
* @param capacity The initial capacity of the created BindingSet object.
*/
public MapBindingSet(int capacity) {
@@ -43,7 +43,7 @@ public MapBindingSet(int capacity) {
/**
* Adds a binding to the binding set.
- *
+ *
* @param name The binding's name.
* @param value The binding's value.
*/
@@ -53,7 +53,7 @@ public void addBinding(String name, Value value) {
/**
* Adds a binding to the binding set.
- *
+ *
* @param binding The binding to add to the binding set.
*/
public void addBinding(Binding binding) {
@@ -62,7 +62,7 @@ public void addBinding(Binding binding) {
/**
* Removes a binding from the binding set.
- *
+ *
* @param name The binding's name.
*/
public void removeBinding(String name) {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MutableTupleQueryResult.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MutableTupleQueryResult.java
index 8743f0e860c..87aea2cb613 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MutableTupleQueryResult.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/MutableTupleQueryResult.java
@@ -25,7 +25,7 @@
* An implementation of the {@link TupleQueryResult} interface that stores the complete query result in memory. The
* query results in a MutableTupleQueryResult can be iterated over multiple times and can also be iterated over in
* reverse order.
- *
+ *
* @author Arjohn Kampman
*/
public class MutableTupleQueryResult implements TupleQueryResult, Cloneable {
@@ -61,7 +61,7 @@ public MutableTupleQueryResult(Collection bindingN
* Creates a query result table with the supplied binding names. The supplied list of binding names is assumed
* to be constant; care should be taken that the contents of this list doesn't change after supplying it to
* this solution.
- *
+ *
* @param bindingNames The binding names, in order of projection.
*/
public MutableTupleQueryResult(Collection bindingNames, Collection extends BindingSet> bindingSets) {
@@ -161,7 +161,7 @@ public void afterLast() {
* {@link #previous}, if any. (If the table contains no binding sets, the new element becomes the sole element on
* the table.) The new element is inserted before the implicit cursor: a subsequent call to next() would be
* unaffected, and a subsequent call to previous() would return the new binding set.
- *
+ *
* @param bindingSet The binding set to insert.
*/
public void insert(BindingSet bindingSet) {
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/QueueCursor.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/QueueCursor.java
index 9d3e42793b9..efcdc3e1cc8 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/QueueCursor.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/QueueCursor.java
@@ -16,14 +16,14 @@
/**
* Makes working with a queue easier by adding the methods {@link #done()} and {@link #toss(Exception)} and
* automatically converting the exception into a QueryEvaluationException with an appropriate stack trace.
- *
+ *
* @author James Leigh
*/
public class QueueCursor extends QueueIteration {
/**
* Creates an QueueCursor with the given (fixed) capacity and default access policy.
- *
+ *
* @param capacity the capacity of this queue
*/
public QueueCursor(int capacity) {
@@ -32,7 +32,7 @@ public QueueCursor(int capacity) {
/**
* Creates an QueueCursor with the given (fixed) capacity and the specified access policy.
- *
+ *
* @param capacity the capacity of this queue
* @param fair if true then queue accesses for threads blocked on insertion or removal, are processed
* in FIFO order; if false the access order is unspecified.
@@ -45,7 +45,7 @@ public QueueCursor(int capacity, boolean fair) {
* Creates an QueueCursor with the given {@link BlockingQueue} as its backing queue.
* It may not be threadsafe to modify or access the given {@link BlockingQueue} from other locations. This method
* only enables the default {@link ArrayBlockingQueue} to be overridden.
- *
+ *
* @param queue A BlockingQueue that is not used in other locations, but will be used as the backing Queue
* implementation for this cursor.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleBinding.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleBinding.java
index a7d460ca3a8..bcb87e578f7 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleBinding.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleBinding.java
@@ -12,7 +12,7 @@
/**
* An implementation of the {@link Binding} interface.
- *
+ *
* @author Jeen Broekstra
*/
public class SimpleBinding implements Binding {
@@ -25,7 +25,7 @@ public class SimpleBinding implements Binding {
/**
* Creates a binding object with the supplied name and value.
- *
+ *
* @param name The binding's name.
* @param value The binding's value.
*/
diff --git a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleDataset.java b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleDataset.java
index 49b0e236224..285cce64ff1 100644
--- a/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleDataset.java
+++ b/core/query/src/main/java/org/eclipse/rdf4j/query/impl/SimpleDataset.java
@@ -17,7 +17,7 @@
/**
* A simple implementation of the {@link Dataset} interface.
- *
+ *
* @author Arjohn Kampman
* @author James Leigh
*/
@@ -50,7 +50,7 @@ public void addDefaultRemoveGraph(IRI graphURI) {
/**
* Removes a graph URI from the set of default remove graph URIs.
- *
+ *
* @return true if the URI was removed from the set, false if the set did not contain the URI.
*/
public boolean removeDefaultRemoveGraph(IRI graphURI) {
@@ -86,7 +86,7 @@ public void addDefaultGraph(IRI graphURI) {
/**
* Removes a graph URI from the set of default graph URIs.
- *
+ *
* @return true if the URI was removed from the set, false if the set did not contain the URI.
*/
public boolean removeDefaultGraph(IRI graphURI) {
@@ -110,7 +110,7 @@ public void addNamedGraph(IRI graphURI) {
/**
* Removes a graph URI from the set of named graph URIs.
- *
+ *
* @return true if the URI was removed from the set, false if the set did not contain the URI.
*/
public boolean removeNamedGraph(IRI graphURI) {
diff --git a/core/query/src/test/java/org/eclipse/rdf4j/query/BindingSetTest.java b/core/query/src/test/java/org/eclipse/rdf4j/query/BindingSetTest.java
index d0ad009873d..9f63b5ebfe5 100644
--- a/core/query/src/test/java/org/eclipse/rdf4j/query/BindingSetTest.java
+++ b/core/query/src/test/java/org/eclipse/rdf4j/query/BindingSetTest.java
@@ -13,7 +13,7 @@
/**
* Unit tests for BindingSet implementations.
- *
+ *
* @author jeen
*/
public abstract class BindingSetTest {
@@ -37,7 +37,7 @@ public void testEqualsHashcode() {
/**
* Creates two equal, but differently ordered, BindingSet objects.
- *
+ *
* @return an array of two equal but differently ordered BindingSets.
*/
protected abstract T[] createTwoEqualReorderedBindingSets();
diff --git a/core/query/src/test/java/org/eclipse/rdf4j/query/impl/ListBindingSetTest.java b/core/query/src/test/java/org/eclipse/rdf4j/query/impl/ListBindingSetTest.java
index ddad783bc6f..bb79daf6fed 100644
--- a/core/query/src/test/java/org/eclipse/rdf4j/query/impl/ListBindingSetTest.java
+++ b/core/query/src/test/java/org/eclipse/rdf4j/query/impl/ListBindingSetTest.java
@@ -15,7 +15,7 @@
/**
* Unit tests for {@link ListBindingSet}
- *
+ *
* @author Jeen Broekstra
*/
public class ListBindingSetTest extends BindingSetTest {
diff --git a/core/query/src/test/java/org/eclipse/rdf4j/query/impl/MapBindingSetTest.java b/core/query/src/test/java/org/eclipse/rdf4j/query/impl/MapBindingSetTest.java
index fda9530c224..5161e343c8c 100644
--- a/core/query/src/test/java/org/eclipse/rdf4j/query/impl/MapBindingSetTest.java
+++ b/core/query/src/test/java/org/eclipse/rdf4j/query/impl/MapBindingSetTest.java
@@ -12,7 +12,7 @@
/**
* Unit tests for {@link MapBindingSet}
- *
+ *
* @author Jeen Broekstra
*/
public class MapBindingSetTest extends BindingSetTest {
diff --git a/core/queryalgebra/evaluation/pom.xml b/core/queryalgebra/evaluation/pom.xml
index 31cab23f964..f3f7a0040f8 100644
--- a/core/queryalgebra/evaluation/pom.xml
+++ b/core/queryalgebra/evaluation/pom.xml
@@ -4,7 +4,7 @@
org.eclipse.rdf4jrdf4j-queryalgebra
- 3.1.5-SNAPSHOT
+ 3.2.2-SNAPSHOTrdf4j-queryalgebra-evaluationRDF4J: Query algebra - evaluation
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/AbstractQueryPreparer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/AbstractQueryPreparer.java
index df4c2fce308..e1cffb53cb6 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/AbstractQueryPreparer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/AbstractQueryPreparer.java
@@ -34,6 +34,7 @@
import org.eclipse.rdf4j.query.UpdateExecutionException;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.UpdateExpr;
+import org.eclipse.rdf4j.query.explanation.Explanation;
import org.eclipse.rdf4j.query.impl.IteratingGraphQueryResult;
import org.eclipse.rdf4j.query.impl.IteratingTupleQueryResult;
import org.eclipse.rdf4j.query.parser.ParsedBooleanQuery;
@@ -126,6 +127,11 @@ public boolean evaluate() throws QueryEvaluationException {
}
}
}
+
+ @Override
+ public Explanation explain(Explanation.Level level) {
+ throw new UnsupportedOperationException();
+ }
}
class TupleQueryImpl extends AbstractParserQuery implements TupleQuery {
@@ -180,6 +186,11 @@ public void evaluate(TupleQueryResultHandler handler)
TupleQueryResult queryResult = evaluate();
QueryResults.report(queryResult, handler);
}
+
+ @Override
+ public Explanation explain(Explanation.Level level) {
+ throw new UnsupportedOperationException();
+ }
}
class GraphQueryImpl extends AbstractParserQuery implements GraphQuery {
@@ -284,6 +295,11 @@ public void evaluate(RDFHandler handler) throws QueryEvaluationException, RDFHan
GraphQueryResult queryResult = evaluate();
QueryResults.report(queryResult, handler);
}
+
+ @Override
+ public Explanation explain(Explanation.Level level) {
+ throw new UnsupportedOperationException();
+ }
}
class UpdateImpl extends AbstractParserUpdate {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategy.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategy.java
index 161bbe12714..b294c5a00f8 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategy.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategy.java
@@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation;
+import org.eclipse.rdf4j.common.annotation.Experimental;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.BindingSet;
@@ -21,7 +22,7 @@
/**
* Evaluates {@link TupleExpr}s and {@link ValueExpr}s.
- *
+ *
* @author Arjohn Kampman
* @author James Leigh
*/
@@ -30,27 +31,27 @@ public interface EvaluationStrategy extends FederatedServiceResolver {
/**
* Retrieve the {@link FederatedService} registered for serviceUrl. If there is no service registered for
* serviceUrl, a new {@link SPARQLFederatedService} is created and registered.
- *
+ *
* @param serviceUrl URL of the service.
* @return the {@link FederatedService} registered for the serviceUrl.
* @throws QueryEvaluationException
* @see org.eclipse.rdf4j.query.algebra.evaluation.federation.FederatedServiceResolver#getService(java.lang.String)
*/
@Override
- public FederatedService getService(String serviceUrl) throws QueryEvaluationException;
+ FederatedService getService(String serviceUrl) throws QueryEvaluationException;
/**
* Set the {@link QueryOptimizerPipeline} to use for optimizing any incoming queries.
- *
+ *
* @param pipeline the {@link QueryOptimizerPipeline}.
* @see #optimize(TupleExpr, EvaluationStatistics, BindingSet)
* @since 3.0
*/
- public void setOptimizerPipeline(QueryOptimizerPipeline pipeline);
+ void setOptimizerPipeline(QueryOptimizerPipeline pipeline);
/**
* Execute the {@link QueryOptimizerPipeline} on the given {@link TupleExpr} to optimize its execution plan.
- *
+ *
* @param expr the {@link TupleExpr} to optimize.
* @param evaluationStatistics the {@link EvaluationStatistics} of the data source, to be used for query planning.
* @param bindings a-priori bindings supplied for the query, which can potentially be inlined.
@@ -58,45 +59,45 @@ public interface EvaluationStrategy extends FederatedServiceResolver {
* @see #setOptimizerPipeline(QueryOptimizerPipeline)
* @since 3.0
*/
- public TupleExpr optimize(TupleExpr expr, EvaluationStatistics evaluationStatistics,
+ TupleExpr optimize(TupleExpr expr, EvaluationStatistics evaluationStatistics,
BindingSet bindings);
/**
* Evaluates the tuple expression against the supplied triple source with the specified set of variable bindings as
* input.
- *
+ *
* @param expr The Service Expression to evaluate
* @param serviceUri TODO
* @param bindings The variables bindings iterator to use for evaluating the expression, if applicable.
* @return A closeable iterator over all of variable binding sets that match the tuple expression.
*/
- public CloseableIteration evaluate(Service expr, String serviceUri,
+ CloseableIteration evaluate(Service expr, String serviceUri,
CloseableIteration bindings) throws QueryEvaluationException;
/**
* Evaluates the tuple expression against the supplied triple source with the specified set of variable bindings as
* input.
- *
+ *
* @param expr The Tuple Expression to evaluate
* @param bindings The variables bindings to use for evaluating the expression, if applicable.
* @return A closeable iterator over the variable binding sets that match the tuple expression.
*/
- public CloseableIteration evaluate(TupleExpr expr, BindingSet bindings)
+ CloseableIteration evaluate(TupleExpr expr, BindingSet bindings)
throws QueryEvaluationException;
/**
* Gets the value of this expression.
- *
+ *
* @param expr
* @param bindings The variables bindings to use for evaluating the expression, if applicable.
* @return The Value that this expression evaluates to, or null if the expression could not be evaluated.
*/
- public Value evaluate(ValueExpr expr, BindingSet bindings)
+ Value evaluate(ValueExpr expr, BindingSet bindings)
throws ValueExprEvaluationException, QueryEvaluationException;
/**
* Evaluates the boolean expression on the supplied TripleSource object.
- *
+ *
* @param expr
* @param bindings The variables bindings to use for evaluating the expression, if applicable.
* @return The result of the evaluation.
@@ -104,6 +105,28 @@ public Value evaluate(ValueExpr expr, BindingSet bindings)
* two incompatible operands. When thrown, the result of the boolean expression
* is neither true nor false , but unknown.
*/
- public boolean isTrue(ValueExpr expr, BindingSet bindings)
+ boolean isTrue(ValueExpr expr, BindingSet bindings)
throws ValueExprEvaluationException, QueryEvaluationException;
+
+ /**
+ * Enable or disable results size tracking for the query plan. Useful to determine which parts of a query plan
+ * generated the most data.
+ *
+ * @param trackResultSize true to enable tracking.
+ */
+ @Experimental
+ default void setTrackResultSize(boolean trackResultSize) {
+ // no-op for backwards compatibility
+ }
+
+ /**
+ * Enable or disable time tracking for the query plan. Useful to determine which parts of a query plan take the most
+ * time to evaluate.
+ *
+ * @param trackTime true to enable tracking.
+ */
+ @Experimental
+ default void setTrackTime(boolean trackTime) {
+ // no-op for backwards compatibility
+ }
}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategyFactory.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategyFactory.java
index 85d75b3b6d8..4ba0ddb68ab 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategyFactory.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/EvaluationStrategyFactory.java
@@ -21,7 +21,7 @@ public interface EvaluationStrategyFactory {
* Set the number of query solutions the {@link EvaluationStrategy} will keep in main memory before it attempts to
* sync to a temporary disk cache. If set to 0, no disk caching will occur. EvaluationStrategies that provide no
* disk caching functionality are free to ignore this parameter.
- *
+ *
* @param threshold the number of query solutions that the EvaluationStrategy can cache in main memory before
* attempting disk sync.
*/
@@ -36,7 +36,7 @@ public interface EvaluationStrategyFactory {
/**
* Set a {@link QueryOptimizerPipeline} to be used for query execution planning by the {@link EvaluationStrategy}.
- *
+ *
* @param pipeline a {@link QueryOptimizerPipeline}
*/
void setOptimizerPipeline(QueryOptimizerPipeline pipeline);
@@ -44,7 +44,7 @@ public interface EvaluationStrategyFactory {
/**
* Get the {@link QueryOptimizerPipeline} that this factory will inject into the {@link EvaluationStrategy}, if any.
* If no {@link QueryOptimizerPipeline} is defined, the {@link EvaluationStrategy} itself determines the pipeline.
- *
+ *
* @return a {@link QueryOptimizerPipeline}, or {@link Optional#empty()} if no pipeline is set on this factory.
*/
Optional getOptimizerPipeline();
@@ -52,7 +52,7 @@ public interface EvaluationStrategyFactory {
/**
* Returns the {@link EvaluationStrategy} to use to evaluate queries for the given {@link Dataset} and
* {@link TripleSource}.
- *
+ *
* @param dataset the DataSet to evaluate queries against.
* @param tripleSource the TripleSource to evaluate queries against.
* @param evaluationStatistics the store evaluation statistics to use for query optimization.
@@ -61,4 +61,24 @@ public interface EvaluationStrategyFactory {
EvaluationStrategy createEvaluationStrategy(Dataset dataset, TripleSource tripleSource,
EvaluationStatistics evaluationStatistics);
+ /**
+ * Returns the status of the result size tracking for the query plan. Useful to determine which parts of a query
+ * plan generated the most data.
+ *
+ * @return true if result size tracking is enabled.
+ */
+ default boolean isTrackResultSize() {
+ return false;
+ }
+
+ /**
+ * Enable or disable results size tracking for the query plan. Useful to determine which parts of a query plan
+ * generated the most data.
+ *
+ * @param trackResultSize true to enable tracking.
+ */
+ default void setTrackResultSize(boolean trackResultSize) {
+ // no-op for backwards compatibility
+ }
+
}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryBindingSet.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryBindingSet.java
index fcf6f429ef9..f15e59239e7 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryBindingSet.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryBindingSet.java
@@ -59,7 +59,7 @@ public void addAll(BindingSet bindingSet) {
/**
* Adds a new binding to the binding set. The binding's name must not already be part of this binding set.
- *
+ *
* @param binding The binding to add this this BindingSet.
*/
public void addBinding(Binding binding) {
@@ -68,7 +68,7 @@ public void addBinding(Binding binding) {
/**
* Adds a new binding to the binding set. The binding's name must not already be part of this binding set.
- *
+ *
* @param name The binding's name, must not be bound in this binding set already.
* @param value The binding's value.
*/
@@ -152,4 +152,4 @@ public boolean equals(Object other) {
return super.equals(other);
}
}
-}
\ No newline at end of file
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContext.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContext.java
index 2867da5bd79..9a9894042b1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContext.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContext.java
@@ -23,7 +23,7 @@ public class QueryContext {
private static final String QUERY_PREPARER_ATTRIBUTE = QueryPreparer.class.getName();
- private static final ThreadLocal queryContext = new ThreadLocal();
+ private static final ThreadLocal queryContext = new ThreadLocal<>();
public static QueryContext getQueryContext() {
return queryContext.get();
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContextInitializer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContextInitializer.java
index 3f8d0009230..aac02b8e6b3 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContextInitializer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryContextInitializer.java
@@ -14,14 +14,14 @@ public interface QueryContextInitializer {
/**
* Called after a QueryContext has begun.
- *
+ *
* @param ctx
*/
void init(QueryContext ctx);
/**
* Called before a QueryContext has ended.
- *
+ *
* @param ctx
*/
void destroy(QueryContext ctx);
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizer.java
index 0987731683b..e3e2642ce1e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizer.java
@@ -13,7 +13,7 @@
/**
* Interface used by {@link EvaluationStrategy}s to optimize the {@link TupleExpr} prior to evaluating the query.
- *
+ *
* @author James Leigh
* @author Arjohn Kampman
* @see QueryOptimizerPipeline
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizerPipeline.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizerPipeline.java
index 5f754bd68d3..1e8a40b6f85 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizerPipeline.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/QueryOptimizerPipeline.java
@@ -12,7 +12,7 @@
/**
* A pipeline of {@link QueryOptimizer}s that, when executed in order on a {@link TupleExpr}, convert that
* {@link TupleExpr} to a more optimal query execution plan.
- *
+ *
* @author Jeen Broekstra
*
*/
@@ -20,7 +20,7 @@ public interface QueryOptimizerPipeline {
/**
* Get the optimizers that make up this pipeline.
- *
+ *
* @return an {@link Iterable} of {@link QueryOptimizer}s
*/
Iterable getOptimizers();
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java
new file mode 100644
index 00000000000..8a806bd7863
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation;
+
+import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+
+public interface RDFStarTripleSource extends TripleSource {
+ /**
+ * Gets all Triple nodes that have a specific subject, predicate and/or object. All three parameters may be null to
+ * indicate wildcards.
+ *
+ * @param subj A Resource specifying the triple's subject, or null for a wildcard.
+ * @param pred A URI specifying the triple's predicate, or null for a wildcard.
+ * @param obj A Value specifying the triple's object, or null for a wildcard.
+ * @return An iterator over the relevant triples.
+ * @throws QueryEvaluationException If the rdf star triple source failed to get the statements.
+ */
+ public CloseableIteration extends Triple, QueryEvaluationException> getRdfStarTriples(Resource subj, IRI pred,
+ Value obj) throws QueryEvaluationException;
+
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java
index db9ee34a00b..36ebacd74ab 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java
@@ -25,7 +25,7 @@ public interface TripleSource {
* Gets all statements that have a specific subject, predicate and/or object. All three parameters may be null to
* indicate wildcards. Optionally a (set of) context(s) may be specified in which case the result will be restricted
* to statements matching one or more of the specified contexts.
- *
+ *
* @param subj A Resource specifying the subject, or null for a wildcard.
* @param pred A URI specifying the predicate, or null for a wildcard.
* @param obj A Value specifying the object, or null for a wildcard.
@@ -39,7 +39,7 @@ public CloseableIteration extends Statement, QueryEvaluationException> getStat
/**
* Gets a ValueFactory object that can be used to create URI-, blank node- and literal objects.
- *
+ *
* @return a ValueFactory object for this TripleSource.
*/
public ValueFactory getValueFactory();
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/ValueExprEvaluationException.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/ValueExprEvaluationException.java
index 32bfa5c1e1d..a2a1e7458c1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/ValueExprEvaluationException.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/ValueExprEvaluationException.java
@@ -13,7 +13,7 @@
/**
* An exception indicating that a {@link ValueExpr} could not be evaluated due to illegal or incompatible values. When
* thrown, the result of the evaluation should be considered to be "unknown".
- *
+ *
* @author Arjohn Kampman
*/
public class ValueExprEvaluationException extends QueryEvaluationException {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/FederatedServiceResolverImpl.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/FederatedServiceResolverImpl.java
index 645344a846c..dd0377f9f4e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/FederatedServiceResolverImpl.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/FederatedServiceResolverImpl.java
@@ -13,7 +13,7 @@
*
* Lookup can be done via the serviceUrl using the method {@link #getService(String)}. If there is no service for the
* specified url, a {@link SPARQLFederatedService} is created and registered for future use.
- *
+ *
* @author Andreas Schwarte
* @author James Leigh
* @deprecated since 2.3 use {@link org.eclipse.rdf4j.repository.sparql.federation.SPARQLServiceResolver}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/JoinExecutorBase.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/JoinExecutorBase.java
index 7414c279112..0c5ffdde29c 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/JoinExecutorBase.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/JoinExecutorBase.java
@@ -17,7 +17,7 @@
* Base class for any join parallel join executor. Note that this class extends {@link LookAheadIteration} and thus any
* implementation of this class is applicable for pipelining when used in a different thread (access to shared variables
* is synchronized).
- *
+ *
* @author Andreas Schwarte
* @deprecated since 2.3 use {@link org.eclipse.rdf4j.repository.sparql.federation.JoinExecutorBase}
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/RepositoryFederatedService.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/RepositoryFederatedService.java
index 1f02c395537..1daab3456c7 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/RepositoryFederatedService.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/RepositoryFederatedService.java
@@ -11,7 +11,7 @@
/**
* Federated Service wrapping the {@link Repository} to communicate with a SPARQL endpoint.
- *
+ *
* @author Andreas Schwarte
* @deprecated since 2.3 use {@link org.eclipse.rdf4j.repository.sparql.federation.RepositoryFederatedService}
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/SPARQLFederatedService.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/SPARQLFederatedService.java
index d50bf831cf6..29966a40131 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/SPARQLFederatedService.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/SPARQLFederatedService.java
@@ -12,7 +12,7 @@
/**
* Federated Service wrapping the {@link SPARQLRepository} to communicate with a SPARQL endpoint.
- *
+ *
* @author Andreas Schwarte
* @deprecated since 2.3 use {@link org.eclipse.rdf4j.repository.sparql.federation.SPARQLFederatedService}
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceCrossProductIteration.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceCrossProductIteration.java
index 6517ea8ac25..0ebef634a71 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceCrossProductIteration.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceCrossProductIteration.java
@@ -19,7 +19,7 @@
* inner iteration. See {@link SPARQLFederatedService}. Example:
- *
+ *
* @author Andreas Schwarte
*/
@Deprecated
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinConversionIteration.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinConversionIteration.java
index 2535e8d664f..043d1a35cf2 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinConversionIteration.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinConversionIteration.java
@@ -16,7 +16,7 @@
/**
* Inserts original bindings into the result, uses ?__rowIdx to resolve original bindings. See
* {@link ServiceJoinIterator} and {@link SPARQLFederatedService}.
- *
+ *
* @author Andreas Schwarte
* @deprecated since 2.3 use {@link org.eclipse.rdf4j.repository.sparql.federation.ServiceJoinConversionIteration}
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinIterator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinIterator.java
index a7a7647c6ce..3840e4ded24 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinIterator.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/federation/ServiceJoinIterator.java
@@ -16,7 +16,7 @@
/**
* Iterator for efficient SERVICE evaluation (vectored). SERVICE is the right handside argument of this join.
- *
+ *
* @author Andreas Schwarte
*/
public class ServiceJoinIterator extends JoinExecutorBase {
@@ -27,7 +27,7 @@ public class ServiceJoinIterator extends JoinExecutorBase {
/**
* Construct a service join iteration to use vectored evaluation. The constructor automatically starts evaluation.
- *
+ *
* @param leftIter
* @param service
* @param bindings
@@ -47,9 +47,9 @@ protected void handleBindings() throws Exception {
Var serviceRef = service.getServiceRef();
String serviceUri;
- if (serviceRef.hasValue())
+ if (serviceRef.hasValue()) {
serviceUri = serviceRef.getValue().stringValue();
- else {
+ } else {
// case 2: the service ref is not defined beforehand
// => use a fallback to the naive evaluation.
// exceptions occurring here must NOT be silenced!
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/BooleanCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/BooleanCast.java
index 8fd5102aa1a..77d1408a193 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/BooleanCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/BooleanCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:boolean.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.BooleanCast} instead
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DateTimeCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DateTimeCast.java
index ca3d01d56c0..ea193457374 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DateTimeCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DateTimeCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:dateTime.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DateTimeCast} instead.
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DecimalCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DecimalCast.java
index 3cfdf4b7f23..e36ade770f2 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DecimalCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DecimalCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:decimal.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DecimalCast} instead.
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DoubleCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DoubleCast.java
index db59c82c0f6..a2cec8f1a70 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DoubleCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/DoubleCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:double.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DoubleCast} instead.
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FloatCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FloatCast.java
index 58fd5046b07..b092d67ffaf 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FloatCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FloatCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:float.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.FloatCast} instead.
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FunctionRegistry.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FunctionRegistry.java
index 250a7a83331..5683e396fb5 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FunctionRegistry.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/FunctionRegistry.java
@@ -24,7 +24,7 @@ private static class FunctionRegistryHolder {
/**
* Gets the default FunctionRegistry.
- *
+ *
* @return The default registry.
*/
public static FunctionRegistry getInstance() {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/IntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/IntegerCast.java
index 2b6dd093ed9..f90ecae1005 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/IntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/IntegerCast.java
@@ -10,7 +10,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:integer .
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.IntegerCast} instead
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/StringCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/StringCast.java
index 32dd30cb90e..698cf650bde 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/StringCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/StringCast.java
@@ -10,10 +10,10 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:string.
- *
+ *
* @author Arjohn Kampman
* @deprecated use {@link org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.StringCast} instead
*/
@Deprecated
public class StringCast extends org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.StringCast {
-}
\ No newline at end of file
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/TupleFunctionRegistry.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/TupleFunctionRegistry.java
index 213b488234f..729a3f98ceb 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/TupleFunctionRegistry.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/TupleFunctionRegistry.java
@@ -15,7 +15,7 @@ public class TupleFunctionRegistry extends ServiceRegistrySPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Day implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Hours.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Hours.java
index 1ec6b1f47fd..2c61b2dd7aa 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Hours.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Hours.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} HOURS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Hours implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Minutes.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Minutes.java
index 2d4c5120185..4eab02519e4 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Minutes.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Minutes.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} MINUTES, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Minutes implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Month.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Month.java
index 502d2ebeb01..ea38d544b82 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Month.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Month.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} MONTH, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Month implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Now.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Now.java
index 7e28250cdbb..f550babb2a3 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Now.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Now.java
@@ -24,7 +24,7 @@
/**
* The SPARQL built-in {@link Function} NOW, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Now implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Seconds.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Seconds.java
index fdd6e0ee209..3f7743b86d2 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Seconds.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Seconds.java
@@ -25,7 +25,7 @@
/**
* The SPARQL built-in {@link Function} SECONDS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Seconds implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Timezone.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Timezone.java
index 31f280b642a..5f10111db46 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Timezone.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Timezone.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} TIMEZONE, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Timezone implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Tz.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Tz.java
index e504767250a..6eeddabf407 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Tz.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Tz.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} TZ, as defined in SPARQL
* Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Tz implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Year.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Year.java
index 1b6d8235cc8..a623187e094 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Year.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/datetime/Year.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} YEAR, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Year implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/MD5.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/MD5.java
index 6515d407e82..ffc5212dcb9 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/MD5.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/MD5.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} MD5, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class MD5 extends HashFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA1.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA1.java
index 9d9082f7f1c..654b7cb061b 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA1.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA1.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} SHA1, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class SHA1 extends HashFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA256.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA256.java
index f5876ac940b..3cb8d1cca40 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA256.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA256.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} SHA256, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class SHA256 extends HashFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA384.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA384.java
index f38c9a66bb8..1770fa43949 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA384.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA384.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} SHA384, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class SHA384 extends HashFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA512.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA512.java
index 9a0e2074b20..0b591a5843e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA512.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/hash/SHA512.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} SHA512, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class SHA512 extends HashFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Abs.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Abs.java
index 0b1e4778ad3..3fd164b1eca 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Abs.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Abs.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} ABS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Abs implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Ceil.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Ceil.java
index 0a8696c3ad1..927a37ea5e2 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Ceil.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Ceil.java
@@ -22,7 +22,7 @@
/**
* The SPARQL built-in {@link Function} CEIL, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Ceil implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Floor.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Floor.java
index d7ec7c875f4..d5d515c70fc 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Floor.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Floor.java
@@ -22,7 +22,7 @@
/**
* The SPARQL built-in {@link Function} FLOOR, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Floor implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Rand.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Rand.java
index 84bbeaa2ce8..64c29a7fec6 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Rand.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Rand.java
@@ -18,7 +18,7 @@
/**
* The SPARQL built-in {@link Function} RAND, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Rand implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Round.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Round.java
index da98f7e7569..40c45f0e821 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Round.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/numeric/Round.java
@@ -22,7 +22,7 @@
/**
* The SPARQL built-in {@link Function} ROUND, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Round implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/STRUUID.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/STRUUID.java
index 690865f4016..e2856b5d6d4 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/STRUUID.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/STRUUID.java
@@ -16,7 +16,7 @@
/**
* The SPARQL built-in {@link Function} UUID, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class STRUUID implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrDt.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrDt.java
index c9ab600251d..50e07e08b55 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrDt.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrDt.java
@@ -18,7 +18,7 @@
/**
* The SPARQL built-in {@link Function} STRDT, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class StrDt implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrLang.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrLang.java
index 9f44ddd17bb..52b440a293a 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrLang.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/StrLang.java
@@ -17,7 +17,7 @@
/**
* The SPARQL built-in {@link Function} STRLANG, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class StrLang implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/UUID.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/UUID.java
index 5c9a800c327..b8e5412cc1d 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/UUID.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/rdfterm/UUID.java
@@ -16,7 +16,7 @@
/**
* The SPARQL built-in {@link Function} UUID, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class UUID implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Concat.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Concat.java
index 19d8f94622a..4957908e45e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Concat.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Concat.java
@@ -19,7 +19,7 @@
/**
* The SPARQL built-in {@link Function} CONCAT, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Concat implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Contains.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Contains.java
index 4c56c0875af..04e30e48ced 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Contains.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Contains.java
@@ -19,7 +19,7 @@
/**
* The SPARQL built-in {@link Function} CONTAINS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class Contains implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/EncodeForUri.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/EncodeForUri.java
index 97b28329bfc..41109ea2e97 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/EncodeForUri.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/EncodeForUri.java
@@ -20,7 +20,7 @@
/**
* The SPARQL built-in {@link Function} ENCODE_FOR_URI, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
* @author Arjohn Kampman
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/LowerCase.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/LowerCase.java
index 92968ec520e..8e1cb2d0451 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/LowerCase.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/LowerCase.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} LCASE, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class LowerCase implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Replace.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Replace.java
index 45007a25a1c..234c0d1f475 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Replace.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Replace.java
@@ -22,7 +22,7 @@
/**
* The SPARQL built-in {@link Function} REPLACE, as defined in
* SPARQL Query Language for RDF.
- *
+ *
* @author Jeen Broekstra
*/
public class Replace implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrAfter.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrAfter.java
index 9926948c8a5..29e739dba50 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrAfter.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrAfter.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} STRAFTER, as defined in
* SPARQL Query Language for RDF.
- *
+ *
* @author Jeen Broekstra
*/
public class StrAfter implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrBefore.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrBefore.java
index 670acc02f76..312c2ce73fa 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrBefore.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrBefore.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} STRBEFORE, as defined in
* SPARQL Query Language for RDF.
- *
+ *
* @author Jeen Broekstra
*/
public class StrBefore implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrEnds.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrEnds.java
index 855840cd4ef..76bc55fd8c9 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrEnds.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrEnds.java
@@ -19,7 +19,7 @@
/**
* The SPARQL built-in {@link Function} STRENDS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class StrEnds implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrLen.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrLen.java
index 2c4443bc625..981431882d1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrLen.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrLen.java
@@ -19,7 +19,7 @@
/**
* The SPARQL built-in {@link Function} STRLEN, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class StrLen implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrStarts.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrStarts.java
index d1fc263d428..83dc96a8684 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrStarts.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/StrStarts.java
@@ -19,7 +19,7 @@
/**
* The SPARQL built-in {@link Function} STRSTARTS, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class StrStarts implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Substring.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Substring.java
index 6368b450a79..3ee0a460dc6 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Substring.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/Substring.java
@@ -23,7 +23,7 @@
/**
* The SPARQL built-in {@link Function} SUBSTR, as defined in
* SPARQL Query Language for RDF.
- *
+ *
* @author Jeen Broekstra
*/
public class Substring implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/UpperCase.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/UpperCase.java
index abe0180f05d..68ceff2a7e8 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/UpperCase.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/string/UpperCase.java
@@ -21,7 +21,7 @@
/**
* The SPARQL built-in {@link Function} UCASE, as defined in
* SPARQL Query Language for RDF
- *
+ *
* @author Jeen Broekstra
*/
public class UpperCase implements Function {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/IsTripleFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/IsTripleFunction.java
new file mode 100644
index 00000000000..11d2f962f24
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/IsTripleFunction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation.function.triple;
+
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
+
+/**
+ * Function that return "true"^^xsd:boolean if its argument is RDF* Triple otherwise return "false"^^xsd:boolean the
+ * function's IRI uses RDF namespace to match the other functions in the package
+ *
+ * @author damyan.ognyanov
+ *
+ */
+public class IsTripleFunction implements Function {
+ @Override
+ public String getURI() {
+ return RDF.NAMESPACE + "isTriple";
+ }
+
+ @Override
+ public Value evaluate(ValueFactory vf, Value... args) throws ValueExprEvaluationException {
+ if (args.length != 1) {
+ throw new ValueExprEvaluationException("expect exactly 1 argument");
+ }
+ return vf.createLiteral((args[0] instanceof Triple));
+ }
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/StatementFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/StatementFunction.java
new file mode 100644
index 00000000000..61cd97af282
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/StatementFunction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation.function.triple;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
+
+/**
+ * Function constructing RDF* Triple from its 3 arguments reused the IRI of rdf:Statement as name
+ *
+ * @author damyan.ognyanov
+ *
+ */
+public class StatementFunction implements Function {
+ @Override
+ public String getURI() {
+ return RDF.STATEMENT.toString();
+ }
+
+ @Override
+ public Value evaluate(ValueFactory vf, Value... args) throws ValueExprEvaluationException {
+ if (args.length != 3) {
+ throw new ValueExprEvaluationException("expect exactly 3 arguments");
+ }
+ if (!(args[0] instanceof Resource)) {
+ throw new ValueExprEvaluationException("arg1 must be Resource");
+ }
+ if (!(args[1] instanceof IRI)) {
+ throw new ValueExprEvaluationException("arg2 must be IRI");
+ }
+ if (!(args[2] instanceof Value)) {
+ throw new ValueExprEvaluationException("arg3 must be Value");
+ }
+ return vf.createTriple((Resource) args[0], (IRI) args[1], args[2]);
+ }
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleObjectFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleObjectFunction.java
new file mode 100644
index 00000000000..f53aaca5127
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleObjectFunction.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation.function.triple;
+
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
+
+/**
+ * Function returning the object component of RDF* Triple reused the IRI of rdf:object as name
+ *
+ * @author damyan.ognyanov
+ *
+ */
+public class TripleObjectFunction implements Function {
+ @Override
+ public String getURI() {
+ return RDF.OBJECT.toString();
+ }
+
+ @Override
+ public Value evaluate(ValueFactory vf, Value... args) throws ValueExprEvaluationException {
+ if (args.length != 1) {
+ throw new ValueExprEvaluationException("expect exactly 1 argument");
+ }
+ if (!(args[0] instanceof Triple)) {
+ throw new ValueExprEvaluationException("arg1 must be a Triple");
+ }
+ return ((Triple) args[0]).getObject();
+ }
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TriplePredicateFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TriplePredicateFunction.java
new file mode 100644
index 00000000000..a8d1eba070a
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TriplePredicateFunction.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation.function.triple;
+
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
+
+/**
+ * Function returning the predicate component of RDF* Triple reused the IRI of rdf:predicate as name
+ *
+ * @author damyan.ognyanov
+ *
+ */
+public class TriplePredicateFunction implements Function {
+ @Override
+ public String getURI() {
+ return RDF.PREDICATE.toString();
+ }
+
+ @Override
+ public Value evaluate(ValueFactory vf, Value... args) throws ValueExprEvaluationException {
+ if (args.length != 1) {
+ throw new ValueExprEvaluationException("expect exactly 1 argument");
+ }
+ if (!(args[0] instanceof Triple)) {
+ throw new ValueExprEvaluationException("arg1 must be a Triple");
+ }
+ return ((Triple) args[0]).getPredicate();
+ }
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleSubjectFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleSubjectFunction.java
new file mode 100644
index 00000000000..e8d2b0606fe
--- /dev/null
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/triple/TripleSubjectFunction.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.algebra.evaluation.function.triple;
+
+import org.eclipse.rdf4j.model.Triple;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
+import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
+
+/**
+ * Function returning the subject component of RDF* Triple reused the IRI of rdf:subject as name
+ *
+ * @author damyan.ognyanov
+ *
+ */
+public class TripleSubjectFunction implements Function {
+ @Override
+ public String getURI() {
+ return RDF.SUBJECT.toString();
+ }
+
+ @Override
+ public Value evaluate(ValueFactory vf, Value... args) throws ValueExprEvaluationException {
+ if (args.length != 1) {
+ throw new ValueExprEvaluationException("expect exactly 1 argument");
+ }
+ if (!(args[0] instanceof Triple)) {
+ throw new ValueExprEvaluationException("arg1 must be a Triple");
+ }
+ return ((Triple) args[0]).getSubject();
+ }
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/BooleanCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/BooleanCast.java
index 1a407717ff9..9baf86e30bc 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/BooleanCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/BooleanCast.java
@@ -17,12 +17,11 @@
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:boolean.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ByteCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ByteCast.java
index dc4e1ce2117..11564464dd1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ByteCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ByteCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:byte .
- *
+ *
* @author Jeen Broekstra
* @see XMLSchema#BYTE
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/CastFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/CastFunction.java
index 62825f3d635..419aca302b7 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/CastFunction.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/CastFunction.java
@@ -20,7 +20,7 @@
/**
* Abstract superclass for {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function}s that cast an argument
* to an XML Schema datatype.
- *
+ *
* @author Jeen Broekstra
* @see XMLSchema
*/
@@ -60,7 +60,7 @@ public Literal evaluate(ValueFactory valueFactory, Value... args) throws ValueEx
/**
* Convert the supplied value to a literal of the function output datatype.
- *
+ *
* @param vf the valueFactory to use
* @param v a value that is not a string-typed literal, and not a literal of the same datatype as the function
* output datatype.
@@ -71,14 +71,14 @@ public Literal evaluate(ValueFactory valueFactory, Value... args) throws ValueEx
/**
* Get the specific XML Schema datatype which this function returns.
- *
+ *
* @return an XML Schema datatype IRI
*/
protected abstract IRI getXsdDatatype();
/**
* Returns a prefixed name representation of the specific datatype that this function returns
- *
+ *
* @return a prefixed name, e.g. 'xsd:integer'.
*/
protected String getXsdName() {
@@ -87,7 +87,7 @@ protected String getXsdName() {
/**
* Verifies that the supplied lexical value is valid for the datatype.
- *
+ *
* @param lexicalValue a lexical value
* @return true if the lexical value is valid for the datatype, false otherwise.
*/
@@ -95,7 +95,7 @@ protected String getXsdName() {
/**
* Creates a {@link ValueExprEvaluationException} that signals a type error.
- *
+ *
* @param arg the function argument value.
* @param cause root cause throwable. May be null.
* @return a {@link ValueExprEvaluationException} with a standardized message and wrapped cause.
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DateTimeCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DateTimeCast.java
index 5bdc67ef22d..a206e904a28 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DateTimeCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DateTimeCast.java
@@ -17,12 +17,11 @@
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:dateTime.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DecimalCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DecimalCast.java
index 81253840b95..9ffba147beb 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DecimalCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DecimalCast.java
@@ -16,12 +16,11 @@
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:decimal.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DoubleCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DoubleCast.java
index c6d7a8bab06..658ce278b25 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DoubleCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/DoubleCast.java
@@ -18,7 +18,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:double.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/FloatCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/FloatCast.java
index 2bce4e41b40..6979197ec74 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/FloatCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/FloatCast.java
@@ -18,7 +18,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:float.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntCast.java
index 3f5ab2e501d..fe70b7d7650 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:int .
- *
+ *
* @author Jeen Broekstra
*/
public class IntCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCast.java
index 98c8ec78aad..81db02a84dd 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:integer .
- *
+ *
* @author Jeen Broekstra
*/
public class IntegerCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCastFunction.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCastFunction.java
index 0324825a0c0..f9c2313e0b8 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCastFunction.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/IntegerCastFunction.java
@@ -21,7 +21,7 @@
/**
* Abstract superclass for {@link CastFunction}s that cast their arguments to an xsd:integer or one of its derived
* types.
- *
+ *
* @author Jeen Broekstra
*/
public abstract class IntegerCastFunction extends CastFunction {
@@ -68,7 +68,7 @@ protected Literal convert(ValueFactory valueFactory, Value value) throws ValueEx
/**
* create a {@link Literal} with the specific datatype for the supplied {@link BigInteger} value.
- *
+ *
* @param vf the {@link ValueFactory} to use for creating the {@link Literal}
* @param integerValue the integer value to use for creating the {@link Literal}
* @return an {@link Optional} literal value, which may be empty if the supplied integerValue can not be
@@ -81,7 +81,7 @@ protected abstract Optional createTypedLiteral(ValueFactory vf, BigInte
/**
* create a {@link Literal} with the specific datatype for the supplied boolean value.
- *
+ *
* @param vf the {@link ValueFactory} to use for creating the {@link Literal}
* @param booleanValue the boolean value to use for creating the {@link Literal}
* @return an {@link Optional} literal value, which may be empty if the supplied boolean value can not be
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/LongCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/LongCast.java
index 8e45b9a2a12..4edddb53afb 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/LongCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/LongCast.java
@@ -18,7 +18,7 @@
/**
* A {@link IntegerCastFunction} that tries to cast its argument to an xsd:long .
- *
+ *
* @author Jeen Broekstra
*/
public class LongCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NegativeIntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NegativeIntegerCast.java
index d9ff76071eb..4bd35d89f29 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NegativeIntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NegativeIntegerCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:negativeInteger .
- *
+ *
* @author Jeen Broekstra
*/
public class NegativeIntegerCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonNegativeIntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonNegativeIntegerCast.java
index e954055bfd3..c8da4c388f1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonNegativeIntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonNegativeIntegerCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:nonNegativeInteger .
- *
+ *
* @author Jeen Broekstra
*/
public class NonNegativeIntegerCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonPositiveIntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonPositiveIntegerCast.java
index cc7b46134dd..8fd632b8fc4 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonPositiveIntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/NonPositiveIntegerCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:nonPositiveInteger .
- *
+ *
* @author Jeen Broekstra
*/
public class NonPositiveIntegerCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/PositiveIntegerCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/PositiveIntegerCast.java
index 516b61372c8..322585b5502 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/PositiveIntegerCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/PositiveIntegerCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:positiveInteger .
- *
+ *
* @author Jeen Broekstra
*/
public class PositiveIntegerCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ShortCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ShortCast.java
index 558ac20ddc6..b4707b896a3 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ShortCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/ShortCast.java
@@ -15,12 +15,11 @@
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
-import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:short .
- *
+ *
* @author Jeen Broekstra
*/
public class ShortCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/StringCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/StringCast.java
index c8394b7a09c..d077ef5078f 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/StringCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/StringCast.java
@@ -20,7 +20,7 @@
/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* xsd:string.
- *
+ *
* @author Arjohn Kampman
* @author Jeen Broekstra
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedByteCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedByteCast.java
index f02e5540ee1..42320791bd9 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedByteCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedByteCast.java
@@ -18,7 +18,7 @@
/**
* A {@link IntegerCastFunction} that tries to cast its argument to an xsd:unsignedByte .
- *
+ *
* @author Jeen Broekstra
*/
public class UnsignedByteCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedIntCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedIntCast.java
index 061687d5dcd..ec8fa08c2eb 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedIntCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedIntCast.java
@@ -18,7 +18,7 @@
/**
* A {@link IntegerCastFunction} that tries to cast its argument to an xsd:unsignedInt .
- *
+ *
* @author Jeen Broekstra
*/
public class UnsignedIntCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedLongCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedLongCast.java
index 1a89ec02619..54b77774a2d 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedLongCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedLongCast.java
@@ -18,7 +18,7 @@
/**
* A {@link IntegerCastFunction} that tries to cast its argument to an xsd:unsignedShort .
- *
+ *
* @author Jeen Broekstra
*/
public class UnsignedLongCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedShortCast.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedShortCast.java
index 7d6a9b60f4e..62e791f197e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedShortCast.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/UnsignedShortCast.java
@@ -18,7 +18,7 @@
/**
* A {@link IntegerCastFunction} that tries to cast its argument to an xsd:unsignedShort .
- *
+ *
* @author Jeen Broekstra
*/
public class UnsignedShortCast extends IntegerCastFunction {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/package-info.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/package-info.java
index 5cba8c763ee..20809d5bc7b 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/package-info.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/function/xsd/package-info.java
@@ -1,6 +1,6 @@
/**
* Functions for casting values to various XML Schema datatypes
- *
+ *
* @see org.eclipse.rdf4j.model.vocabulary.XMLSchema
*/
-package org.eclipse.rdf4j.query.algebra.evaluation.function.xsd;
\ No newline at end of file
+package org.eclipse.rdf4j.query.algebra.evaluation.function.xsd;
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/AbstractEvaluationStrategyFactory.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/AbstractEvaluationStrategyFactory.java
index 176016d36d9..1e45bfd9c52 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/AbstractEvaluationStrategyFactory.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/AbstractEvaluationStrategyFactory.java
@@ -14,13 +14,16 @@
/**
* Abstract base class for {@link ExtendedEvaluationStrategy}.
- *
+ *
* @author Jeen Broekstra
*/
public abstract class AbstractEvaluationStrategyFactory implements EvaluationStrategyFactory {
private long querySolutionCacheThreshold;
+ // track the results size that each node in the query plan produces during execution
+ private boolean trackResultSize;
+
private QueryOptimizerPipeline pipeline;
@Override
@@ -43,4 +46,13 @@ public Optional getOptimizerPipeline() {
return Optional.ofNullable(pipeline);
}
+ @Override
+ public boolean isTrackResultSize() {
+ return trackResultSize;
+ }
+
+ @Override
+ public void setTrackResultSize(boolean trackResultSize) {
+ this.trackResultSize = trackResultSize;
+ }
}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/BindingAssigner.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/BindingAssigner.java
index 6c1518a4238..4f252a26b99 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/BindingAssigner.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/BindingAssigner.java
@@ -17,7 +17,7 @@
/**
* Assigns values to variables based on a supplied set of bindings.
- *
+ *
* @author Arjohn Kampman
*/
public class BindingAssigner implements QueryOptimizer {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/CompareOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/CompareOptimizer.java
index e38eca350d1..3fffa17f159 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/CompareOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/CompareOptimizer.java
@@ -23,7 +23,7 @@
/**
* A query optimizer that replaces {@link Compare} operators with {@link SameTerm}s, if possible.
- *
+ *
* @author Arjohn Kampman
*/
public class CompareOptimizer implements QueryOptimizer {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConjunctiveConstraintSplitter.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConjunctiveConstraintSplitter.java
index e53893c49be..b40c0680438 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConjunctiveConstraintSplitter.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConjunctiveConstraintSplitter.java
@@ -23,7 +23,7 @@
/**
* Splits conjunctive constraints into seperate constraints.
- *
+ *
* @author Arjohn Kampman
*/
public class ConjunctiveConstraintSplitter implements QueryOptimizer {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConstantOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConstantOptimizer.java
index 963671ab620..eb11ac451e1 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConstantOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ConstantOptimizer.java
@@ -49,7 +49,7 @@
/**
* A query optimizer that optimizes constant value expressions.
- *
+ *
* @author James Leigh
* @author Arjohn Kampman
*/
@@ -248,7 +248,7 @@ public void meet(FunctionCall functionCall) {
/**
* Determines if the provided zero-arg function is a function that should return a constant value for the entire
* query execution (e.g NOW()), or if it should generate a new value for every call (e.g. RAND()).
- *
+ *
* @param functionCall a zero-arg function call.
* @return true iff the provided function returns a constant value for the query execution, false
* otherwise.
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DisjunctiveConstraintOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DisjunctiveConstraintOptimizer.java
index 6f80ad10a4c..b68d199336c 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DisjunctiveConstraintOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DisjunctiveConstraintOptimizer.java
@@ -23,7 +23,7 @@
* A query optimizer that optimize disjunctive constraints on tuple expressions. Currently, this optimizer {@link Union
* unions} a clone of the underlying tuple expression with the original expression for each {@link SameTerm} operator,
* moving the SameTerm to the cloned tuple expression.
- *
+ *
* @author Arjohn Kampman
* @author James Leigh
*/
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java
index 7fcbc238783..c96470e0c71 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java
@@ -20,6 +20,7 @@
import org.eclipse.rdf4j.query.algebra.Service;
import org.eclipse.rdf4j.query.algebra.SingletonSet;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
+import org.eclipse.rdf4j.query.algebra.TripleRef;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.UnaryTupleOperator;
import org.eclipse.rdf4j.query.algebra.Var;
@@ -28,7 +29,7 @@
/**
* Supplies various query model statistics to the query engine/optimizer.
- *
+ *
* @author Arjohn Kampman
* @author James Leigh
*/
@@ -129,10 +130,10 @@ public void meet(Service node) {
// more than one free variable in a single triple pattern
if (count == 1 && node.getServiceVars().size() > 1) {
cardinality = 100 + node.getServiceVars().size(); // TODO (should
- // be higher
- // than other
- // simple
- // stmts)
+ // be higher
+ // than other
+ // simple
+ // stmts)
} else {
// only very selective statements should be better than this
// => evaluate service expressions first
@@ -146,6 +147,13 @@ public void meet(StatementPattern sp) {
cardinality = getCardinality(sp);
}
+ @Override
+ public void meet(TripleRef tripleRef) {
+ cardinality = getSubjectCardinality(tripleRef.getSubjectVar())
+ * getPredicateCardinality(tripleRef.getPredicateVar())
+ * getObjectCardinality(tripleRef.getObjectVar());
+ }
+
protected double getCardinality(StatementPattern sp) {
return getSubjectCardinality(sp) * getPredicateCardinality(sp) * getObjectCardinality(sp)
* getContextCardinality(sp);
@@ -280,5 +288,7 @@ public int getStatementCount() {
public void meet(StatementPattern node) throws RuntimeException {
count++;
}
- };
+ }
+
+ ;
}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategy.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategy.java
index 2c0eafbd2f6..a677bd06ac4 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategy.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategy.java
@@ -24,7 +24,7 @@
/**
* SPARQL 1.1 extended query evaluation strategy. This strategy adds the use of virtual properties, as well as extended
* comparison and mathematical operators to the minimally-conforming {@link StrictEvaluationStrategy}.
- *
+ *
* @author Jeen Broekstra
*/
public class ExtendedEvaluationStrategy extends TupleFunctionEvaluationStrategy {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategyFactory.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategyFactory.java
index 67e2dc20226..6adf08fa79e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategyFactory.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExtendedEvaluationStrategyFactory.java
@@ -42,4 +42,4 @@ public EvaluationStrategy createEvaluationStrategy(Dataset dataset, TripleSource
evaluationStatistics);
}
-}
\ No newline at end of file
+}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExternalSet.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExternalSet.java
index becd874f7be..80232eb26cc 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExternalSet.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ExternalSet.java
@@ -19,7 +19,7 @@
/**
* @author James Leigh
- *
+ *
* @deprecated since 3.0.
*/
@Deprecated
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/FilterOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/FilterOptimizer.java
index eda957ea4ea..15ec407039c 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/FilterOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/FilterOptimizer.java
@@ -31,7 +31,7 @@
/**
* Optimizes a query model by pushing {@link Filter}s as far down in the model tree as possible.
- *
+ *
* @author Arjohn Kampman
*/
public class FilterOptimizer implements QueryOptimizer {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/OrderLimitOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/OrderLimitOptimizer.java
index dab5db93878..3383fabd8ee 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/OrderLimitOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/OrderLimitOptimizer.java
@@ -23,7 +23,7 @@
/**
* Moves the Order node above the Projection when variables are projected.
- *
+ *
* @author James Leigh
*/
public class OrderLimitOptimizer implements QueryOptimizer {
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/QueryJoinOptimizer.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/QueryJoinOptimizer.java
index 93d6d35dd6b..564187e9476 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/QueryJoinOptimizer.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/QueryJoinOptimizer.java
@@ -56,6 +56,12 @@ public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings)
tupleExpr.visit(new JoinVisitor());
}
+ /**
+ *
+ * @deprecated This class is protected for historic reasons only, and will be made private in a future major
+ * release.
+ */
+ @Deprecated
protected class JoinVisitor extends AbstractQueryModelVisitor {
Set boundVars = new HashSet<>();
@@ -75,6 +81,12 @@ public void meet(LeftJoin leftJoin) {
}
}
+ @Override
+ public void meet(StatementPattern node) throws RuntimeException {
+ super.meet(node);
+ node.setResultSizeEstimate(Math.max(statistics.getCardinality(node), node.getResultSizeEstimate()));
+ }
+
@Override
public void meet(Join node) {
@@ -109,7 +121,9 @@ public void meet(Join node) {
Map> varsMap = new HashMap<>();
for (TupleExpr tupleExpr : joinArgs) {
- cardinalityMap.put(tupleExpr, statistics.getCardinality(tupleExpr));
+ double cardinality = statistics.getCardinality(tupleExpr);
+ tupleExpr.setResultSizeEstimate(Math.max(cardinality, tupleExpr.getResultSizeEstimate()));
+ cardinalityMap.put(tupleExpr, cardinality);
if (tupleExpr instanceof ZeroLengthPath) {
varsMap.put(tupleExpr, ((ZeroLengthPath) tupleExpr).getVarList());
} else {
@@ -372,30 +386,34 @@ private TupleExpr getNextSubselect(List currentList, List
protected TupleExpr selectNextTupleExpr(List expressions, Map