From bb3e8694e3fc27897a0d7a43ec1505db73b57fe5 Mon Sep 17 00:00:00 2001 From: silamon <32477463+silamon@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:56:02 +0100 Subject: [PATCH] ChannelDTO bugfixes (#1346) * Fix bug in ChannelDTOMapper * Add AutoUpdatePolicy to ChannelDTO Also-by: Christoph Weitkamp Signed-off-by: Simon Lamon --- .../openhab/core/thing/dto/ChannelDTO.java | 8 +- .../core/thing/dto/ChannelDTOMapper.java | 14 ++- .../thing/dto/StrippedThingTypeDTOMapper.java | 2 + .../core/thing/dto/ThingDTOMapper.java | 6 +- .../core/thing/type/AutoUpdatePolicy.java | 23 ++++- .../binding/builder/ThingBuilderTest.java | 5 +- .../core/thing/dto/ChannelDTOTest.java | 70 +++++++++++++++ .../openhab/core/thing/dto/ThingDTOTest.java | 86 +++++++++++++++++++ 8 files changed, 202 insertions(+), 12 deletions(-) create mode 100644 bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ChannelDTOTest.java create mode 100644 bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ThingDTOTest.java diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTO.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTO.java index 02b2238c74..1bcc9c1081 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTO.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTO.java @@ -19,6 +19,7 @@ import java.util.Set; import org.openhab.core.config.core.Configuration; import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.type.AutoUpdatePolicy; import org.openhab.core.thing.type.ChannelKind; /** @@ -40,12 +41,14 @@ public class ChannelDTO { public Set defaultTags; public Map properties; public Map configuration; + public String autoUpdatePolicy; public ChannelDTO() { } public ChannelDTO(ChannelUID uid, String channelTypeUID, String itemType, ChannelKind kind, String label, - String description, Map properties, Configuration configuration, Set defaultTags) { + String description, Map properties, Configuration configuration, Set defaultTags, + AutoUpdatePolicy autoUpdatePolicy) { this.uid = uid.toString(); this.id = uid.getId(); this.channelTypeUID = channelTypeUID; @@ -56,6 +59,9 @@ public class ChannelDTO { this.configuration = toMap(configuration); this.defaultTags = new HashSet<>(defaultTags); this.kind = kind.toString(); + if (autoUpdatePolicy != null) { + this.autoUpdatePolicy = autoUpdatePolicy.toString(); + } } private Map toMap(Configuration configuration) { diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTOMapper.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTOMapper.java index d184137613..50e8d0b1a1 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTOMapper.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ChannelDTOMapper.java @@ -12,10 +12,12 @@ */ package org.openhab.core.thing.dto; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.config.core.Configuration; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.binding.builder.ChannelBuilder; +import org.openhab.core.thing.type.AutoUpdatePolicy; import org.openhab.core.thing.type.ChannelKind; import org.openhab.core.thing.type.ChannelTypeUID; @@ -25,6 +27,7 @@ import org.openhab.core.thing.type.ChannelTypeUID; * @author Stefan Bußweiler - Initial contribution * @author Kai Kreuzer - added DTO to channel mapping */ +@NonNullByDefault public class ChannelDTOMapper { /** @@ -35,10 +38,10 @@ public class ChannelDTOMapper { */ public static ChannelDTO map(Channel channel) { ChannelTypeUID channelTypeUID = channel.getChannelTypeUID(); - String channelTypeUIDValue = channelTypeUID != null ? channelTypeUID.toString() : null; + String channelTypeUIDValue = channelTypeUID != null ? channelTypeUID.getAsString() : null; return new ChannelDTO(channel.getUID(), channelTypeUIDValue, channel.getAcceptedItemType(), channel.getKind(), channel.getLabel(), channel.getDescription(), channel.getProperties(), channel.getConfiguration(), - channel.getDefaultTags()); + channel.getDefaultTags(), channel.getAutoUpdatePolicy()); } /** @@ -49,10 +52,13 @@ public class ChannelDTOMapper { */ public static Channel map(ChannelDTO channelDTO) { ChannelUID channelUID = new ChannelUID(channelDTO.uid); - ChannelTypeUID channelTypeUID = new ChannelTypeUID(channelDTO.channelTypeUID); + ChannelTypeUID channelTypeUID = channelDTO.channelTypeUID != null + ? new ChannelTypeUID(channelDTO.channelTypeUID) + : null; return ChannelBuilder.create(channelUID, channelDTO.itemType) .withConfiguration(new Configuration(channelDTO.configuration)).withLabel(channelDTO.label) .withDescription(channelDTO.description).withProperties(channelDTO.properties).withType(channelTypeUID) - .withDefaultTags(channelDTO.defaultTags).withKind(ChannelKind.parse(channelDTO.kind)).build(); + .withDefaultTags(channelDTO.defaultTags).withKind(ChannelKind.parse(channelDTO.kind)) + .withAutoUpdatePolicy(AutoUpdatePolicy.parse(channelDTO.autoUpdatePolicy)).build(); } } diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/StrippedThingTypeDTOMapper.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/StrippedThingTypeDTOMapper.java index 5d2ac47da5..6686eb7ff2 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/StrippedThingTypeDTOMapper.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/StrippedThingTypeDTOMapper.java @@ -14,6 +14,7 @@ package org.openhab.core.thing.dto; import java.util.Locale; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.thing.type.BridgeType; import org.openhab.core.thing.type.ThingType; @@ -23,6 +24,7 @@ import org.openhab.core.thing.type.ThingType; * * @author Miki Jankov - Initial contribution */ +@NonNullByDefault public class StrippedThingTypeDTOMapper { /** diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ThingDTOMapper.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ThingDTOMapper.java index 02359d1078..de961a7731 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ThingDTOMapper.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/dto/ThingDTOMapper.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.config.core.Configuration; import org.openhab.core.thing.Channel; import org.openhab.core.thing.Thing; @@ -32,6 +33,7 @@ import org.openhab.core.thing.util.ThingHelper; * @author Stefan Bußweiler - Initial contribution * @author Kai Kreuzer - Added DTO to Thing mapping */ +@NonNullByDefault public class ThingDTOMapper { /** @@ -76,10 +78,6 @@ public class ThingDTOMapper { } private static Map toMap(Configuration configuration) { - if (configuration == null) { - return null; - } - Map configurationMap = new HashMap<>(configuration.keySet().size()); for (String key : configuration.keySet()) { configurationMap.put(key, configuration.get(key)); diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/type/AutoUpdatePolicy.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/type/AutoUpdatePolicy.java index 5a50518833..6ef59243cf 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/type/AutoUpdatePolicy.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/type/AutoUpdatePolicy.java @@ -36,5 +36,26 @@ public enum AutoUpdatePolicy { * An automatic state update should be sent by the framework because no updates will be sent by the binding. * This usually is the case when devices don't expose their current state to the handler. */ - RECOMMEND, + RECOMMEND; + + /** + * Parses the input string into a {@link AutoUpdatePolicy}. + * + * @param input the input string + * @return the parsed AutoUpdatePolicy + * @throws IllegalArgumentException if the input couldn't be parsed. + */ + public static AutoUpdatePolicy parse(String input) { + if (input == null) { + return DEFAULT; + } + + for (AutoUpdatePolicy value : values()) { + if (value.name().equalsIgnoreCase(input)) { + return value; + } + } + + throw new IllegalArgumentException(String.format("Unknown auto update policy: '%s'", input)); + } } diff --git a/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/builder/ThingBuilderTest.java b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/builder/ThingBuilderTest.java index 3792e64a63..95115676f5 100644 --- a/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/builder/ThingBuilderTest.java +++ b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/builder/ThingBuilderTest.java @@ -13,6 +13,7 @@ package org.openhab.core.thing.binding.builder; import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.junit.Assert.assertThat; import java.util.Arrays; @@ -94,7 +95,7 @@ public class ThingBuilderTest { ChannelBuilder.create(new ChannelUID(THING_UID, "channel2"), "").build()); thingBuilder.withoutChannel(new ChannelUID(THING_UID, "channel1")); Thing thing = thingBuilder.build(); - assertThat(thing.getChannels().size(), is(equalTo(1))); + assertThat(thing.getChannels(), hasSize(1)); assertThat(thing.getChannels().get(0).getUID().getId(), is(equalTo("channel2"))); } @@ -104,7 +105,7 @@ public class ThingBuilderTest { ChannelBuilder.create(new ChannelUID(THING_UID, "channel1"), "").build(), // ChannelBuilder.create(new ChannelUID(THING_UID, "channel2"), "").build()); thingBuilder.withoutChannel(new ChannelUID(THING_UID, "channel3")); - assertThat(thingBuilder.build().getChannels().size(), is(equalTo(2))); + assertThat(thingBuilder.build().getChannels(), hasSize(2)); } @Test(expected = IllegalArgumentException.class) diff --git a/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ChannelDTOTest.java b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ChannelDTOTest.java new file mode 100644 index 0000000000..cf1cc86946 --- /dev/null +++ b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ChannelDTOTest.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.core.thing.dto; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.Assert.assertThat; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; +import org.openhab.core.config.core.Configuration; +import org.openhab.core.library.CoreItemFactory; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingTypeUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.binding.builder.ChannelBuilder; +import org.openhab.core.thing.type.AutoUpdatePolicy; +import org.openhab.core.thing.type.ChannelTypeUID; + +/** + * This is the test class for {@link ChannelDTO}. + * + * @author Christoph Weitkamp - Initial contribution + */ +public class ChannelDTOTest { + + private static final ThingTypeUID THING_TYPE_UID = new ThingTypeUID("binding-id", "thing-type-id"); + private static final ThingUID THING_UID = new ThingUID(THING_TYPE_UID, "thing-id"); + private static final ChannelTypeUID CHANNEL_TYPE_UID = new ChannelTypeUID("binding-id", "channel-type-id"); + private static final ChannelUID CHANNEL_UID = new ChannelUID(THING_UID, "channel1"); + private final Map properties = Collections.singletonMap("key1", "value1"); + private final Set tags = Collections.singleton("tag1"); + + @Test + public void testChannelDTOMappingIsBidirectional() { + Channel subject = ChannelBuilder.create(CHANNEL_UID, CoreItemFactory.STRING).withType(CHANNEL_TYPE_UID) + .withLabel("Test").withDescription("My test channel") + .withConfiguration(new Configuration(Collections.singletonMap("param1", "value1"))) + .withProperties(properties).withDefaultTags(tags).withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build(); + Channel result = ChannelDTOMapper.map(ChannelDTOMapper.map(subject)); + assertThat(result, is(instanceOf(Channel.class))); + assertThat(result.getChannelTypeUID(), is(CHANNEL_TYPE_UID)); + assertThat(result.getUID(), is(CHANNEL_UID)); + assertThat(result.getAcceptedItemType(), is(subject.getAcceptedItemType())); + assertThat(result.getKind(), is(subject.getKind())); + assertThat(result.getLabel(), is(subject.getLabel())); + assertThat(result.getDescription(), is(subject.getDescription())); + assertThat(result.getConfiguration(), is(subject.getConfiguration())); + assertThat(result.getProperties().values(), hasSize(1)); + assertThat(result.getProperties(), is(subject.getProperties())); + assertThat(result.getDefaultTags(), hasSize(1)); + assertThat(result.getDefaultTags(), is(subject.getDefaultTags())); + assertThat(result.getAutoUpdatePolicy(), is(subject.getAutoUpdatePolicy())); + } + +} diff --git a/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ThingDTOTest.java b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ThingDTOTest.java new file mode 100644 index 0000000000..eecf2fec50 --- /dev/null +++ b/bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/dto/ThingDTOTest.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.core.thing.dto; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.Assert.assertThat; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.openhab.core.config.core.Configuration; +import org.openhab.core.library.CoreItemFactory; +import org.openhab.core.thing.Bridge; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.Thing; +import org.openhab.core.thing.ThingTypeUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.binding.builder.BridgeBuilder; +import org.openhab.core.thing.binding.builder.ChannelBuilder; +import org.openhab.core.thing.binding.builder.ThingBuilder; +import org.openhab.core.thing.internal.BridgeImpl; +import org.openhab.core.thing.internal.ThingImpl; + +/** + * This is the test class for {@link ThingDTO}. + * + * @author Christoph Weitkamp - Initial contribution + */ +public class ThingDTOTest { + + private static final ThingTypeUID THING_TYPE_UID = new ThingTypeUID("binding-id", "thing-type-id"); + private static final ThingUID THING_UID = new ThingUID(THING_TYPE_UID, "thing-id"); + private final Map properties = Collections.singletonMap("key1", "value1"); + + @Test + public void testThingDTOMappingIsBidirectional() { + Thing subject = ThingBuilder.create(THING_TYPE_UID, THING_UID).withLabel("Test") + .withBridge(new ThingUID(new ThingTypeUID("binding-id", "bridge-type-id"), "bridge-id")) + .withChannels( + ChannelBuilder.create(new ChannelUID(THING_UID, "channel1"), CoreItemFactory.STRING).build(), + ChannelBuilder.create(new ChannelUID(THING_UID, "channel2"), CoreItemFactory.STRING).build()) + .withConfiguration(new Configuration(Collections.singletonMap("param1", "value1"))) + .withProperties(properties).withLocation("Somewhere over the rainbow").build(); + Thing result = ThingDTOMapper.map(ThingDTOMapper.map(subject), false); + assertThat(result, is(instanceOf(ThingImpl.class))); + assertThat(result.getThingTypeUID(), is(THING_TYPE_UID)); + assertThat(result.getUID(), is(THING_UID)); + assertThat(result.getLabel(), is(subject.getLabel())); + assertThat(result.getBridgeUID(), is(subject.getBridgeUID())); + assertThatChannelsArePresent(result.getChannels(), subject.getChannels()); + assertThat(result.getConfiguration(), is(subject.getConfiguration())); + assertThat(result.getProperties().values(), hasSize(1)); + assertThat(result.getProperties(), is(subject.getProperties())); + assertThat(result.getLocation(), is(subject.getLocation())); + } + + @Test + public void testBridgeDTOMappingIsBidirectional() { + Bridge subject = BridgeBuilder.create(THING_TYPE_UID, THING_UID).build(); + Thing result = ThingDTOMapper.map(ThingDTOMapper.map(subject), true); + assertThat(result, is(instanceOf(BridgeImpl.class))); + } + + private void assertThatChannelsArePresent(List actual, List expected) { + assertThat(actual, hasSize(expected.size())); + actual.stream().map(channel -> channel.getUID()).forEach(uid -> { + assertThat(expected.stream().filter(channel -> uid.equals(channel.getUID())).findFirst().orElse(null), + is(notNullValue())); + }); + } + +}