documentCache;
private boolean uriValidation;
+
+ private Duration timeout;
public JsonLdOptions() {
this(SchemeRouter.defaultInstance());
@@ -157,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) {
@@ -188,6 +194,7 @@ public JsonLdOptions(JsonLdOptions options) {
this.contextCache = options.contextCache;
this.documentCache = options.documentCache;
this.uriValidation = options.uriValidation;
+ this.timeout = options.timeout;
}
/**
@@ -215,8 +222,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 +234,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 +453,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 +465,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 +482,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 +496,31 @@ 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() {
+ 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
diff --git a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java
index d6c61a29..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;
@@ -169,7 +168,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 +241,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)
@@ -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 31bafbec..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,19 +395,18 @@ 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);
// 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);
} 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 9138ea11..d17018de 100644
--- a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java
+++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java
@@ -21,13 +21,12 @@
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;
import com.apicatalog.jsonld.expansion.ValueExpansion;
import com.apicatalog.jsonld.lang.DirectionType;
+import com.apicatalog.jsonld.processor.ProcessingRuntime;
import jakarta.json.JsonObject;
@@ -61,23 +60,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 +89,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,10 +131,6 @@ public String getVocabularyMapping() {
return vocabularyMapping;
}
- public boolean inMode(final JsonLdVersion version) {
- return options.getProcessingMode() != null && options.getProcessingMode().equals(version);
- }
-
public ActiveContext getPreviousContext() {
return previousContext;
}
@@ -165,7 +160,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,10 +183,6 @@ public TermSelector termSelector(final String variable, final Collection
return TermSelector.with(this, variable, containerMapping, typeLanguage);
}
- public JsonLdOptions getOptions() {
- return options;
- }
-
protected void setDefaultBaseDirection(final DirectionType defaultBaseDirection) {
this.defaultBaseDirection = defaultBaseDirection;
}
@@ -224,4 +215,8 @@ protected void setTerm(final String term, final TermDefinition definition) {
public String toString() {
return "ActiveContext[terms=" + terms + ", previousContext=" + previousContext + "]";
}
+
+ 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 10b3d9fc..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;
@@ -160,8 +159,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.runtime())
+ : new ActiveContext(activeContext.getBaseUrl(), activeContext.getBaseUrl(), result.getPreviousContext(), activeContext.runtime());
// 5.1.3. Continue with the next context
continue;
@@ -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);
}
@@ -230,7 +229,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 +241,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.");
@@ -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.
@@ -494,11 +493,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 +506,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 +526,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 +560,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 +572,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/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/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 5c892796..6343f76e 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;
@@ -135,6 +134,8 @@ public void expand() throws JsonLdError {
continue;
}
+ activeContext.runtime().tick();
+
// 13.2.
String expandedProperty = activeContext
.uriExpansion()
@@ -173,10 +174,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 +190,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)
@@ -377,7 +378,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 +429,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 +491,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;
}
@@ -641,7 +642,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;
}
@@ -975,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/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/CompactionProcessor.java b/src/main/java/com/apicatalog/jsonld/processor/CompactionProcessor.java
index 8c86d65e..fc669d5d 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.of(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..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, 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 6b4cc9fe..46a672e9 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;
@@ -53,7 +52,8 @@
/**
*
- * @see JsonLdProcessor.frame()
+ * @see JsonLdProcessor.frame()
*
*/
public final class FramingProcessor {
@@ -98,10 +98,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 +117,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(), options)
- .newContext()
- .create(context, contextBase);
+ final ActiveContext activeContext = new ActiveContext(input.getDocumentUrl(), input.getDocumentUrl(), ProcessingRuntime.of(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 +147,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,18 +168,17 @@ 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();
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());
@@ -199,20 +194,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();
}
@@ -223,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();
@@ -234,14 +229,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 +299,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 +344,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 +368,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
new file mode 100644
index 00000000..451e7dda
--- /dev/null
+++ b/src/main/java/com/apicatalog/jsonld/processor/ProcessingRuntime.java
@@ -0,0 +1,82 @@
+package com.apicatalog.jsonld.processor;
+
+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.
+ *
+ * @since 1.4.0
+ */
+public class ProcessingRuntime {
+
+ protected final JsonLdOptions options;
+
+ protected ProcessingRuntime(JsonLdOptions options) {
+ this.options = options;
+ }
+
+ 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.
+ *
+ * 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 tick() throws JsonLdError {/* NOP does nothing if timeout is not set */}
+
+ /**
+ * 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() {/* NOP does nothing if timeout is not set */}
+
+ public boolean isUriValidation() {
+ return options.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 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();
+ }
+}
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();
+ }
+}