diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java index 2195d09a..8c29d224 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java @@ -2027,71 +2027,72 @@ public List fromRDF(final RDFDataset dataset, boolean noDuplicatesInData } } - // 4) - for (final String name : graphMap.keySet()) { - final Map graph = graphMap.get(name); + if (!opts.getExpandBNodeList()) { + // 4) + for (final String name : graphMap.keySet()) { + final Map graph = graphMap.get(name); - // 4.1) - if (!graph.containsKey(RDF_NIL)) { - continue; - } + // 4.1) + if (!graph.containsKey(RDF_NIL)) { + continue; + } - // 4.2) - final NodeMapNode nil = graph.get(RDF_NIL); - // 4.3) - for (final UsagesNode usage : nil.usages) { - // 4.3.1) - NodeMapNode node = usage.node; - String property = usage.property; - Map head = usage.value; - // 4.3.2) - final List list = new ArrayList(4); - final List listNodes = new ArrayList(4); - // 4.3.3) - while (RDF_REST.equals(property) && node.isWellFormedListNode()) { - // 4.3.3.1) - list.add(((List) node.get(RDF_FIRST)).get(0)); - // 4.3.3.2) - listNodes.add((String) node.get(JsonLdConsts.ID)); - // 4.3.3.3) - final UsagesNode nodeUsage = node.usages.get(0); - // 4.3.3.4) - node = nodeUsage.node; - property = nodeUsage.property; - head = nodeUsage.value; - // 4.3.3.5) - if (!JsonLdUtils.isBlankNode(node)) { - break; + // 4.2) + final NodeMapNode nil = graph.get(RDF_NIL); + // 4.3) + for (final UsagesNode usage : nil.usages) { + // 4.3.1) + NodeMapNode node = usage.node; + String property = usage.property; + Map head = usage.value; + // 4.3.2) + final List list = new ArrayList(4); + final List listNodes = new ArrayList(4); + // 4.3.3) + while (RDF_REST.equals(property) && node.isWellFormedListNode()) { + // 4.3.3.1) + list.add(((List) node.get(RDF_FIRST)).get(0)); + // 4.3.3.2) + listNodes.add((String) node.get(JsonLdConsts.ID)); + // 4.3.3.3) + final UsagesNode nodeUsage = node.usages.get(0); + // 4.3.3.4) + node = nodeUsage.node; + property = nodeUsage.property; + head = nodeUsage.value; + // 4.3.3.5) + if (!JsonLdUtils.isBlankNode(node)) { + break; + } } - } - // 4.3.4) - if (RDF_FIRST.equals(property)) { - // 4.3.4.1) - if (RDF_NIL.equals(node.get(JsonLdConsts.ID))) { - continue; + // 4.3.4) + if (RDF_FIRST.equals(property)) { + // 4.3.4.1) + if (RDF_NIL.equals(node.get(JsonLdConsts.ID))) { + continue; + } + // 4.3.4.3) + final String headId = (String) head.get(JsonLdConsts.ID); + // 4.3.4.4-5) + head = (Map) ((List) graph.get(headId).get(RDF_REST)) + .get(0); + // 4.3.4.6) + list.remove(list.size() - 1); + listNodes.remove(listNodes.size() - 1); + } + // 4.3.5) + head.remove(JsonLdConsts.ID); + // 4.3.6) + Collections.reverse(list); + // 4.3.7) + head.put(JsonLdConsts.LIST, list); + // 4.3.8) + for (final String nodeId : listNodes) { + graph.remove(nodeId); } - // 4.3.4.3) - final String headId = (String) head.get(JsonLdConsts.ID); - // 4.3.4.4-5) - head = (Map) ((List) graph.get(headId).get(RDF_REST)) - .get(0); - // 4.3.4.6) - list.remove(list.size() - 1); - listNodes.remove(listNodes.size() - 1); - } - // 4.3.5) - head.remove(JsonLdConsts.ID); - // 4.3.6) - Collections.reverse(list); - // 4.3.7) - head.put(JsonLdConsts.LIST, list); - // 4.3.8) - for (final String nodeId : listNodes) { - graph.remove(nodeId); } } } - // 5) final List result = new ArrayList(4); // 6) diff --git a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java index ff0038ee..c03dfb51 100644 --- a/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java +++ b/core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java @@ -58,6 +58,7 @@ public JsonLdOptions copy() { copy.setPruneBlankNodeIdentifiers(pruneBlankNodeIdentifiers); copy.setRequireAll(requireAll); copy.setAllowContainerSetOnType(allowContainerSetOnType); + copy.setExpandBNodeList(expandBNodeList); copy.setUseRdfType(useRdfType); copy.setUseNativeTypes(useNativeTypes); copy.setProduceGeneralizedRdf(produceGeneralizedRdf); @@ -102,6 +103,7 @@ public JsonLdOptions copy() { private Boolean pruneBlankNodeIdentifiers = false; private Boolean requireAll = false; private Boolean allowContainerSetOnType = false; + private Boolean expandBNodeList = false; // RDF conversion options : // http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm @@ -225,6 +227,14 @@ public void setAllowContainerSetOnType(Boolean allowContainerSetOnType) { this.allowContainerSetOnType = allowContainerSetOnType; } + public Boolean getExpandBNodeList() { + return expandBNodeList; + } + + public void setExpandBNodeList(Boolean expandBNodeList) { + this.expandBNodeList = expandBNodeList; + } + public Boolean getCompactArrays() { return compactArrays; } diff --git a/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java b/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java index 7586c1c6..16382b49 100644 --- a/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java +++ b/core/src/test/java/com/github/jsonldjava/core/JsonLdToRdfTest.java @@ -1,5 +1,6 @@ package com.github.jsonldjava.core; +import com.github.jsonldjava.utils.JsonUtils; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -28,4 +29,39 @@ public void testIssue301() throws JsonLdError { out2.toString()); } + @Test + public void testExpandedList() throws Exception { + RDFDataset rdf = new RDFDataset(); + rdf.addTriple( + "_:b0", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first", + "Arnold"); + rdf.addTriple( + "_:b0", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest", + "_:b1"); + rdf.addTriple( + "_:b1", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first", + "Bob"); + rdf.addTriple( + "_:b1", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest", + "_:b2"); + rdf.addTriple( + "_:b2", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#first", + "Catherine"); + rdf.addTriple( + "_:b2", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"); + + JsonLdOptions opts = new JsonLdOptions(); + assertEquals("[{\"@id\":\"_:b0\",\"http://www.w3.org/1999/02/22-rdf-syntax-ns#first\":[{\"@id\":\"Arnold\"}],\"http://www.w3.org/1999/02/22-rdf-syntax-ns#rest\":[{\"@list\":[{\"@id\":\"Bob\"},{\"@id\":\"Catherine\"}]}]}]", JsonUtils.toString(new JsonLdApi(opts).fromRDF(rdf))); + + opts.setExpandBNodeList(true); + assertEquals("[{\"@id\":\"_:b0\",\"http://www.w3.org/1999/02/22-rdf-syntax-ns#first\":[{\"@id\":\"Arnold\"}],\"http://www.w3.org/1999/02/22-rdf-syntax-ns#rest\":[{\"@id\":\"_:b1\"}]},{\"@id\":\"_:b1\",\"http://www.w3.org/1999/02/22-rdf-syntax-ns#first\":[{\"@id\":\"Bob\"}],\"http://www.w3.org/1999/02/22-rdf-syntax-ns#rest\":[{\"@id\":\"_:b2\"}]},{\"@id\":\"_:b2\",\"http://www.w3.org/1999/02/22-rdf-syntax-ns#first\":[{\"@id\":\"Catherine\"}],\"http://www.w3.org/1999/02/22-rdf-syntax-ns#rest\":[{\"@id\":\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\"}]}]", JsonUtils.toString(new JsonLdApi(opts).fromRDF(rdf))); + + } }