Avoid a hidden NPE when getIdentifier() of an uninitialized ThingHandler is called (#9043)

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2020-11-16 21:26:14 +01:00 committed by GitHub
parent 06e30201e9
commit a6dd8ecba2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 41 deletions

View File

@ -20,7 +20,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@ -271,10 +270,8 @@ public abstract class AVMFritzBaseBridgeHandler extends BaseBridgeHandler {
getThing().getThings().forEach(childThing -> {
final AVMFritzBaseThingHandler childHandler = (AVMFritzBaseThingHandler) childThing.getHandler();
if (childHandler != null) {
final Optional<AVMFritzBaseModel> optionalDevice = Optional
.ofNullable(deviceIdentifierMap.get(childHandler.getIdentifier()));
if (optionalDevice.isPresent()) {
final AVMFritzBaseModel device = optionalDevice.get();
final AVMFritzBaseModel device = deviceIdentifierMap.get(childHandler.getIdentifier());
if (device != null) {
deviceList.remove(device);
listeners.forEach(listener -> listener.onDeviceUpdated(childThing.getUID(), device));
} else {

View File

@ -82,7 +82,7 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
* keeps track of the current state for handling of increase/decrease
*/
private @Nullable AVMFritzBaseModel state;
private @NonNullByDefault({}) AVMFritzDeviceConfiguration config;
private @Nullable String identifier;
/**
* Constructor
@ -95,13 +95,13 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
@Override
public void initialize() {
config = getConfigAs(AVMFritzDeviceConfiguration.class);
String newIdentifier = config.ain;
final AVMFritzDeviceConfiguration config = getConfigAs(AVMFritzDeviceConfiguration.class);
final String newIdentifier = config.ain;
if (newIdentifier == null || newIdentifier.trim().isEmpty()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"The 'ain' parameter must be configured.");
} else {
this.identifier = newIdentifier;
updateStatus(ThingStatus.UNKNOWN);
}
}
@ -472,6 +472,6 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
* @return the AIN
*/
public @Nullable String getIdentifier() {
return config.ain;
return identifier;
}
}

View File

@ -23,7 +23,6 @@ import java.util.function.Predicate;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.OpenClosedType;
import org.eclipse.smarthome.core.library.types.QuantityType;
@ -72,7 +71,7 @@ public class Powerline546EHandler extends AVMFritzBaseBridgeHandler implements F
* keeps track of the current state for handling of increase/decrease
*/
private @Nullable AVMFritzBaseModel state;
private @Nullable AVMFritzDeviceConfiguration config;
private @Nullable String identifier;
/**
* Constructor
@ -86,32 +85,28 @@ public class Powerline546EHandler extends AVMFritzBaseBridgeHandler implements F
@Override
public void initialize() {
config = getConfigAs(AVMFritzDeviceConfiguration.class);
final AVMFritzDeviceConfiguration config = getConfigAs(AVMFritzDeviceConfiguration.class);
final String newIdentifier = config.ain;
registerStatusListener(this);
if (newIdentifier != null && !newIdentifier.trim().isEmpty()) {
this.identifier = newIdentifier;
}
super.initialize();
}
@Override
public void dispose() {
unregisterStatusListener(this);
super.dispose();
}
@Override
public void onDeviceListAdded(List<AVMFritzBaseModel> devicelist) {
final String identifier = getIdentifier();
final Predicate<AVMFritzBaseModel> predicate = identifier == null ? it -> thing.getUID().equals(getThingUID(it))
: it -> identifier.equals(it.getIdentifier());
final String ain = getIdentifier();
final Predicate<AVMFritzBaseModel> predicate = ain == null ? it -> thing.getUID().equals(getThingUID(it))
: it -> ain.equals(it.getIdentifier());
final Optional<AVMFritzBaseModel> optionalDevice = devicelist.stream().filter(predicate).findFirst();
if (optionalDevice.isPresent()) {
final AVMFritzBaseModel device = optionalDevice.get();
devicelist.remove(device);
listeners.stream().forEach(listener -> listener.onDeviceUpdated(thing.getUID(), device));
onDeviceUpdated(thing.getUID(), device);
} else {
listeners.stream().forEach(listener -> listener.onDeviceGone(thing.getUID()));
onDeviceGone(thing.getUID());
}
super.onDeviceListAdded(devicelist);
}
@ -125,8 +120,8 @@ public class Powerline546EHandler extends AVMFritzBaseBridgeHandler implements F
public void onDeviceUpdated(ThingUID thingUID, AVMFritzBaseModel device) {
if (thing.getUID().equals(thingUID)) {
// save AIN to config for FRITZ!Powerline 546E stand-alone
if (config == null) {
updateConfiguration(device);
if (this.identifier == null) {
this.identifier = device.getIdentifier();
}
logger.debug("Update self '{}' with device model: {}", thingUID, device);
@ -185,17 +180,6 @@ public class Powerline546EHandler extends AVMFritzBaseBridgeHandler implements F
updateProperties(editProperties);
}
/**
* Updates thing configuration.
*
* @param device the {@link AVMFritzBaseModel}
*/
private void updateConfiguration(AVMFritzBaseModel device) {
Configuration editConfig = editConfiguration();
editConfig.put(CONFIG_AIN, device.getIdentifier());
updateConfiguration(editConfig);
}
/**
* Updates thing channels and creates dynamic channels if missing.
*
@ -311,7 +295,6 @@ public class Powerline546EHandler extends AVMFritzBaseBridgeHandler implements F
* @return the AIN
*/
public @Nullable String getIdentifier() {
AVMFritzDeviceConfiguration localConfig = config;
return localConfig != null ? localConfig.ain : null;
return identifier;
}
}