Skip to content

Commit

Permalink
Fix thing reloading from things file (#3526)
Browse files Browse the repository at this point in the history
It was found that things from textual configuration are not properly updated if changes are only made in configuration or label of a channel. The reason is that for equality only uid and accepted item-type where checked.

Signed-off-by: Jan N. Klug <github@klug.nrw>
  • Loading branch information
J-N-K authored Apr 15, 2023
1 parent 5ca849e commit 016828c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -602,19 +602,20 @@ class GenericThingProvider extends AbstractProviderLazyNullness<Thing> implement
}

def private createThingsFromModelForThingHandlerFactory(String modelName, ThingHandlerFactory factory) {
if (!loadedXmlThingTypes.contains(factory.bundleName)) {
if (!loadedXmlThingTypes.contains(factory.bundleName) || modelRepository == null) {
return
}
val oldThings = thingsMap.get(modelName).clone
val newThings = newArrayList()
if (modelRepository !== null) {
val model = modelRepository.getModel(modelName) as ThingModel
if (model !== null) {
flattenModelThings(model.things).forEach [
createThing(newThings, factory)
]
}

val model = modelRepository.getModel(modelName) as ThingModel
if (model !== null) {
flattenModelThings(model.things).forEach [
createThing(newThings, factory)
]
}
thingsMap.put(modelName, newThings)

newThings.forEach [ newThing |
val oldThing = oldThings.findFirst[it.UID == newThing.UID]
if (oldThing !== null) {
Expand All @@ -624,7 +625,6 @@ class GenericThingProvider extends AbstractProviderLazyNullness<Thing> implement
}
} else {
logger.debug("Adding thing '{}' from model '{}'.", newThing.UID, modelName);
thingsMap.get(modelName).add(newThing)
newThing.notifyListenersAboutAddedElement
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand Down Expand Up @@ -178,4 +179,27 @@ public Set<String> getDefaultTags() {
public @Nullable AutoUpdatePolicy getAutoUpdatePolicy() {
return autoUpdatePolicy;
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Channel channel = (Channel) o;
return Objects.equals(acceptedItemType, channel.acceptedItemType) && kind == channel.kind
&& Objects.equals(uid, channel.uid) && Objects.equals(channelTypeUID, channel.channelTypeUID)
&& Objects.equals(label, channel.label) && Objects.equals(description, channel.description)
&& Objects.equals(configuration, channel.configuration)
&& Objects.equals(properties, channel.properties) && Objects.equals(defaultTags, channel.defaultTags)
&& autoUpdatePolicy == channel.autoUpdatePolicy;
}

@Override
public int hashCode() {
return Objects.hash(acceptedItemType, kind, uid, channelTypeUID, label, description, configuration, properties,
defaultTags, autoUpdatePolicy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
*/
package org.openhab.core.thing.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -79,24 +77,10 @@ public static boolean equals(Thing a, Thing b) {
return false;
}
// channels
List<Channel> channelsOfA = a.getChannels();
List<Channel> channelsOfB = b.getChannels();
if (channelsOfA.size() != channelsOfB.size()) {
return false;
}
if (!toString(channelsOfA).equals(toString(channelsOfB))) {
return false;
}
return true;
}
Set<Channel> channelsOfA = new HashSet<>(a.getChannels());
Set<Channel> channelsOfB = new HashSet<>(b.getChannels());

private static String toString(List<Channel> channels) {
List<String> strings = new ArrayList<>(channels.size());
for (Channel channel : channels) {
strings.add(channel.getUID().toString() + '#' + channel.getAcceptedItemType() + '#' + channel.getKind());
}
Collections.sort(strings);
return String.join(",", strings);
return channelsOfA.equals(channelsOfB);
}

public static void addChannelsToThing(Thing thing, Collection<Channel> channels) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.junit.jupiter.api.Assertions.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand Down Expand Up @@ -142,4 +143,21 @@ public void assertThatNoDuplicateChannelsCanBeAdded() {
ChannelBuilder.create(new ChannelUID(thingUID, "channel3"), "").build())
.collect(toList())));
}

@Test
public void asserThatChannelsWithDifferentConfigurationAreDetectedAsDifferent() {
Thing thingA = ThingBuilder.create(THING_TYPE_UID, THING_UID)
.withChannels(ChannelBuilder.create(new ChannelUID("binding:type:thingId:channel1"), "itemType")
.withConfiguration(new Configuration(Map.of("key", "v1"))).build())
.withConfiguration(new Configuration()).build();

assertTrue(ThingHelper.equals(thingA, thingA));

Thing thingB = ThingBuilder.create(THING_TYPE_UID, THING_UID)
.withChannels(ChannelBuilder.create(new ChannelUID("binding:type:thingId:channel1"), "itemType")
.withConfiguration(new Configuration(Map.of("key", "v2"))).build())
.withConfiguration(new Configuration()).build();

assertFalse(ThingHelper.equals(thingA, thingB));
}
}

0 comments on commit 016828c

Please sign in to comment.