diff --git a/bom/pom.xml b/bom/pom.xml
index c067ea1824..7cc070afdd 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -34,7 +34,7 @@
0.9.5
2.17.2
- 1.5.1
+ 1.5.4
1.4.3
0.6.1
3.7.1
diff --git a/wot/api/src/main/java/org/eclipse/ditto/wot/api/generator/DefaultWotThingModelExtensionResolver.java b/wot/api/src/main/java/org/eclipse/ditto/wot/api/generator/DefaultWotThingModelExtensionResolver.java
index 231c453e3c..58531a6c54 100644
--- a/wot/api/src/main/java/org/eclipse/ditto/wot/api/generator/DefaultWotThingModelExtensionResolver.java
+++ b/wot/api/src/main/java/org/eclipse/ditto/wot/api/generator/DefaultWotThingModelExtensionResolver.java
@@ -15,10 +15,12 @@
import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
+import java.util.stream.Stream;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.json.JsonCollectors;
@@ -28,7 +30,9 @@
import org.eclipse.ditto.json.JsonPointer;
import org.eclipse.ditto.json.JsonValue;
import org.eclipse.ditto.wot.api.provider.WotThingModelFetcher;
+import org.eclipse.ditto.wot.model.BaseLink;
import org.eclipse.ditto.wot.model.IRI;
+import org.eclipse.ditto.wot.model.Links;
import org.eclipse.ditto.wot.model.ThingModel;
import org.eclipse.ditto.wot.model.WotThingModelRefInvalidException;
@@ -73,7 +77,7 @@ public CompletionStage resolveThingModelExtensions(final ThingModel
return CompletableFuture.completedFuture(thingModel);
} else {
CompletionStage currentStage =
- resolveThingModelExtensions(extendedModels.get(0), dittoHeaders) // recurse!
+ resolveThingModelExtensions(extendedModels.getFirst(), dittoHeaders) // recurse!
.thenApply(extendedModel ->
mergeThingModelIntoBuilder().apply(tmBuilder, extendedModel)
);
@@ -91,13 +95,52 @@ public CompletionStage resolveThingModelExtensions(final ThingModel
private BiFunction mergeThingModelIntoBuilder() {
return (builder, model) -> {
- final JsonObject mergedTmObject = JsonFactory.mergeJsonValues(builder.build(), model).asObject();
+ final ThingModel newModel = builder.build();
+ final JsonObject mergedTmObject = JsonFactory.mergeJsonValues(newModel, model).asObject();
builder.removeAll();
builder.setAll(mergedTmObject);
+ mergeLinks(model.getLinks(), newModel.getLinks()).ifPresent(builder::setLinks);
return builder;
};
}
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ private static Optional mergeLinks(final Optional oldOptionalLinks,
+ final Optional newOptionalLinks)
+ {
+ return oldOptionalLinks
+ .map(oldLinks -> filterOutTmExtendsLinkFromOldLinks(newOptionalLinks, oldLinks))
+ .map(adjustedOldLinks ->
+ newOptionalLinks.stream()
+ .flatMap(newLinks -> Stream.concat(adjustedOldLinks, newLinks.stream()))
+ )
+ .map(Stream::toList)
+ .map(Links::of);
+ }
+
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ private static Stream> filterOutTmExtendsLinkFromOldLinks(final Optional newOptionalLinks,
+ final Links oldLinks)
+ {
+ return oldLinks.stream()
+ .filter(oldLink -> {
+ if (isTmExtendsLink(oldLink)) {
+ return newOptionalLinks.filter(DefaultWotThingModelExtensionResolver::containsTmExtendsLink)
+ .isEmpty();
+ } else {
+ return true;
+ }
+ });
+ }
+
+ private static boolean containsTmExtendsLink(final Links links) {
+ return links.stream().anyMatch(DefaultWotThingModelExtensionResolver::isTmExtendsLink);
+ }
+
+ private static boolean isTmExtendsLink(final BaseLink> link) {
+ return link.getRel().isPresent() && link.getRel().filter(TM_EXTENDS::equals).isPresent();
+ }
+
@Override
public CompletionStage resolveThingModelRefs(final ThingModel thingModel, final DittoHeaders dittoHeaders) {
return potentiallyResolveRefs(thingModel, dittoHeaders).thenApply(ThingModel::fromJson);