Skip to content

Commit

Permalink
[systeminfo] Reduce code complexity as well garbage collection (#16838)
Browse files Browse the repository at this point in the history
* [systeminfo] Avoid thing type change as well memory re-allocations

Signed-off-by: Alexander Falkenstern <[email protected]>
  • Loading branch information
falkena authored Jun 6, 2024
1 parent c2e051e commit 6ebe335
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public class SystemInfoBindingConstants {

public static final String BINDING_ID = "systeminfo";

public static final String THING_TYPE_COMPUTER_ID = "computer";
public static final ThingTypeUID THING_TYPE_COMPUTER = new ThingTypeUID(BINDING_ID, THING_TYPE_COMPUTER_ID);
public static final ThingTypeUID THING_TYPE_COMPUTER = new ThingTypeUID(BINDING_ID, "computer");
public static final ThingTypeUID THING_TYPE_COMPUTER_IMPL = new ThingTypeUID(BINDING_ID, "computer-impl");

// Thing properties
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import static org.openhab.binding.systeminfo.internal.SystemInfoBindingConstants.*;

import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.systeminfo.internal.handler.SystemInfoHandler;
Expand Down Expand Up @@ -41,24 +43,25 @@ public class SystemInfoHandlerFactory extends BaseThingHandlerFactory {
private @NonNullByDefault({}) SystemInfoInterface systeminfo;
private @NonNullByDefault({}) SystemInfoThingTypeProvider thingTypeProvider;

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_COMPUTER,
THING_TYPE_COMPUTER_IMPL);

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return BINDING_ID.equals(thingTypeUID.getBindingId())
&& thingTypeUID.getId().startsWith(THING_TYPE_COMPUTER_ID);
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (supportsThingType(thingTypeUID)) {
String extString = "-" + thing.getUID().getId();
ThingTypeUID extThingTypeUID = new ThingTypeUID(BINDING_ID, THING_TYPE_COMPUTER_ID + extString);
if (thingTypeProvider.getThingType(extThingTypeUID, null) == null) {
thingTypeProvider.createThingType(extThingTypeUID);
thingTypeProvider.storeChannelsConfig(thing); // Save the current channels configs, will be restored
// after thing type change.
if (THING_TYPE_COMPUTER.equals(thing.getThingTypeUID())) {
if (thingTypeProvider.getThingType(THING_TYPE_COMPUTER_IMPL, null) == null) {
thingTypeProvider.createThingType(THING_TYPE_COMPUTER_IMPL);
// Save the current channels configs, will be restored after thing type change.
thingTypeProvider.storeChannelsConfig(thing);
}
return new SystemInfoHandler(thing, thingTypeProvider, systeminfo);
} else if (THING_TYPE_COMPUTER_IMPL.equals(thing.getThingTypeUID())) {
return new SystemInfoHandler(thing, thingTypeProvider, systeminfo);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,82 +83,54 @@ public SystemInfoThingTypeProvider(@Reference ThingTypeRegistry thingTypeRegistr
* Create thing type with the provided typeUID and add it to the thing type registry.
*
* @param typeUID
* @return false if base type UID `systeminfo:computer` cannot be found in the thingTypeRegistry
*/
public boolean createThingType(ThingTypeUID typeUID) {
public void createThingType(ThingTypeUID typeUID) {
logger.trace("Creating thing type {}", typeUID);
return updateThingType(typeUID, getChannelGroupDefinitions(typeUID));
updateThingType(typeUID, getChannelGroupDefinitions(typeUID));
}

/**
* Update `ThingType`with `typeUID`, replacing the channel group definitions with `groupDefs`.
*
* @param typeUID
* @param groupDefs
* @return false if `typeUID` or its base type UID `systeminfo:computer` cannot be found in the thingTypeRegistry
* @param channelGroupDefinitions
*/
public boolean updateThingType(ThingTypeUID typeUID, List<ChannelGroupDefinition> groupDefs) {
public void updateThingType(ThingTypeUID typeUID, List<ChannelGroupDefinition> channelGroupDefinitions) {
ThingType baseType = thingTypeRegistry.getThingType(typeUID);
if (baseType == null) {
baseType = thingTypeRegistry.getThingType(THING_TYPE_COMPUTER);
if (baseType == null) {
logger.warn("Could not find base thing type in registry.");
return false;
return;
}
}
ThingTypeBuilder builder = createThingTypeBuilder(typeUID, baseType.getUID());
if (builder != null) {
logger.trace("Adding channel group definitions to thing type");
ThingType type = builder.withChannelGroupDefinitions(groupDefs).build();

putThingType(type);
return true;
} else {
logger.debug("Error adding channel groups");
return false;
}
}

/**
* Return a {@link ThingTypeBuilder} that can create an exact copy of the `ThingType` with `baseTypeUID`.
* Further build steps can be performed on the returned object before recreating the `ThingType` from the builder.
*
* @param newTypeUID
* @param baseTypeUID
* @return the ThingTypeBuilder, null if `baseTypeUID` cannot be found in the thingTypeRegistry
*/
private @Nullable ThingTypeBuilder createThingTypeBuilder(ThingTypeUID newTypeUID, ThingTypeUID baseTypeUID) {
ThingType type = thingTypeRegistry.getThingType(baseTypeUID);
final ThingTypeBuilder builder = ThingTypeBuilder.instance(THING_TYPE_COMPUTER_IMPL, baseType.getLabel());
builder.withChannelGroupDefinitions(baseType.getChannelGroupDefinitions());
builder.withChannelDefinitions(baseType.getChannelDefinitions());
builder.withExtensibleChannelTypeIds(baseType.getExtensibleChannelTypeIds());
builder.withSupportedBridgeTypeUIDs(baseType.getSupportedBridgeTypeUIDs());
builder.withProperties(baseType.getProperties()).isListed(false);

if (type == null) {
return null;
}

ThingTypeBuilder result = ThingTypeBuilder.instance(newTypeUID, type.getLabel())
.withChannelGroupDefinitions(type.getChannelGroupDefinitions())
.withChannelDefinitions(type.getChannelDefinitions())
.withExtensibleChannelTypeIds(type.getExtensibleChannelTypeIds())
.withSupportedBridgeTypeUIDs(type.getSupportedBridgeTypeUIDs()).withProperties(type.getProperties())
.isListed(false);

String representationProperty = type.getRepresentationProperty();
final String representationProperty = baseType.getRepresentationProperty();
if (representationProperty != null) {
result = result.withRepresentationProperty(representationProperty);
builder.withRepresentationProperty(representationProperty);
}
URI configDescriptionURI = type.getConfigDescriptionURI();
final URI configDescriptionURI = baseType.getConfigDescriptionURI();
if (configDescriptionURI != null) {
result = result.withConfigDescriptionURI(configDescriptionURI);
builder.withConfigDescriptionURI(configDescriptionURI);
}
String category = type.getCategory();
final String category = baseType.getCategory();
if (category != null) {
result = result.withCategory(category);
builder.withCategory(category);
}
String description = type.getDescription();
final String description = baseType.getDescription();
if (description != null) {
result = result.withDescription(description);
builder.withDescription(description);
}

return result;
logger.trace("Adding channel group definitions to thing type");
putThingType(builder.withChannelGroupDefinitions(channelGroupDefinitions).build());
}

/**
Expand Down Expand Up @@ -224,18 +196,19 @@ public List<ChannelGroupDefinition> getChannelGroupDefinitions(ThingTypeUID type
channelTypeUID != null ? channelTypeUID.getId() : "null");
return null;
}
ThingUID thingUID = thing.getUID();

String index = String.valueOf(i);
ChannelUID channelUID = new ChannelUID(thingUID, channelID + index);
ChannelBuilder builder = ChannelBuilder.create(channelUID).withType(channelTypeUID)
.withConfiguration(baseChannel.getConfiguration());
ChannelUID channelUID = new ChannelUID(thing.getUID(), channelID + index);
ChannelBuilder builder = ChannelBuilder.create(channelUID).withType(channelTypeUID);
builder.withConfiguration(baseChannel.getConfiguration());
builder.withLabel(channelType.getLabel() + " " + index);
builder.withDefaultTags(channelType.getTags());
String description = channelType.getDescription();

final String description = channelType.getDescription();
if (description != null) {
builder.withDescription(description);
}
String itemType = channelType.getItemType();
final String itemType = channelType.getItemType();
if (itemType != null) {
builder.withAcceptedItemType(itemType);
}
Expand All @@ -252,7 +225,7 @@ public List<ChannelGroupDefinition> getChannelGroupDefinitions(ThingTypeUID type
*/
public void storeChannelsConfig(Thing thing) {
Map<String, Configuration> channelsConfig = thing.getChannels().stream()
.collect(Collectors.toMap(c -> c.getUID().getId(), c -> c.getConfiguration()));
.collect(Collectors.toMap(c -> c.getUID().getId(), Channel::getConfiguration));
thingChannelsConfig.put(thing.getUID(), channelsConfig);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class SystemInfoDiscoveryService extends AbstractDiscoveryService {

private static final int DISCOVERY_TIME_SECONDS = 30;
private static final String THING_UID_VALID_CHARS = "A-Za-z0-9_-";
private static final String HOST_NAME_SEPERATOR = "_";
private static final String HOST_NAME_SEPARATOR = "_";

public SystemInfoDiscoveryService() {
super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_TIME_SECONDS);
Expand All @@ -57,28 +57,31 @@ public SystemInfoDiscoveryService() {
@Override
protected void startScan() {
logger.debug("Starting system information discovery !");
String hostname;

String hostname;
try {
hostname = getHostName();
if (hostname.isEmpty()) {
throw new UnknownHostException();
}
if (!hostname.matches("[" + THING_UID_VALID_CHARS + "]*")) {
hostname = hostname.replaceAll("[^" + THING_UID_VALID_CHARS + "]", HOST_NAME_SEPERATOR);
}
} catch (UnknownHostException ex) {
hostname = DEFAULT_THING_ID;
logger.info("Hostname can not be resolved. Computer name will be set to the default one: {}",
DEFAULT_THING_ID);
}

ThingUID computer = new ThingUID(THING_TYPE_COMPUTER, hostname);
thingDiscovered(DiscoveryResultBuilder.create(computer).withLabel(DEFAULT_THING_LABEL).build());
String thingId = hostname;
if (!thingId.matches("[" + THING_UID_VALID_CHARS + "]*")) {
thingId = thingId.replaceAll("[^" + THING_UID_VALID_CHARS + "]", HOST_NAME_SEPARATOR);
}

final ThingUID computer = new ThingUID(THING_TYPE_COMPUTER, thingId);
final DiscoveryResultBuilder builder = DiscoveryResultBuilder.create(computer);
builder.withLabel(DEFAULT_THING_LABEL);
thingDiscovered(builder.build());
}

protected String getHostName() throws UnknownHostException {
InetAddress addr = InetAddress.getLocalHost();
return addr.getHostName();
return InetAddress.getLocalHost().getHostName();
}
}
Loading

0 comments on commit 6ebe335

Please sign in to comment.