Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 413EA200BA6 for ; Mon, 3 Oct 2016 18:40:11 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 400AD160ACD; Mon, 3 Oct 2016 16:40:11 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id E55C2160ADC for ; Mon, 3 Oct 2016 18:40:09 +0200 (CEST) Received: (qmail 89666 invoked by uid 500); 3 Oct 2016 16:40:09 -0000 Mailing-List: contact commits-help@commonsrdf.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commonsrdf.incubator.apache.org Delivered-To: mailing list commits@commonsrdf.incubator.apache.org Received: (qmail 89657 invoked by uid 99); 3 Oct 2016 16:40:09 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Oct 2016 16:40:09 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id B1BFDC14C1 for ; Mon, 3 Oct 2016 16:40:08 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -6.219 X-Spam-Level: X-Spam-Status: No, score=-6.219 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-2.999] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id u9DaVSrtu3q6 for ; Mon, 3 Oct 2016 16:40:04 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id C5B3760D84 for ; Mon, 3 Oct 2016 16:40:01 +0000 (UTC) Received: (qmail 86779 invoked by uid 99); 3 Oct 2016 16:39:58 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Oct 2016 16:39:58 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4654DDFFD8; Mon, 3 Oct 2016 16:39:58 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: stain@apache.org To: commits@commonsrdf.incubator.apache.org Date: Mon, 03 Oct 2016 16:40:23 -0000 Message-Id: <3d3e40a739d0498c80932b1de586c1bc@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [27/50] incubator-commonsrdf git commit: Added JsonLdDataset, JsonLdGraphLike archived-at: Mon, 03 Oct 2016 16:40:11 -0000 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 Authored: Fri Sep 9 14:28:47 2016 +0100 Committer: Stian Soiland-Reyes 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 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 graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object) { + return super.contains(graphName, subject, predicate, object); + } + + @Override + public void remove(Optional 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 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 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 stream(Optional 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 implements Graph { - /** - * If true, include all Quad statements as Triples. If false, - * only Quads in the default graph (null) are - * included. - */ - private final boolean unionGraph; + private final Optional 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 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 stream() { - if (! unionGraph) { - return rdfDataSet.getQuads("@default").parallelStream().map(factory::asTriple); - } - return rdfDataSet.graphNames().parallelStream().map(rdfDataSet::getQuads).flatMap(List::parallelStream).map(factory::asTriple); + return super.contains(graphName, subject, predicate, object); } - + @Override - public Stream 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 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 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 quadFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) { - Optional subjectNode = Optional.ofNullable(subject).map(factory::asJsonLdNode); - Optional predicateNode = Optional.ofNullable(predicate).map(factory::asJsonLdNode); - Optional 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> + implements GraphLike { + + /** + * 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 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 stream() { + return rdfDataSet.graphNames().parallelStream() + .map(rdfDataSet::getQuads) + .flatMap(List::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 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> filteredGraphs(Optional 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 quadFilter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) { + Optional subjectNode = Optional.ofNullable(subject).map(factory::asJsonLdNode); + Optional predicateNode = Optional.ofNullable(predicate).map(factory::asJsonLdNode); + Optional 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;