Skip to content

Commit

Permalink
[remoteopenhab] Use AbstractStorageBasedTypeProvider
Browse files Browse the repository at this point in the history
Related to openhab#14954

Signed-off-by: Laurent Garnier <[email protected]>
  • Loading branch information
lolodomo committed May 9, 2023
1 parent 0bd39a8 commit d4d8977
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@

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.stream.Collectors;

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.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.
Expand All @@ -37,67 +39,67 @@
*/
@Component(service = { ChannelTypeProvider.class, RemoteopenhabChannelTypeProvider.class })
@NonNullByDefault
public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
private final List<ChannelType> channelTypes = new CopyOnWriteArrayList<>();
private final Map<String, List<ChannelType>> channelTypesForItemTypes = new ConcurrentHashMap<>();
public class RemoteopenhabChannelTypeProvider extends AbstractStorageBasedTypeProvider {

@Override
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
return channelTypes;
private static final String CHANNEL_TYPE_ID_PREFIX = "item-";
private static final String PATTERN_PREFIX_CHANNEL_TYPE_ID = CHANNEL_TYPE_ID_PREFIX + "%s-";
private static final String PATTERN_CHANNEL_TYPE_ID = PATTERN_PREFIX_CHANNEL_TYPE_ID + "%d";

private final Logger logger = LoggerFactory.getLogger(RemoteopenhabChannelTypeProvider.class);

@Activate
public RemoteopenhabChannelTypeProvider(@Reference StorageService storageService) {
super(storageService);
}

@Override
public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
for (ChannelType channelType : channelTypes) {
if (channelType.getUID().equals(channelTypeUID)) {
return channelType;
}
}
return null;
private List<ChannelType> getChannelTypesForItemType(String itemType) {
String prefix = String.format(PATTERN_PREFIX_CHANNEL_TYPE_ID, itemType.toLowerCase().replace(":", "-"));
return getChannelTypes(null).stream().filter(ct -> ct.getUID().getId().startsWith(prefix))
.collect(Collectors.toList());
}

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;
}
List<ChannelType> channelTypesForItemType = getChannelTypesForItemType(itemType);
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 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));
}
List<ChannelType> channelTypesForItemType = getChannelTypesForItemType(itemType);
String prefix = String.format(PATTERN_PREFIX_CHANNEL_TYPE_ID, itemType.toLowerCase().replace(":", "-"));
int max = 0;
for (ChannelType ct : channelTypesForItemType) {
try {
int nb = Integer.parseInt(ct.getUID().getId().substring(prefix.length()));
if (nb > max) {
max = nb;
}

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);
} catch (NumberFormatException e) {
// Ignore
}
}
return new ChannelTypeUID(BINDING_ID,
String.format(PATTERN_CHANNEL_TYPE_ID, itemType.toLowerCase().replace(":", "-"), max + 1));
}

public void removeChannelType(String itemType, ChannelType channelType) {
channelTypes.remove(channelType);
List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
if (channelTypesForItemType != null) {
channelTypesForItemType.remove(channelType);
}
@Override
public void putChannelType(ChannelType channelType) {
logger.info("putChannelType {}", channelType.getUID().getAsString());
super.putChannelType(channelType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ private boolean createChannels(List<RemoteopenhabItem> items, boolean replace) {
.withDescription(description)
.withStateDescriptionFragment(stateDescriptionBuilder.build())
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
channelTypeProvider.addChannelType(itemType, channelType);
channelTypeProvider.putChannelType(channelType);
nbChannelTypesCreated++;
} else {
channelTypeUID = channelType.getUID();
Expand Down

0 comments on commit d4d8977

Please sign in to comment.