]> git.basschouten.com Git - openhab-addons.git/commitdiff
[remoteopenhab] Use AbstractStorageBasedTypeProvider (#14956)
authorlolodomo <lg.hc@free.fr>
Fri, 12 May 2023 18:51:36 +0000 (20:51 +0200)
committerGitHub <noreply@github.com>
Fri, 12 May 2023 18:51:36 +0000 (20:51 +0200)
* [remoteopenhab] Use AbstractStorageBasedTypeProvider

Related to #14954

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/RemoteopenhabChannelTypeProvider.java

index 822c675dd988252b64bbd3d4e6df9d42a55ae190..3b783a6b09e013b0af0c70634cfb2333c481ec0d 100644 (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);