Skip to content

Commit 7aeae88

Browse files
committed
Support JSON literals
1 parent c6b0098 commit 7aeae88

File tree

6 files changed

+74
-12
lines changed

6 files changed

+74
-12
lines changed

core/src/main/java/com/github/jsonldjava/core/Context.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,14 @@ private void createTermDefinition(Map<String, Object> context, String term,
384384
}
385385
throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type, error);
386386
}
387+
// jsonld 1.1: 13.3 in https://w3c.github.io/json-ld-api/#algorithm-0
388+
if (JsonLdOptions.JSON_LD_1_0.equals(options.getProcessingMode())
389+
&& (JsonLdConsts.NONE.equals(type) || JsonLdConsts.JSON.equals(type))) {
390+
throw new JsonLdError(Error.INVALID_TYPE_MAPPING, type);
391+
}
387392
// TODO: fix check for absoluteIri (blank nodes shouldn't count, at
388393
// least not here!)
389-
if (JsonLdConsts.ID.equals(type) || JsonLdConsts.VOCAB.equals(type)
394+
if (JsonLdConsts.ID.equals(type) || JsonLdConsts.VOCAB.equals(type) || JsonLdConsts.JSON.equals(type)
390395
|| (!type.startsWith(JsonLdConsts.BLANK_NODE_PREFIX)
391396
&& JsonLdUtils.isAbsoluteIri(type))) {
392397
definition.put(JsonLdConsts.TYPE, type);
@@ -522,8 +527,7 @@ private String selectContainer(final List<?> allContainers) {
522527
return (String) supportedContainer.orElse(null);
523528
}
524529

525-
// jsonld 1.1: 22.1 in
526-
// https://w3c.github.io/json-ld-api/#create-term-definition
530+
// jsonld 1.1: 22.1 in https://w3c.github.io/json-ld-api/#create-term-definition
527531
private List<?> checkValidContainerEntry(final Object containerObject) {
528532
List<?> container = (List<?>) (containerObject instanceof List ? containerObject
529533
: Arrays.asList(containerObject));
@@ -607,8 +611,6 @@ String expandIri(String value, boolean relative, boolean vocab, Map<String, Obje
607611
// 6)
608612
else if (relative) {
609613
return JsonLdUrl.resolve((String) this.get(JsonLdConsts.BASE), value);
610-
} else if (context != null && JsonLdUtils.isRelativeIri(value)) {
611-
throw new JsonLdError(Error.INVALID_IRI_MAPPING, "not an absolute IRI: " + value);
612614
}
613615
// 7)
614616
return value;

core/src/main/java/com/github/jsonldjava/core/JsonLdApi.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,12 @@ public Object compact(Context activeCtx, String activeProperty, Object element,
188188
// 4
189189
if (elem.containsKey(JsonLdConsts.VALUE) || elem.containsKey(JsonLdConsts.ID)) {
190190
final Object compactedValue = activeCtx.compactValue(activeProperty, elem);
191-
if (!(compactedValue instanceof Map || compactedValue instanceof List)) {
191+
boolean isScalar = !(compactedValue instanceof Map || compactedValue instanceof List);
192+
// jsonld 1.1: 7 in https://w3c.github.io/json-ld-api/#algorithm-6
193+
boolean isJson = activeCtx.getTermDefinition(activeProperty) != null
194+
&& JsonLdConsts.JSON.equals(
195+
activeCtx.getTermDefinition(activeProperty).get(JsonLdConsts.TYPE));
196+
if (isScalar || isJson) {
192197
return compactedValue;
193198
}
194199
}
@@ -580,6 +585,8 @@ else if (element instanceof Map) {
580585
throw new JsonLdError(Error.COLLIDING_KEYWORDS,
581586
expandedProperty + " already exists in result");
582587
}
588+
// jsonld 1.1: 12 in https://w3c.github.io/json-ld-api/#algorithm-3
589+
Object inputType = elem.get(JsonLdConsts.TYPE);
583590
// 7.4.3)
584591
if (JsonLdConsts.ID.equals(expandedProperty)) {
585592
if (value instanceof String) {
@@ -645,6 +652,13 @@ else if (JsonLdConsts.GRAPH.equals(expandedProperty)) {
645652
}
646653
// 7.4.6)
647654
else if (JsonLdConsts.VALUE.equals(expandedProperty)) {
655+
// jsonld 1.1: 13.4.7.1 in https://w3c.github.io/json-ld-api/#algorithm-3
656+
if(JsonLdConsts.JSON.equals(inputType)) {
657+
expandedValue = value;
658+
if(opts.getProcessingMode().equals(JsonLdOptions.JSON_LD_1_0)) {
659+
throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE, value);
660+
}
661+
}
648662
if (value != null && (value instanceof Map || value instanceof List)) {
649663
throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE,
650664
"value of " + expandedProperty + " must be a scalar or null");
@@ -779,14 +793,26 @@ else if (frameExpansion && (JsonLdConsts.EXPLICIT.equals(expandedProperty)
779793
expandedValue = expand(activeCtx, expandedProperty, value);
780794
}
781795
// 7.4.12)
782-
if (expandedValue != null) {
796+
// jsonld 1.1: 13.4.16 in https://w3c.github.io/json-ld-api/#algorithm-3
797+
if (!(expandedValue == null && JsonLdConsts.VALUE.equals(expandedProperty)
798+
&& (inputType == null || JsonLdConsts.JSON.equals(inputType)))) {
783799
result.put(expandedProperty, expandedValue);
784800
}
785801
// 7.4.13)
786802
continue;
787803
}
804+
// jsonld 1.1: 13.5 in https://w3c.github.io/json-ld-api/#algorithm-3
805+
String containerMapping = activeCtx.getContainer(key);
806+
// jsonld 1.1: 13.6 in https://w3c.github.io/json-ld-api/#algorithm-3
807+
if (activeCtx.getTermDefinition(key) != null
808+
&& JsonLdConsts.JSON.equals(activeCtx.getTermDefinition(key).get(JsonLdConsts.TYPE))) {
809+
Map<String, Object> newMap = newMap();
810+
newMap.put(JsonLdConsts.VALUE, value);
811+
newMap.put(JsonLdConsts.TYPE, JsonLdConsts.JSON);
812+
expandedValue = newMap;
813+
}
788814
// 7.5
789-
else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key))
815+
else if (JsonLdConsts.LANGUAGE.equals(containerMapping)
790816
&& value instanceof Map) {
791817
// 7.5.1)
792818
expandedValue = new ArrayList<Object>();
@@ -937,8 +963,11 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
937963
// null, so simply return it
938964
return null;
939965
}
966+
else if (result.getOrDefault(JsonLdConsts.TYPE,"").equals(JsonLdConsts.JSON)) {
967+
// jsonld 1.1: 14.3 in https://w3c.github.io/json-ld-api/#algorithm-3
968+
}
940969
// 8.3)
941-
if (!(rval instanceof String) && result.containsKey(JsonLdConsts.LANGUAGE)) {
970+
else if (!(rval instanceof String) && result.containsKey(JsonLdConsts.LANGUAGE)) {
942971
throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_VALUE,
943972
"when @language is used, @value must be a string");
944973
}

core/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public final class JsonLdConsts {
2727
public static final String RDF_OBJECT = RDF_SYNTAX_NS + "object";
2828
public static final String RDF_LANGSTRING = RDF_SYNTAX_NS + "langString";
2929
public static final String RDF_LIST = RDF_SYNTAX_NS + "List";
30+
public static final String RDF_JSON = RDF_SYNTAX_NS + "JSON";
3031

3132
public static final String TEXT_TURTLE = "text/turtle";
3233
public static final String APPLICATION_NQUADS = "application/n-quads"; // https://www.w3.org/TR/n-quads/#sec-mediatype
@@ -63,6 +64,7 @@ public final class JsonLdConsts {
6364
public static final String PROPAGATE = "@propagate";
6465
public static final String IMPORT = "@import";
6566
public static final String DIRECTION = "@direction";
67+
public static final String JSON = "@json";
6668

6769
public enum Embed {
6870
ALWAYS, NEVER, LAST, LINK;

core/src/main/java/com/github/jsonldjava/core/JsonLdError.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ public enum Error {
117117

118118
PARSE_ERROR("parse error"),
119119

120+
INVALID_JSON_LITERAL("invalid JSON literal"),
121+
120122
UNKNOWN_ERROR("unknown error");
121123

122124
private final String error;

core/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ static boolean isKeyword(Object key) {
3232
|| "@language".equals(key) || "@list".equals(key) || "@omitDefault".equals(key)
3333
|| "@reverse".equals(key) || "@preserve".equals(key) || "@set".equals(key)
3434
|| "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key)
35-
|| "@requireAll".equals(key);
35+
|| "@requireAll".equals(key) || "@version".equals(key)|| "@protected".equals(key)
36+
|| "@propagate".equals(key)|| "@import".equals(key)|| "@direction".equals(key)
37+
|| "@json".equals(key);
3638
}
3739

3840
public static Boolean deepCompare(Object v1, Object v2, Boolean listOrderMatters) {

core/src/main/java/com/github/jsonldjava/core/RDFDataset.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static com.github.jsonldjava.core.JsonLdConsts.RDF_NIL;
66
import static com.github.jsonldjava.core.JsonLdConsts.RDF_REST;
77
import static com.github.jsonldjava.core.JsonLdConsts.RDF_TYPE;
8+
import static com.github.jsonldjava.core.JsonLdConsts.RDF_JSON;
89
import static com.github.jsonldjava.core.JsonLdConsts.XSD_BOOLEAN;
910
import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE;
1011
import static com.github.jsonldjava.core.JsonLdConsts.XSD_INTEGER;
@@ -16,6 +17,7 @@
1617
import static com.github.jsonldjava.core.JsonLdUtils.isValue;
1718
import static com.github.jsonldjava.utils.Obj.newMap;
1819

20+
import java.io.IOException;
1921
import java.text.DecimalFormat;
2022
import java.text.DecimalFormatSymbols;
2123
import java.util.ArrayList;
@@ -27,6 +29,8 @@
2729
import java.util.Set;
2830
import java.util.regex.Pattern;
2931

32+
import com.github.jsonldjava.utils.JsonUtils;
33+
3034
/**
3135
* Starting to migrate away from using plain java Maps as the internal RDF
3236
* dataset store. Currently each item just wraps a Map based on the old format
@@ -239,7 +243,18 @@ Map<String, Object> toObject(Boolean useNativeTypes) throws JsonLdError {
239243
else {
240244
rval.put("@type", type);
241245
}
242-
} else if (!XSD_STRING.equals(type)) {
246+
}
247+
// jsonld 1.1: 2.5 in https://w3c.github.io/json-ld-api/#algorithm-16
248+
else if(RDF_JSON.equals(type)) {
249+
rval.put("@type", "@json");
250+
try {
251+
rval.put("@value", JsonUtils.fromString(value));
252+
} catch (IOException e) {
253+
e.printStackTrace();
254+
throw new JsonLdError(JsonLdError.Error.INVALID_JSON_LITERAL, value, e);
255+
}
256+
}
257+
else if (!XSD_STRING.equals(type)) {
243258
rval.put("@type", type);
244259
}
245260
}
@@ -680,7 +695,17 @@ private Node objectToRDF(Object item) {
680695
return new Literal((String) value,
681696
datatype == null ? RDF_LANGSTRING : (String) datatype,
682697
(String) ((Map<String, Object>) item).get("@language"));
683-
} else {
698+
}
699+
// jsonld 1.1: 8 in https://w3c.github.io/json-ld-api/#algorithm-13
700+
else if(JsonLdConsts.JSON.equals(datatype)) {
701+
try {
702+
return new Literal(JsonUtils.toString(value), RDF_JSON, null);
703+
} catch (IOException e) {
704+
e.printStackTrace();
705+
return null;
706+
}
707+
}
708+
else {
684709
return new Literal((String) value,
685710
datatype == null ? XSD_STRING : (String) datatype, null);
686711
}

0 commit comments

Comments
 (0)