From a9ff1a0d62b1bb5f57851ab078a12343724e98df Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 10 Oct 2024 22:04:08 +0200 Subject: [PATCH 1/3] Minor code improvements --- pom.xml | 2 +- pom_jre8.xml | 2 +- pom_parent.xml | 2 +- .../jsonld/compaction/Compaction.java | 91 ++++++------- .../jsonld/compaction/UriCompaction.java | 10 +- .../jsonld/compaction/ValueCompaction.java | 124 ++++++++---------- .../jsonld/context/ActiveContext.java | 3 +- .../jsonld/context/InverseContext.java | 61 ++++----- .../jsonld/context/InverseDefinition.java | 54 ++++++++ .../jsonld/context/TermSelector.java | 19 +-- .../jsonld/expansion/ArrayExpansion.java | 30 ++--- .../jsonld/expansion/ScalarExpansion.java | 9 +- .../jsonld/expansion/UriExpansion.java | 2 +- .../apicatalog/jsonld/lang/ListObject.java | 28 ++-- 14 files changed, 237 insertions(+), 200 deletions(-) create mode 100644 src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java diff --git a/pom.xml b/pom.xml index 4f1fcce1..21f31aa9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.apicatalog titanium - 1.4.1 + 1.4.2-SNAPSHOT pom_parent.xml titanium-json-ld diff --git a/pom_jre8.xml b/pom_jre8.xml index d07357ce..8fe1fd70 100644 --- a/pom_jre8.xml +++ b/pom_jre8.xml @@ -6,7 +6,7 @@ com.apicatalog titanium - 1.4.1 + 1.4.2-SNAPSHOT pom_parent.xml titanium-json-ld-jre8 diff --git a/pom_parent.xml b/pom_parent.xml index 15584bc0..16524753 100644 --- a/pom_parent.xml +++ b/pom_parent.xml @@ -6,7 +6,7 @@ 4.0.0 com.apicatalog titanium - 1.4.1 + 1.4.2-SNAPSHOT pom Titanium JSON-LD 1.1 diff --git a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java index 606a0ce5..f482103b 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/Compaction.java @@ -107,8 +107,12 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t // 3. if (JsonUtils.isArray(element)) { + if (element.asJsonArray().isEmpty()) { + return JsonArray.EMPTY_JSON_ARRAY; + } + // 3.1. - final JsonArrayBuilder resultBuilder = JsonProvider.instance().createArrayBuilder(); + final Collection result = new ArrayList<>(element.asJsonArray().size()); // 3.2. for (final JsonValue item : element.asJsonArray()) { @@ -121,15 +125,16 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t .compact(activeProperty, item); // 3.2.2. if (JsonUtils.isNotNull(compactedItem)) { - resultBuilder.add(compactedItem); + result.add(compactedItem); } } - final JsonArray result = resultBuilder.build(); + if (result.isEmpty()) { + return JsonArray.EMPTY_JSON_ARRAY; + } // 3.3. - if (result.isEmpty() - || result.size() > 1 + if (result.size() > 1 || !compactArrays || Keywords.GRAPH.equals(activeProperty) || Keywords.SET.equals(activeProperty) @@ -137,11 +142,11 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t .filter(d -> d.hasContainerMapping(Keywords.LIST) || d.hasContainerMapping(Keywords.SET)) .isPresent()) { - return result; + return JsonProvider.instance().createArrayBuilder(result).build(); } // 3.4. - return result.get(0); + return result.iterator().next(); } // 4. @@ -665,59 +670,57 @@ public JsonValue compact(final String activeProperty, final JsonValue element) t mapKey = expandedItem.asJsonObject().getString(Keywords.LANGUAGE); } - // 12.8.9.5. - } else if (container.contains(Keywords.INDEX) - && Keywords.INDEX.equals(indexKey)) { + } else if (container.contains(Keywords.INDEX)) { - if (expandedItem.asJsonObject().containsKey(Keywords.INDEX)) { + if (Keywords.INDEX.equals(indexKey)) { - mapKey = expandedItem.asJsonObject().getString(Keywords.INDEX); - } + if (expandedItem.asJsonObject().containsKey(Keywords.INDEX)) { + mapKey = expandedItem.asJsonObject().getString(Keywords.INDEX); + } - // 12.8.9.6. - } else if (container.contains(Keywords.INDEX) - && !Keywords.INDEX.equals(indexKey)) { + } else { - // 12.8.9.6.1. - containerKey = activeContext - .uriCompaction() - .vocab(true) - .compact(activeContext.uriExpansion().expand(indexKey)); + // 12.8.9.6.1. + containerKey = activeContext + .uriCompaction() + .vocab(true) + .compact(activeContext.uriExpansion().expand(indexKey)); - // 12.8.9.6.2. - if (JsonUtils.containsKey(compactedItem, containerKey)) { + // 12.8.9.6.2. + if (JsonUtils.containsKey(compactedItem, containerKey)) { - final JsonValue containerValue = compactedItem.asJsonObject().get(containerKey); + final JsonValue containerValue = compactedItem.asJsonObject().get(containerKey); - if (JsonUtils.isString(containerValue)) { - mapKey = ((JsonString) containerValue).getString(); + if (JsonUtils.isString(containerValue)) { + mapKey = ((JsonString) containerValue).getString(); - // 12.8.9.6.3. - compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()).remove(containerKey).build(); + // 12.8.9.6.3. + compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()).remove(containerKey).build(); - } else if (JsonUtils.isArray(containerValue) && !JsonUtils.isEmptyArray(containerValue)) { + } else if (JsonUtils.isArray(containerValue) && !JsonUtils.isEmptyArray(containerValue)) { - mapKey = containerValue.asJsonArray().getString(0); + mapKey = containerValue.asJsonArray().getString(0); - // 12.8.9.6.3. - if (containerValue.asJsonArray().size() > 1) { + // 12.8.9.6.3. + if (containerValue.asJsonArray().size() > 1) { - JsonValue containerKeyValue = null; + JsonValue containerKeyValue = null; - if (containerValue.asJsonArray().size() == 2) { - containerKeyValue = containerValue.asJsonArray().get(1); + if (containerValue.asJsonArray().size() == 2) { + containerKeyValue = containerValue.asJsonArray().get(1); - } else { - containerKeyValue = JsonProvider.instance().createArrayBuilder(containerValue.asJsonArray()).remove(0).build(); - } + } else { + containerKeyValue = JsonProvider.instance().createArrayBuilder(containerValue.asJsonArray()).remove(0).build(); + } - compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()) - .remove(containerKey) - .add(containerKey, containerKeyValue) - .build(); + compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()) + .remove(containerKey) + .add(containerKey, containerKeyValue) + .build(); - } else { - compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()).remove(containerKey).build(); + } else { + compactedItem = JsonProvider.instance().createObjectBuilder(compactedItem.asJsonObject()).remove(containerKey).build(); + } } } } diff --git a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java index c1840b80..8e527d87 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/UriCompaction.java @@ -91,14 +91,12 @@ public String compact(final String variable) throws JsonLdError { return null; } - // 2. - if (activeContext.getInverseContext() == null) { - activeContext.createInverseContext(); - } - - // 3. InverseContext inverseContext = activeContext.getInverseContext(); + if (inverseContext == null) { + inverseContext = activeContext.createInverseContext(); + } + // 4. if (vocab && inverseContext.contains(variable)) { diff --git a/src/main/java/com/apicatalog/jsonld/compaction/ValueCompaction.java b/src/main/java/com/apicatalog/jsonld/compaction/ValueCompaction.java index 91808412..e43f8c7a 100644 --- a/src/main/java/com/apicatalog/jsonld/compaction/ValueCompaction.java +++ b/src/main/java/com/apicatalog/jsonld/compaction/ValueCompaction.java @@ -34,7 +34,8 @@ /** * - * @see Value Compaction + * @see Value + * Compaction * */ public final class ValueCompaction { @@ -73,8 +74,8 @@ public JsonValue compact(final JsonObject value, final String activeProperty) th if (language == null) { language = activeContext.getDefaultLanguage() != null - ? JsonProvider.instance().createValue(activeContext.getDefaultLanguage()) - : null; + ? JsonProvider.instance().createValue(activeContext.getDefaultLanguage()) + : null; } if (direction == null) { @@ -84,58 +85,50 @@ public JsonValue compact(final JsonObject value, final String activeProperty) th // 6. if (value.containsKey(Keywords.ID) && ((value.size() == 1) - || (value.size() == 2 && value.containsKey(Keywords.INDEX))) - ) { + || (value.size() == 2 && value.containsKey(Keywords.INDEX)))) { // 6.1. if (activePropertyDefinition .map(TermDefinition::getTypeMapping) .filter(Keywords.ID::equals) - .isPresent() - ) { + .isPresent()) { result = JsonUtils.toJsonValue(activeContext - .uriCompaction() - .compact(value.getString(Keywords.ID))); + .uriCompaction() + .compact(value.getString(Keywords.ID))); - // 6.2. + // 6.2. } else if (activePropertyDefinition - .map(TermDefinition::getTypeMapping) - .filter(Keywords.VOCAB::equals) - .isPresent() - ) { + .map(TermDefinition::getTypeMapping) + .filter(Keywords.VOCAB::equals) + .isPresent()) { result = JsonUtils.toJsonValue(activeContext - .uriCompaction() - .vocab(true) - .compact(value.getString(Keywords.ID))); + .uriCompaction() + .vocab(true) + .compact(value.getString(Keywords.ID))); } - // 7. + // 7. } else if (value.containsKey(Keywords.TYPE) - && activePropertyDefinition - .map(TermDefinition::getTypeMapping) - .filter(d -> JsonUtils.contains( - d, - value.get(Keywords.TYPE)) - ) - .isPresent() - ) { + && activePropertyDefinition + .map(TermDefinition::getTypeMapping) + .filter(d -> JsonUtils.contains( + d, + value.get(Keywords.TYPE))) + .isPresent()) { result = value.get(Keywords.VALUE); - // 8. + // 8. } else if (activePropertyDefinition - .map(TermDefinition::getTypeMapping) - .filter(Keywords.NONE::equals) - .isPresent() - || (value.containsKey(Keywords.TYPE) - && (activePropertyDefinition - .map(TermDefinition::getTypeMapping) - .map(d -> !JsonUtils.contains(d, value.get(Keywords.TYPE))) - .orElse(true) - ) - ) - ) { + .map(TermDefinition::getTypeMapping) + .filter(Keywords.NONE::equals) + .isPresent() + || (value.containsKey(Keywords.TYPE) + && (activePropertyDefinition + .map(TermDefinition::getTypeMapping) + .map(d -> !JsonUtils.contains(d, value.get(Keywords.TYPE))) + .orElse(true)))) { // 8.1. final JsonArrayBuilder types = JsonProvider.instance().createArrayBuilder(); @@ -145,44 +138,36 @@ public JsonValue compact(final JsonObject value, final String activeProperty) th if (JsonUtils.isNotNull(resultTypes)) { for (final JsonValue type : JsonUtils.toCollection(resultTypes)) { - types.add(activeContext.uriCompaction().vocab(true).compact(((JsonString)type).getString())); + types.add(activeContext.uriCompaction().vocab(true).compact(((JsonString) type).getString())); } result = JsonProvider.instance().createObjectBuilder(result.asJsonObject()).add(Keywords.TYPE, types.build()).build(); } - // 9. + // 9. } else if (JsonUtils.isNotString(value.get(Keywords.VALUE))) { if (!value.containsKey(Keywords.INDEX) - || activePropertyDefinition.filter(td -> td.hasContainerMapping(Keywords.INDEX)).isPresent() - ) { + || activePropertyDefinition.filter(td -> td.hasContainerMapping(Keywords.INDEX)).isPresent()) { result = value.get(Keywords.VALUE); } - // 10. + // 10. } else if ((((value.containsKey(Keywords.LANGUAGE) - && JsonUtils.isString(value.get(Keywords.LANGUAGE)) - && JsonUtils.isString(language) - && (((JsonString)language).getString().equalsIgnoreCase(value.getString(Keywords.LANGUAGE))) - ) - || (JsonUtils.isNull(language) - && (!value.containsKey(Keywords.LANGUAGE) || JsonUtils.isNull(value.get(Keywords.LANGUAGE)))) - ) - && ((direction != null && direction != DirectionType.NULL - && JsonUtils.isString(value.get(Keywords.DIRECTION)) - && direction == DirectionType.valueOf(value.getString(Keywords.DIRECTION).toUpperCase()) - ) - || ((direction == null || direction == DirectionType.NULL) - && (!value.containsKey(Keywords.DIRECTION) - || DirectionType.NULL == DirectionType.valueOf(value.getString(Keywords.DIRECTION).toUpperCase()) - )) - ) - ) - && (!value.containsKey(Keywords.INDEX) || activePropertyDefinition.filter(d -> d.hasContainerMapping(Keywords.INDEX)).isPresent()) - ){ + && JsonUtils.isString(value.get(Keywords.LANGUAGE)) + && JsonUtils.isString(language) + && (((JsonString) language).getString().equalsIgnoreCase(value.getString(Keywords.LANGUAGE)))) + || (JsonUtils.isNull(language) + && (!value.containsKey(Keywords.LANGUAGE) || JsonUtils.isNull(value.get(Keywords.LANGUAGE))))) + && ((direction != null && direction != DirectionType.NULL + && JsonUtils.isString(value.get(Keywords.DIRECTION)) + && direction == DirectionType.valueOf(value.getString(Keywords.DIRECTION).toUpperCase())) + || ((direction == null || direction == DirectionType.NULL) + && (!value.containsKey(Keywords.DIRECTION) + || DirectionType.NULL == DirectionType.valueOf(value.getString(Keywords.DIRECTION).toUpperCase()))))) + && (!value.containsKey(Keywords.INDEX) || activePropertyDefinition.filter(d -> d.hasContainerMapping(Keywords.INDEX)).isPresent())) { - result = value.get(Keywords.VALUE); + result = value.get(Keywords.VALUE); } // 11. @@ -192,15 +177,14 @@ public JsonValue compact(final JsonObject value, final String activeProperty) th for (Entry entry : result.asJsonObject().entrySet()) { resultBuilder.add( - activeContext - .uriCompaction() - .vocab(true) - .compact(entry.getKey()), - entry.getValue() - ); + activeContext + .uriCompaction() + .vocab(true) + .compact(entry.getKey()), + entry.getValue()); } - result = resultBuilder.build(); + return resultBuilder.build(); } // 12. diff --git a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java index d17018de..46e92544 100644 --- a/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/ActiveContext.java @@ -92,8 +92,9 @@ public ActiveContext(final ActiveContext origin) { this.runtime = origin.runtime; } - public void createInverseContext() { + public InverseContext createInverseContext() { this.inverseContext = InverseContextBuilder.with(this).build(); + return this.inverseContext; } public boolean containsTerm(final String term) { diff --git a/src/main/java/com/apicatalog/jsonld/context/InverseContext.java b/src/main/java/com/apicatalog/jsonld/context/InverseContext.java index 6840b396..a4fa515f 100644 --- a/src/main/java/com/apicatalog/jsonld/context/InverseContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/InverseContext.java @@ -17,58 +17,55 @@ import java.util.LinkedHashMap; import java.util.Map; -import java.util.Optional; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; public final class InverseContext { - private final Map>>> context; + final Map definitions; public InverseContext() { - this.context = new LinkedHashMap<>(); + this.definitions = new LinkedHashMap<>(16); } - private void set(final String variable, final String container, final String type, final String key, final String value) { - context.computeIfAbsent(variable, x -> new LinkedHashMap<>()) - .computeIfAbsent(container, x -> new LinkedHashMap<>()) - .computeIfAbsent(type, x -> new LinkedHashMap<>()) - .put(key, value); - } - - private boolean doesNotContain(final String variable, final String container, final String type, final String key) { - return !context.containsKey(variable) - || !context.get(variable).containsKey(container) - || !context.get(variable).get(container).containsKey(type) - || !context.get(variable).get(container).get(type).containsKey(key); + void set(final String variable, final String container, final String type, final String key, final String value) { + definitions.put(new InverseDefinition(variable, container, type, key), value); } public boolean contains(final String variable) { - return context.containsKey(variable); + return definitions.keySet().stream() + .map(InverseDefinition::variable) + .anyMatch(variable::equals); } - public boolean contains(final String variable, final String container, final String type) { - return context.containsKey(variable) - && context.get(variable).containsKey(container) - && context.get(variable).get(container).containsKey(type); + public Map definition(final String variable, final String container, final String type) { + return definitions.keySet().stream() + .filter(def -> Objects.equals(def.variable(), variable) + && Objects.equals(def.container(), container) + && Objects.equals(def.type(), type)) + .collect(Collectors.toUnmodifiableMap( + InverseDefinition::key, + Function.identity())); } - public boolean contains(final String variable, final String container, final String type, final String key) { - return contains(variable) - && context.get(variable).containsKey(container) - && context.get(variable).get(container).containsKey(type) - && context.get(variable).get(container).get(type).containsKey(key); + boolean contains(final String variable, final String container, final String type, final String key) { + return definitions.keySet().stream() + .anyMatch(def -> Objects.equals(def.variable(), variable) + && Objects.equals(def.container(), container) + && Objects.equals(def.type(), type) + && Objects.equals(def.key(), key)); } public InverseContext setIfAbsent(final String variable, final String container, final String type, final String key, final String value) { - if (doesNotContain(variable, container, type, key)) { - set(variable, container, type, key, value); + if (contains(variable, container, type, key)) { + return this; } + set(variable, container, type, key, value); return this; } - public Optional get(final String variable, final String container, final String type, final String key) { - if (doesNotContain(variable, container, type, key)) { - return Optional.empty(); - } - return Optional.ofNullable(context.get(variable).get(container).get(type).get(key)); + public String get(final InverseDefinition def) { + return definitions.get(def); } } \ No newline at end of file diff --git a/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java b/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java new file mode 100644 index 00000000..37b8f6f9 --- /dev/null +++ b/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java @@ -0,0 +1,54 @@ +package com.apicatalog.jsonld.context; + +import java.util.Objects; + +class InverseDefinition { + + final String variable; + final String container; + final String type; + final String key; + + public InverseDefinition(final String variable, final String container, final String type, final String key) { + this.variable = variable; + this.container = container; + this.type = type; + this.key = key; + } + + public String variable() { + return variable; + } + + public String container() { + return container; + } + + public String type() { + return type; + } + + public String key() { + return key; + } + + @Override + public int hashCode() { + return Objects.hash(container, key, type, variable); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + InverseDefinition other = (InverseDefinition) obj; + return Objects.equals(container, other.container) + && Objects.equals(key, other.key) + && Objects.equals(type, other.type) + && Objects.equals(variable, other.variable); + } +} diff --git a/src/main/java/com/apicatalog/jsonld/context/TermSelector.java b/src/main/java/com/apicatalog/jsonld/context/TermSelector.java index 7c4f10d8..74ef6df3 100644 --- a/src/main/java/com/apicatalog/jsonld/context/TermSelector.java +++ b/src/main/java/com/apicatalog/jsonld/context/TermSelector.java @@ -16,8 +16,10 @@ package com.apicatalog.jsonld.context; import java.util.Collection; +import java.util.Map; +import java.util.Objects; import java.util.Optional; -import java.util.stream.Stream; +import java.util.function.Predicate; /** * @@ -60,14 +62,13 @@ public Optional match(final Collection preferredValues) { // context. final InverseContext inverseContext = activeContext.getInverseContext(); - // 4. - return containers - .stream() - .filter(container -> inverseContext.contains(variable, container, typeLanguage)) - .flatMap(container -> preferredValues - .stream() - .map(item -> inverseContext.get(variable, container, typeLanguage, item))) - .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) + return containers.stream() + .map(container -> inverseContext.definition(variable, container, typeLanguage)) + .filter(Predicate.not(Map::isEmpty)) + .flatMap(defs -> preferredValues.stream() + .map(defs::get) + .filter(Objects::nonNull) + .map(inverseContext::get)) .findFirst(); } } \ No newline at end of file diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java index a63c5c3e..6c12604d 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ArrayExpansion.java @@ -88,34 +88,32 @@ public JsonArray expand() throws JsonLdError { // 5.2. for (final JsonValue item : element) { - + activeContext.runtime().tick(); // 5.2.1 - JsonValue expanded = Expansion + final JsonValue expanded = Expansion .with(activeContext, item, activeProperty, baseUrl) .frameExpansion(frameExpansion) .ordered(ordered) .fromMap(fromMap) .compute(); - // 5.2.2 - if (JsonUtils.isArray(expanded) - && activeContext.getTerm(activeProperty) - .map(TermDefinition::getContainerMapping) - .filter(c -> c.contains(Keywords.LIST)).isPresent()) { + if (JsonUtils.isArray(expanded)) { - expanded = ListObject.toListObject(expanded); - } + if (activeContext.getTerm(activeProperty) + .map(TermDefinition::getContainerMapping) + .filter(c -> c.contains(Keywords.LIST)).isPresent()) { - // 5.2.3 - if (JsonUtils.isArray(expanded)) { - expanded.asJsonArray() - .stream() - .filter(JsonUtils::isNotNull) - .forEach(result::add); + result.add(ListObject.toListObject(expanded.asJsonArray())); + + } else { + expanded.asJsonArray() + .stream() + .filter(JsonUtils::isNotNull) + .forEach(result::add); + } - // append non-null element } else if (JsonUtils.isNotNull(expanded)) { result.add(expanded); } diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ScalarExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ScalarExpansion.java index 3d7b29f0..ab244189 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ScalarExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ScalarExpansion.java @@ -69,11 +69,10 @@ public JsonValue expand() throws JsonLdError { */ if (propertyContext != null) { activeContext = activeContext - .newContext() - .create( - propertyContext, - activeContext.getTerm(activeProperty).map(TermDefinition::getBaseUrl).orElse(null) - ); + .newContext() + .create( + propertyContext, + activeContext.getTerm(activeProperty).map(TermDefinition::getBaseUrl).orElse(null)); } /* diff --git a/src/main/java/com/apicatalog/jsonld/expansion/UriExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/UriExpansion.java index 3a6397bf..22796436 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/UriExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/UriExpansion.java @@ -126,7 +126,7 @@ public String expand(final String value) throws JsonLdError { final int splitIndex = result.indexOf(':', 1); if (splitIndex != -1) { - // 6.1. Split value into a prefix and suffix + // 6.1. Split value into a prefix and suffix // at the first occurrence of a colon (:). // 6.2. If prefix is underscore (_) or suffix begins with double-forward-slash // (//), return value as it is already an IRI or a blank node identifier. diff --git a/src/main/java/com/apicatalog/jsonld/lang/ListObject.java b/src/main/java/com/apicatalog/jsonld/lang/ListObject.java index 2ec2afb8..30694ff4 100644 --- a/src/main/java/com/apicatalog/jsonld/lang/ListObject.java +++ b/src/main/java/com/apicatalog/jsonld/lang/ListObject.java @@ -18,6 +18,7 @@ import com.apicatalog.jsonld.json.JsonProvider; import com.apicatalog.jsonld.json.JsonUtils; +import jakarta.json.JsonArray; import jakarta.json.JsonObject; import jakarta.json.JsonValue; @@ -27,9 +28,9 @@ private ListObject() { } /** - * A list object is a map that has a @list key. It may also have - * an @index key, but no other entries. See the Lists and Sets section of - * JSON-LD 1.1 for a normative description. + * A list object is a map that has a @list key. It may also have an @index key, + * but no other entries. See the Lists and Sets section of JSON-LD 1.1 for a + * normative description. * * @see List * Object @@ -39,27 +40,28 @@ private ListObject() { */ public static final boolean isListObject(JsonValue value) { return JsonUtils.containsKey(value, Keywords.LIST) - && (value.asJsonObject().size() == 1 - || (value.asJsonObject().size() == 2 - && value.asJsonObject().containsKey(Keywords.INDEX) - ) - ); + && (value.asJsonObject().size() == 1 + || (value.asJsonObject().size() == 2 + && value.asJsonObject().containsKey(Keywords.INDEX))); } /** * Convert expanded value to a list object by first setting it to an array * containing only expanded value if it is not already an array, and then by - * setting it to a map containing the key-value pair @list-expanded value. + * setting it to a map containing the key-value pair @list expanded value. * * @param value to convert * @return list object containing the provided value */ - public static final JsonObject toListObject(JsonValue value) { + public static final JsonObject toListObject(final JsonValue value) { if (JsonUtils.isArray(value)) { - return JsonProvider.instance().createObjectBuilder().add(Keywords.LIST, value).build(); + return toListObject(value.asJsonArray()); } - return JsonProvider.instance().createObjectBuilder().add(Keywords.LIST, JsonProvider.instance().createArrayBuilder().add(value)).build(); - + return toListObject(JsonProvider.instance().createArrayBuilder().add(value).build()); + } + + public static final JsonObject toListObject(final JsonArray value) { + return JsonProvider.instance().createObjectBuilder().add(Keywords.LIST, value).build(); } } From 2c42cea63f38817fb7f7a3642d3e2311b1287ef9 Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 10 Oct 2024 22:30:04 +0200 Subject: [PATCH 2/3] Minor code improvements --- .../jsonld/context/InverseContext.java | 14 ++-- .../jsonld/context/InverseDefinition.java | 13 ++++ .../jsonld/context/TermSelector.java | 4 +- .../jsonld/expansion/ValueExpansion.java | 68 ++++++++++--------- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/apicatalog/jsonld/context/InverseContext.java b/src/main/java/com/apicatalog/jsonld/context/InverseContext.java index a4fa515f..600c5ddb 100644 --- a/src/main/java/com/apicatalog/jsonld/context/InverseContext.java +++ b/src/main/java/com/apicatalog/jsonld/context/InverseContext.java @@ -17,7 +17,6 @@ import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @@ -39,11 +38,9 @@ public boolean contains(final String variable) { .anyMatch(variable::equals); } - public Map definition(final String variable, final String container, final String type) { + public Map definitions(final String variable, final String container, final String type) { return definitions.keySet().stream() - .filter(def -> Objects.equals(def.variable(), variable) - && Objects.equals(def.container(), container) - && Objects.equals(def.type(), type)) + .filter(def -> def.match(variable, container, type)) .collect(Collectors.toUnmodifiableMap( InverseDefinition::key, Function.identity())); @@ -51,10 +48,7 @@ public Map definition(final String variable, final St boolean contains(final String variable, final String container, final String type, final String key) { return definitions.keySet().stream() - .anyMatch(def -> Objects.equals(def.variable(), variable) - && Objects.equals(def.container(), container) - && Objects.equals(def.type(), type) - && Objects.equals(def.key(), key)); + .anyMatch(def -> def.match(variable, container, type, key)); } public InverseContext setIfAbsent(final String variable, final String container, final String type, final String key, final String value) { @@ -65,7 +59,7 @@ public InverseContext setIfAbsent(final String variable, final String container, return this; } - public String get(final InverseDefinition def) { + public String value(final InverseDefinition def) { return definitions.get(def); } } \ No newline at end of file diff --git a/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java b/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java index 37b8f6f9..a1123c93 100644 --- a/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java +++ b/src/main/java/com/apicatalog/jsonld/context/InverseDefinition.java @@ -16,6 +16,19 @@ public InverseDefinition(final String variable, final String container, final St this.key = key; } + public boolean match(final String variable, final String container, final String type) { + return Objects.equals(this.variable, variable) + && Objects.equals(this.container, container) + && Objects.equals(this.type, type); + } + + public boolean match(final String variable, final String container, final String type, final String key) { + return Objects.equals(this.variable, variable) + && Objects.equals(this.container, container) + && Objects.equals(this.type, type) + && Objects.equals(this.key, key); + } + public String variable() { return variable; } diff --git a/src/main/java/com/apicatalog/jsonld/context/TermSelector.java b/src/main/java/com/apicatalog/jsonld/context/TermSelector.java index 74ef6df3..9485bc8f 100644 --- a/src/main/java/com/apicatalog/jsonld/context/TermSelector.java +++ b/src/main/java/com/apicatalog/jsonld/context/TermSelector.java @@ -63,12 +63,12 @@ public Optional match(final Collection preferredValues) { final InverseContext inverseContext = activeContext.getInverseContext(); return containers.stream() - .map(container -> inverseContext.definition(variable, container, typeLanguage)) + .map(container -> inverseContext.definitions(variable, container, typeLanguage)) .filter(Predicate.not(Map::isEmpty)) .flatMap(defs -> preferredValues.stream() .map(defs::get) .filter(Objects::nonNull) - .map(inverseContext::get)) + .map(inverseContext::value)) .findFirst(); } } \ No newline at end of file diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java index fa050756..e2b86d51 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java @@ -57,48 +57,51 @@ public JsonObject expand(final JsonValue value, final String activeProperty) thr definition = activeContext.getTerm(activeProperty); - final Optional typeMapping = definition.map(TermDefinition::getTypeMapping); + final String typeMapping = definition.map(TermDefinition::getTypeMapping).orElse(null); - if (typeMapping.isPresent()) { - // 1. - if (Keywords.ID.equals(typeMapping.get())) { + // 1. + if (Keywords.ID.equals(typeMapping)) { - String idValue = null; + String idValue = null; - if (JsonUtils.isString(value)) { - idValue = ((JsonString) value).getString(); + if (JsonUtils.isString(value)) { + idValue = ((JsonString) value).getString(); - // custom extension allowing to process numeric ids - } else if (activeContext.runtime().isNumericId() && JsonUtils.isNumber(value)) { - idValue = ((JsonNumber) value).toString(); - } - - if (idValue != null) { - final String expandedValue = activeContext.uriExpansion().documentRelative(true) - .vocab(false).expand(idValue); - - return JsonProvider.instance().createObjectBuilder().add(Keywords.ID, expandedValue).build(); - } - - // 2. - } else if (Keywords.VOCAB.equals(typeMapping.get()) && JsonUtils.isString(value)) { - - String expandedValue = activeContext.uriExpansion().documentRelative(true) - .vocab(true).expand(((JsonString) value).getString()); + // custom extension allowing to process numeric ids + } else if (activeContext.runtime().isNumericId() && JsonUtils.isNumber(value)) { + idValue = ((JsonNumber) value).toString(); + } - return JsonProvider.instance().createObjectBuilder().add(Keywords.ID, expandedValue).build(); + if (idValue != null) { + return JsonProvider.instance().createObjectBuilder() + .add(Keywords.ID, + activeContext.uriExpansion() + .documentRelative(true) + .vocab(false) + .expand(idValue)) + .build(); } + + // 2. + } else if (Keywords.VOCAB.equals(typeMapping) && JsonUtils.isString(value)) { + return JsonProvider.instance().createObjectBuilder() + .add(Keywords.ID, + activeContext.uriExpansion() + .documentRelative(true) + .vocab(true) + .expand(((JsonString) value).getString())) + .build(); } // 3. final JsonObjectBuilder result = JsonProvider.instance().createObjectBuilder().add(Keywords.VALUE, value); // 4. - if (typeMapping - .filter(t -> !Keywords.ID.equals(t) && !Keywords.VOCAB.equals(t) && !Keywords.NONE.equals(t)) - .isPresent()) { - - result.add(Keywords.TYPE, typeMapping.get()); + if (typeMapping != null + && !Keywords.ID.equals(typeMapping) + && !Keywords.VOCAB.equals(typeMapping) + && !Keywords.NONE.equals(typeMapping)) { + result.add(Keywords.TYPE, typeMapping); // 5. } else if (JsonUtils.isString(value)) { @@ -115,9 +118,8 @@ private void buildStringValue(final JsonObjectBuilder result) { final JsonValue language = definition .map(TermDefinition::getLanguageMapping) .orElseGet(() -> activeContext.getDefaultLanguage() != null - ? JsonProvider.instance().createValue(activeContext.getDefaultLanguage()) - : null - ); + ? JsonProvider.instance().createValue(activeContext.getDefaultLanguage()) + : null); // 5.2. final DirectionType direction = definition From bbed23e20ae61bf4213bcc26cceb6315a84fd39f Mon Sep 17 00:00:00 2001 From: Filip Date: Mon, 28 Oct 2024 23:18:27 +0100 Subject: [PATCH 3/3] Minor code improvements --- .../java/com/apicatalog/jsonld/expansion/ValueExpansion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java index e2b86d51..969c1184 100644 --- a/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java +++ b/src/main/java/com/apicatalog/jsonld/expansion/ValueExpansion.java @@ -94,7 +94,8 @@ public JsonObject expand(final JsonValue value, final String activeProperty) thr } // 3. - final JsonObjectBuilder result = JsonProvider.instance().createObjectBuilder().add(Keywords.VALUE, value); + final JsonObjectBuilder result = JsonProvider.instance().createObjectBuilder() + .add(Keywords.VALUE, value); // 4. if (typeMapping != null