[remoteopenhab] Consider the remote item pattern formatter (#9657)

* [remoteopenhab] Consider the remote item pattern formatter

Fux #9645
* Review comment: use computeIfAbsent

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2021-01-04 06:35:09 +01:00 committed by GitHub
parent 4f1e915e50
commit a63acf000e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 15 deletions

View File

@ -12,9 +12,13 @@
*/
package org.openhab.binding.remoteopenhab.internal;
import static org.openhab.binding.remoteopenhab.internal.RemoteopenhabBindingConstants.BINDING_ID;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jdt.annotation.NonNullByDefault;
@ -22,6 +26,7 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.type.ChannelType;
import org.openhab.core.thing.type.ChannelTypeProvider;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.StateDescription;
import org.osgi.service.component.annotations.Component;
/**
@ -34,6 +39,7 @@ import org.osgi.service.component.annotations.Component;
@NonNullByDefault
public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
private final List<ChannelType> channelTypes = new CopyOnWriteArrayList<>();
private final Map<String, List<ChannelType>> channelTypesForItemTypes = new ConcurrentHashMap<>();
@Override
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
@ -50,11 +56,48 @@ public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
return null;
}
public void addChannelType(ChannelType type) {
channelTypes.add(type);
public @Nullable ChannelType getChannelType(String itemType, boolean readOnly, String pattern) {
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
if (channelTypesForItemType != null) {
for (ChannelType channelType : channelTypesForItemType) {
boolean channelTypeReadOnly = false;
String channelTypePattern = null;
StateDescription stateDescription = channelType.getState();
if (stateDescription != null) {
channelTypeReadOnly = stateDescription.isReadOnly();
channelTypePattern = stateDescription.getPattern();
}
if (channelTypePattern == null) {
channelTypePattern = "";
}
if (channelTypeReadOnly == readOnly && channelTypePattern.equals(pattern)) {
return channelType;
}
}
}
return null;
}
public void removeChannelType(ChannelType type) {
channelTypes.remove(type);
public ChannelTypeUID buildNewChannelTypeUID(String itemType) {
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
int nb = channelTypesForItemType == null ? 0 : channelTypesForItemType.size();
return new ChannelTypeUID(BINDING_ID, String.format("item%s%d", itemType.replace(":", ""), nb + 1));
}
public void addChannelType(String itemType, ChannelType channelType) {
channelTypes.add(channelType);
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.computeIfAbsent(itemType,
type -> new CopyOnWriteArrayList<>());
if (channelTypesForItemType != null) {
channelTypesForItemType.add(channelType);
}
}
public void removeChannelType(String itemType, ChannelType channelType) {
channelTypes.remove(channelType);
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
if (channelTypesForItemType != null) {
channelTypesForItemType.remove(channelType);
}
}
}

View File

@ -12,8 +12,6 @@
*/
package org.openhab.binding.remoteopenhab.internal.handler;
import static org.openhab.binding.remoteopenhab.internal.RemoteopenhabBindingConstants.BINDING_ID;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.ZonedDateTime;
@ -217,6 +215,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
synchronized (updateThingLock) {
try {
int nbGroups = 0;
int nbChannelTypesCreated = 0;
List<Channel> channels = new ArrayList<>();
for (RemoteopenhabItem item : items) {
String itemType = item.type;
@ -234,21 +233,33 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
readOnly = true;
}
}
String channelTypeId = String.format("item%s%s", itemType.replace(":", ""), readOnly ? "RO" : "");
ChannelTypeUID channelTypeUID = new ChannelTypeUID(BINDING_ID, channelTypeId);
ChannelType channelType = channelTypeProvider.getChannelType(channelTypeUID, null);
// Ignore pattern containing a transformation (detected by a parenthesis in the pattern)
RemoteopenhabStateDescription stateDescription = item.stateDescription;
String pattern = (stateDescription == null || stateDescription.pattern.contains("(")) ? ""
: stateDescription.pattern;
ChannelTypeUID channelTypeUID;
ChannelType channelType = channelTypeProvider.getChannelType(itemType, readOnly, pattern);
String label;
String description;
if (channelType == null) {
logger.trace("Create the channel type {} for item type {}", channelTypeUID, itemType);
channelTypeUID = channelTypeProvider.buildNewChannelTypeUID(itemType);
logger.trace("Create the channel type {} for item type {} ({} and with pattern {})",
channelTypeUID, itemType, readOnly ? "read only" : "read write", pattern);
label = String.format("Remote %s Item", itemType);
description = String.format("An item of type %s from the remote server.", itemType);
StateDescriptionFragmentBuilder stateDescriptionBuilder = StateDescriptionFragmentBuilder
.create().withReadOnly(readOnly);
if (!pattern.isEmpty()) {
stateDescriptionBuilder = stateDescriptionBuilder.withPattern(pattern);
}
channelType = ChannelTypeBuilder.state(channelTypeUID, label, itemType)
.withDescription(description)
.withStateDescriptionFragment(
StateDescriptionFragmentBuilder.create().withReadOnly(readOnly).build())
.withStateDescriptionFragment(stateDescriptionBuilder.build())
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
channelTypeProvider.addChannelType(channelType);
channelTypeProvider.addChannelType(itemType, channelType);
nbChannelTypesCreated++;
} else {
channelTypeUID = channelType.getUID();
}
ChannelUID channelUID = new ChannelUID(getThing().getUID(), item.name);
logger.trace("Create the channel {} of type {}", channelUID, channelTypeUID);
@ -261,8 +272,9 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
if (replace) {
thingBuilder.withChannels(channels);
updateThing(thingBuilder.build());
logger.debug("{} channels defined for the thing {} (from {} items including {} groups)",
channels.size(), getThing().getUID(), items.size(), nbGroups);
logger.debug(
"{} channels defined (with {} different channel types) for the thing {} (from {} items including {} groups)",
channels.size(), nbChannelTypesCreated, getThing().getUID(), items.size(), nbGroups);
} else if (channels.size() > 0) {
int nbRemoved = 0;
for (Channel channel : channels) {