Fix reloading channel config changes in .items file (#4075)

* Apply channel config changes in .items file

Changes in channel config weren't applied because ItemChannelLink.equals() include the link configurations in the comparison. This caused the new link not being found in the set lookup, which leads to erroneously calling notifyListenersAboutAddedElement, when it should've called notifyListenersAboutUpdatedElement instead.

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
pull/4020/head
jimtng 2024-02-04 20:23:10 +10:00 committed by GitHub
parent 85056d9d7b
commit c929e7dfe2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 15 additions and 11 deletions

View File

@ -13,6 +13,7 @@
package org.openhab.core.model.thing.internal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
@ -45,7 +46,7 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
private final Logger logger = LoggerFactory.getLogger(GenericItemChannelLinkProvider.class);
/** caches binding configurations. maps itemNames to {@link ItemChannelLink}s */
protected Map<String, Set<ItemChannelLink>> itemChannelLinkMap = new ConcurrentHashMap<>();
protected Map<String, Map<ChannelUID, ItemChannelLink>> itemChannelLinkMap = new ConcurrentHashMap<>();
/**
* stores information about the context of items. The map has this content
@ -98,15 +99,20 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
previousItemNames.remove(itemName);
}
Set<ItemChannelLink> links = itemChannelLinkMap.get(itemName);
Map<ChannelUID, ItemChannelLink> links = itemChannelLinkMap.get(itemName);
if (links == null) {
itemChannelLinkMap.put(itemName, links = new HashSet<>());
// Create a HashMap with an initial capacity of 2 (the default is 16) to save memory
// because most items have only one channel. A capacity of 2 is enough to avoid
// resizing the HashMap in most cases, whereas 1 would trigger a resize as soon as
// one element is added.
itemChannelLinkMap.put(itemName, links = new HashMap<>(2));
}
if (!links.contains(itemChannelLink)) {
links.add(itemChannelLink);
ItemChannelLink oldLink = links.put(channelUIDObject, itemChannelLink);
if (oldLink == null) {
notifyListenersAboutAddedElement(itemChannelLink);
} else {
notifyListenersAboutUpdatedElement(itemChannelLink, itemChannelLink);
notifyListenersAboutUpdatedElement(oldLink, itemChannelLink);
}
}
@ -128,11 +134,9 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
}
for (String itemName : previousItemNames) {
// we remove all binding configurations that were not processed
Set<ItemChannelLink> links = itemChannelLinkMap.remove(itemName);
Map<ChannelUID, ItemChannelLink> links = itemChannelLinkMap.remove(itemName);
if (links != null) {
for (ItemChannelLink removedItemChannelLink : links) {
notifyListenersAboutRemovedElement(removedItemChannelLink);
}
links.values().forEach(this::notifyListenersAboutRemovedElement);
}
}
Optional.ofNullable(contextMap.get(context)).ifPresent(ctx -> ctx.removeAll(previousItemNames));
@ -140,6 +144,6 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
@Override
public Collection<ItemChannelLink> getAll() {
return itemChannelLinkMap.values().stream().flatMap(Collection::stream).toList();
return itemChannelLinkMap.values().stream().flatMap(m -> m.values().stream()).toList();
}
}