You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commonsrdf.apache.org by st...@apache.org on 2016/10/07 15:01:39 UTC
[36/50] incubator-commonsrdf git commit: Added ClosableIterable for
rdf4j .iterate
Added ClosableIterable for rdf4j .iterate
Project: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/commit/a47ad362
Tree: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/tree/a47ad362
Diff: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/diff/a47ad362
Branch: refs/heads/master
Commit: a47ad3623d178ea4957ce95d3b905d0415cd4b16
Parents: 365b5f2
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Oct 7 00:16:53 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Oct 7 00:16:53 2016 +0100
----------------------------------------------------------------------
.../commons/rdf/rdf4j/ClosableIterable.java | 22 +++++++++
.../apache/commons/rdf/rdf4j/RDF4JGraph.java | 49 ++++++++++++++++++-
.../commons/rdf/rdf4j/impl/ModelGraphImpl.java | 26 ++++++++++
.../rdf/rdf4j/impl/RepositoryGraphImpl.java | 51 ++++++++++++++++++++
.../commons/rdf/rdf4j/NativeStoreGraphTest.java | 10 ++--
5 files changed, 152 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a47ad362/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/ClosableIterable.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/ClosableIterable.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/ClosableIterable.java
new file mode 100644
index 0000000..2cca6c6
--- /dev/null
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/ClosableIterable.java
@@ -0,0 +1,22 @@
+package org.apache.commons.rdf.rdf4j;
+
+/**
+ * An {@link Iterable} which should be {@link #close()}d after use.
+ * <p>
+ * A good pattern to use this iterator is with an outer try-with-resources
+ * block:
+ * <code>
+ * for (ClosableIterable<Triple> triples : graph.iterate()) {
+ * for (Triple t : triples) {
+ * return t; // OK to terminate for-loop early
+ * }
+ * }
+ * </code>
+ * The above will ensure that underlying resources are closed even if
+ * the iteration does not exhaust all triples.
+ *
+ * @param <T>
+ */
+public interface ClosableIterable<T> extends Iterable<T>, AutoCloseable {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a47ad362/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
index 93886a4..8030723 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JGraph.java
@@ -17,6 +17,7 @@
*/
package org.apache.commons.rdf.rdf4j;
+import java.util.ConcurrentModificationException;
import java.util.Set;
import java.util.stream.Stream;
@@ -97,7 +98,7 @@ public interface RDF4JGraph extends Graph, RDF4JGraphLike<Triple> {
* This can generally achieved using a try-with-resources block, e.g.:
* <pre>
* int subjects;
- * try (Stream<RDF4JTriple> s : graph.stream()) {
+ * try (Stream<RDF4JTriple> s : graph.stream(s,p,o)) {
* subjects = s.map(RDF4JTriple::getSubject).distinct().count()
* }
* </pre>
@@ -105,4 +106,50 @@ public interface RDF4JGraph extends Graph, RDF4JGraphLike<Triple> {
@Override
Stream<RDF4JTriple> stream(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note that the iterable <strong>must be closed</strong> with
+ * {@link ClosableIterable#close()}.
+ * call
+ * <p>
+ * This can generally achieved using a try-with-resources block, e.g.:
+ * <pre>
+ * int subjects;
+ * try (ClosableIterable<Triple> s : graph.iterate()) {
+ * for (Triple t : triples) {
+ * return t; // OK to terminate for-loop early
+ * }
+ * }
+ * </pre>
+ * If you don't use a try-with-resources block, the iterator will
+ * attempt to close the ClosableIterable
+ * when reaching the end of the iteration.
+ */
+ @Override
+ ClosableIterable<Triple> iterate() throws ConcurrentModificationException, IllegalStateException;
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note that the iterable <strong>must be closed</strong> with
+ * {@link ClosableIterable#close()}.
+ * call
+ * <p>
+ * This can generally achieved using a try-with-resources block, e.g.:
+ * <pre>
+ * int subjects;
+ * try (ClosableIterable<Triple> s : graph.iterate(s,p,o)) {
+ * for (Triple t : triples) {
+ * return t; // OK to terminate for-loop early
+ * }
+ * }
+ * </pre>
+ * If you don't use a try-with-resources block, the iterator will
+ * attempt to close the ClosableIterable
+ * when reaching the end of the iteration.
+ */
+ @Override
+ Iterable<Triple> iterate(BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
}
http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a47ad362/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
index e207007..17aeccb 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/ModelGraphImpl.java
@@ -18,13 +18,17 @@
package org.apache.commons.rdf.rdf4j.impl;
import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDFTerm;
import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.rdf4j.ClosableIterable;
import org.apache.commons.rdf.rdf4j.RDF4JBlankNodeOrIRI;
import org.apache.commons.rdf.rdf4j.RDF4JGraph;
import org.apache.commons.rdf.rdf4j.RDF4JTermFactory;
@@ -128,5 +132,27 @@ final class ModelGraphImpl implements RDF4JGraph {
return Collections.emptySet();
// TODO: Should we support contextMask like in RepositoryGraphImpl?
}
+
+ @Override
+ public ClosableIterable<Triple> iterate(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+ return new ClosableIterable<Triple>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public Iterator<Triple> iterator() {
+ // double-cast to fight Java generics..
+ Stream<? extends Triple> s = stream(subject, predicate, object);
+ return (Iterator<Triple>) s.iterator();
+ }
+ @Override
+ public void close() throws Exception {
+ // no-op as Model don't have transaction
+ }
+ };
+ }
+
+ @Override
+ public ClosableIterable<Triple> iterate() throws ConcurrentModificationException, IllegalStateException {
+ return iterate(null, null, null);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a47ad362/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
index b6b44d9..ce0add1 100644
--- a/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
+++ b/rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/impl/RepositoryGraphImpl.java
@@ -18,7 +18,9 @@
package org.apache.commons.rdf.rdf4j.impl;
import java.util.Collections;
+import java.util.ConcurrentModificationException;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
@@ -28,6 +30,7 @@ import org.apache.commons.rdf.api.Graph;
import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDFTerm;
import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.rdf4j.ClosableIterable;
import org.apache.commons.rdf.rdf4j.RDF4JBlankNodeOrIRI;
import org.apache.commons.rdf.rdf4j.RDF4JGraph;
import org.apache.commons.rdf.rdf4j.RDF4JTriple;
@@ -41,6 +44,40 @@ import org.eclipse.rdf4j.repository.RepositoryResult;
class RepositoryGraphImpl extends AbstractRepositoryGraphLike<Triple> implements Graph, RDF4JGraph {
+ private final class TripleIteration implements ClosableIterable<Triple> {
+ private RepositoryConnection conn;
+ private RepositoryResult<Statement> results;
+ private TripleIteration(Resource subj, org.eclipse.rdf4j.model.IRI pred, Value obj) {
+ conn = getRepositoryConnection();
+ results = conn.getStatements(subj, pred, obj, contextMask);
+ }
+
+ @Override
+ public Iterator<Triple> iterator() {
+ return new Iterator<Triple>(){
+ @Override
+ public boolean hasNext() {
+ boolean hasNext = results.hasNext();
+ if (! hasNext) {
+ close();
+ }
+ return hasNext;
+ }
+ @Override
+ public Triple next() {
+ Statement statement = results.next();
+ return rdf4jTermFactory.asTriple(statement);
+ }
+ };
+ }
+
+ @Override
+ public void close() {
+ results.close();
+ conn.close();
+ }
+ }
+
private final Resource[] contextMask;
RepositoryGraphImpl(Repository repository, boolean handleInitAndShutdown, boolean includeInferred, Resource... contextMask) {
@@ -128,6 +165,20 @@ class RepositoryGraphImpl extends AbstractRepositoryGraphLike<Triple> implements
conn.commit();
}
}
+
+ @Override
+ public ClosableIterable<Triple> iterate() throws ConcurrentModificationException, IllegalStateException {
+ return iterate(null, null, null);
+ }
+
+ @Override
+ public ClosableIterable<Triple> iterate(BlankNodeOrIRI subject, IRI predicate, RDFTerm object)
+ throws ConcurrentModificationException, IllegalStateException {
+ Resource subj = (Resource) rdf4jTermFactory.asValue(subject);
+ org.eclipse.rdf4j.model.IRI pred = (org.eclipse.rdf4j.model.IRI) rdf4jTermFactory.asValue(predicate);
+ Value obj = rdf4jTermFactory.asValue(object);
+ return new TripleIteration(subj, pred, obj);
+ }
@Override
public Stream<RDF4JTriple> stream() {
http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/a47ad362/rdf4j/src/test/java/org/apache/commons/rdf/rdf4j/NativeStoreGraphTest.java
----------------------------------------------------------------------
diff --git a/rdf4j/src/test/java/org/apache/commons/rdf/rdf4j/NativeStoreGraphTest.java b/rdf4j/src/test/java/org/apache/commons/rdf/rdf4j/NativeStoreGraphTest.java
index 392d63d..aed763b 100644
--- a/rdf4j/src/test/java/org/apache/commons/rdf/rdf4j/NativeStoreGraphTest.java
+++ b/rdf4j/src/test/java/org/apache/commons/rdf/rdf4j/NativeStoreGraphTest.java
@@ -19,6 +19,8 @@ package org.apache.commons.rdf.rdf4j;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.util.Collections;
+import java.util.Set;
import org.apache.commons.rdf.api.AbstractGraphTest;
import org.apache.commons.rdf.api.BlankNodeOrIRI;
@@ -39,10 +41,6 @@ import org.junit.rules.TemporaryFolder;
/**
* Test a graph within a file-based RDF4J {@link SailRepository}.
* <p>
- * Note that for efficiency reasons this test uses a shared repository for all
- * tests, but uses a different BlankNode context for each
- * {@link NativeStoreFactory#createGraph()}.
- * <p>
* TIP: If the {@link #shutdownAndDelete()} take about 20 seconds
* this is a hint that a {@link RepositoryConnection} or
* {@link RepositoryResult} was not closed correctly.
@@ -56,7 +54,9 @@ public class NativeStoreGraphTest extends AbstractGraphTest {
@Override
public RDF4JGraph createGraph() {
- return rdf4jFactory.asRDFTermGraph(getRepository());
+ // We re-use the repository connection, but use a different context every time
+ Set<RDF4JBlankNode> context = Collections.singleton(rdf4jFactory.createBlankNode());
+ return rdf4jFactory.asRDFTermGraph(getRepository(), context);
}
// Delegate methods