Skip to content

Commit 3c8039f

Browse files
authored
Merge pull request #284 from jsonld-java/1.1
Current state of 1.1 development
2 parents 6faa828 + b6ba9e8 commit 3c8039f

File tree

8 files changed

+224
-140
lines changed

8 files changed

+224
-140
lines changed

core/reports/json-ld-api-tests-skip

Lines changed: 0 additions & 94 deletions
Large diffs are not rendered by default.

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

Lines changed: 117 additions & 34 deletions
Large diffs are not rendered by default.

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

Lines changed: 59 additions & 7 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
}
@@ -312,7 +317,9 @@ else if (JsonLdConsts.INDEX.equals(expandedProperty)
312317

313318
// NOTE: expanded value must be an array due to expansion
314319
// algorithm.
315-
320+
if (!(expandedValue instanceof List)) {
321+
throw new JsonLdError(Error.NOT_IMPLEMENTED, "no array: " + expandedValue);
322+
}
316323
// 7.5)
317324
if (((List<Object>) expandedValue).size() == 0) {
318325
// 7.5.1)
@@ -514,6 +521,7 @@ public Object expand(Context activeCtx, String activeProperty, Object element)
514521
return null;
515522
}
516523

524+
// GK: This would be the point to set `propertyScopedContext` to the `@context` entry for any term definition associated with `activeProperty`.
517525
// 3)
518526
if (element instanceof List) {
519527
// 3.1)
@@ -546,14 +554,19 @@ else if (element instanceof Map) {
546554
// access helper
547555
final Map<String, Object> elem = (Map<String, Object>) element;
548556
// 5)
557+
// This would be the place to revert the active context from any previous type-scoped context if the active context has a `previousContext` entry (with some exceptions when called from a map, or if it's a value object or a subject reference).
558+
// GK: If we found a `propertyScopedContext` above, we can parse it to create a new activeCtx using the `override protected` option
549559
if (elem.containsKey(JsonLdConsts.CONTEXT)) {
550560
activeCtx = activeCtx.parse(elem.get(JsonLdConsts.CONTEXT));
551561
}
562+
// GK: This would be the place to remember this version of activeCtx as `typeScopedContext`.
552563
// 6)
553564
Map<String, Object> result = newMap();
554565
// 7)
555566
final List<String> keys = new ArrayList<String>(elem.keySet());
556567
Collections.sort(keys);
568+
// GK: This is the place to check for a type-scoped context by checking any key that expands to `@type` to see the current context has a term that equals that key where the term definition includes `@context`, updating the activeCtx as you go (but using termScopedContext when checking the keys).
569+
// GK: 1.1 made the following loop somewhat recursive, due to nesting, so might want to extract into a method.
557570
for (final String key : keys) {
558571
final Object value = elem.get(key);
559572
// 7.1)
@@ -580,6 +593,8 @@ else if (element instanceof Map) {
580593
throw new JsonLdError(Error.COLLIDING_KEYWORDS,
581594
expandedProperty + " already exists in result");
582595
}
596+
// jsonld 1.1: 12 in https://w3c.github.io/json-ld-api/#algorithm-3
597+
Object inputType = elem.get(JsonLdConsts.TYPE);
583598
// 7.4.3)
584599
if (JsonLdConsts.ID.equals(expandedProperty)) {
585600
if (value instanceof String) {
@@ -645,11 +660,23 @@ else if (JsonLdConsts.GRAPH.equals(expandedProperty)) {
645660
}
646661
// 7.4.6)
647662
else if (JsonLdConsts.VALUE.equals(expandedProperty)) {
648-
if (value != null && (value instanceof Map || value instanceof List)) {
663+
// jsonld 1.1: 13.4.7.1 in https://w3c.github.io/json-ld-api/#algorithm-3
664+
if(JsonLdConsts.JSON.equals(inputType)) {
665+
expandedValue = value;
666+
if(opts.getProcessingMode().equals(JsonLdOptions.JSON_LD_1_0)) {
667+
throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE, value);
668+
}
669+
}
670+
// jsonld 1.1: 13.4.7.2 in https://w3c.github.io/json-ld-api/#algorithm-3
671+
else if (value != null && (value instanceof Map || value instanceof List)) {
649672
throw new JsonLdError(Error.INVALID_VALUE_OBJECT_VALUE,
650-
"value of " + expandedProperty + " must be a scalar or null");
673+
"value of " + expandedProperty + " must be a scalar or null, but was: " + value);
651674
}
652-
expandedValue = value;
675+
// jsonld 1.1: 13.4.7.3 in https://w3c.github.io/json-ld-api/#algorithm-3
676+
else {
677+
expandedValue = value;
678+
}
679+
// jsonld 1.1: 13.4.7.4 in https://w3c.github.io/json-ld-api/#algorithm-3
653680
if (expandedValue == null) {
654681
result.put(JsonLdConsts.VALUE, null);
655682
continue;
@@ -766,6 +793,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) {
766793
}
767794
}
768795
}
796+
// GK: Also, `@included`, `@graph`, and `@direction`
769797
// 7.4.11.4)
770798
continue;
771799
}
@@ -780,13 +808,26 @@ else if (frameExpansion && (JsonLdConsts.EXPLICIT.equals(expandedProperty)
780808
}
781809
// 7.4.12)
782810
if (expandedValue != null) {
811+
/* jsonld 1.1: 13.4.16 in https://w3c.github.io/json-ld-api/#algorithm-3
812+
if (!(expandedValue == null && JsonLdConsts.VALUE.equals(expandedProperty)
813+
&& (inputType == null || JsonLdConsts.JSON.equals(inputType)))) { */
783814
result.put(expandedProperty, expandedValue);
784815
}
785816
// 7.4.13)
786817
continue;
787818
}
819+
// jsonld 1.1: 13.5 in https://w3c.github.io/json-ld-api/#algorithm-3
820+
String containerMapping = activeCtx.getContainer(key);
821+
// jsonld 1.1: 13.6 in https://w3c.github.io/json-ld-api/#algorithm-3
822+
if (activeCtx.getTermDefinition(key) != null
823+
&& JsonLdConsts.JSON.equals(activeCtx.getTermDefinition(key).get(JsonLdConsts.TYPE))) {
824+
Map<String, Object> newMap = newMap();
825+
newMap.put(JsonLdConsts.VALUE, value);
826+
newMap.put(JsonLdConsts.TYPE, JsonLdConsts.JSON);
827+
expandedValue = newMap;
828+
}
788829
// 7.5
789-
else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key))
830+
else if (JsonLdConsts.LANGUAGE.equals(containerMapping)
790831
&& value instanceof Map) {
791832
// 7.5.1)
792833
expandedValue = new ArrayList<Object>();
@@ -801,6 +842,10 @@ else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key))
801842
}
802843
// 7.5.2.2)
803844
for (final Object item : (List<Object>) languageValue) {
845+
// jsonld 1.1: 13.7.4.2.1 in https://w3c.github.io/json-ld-api/#expansion-algorithm
846+
if(item == null) {
847+
continue;
848+
}
804849
// 7.5.2.2.1)
805850
if (!(item instanceof String)) {
806851
throw new JsonLdError(Error.INVALID_LANGUAGE_MAP_VALUE,
@@ -815,9 +860,12 @@ else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key))
815860
}
816861
}
817862
// 7.6)
863+
// GK: Also a place to see if key is `@json` for JSON literals.
818864
else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
819865
&& value instanceof Map) {
820866
// 7.6.1)
867+
// GK: `@index` also supports property indexing, if the term definition includes `@index`.
868+
// GK: A map can also include `@none`.
821869
expandedValue = new ArrayList<Object>();
822870
// 7.6.2)
823871
final List<String> indexKeys = new ArrayList<String>(
@@ -865,6 +913,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
865913
((Map<String, Object>) expandedValue).put(JsonLdConsts.LIST, tmp);
866914
}
867915
}
916+
// GK: Other container possibilities including `@graph`, `@id`, and `@type` along with variations.
868917
// 7.10)
869918
if (activeCtx.isReverseProperty(key)) {
870919
// 7.10.1)
@@ -937,8 +986,11 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
937986
// null, so simply return it
938987
return null;
939988
}
989+
else if (result.getOrDefault(JsonLdConsts.TYPE,"").equals(JsonLdConsts.JSON)) {
990+
// jsonld 1.1: 14.3 in https://w3c.github.io/json-ld-api/#algorithm-3
991+
}
940992
// 8.3)
941-
if (!(rval instanceof String) && result.containsKey(JsonLdConsts.LANGUAGE)) {
993+
else if (!(rval instanceof String) && result.containsKey(JsonLdConsts.LANGUAGE)) {
942994
throw new JsonLdError(Error.INVALID_LANGUAGE_TAGGED_VALUE,
943995
"when @language is used, @value must be a string");
944996
}

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

Lines changed: 8 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
@@ -58,6 +59,13 @@ public final class JsonLdConsts {
5859
public static final String VOCAB = "@vocab";
5960
public static final String BASE = "@base";
6061
public static final String REQUIRE_ALL = "@requireAll";
62+
public static final String VERSION = "@version";
63+
public static final String PROTECTED = "@protected";
64+
public static final String PROPAGATE = "@propagate";
65+
public static final String IMPORT = "@import";
66+
public static final String DIRECTION = "@direction";
67+
public static final String JSON = "@json";
68+
public static final String ANY = "@any";
6169

6270
public enum Embed {
6371
ALWAYS, NEVER, LAST, LINK;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,23 @@ public enum Error {
102102

103103
INVALID_EMBED_VALUE("invalid @embed value"),
104104

105+
INVALID_VERSION_VALUE("invalid @version value"),
106+
107+
PROCESSING_MODE_CONFLICT("processing mode conflict"),
108+
105109
// non spec related errors
106110
SYNTAX_ERROR("syntax error"),
107111

108-
NOT_IMPLEMENTED("not implemnted"),
112+
NOT_IMPLEMENTED("not implemented"),
109113

110114
UNKNOWN_FORMAT("unknown format"),
111115

112116
INVALID_INPUT("invalid input"),
113117

114118
PARSE_ERROR("parse error"),
115119

120+
INVALID_JSON_LITERAL("invalid JSON literal"),
121+
116122
UNKNOWN_ERROR("unknown error");
117123

118124
private final String error;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public JsonLdOptions copy() {
8787
* http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-processingMode
8888
* jsonld 1.1: https://www.w3.org/TR/json-ld11/#dfn-processing-mode
8989
*/
90-
private String processingMode = JSON_LD_1_0;
90+
private String processingMode = JSON_LD_1_1;
9191
/**
9292
* http://www.w3.org/TR/json-ld-api/#widl-JsonLdOptions-documentLoader
9393
*/

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ static boolean isKeyword(Object key) {
2626
if (!isString(key)) {
2727
return false;
2828
}
29+
// GK: Note that this set is somewhat dependent on the processing mode.
2930
return "@base".equals(key) || "@context".equals(key) || "@container".equals(key)
3031
|| "@default".equals(key) || "@embed".equals(key) || "@explicit".equals(key)
3132
|| "@graph".equals(key) || "@id".equals(key) || "@index".equals(key)
3233
|| "@language".equals(key) || "@list".equals(key) || "@omitDefault".equals(key)
3334
|| "@reverse".equals(key) || "@preserve".equals(key) || "@set".equals(key)
3435
|| "@type".equals(key) || "@value".equals(key) || "@vocab".equals(key)
35-
|| "@requireAll".equals(key);
36+
|| "@requireAll".equals(key) || "@version".equals(key)|| "@protected".equals(key)
37+
|| "@propagate".equals(key)|| "@import".equals(key)|| "@direction".equals(key)
38+
|| "@json".equals(key) || "@none".equals(key) || "@included".equals(key)
39+
|| "@nest".equals(key) || "@prefix".equals(key);
3640
}
3741

3842
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_DECIMAL;
1011
import static com.github.jsonldjava.core.JsonLdConsts.XSD_DOUBLE;
@@ -17,6 +18,7 @@
1718
import static com.github.jsonldjava.core.JsonLdUtils.isValue;
1819
import static com.github.jsonldjava.utils.Obj.newMap;
1920

21+
import java.io.IOException;
2022
import java.text.DecimalFormat;
2123
import java.text.DecimalFormatSymbols;
2224
import java.util.ArrayList;
@@ -28,6 +30,8 @@
2830
import java.util.Set;
2931
import java.util.regex.Pattern;
3032

33+
import com.github.jsonldjava.utils.JsonUtils;
34+
3135
/**
3236
* Starting to migrate away from using plain java Maps as the internal RDF
3337
* dataset store. Currently each item just wraps a Map based on the old format
@@ -240,7 +244,18 @@ Map<String, Object> toObject(Boolean useNativeTypes) throws JsonLdError {
240244
else {
241245
rval.put("@type", type);
242246
}
243-
} else if (!XSD_STRING.equals(type)) {
247+
}
248+
// jsonld 1.1: 2.5 in https://w3c.github.io/json-ld-api/#algorithm-16
249+
else if(RDF_JSON.equals(type)) {
250+
rval.put("@type", "@json");
251+
try {
252+
rval.put("@value", JsonUtils.fromString(value));
253+
} catch (IOException e) {
254+
e.printStackTrace();
255+
throw new JsonLdError(JsonLdError.Error.INVALID_JSON_LITERAL, value, e);
256+
}
257+
}
258+
else if (!XSD_STRING.equals(type)) {
244259
rval.put("@type", type);
245260
}
246261
}
@@ -684,7 +699,17 @@ private Node objectToRDF(Object item) {
684699
return new Literal((String) value,
685700
datatype == null ? RDF_LANGSTRING : (String) datatype,
686701
(String) ((Map<String, Object>) item).get("@language"));
687-
} else {
702+
}
703+
// jsonld 1.1: 8 in https://w3c.github.io/json-ld-api/#algorithm-13
704+
else if(JsonLdConsts.JSON.equals(datatype)) {
705+
try {
706+
return new Literal(JsonUtils.toString(value), RDF_JSON, null);
707+
} catch (IOException e) {
708+
e.printStackTrace();
709+
return null;
710+
}
711+
}
712+
else {
688713
return new Literal((String) value,
689714
datatype == null ? XSD_STRING : (String) datatype, null);
690715
}

0 commit comments

Comments
 (0)