Skip to content

Commit

Permalink
Merge pull request #198 from fsteeg/pruneBlankNodeIdentifiers
Browse files Browse the repository at this point in the history
Support `pruneBlankNodeIdentifiers` framing option in 1.1 mode
  • Loading branch information
ansell committed Aug 17, 2017
2 parents 034e33b + e79b27d commit 4dd9cd3
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 9 deletions.
4 changes: 4 additions & 0 deletions core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
18 changes: 17 additions & 1 deletion core/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
*/
public class JsonLdOptions {

private static final String JSON_LD_1_0 = "json-ld-1.0";

private static final String JSON_LD_1_1 = "json-ld-1.1";

public static final boolean DEFAULT_COMPACT_ARRAYS = true;

/**
Expand Down Expand Up @@ -47,7 +51,7 @@ public JsonLdOptions(String base) {
/**
* http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-processingMode
*/
private String processingMode = "json-ld-1.0";
private String processingMode = JSON_LD_1_0;
/**
* http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-documentLoader
*/
Expand All @@ -58,6 +62,7 @@ public JsonLdOptions(String base) {
private Boolean embed = null;
private Boolean explicit = null;
private Boolean omitDefault = null;
private Boolean pruneBlankNodeIdentifiers = true;

// RDF conversion options :
// http://www.w3.org/TR/json-ld-api/#serialize-rdf-as-json-ld-algorithm
Expand Down Expand Up @@ -90,6 +95,17 @@ public void setOmitDefault(Boolean omitDefault) {
this.omitDefault = omitDefault;
}

public Boolean getPruneBlankNodeIdentifiers() {
return pruneBlankNodeIdentifiers && getProcessingMode().equals(JSON_LD_1_1);
}

public void setPruneBlankNodeIdentifiers(Boolean pruneBlankNodeIdentifiers) {
if(pruneBlankNodeIdentifiers) {
setProcessingMode(JSON_LD_1_1);
}
this.pruneBlankNodeIdentifiers = pruneBlankNodeIdentifiers;
}

public Boolean getCompactArrays() {
return compactArrays;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.github.jsonldjava.core.JsonLdError.Error;
import com.github.jsonldjava.impl.NQuadRDFParser;
Expand Down Expand Up @@ -319,10 +325,33 @@ public static Map<String, Object> frame(Object input, Object frame, JsonLdOption
final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH);
final Map<String, Object> rval = activeCtx.serialize();
rval.put(alias, compacted);
JsonLdUtils.removePreserve(activeCtx, rval, opts);

Set<Object> toPrune = opts.getPruneBlankNodeIdentifiers() ?
blankNodeIdsToPrune(rval, new HashSet<>()) : Collections.emptySet();
JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune);
return rval;
}

private static Set<Object> blankNodeIdsToPrune(Object input, Set<Object> set) {
if (input instanceof List) {
((List<?>) input).forEach(e -> blankNodeIdsToPrune(e, set));
} else if (input instanceof Map) {
((Map<?, ?>) input).entrySet().forEach(e -> blankNodeIdsToPrune(e.getValue(), set));
} else if (input instanceof String) {
String p = (String) input;
if (p.startsWith("_:")) {
if(set.contains(p)){
// more than 1, don't prune
set.remove(p);
} else {
// exactly 1, prune
set.add(p);
}
}
}
return set;
}

/**
* A registry for RDF Parsers (in this case, JSONLDSerializers) used by
* fromRDF if no specific serializer is specified and options.format is set.
Expand Down
21 changes: 14 additions & 7 deletions core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.github.jsonldjava.utils.JsonLdUrl;
import com.github.jsonldjava.utils.Obj;
Expand Down Expand Up @@ -187,24 +189,25 @@ public static boolean isRelativeIri(String value) {
}

/**
* Removes the @preserve keywords as the last step of the framing algorithm.
* Removes the @preserve keywords and blank node IDs to prune as the last step of the framing algorithm.
*
* @param ctx
* the active context used to compact the input.
* @param input
* the framed, compacted output.
* @param toPrune The blank node IDs to prune.
* @param options
* the compaction options used.
*
* @return the resulting output.
* @throws JsonLdError
*/
static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) throws JsonLdError {
static Object removePreserveAndPrune(Context ctx, Object input, JsonLdOptions opts, Set<Object> toPrune) throws JsonLdError {
// recurse through arrays
if (isArray(input)) {
final List<Object> output = new ArrayList<Object>();
for (final Object i : (List<Object>) input) {
final Object result = removePreserve(ctx, i, opts);
final Object result = removePreserveAndPrune(ctx, i, opts, toPrune);
// drop nulls from arrays
if (result != null) {
output.add(result);
Expand All @@ -228,19 +231,23 @@ static Object removePreserve(Context ctx, Object input, JsonLdOptions opts) thro
// recurse through @lists
if (isList(input)) {
((Map<String, Object>) input).put("@list",
removePreserve(ctx, ((Map<String, Object>) input).get("@list"), opts));
removePreserveAndPrune(ctx, ((Map<String, Object>) input).get("@list"), opts, toPrune));
return input;
}

// recurse through properties
for (final String prop : ((Map<String, Object>) input).keySet()) {
Object result = removePreserve(ctx, ((Map<String, Object>) input).get(prop), opts);
for (final String prop : new LinkedHashSet<>(((Map<String, Object>) input).keySet())) {
Object result = removePreserveAndPrune(ctx, ((Map<String, Object>) input).get(prop), opts, toPrune);
final String container = ctx.getContainer(prop);
if (opts.getCompactArrays() && isArray(result)
&& ((List<Object>) result).size() == 1 && container == null) {
result = ((List<Object>) result).get(0);
}
((Map<String, Object>) input).put(prop, result);
if(ctx.expandIri(prop, false, false, null, null).equals(JsonLdConsts.ID) && toPrune.contains(result)) {
((Map<String, Object>) input).remove(prop);
} else {
((Map<String, Object>) input).put(prop, result);
}
}
}
return input;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.jsonldjava.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import java.io.IOException;
import java.util.Map;
Expand Down Expand Up @@ -41,4 +42,22 @@ public void testFrame0002() throws IOException, JsonLdError {
assertEquals(out, frame2);
}

@Test
public void testFrame0003() throws IOException, JsonLdError {
final Object frame = JsonUtils
.fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-frame.jsonld"));
final Object in = JsonUtils
.fromInputStream(getClass().getResourceAsStream("/custom/frame-0002-in.jsonld"));

JsonLdOptions opts = new JsonLdOptions();
opts.setCompactArrays(false);
opts.setProcessingMode("json-ld-1.1");
final Map<String, Object> frame2 = JsonLdProcessor.frame(in, frame, opts);
assertFalse("Result should contain no blank nodes", frame2.toString().contains("_:"));

final Object out = JsonUtils
.fromInputStream(getClass().getResourceAsStream("/custom/frame-0003-out.jsonld"));
assertEquals(out, frame2);
}

}
11 changes: 11 additions & 0 deletions core/src/test/resources/custom/frame-0003-out.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"@context" : {
"@vocab" : "http://xmlns.com/foaf/0.1/"
},
"@graph" : [ {
"@type" : "Person",
"member" : [{
"@type" : "Group"
}]
} ]
}

0 comments on commit 4dd9cd3

Please sign in to comment.