jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aj...@apache.org
Subject [10/10] jena git commit: Parallelize assembler for WPG datasets
Date Sun, 08 Jan 2017 14:45:32 GMT
Parallelize assembler for WPG datasets


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/64de6d3d
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/64de6d3d
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/64de6d3d

Branch: refs/heads/ThreadPerGraphDataset
Commit: 64de6d3dfd7a71ac2d3183f3c8ef7c902c298670
Parents: 3ff7999
Author: ajs6f <ajs6f@virginia.edu>
Authored: Sat Jan 7 18:29:37 2017 -0500
Committer: ajs6f <ajs6f@virginia.edu>
Committed: Sun Jan 8 09:29:52 2017 -0500

----------------------------------------------------------------------
 .../core/assembler/DatasetAssemblerVocab.java   |   3 +-
 .../TransactionalInMemDatasetAssembler.java     |  29 ++--
 .../WriterPerGraphDatasetAssembler.java         |  79 ++++++++--
 .../sparql/core/assembler/TS_Assembler.java     |   2 +-
 .../assembler/TestInMemDatasetAssembler.java    | 145 -------------------
 .../assembler/TestTxnInMemDatasetAssembler.java | 145 +++++++++++++++++++
 6 files changed, 228 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/DatasetAssemblerVocab.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/DatasetAssemblerVocab.java
b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/DatasetAssemblerVocab.java
index 1c234d1..260672c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/DatasetAssemblerVocab.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/DatasetAssemblerVocab.java
@@ -34,7 +34,8 @@ public class DatasetAssemblerVocab
     public static final Resource tDatasetTxnMem      = ResourceFactory.createResource(NS+"DatasetTxnMem")
;
     // Writer-per-graph txn in-memory dataset
     public static final Resource tDatasetPGraphWriter = ResourceFactory.createResource(NS+"DatasetMemWriterPerGraph");
-    
+    public static final Property pParallelize        = ResourceFactory.createProperty(NS,
"parallelize") ;
+
     public static final Resource tDatasetNull        = ResourceFactory.createResource(NS+"DatasetNull")
;
     
     public static final Property pDefaultGraph       = ResourceFactory.createProperty(NS,
"defaultGraph") ;

http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/TransactionalInMemDatasetAssembler.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/TransactionalInMemDatasetAssembler.java
b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/TransactionalInMemDatasetAssembler.java
index 12fc1fc..72e23b0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/TransactionalInMemDatasetAssembler.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/TransactionalInMemDatasetAssembler.java
@@ -45,22 +45,27 @@ public abstract class TransactionalInMemDatasetAssembler extends AssemblerBase
{
 
         dataset.begin(WRITE);
         try {
-            // load data into the default graph
-            if (root.hasProperty(data))
-                multiValueResource(root, data)
-                    .forEach(defaultGraphDocument -> read(dataset, defaultGraphDocument.getURI()));
-
-            // load data into named graphs
-            multiValueResource(root, pNamedGraph).forEach(namedGraphResource -> {
-                final String graphName = getAsStringValue(namedGraphResource, pGraphName);
-                if (namedGraphResource.hasProperty(data))
-                    multiValueResource(namedGraphResource, data)
-                            .forEach(namedGraphData -> read(dataset.getNamedModel(graphName),
namedGraphData.getURI()));
-            });
+            loadDefaultGraph(root, dataset);
+            loadNamedGraphs(root, dataset);
             dataset.commit();
         } finally {
             dataset.end();
         }
         return dataset;
     }
+
+    protected void loadNamedGraphs(final Resource root, final Dataset dataset) {
+        multiValueResource(root, pNamedGraph).forEach(namedGraphResource -> {
+            final String graphName = getAsStringValue(namedGraphResource, pGraphName);
+            if (namedGraphResource.hasProperty(data))
+                multiValueResource(namedGraphResource, data)
+                        .forEach(namedGraphData -> read(dataset.getNamedModel(graphName),
namedGraphData.getURI()));
+        });
+    }
+
+    protected void loadDefaultGraph(final Resource root, final Dataset dataset) {
+        if (root.hasProperty(data))
+            multiValueResource(root, data)
+                .forEach(defaultGraphDocument -> read(dataset, defaultGraphDocument.getURI()));
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/WriterPerGraphDatasetAssembler.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/WriterPerGraphDatasetAssembler.java
b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/WriterPerGraphDatasetAssembler.java
index 2ebefd9..255e24c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/WriterPerGraphDatasetAssembler.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/WriterPerGraphDatasetAssembler.java
@@ -1,27 +1,38 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
agreements. See the NOTICE
+ * file distributed with this work for additional information regarding copyright ownership.
The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the
+ * License. You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the
+ * specific language governing permissions and limitations under the License.
  */
 
 package org.apache.jena.sparql.core.assembler;
 
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.apache.jena.assembler.JA.data;
+import static org.apache.jena.query.ReadWrite.WRITE;
+import static org.apache.jena.riot.RDFDataMgr.read;
+import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pGraphName;
+import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pNamedGraph;
+import static org.apache.jena.sparql.util.graph.GraphUtils.getAsStringValue;
+import static org.apache.jena.sparql.util.graph.GraphUtils.getResourceValue;
+import static org.apache.jena.sparql.util.graph.GraphUtils.multiValueResource;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
 import org.apache.jena.assembler.Assembler;
 import org.apache.jena.query.Dataset;
 import org.apache.jena.query.DatasetFactory;
 import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.shared.JenaException;
 import org.apache.jena.sparql.core.DatasetGraphPerGraphLocking;
 
 /**
@@ -31,11 +42,47 @@ public class WriterPerGraphDatasetAssembler extends TransactionalInMemDatasetAss
 
     @Override
     public Resource getType() {
-        return DatasetAssemblerVocab.tDatasetPGraphWriter ;
+        return DatasetAssemblerVocab.tDatasetPGraphWriter;
     }
-    
+
     @Override
     public Dataset createDataset() {
-        return DatasetFactory.wrap(new DatasetGraphPerGraphLocking()) ;
+        return DatasetFactory.wrap(new DatasetGraphPerGraphLocking());
+    }
+
+    @Override
+    protected void loadNamedGraphs(Resource root, Dataset dataset) {
+        List<Resource> namedGraphs = multiValueResource(root, pNamedGraph);
+        Resource parallelizeValue = getResourceValue(root, DatasetAssemblerVocab.pParallelize);
+        // defaults to false
+        boolean parallelize = parallelizeValue != null ? parallelizeValue.asLiteral().getBoolean()
: false;
+        if (parallelize) {
+            // take advantage of writer-per-graph to load in parallel, one thread per named
graph
+            ExecutorService loaderThreadPool = newFixedThreadPool(namedGraphs.size());
+            try {
+                loaderThreadPool
+                        .submit(() -> namedGraphs.stream().parallel().forEach(namedGraphResource
-> {
+                            dataset.begin(WRITE);
+                            try {
+                                loadNamedGraph(dataset, namedGraphResource);
+                                dataset.commit();
+                            } finally {
+                                dataset.end();
+                            }
+                        })).get();
+            } catch (InterruptedException | ExecutionException e) {
+                loaderThreadPool.shutdownNow();
+                throw new JenaException(e);
+            }
+            loaderThreadPool.shutdown();
+        } else 
+            // load using only this thread, default mode
+            namedGraphs.forEach(namedGraphResource -> loadNamedGraph(dataset, namedGraphResource));
+    }
+
+    private static void loadNamedGraph(Dataset dataset, Resource namedGraphResource) {
+        final String graphName = getAsStringValue(namedGraphResource, pGraphName);
+        if (namedGraphResource.hasProperty(data)) multiValueResource(namedGraphResource,
data)
+                .forEach(namedGraphData -> read(dataset.getNamedModel(graphName), namedGraphData.getURI()));
     }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TS_Assembler.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TS_Assembler.java
b/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TS_Assembler.java
index 3dbe1bd..bb27b4c 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TS_Assembler.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TS_Assembler.java
@@ -23,5 +23,5 @@ import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
-@SuiteClasses({ TestInMemDatasetAssembler.class })
+@SuiteClasses({ TestTxnInMemDatasetAssembler.class })
 public class TS_Assembler {}

http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestInMemDatasetAssembler.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestInMemDatasetAssembler.java
b/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestInMemDatasetAssembler.java
deleted file mode 100644
index ad4114c..0000000
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestInMemDatasetAssembler.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.sparql.core.assembler;
-
-import static java.nio.file.Files.createTempFile;
-import static org.apache.jena.assembler.JA.MemoryModel ;
-import static org.apache.jena.assembler.JA.data ;
-import static org.apache.jena.assembler.Mode.DEFAULT;
-import static org.apache.jena.query.DatasetFactory.createTxnMem;
-import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel;
-import static org.apache.jena.riot.Lang.NQUADS;
-import static org.apache.jena.riot.RDFDataMgr.write;
-import static org.apache.jena.riot.RDFFormat.NTRIPLES;
-import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pGraphName;
-import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pNamedGraph;
-import static org.apache.jena.vocabulary.RDF.type;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.util.Iterator;
-
-import org.apache.jena.assembler.JA ;
-import org.apache.jena.assembler.exceptions.CannotConstructException;
-import org.apache.jena.graph.Node;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.Resource;
-import org.apache.jena.rdf.model.Statement;
-import org.apache.jena.sparql.core.DatasetGraph;
-import org.apache.jena.sparql.core.Quad;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests for {@link TxnInMemDatasetAssembler}
- *
- */
-public class TestInMemDatasetAssembler extends Assert {
-
-    private Dataset assemble(final Resource example) {
-	    Model model = example.getModel() ;
-	    model.setNsPrefix("ja", JA.getURI()) ;
-//	    System.out.println("-------------");
-//	    RDFDataMgr.write(System.out, model, Lang.TTL) ;
-	    final TxnInMemDatasetAssembler testAssembler = new TxnInMemDatasetAssembler();
-		return testAssembler.open(testAssembler, example, DEFAULT);
-	}
-	
-	@Test
-	public void emptyDataset() {
-	    final Model model = createDefaultModel();
-	    final Resource empty = model.createResource("test:empty");
-	    empty.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem) ;
-	    Dataset dataset = assemble(empty) ;
-	    assertFalse(dataset.asDatasetGraph().find().hasNext()) ;
-	}
-
-	@Test
-	public void directDataLinkForDefaultAndNamedGraphs() throws IOException {
-		// first make a file of triples to load later
-		final Model model = createDefaultModel();
-		final Path triples = createTempFile("simpleExample", ".nt");
-		final Resource triplesURI = model.createResource(triples.toFile().toURI().toString());
-		final Resource simpleExample = model.createResource("test:simpleExample");
-		simpleExample.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem);
-		// add a default graph
-		simpleExample.addProperty(data, triplesURI);
-		// add a named graph
-		final Resource namedGraphDef = model.createResource("test:namedGraphDef");
-		simpleExample.addProperty(pNamedGraph, namedGraphDef);
-		final Resource namedGraphName = model.createResource("test:namedGraphExample");
-		namedGraphDef.addProperty(type, MemoryModel);
-		namedGraphDef.addProperty(pGraphName, namedGraphName);
-		namedGraphDef.addProperty(data, triplesURI);
-
-		try (OutputStream out = new FileOutputStream(triples.toFile())) {
-			write(out, model, NTRIPLES);
-		}
-
-		final Dataset dataset = assemble(simpleExample);
-		final Model assembledDefaultModel = dataset.getDefaultModel();
-		final Model assembledNamedModel = dataset.getNamedModel(namedGraphName.getURI());
-
-		// we put the same triples in each model, so we check for the same triples in each model
-		for (final Model m : new Model[] { assembledDefaultModel, assembledNamedModel }) {
-			assertTrue(m.contains(simpleExample, pNamedGraph, namedGraphDef));
-			assertTrue(m.contains(namedGraphDef, pGraphName, namedGraphName));
-			assertTrue(m.contains(simpleExample, data, triplesURI));
-
-		}
-		final Iterator<Node> graphNodes = dataset.asDatasetGraph().listGraphNodes();
-		assertTrue(graphNodes.hasNext());
-		assertEquals(namedGraphName.asNode(), graphNodes.next());
-		assertFalse(graphNodes.hasNext());
-	}
-
-	@Test
-	public void directDataLinkToQuads() throws IOException {
-		// first make a file of quads to load later
-		final Model model = createDefaultModel();
-		final Path quads = createTempFile("quadExample", ".nq");
-		final Resource quadsURI = model.createResource(quads.toFile().toURI().toString());
-		final Resource simpleExample = model.createResource("test:simpleExample");
-		simpleExample.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem);
-		simpleExample.addProperty(data, quadsURI);
-
-		final DatasetGraph dsg = createTxnMem().asDatasetGraph();
-		model.listStatements().mapWith(Statement::asTriple).mapWith(t -> new Quad(quadsURI.asNode(),
t))
-				.forEachRemaining(dsg::add);
-		try (OutputStream out = new FileOutputStream(quads.toFile())) {
-			write(out, dsg, NQUADS);
-		}
-
-		final Dataset dataset = assemble(simpleExample);
-		final Model assembledDefaultModel = dataset.getDefaultModel();
-		final Model assembledNamedModel = dataset.getNamedModel(quadsURI.getURI());
-		assertTrue(assembledDefaultModel.isEmpty());
-		assertTrue(assembledNamedModel.contains(assembledNamedModel.createStatement(simpleExample,
data, quadsURI)));
-	}
-
-	@Test(expected = CannotConstructException.class)
-	public void wrongKindOfAssemblerDefinition() {
-		final Model model = createDefaultModel();
-		final Resource badExample = model.createResource("test:badExample");
-		assemble(badExample);
-	}
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/64de6d3d/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestTxnInMemDatasetAssembler.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestTxnInMemDatasetAssembler.java
b/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestTxnInMemDatasetAssembler.java
new file mode 100644
index 0000000..3c2b8c9
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/assembler/TestTxnInMemDatasetAssembler.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.core.assembler;
+
+import static java.nio.file.Files.createTempFile;
+import static org.apache.jena.assembler.JA.MemoryModel ;
+import static org.apache.jena.assembler.JA.data ;
+import static org.apache.jena.assembler.Mode.DEFAULT;
+import static org.apache.jena.query.DatasetFactory.createTxnMem;
+import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel;
+import static org.apache.jena.riot.Lang.NQUADS;
+import static org.apache.jena.riot.RDFDataMgr.write;
+import static org.apache.jena.riot.RDFFormat.NTRIPLES;
+import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pGraphName;
+import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pNamedGraph;
+import static org.apache.jena.vocabulary.RDF.type;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.util.Iterator;
+
+import org.apache.jena.assembler.JA ;
+import org.apache.jena.assembler.exceptions.CannotConstructException;
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.Quad;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for {@link TxnInMemDatasetAssembler}
+ *
+ */
+public class TestTxnInMemDatasetAssembler extends Assert {
+
+    private Dataset assemble(final Resource example) {
+	    Model model = example.getModel() ;
+	    model.setNsPrefix("ja", JA.getURI()) ;
+//	    System.out.println("-------------");
+//	    RDFDataMgr.write(System.out, model, Lang.TTL) ;
+	    final TxnInMemDatasetAssembler testAssembler = new TxnInMemDatasetAssembler();
+		return testAssembler.open(testAssembler, example, DEFAULT);
+	}
+	
+	@Test
+	public void emptyDataset() {
+	    final Model model = createDefaultModel();
+	    final Resource empty = model.createResource("test:empty");
+	    empty.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem) ;
+	    Dataset dataset = assemble(empty) ;
+	    assertFalse(dataset.asDatasetGraph().find().hasNext()) ;
+	}
+
+	@Test
+	public void directDataLinkForDefaultAndNamedGraphs() throws IOException {
+		// first make a file of triples to load later
+		final Model model = createDefaultModel();
+		final Path triples = createTempFile("simpleExample", ".nt");
+		final Resource triplesURI = model.createResource(triples.toFile().toURI().toString());
+		final Resource simpleExample = model.createResource("test:simpleExample");
+		simpleExample.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem);
+		// add a default graph
+		simpleExample.addProperty(data, triplesURI);
+		// add a named graph
+		final Resource namedGraphDef = model.createResource("test:namedGraphDef");
+		simpleExample.addProperty(pNamedGraph, namedGraphDef);
+		final Resource namedGraphName = model.createResource("test:namedGraphExample");
+		namedGraphDef.addProperty(type, MemoryModel);
+		namedGraphDef.addProperty(pGraphName, namedGraphName);
+		namedGraphDef.addProperty(data, triplesURI);
+
+		try (OutputStream out = new FileOutputStream(triples.toFile())) {
+			write(out, model, NTRIPLES);
+		}
+
+		final Dataset dataset = assemble(simpleExample);
+		final Model assembledDefaultModel = dataset.getDefaultModel();
+		final Model assembledNamedModel = dataset.getNamedModel(namedGraphName.getURI());
+
+		// we put the same triples in each model, so we check for the same triples in each model
+		for (final Model m : new Model[] { assembledDefaultModel, assembledNamedModel }) {
+			assertTrue(m.contains(simpleExample, pNamedGraph, namedGraphDef));
+			assertTrue(m.contains(namedGraphDef, pGraphName, namedGraphName));
+			assertTrue(m.contains(simpleExample, data, triplesURI));
+
+		}
+		final Iterator<Node> graphNodes = dataset.asDatasetGraph().listGraphNodes();
+		assertTrue(graphNodes.hasNext());
+		assertEquals(namedGraphName.asNode(), graphNodes.next());
+		assertFalse(graphNodes.hasNext());
+	}
+
+	@Test
+	public void directDataLinkToQuads() throws IOException {
+		// first make a file of quads to load later
+		final Model model = createDefaultModel();
+		final Path quads = createTempFile("quadExample", ".nq");
+		final Resource quadsURI = model.createResource(quads.toFile().toURI().toString());
+		final Resource simpleExample = model.createResource("test:simpleExample");
+		simpleExample.addProperty(type, DatasetAssemblerVocab.tDatasetTxnMem);
+		simpleExample.addProperty(data, quadsURI);
+
+		final DatasetGraph dsg = createTxnMem().asDatasetGraph();
+		model.listStatements().mapWith(Statement::asTriple).mapWith(t -> new Quad(quadsURI.asNode(),
t))
+				.forEachRemaining(dsg::add);
+		try (OutputStream out = new FileOutputStream(quads.toFile())) {
+			write(out, dsg, NQUADS);
+		}
+
+		final Dataset dataset = assemble(simpleExample);
+		final Model assembledDefaultModel = dataset.getDefaultModel();
+		final Model assembledNamedModel = dataset.getNamedModel(quadsURI.getURI());
+		assertTrue(assembledDefaultModel.isEmpty());
+		assertTrue(assembledNamedModel.contains(assembledNamedModel.createStatement(simpleExample,
data, quadsURI)));
+	}
+
+	@Test(expected = CannotConstructException.class)
+	public void wrongKindOfAssemblerDefinition() {
+		final Model model = createDefaultModel();
+		final Resource badExample = model.createResource("test:badExample");
+		assemble(badExample);
+	}
+}


Mime
View raw message