From 13508fa0dcb4671ea12813aebaa9c57a13aad8bc Mon Sep 17 00:00:00 2001 From: Filip Date: Tue, 5 Dec 2023 23:28:51 +0100 Subject: [PATCH 01/13] Add ProcessingContext skeleton --- .../jsonld/processor/ProcessingContext.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java new file mode 100644 index 00000000..85643a40 --- /dev/null +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java @@ -0,0 +1,42 @@ +package com.apicatalog.jsonld.processor; + +import java.time.Duration; + +import com.apicatalog.jsonld.JsonLdError; + +/** + * A runtime context used during a transformation processing. + * + * @since 1.4.0 + */ +public class ProcessingContext { + + protected Duration timout; + + /** + * Called in multiple places during a processing to check processing timeout if + * set. Does nothing if timeout is not set. + * + * When hit for the first time a timestamp is set, otherwise a duration is + * decreased by timestamps difference. + * + * @throws JsonLdError if a processing has exceeded + */ + public void ping() throws JsonLdError { + + } + + /** + * Update remaining time and resets timestamp. Is used top stop counting + * processing time when an external library is called, e.g. a HTTP call. + */ + public void pause() { + + } + + public ProcessingContext timout(Duration timout) { + this.timout = timout; + return this; + } + +} From 20db8d5196c4e4e502db3293ea172bf857a3510b Mon Sep 17 00:00:00 2001 From: Filip Date: Tue, 5 Dec 2023 23:51:18 +0100 Subject: [PATCH 02/13] Hookup ProcessingRuntime into ActiveContext --- .../jsonld/context/ActiveContext.java | 32 ++++++++++------- .../jsonld/context/ActiveContextBuilder.java | 4 +-- .../jsonld/processor/CompactionProcessor.java | 36 +++++++++---------- .../jsonld/processor/ExpansionProcessor.java | 2 +- .../jsonld/processor/FramingProcessor.java | 2 +- ...ingContext.java => ProcessingRuntime.java} | 19 ++++++++-- 6 files changed, 59 insertions(+), 36 deletions(-) rename src/main/java/com/apicatalog/jsonld/processor/{ProcessingContext.java => ProcessingRuntime.java} (64%) diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java index 9138ea11..db12de00 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java @@ -28,6 +28,7 @@ import com.apicatalog.jsonld.expansion.UriExpansion; import com.apicatalog.jsonld.expansion.ValueExpansion; import com.apicatalog.jsonld.lang.DirectionType; +import com.apicatalog.jsonld.processor.ProcessingRuntime; import jakarta.json.JsonObject; @@ -61,23 +62,23 @@ public final class ActiveContext { // an optional default base direction ("ltr" or "rtl") private DirectionType defaultBaseDirection; + + private final ProcessingRuntime runtime; - private final JsonLdOptions options; - - public ActiveContext(final JsonLdOptions options) { - this(null, null, null, options); + public ActiveContext(final ProcessingRuntime runtime) { + this(null, null, null, runtime); } - public ActiveContext(final URI baseUri, final URI baseUrl, JsonLdOptions options) { - this(baseUri, baseUrl, null, options); + public ActiveContext(final URI baseUri, final URI baseUrl, ProcessingRuntime runtime) { + this(baseUri, baseUrl, null, runtime); } - public ActiveContext(final URI baseUri, final URI baseUrl, final ActiveContext previousContext, final JsonLdOptions options) { + public ActiveContext(final URI baseUri, final URI baseUrl, final ActiveContext previousContext, final ProcessingRuntime runtime) { this.baseUri = baseUri; this.baseUrl = baseUrl; this.previousContext = previousContext; this.terms = new LinkedHashMap<>(); - this.options = options; + this.runtime = runtime; } // copy constructor @@ -90,7 +91,7 @@ public ActiveContext(final ActiveContext origin) { this.vocabularyMapping = origin.vocabularyMapping; this.defaultLanguage = origin.defaultLanguage; this.defaultBaseDirection = origin.defaultBaseDirection; - this.options = origin.options; + this.runtime = origin.runtime; } public void createInverseContext() { @@ -132,8 +133,10 @@ public String getVocabularyMapping() { return vocabularyMapping; } + //TODO move to runtime + @Deprecated(since="1.4.0") public boolean inMode(final JsonLdVersion version) { - return options.getProcessingMode() != null && options.getProcessingMode().equals(version); + return getOptions().getProcessingMode() != null && getOptions().getProcessingMode().equals(version); } public ActiveContext getPreviousContext() { @@ -165,7 +168,7 @@ public ActiveContextBuilder newContext() { } public UriExpansion uriExpansion() { - return UriExpansion.with(this).uriValidation(options.isUriValidation()); + return UriExpansion.with(this).uriValidation(runtime.isUriValidation()); } public ValueExpansion valueExpansion() { @@ -188,8 +191,9 @@ public TermSelector termSelector(final String variable, final Collection return TermSelector.with(this, variable, containerMapping, typeLanguage); } + @Deprecated(since="1.4.0") public JsonLdOptions getOptions() { - return options; + return runtime.getOptions(); } protected void setDefaultBaseDirection(final DirectionType defaultBaseDirection) { @@ -224,4 +228,8 @@ protected void setTerm(final String term, final TermDefinition definition) { public String toString() { return "ActiveContext[terms=" + terms + ", previousContext=" + previousContext + "]"; } + + public ProcessingRuntime getRuntime() { + return runtime; + } } diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java index 10b3d9fc..e6ee66b5 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java @@ -160,8 +160,8 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr // and, if propagate is false, previous context in result to the previous value // of result. result = propagate - ? new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), activeContext.getOptions()) - : new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), result.getPreviousContext(), activeContext.getOptions()); + ? new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), activeContext.getRuntime()) + : new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), result.getPreviousContext(), activeContext.getRuntime()); // 5.1.3. Continue with the next context continue; diff --git a/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java index 8c86d65e..3fec2731 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java @@ -34,7 +34,8 @@ /** * - * @see JsonLdProcessor.compact() + * @see JsonLdProcessor.compact() * */ public final class CompactionProcessor { @@ -108,11 +109,12 @@ public static final JsonObject compact(final Document input, final Document cont // 6. final JsonValue contextValue = context.getJsonContent() - .map(ctx -> JsonUtils.flatten(ctx, Keywords.CONTEXT)) - .orElse(JsonValue.EMPTY_JSON_OBJECT); + .map(ctx -> JsonUtils.flatten(ctx, Keywords.CONTEXT)) + .orElse(JsonValue.EMPTY_JSON_OBJECT); // 7. - final ActiveContext activeContext = new ActiveContext(options).newContext().create(contextValue, contextBase); + final ActiveContext activeContext = new ActiveContext( + ProcessingRuntime.from(options)).newContext().create(contextValue, contextBase); // 8. if (activeContext.getBaseUri() == null) { @@ -127,23 +129,22 @@ public static final JsonObject compact(final Document input, final Document cont // 9. JsonValue compactedOutput = Compaction - .with(activeContext) - .compactArrays(options.isCompactArrays()) - .ordered(options.isOrdered()) - .compact(expandedInput); + .with(activeContext) + .compactArrays(options.isCompactArrays()) + .ordered(options.isOrdered()) + .compact(expandedInput); // 9.1. if (JsonUtils.isEmptyArray(compactedOutput)) { compactedOutput = JsonValue.EMPTY_JSON_OBJECT; - // 9.2. + // 9.2. } else if (JsonUtils.isArray(compactedOutput)) { compactedOutput = JsonProvider.instance().createObjectBuilder() - .add( - activeContext.uriCompaction().vocab(true).compact(Keywords.GRAPH), - compactedOutput - ) - .build(); + .add( + activeContext.uriCompaction().vocab(true).compact(Keywords.GRAPH), + compactedOutput) + .build(); } if (JsonUtils.isNull(compactedOutput) || compactedOutput.asJsonObject().isEmpty()) { @@ -153,11 +154,10 @@ public static final JsonObject compact(final Document input, final Document cont // 9.3. if (JsonUtils.isNotNull(contextValue) && !JsonUtils.isEmptyArray(contextValue) - && !JsonUtils.isEmptyObject(contextValue) - ) { + && !JsonUtils.isEmptyObject(contextValue)) { compactedOutput = JsonProvider.instance().createObjectBuilder(compactedOutput.asJsonObject()) - .add(Keywords.CONTEXT, contextValue) - .build(); + .add(Keywords.CONTEXT, contextValue) + .build(); } return compactedOutput.asJsonObject(); diff --git a/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java index 6b615374..b51bf9c5 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java @@ -93,7 +93,7 @@ public static final JsonArray expand(Document input, final JsonLdOptions options baseUri = options.getBase(); } - ActiveContext activeContext = new ActiveContext(baseUri, baseUrl, options); + ActiveContext activeContext = new ActiveContext(baseUri, baseUrl, ProcessingRuntime.from(options)); // 6. If the expandContext option in options is set, update the active context // using the Context Processing algorithm, passing the expandContext as diff --git a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java index 6b4cc9fe..2fa53731 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java @@ -133,7 +133,7 @@ public static final JsonObject frame(final Document input, final Document frame, // 10-11. final ActiveContext activeContext = - new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), options) + new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.from(options)) .newContext() .create(context, contextBase); diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java similarity index 64% rename from src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java rename to src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 85643a40..20f8c775 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingContext.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -3,14 +3,16 @@ import java.time.Duration; import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.JsonLdOptions; /** * A runtime context used during a transformation processing. * * @since 1.4.0 */ -public class ProcessingContext { +public class ProcessingRuntime { + protected JsonLdOptions options; protected Duration timout; /** @@ -34,9 +36,22 @@ public void pause() { } - public ProcessingContext timout(Duration timout) { + public ProcessingRuntime timout(Duration timout) { this.timout = timout; return this; } + public JsonLdOptions getOptions() { + return options; + } + + public boolean isUriValidation() { + // TODO Auto-generated method stub + return false; + } + + public static ProcessingRuntime from(JsonLdOptions options) { + // TODO Auto-generated method stub + return null; + } } From 5f52335410bf1fcd11fb81f9c5208e78bd9a66ba Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:03:35 +0100 Subject: [PATCH 03/13] Integrate ProcessingRuntime --- .../jsonld/compaction/Compaction.java | 4 +- .../jsonld/compaction/UriCompaction.java | 2 +- .../jsonld/context/ActiveContext.java | 3 +- .../jsonld/context/ActiveContextBuilder.java | 36 ++++----- .../jsonld/expansion/ObjectExpansion1314.java | 8 +- .../jsonld/expansion/ValueExpansion.java | 2 +- .../jsonld/processor/FramingProcessor.java | 78 +++++++++---------- .../jsonld/processor/ProcessingRuntime.java | 47 +++++++++-- 8 files changed, 101 insertions(+), 79 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java index d6c61a29..0c2acaab 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java @@ -169,7 +169,7 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t // 7. if ((elementObject.containsKey(Keywords.VALUE) || elementObject.containsKey(Keywords.ID)) - && (!activeContext.getOptions().isRdfStar() || !elementObject.containsKey(Keywords.ANNOTATION))) { + && (!activeContext.runtime().isRdfStar() || !elementObject.containsKey(Keywords.ANNOTATION))) { final JsonValue result = activeContext.valueCompaction().compact(elementObject, activeProperty); @@ -242,7 +242,7 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t compactedValue = JsonUtils.toJsonValue(activeContext.uriCompaction().compact(((JsonString) expandedValue).getString())); // json-ld-star - } else if (activeContext.getOptions().isRdfStar() && NodeObject.isEmbeddedNode(expandedValue)) { + } else if (activeContext.runtime().isRdfStar() && NodeObject.isEmbeddedNode(expandedValue)) { compactedValue = Compaction.with(activeContext) .compactArrays(compactArrays) .ordered(ordered) diff --git a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java index 31bafbec..0ce498f0 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java @@ -406,7 +406,7 @@ public String compact(final String variable) throws JsonLdError { final JsonValue idValue = value.asJsonObject().get(Keywords.ID); // json-ld-star - if (activeContext.getOptions().isRdfStar() && NodeObject.isEmbeddedNode(idValue)) { + if (activeContext.runtime().isRdfStar() && NodeObject.isEmbeddedNode(idValue)) { preferredValues.add(Keywords.ID); preferredValues.add(Keywords.VOCAB); diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java index db12de00..c66e04e6 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java @@ -133,7 +133,6 @@ public String getVocabularyMapping() { return vocabularyMapping; } - //TODO move to runtime @Deprecated(since="1.4.0") public boolean inMode(final JsonLdVersion version) { return getOptions().getProcessingMode() != null && getOptions().getProcessingMode().equals(version); @@ -229,7 +228,7 @@ public String toString() { return "ActiveContext[terms=" + terms + ", previousContext=" + previousContext + "]"; } - public ProcessingRuntime getRuntime() { + public ProcessingRuntime runtime() { return runtime; } } diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java index e6ee66b5..719a0669 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java @@ -160,8 +160,8 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr // and, if propagate is false, previous context in result to the previous value // of result. result = propagate - ? new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), activeContext.getRuntime()) - : new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), result.getPreviousContext(), activeContext.getRuntime()); + ? new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), activeContext.runtime()) + : new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), result.getPreviousContext(), activeContext.runtime()); // 5.1.3. Continue with the next context continue; @@ -230,7 +230,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr final URI contextImportUri = UriResolver.resolveAsUri(baseUrl, ((JsonString) contextImport).getString()); // 5.6.4. - if (activeContext.getOptions().getDocumentLoader() == null) { + if (activeContext.runtime().getDocumentLoader() == null) { throw new JsonLdError(JsonLdErrorCode.LOADING_REMOTE_CONTEXT_FAILED); } @@ -242,7 +242,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr try { - final Document importedDocument = activeContext.getOptions().getDocumentLoader().loadDocument(contextImportUri, loaderOptions); + final Document importedDocument = activeContext.runtime().getDocumentLoader().loadDocument(contextImportUri, loaderOptions); if (importedDocument == null) { throw new JsonLdError(JsonLdErrorCode.INVALID_REMOTE_CONTEXT, "Imported context[" + contextImportUri + "] is null."); @@ -494,11 +494,10 @@ private void fetch(final String context, final URI baseUrl) throws JsonLdError { remoteContexts.add(contextKey); // 5.2.4 - if (activeContext.getOptions() != null - && activeContext.getOptions().getContextCache() != null - && activeContext.getOptions().getContextCache().containsKey(contextKey) && !validateScopedContext) { + if (activeContext.runtime().getContextCache() != null + && activeContext.runtime().getContextCache().containsKey(contextKey) && !validateScopedContext) { - JsonValue cachedContext = activeContext.getOptions().getContextCache().get(contextKey); + JsonValue cachedContext = activeContext.runtime().getContextCache().get(contextKey); result = result .newContext() .remoteContexts(new ArrayList<>(remoteContexts)) @@ -508,17 +507,16 @@ private void fetch(final String context, final URI baseUrl) throws JsonLdError { } // 5.2.5. - if (activeContext.getOptions().getDocumentLoader() == null) { + if (activeContext.runtime().getDocumentLoader() == null) { throw new JsonLdError(JsonLdErrorCode.LOADING_REMOTE_CONTEXT_FAILED, "Document loader is null. Cannot fetch [" + contextUri + "]."); } Document remoteImport = null; - if (activeContext.getOptions() != null - && activeContext.getOptions().getDocumentCache() != null - && activeContext.getOptions().getDocumentCache().containsKey(contextKey)) { + if (activeContext.runtime().getDocumentCache() != null + && activeContext.runtime().getDocumentCache().containsKey(contextKey)) { - remoteImport = activeContext.getOptions().getDocumentCache().get(contextKey); + remoteImport = activeContext.runtime().getDocumentCache().get(contextKey); } if (remoteImport == null) { @@ -529,7 +527,7 @@ private void fetch(final String context, final URI baseUrl) throws JsonLdError { try { - remoteImport = activeContext.getOptions().getDocumentLoader().loadDocument(contextUri, loaderOptions); + remoteImport = activeContext.runtime().getDocumentLoader().loadDocument(contextUri, loaderOptions); // 5.2.5.1. } catch (JsonLdError e) { @@ -563,10 +561,8 @@ private void fetch(final String context, final URI baseUrl) throws JsonLdError { importedContext = JsonProvider.instance().createObjectBuilder(importedContext.asJsonObject()).remove(Keywords.BASE).build(); } - if (activeContext.getOptions() != null - && activeContext.getOptions().getDocumentCache() != null) { - - activeContext.getOptions().getDocumentCache().put(contextKey, remoteImport); + if (activeContext.runtime().getDocumentCache() != null) { + activeContext.runtime().getDocumentCache().put(contextKey, remoteImport); } // 5.2.6 @@ -577,8 +573,8 @@ private void fetch(final String context, final URI baseUrl) throws JsonLdError { .validateScopedContext(validateScopedContext) .create(importedContext, remoteImport.getDocumentUrl()); - if (result.getOptions() != null && result.getOptions().getContextCache() != null && !validateScopedContext) { - result.getOptions().getContextCache().put(contextKey, importedContext); + if (result.runtime().getContextCache() != null && !validateScopedContext) { + result.runtime().getContextCache().put(contextKey, importedContext); } } catch (JsonLdError e) { diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java index 5c892796..e07e87bf 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java @@ -173,10 +173,10 @@ public void expand() throws JsonLdError { if (Keywords.ID.equals(expandedProperty)) { // Extension: JSON-LD-STAR (Experimental) - if (!activeContext.getOptions().isRdfStar() && Keywords.ANNOTATION.equals(activeProperty)) { + if (!activeContext.runtime().isRdfStar() && Keywords.ANNOTATION.equals(activeProperty)) { throw new JsonLdError(JsonLdErrorCode.INVALID_ANNOTATION); - } else if (activeContext.getOptions().isRdfStar() && JsonUtils.isNonEmptyObject(value)) { + } else if (activeContext.runtime().isRdfStar() && JsonUtils.isNonEmptyObject(value)) { expandedValue = Expansion .with(activeContext, value, null, baseUrl) @@ -189,7 +189,7 @@ public void expand() throws JsonLdError { } // 13.4.3.1 - } else if (!frameExpansion && JsonUtils.isNotString(value) && (!activeContext.getOptions().isNumericId() || JsonUtils.isNotNumber(value)) + } else if (!frameExpansion && JsonUtils.isNotString(value) && (!activeContext.runtime().isNumericId() || JsonUtils.isNotNumber(value)) || frameExpansion && JsonUtils.isNotString(value) && JsonUtils.isNonEmptyObject(value) @@ -641,7 +641,7 @@ else if (Keywords.INCLUDED.equals(expandedProperty)) { // Extension: JSON-LD-STAR (Experimental) if (Keywords.ANNOTATION.equals(expandedProperty)) { - if (!activeContext.getOptions().isRdfStar()) { + if (!activeContext.runtime().isRdfStar()) { continue; } diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java index 1cb247bb..93aad9e0 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java @@ -70,7 +70,7 @@ public JsonObject expand(final JsonValue value, final String activeProperty) thr idValue = ((JsonString) value).getString(); // custom extension allowing to process numeric ids - } else if (activeContext.getOptions().isNumericId() && JsonUtils.isNumber(value)) { + } else if (activeContext.runtime().isNumericId() && JsonUtils.isNumber(value)) { idValue = ((JsonNumber) value).toString(); } diff --git a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java index 2fa53731..c5e0578c 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java @@ -53,7 +53,8 @@ /** * - * @see JsonLdProcessor.frame() + * @see JsonLdProcessor.frame() * */ public final class FramingProcessor { @@ -98,10 +99,9 @@ public static final JsonObject frame(final Document input, final Document frame, throw new JsonLdError(JsonLdErrorCode.LOADING_DOCUMENT_FAILED, "Frame or Frame.Document is null."); } - final JsonStructure frameStructure = - frame - .getJsonContent() - .orElseThrow(() -> new JsonLdError(JsonLdErrorCode.LOADING_DOCUMENT_FAILED, "Frame is not JSON object but null.")); + final JsonStructure frameStructure = frame + .getJsonContent() + .orElseThrow(() -> new JsonLdError(JsonLdErrorCode.LOADING_DOCUMENT_FAILED, "Frame is not JSON object but null.")); if (JsonUtils.isNotObject(frameStructure)) { throw new JsonLdError(JsonLdErrorCode.LOADING_DOCUMENT_FAILED, "Frame is not JSON object but [" + frameStructure + "]."); @@ -118,31 +118,28 @@ public static final JsonObject frame(final Document input, final Document frame, // 7. JsonArray expandedFrame = ExpansionProcessor.expand(frame, expansionOptions, true); - JsonValue context = JsonValue.EMPTY_JSON_OBJECT; - if (frameObject.containsKey(Keywords.CONTEXT) - ) { + if (frameObject.containsKey(Keywords.CONTEXT)) { context = frameObject.get(Keywords.CONTEXT); } // 9. final URI contextBase = (frame.getContextUrl() != null) - ? frame.getDocumentUrl() - : options.getBase(); + ? frame.getDocumentUrl() + : options.getBase(); // 10-11. - final ActiveContext activeContext = - new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.from(options)) - .newContext() - .create(context, contextBase); + final ActiveContext activeContext = new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.from(options)) + .newContext() + .create(context, contextBase); final String graphKey = activeContext.uriCompaction().vocab(true).compact(Keywords.GRAPH); // 13. boolean frameDefault = false; for (final String key : frameObject.keySet()) { - if(key.equals(graphKey)) { + if (key.equals(graphKey)) { frameDefault = true; break; } @@ -151,13 +148,13 @@ public static final JsonObject frame(final Document input, final Document frame, // 14. final FramingState state = new FramingState(); - state.setEmbed(options.getEmbed()); // 14.1. - state.setEmbedded(false); // 14.2. - state.setExplicitInclusion(options.isExplicit()); // 14.3. - state.setRequireAll(options.isRequiredAll()); // 14.4. - state.setOmitDefault(options.isOmitDefault()); // 14.5. + state.setEmbed(options.getEmbed()); // 14.1. + state.setEmbedded(false); // 14.2. + state.setExplicitInclusion(options.isExplicit()); // 14.3. + state.setRequireAll(options.isRequiredAll()); // 14.4. + state.setOmitDefault(options.isOmitDefault()); // 14.5. - state.setGraphMap(NodeMapBuilder.with(expandedInput, new NodeMap()).build()); // 14.7. + state.setGraphMap(NodeMapBuilder.with(expandedInput, new NodeMap()).build()); // 14.7. if (frameDefault) { state.setGraphName(Keywords.DEFAULT); // 14.6. @@ -172,11 +169,10 @@ public static final JsonObject frame(final Document input, final Document frame, // 16. Framing.with(state, - new ArrayList<>(state.getGraphMap().subjects(state.getGraphName())), - Frame.of(expandedFrame), - resultMap, - null - ) + new ArrayList<>(state.getGraphMap().subjects(state.getGraphName())), + Frame.of(expandedFrame), + resultMap, + null) .ordered(options.isOrdered()) .frame(); @@ -199,20 +195,20 @@ public static final JsonObject frame(final Document input, final Document frame, // 19. JsonValue compactedResults = Compaction - .with(activeContext) - .compactArrays(options.isCompactArrays()) - .ordered(options.isOrdered()) - .compact(filtered.build()); + .with(activeContext) + .compactArrays(options.isCompactArrays()) + .ordered(options.isOrdered()) + .compact(filtered.build()); // 19.1. if (JsonUtils.isEmptyArray(compactedResults)) { compactedResults = JsonValue.EMPTY_JSON_OBJECT; - // 19.2. + // 19.2. } else if (JsonUtils.isArray(compactedResults)) { compactedResults = JsonProvider.instance().createObjectBuilder() - .add(graphKey, compactedResults).build(); + .add(graphKey, compactedResults).build(); } @@ -234,14 +230,12 @@ public static final JsonObject frame(final Document input, final Document frame, if (compactedResults.asJsonObject().isEmpty()) { compactedResults = JsonProvider.instance().createObjectBuilder().add(graphKey, - JsonValue.EMPTY_JSON_ARRAY - ).build(); + JsonValue.EMPTY_JSON_ARRAY).build(); } else { compactedResults = JsonProvider.instance().createObjectBuilder().add(graphKey, - JsonProvider.instance().createArrayBuilder().add(compactedResults) - ).build(); + JsonProvider.instance().createArrayBuilder().add(compactedResults)).build(); } } @@ -306,7 +300,7 @@ private static final JsonValue removePreserve(JsonValue value) { private static final JsonValue replaceNull(JsonValue value) { - if (JsonUtils.isString(value) && Keywords.NULL.equals(((JsonString)value).getString())) { + if (JsonUtils.isString(value) && Keywords.NULL.equals(((JsonString) value).getString())) { return JsonValue.NULL; } else if (JsonUtils.isScalar(value)) { @@ -351,9 +345,9 @@ private static final JsonValue removeBlankIdKey(JsonValue value, List bl if (Keywords.ID.equals(entry.getKey()) && JsonUtils.isString(entry.getValue()) - && blankNodes.contains(((JsonString)entry.getValue()).getString())) { + && blankNodes.contains(((JsonString) entry.getValue()).getString())) { - continue; + continue; } object.add(entry.getKey(), removeBlankIdKey(entry.getValue(), blankNodes)); @@ -375,9 +369,9 @@ private static final void findBlankNodes(JsonValue value, final Map 0); - blankNodes.put(((JsonString)value).getString(), ++count); + if (BlankNode.isWellFormed(((JsonString) value).getString())) { + Integer count = blankNodes.computeIfAbsent(((JsonString) value).getString(), x -> 0); + blankNodes.put(((JsonString) value).getString(), ++count); } return; diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 20f8c775..3adfc17f 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -4,6 +4,12 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdOptions; +import com.apicatalog.jsonld.JsonLdVersion; +import com.apicatalog.jsonld.context.cache.Cache; +import com.apicatalog.jsonld.document.Document; +import com.apicatalog.jsonld.loader.DocumentLoader; + +import jakarta.json.JsonValue; /** * A runtime context used during a transformation processing. @@ -12,8 +18,13 @@ */ public class ProcessingRuntime { - protected JsonLdOptions options; - protected Duration timout; + protected final JsonLdOptions options; + protected Duration timeout; + + protected ProcessingRuntime(JsonLdOptions options) { + this.options = options; + this.timeout = null; + } /** * Called in multiple places during a processing to check processing timeout if @@ -37,7 +48,7 @@ public void pause() { } public ProcessingRuntime timout(Duration timout) { - this.timout = timout; + this.timeout = timout; return this; } @@ -46,12 +57,34 @@ public JsonLdOptions getOptions() { } public boolean isUriValidation() { - // TODO Auto-generated method stub - return false; + return options.isUriValidation(); + } + + public boolean inMode(final JsonLdVersion version) { + return options.getProcessingMode() != null && options.getProcessingMode().equals(version); } public static ProcessingRuntime from(JsonLdOptions options) { - // TODO Auto-generated method stub - return null; + return new ProcessingRuntime(options); + } + + public DocumentLoader getDocumentLoader() { + return options.getDocumentLoader(); + } + + public Cache getContextCache() { + return options.getContextCache(); + } + + public Cache getDocumentCache() { + return options.getDocumentCache(); + } + + public boolean isRdfStar() { + return options.isRdfStar(); + } + + public boolean isNumericId() { + return options.isNumericId(); } } From 0d1a5a88f216d47f8df8ba6efec5a0714924245b Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:04:34 +0100 Subject: [PATCH 04/13] Hide options --- .../com/apicatalog/jsonld/processor/ProcessingRuntime.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 3adfc17f..a43fc367 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -52,10 +52,6 @@ public ProcessingRuntime timout(Duration timout) { return this; } - public JsonLdOptions getOptions() { - return options; - } - public boolean isUriValidation() { return options.isUriValidation(); } From b204b484c1b94641d0b98af4dbdb26c445a486ef Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:18:04 +0100 Subject: [PATCH 05/13] Runtime integration iprovements --- .../jsonld/compaction/Compaction.java | 3 +- .../jsonld/compaction/UriCompaction.java | 111 ++++++++---------- .../jsonld/context/ActiveContext.java | 12 -- .../jsonld/context/ActiveContextBuilder.java | 9 +- .../jsonld/context/TermDefinitionBuilder.java | 17 ++- .../jsonld/expansion/ArrayExpansion.java | 2 + .../jsonld/expansion/ObjectExpansion1314.java | 7 +- .../jsonld/processor/FramingProcessor.java | 5 +- .../jsonld/processor/ProcessingRuntime.java | 12 +- 9 files changed, 78 insertions(+), 100 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java index 0c2acaab..606a0ce5 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java @@ -25,7 +25,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.context.ActiveContext; import com.apicatalog.jsonld.context.TermDefinition; import com.apicatalog.jsonld.json.JsonMapBuilder; @@ -294,7 +293,7 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t // 12.2.4. final boolean asArray = !compactArrays - || (activeContext.inMode(JsonLdVersion.V1_1) + || (activeContext.runtime().isV11() && activeContext.getTerm(alias).filter(t -> t.hasContainerMapping(Keywords.SET)).isPresent()); // 12.2.5. diff --git a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java index 0ce498f0..c1840b80 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java @@ -24,7 +24,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.context.ActiveContext; import com.apicatalog.jsonld.context.InverseContext; import com.apicatalog.jsonld.context.TermDefinition; @@ -43,7 +42,8 @@ /** * - * @see IRI Compaction + * @see IRI + * Compaction * */ public final class UriCompaction { @@ -149,7 +149,7 @@ public String compact(final String variable) throws JsonLdError { containers.add(Keywords.SET); - // 4.7. + // 4.7. } else if (ListObject.isListObject(value)) { // 4.7.1. @@ -163,8 +163,8 @@ public String compact(final String variable) throws JsonLdError { // 4.7.3. String commonType = null; String commonLanguage = list.isEmpty() - ? defaultLanguage - : null; + ? defaultLanguage + : null; // 4.7.4. for (JsonValue item : list) { @@ -186,22 +186,22 @@ public String compact(final String variable) throws JsonLdError { itemLanguage += "_".concat(item.asJsonObject().getString(Keywords.DIRECTION).toLowerCase()); - // 4.7.4.2.2. + // 4.7.4.2.2. } else if (item.asJsonObject().containsKey(Keywords.LANGUAGE)) { itemLanguage = item.asJsonObject().getString(Keywords.LANGUAGE).toLowerCase(); - // 4.7.4.2.3. + // 4.7.4.2.3. } else if (item.asJsonObject().containsKey(Keywords.TYPE)) { itemType = item.asJsonObject().getString(Keywords.TYPE); - // 4.7.4.2.4. + // 4.7.4.2.4. } else { itemLanguage = Keywords.NULL; } - // 4.7.4.3. + // 4.7.4.3. } else { itemType = Keywords.ID; } @@ -210,10 +210,9 @@ public String compact(final String variable) throws JsonLdError { if (commonLanguage == null) { commonLanguage = itemLanguage; - // 4.7.4.5. + // 4.7.4.5. } else if (!Objects.equals(itemLanguage, commonLanguage) - && JsonUtils.containsKey(item, Keywords.VALUE) - ) { + && JsonUtils.containsKey(item, Keywords.VALUE)) { commonLanguage = Keywords.NONE; } @@ -221,7 +220,7 @@ public String compact(final String variable) throws JsonLdError { if (commonType == null) { commonType = itemType; - // 4.7.4.7. + // 4.7.4.7. } else if (!Objects.equals(itemType, commonType)) { commonType = Keywords.NONE; } @@ -247,12 +246,12 @@ public String compact(final String variable) throws JsonLdError { typeLanguage = Keywords.TYPE; typeLanguageValue = commonType; - // 4.7.8. + // 4.7.8. } else { typeLanguageValue = commonLanguage; } - // 4.8. + // 4.8. } else if (GraphObject.isGraphObject(value)) { // 4.8.1. @@ -292,7 +291,7 @@ public String compact(final String variable) throws JsonLdError { typeLanguage = Keywords.TYPE; typeLanguageValue = Keywords.ID; - // 4.9. + // 4.9. } else { // 4.9.1. @@ -300,8 +299,7 @@ public String compact(final String variable) throws JsonLdError { // 4.9.1.1. if (JsonUtils.contains(Keywords.DIRECTION, value) - && !JsonUtils.contains(Keywords.INDEX, value) - ) { + && !JsonUtils.contains(Keywords.INDEX, value)) { typeLanguageValue = ""; @@ -310,36 +308,35 @@ public String compact(final String variable) throws JsonLdError { JsonValue language = value.asJsonObject().get(Keywords.LANGUAGE); if (JsonUtils.isString(language)) { - typeLanguageValue = ((JsonString)language).getString().toLowerCase(); + typeLanguageValue = ((JsonString) language).getString().toLowerCase(); } } JsonValue direction = value.asJsonObject().get(Keywords.DIRECTION); if (JsonUtils.isString(direction)) { - typeLanguageValue += "_".concat(((JsonString)direction).getString().toLowerCase()); + typeLanguageValue += "_".concat(((JsonString) direction).getString().toLowerCase()); } containers.add(Keywords.LANGUAGE); containers.add(Keywords.LANGUAGE.concat(Keywords.SET)); - // 4.9.1.2. + // 4.9.1.2. } else if (JsonUtils.contains(Keywords.LANGUAGE, value) - && !JsonUtils.contains(Keywords.INDEX, value) - ) { + && !JsonUtils.contains(Keywords.INDEX, value)) { if (JsonUtils.contains(Keywords.LANGUAGE, value)) { JsonValue language = value.asJsonObject().get(Keywords.LANGUAGE); if (JsonUtils.isString(language)) { - typeLanguageValue = ((JsonString)language).getString().toLowerCase(); + typeLanguageValue = ((JsonString) language).getString().toLowerCase(); } } containers.add(Keywords.LANGUAGE); containers.add(Keywords.LANGUAGE.concat(Keywords.SET)); - // 4.9.1.3. + // 4.9.1.3. } else if (JsonUtils.contains(Keywords.TYPE, value)) { typeLanguage = Keywords.TYPE; @@ -347,7 +344,7 @@ public String compact(final String variable) throws JsonLdError { } - // 4.9.2. + // 4.9.2. } else { typeLanguage = Keywords.TYPE; @@ -367,19 +364,17 @@ public String compact(final String variable) throws JsonLdError { containers.add(Keywords.NONE); // 4.11. - if (!activeContext.inMode(JsonLdVersion.V1_0) + if (!activeContext.runtime().isV10() && (JsonUtils.isNotObject(value) - || !value.asJsonObject().containsKey(Keywords.INDEX)) - ) { + || !value.asJsonObject().containsKey(Keywords.INDEX))) { containers.add(Keywords.INDEX); containers.add(Keywords.INDEX.concat(Keywords.SET)); } // 4.12. - if (!activeContext.inMode(JsonLdVersion.V1_0) + if (!activeContext.runtime().isV10() && JsonUtils.containsKey(value, Keywords.VALUE) - && value.asJsonObject().size() == 1 - ) { + && value.asJsonObject().size() == 1) { containers.add(Keywords.LANGUAGE); containers.add(Keywords.LANGUAGE.concat(Keywords.SET)); @@ -400,8 +395,7 @@ public String compact(final String variable) throws JsonLdError { // 4.16. if ((Keywords.REVERSE.equals(typeLanguageValue) || Keywords.ID.equals(typeLanguageValue)) - && JsonUtils.containsKey(value, Keywords.ID) - ) { + && JsonUtils.containsKey(value, Keywords.ID)) { final JsonValue idValue = value.asJsonObject().get(Keywords.ID); @@ -412,7 +406,7 @@ public String compact(final String variable) throws JsonLdError { } else if (JsonUtils.isString(idValue)) { // 4.16.1. - final String idString = ((JsonString)idValue).getString(); + final String idString = ((JsonString) idValue).getString(); final String compactedIdValue = activeContext.uriCompaction().vocab(true).compact(idString); @@ -421,24 +415,23 @@ public String compact(final String variable) throws JsonLdError { if (compactedIdValueTermDefinition .map(TermDefinition::getUriMapping) .filter(idString::equals) - .isPresent() - ) { + .isPresent()) { preferredValues.add(Keywords.VOCAB); preferredValues.add(Keywords.ID); - // 4.16.2. + // 4.16.2. } else { preferredValues.add(Keywords.ID); preferredValues.add(Keywords.VOCAB); } } else { - throw new JsonLdError(JsonLdErrorCode.INVALID_KEYWORD_ID_VALUE, "An @id entry was encountered whose value was not a string but [" + idValue + "]."); + throw new JsonLdError(JsonLdErrorCode.INVALID_KEYWORD_ID_VALUE, "An @id entry was encountered whose value was not a string but [" + idValue + "]."); } preferredValues.add(Keywords.NONE); - // 4.17. + // 4.17. } else { preferredValues.add(typeLanguageValue); @@ -478,7 +471,7 @@ public String compact(final String variable) throws JsonLdError { // 5., 5.1. if ((vocab && activeContext.getVocabularyMapping() != null) && (variable.startsWith(activeContext.getVocabularyMapping()) - && variable.length() > activeContext.getVocabularyMapping().length())) { + && variable.length() > activeContext.getVocabularyMapping().length())) { String suffix = variable.substring(activeContext.getVocabularyMapping().length()); @@ -499,28 +492,24 @@ public String compact(final String variable) throws JsonLdError { if (termDefinition.getUriMapping() == null || variable.equals(termDefinition.getUriMapping()) || !variable.startsWith(termDefinition.getUriMapping()) - || termDefinition.isNotPrefix() - ) { + || termDefinition.isNotPrefix()) { continue; } // 7.2. - String compactUriCandidate = - termEntry.getKey() - .concat(":") - .concat(variable.substring(termDefinition.getUriMapping().length())); + String compactUriCandidate = termEntry.getKey() + .concat(":") + .concat(variable.substring(termDefinition.getUriMapping().length())); // 7.3. if (((compactUri == null || (compactUriCandidate.compareTo(compactUri) < 0)) - && !activeContext.containsTerm(compactUriCandidate)) + && !activeContext.containsTerm(compactUriCandidate)) || (activeContext - .getTerm(compactUriCandidate) - .map(TermDefinition::getUriMapping) - .filter(u -> u.equals(variable)) - .isPresent() - && JsonUtils.isNull(value) - ) - ) { + .getTerm(compactUriCandidate) + .map(TermDefinition::getUriMapping) + .filter(u -> u.equals(variable)) + .isPresent() + && JsonUtils.isNull(value))) { compactUri = compactUriCandidate; } } @@ -538,17 +527,17 @@ public String compact(final String variable) throws JsonLdError { && uri.isAbsolute() && uri.getScheme() != null && uri.getAuthority() == null - && activeContext.getTerm(uri.getScheme()).filter(TermDefinition::isPrefix).isPresent() - ) { - throw new JsonLdError(JsonLdErrorCode.IRI_CONFUSED_WITH_PREFIX); + && activeContext.getTerm(uri.getScheme()).filter(TermDefinition::isPrefix).isPresent()) { + throw new JsonLdError(JsonLdErrorCode.IRI_CONFUSED_WITH_PREFIX); } - } catch (IllegalArgumentException e) { /* variable is not URI */ } + } catch (IllegalArgumentException e) { + /* variable is not URI */ } // 10. if (!vocab && activeContext.getBaseUri() != null && !BlankNode.hasPrefix(variable)) { - final String relativeUri = UriRelativizer.relativize(activeContext.getBaseUri(), variable); + final String relativeUri = UriRelativizer.relativize(activeContext.getBaseUri(), variable); - return Keywords.matchForm(relativeUri) ? "./".concat(relativeUri) : relativeUri; + return Keywords.matchForm(relativeUri) ? "./".concat(relativeUri) : relativeUri; } // 11. diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java index c66e04e6..d17018de 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java @@ -21,8 +21,6 @@ import java.util.Map; import java.util.Optional; -import com.apicatalog.jsonld.JsonLdOptions; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.compaction.UriCompaction; import com.apicatalog.jsonld.compaction.ValueCompaction; import com.apicatalog.jsonld.expansion.UriExpansion; @@ -133,11 +131,6 @@ public String getVocabularyMapping() { return vocabularyMapping; } - @Deprecated(since="1.4.0") - public boolean inMode(final JsonLdVersion version) { - return getOptions().getProcessingMode() != null && getOptions().getProcessingMode().equals(version); - } - public ActiveContext getPreviousContext() { return previousContext; } @@ -190,11 +183,6 @@ public TermSelector termSelector(final String variable, final Collection return TermSelector.with(this, variable, containerMapping, typeLanguage); } - @Deprecated(since="1.4.0") - public JsonLdOptions getOptions() { - return runtime.getOptions(); - } - protected void setDefaultBaseDirection(final DirectionType defaultBaseDirection) { this.defaultBaseDirection = defaultBaseDirection; } diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java index 719a0669..8e38489d 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContextBuilder.java @@ -25,7 +25,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.StringUtils; import com.apicatalog.jsonld.document.Document; import com.apicatalog.jsonld.http.ProfileConstants; @@ -206,7 +205,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr } // 5.5.2. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.PROCESSING_MODE_CONFLICT); } } @@ -215,7 +214,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr if (contextDefinition.containsKey(Keywords.IMPORT)) { // 5.6.1. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_CONTEXT_ENTRY); } @@ -394,7 +393,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr if (contextDefinition.containsKey(Keywords.DIRECTION)) { // 5.10.1. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_CONTEXT_ENTRY); } @@ -428,7 +427,7 @@ public ActiveContext create(final JsonValue localContext, final URI baseUrl) thr // 5.11. if (contextDefinition.containsKey(Keywords.PROPAGATE)) { // 5.11.1. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_CONTEXT_ENTRY); } // 5.11.2. diff --git a/src/main/java/com/apicatalog/jsonld/context/TermDefinitionBuilder.java b/src/main/java/com/apicatalog/jsonld/context/TermDefinitionBuilder.java index 2ddf0d9e..238afa75 100644 --- a/src/main/java/com/apicatalog/jsonld/context/TermDefinitionBuilder.java +++ b/src/main/java/com/apicatalog/jsonld/context/TermDefinitionBuilder.java @@ -26,7 +26,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.StringUtils; import com.apicatalog.jsonld.json.JsonUtils; import com.apicatalog.jsonld.lang.BlankNode; @@ -150,7 +149,7 @@ public void create(final String term) throws JsonLdError { // 4. if (Keywords.TYPE.equals(term)) { - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.KEYWORD_REDEFINITION); } @@ -231,7 +230,7 @@ public void create(final String term) throws JsonLdError { // 11. if (valueObject.containsKey(Keywords.PROTECTED)) { - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_TERM_DEFINITION); } @@ -268,7 +267,7 @@ public void create(final String term) throws JsonLdError { // 12.3. if (((Keywords.JSON.equals(expandedTypeString) || Keywords.NONE.equals(expandedTypeString)) - && activeContext.inMode(JsonLdVersion.V1_0)) + && activeContext.runtime().isV10()) // 12.4. || (Keywords.noneMatch(expandedTypeString, Keywords.ID, Keywords.JSON, Keywords.NONE, Keywords.VOCAB) && UriUtils.isNotAbsoluteUri(expandedTypeString, true))) { @@ -504,7 +503,7 @@ public void create(final String term) throws JsonLdError { if (valueObject.containsKey(Keywords.INDEX)) { // 20.1. - if (activeContext.inMode(JsonLdVersion.V1_0) || !definition.getContainerMapping().contains(Keywords.INDEX)) { + if (activeContext.runtime().isV10() || !definition.getContainerMapping().contains(Keywords.INDEX)) { throw new JsonLdError(JsonLdErrorCode.INVALID_TERM_DEFINITION); } @@ -535,7 +534,7 @@ public void create(final String term) throws JsonLdError { if (valueObject.containsKey(Keywords.CONTEXT)) { // 21.1. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_TERM_DEFINITION); } @@ -610,7 +609,7 @@ public void create(final String term) throws JsonLdError { if (valueObject.containsKey(Keywords.NEST)) { // 24.1 - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_TERM_DEFINITION); } @@ -633,7 +632,7 @@ public void create(final String term) throws JsonLdError { if (valueObject.containsKey(Keywords.PREFIX)) { // 25.1. - if (activeContext.inMode(JsonLdVersion.V1_0) || term.contains(":") || term.contains("/")) { + if (activeContext.runtime().isV10() || term.contains(":") || term.contains("/")) { throw new JsonLdError(JsonLdErrorCode.INVALID_TERM_DEFINITION); } @@ -687,7 +686,7 @@ private final boolean validateContainer(final JsonValue value) { return false; } - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { return JsonUtils.isString(container) && Keywords.noneMatch( diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java index 2bf7025c..a63c5c3e 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java @@ -88,6 +88,8 @@ public JsonArray expand() throws JsonLdError { // 5.2. for (final JsonValue item : element) { + + activeContext.runtime().tick(); // 5.2.1 JsonValue expanded = Expansion diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java index e07e87bf..f6311286 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java @@ -27,7 +27,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.context.ActiveContext; import com.apicatalog.jsonld.context.TermDefinition; import com.apicatalog.jsonld.json.JsonMapBuilder; @@ -377,7 +376,7 @@ else if (Keywords.GRAPH.equals(expandedProperty)) { else if (Keywords.INCLUDED.equals(expandedProperty)) { // 13.4.6.1 - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { continue; } @@ -428,7 +427,7 @@ else if (Keywords.INCLUDED.equals(expandedProperty)) { // 13.4.7.1 if (Keywords.JSON.equals(inputType)) { - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { throw new JsonLdError(JsonLdErrorCode.INVALID_VALUE_OBJECT_VALUE); } @@ -490,7 +489,7 @@ else if (Keywords.INCLUDED.equals(expandedProperty)) { // 13.4.9. if (Keywords.DIRECTION.equals(expandedProperty)) { // 13.4.9.1. - if (activeContext.inMode(JsonLdVersion.V1_0)) { + if (activeContext.runtime().isV10()) { continue; } diff --git a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java index c5e0578c..73f475d4 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java @@ -27,7 +27,6 @@ import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdErrorCode; import com.apicatalog.jsonld.JsonLdOptions; -import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.compaction.Compaction; import com.apicatalog.jsonld.context.ActiveContext; import com.apicatalog.jsonld.document.Document; @@ -179,7 +178,7 @@ public static final JsonObject frame(final Document input, final Document frame, Stream result = resultMap.valuesToArray().stream(); // 17. - remove blank @id - if (!activeContext.inMode(JsonLdVersion.V1_0)) { + if (!activeContext.runtime().isV10()) { final List remove = findBlankNodes(resultMap.valuesToArray()); @@ -219,7 +218,7 @@ public static final JsonObject frame(final Document input, final Document frame, if (options.isOmitGraph() == null) { - omitGraph = activeContext.inMode(JsonLdVersion.V1_1); + omitGraph = activeContext.runtime().isV11(); } else { omitGraph = options.isOmitGraph(); diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index a43fc367..55fc558f 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -35,7 +35,7 @@ protected ProcessingRuntime(JsonLdOptions options) { * * @throws JsonLdError if a processing has exceeded */ - public void ping() throws JsonLdError { + public void tick() throws JsonLdError { } @@ -56,10 +56,14 @@ public boolean isUriValidation() { return options.isUriValidation(); } - public boolean inMode(final JsonLdVersion version) { - return options.getProcessingMode() != null && options.getProcessingMode().equals(version); + public boolean isV10() { + return options.getProcessingMode() != null && options.getProcessingMode().equals(JsonLdVersion.V1_0); } - + + public boolean isV11() { + return options.getProcessingMode() != null && options.getProcessingMode().equals(JsonLdVersion.V1_1); + } + public static ProcessingRuntime from(JsonLdOptions options) { return new ProcessingRuntime(options); } From 97415cc59256dc44d6c9bc955a9a9b7384a407dc Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:33:38 +0100 Subject: [PATCH 06/13] Update ProcessingRuntime ticker API --- .../apicatalog/jsonld/expansion/ObjectExpansion.java | 6 ++++++ .../jsonld/expansion/ObjectExpansion1314.java | 4 ++++ .../jsonld/processor/ProcessingRuntime.java | 11 ++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion.java index 1e217c36..e87de309 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion.java @@ -170,6 +170,8 @@ private void initPreviousContext() throws JsonLdError { for (final String key : Utils.index(element.keySet(), true)) { + activeContext.runtime().tick(); + final String expandedKey = activeContext .uriExpansion() .vocab(true) @@ -203,6 +205,8 @@ private String processTypeScoped(final ActiveContext typeContext) throws JsonLdE // 11. for (final String key : Utils.index(element.keySet(), true)) { + activeContext.runtime().tick(); + final String expandedKey = activeContext .uriExpansion() .vocab(true) @@ -226,6 +230,8 @@ private String processTypeScoped(final ActiveContext typeContext) throws JsonLdE while (terms.hasNext()) { + activeContext.runtime().tick(); + final String term = terms.next(); final Optional localContext = typeContext.getTerm(term).map(TermDefinition::getLocalContext); diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java index f6311286..6343f76e 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ObjectExpansion1314.java @@ -134,6 +134,8 @@ public void expand() throws JsonLdError { continue; } + activeContext.runtime().tick(); + // 13.2. String expandedProperty = activeContext .uriExpansion() @@ -974,6 +976,8 @@ else if (Keywords.INCLUDED.equals(expandedProperty)) { private void recurse() throws JsonLdError { + activeContext.runtime().tick(); + // step 3 final Optional propertyContext = activeContext .getTerm(activeProperty) diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 55fc558f..260d518b 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -40,10 +40,11 @@ public void tick() throws JsonLdError { } /** - * Update remaining time and resets timestamp. Is used top stop counting - * processing time when an external library is called, e.g. a HTTP call. + * Resume ticker, a next ping decreases remaining time if timeout is set. Is + * used after an external method call, to exclude time consumed by + * the external call. e.g. when calling HTTP client. */ - public void pause() { + public void resetTicker() { } @@ -59,11 +60,11 @@ public boolean isUriValidation() { public boolean isV10() { return options.getProcessingMode() != null && options.getProcessingMode().equals(JsonLdVersion.V1_0); } - + public boolean isV11() { return options.getProcessingMode() != null && options.getProcessingMode().equals(JsonLdVersion.V1_1); } - + public static ProcessingRuntime from(JsonLdOptions options) { return new ProcessingRuntime(options); } From e317a4bceb3ea554aed3b2e2f2196049052fc410 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:40:57 +0100 Subject: [PATCH 07/13] Hookup JsonLdOptions.timeout to ProcessingRuntime --- .../com/apicatalog/jsonld/JsonLdOptions.java | 67 ++++++++++++------- .../jsonld/processor/ProcessingRuntime.java | 23 ++++--- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java b/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java index f49d5f78..32cb0a8d 100644 --- a/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java +++ b/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java @@ -16,6 +16,7 @@ package com.apicatalog.jsonld; import java.net.URI; +import java.time.Duration; import com.apicatalog.jsonld.context.cache.Cache; import com.apicatalog.jsonld.context.cache.LruCache; @@ -29,9 +30,11 @@ import jakarta.json.JsonValue; /** - * The {@link JsonLdOptions} type is used to pass various options to the processor. + * The {@link JsonLdOptions} type is used to pass various options to the + * processor. * - * @see The + * @see The * JsonLdOptions Specification. * */ @@ -48,35 +51,35 @@ public enum RdfDirection { public static final boolean DEFAULT_URI_VALIDATION = true; /** - * The base IRI to use when expanding or compacting the document. - * If set, this overrides the input document's IRI. + * The base IRI to use when expanding or compacting the document. If set, this + * overrides the input document's IRI. */ private URI base; /** - * If set to true, the JSON-LD processor replaces arrays with - * just one element with that element during compaction. - * If set to false, all arrays will remain arrays - * even if they have just one element. + * If set to true, the JSON-LD processor replaces arrays with just one element + * with that element during compaction. If set to false, all arrays will remain + * arrays even if they have just one element. */ private boolean compactArrays; /** - * Determines if IRIs are compacted relative to the base option - * or document location when compacting. + * Determines if IRIs are compacted relative to the base option or document + * location when compacting. */ private boolean compactToRelative; /** - * The callback of the loader to be used to retrieve remote documents and contexts, - * implementing the LoadDocumentCallback. If specified, it is used to retrieve - * remote documents and contexts; otherwise, if not specified, - * the processor's built-in loader is used. + * The callback of the loader to be used to retrieve remote documents and + * contexts, implementing the LoadDocumentCallback. If specified, it is used to + * retrieve remote documents and contexts; otherwise, if not specified, the + * processor's built-in loader is used. */ private DocumentLoader documentLoader; /** - * A context that is used to initialize the active context when expanding a document. + * A context that is used to initialize the active context when expanding a + * document. */ private Document expandContext; @@ -215,8 +218,8 @@ public boolean isCompactArrays() { } /** - * Determines if IRIs are compacted relative to the {@link #getBase()} option - * or document location when + * Determines if IRIs are compacted relative to the {@link #getBase()} option or + * document location when * compacting. * * @return true if IRI relativization is enabled @@ -227,9 +230,9 @@ public boolean isCompactToRelative() { /** * The callback of the loader to be used to retrieve remote documents and - * contexts, implementing the {@link DocumentLoader}. If specified, it is - * used to retrieve remote documents and contexts; otherwise, if not specified, - * the processor's built-in loader is used. + * contexts, implementing the {@link DocumentLoader}. If specified, it is used + * to retrieve remote documents and contexts; otherwise, if not specified, the + * processor's built-in loader is used. * * @return the loader or null is is not set */ @@ -446,7 +449,8 @@ public boolean isRdfStar() { } /** - * Experimental: Enables JSON-LD-STAR extension. Only expansion is supported. Disabled by default. + * Experimental: Enables JSON-LD-STAR extension. Only expansion is supported. + * Disabled by default. * * @see JSON-LD-STAR Draft * @@ -457,7 +461,8 @@ public void setRdfStar(boolean rdfStar) { /** * if disabled only URIs required for processing are parsed and validated. - * Disabling URI validation might improve performance depending on the number of processed URIs. + * Disabling URI validation might improve performance depending on the number of + * processed URIs. *

* Warning: Disabled validation could cause an invalid output. *

@@ -473,7 +478,8 @@ public boolean isUriValidation() { /** * if disabled only URIs required for processing are parsed and validated. - * Disabling URI validation might improve performance depending on the number of processed URIs. + * Disabling URI validation might improve performance depending on the number of + * processed URIs. *

* Warning: Disabled validation could cause an invalid output. *

@@ -486,4 +492,19 @@ public boolean isUriValidation() { public void setUriValidation(boolean enabled) { this.uriValidation = enabled; } + + /** + * A processing timeout. An exception is thrown when a processing time exceeds + * the duration, if set. There is no currency that processing gets terminated + * immediately, but eventually. + * + * Please note, the timeout does not include time consumed by + * {@link DocumentLoader}. + * + * @return a duration after which a processing is prematurely terminated. + */ + public Duration getTimeout() { + // TODO Auto-generated method stub + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 260d518b..3aaf7f13 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -1,6 +1,6 @@ package com.apicatalog.jsonld.processor; -import java.time.Duration; +import java.time.Instant; import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdOptions; @@ -19,11 +19,11 @@ public class ProcessingRuntime { protected final JsonLdOptions options; - protected Duration timeout; + protected Instant ticker; protected ProcessingRuntime(JsonLdOptions options) { this.options = options; - this.timeout = null; + this.ticker = options.getTimeout() != null ? Instant.now() : null; } /** @@ -36,21 +36,24 @@ protected ProcessingRuntime(JsonLdOptions options) { * @throws JsonLdError if a processing has exceeded */ public void tick() throws JsonLdError { - + if (ticker == null) { + return; + } + //TODO } /** * Resume ticker, a next ping decreases remaining time if timeout is set. Is * used after an external method call, to exclude time consumed by * the external call. e.g. when calling HTTP client. + * + * Does nothing if timeout is not set. */ public void resetTicker() { - - } - - public ProcessingRuntime timout(Duration timout) { - this.timeout = timout; - return this; + if (ticker == null) { + return; + } + //TODO } public boolean isUriValidation() { From 1ef9f4c1d9fabcf4346849c20f13d5a694d6d02b Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:52:01 +0100 Subject: [PATCH 08/13] Update options of timeout --- README.md | 10 ++++++++++ .../com/apicatalog/jsonld/JsonLdOptions.java | 20 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77d21811..613f3c41 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,16 @@ JsonLd.compact(document, contextDocument).get(); ... ``` +#### Processing Timeout +A processor gets terminated eventually after a specified time. Please note +the duration does not cover `DocumentLoader` calls processing time. +You have to set-up a read timeout separately. + +```javascript +// since 1.4.0 - +JsonLd.expand(...).timeout(duration)...get(); +``` + #### HTTP Document Loader Timeout Configure and set a custom HTTP document loader instance. diff --git a/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java b/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java index 32cb0a8d..c23591c7 100644 --- a/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java +++ b/src/main/java/com/apicatalog/jsonld/JsonLdOptions.java @@ -124,6 +124,8 @@ public enum RdfDirection { private Cache documentCache; private boolean uriValidation; + + private Duration timeout; public JsonLdOptions() { this(SchemeRouter.defaultInstance()); @@ -160,6 +162,7 @@ public JsonLdOptions(DocumentLoader loader) { this.contextCache = new LruCache<>(256); this.documentCache = null; this.uriValidation = DEFAULT_URI_VALIDATION; + this.timeout = null; } public JsonLdOptions(JsonLdOptions options) { @@ -191,6 +194,7 @@ public JsonLdOptions(JsonLdOptions options) { this.contextCache = options.contextCache; this.documentCache = options.documentCache; this.uriValidation = options.uriValidation; + this.timeout = options.timeout; } /** @@ -504,7 +508,19 @@ public void setUriValidation(boolean enabled) { * @return a duration after which a processing is prematurely terminated. */ public Duration getTimeout() { - // TODO Auto-generated method stub - return null; + return timeout; + } + + /** + * Set a pressing timeout. A processing is eventually terminated after the + * specified duration. Set null for no timeout. + * + * Please note, the timeout does not include time consumed by + * {@link DocumentLoader}. + * + * @param timeout to limit processing time + */ + public void setTimeout(Duration timeout) { + this.timeout = timeout; } } \ No newline at end of file From 57c0bbb0e28fd07c252ef94beb1d8e927ca51425 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 00:55:18 +0100 Subject: [PATCH 09/13] Update README --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 613f3c41..7553c32e 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,8 @@ implementation("org.glassfish:jakarta.json:2.0.1") Titanium provides high-level [JsonLd](https://javadoc.io/doc/com.apicatalog/titanium-json-ld/latest/com/apicatalog/jsonld/JsonLd.html) API to interact with the processor. +#### Transformations + ```javascript // Expansion @@ -141,8 +143,9 @@ JsonLd.frame("https://example/document.jsonld", "https://example/frame.jsonld"). ``` +#### Local JSON Document + ```javascript -// Local document Document document = JsonDocument.of(InputStream) or JsonDocument.of(Reader) ... JsonLd.expand(document).get(); @@ -153,7 +156,7 @@ JsonLd.compact(document, contextDocument).get(); #### Processing Timeout A processor gets terminated eventually after a specified time. Please note -the duration does not cover `DocumentLoader` calls processing time. +the duration does not cover `DocumentLoader` processing time. You have to set-up a read timeout separately. ```javascript From 9d46ec63b7f17e8f19cfd6f426cd897df6b508f8 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 01:12:02 +0100 Subject: [PATCH 10/13] Implement ticker --- .../jsonld/processor/ProcessingRuntime.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 3aaf7f13..1202d568 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -1,8 +1,10 @@ package com.apicatalog.jsonld.processor; +import java.time.Duration; import java.time.Instant; import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.JsonLdErrorCode; import com.apicatalog.jsonld.JsonLdOptions; import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.context.cache.Cache; @@ -20,9 +22,11 @@ public class ProcessingRuntime { protected final JsonLdOptions options; protected Instant ticker; + protected Duration ttl; protected ProcessingRuntime(JsonLdOptions options) { this.options = options; + this.ttl = options.getTimeout(); this.ticker = options.getTimeout() != null ? Instant.now() : null; } @@ -39,7 +43,14 @@ public void tick() throws JsonLdError { if (ticker == null) { return; } - //TODO + final Instant now = Instant.now(); + + ttl = ttl.minus(Duration.between(now, ticker).abs()); + + if (ttl.isNegative()) { + throw new JsonLdError(JsonLdErrorCode.PROCESSING_TIMEOUT_EXCEEDED); + } + ticker = now; } /** @@ -53,7 +64,7 @@ public void resetTicker() { if (ticker == null) { return; } - //TODO + ticker = Instant.now(); } public boolean isUriValidation() { From ae7635a54a030b3377ca013135296771e2866941 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 01:22:46 +0100 Subject: [PATCH 11/13] Separate Ticker implementation, use NOP when timeout not set --- .../jsonld/processor/CompactionProcessor.java | 2 +- .../jsonld/processor/ExpansionProcessor.java | 2 +- .../jsonld/processor/FramingProcessor.java | 2 +- .../jsonld/processor/ProcessingRuntime.java | 32 ++++------------ .../apicatalog/jsonld/processor/Ticker.java | 38 +++++++++++++++++++ 5 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/apicatalog/jsonld/processor/Ticker.java diff --git a/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java index 3fec2731..fc669d5d 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java @@ -114,7 +114,7 @@ public static final JsonObject compact(final Document input, final Document cont // 7. final ActiveContext activeContext = new ActiveContext( - ProcessingRuntime.from(options)).newContext().create(contextValue, contextBase); + ProcessingRuntime.of(options)).newContext().create(contextValue, contextBase); // 8. if (activeContext.getBaseUri() == null) { diff --git a/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java index b51bf9c5..55231837 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ExpansionProcessor.java @@ -93,7 +93,7 @@ public static final JsonArray expand(Document input, final JsonLdOptions options baseUri = options.getBase(); } - ActiveContext activeContext = new ActiveContext(baseUri, baseUrl, ProcessingRuntime.from(options)); + ActiveContext activeContext = new ActiveContext(baseUri, baseUrl, ProcessingRuntime.of(options)); // 6. If the expandContext option in options is set, update the active context // using the Context Processing algorithm, passing the expandContext as diff --git a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java index 73f475d4..46a672e9 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java +++ b/src/main/java/com/apicatalog/jsonld/processor/FramingProcessor.java @@ -129,7 +129,7 @@ public static final JsonObject frame(final Document input, final Document frame, : options.getBase(); // 10-11. - final ActiveContext activeContext = new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.from(options)) + final ActiveContext activeContext = new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.of(options)) .newContext() .create(context, contextBase); diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 1202d568..fb1adf30 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -4,7 +4,6 @@ import java.time.Instant; import com.apicatalog.jsonld.JsonLdError; -import com.apicatalog.jsonld.JsonLdErrorCode; import com.apicatalog.jsonld.JsonLdOptions; import com.apicatalog.jsonld.JsonLdVersion; import com.apicatalog.jsonld.context.cache.Cache; @@ -30,6 +29,12 @@ protected ProcessingRuntime(JsonLdOptions options) { this.ticker = options.getTimeout() != null ? Instant.now() : null; } + public static ProcessingRuntime of(JsonLdOptions options) { + return options.getTimeout() != null + ? new Ticker(options) + : new ProcessingRuntime(options); + } + /** * Called in multiple places during a processing to check processing timeout if * set. Does nothing if timeout is not set. @@ -39,19 +44,7 @@ protected ProcessingRuntime(JsonLdOptions options) { * * @throws JsonLdError if a processing has exceeded */ - public void tick() throws JsonLdError { - if (ticker == null) { - return; - } - final Instant now = Instant.now(); - - ttl = ttl.minus(Duration.between(now, ticker).abs()); - - if (ttl.isNegative()) { - throw new JsonLdError(JsonLdErrorCode.PROCESSING_TIMEOUT_EXCEEDED); - } - ticker = now; - } + public void tick() throws JsonLdError {} /** * Resume ticker, a next ping decreases remaining time if timeout is set. Is @@ -60,12 +53,7 @@ public void tick() throws JsonLdError { * * Does nothing if timeout is not set. */ - public void resetTicker() { - if (ticker == null) { - return; - } - ticker = Instant.now(); - } + public void resetTicker() {} public boolean isUriValidation() { return options.isUriValidation(); @@ -79,10 +67,6 @@ public boolean isV11() { return options.getProcessingMode() != null && options.getProcessingMode().equals(JsonLdVersion.V1_1); } - public static ProcessingRuntime from(JsonLdOptions options) { - return new ProcessingRuntime(options); - } - public DocumentLoader getDocumentLoader() { return options.getDocumentLoader(); } diff --git a/src/main/java/com/apicatalog/jsonld/processor/Ticker.java b/src/main/java/com/apicatalog/jsonld/processor/Ticker.java new file mode 100644 index 00000000..34d17c39 --- /dev/null +++ b/src/main/java/com/apicatalog/jsonld/processor/Ticker.java @@ -0,0 +1,38 @@ +package com.apicatalog.jsonld.processor; + +import java.time.Duration; +import java.time.Instant; + +import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.JsonLdErrorCode; +import com.apicatalog.jsonld.JsonLdOptions; + +class Ticker extends ProcessingRuntime { + + Instant ticker; + Duration ttl; + + Ticker(JsonLdOptions options) { + super(options); + this.ttl = options.getTimeout(); + this.ticker = Instant.now(); + } + + @Override + public void tick() throws JsonLdError { + + final Instant now = Instant.now(); + + ttl = ttl.minus(Duration.between(now, ticker).abs()); + + if (ttl.isNegative()) { + throw new JsonLdError(JsonLdErrorCode.PROCESSING_TIMEOUT_EXCEEDED); + } + ticker = now; + } + + @Override + public void resetTicker() { + ticker = Instant.now(); + } +} From 76ac36621e847abea02f90efc2f34427c820db0f Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 01:23:20 +0100 Subject: [PATCH 12/13] Remove forgotten props --- .../com/apicatalog/jsonld/processor/ProcessingRuntime.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index fb1adf30..4cc0de36 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -1,8 +1,5 @@ package com.apicatalog.jsonld.processor; -import java.time.Duration; -import java.time.Instant; - import com.apicatalog.jsonld.JsonLdError; import com.apicatalog.jsonld.JsonLdOptions; import com.apicatalog.jsonld.JsonLdVersion; @@ -20,13 +17,9 @@ public class ProcessingRuntime { protected final JsonLdOptions options; - protected Instant ticker; - protected Duration ttl; protected ProcessingRuntime(JsonLdOptions options) { this.options = options; - this.ttl = options.getTimeout(); - this.ticker = options.getTimeout() != null ? Instant.now() : null; } public static ProcessingRuntime of(JsonLdOptions options) { From d6121888d591dde80d72bcd425cdafaae8726d11 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 6 Dec 2023 01:29:43 +0100 Subject: [PATCH 13/13] Improve methods doc --- .../com/apicatalog/jsonld/processor/ProcessingRuntime.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java index 4cc0de36..451e7dda 100644 --- a/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java +++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java @@ -37,7 +37,7 @@ public static ProcessingRuntime of(JsonLdOptions options) { * * @throws JsonLdError if a processing has exceeded */ - public void tick() throws JsonLdError {} + public void tick() throws JsonLdError {/* NOP does nothing if timeout is not set */} /** * Resume ticker, a next ping decreases remaining time if timeout is set. Is @@ -46,7 +46,7 @@ public void tick() throws JsonLdError {} * * Does nothing if timeout is not set. */ - public void resetTicker() {} + public void resetTicker() {/* NOP does nothing if timeout is not set */} public boolean isUriValidation() { return options.isUriValidation();