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&lt;Triple&gt; 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&lt;RDF4JTriple&gt; s : graph.stream()) {
+	 * try (Stream&lt;RDF4JTriple&gt; 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&lt;Triple&gt; 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&lt;Triple&gt; 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