@@ -84,7 +84,6 @@ public class YamlThingProvider extends AbstractProvider<Thing>
84
84
85
85
private final Logger logger = LoggerFactory .getLogger (YamlThingProvider .class );
86
86
87
- private final YamlModelRepository modelRepository ;
88
87
private final BundleResolver bundleResolver ;
89
88
private final ThingTypeRegistry thingTypeRegistry ;
90
89
private final ChannelTypeRegistry channelTypeRegistry ;
@@ -93,6 +92,7 @@ public class YamlThingProvider extends AbstractProvider<Thing>
93
92
94
93
private final List <ThingHandlerFactory > thingHandlerFactories = new CopyOnWriteArrayList <>();
95
94
private final Set <String > loadedXmlThingTypes = new CopyOnWriteArraySet <>();
95
+ private final List <ThingHandlerFactory > thingHandlerFactoriesToProcess = new CopyOnWriteArrayList <>();
96
96
97
97
private final Map <String , Collection <Thing >> thingsMap = new ConcurrentHashMap <>();
98
98
@@ -148,17 +148,18 @@ public void run() {
148
148
149
149
private @ Nullable Thread lazyRetryThread ;
150
150
151
+ private @ Nullable YamlModelRepository modelRepository ;
152
+
151
153
private record QueueContent (ThingHandlerFactory thingHandlerFactory , ThingTypeUID thingTypeUID ,
152
154
Configuration configuration , ThingUID thingUID , @ Nullable ThingUID bridgeUID ) {
153
155
}
154
156
155
157
@ Activate
156
- public YamlThingProvider (final @ Reference YamlModelRepository modelRepository ,
157
- final @ Reference BundleResolver bundleResolver , final @ Reference ThingTypeRegistry thingTypeRegistry ,
158
+ public YamlThingProvider (final @ Reference BundleResolver bundleResolver ,
159
+ final @ Reference ThingTypeRegistry thingTypeRegistry ,
158
160
final @ Reference ChannelTypeRegistry channelTypeRegistry ,
159
161
final @ Reference ConfigDescriptionRegistry configDescriptionRegistry ,
160
162
final @ Reference LocaleProvider localeProvider ) {
161
- this .modelRepository = modelRepository ;
162
163
this .bundleResolver = bundleResolver ;
163
164
this .thingTypeRegistry = thingTypeRegistry ;
164
165
this .channelTypeRegistry = channelTypeRegistry ;
@@ -240,14 +241,29 @@ public void removedModel(String modelName, Collection<YamlThingDTO> elements) {
240
241
}
241
242
}
242
243
244
+ @ Override
245
+ public void refreshedModel (String modelName , Collection <YamlThingDTO > elements ) {
246
+ List <YamlThingDTO > elementsNeedingRefresh = elements .stream ().filter (this ::refreshNeeded ).toList ();
247
+ if (!elementsNeedingRefresh .isEmpty ()) {
248
+ logger .info ("Refreshing {} {} from YAML model {}" , elementsNeedingRefresh .size (),
249
+ getElementClass ().getAnnotation (YamlElementName .class ).value (), modelName );
250
+ updatedModel (modelName , elementsNeedingRefresh );
251
+ } else {
252
+ logger .debug ("No refresh needed from YAML model {}" , modelName );
253
+ }
254
+ }
255
+
243
256
@ Reference (cardinality = ReferenceCardinality .MULTIPLE , policy = ReferencePolicy .DYNAMIC )
244
257
protected void addThingHandlerFactory (final ThingHandlerFactory thingHandlerFactory ) {
258
+ logger .debug ("addThingHandlerFactory {}" , thingHandlerFactory .getClass ().getSimpleName ());
245
259
thingHandlerFactories .add (thingHandlerFactory );
246
- thingHandlerFactoryAdded (thingHandlerFactory );
260
+ thingHandlerFactoriesToProcess .add (thingHandlerFactory );
261
+ processAddedthingHandlerFactory (thingHandlerFactory );
247
262
}
248
263
249
264
protected void removeThingHandlerFactory (final ThingHandlerFactory thingHandlerFactory ) {
250
265
thingHandlerFactories .remove (thingHandlerFactory );
266
+ thingHandlerFactoriesToProcess .remove (thingHandlerFactory );
251
267
}
252
268
253
269
@ Reference
@@ -267,26 +283,56 @@ public void onReadyMarkerAdded(ReadyMarker readyMarker) {
267
283
} else if (XML_THING_TYPE .equals (type )) {
268
284
String bsn = readyMarker .getIdentifier ();
269
285
loadedXmlThingTypes .add (bsn );
270
- thingHandlerFactories .stream ().filter (factory -> bsn .equals (getBundleName (factory ))).forEach (factory -> {
271
- thingHandlerFactoryAdded (factory );
272
- });
286
+ thingHandlerFactoriesToProcess .stream ().filter (factory -> bsn .equals (getBundleName (factory )))
287
+ .forEach (factory -> {
288
+ processAddedthingHandlerFactory (factory );
289
+ });
273
290
}
274
291
}
275
292
293
+ @ Reference (cardinality = ReferenceCardinality .OPTIONAL , policy = ReferencePolicy .DYNAMIC )
294
+ public void setModelRepository (final YamlModelRepository modelRepository ) {
295
+ logger .debug ("setModelRepository" );
296
+ this .modelRepository = modelRepository ;
297
+ thingHandlerFactoriesToProcess .forEach (factory -> {
298
+ processAddedthingHandlerFactory (factory );
299
+ });
300
+ }
301
+
302
+ public void unsetModelRepository (final YamlModelRepository modelRepository ) {
303
+ this .modelRepository = null ;
304
+ }
305
+
276
306
@ Override
277
307
public void onReadyMarkerRemoved (ReadyMarker readyMarker ) {
278
308
loadedXmlThingTypes .remove (readyMarker .getIdentifier ());
279
309
}
280
310
281
- private void thingHandlerFactoryAdded (ThingHandlerFactory thingHandlerFactory ) {
311
+ private boolean refreshNeeded (YamlThingDTO thingDto ) {
312
+ ThingUID thingUID = new ThingUID (thingDto .uid );
313
+ String [] segments = thingUID .getAsString ().split (AbstractUID .SEPARATOR );
314
+ ThingTypeUID thingTypeUID = new ThingTypeUID (thingUID .getBindingId (), segments [1 ]);
315
+ ThingHandlerFactory handlerFactory = thingHandlerFactoriesToProcess .stream ()
316
+ .filter (thf -> thf .supportsThingType (thingTypeUID )).findFirst ().orElse (null );
317
+ return handlerFactory != null ;
318
+ }
319
+
320
+ private void processAddedthingHandlerFactory (ThingHandlerFactory thingHandlerFactory ) {
282
321
String bundleName = getBundleName (thingHandlerFactory );
283
- if (bundleName != null && loadedXmlThingTypes .contains (bundleName )) {
284
- logger .debug ("Refreshing models due to new thing handler factory {}" ,
285
- thingHandlerFactory .getClass ().getSimpleName ());
286
- thingsMap .keySet ().forEach (modelName -> {
287
- modelRepository .refreshModelElements (modelName ,
288
- getElementClass ().getAnnotation (YamlElementName .class ).value ());
289
- });
322
+ YamlModelRepository repository = modelRepository ;
323
+ if (repository != null && bundleName != null && loadedXmlThingTypes .contains (bundleName )) {
324
+ if (!thingsMap .isEmpty ()) {
325
+ logger .debug ("Refreshing models due to new thing handler factory {}" ,
326
+ thingHandlerFactory .getClass ().getSimpleName ());
327
+ thingsMap .keySet ().forEach (modelName -> {
328
+ repository .refreshModelElements (modelName ,
329
+ getElementClass ().getAnnotation (YamlElementName .class ).value ());
330
+ });
331
+ } else {
332
+ logger .debug ("No things yet loaded; no need to trigger a refresh due to new thing handler factory {}" ,
333
+ thingHandlerFactory .getClass ().getSimpleName ());
334
+ }
335
+ thingHandlerFactoriesToProcess .remove (thingHandlerFactory );
290
336
}
291
337
}
292
338
0 commit comments