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) {
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) {
}
}
- 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);