Skip to content

Commit

Permalink
Fix reloading channel config changes in .items file (#4075)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
jimtng authored Feb 4, 2024
1 parent 85056d9 commit c929e7d
Showing 1 changed file with 15 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -98,15 +99,20 @@ private void createItemChannelLink(String context, String itemName, String chann
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);
}
}

Expand All @@ -128,18 +134,16 @@ public void stopConfigurationUpdate(String context) {
}
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));
}

@Override
public Collection<ItemChannelLink> getAll() {
return itemChannelLinkMap.values().stream().flatMap(Collection::stream).toList();
return itemChannelLinkMap.values().stream().flatMap(m -> m.values().stream()).toList();
}
}

0 comments on commit c929e7d

Please sign in to comment.