Skip to content

Commit 53aa216

Browse files
committed
Some inline comments on areas that can use improvement for 1.1, focusing on expansion and context/term processing.
1 parent bbae6c3 commit 53aa216

3 files changed

Lines changed: 26 additions & 0 deletions

File tree

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,15 @@ public Context parse(Object localContext, List<String> remoteContexts) throws Js
163163
* @throws JsonLdError
164164
* If there is an error parsing the contexts.
165165
*/
166+
// GK: Note that parsing may also depend on some options: `override protected and `propagate`
166167
private Context parse(Object localContext, List<String> remoteContexts,
167168
boolean parsingARemoteContext) throws JsonLdError {
168169
if (remoteContexts == null) {
169170
remoteContexts = new ArrayList<String>();
170171
}
171172
// 1. Initialize result to the result of cloning active context.
172173
Context result = this.clone(); // TODO: clone?
174+
// GK: note if localContext is a Map containing `@propagate` that value overrides the `propagate` option.
173175
// 2)
174176
if (!(localContext instanceof List)) {
175177
final Object temp = localContext;
@@ -180,6 +182,8 @@ private Context parse(Object localContext, List<String> remoteContexts,
180182
for (final Object context : ((List<Object>) localContext)) {
181183
// 3.1)
182184
if (context == null) {
185+
// GK: Note, if active context has any protected terms, and `override protected` is not true, this should fail with 'invalid context nullification'.
186+
// GK: Note, if `propagate` is false, the previous context should be associated with this new (null) context for potential rollback.
183187
result = new Context(this.options);
184188
continue;
185189
} else if (context instanceof Context) {
@@ -188,6 +192,7 @@ private Context parse(Object localContext, List<String> remoteContexts,
188192
// 3.2)
189193
else if (context instanceof String) {
190194
String uri = (String) result.get(JsonLdConsts.BASE);
195+
// GK: Note, the context needs to be resolved against the location of the file containing the reference, not the base association from the context. The spec defines a `context base` for this purpose.
191196
uri = JsonLdUrl.resolve(uri, (String) context);
192197
// 3.2.2
193198
if (remoteContexts.contains(uri)) {
@@ -273,6 +278,8 @@ else if (context instanceof String) {
273278
}
274279
}
275280

281+
// GK: There are more keys to be checked: `@import`, `@direction`, `@propagate` and `@version`.
282+
// GK: You'll want some `processingMode` method to use when doing conditional checks; default value is `json-ld-1.1`, but can be overridden using an API option.
276283
// 3.7
277284
final Map<String, Boolean> defined = new LinkedHashMap<String, Boolean>();
278285
for (final String key : ((Map<String, Object>) context).keySet()) {
@@ -321,12 +328,14 @@ private void createTermDefinition(Map<String, Object> context, String term,
321328

322329
defined.put(term, false);
323330

331+
// GK: Note, `@type` can also contain `@protected` in addition to `@container`. If `@container` is there, its value can only be `@set` (or `['@set']`).
324332
if (JsonLdUtils.isKeyword(term)
325333
&& !(options.getAllowContainerSetOnType() && JsonLdConsts.TYPE.equals(term)
326334
&& !(context.get(term)).toString().contains(JsonLdConsts.ID))) {
327335
throw new JsonLdError(Error.KEYWORD_REDEFINITION, term);
328336
}
329337

338+
// GK: Note, you'll need to retain any previous definition to make sure, if protected, that any new definition is compatible with it before ending this method.
330339
this.termDefinitions.remove(term);
331340
Object value = context.get(term);
332341
if (value == null || (value instanceof Map
@@ -415,6 +424,7 @@ private void createTermDefinition(Map<String, Object> context, String term,
415424
definition.put(JsonLdConsts.REVERSE, false);
416425

417426
// 13)
427+
// GK: Note, there are some required checks to be sure that if the associated term expands to an IRI, it is compatible with `@id` and some other checks.
418428
if (val.get(JsonLdConsts.ID) != null && !term.equals(val.get(JsonLdConsts.ID))) {
419429
if (!(val.get(JsonLdConsts.ID) instanceof String)) {
420430
throw new JsonLdError(Error.INVALID_IRI_MAPPING,
@@ -458,6 +468,7 @@ else if (term.indexOf(":") >= 0) {
458468
}
459469

460470
// 16)
471+
// GK: Note, `@container` can take on many more values, and be an array. Best always cast to an array and check to see if the container includes any useful value. There are also some checks to make sure that the content of `@context` is consistent.
461472
if (val.containsKey(JsonLdConsts.CONTAINER)) {
462473
final String container = (String) val.get(JsonLdConsts.CONTAINER);
463474
if (!JsonLdConsts.LIST.equals(container) && !JsonLdConsts.SET.equals(container)
@@ -485,6 +496,8 @@ else if (term.indexOf(":") >= 0) {
485496
}
486497
}
487498

499+
// GK: Note, other keys to check for are `@index`, `@context` (which requires a recursive call to Context.parse to make sure it's valid), `@direction`, `@nest`, and `@prefix`.
500+
// GK: Note, this is where to check if the previous definition exists and is protected, and we're not overriding protected, that the two definitions are essentially compatible.
488501
// 18)
489502
this.termDefinitions.put(term, definition);
490503
defined.put(term, true);
@@ -588,6 +601,7 @@ String compactIri(String iri, Object value, boolean relativeToVocab, boolean rev
588601

589602
// 2)
590603
if (relativeToVocab && getInverse().containsKey(iri)) {
604+
// GK: Sadly, term selection has become much more involved in 1.1.
591605
// 2.1)
592606
String defaultLanguage = (String) this.get(JsonLdConsts.LANGUAGE);
593607
if (defaultLanguage == null) {

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ public Object expand(Context activeCtx, String activeProperty, Object element)
514514
return null;
515515
}
516516

517+
// GK: This would be the point to set `propertyScopedContext` to the `@context` entry for any term definition associated with `activeProperty`.
517518
// 3)
518519
if (element instanceof List) {
519520
// 3.1)
@@ -546,14 +547,19 @@ else if (element instanceof Map) {
546547
// access helper
547548
final Map<String, Object> elem = (Map<String, Object>) element;
548549
// 5)
550+
// 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).
551+
// GK: If we found a `propertyScopedContext` above, we can parse it to create a new activeCtx using the `override protected` option
549552
if (elem.containsKey(JsonLdConsts.CONTEXT)) {
550553
activeCtx = activeCtx.parse(elem.get(JsonLdConsts.CONTEXT));
551554
}
555+
// GK: This would be the place to remember this version of activeCtx as `typeScopedContext`.
552556
// 6)
553557
Map<String, Object> result = newMap();
554558
// 7)
555559
final List<String> keys = new ArrayList<String>(elem.keySet());
556560
Collections.sort(keys);
561+
// 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).
562+
// GK: 1.1 made the following loop somewhat recursive, due to nesting, so might want to extract into a method.
557563
for (final String key : keys) {
558564
final Object value = elem.get(key);
559565
// 7.1)
@@ -766,6 +772,7 @@ else if (JsonLdConsts.REVERSE.equals(expandedProperty)) {
766772
}
767773
}
768774
}
775+
// GK: Also, `@included`, `@graph`, and `@direction`
769776
// 7.4.11.4)
770777
continue;
771778
}
@@ -815,9 +822,12 @@ else if (JsonLdConsts.LANGUAGE.equals(activeCtx.getContainer(key))
815822
}
816823
}
817824
// 7.6)
825+
// GK: Also a place to see if key is `@json` for JSON literals.
818826
else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
819827
&& value instanceof Map) {
820828
// 7.6.1)
829+
// GK: `@index` also supports property indexing, if the term definition includes `@index`.
830+
// GK: A map can also include `@none`.
821831
expandedValue = new ArrayList<Object>();
822832
// 7.6.2)
823833
final List<String> indexKeys = new ArrayList<String>(
@@ -865,6 +875,7 @@ else if (JsonLdConsts.INDEX.equals(activeCtx.getContainer(key))
865875
((Map<String, Object>) expandedValue).put(JsonLdConsts.LIST, tmp);
866876
}
867877
}
878+
// GK: Other container possibilities including `@graph`, `@id`, and `@type` along with variations.
868879
// 7.10)
869880
if (activeCtx.isReverseProperty(key)) {
870881
// 7.10.1)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ 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)

0 commit comments

Comments
 (0)