15
15
import static org .eclipse .ditto .base .model .common .ConditionChecker .checkNotNull ;
16
16
17
17
import java .util .List ;
18
+ import java .util .Optional ;
18
19
import java .util .concurrent .CompletableFuture ;
19
20
import java .util .concurrent .CompletionStage ;
20
21
import java .util .concurrent .Executor ;
21
22
import java .util .function .BiFunction ;
23
+ import java .util .stream .Stream ;
22
24
23
25
import org .eclipse .ditto .base .model .headers .DittoHeaders ;
24
26
import org .eclipse .ditto .json .JsonCollectors ;
28
30
import org .eclipse .ditto .json .JsonPointer ;
29
31
import org .eclipse .ditto .json .JsonValue ;
30
32
import org .eclipse .ditto .wot .api .provider .WotThingModelFetcher ;
33
+ import org .eclipse .ditto .wot .model .BaseLink ;
31
34
import org .eclipse .ditto .wot .model .IRI ;
35
+ import org .eclipse .ditto .wot .model .Links ;
32
36
import org .eclipse .ditto .wot .model .ThingModel ;
33
37
import org .eclipse .ditto .wot .model .WotThingModelRefInvalidException ;
34
38
@@ -73,7 +77,7 @@ public CompletionStage<ThingModel> resolveThingModelExtensions(final ThingModel
73
77
return CompletableFuture .completedFuture (thingModel );
74
78
} else {
75
79
CompletionStage <ThingModel .Builder > currentStage =
76
- resolveThingModelExtensions (extendedModels .get ( 0 ), dittoHeaders ) // recurse!
80
+ resolveThingModelExtensions (extendedModels .getFirst ( ), dittoHeaders ) // recurse!
77
81
.thenApply (extendedModel ->
78
82
mergeThingModelIntoBuilder ().apply (tmBuilder , extendedModel )
79
83
);
@@ -91,13 +95,52 @@ public CompletionStage<ThingModel> resolveThingModelExtensions(final ThingModel
91
95
92
96
private BiFunction <ThingModel .Builder , ThingModel , ThingModel .Builder > mergeThingModelIntoBuilder () {
93
97
return (builder , model ) -> {
94
- final JsonObject mergedTmObject = JsonFactory .mergeJsonValues (builder .build (), model ).asObject ();
98
+ final ThingModel newModel = builder .build ();
99
+ final JsonObject mergedTmObject = JsonFactory .mergeJsonValues (newModel , model ).asObject ();
95
100
builder .removeAll ();
96
101
builder .setAll (mergedTmObject );
102
+ mergeLinks (model .getLinks (), newModel .getLinks ()).ifPresent (builder ::setLinks );
97
103
return builder ;
98
104
};
99
105
}
100
106
107
+ @ SuppressWarnings ("OptionalUsedAsFieldOrParameterType" )
108
+ private static Optional <Links > mergeLinks (final Optional <Links > oldOptionalLinks ,
109
+ final Optional <Links > newOptionalLinks )
110
+ {
111
+ return oldOptionalLinks
112
+ .map (oldLinks -> filterOutTmExtendsLinkFromOldLinks (newOptionalLinks , oldLinks ))
113
+ .map (adjustedOldLinks ->
114
+ newOptionalLinks .stream ()
115
+ .flatMap (newLinks -> Stream .concat (adjustedOldLinks , newLinks .stream ()))
116
+ )
117
+ .map (Stream ::toList )
118
+ .map (Links ::of );
119
+ }
120
+
121
+ @ SuppressWarnings ("OptionalUsedAsFieldOrParameterType" )
122
+ private static Stream <BaseLink <?>> filterOutTmExtendsLinkFromOldLinks (final Optional <Links > newOptionalLinks ,
123
+ final Links oldLinks )
124
+ {
125
+ return oldLinks .stream ()
126
+ .filter (oldLink -> {
127
+ if (isTmExtendsLink (oldLink )) {
128
+ return newOptionalLinks .filter (DefaultWotThingModelExtensionResolver ::containsTmExtendsLink )
129
+ .isEmpty ();
130
+ } else {
131
+ return true ;
132
+ }
133
+ });
134
+ }
135
+
136
+ private static boolean containsTmExtendsLink (final Links links ) {
137
+ return links .stream ().anyMatch (DefaultWotThingModelExtensionResolver ::isTmExtendsLink );
138
+ }
139
+
140
+ private static boolean isTmExtendsLink (final BaseLink <?> link ) {
141
+ return link .getRel ().isPresent () && link .getRel ().filter (TM_EXTENDS ::equals ).isPresent ();
142
+ }
143
+
101
144
@ Override
102
145
public CompletionStage <ThingModel > resolveThingModelRefs (final ThingModel thingModel , final DittoHeaders dittoHeaders ) {
103
146
return potentiallyResolveRefs (thingModel , dittoHeaders ).thenApply (ThingModel ::fromJson );
0 commit comments