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/03 16:40:23 UTC

[27/50] incubator-commonsrdf git commit: Added JsonLdDataset, JsonLdGraphLike

Added JsonLdDataset, JsonLdGraphLike


Project: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/commit/1330627e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/tree/1330627e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/diff/1330627e

Branch: refs/heads/master
Commit: 1330627e7d0c133b06dcc04c8581b11ba8ea7f2c
Parents: f2bcb3d
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Sep 9 14:28:47 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Sep 9 14:28:47 2016 +0100

----------------------------------------------------------------------
 .../commons/rdf/jsonldjava/JsonLdDataset.java   |  99 ++++++++
 .../commons/rdf/jsonldjava/JsonLdGraph.java     | 184 +++-----------
 .../commons/rdf/jsonldjava/JsonLdGraphLike.java | 239 +++++++++++++++++++
 .../rdf/jsonldjava/JsonLdRDFTermFactory.java    |  54 +++--
 4 files changed, 401 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/1330627e/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
----------------------------------------------------------------------
diff --git a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
new file mode 100644
index 0000000..e18dfaf
--- /dev/null
+++ b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdDataset.java
@@ -0,0 +1,99 @@
+/**
+ * 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.commons.rdf.jsonldjava;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.Dataset;
+import org.apache.commons.rdf.api.Graph;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.api.RDFTerm;
+
+import com.github.jsonldjava.core.RDFDataset;
+
+public class JsonLdDataset extends JsonLdGraphLike<org.apache.commons.rdf.api.Quad> implements Dataset {
+
+	JsonLdDataset(String bnodePrefix) {
+		super(bnodePrefix);
+	}
+
+	JsonLdDataset(RDFDataset rdfDataset, String bnodePrefix) {
+		super(rdfDataset, bnodePrefix);
+	}
+
+	public JsonLdDataset(RDFDataset rdfDataSet) {
+		super(rdfDataSet);
+	}
+
+	@Override
+	public void add(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		super.add(graphName, subject, predicate, object);
+	}
+
+	@Override
+	public boolean contains(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		return super.contains(graphName, subject, predicate, object);
+	}
+	
+	@Override
+	public void remove(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		super.remove(graphName, subject, predicate, object);
+	}	
+
+	@Override
+	public Graph getGraph() {
+		return new JsonLdGraph(rdfDataSet, Optional.empty(), bnodePrefix);
+	}
+
+	@Override
+	public Optional<Graph> getGraph(BlankNodeOrIRI graphName) {
+		if (graphName == null) {
+			return Optional.of(getGraph());
+		}
+		return getGraphNames()
+				.map(g -> (Graph)new JsonLdGraph(rdfDataSet, Optional.of(g), bnodePrefix))
+				.findAny();
+	}
+
+	@Override
+	public Stream<BlankNodeOrIRI> getGraphNames() {
+		return rdfDataSet.graphNames().parallelStream().filter(Predicate.isEqual("@default").negate())
+				.map(s -> s.startsWith("_:") ? new RDFDataset.BlankNode(s) : new RDFDataset.IRI(s))
+				.map(n -> (BlankNodeOrIRI) factory.asTerm(n, bnodePrefix));		
+	}
+
+	@Override
+	public Stream<? extends Quad> stream(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate,
+			RDFTerm object) {		
+		return filteredGraphs(graphName)
+				.flatMap(List::stream)
+				.filter(quadFilter(subject, predicate, object))
+				.map(factory::createQuad);
+	}
+
+	@Override
+	Quad asTripleOrQuad(com.github.jsonldjava.core.RDFDataset.Quad jsonldQuad) {
+		return factory.createQuad(jsonldQuad);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/1330627e/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraph.java
----------------------------------------------------------------------
diff --git a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraph.java b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraph.java
index c7c3491..22d5291 100644
--- a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraph.java
+++ b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraph.java
@@ -19,195 +19,69 @@ package org.apache.commons.rdf.jsonldjava;
 
 import java.util.List;
 import java.util.Optional;
-import java.util.UUID;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import org.apache.commons.rdf.api.BlankNode;
 import org.apache.commons.rdf.api.BlankNodeOrIRI;
 import org.apache.commons.rdf.api.Graph;
 import org.apache.commons.rdf.api.IRI;
-import org.apache.commons.rdf.api.Literal;
 import org.apache.commons.rdf.api.RDFTerm;
-import org.apache.commons.rdf.api.Triple;
 
 import com.github.jsonldjava.core.RDFDataset;
-import com.github.jsonldjava.core.RDFDataset.Node;
-import com.github.jsonldjava.core.RDFDataset.Quad;
 
-public class JsonLdGraph implements Graph {
-	
-	/** 
-	 * Used by {@link #bnodePrefix()} to get a unique UUID per JVM run
-	 */
-	private static UUID SALT = UUID.randomUUID();
-	
-	/**
-	 * The underlying JSON-LD {@link RDFDataset}.
-	 */
-	private RDFDataset rdfDataSet;
+public class JsonLdGraph extends JsonLdGraphLike<org.apache.commons.rdf.api.Triple> implements Graph {
 
-	/**
-	 * If true, include all Quad statements as Triples. If false, 
-	 * only Quads in the default graph (<code>null</code>) are
-	 * included.
-	 */
-	private final boolean unionGraph;
+	private final Optional<BlankNodeOrIRI> graphName;
 
-	/**
-	 * Prefix to use in blank node identifiers
-	 */
-	private final String bnodePrefix;
-
-	private JsonLdRDFTermFactory factory;
-	
-	public JsonLdGraph() {
-		this(new RDFDataset(), false);		
+	JsonLdGraph(String bnodePrefix) {
+		super(bnodePrefix);
+		this.graphName = Optional.empty();
 	}
 	
-	public JsonLdGraph(RDFDataset rdfDataset) {
-		this(rdfDataset, false);
+	public JsonLdGraph(RDFDataset rdfDataSet) {
+		super(rdfDataSet);
+		this.graphName = Optional.empty();
 	}
-
-	public JsonLdGraph(RDFDataset rdfDataset, boolean unionGraph) {
-		this.rdfDataSet = rdfDataset;	
-		this.unionGraph = unionGraph;
-		this.bnodePrefix = "urn:uuid:" + SALT + "#" +  "g"+ System.identityHashCode(rdfDataSet);
-		this.factory = new JsonLdRDFTermFactory(bnodePrefix);
-	}
-
 	
-	public RDFDataset getRdfDataSet() {
-		return rdfDataSet;
+	JsonLdGraph(RDFDataset rdfDataSet, Optional<BlankNodeOrIRI> graphName, String bnodePrefix) {
+		super(rdfDataSet, bnodePrefix);
+		this.graphName = graphName;
 	}
 
 
 	@Override
 	public void add(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		String subjectStr;
-		if (subject instanceof BlankNode) { 
-			subjectStr = subject.ntriplesString();
-		} else if (subject instanceof IRI){
-			subjectStr = ((IRI)subject).getIRIString();
-		} else { 
-			throw new IllegalStateException("Subject was neither IRI or BlankNode: " + subject);
-		}
-		
-		String predicateStr = predicate.getIRIString();
-		
-		if (object instanceof Literal) {
-			Literal literal = (Literal) object;
-			rdfDataSet.addTriple(subjectStr, predicateStr, literal.getLexicalForm(), literal.getDatatype().getIRIString(), literal.getLanguageTag().orElse(null));			
-		} else if (object instanceof BlankNode) {
-			rdfDataSet.addTriple(subjectStr, predicateStr, object.ntriplesString());
-		} else if (object instanceof IRI) { 
-			rdfDataSet.addTriple(subjectStr, predicateStr, ((IRI)object).getIRIString());
-		} else { 
-			throw new IllegalStateException("Object was neither IRI, BlankNode nor Literal: " + object);
-		}				
+		super.add(graphName.orElse(null), subject, predicate, object);
 	}
 
 	@Override
-	public void add(Triple triple) {
-		// Quad q = asJsonLdQuad(triple);
-		// rdfDataSet.addQuad(q);
-		
-		add(triple.getSubject(), triple.getPredicate(), triple.getObject());
-	}
-
-	@Override
-	public void clear() {
-		if (unionGraph) {
-			// Delete all quads
-			rdfDataSet.clear();
-		} else {
-			// Only the @default quads removed
-			rdfDataSet.getQuads("@default").clear();
-		}
-	}
-	@Override
-	public void close() {
-		// Drop the memory reference, but don't clear it
-		rdfDataSet = null;			
-	}
-	
-	@Override
 	public boolean contains(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		return stream(subject, predicate, object).findAny().isPresent();
-	}
-
-	@Override
-	public boolean contains(Triple triple) {
-		return stream().anyMatch(Predicate.isEqual(triple));
-	}
-
-	@Override
-	public Stream<? extends Triple> stream() {
-		if (! unionGraph) {
-			return rdfDataSet.getQuads("@default").parallelStream().map(factory::asTriple);
-		}
-		return rdfDataSet.graphNames().parallelStream().map(rdfDataSet::getQuads).flatMap(List<Quad>::parallelStream).map(factory::asTriple);
+		return super.contains(graphName, subject, predicate, object);
 	}
-
+	
 	@Override
-	public Stream<? extends Triple> stream(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		// RDFDataSet has no optimizations to help us, so we'll dispatch to filter()
-        return stream().filter(t -> {
-            if (subject != null && !t.getSubject().equals(subject)) {
-                return false;
-            }
-            if (predicate != null && !t.getPredicate().equals(predicate)) {
-                return false;
-            }
-            if (object != null && !t.getObject().equals(object)) {
-                return false;
-            }
-            return true;
-        });
+	public void remove(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		super.remove(graphName, subject, predicate, object);
 	}
 
 	@Override
-	public void remove(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {		
-		Predicate<? super Quad> filter = quadFilter(subject, predicate, object);
-		if (! unionGraph) {
-			rdfDataSet.getQuads("@default").removeIf(filter);
-		} else {
-			rdfDataSet.graphNames().parallelStream().map(rdfDataSet::getQuads).map(t -> t.removeIf(filter));
-		}
+	public Stream<JsonLdTriple> stream(BlankNodeOrIRI subject, IRI predicate,
+			RDFTerm object) {		
+		return filteredGraphs(graphName)
+				.flatMap(List::stream)
+				.filter(quadFilter(subject, predicate, object))
+				.map(factory::createTriple);
 	}
 
 	@Override
-	public void remove(Triple triple) {
-		remove(triple.getSubject(), triple.getPredicate(), triple.getObject());
+	JsonLdTriple asTripleOrQuad(com.github.jsonldjava.core.RDFDataset.Quad jsonldQuad) {
+		return factory.createTriple(jsonldQuad);
 	}
-
+	
 	@Override
 	public long size() {
-		if (! unionGraph) {
-			return rdfDataSet.getQuads("@default").size();
-		} else {
-			// Summarize graph.size() for all graphs
-			return rdfDataSet.graphNames().parallelStream().map(rdfDataSet::getQuads).collect(Collectors.summingLong(List::size));
-		}
-	}
-	
-	private Predicate<? super Quad> quadFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
-		Optional<Node> subjectNode = Optional.ofNullable(subject).map(factory::asJsonLdNode);
-		Optional<Node> predicateNode = Optional.ofNullable(predicate).map(factory::asJsonLdNode);
-		Optional<Node> objectNode = Optional.ofNullable(object).map(factory::asJsonLdNode);
-		
-		return q -> {
-		    if (subjectNode.isPresent() && subjectNode.get().compareTo(q.getSubject()) != 0) {
-		        return false;
-		    }
-		    if (predicateNode.isPresent() && predicateNode.get().compareTo(q.getPredicate()) != 0) {	          
-		        return false;
-		    }
-		    if (objectNode.isPresent() && objectNode.get().compareTo(q.getObject()) != 0) {
-		        return false;
-		    }
-		    return true;			
-		};
+		String g = graphName.map(this::asJsonLdString).orElse("@default");
+		return Optional.ofNullable(rdfDataSet.getQuads(g))
+				.map(List::size).orElse(0);
 	}
 }
+

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/1330627e/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraphLike.java
----------------------------------------------------------------------
diff --git a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraphLike.java b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraphLike.java
new file mode 100644
index 0000000..1da7506
--- /dev/null
+++ b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdGraphLike.java
@@ -0,0 +1,239 @@
+/**
+ * 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.commons.rdf.jsonldjava;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.rdf.api.BlankNode;
+import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.GraphLike;
+import org.apache.commons.rdf.api.IRI;
+import org.apache.commons.rdf.api.Literal;
+import org.apache.commons.rdf.api.RDFTerm;
+// NOTE: To avod confusion, don't importing either of the Quad
+import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.api.TripleLike;
+
+import com.github.jsonldjava.core.RDFDataset;
+import com.github.jsonldjava.core.RDFDataset.Node;
+import com.github.jsonldjava.core.RDFDataset.Quad;
+
+abstract class JsonLdGraphLike<T extends TripleLike<BlankNodeOrIRI, IRI, RDFTerm>>
+	implements GraphLike<T, BlankNodeOrIRI, IRI, RDFTerm> {
+	
+	/** 
+	 * Used by {@link #bnodePrefix()} to get a unique UUID per JVM run
+	 */
+	private static UUID SALT = UUID.randomUUID();
+	
+	/**
+	 * The underlying JSON-LD {@link RDFDataset}.
+	 */
+	RDFDataset rdfDataSet;
+
+	/**
+	 * Prefix to use in blank node identifiers
+	 */
+	final String bnodePrefix;
+
+	protected JsonLdRDFTermFactory factory;
+	
+	JsonLdGraphLike(String bnodePrefix) {
+		this(new RDFDataset(), bnodePrefix);
+	}
+
+	JsonLdGraphLike(RDFDataset rdfDataSet) {
+		this(rdfDataSet, "urn:uuid:" + SALT + "#" +  "g"+ System.identityHashCode(rdfDataSet));
+	}
+	
+	JsonLdGraphLike(RDFDataset rdfDataset, String bnodePrefix) {
+		rdfDataSet = rdfDataset;
+		this.bnodePrefix = bnodePrefix;
+		this.factory = new JsonLdRDFTermFactory(bnodePrefix);
+	}
+	
+	public RDFDataset getRdfDataSet() {
+		return rdfDataSet;
+	}
+
+	@Override
+	public void add(T tripleOrQuad) {
+		String g = graphNameAsJsonLdString(tripleOrQuad);
+
+		String s = asJsonLdString(tripleOrQuad.getSubject());
+		String p = asJsonLdString(tripleOrQuad.getPredicate());
+		
+		if (tripleOrQuad.getObject() instanceof BlankNodeOrIRI) {
+			String o = asJsonLdString((BlankNodeOrIRI)tripleOrQuad.getObject());
+			rdfDataSet.addQuad(s,p,o,g);
+		} else if(tripleOrQuad.getObject() instanceof Literal) { 
+			Literal literal = (Literal) tripleOrQuad.getObject();
+			String language = literal.getLanguageTag().orElse(null);
+			String datatype = literal.getDatatype().getIRIString();
+			rdfDataSet.addQuad(s,p,literal.getLexicalForm(), datatype, language, g);
+		}
+	}
+	
+	void add(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		String g = asJsonLdString(graphName);
+		String s = asJsonLdString(subject);
+		String p = asJsonLdString(predicate);		
+		if (object instanceof BlankNodeOrIRI) {
+			String o = asJsonLdString((BlankNodeOrIRI)object);
+			rdfDataSet.addQuad(s,p,o,g);
+		} else if(object instanceof Literal) { 
+			Literal literal = (Literal) object;
+			String language = literal.getLanguageTag().orElse(null);
+			String datatype = literal.getDatatype().getIRIString();
+			rdfDataSet.addQuad(s,p,literal.getLexicalForm(), datatype, language, g);
+		}		
+	}
+	
+
+	private String graphNameAsJsonLdString(T tripleOrQuad) {
+		if (tripleOrQuad instanceof org.apache.commons.rdf.api.Quad) {
+			org.apache.commons.rdf.api.Quad quad = (org.apache.commons.rdf.api.Quad)tripleOrQuad;
+			return quad.getGraphName().map(this::asJsonLdString).orElse("@default");			
+		}
+		return "@default";
+	}
+
+	protected String asJsonLdString(BlankNodeOrIRI blankNodeOrIRI) {
+		if (blankNodeOrIRI == null) {
+			return null;
+		}
+		if (blankNodeOrIRI instanceof IRI) {
+			return ((IRI)blankNodeOrIRI).getIRIString();
+		} else if (blankNodeOrIRI instanceof BlankNode) {
+			BlankNode blankNode = (BlankNode) blankNodeOrIRI;
+			String ref = blankNode.uniqueReference();
+			if (ref.startsWith(bnodePrefix)) { 
+				// One of ours (but possibly not a JsonLdBlankNode) -  
+				// we can use the suffix directly
+				return ref.replace(bnodePrefix, "_:");
+			} else {
+				// Map to unique bnode identifier, e.g. _:0dbd92ee-ab1a-45e7-bba2-7ade54f87ec5
+				UUID uuid = UUID.nameUUIDFromBytes(ref.getBytes(StandardCharsets.UTF_8));
+				return "_:"+ uuid;
+			}
+		} else {
+			throw new IllegalArgumentException("Expected a BlankNode or IRI, not: " + blankNodeOrIRI);
+		}
+	}
+	
+	@Override
+	public void clear() {
+		rdfDataSet.clear();
+	}
+	
+	public void close() {
+		// Drop the memory reference, but don't clear it
+		rdfDataSet = null;			
+	}
+	
+	@Override
+	public boolean contains(T tripleOrQuad) {		
+		return stream().anyMatch(Predicate.isEqual(tripleOrQuad));
+	}
+
+
+	// This will be made public in JsonLdDataset
+	// and is used by the other  methods.
+	boolean contains(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI s, IRI p, RDFTerm o) {
+		return filteredGraphs(graphName).flatMap(List::stream).anyMatch(quadFilter(s,p,o));
+	}
+	
+	/**
+	 * Convert JsonLd Quad to a Commons RDF {@link Triple} or {@link org.apache.commons.rdf.api.Quad}
+	 * 
+	 * 
+	 * @see JsonLdRDFTermFactory#createTriple(Quad)
+	 * @see JsonLdRDFTermFactory#createQuad(Quad)
+	 * @param jsonldQuad jsonld quad to convert
+	 * @return converted {@link TripleLike}
+	 */
+	abstract T asTripleOrQuad(RDFDataset.Quad jsonldQuad);
+	
+	@Override
+	public Stream<? extends T> stream() {
+		return rdfDataSet.graphNames().parallelStream()
+				.map(rdfDataSet::getQuads)
+				.flatMap(List<RDFDataset.Quad>::parallelStream)
+				.map(this::asTripleOrQuad);
+	}
+
+	@Override
+	public void remove(T t) {
+		if (t instanceof org.apache.commons.rdf.api.Quad) {
+			org.apache.commons.rdf.api.Quad q = (org.apache.commons.rdf.api.Quad) t;
+			remove(q.getGraphName(), q.getSubject(), q.getPredicate(), q.getObject());
+		} else {
+			remove(Optional.empty(), t.getSubject(), t.getPredicate(), t.getObject());
+		}
+	}
+
+	// This will be made public in JsonLdDataset
+	// and is used by the other remove methods.
+	void remove(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		// remove the quads which match our filter (which could have nulls as wildcards) 
+		filteredGraphs(graphName).forEach(t -> t.removeIf(quadFilter(subject, predicate, object)));
+	}
+
+	Stream<List<Quad>> filteredGraphs(Optional<BlankNodeOrIRI> graphName) {
+		return rdfDataSet.graphNames().parallelStream()
+				// if graphName == null (wildcard), select all graphs, 
+	 			// otherwise check its jsonld string
+			    // (including @default for default graph)
+				.filter(g -> graphName == null ||
+						g.equals(graphName.map(this::asJsonLdString).orElse("@default")))
+				// remove the quads which match our filter (which could have nulls as wildcards) 
+				.map(rdfDataSet::getQuads);
+	}
+	
+	
+	Predicate<RDFDataset.Quad> quadFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
+		Optional<Node> subjectNode = Optional.ofNullable(subject).map(factory::asJsonLdNode);
+		Optional<Node> predicateNode = Optional.ofNullable(predicate).map(factory::asJsonLdNode);
+		Optional<Node> objectNode = Optional.ofNullable(object).map(factory::asJsonLdNode);
+		
+		return q -> {
+		    if (subjectNode.isPresent() && subjectNode.get().compareTo(q.getSubject()) != 0) {
+		        return false;
+		    }
+		    if (predicateNode.isPresent() && predicateNode.get().compareTo(q.getPredicate()) != 0) {	          
+		        return false;
+		    }
+		    if (objectNode.isPresent() && objectNode.get().compareTo(q.getObject()) != 0) {
+		        return false;
+		    }
+		    return true;			
+		};
+	}
+	
+	@Override
+	public long size() {		
+		return rdfDataSet.graphNames().parallelStream().map(rdfDataSet::getQuads).collect(Collectors.summingLong(List::size));
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/1330627e/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdRDFTermFactory.java
----------------------------------------------------------------------
diff --git a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdRDFTermFactory.java b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdRDFTermFactory.java
index 607e319..be271ea 100644
--- a/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdRDFTermFactory.java
+++ b/jsonld-java/src/main/java/org/apache/commons/rdf/jsonldjava/JsonLdRDFTermFactory.java
@@ -17,30 +17,32 @@
  */
 package org.apache.commons.rdf.jsonldjava;
 
+import java.nio.charset.StandardCharsets;
 import java.util.UUID;
 
 import org.apache.commons.rdf.api.BlankNode;
 import org.apache.commons.rdf.api.BlankNodeOrIRI;
+import org.apache.commons.rdf.api.Dataset;
 import org.apache.commons.rdf.api.Graph;
 import org.apache.commons.rdf.api.IRI;
 import org.apache.commons.rdf.api.Literal;
 import org.apache.commons.rdf.api.QuadLike;
 import org.apache.commons.rdf.api.RDFTerm;
 import org.apache.commons.rdf.api.RDFTermFactory;
-import org.apache.commons.rdf.api.Triple;
 import org.apache.commons.rdf.api.TripleLike;
-import org.apache.commons.rdf.simple.Types;
 import org.apache.commons.rdf.jsonldjava.JsonLdBlankNode.JsonLdBlankNodeImpl;
-import org.apache.commons.rdf.jsonldjava.JsonLdTriple.JsonLdTripleImpl;
-import org.apache.commons.rdf.jsonldjava.JsonLdQuad.JsonLdQuadImpl;
 import org.apache.commons.rdf.jsonldjava.JsonLdLiteral.JsonLdLiteralImpl;
+import org.apache.commons.rdf.jsonldjava.JsonLdQuad.JsonLdQuadImpl;
+import org.apache.commons.rdf.jsonldjava.JsonLdTriple.JsonLdTripleImpl;
+import org.apache.commons.rdf.simple.Types;
 
 import com.github.jsonldjava.core.RDFDataset;
 import com.github.jsonldjava.core.RDFDataset.Node;
 
-
 public final class JsonLdRDFTermFactory implements RDFTermFactory {
 	
+	private final String bnodePrefix;
+	
 	public JsonLdRDFTermFactory() {
 		// An "outside Graph" bnodePrefix
 		this("urn:uuid:" + UUID.randomUUID() + "#b");
@@ -50,11 +52,14 @@ public final class JsonLdRDFTermFactory implements RDFTermFactory {
 		this.bnodePrefix = bnodePrefix;
 	}
 	
-	String bnodePrefix;
-	
 	@Override
 	public Graph createGraph() throws UnsupportedOperationException {
-		return new JsonLdGraph();
+		return new JsonLdGraph(bnodePrefix);
+	}
+	
+	@Override
+	public Dataset createDataset() throws UnsupportedOperationException {
+		return new JsonLdDataset(bnodePrefix);
 	}
 	
 	@Override
@@ -71,7 +76,7 @@ public final class JsonLdRDFTermFactory implements RDFTermFactory {
 	@Override
 	public JsonLdBlankNode createBlankNode(String name) {
 		String id = "_:" + name;
-		// TODO: Check if name is valid JSON-LD BlankNode identifier
+		// TODO: Check if name is valid JSON-LD BlankNode identifier		
 		return new JsonLdBlankNodeImpl(new RDFDataset.BlankNode(id), bnodePrefix);
 	}
 	
@@ -80,10 +85,14 @@ public final class JsonLdRDFTermFactory implements RDFTermFactory {
 		return new JsonLdTripleImpl(asJsonLdQuad(subject, predicate, object), bnodePrefix);
 	}
 	
-	public Triple asTriple(final RDFDataset.Quad quad) {
+	public JsonLdTriple createTriple(final RDFDataset.Quad quad) {
 		return new JsonLdTripleImpl(quad, bnodePrefix);
 	}
 
+	public JsonLdQuad createQuad(final RDFDataset.Quad quad) {
+		return new JsonLdQuadImpl(quad, bnodePrefix);
+	}
+	
 	@Override
 	public JsonLdQuad createQuad(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object)
 			throws IllegalArgumentException, UnsupportedOperationException {
@@ -91,18 +100,20 @@ public final class JsonLdRDFTermFactory implements RDFTermFactory {
 	}
 	
 	@Override
-	public JsonLdLiteral createLiteral(String literal) {		
+	public JsonLdLiteral createLiteral(String literal) {
 		return new JsonLdLiteralImpl(new RDFDataset.Literal(literal, null, null));
 	}
+
 	@Override
 	public JsonLdLiteral createLiteral(String literal, IRI dataType) {
-		return new JsonLdLiteralImpl(new RDFDataset.Literal(literal, dataType.getIRIString(), null));	}
+		return new JsonLdLiteralImpl(new RDFDataset.Literal(literal, dataType.getIRIString(), null));
+	}
+
 	@Override
 	public JsonLdLiteral createLiteral(String literal, String language) {
-		return new JsonLdLiteralImpl(new RDFDataset.Literal(literal, Types.RDF_LANGSTRING.getIRIString(), language));		
+		return new JsonLdLiteralImpl(new RDFDataset.Literal(literal, Types.RDF_LANGSTRING.getIRIString(), language));
 	}
 
-
 	public Node asJsonLdNode(RDFTerm term) {
 		if (term instanceof JsonLdTerm) {
 			// Return original Node
@@ -113,13 +124,16 @@ public final class JsonLdRDFTermFactory implements RDFTermFactory {
 		}
 		if (term instanceof BlankNode) {
 			
-			String uniqueReference = ((BlankNode)term).uniqueReference();
-			if (uniqueReference.startsWith(bnodePrefix)) {
-				// one of our own
-				// TODO: Retrieve the original BlankNode
-				return new RDFDataset.BlankNode(term.ntriplesString());
+			String ref = ((BlankNode)term).uniqueReference();
+			if (ref.startsWith(bnodePrefix)) {
+				// one of our own (but no longer a JsonLdBlankNode),
+				// we can recover the label after our unique prefix
+				return new RDFDataset.BlankNode(ref.replace(bnodePrefix, ""));
 			} 
-			return new RDFDataset.BlankNode( "_:" + uniqueReference );
+			// The "foreign" unique reference might not be a valid bnode string, 
+			// we'll convert to a UUID
+			UUID uuid = UUID.nameUUIDFromBytes(ref.getBytes(StandardCharsets.UTF_8));
+			return new RDFDataset.BlankNode( "_:" + uuid );
 		}
 		if (term instanceof Literal) {
 			Literal literal = (Literal) term;