Another warning hunting session (#4484)
* Another warning hunting session, focusing on Potential null pointer access Signed-off-by: Gaël L'hopital <gael@lhopital.org>pull/4541/head
parent
1e0b3c2410
commit
13eeea96e8
|
@ -82,11 +82,12 @@ public abstract class AbstractEvent implements Event {
|
|||
if (!payload.equals(other.payload)) {
|
||||
return false;
|
||||
}
|
||||
if (source == null) {
|
||||
String localSource = source;
|
||||
if (localSource == null) {
|
||||
if (other.source != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!source.equals(other.source)) {
|
||||
} else if (!localSource.equals(other.source)) {
|
||||
return false;
|
||||
}
|
||||
if (!topic.equals(other.topic)) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -98,13 +99,14 @@ abstract class AbstractInvocationHandler<T> {
|
|||
void handleException(Method method, InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
logger.error(MSG_ERROR, toString(method), target, cause == null ? "" : cause.getMessage(), e.getCause());
|
||||
if (exceptionHandler != null) {
|
||||
exceptionHandler.accept(cause == null ? e : cause);
|
||||
Consumer<Throwable> localConsumer = exceptionHandler;
|
||||
if (localConsumer != null) {
|
||||
localConsumer.accept(cause == null ? e : cause);
|
||||
}
|
||||
}
|
||||
|
||||
void handleDuplicate(Method method, DuplicateExecutionException e) {
|
||||
Thread thread = e.getCallable().getThread();
|
||||
Thread thread = Objects.requireNonNull(e.getCallable().getThread());
|
||||
logger.debug(MSG_DUPLICATE, toString(method), target, toString(e.getCallable().getMethod()), thread.getName(),
|
||||
thread.getId(), thread.getState().toString(), getStacktrace(thread));
|
||||
}
|
||||
|
|
|
@ -101,16 +101,15 @@ public class MetadataStateDescriptionFragmentProvider implements StateDescriptio
|
|||
builder.withReadOnly(getBoolean(readOnly));
|
||||
}
|
||||
|
||||
if (metadata.getConfiguration().containsKey("options")) {
|
||||
List<StateOption> stateOptions = Stream
|
||||
.of(metadata.getConfiguration().get("options").toString().split(",")).map(o -> {
|
||||
if (o.contains("=")) {
|
||||
var pair = parseValueLabelPair(o.trim());
|
||||
return new StateOption(pair[0], pair[1]);
|
||||
} else {
|
||||
return new StateOption(o.trim(), null);
|
||||
}
|
||||
}).toList();
|
||||
if (metadata.getConfiguration().get("options") instanceof Object options) {
|
||||
List<StateOption> stateOptions = Stream.of(options.toString().split(",")).map(o -> {
|
||||
if (o.contains("=")) {
|
||||
var pair = parseValueLabelPair(o.trim());
|
||||
return new StateOption(pair[0], pair[1]);
|
||||
} else {
|
||||
return new StateOption(o.trim(), null);
|
||||
}
|
||||
}).toList();
|
||||
builder.withOptions(stateOptions);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import tech.units.indriya.function.Calculus;
|
|||
*/
|
||||
@NonNullByDefault
|
||||
public class CurrencyConverter extends AbstractConverter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final BigDecimal factor;
|
||||
|
||||
|
@ -103,7 +104,7 @@ public class CurrencyConverter extends AbstractConverter {
|
|||
@SuppressWarnings("unchecked")
|
||||
Map<Class<? extends AbstractConverter>, Integer> original = (Map<Class<? extends AbstractConverter>, Integer>) field
|
||||
.get(null);
|
||||
original.put(CurrencyConverter.class, 1000);
|
||||
Objects.requireNonNull(original).put(CurrencyConverter.class, 1000);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new IllegalStateException("Could not add currency converter", e);
|
||||
}
|
||||
|
|
|
@ -206,8 +206,8 @@ public class SchedulerImpl implements Scheduler {
|
|||
exceptionally(e -> {
|
||||
synchronized (this) {
|
||||
if (e instanceof CancellationException) {
|
||||
if (scheduledPromise != null) {
|
||||
scheduledPromise.cancel(true);
|
||||
if (scheduledPromise instanceof ScheduledCompletableFuture promise) {
|
||||
promise.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public class SchedulerImpl implements Scheduler {
|
|||
future.cancel(true);
|
||||
} else {
|
||||
scheduledPromise = future;
|
||||
scheduledPromise.getPromise().exceptionally(ex -> {
|
||||
future.getPromise().exceptionally(ex -> {
|
||||
// if an error occurs in the scheduled job propagate to parent
|
||||
ScheduledCompletableFutureRecurring.this.completeExceptionally(ex);
|
||||
return null;
|
||||
|
@ -233,12 +233,13 @@ public class SchedulerImpl implements Scheduler {
|
|||
|
||||
@Override
|
||||
public long getDelay(@Nullable TimeUnit timeUnit) {
|
||||
return scheduledPromise != null ? scheduledPromise.getDelay(timeUnit) : 0;
|
||||
return scheduledPromise instanceof ScheduledCompletableFuture promise ? promise.getDelay(timeUnit) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime getScheduledTime() {
|
||||
return scheduledPromise != null ? scheduledPromise.getScheduledTime() : super.getScheduledTime();
|
||||
return scheduledPromise instanceof ScheduledCompletableFuture promise ? promise.getScheduledTime()
|
||||
: super.getScheduledTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.core.internal.service;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
@ -114,7 +115,7 @@ public class ReadyServiceImpl implements ReadyService {
|
|||
}
|
||||
|
||||
private void notifyTracker(ReadyTracker readyTracker, Consumer<ReadyMarker> action) {
|
||||
ReadyMarkerFilter f = trackers.get(readyTracker);
|
||||
ReadyMarkerFilter f = Objects.requireNonNull(trackers.get(readyTracker));
|
||||
markers.stream().filter(f::apply).forEach(action);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,7 +195,8 @@ public class StateDescriptionFragmentImpl implements StateDescriptionFragment {
|
|||
if (readOnly == null) {
|
||||
readOnly = fragment.isReadOnly();
|
||||
}
|
||||
if (options == null || options.isEmpty()) {
|
||||
List<StateOption> localOptions = options;
|
||||
if (localOptions == null || localOptions.isEmpty()) {
|
||||
options = fragment.getOptions();
|
||||
}
|
||||
return this;
|
||||
|
@ -205,12 +206,12 @@ public class StateDescriptionFragmentImpl implements StateDescriptionFragment {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (minimum != null ? minimum.hashCode() : 0);
|
||||
result = prime * result + (maximum != null ? maximum.hashCode() : 0);
|
||||
result = prime * result + (step != null ? step.hashCode() : 0);
|
||||
result = prime * result + (pattern != null ? pattern.hashCode() : 0);
|
||||
result = prime * result + Objects.hashCode(minimum);
|
||||
result = prime * result + Objects.hashCode(maximum);
|
||||
result = prime * result + Objects.hashCode(step);
|
||||
result = prime * result + Objects.hashCode(pattern);
|
||||
result = prime * result + (readOnly ? 1231 : 1237);
|
||||
result = prime * result + (options != null ? options.hashCode() : 0);
|
||||
result = prime * result + Objects.hashCode(options);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -192,8 +192,8 @@ public abstract class GenericItem implements ActiveItem {
|
|||
|
||||
protected void internalSend(Command command) {
|
||||
// try to send the command to the bus
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.post(ItemEventFactory.createCommandEvent(this.getName(), command));
|
||||
if (eventPublisher instanceof EventPublisher publisher) {
|
||||
publisher.post(ItemEventFactory.createCommandEvent(this.getName(), command));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,8 +456,8 @@ public abstract class GenericItem implements ActiveItem {
|
|||
|
||||
@Override
|
||||
public @Nullable StateDescription getStateDescription(@Nullable Locale locale) {
|
||||
if (stateDescriptionService != null) {
|
||||
return stateDescriptionService.getStateDescription(this.name, locale);
|
||||
if (stateDescriptionService instanceof StateDescriptionService service) {
|
||||
return service.getStateDescription(this.name, locale);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -499,8 +499,8 @@ public abstract class GenericItem implements ActiveItem {
|
|||
}
|
||||
|
||||
protected @Nullable CommandDescription getCommandOptions(@Nullable Locale locale) {
|
||||
if (commandDescriptionService != null) {
|
||||
CommandDescription commandDescription = commandDescriptionService.getCommandDescription(this.name, locale);
|
||||
if (commandDescriptionService instanceof CommandDescriptionService service) {
|
||||
CommandDescription commandDescription = service.getCommandDescription(this.name, locale);
|
||||
if (commandDescription != null) {
|
||||
return commandDescription;
|
||||
}
|
||||
|
|
|
@ -224,8 +224,8 @@ public class GroupItem extends GenericItem implements StateChangeListener, Metad
|
|||
*/
|
||||
@Override
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
if (baseItem != null) {
|
||||
return baseItem.getAcceptedDataTypes();
|
||||
if (baseItem instanceof Item item) {
|
||||
return item.getAcceptedDataTypes();
|
||||
} else {
|
||||
List<Class<? extends State>> acceptedDataTypes = null;
|
||||
|
||||
|
@ -249,8 +249,8 @@ public class GroupItem extends GenericItem implements StateChangeListener, Metad
|
|||
*/
|
||||
@Override
|
||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
||||
if (baseItem != null) {
|
||||
return baseItem.getAcceptedCommandTypes();
|
||||
if (baseItem instanceof Item item) {
|
||||
return item.getAcceptedCommandTypes();
|
||||
} else {
|
||||
List<Class<? extends Command>> acceptedCommandTypes = null;
|
||||
|
||||
|
@ -289,8 +289,8 @@ public class GroupItem extends GenericItem implements StateChangeListener, Metad
|
|||
// if a group does not have a function it cannot have a state
|
||||
@Nullable
|
||||
T newState = null;
|
||||
if (function != null) {
|
||||
newState = function.getStateAs(getStateMembers(getMembers()), typeClass);
|
||||
if (function instanceof GroupFunction groupFunction) {
|
||||
newState = groupFunction.getStateAs(getStateMembers(getMembers()), typeClass);
|
||||
}
|
||||
|
||||
Item baseItem = this.baseItem;
|
||||
|
@ -354,8 +354,8 @@ public class GroupItem extends GenericItem implements StateChangeListener, Metad
|
|||
State oldState = this.state;
|
||||
State newState = oldState;
|
||||
ItemStateConverter itemStateConverter = this.itemStateConverter;
|
||||
if (function != null && baseItem != null && itemStateConverter != null) {
|
||||
State calculatedState = function.calculate(getStateMembers(getMembers()));
|
||||
if (function instanceof GroupFunction groupFunction && baseItem != null && itemStateConverter != null) {
|
||||
State calculatedState = groupFunction.calculate(getStateMembers(getMembers()));
|
||||
newState = itemStateConverter.convertToAcceptedState(calculatedState, baseItem);
|
||||
setState(newState);
|
||||
sendGroupStateUpdatedEvent(item.getName(), newState);
|
||||
|
|
|
@ -252,8 +252,8 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
private GroupFunction getGroupFunction(PersistedItem persistedItem, @Nullable Item baseItem) {
|
||||
GroupFunctionDTO functionDTO = new GroupFunctionDTO();
|
||||
functionDTO.name = persistedItem.functionName;
|
||||
if (persistedItem.functionParams != null) {
|
||||
functionDTO.params = persistedItem.functionParams.toArray(new String[persistedItem.functionParams.size()]);
|
||||
if (persistedItem.functionParams instanceof List<?> list) {
|
||||
functionDTO.params = list.toArray(new String[list.size()]);
|
||||
}
|
||||
return ItemDTOMapper.mapFunction(baseItem, functionDTO);
|
||||
}
|
||||
|
|
|
@ -147,12 +147,14 @@ public interface QuantityTypeArithmeticGroupFunction extends GroupFunction {
|
|||
if (unit == null) {
|
||||
unit = itemState.getUnit(); // set it to the first item's unit
|
||||
}
|
||||
values.add(itemState.toInvertibleUnit(unit).toBigDecimal());
|
||||
if (itemState.toInvertibleUnit(unit) instanceof QuantityType<?> inverted) {
|
||||
values.add(inverted.toBigDecimal());
|
||||
}
|
||||
}
|
||||
|
||||
if (!values.isEmpty()) {
|
||||
BigDecimal median = Statistics.median(values);
|
||||
if (median != null) {
|
||||
if (median != null && unit != null) {
|
||||
return new QuantityType<>(median, unit);
|
||||
}
|
||||
|
||||
|
|
|
@ -176,8 +176,8 @@ public final class CurrencyUnit extends AbstractUnit<Currency> {
|
|||
return nameCompare;
|
||||
}
|
||||
String thatSymbol = that.getSymbol();
|
||||
if (symbol != null && thatSymbol != null) {
|
||||
return symbol.compareTo(thatSymbol);
|
||||
if (symbol instanceof String localSymbol && thatSymbol != null) {
|
||||
return localSymbol.compareTo(thatSymbol);
|
||||
} else if (symbol != null) {
|
||||
return 1;
|
||||
} else if (thatSymbol != null) {
|
||||
|
|
|
@ -111,8 +111,8 @@ public class NetUtil implements NetworkAddressService {
|
|||
lastKnownInterfaceAddresses = List.of();
|
||||
networkAddressChangeListeners = ConcurrentHashMap.newKeySet();
|
||||
|
||||
if (networkInterfacePollFuture != null) {
|
||||
networkInterfacePollFuture.cancel(true);
|
||||
if (networkInterfacePollFuture instanceof ScheduledFuture<?> future) {
|
||||
future.cancel(true);
|
||||
networkInterfacePollFuture = null;
|
||||
}
|
||||
}
|
||||
|
@ -159,13 +159,13 @@ public class NetUtil implements NetworkAddressService {
|
|||
public @Nullable String getPrimaryIpv4HostAddress() {
|
||||
String primaryIP;
|
||||
|
||||
if (primaryAddress != null) {
|
||||
String[] addrString = primaryAddress.split("/");
|
||||
if (primaryAddress instanceof String address) {
|
||||
String[] addrString = address.split("/");
|
||||
if (addrString.length > 1) {
|
||||
String ip = getIPv4inSubnet(addrString[0], addrString[1]);
|
||||
if (ip == null) {
|
||||
// an error has occurred, using first interface like nothing has been configured
|
||||
LOGGER.warn("Invalid address '{}', will use first interface instead.", primaryAddress);
|
||||
LOGGER.warn("Invalid address '{}', will use first interface instead.", address);
|
||||
primaryIP = getFirstLocalIPv4Address();
|
||||
} else {
|
||||
primaryIP = ip;
|
||||
|
@ -513,8 +513,8 @@ public class NetUtil implements NetworkAddressService {
|
|||
}
|
||||
|
||||
private void scheduleToPollNetworkInterface(int intervalInSeconds) {
|
||||
if (networkInterfacePollFuture != null) {
|
||||
networkInterfacePollFuture.cancel(true);
|
||||
if (networkInterfacePollFuture instanceof ScheduledFuture<?> future) {
|
||||
future.cancel(true);
|
||||
networkInterfacePollFuture = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public class CommandOption {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + command.hashCode();
|
||||
result = prime * result + (label != null ? label.hashCode() : 0);
|
||||
result = prime * result + Objects.hashCode(label);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,10 +116,10 @@ public class StateDescription {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (minimum != null ? minimum.hashCode() : 0);
|
||||
result = prime * result + (maximum != null ? maximum.hashCode() : 0);
|
||||
result = prime * result + (step != null ? step.hashCode() : 0);
|
||||
result = prime * result + (pattern != null ? pattern.hashCode() : 0);
|
||||
result = prime * result + Objects.hashCode(minimum);
|
||||
result = prime * result + Objects.hashCode(maximum);
|
||||
result = prime * result + Objects.hashCode(step);
|
||||
result = prime * result + Objects.hashCode(pattern);
|
||||
result = prime * result + (readOnly ? 1231 : 1237);
|
||||
result = prime * result + options.hashCode();
|
||||
return result;
|
||||
|
|
|
@ -62,7 +62,7 @@ public final class StateOption {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + value.hashCode();
|
||||
result = prime * result + (label != null ? label.hashCode() : 0);
|
||||
result = prime * result + Objects.hashCode(label);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue