[remoteopenhab] Use AbstractStorageBasedTypeProvider (#14956)

* [remoteopenhab] Use AbstractStorageBasedTypeProvider

Related to #14954

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2023-05-12 20:51:36 +02:00 committed by GitHub
parent 36d4d24264
commit 24a0bcbd7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,46 +14,68 @@ 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 java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.storage.StorageService;
import org.openhab.core.thing.binding.AbstractStorageBasedTypeProvider;
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.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Channel type provider used for all the channel types built by the binding when building dynamically the channels.
* One different channel type is built for each different item type found on the remote openHAB server.
*
* @author Laurent Garnier - Initial contribution
* @author Laurent Garnier - Use AbstractStorageBasedTypeProvider
*/
@Component(service = { ChannelTypeProvider.class, RemoteopenhabChannelTypeProvider.class })
@NonNullByDefault
public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
private final List<ChannelType> channelTypes = new CopyOnWriteArrayList<>();
public class RemoteopenhabChannelTypeProvider extends AbstractStorageBasedTypeProvider {
private static final String PATTERN_CHANNEL_TYPE_ID = "item%s%d";
private static final Pattern PATTERN_MATCHING_CHANNEL_TYPE_ID = Pattern.compile("^item([a-zA-Z]+)([0-9]+)$");
private final Logger logger = LoggerFactory.getLogger(RemoteopenhabChannelTypeProvider.class);
private final Map<String, List<ChannelType>> channelTypesForItemTypes = new ConcurrentHashMap<>();
@Override
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
return channelTypes;
@Activate
public RemoteopenhabChannelTypeProvider(@Reference StorageService storageService) {
super(storageService);
getChannelTypes(null).forEach(ct -> {
Matcher matcher = PATTERN_MATCHING_CHANNEL_TYPE_ID.matcher(ct.getUID().getId());
if (matcher.find()) {
String itemType = matcher.group(1);
// Handle number with a dimension
if (itemType.startsWith("Number") && !"Number".equals(itemType)) {
itemType = itemType.replace("Number", "Number:");
}
addChannelTypeForItemType(itemType, ct);
} else {
logger.warn("Invalid channel type ID : {}", ct.getUID().getId());
}
});
}
@Override
public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
for (ChannelType channelType : channelTypes) {
if (channelType.getUID().equals(channelTypeUID)) {
return channelType;
}
}
return null;
@Deactivate
protected void deactivate() {
channelTypesForItemTypes.values().forEach(l -> l.clear());
channelTypesForItemTypes.clear();
}
public @Nullable ChannelType getChannelType(String itemType, boolean readOnly, String pattern) {
@ -80,12 +102,34 @@ public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
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));
int max = 0;
if (channelTypesForItemType != null) {
for (ChannelType ct : channelTypesForItemType) {
Matcher matcher = PATTERN_MATCHING_CHANNEL_TYPE_ID.matcher(ct.getUID().getId());
if (matcher.find()) {
int nb = Integer.parseInt(matcher.group(2));
if (nb > max) {
max = nb;
}
}
}
}
return new ChannelTypeUID(BINDING_ID,
String.format(PATTERN_CHANNEL_TYPE_ID, itemType.replace(":", ""), max + 1));
}
public void addChannelType(String itemType, ChannelType channelType) {
channelTypes.add(channelType);
putChannelType(channelType);
addChannelTypeForItemType(itemType, channelType);
}
public void removeChannelType(String itemType, ChannelType channelType) {
removeChannelType(channelType.getUID());
removeChannelTypeForItemType(itemType, channelType);
}
private void addChannelTypeForItemType(String itemType, ChannelType channelType) {
logger.debug("addChannelTypeForItemType {} {}", itemType, channelType.getUID());
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.computeIfAbsent(itemType,
type -> new CopyOnWriteArrayList<>());
if (channelTypesForItemType != null) {
@ -93,8 +137,7 @@ public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
}
}
public void removeChannelType(String itemType, ChannelType channelType) {
channelTypes.remove(channelType);
private void removeChannelTypeForItemType(String itemType, ChannelType channelType) {
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
if (channelTypesForItemType != null) {
channelTypesForItemType.remove(channelType);