Some non null annotations (#4486)

Signed-off-by: Gaël L'hopital <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital
2025-02-09 14:55:45 +01:00
committed by GitHub
parent d3cfba562b
commit 94bd3fcf7c
14 changed files with 82 additions and 55 deletions
@@ -83,7 +83,7 @@ public class SystemProfileFactory implements ProfileFactory, ProfileAdvisor, Pro
private final Map<LocalizedKey, ProfileType> localizedProfileTypeCache = new ConcurrentHashMap<>(); private final Map<LocalizedKey, ProfileType> localizedProfileTypeCache = new ConcurrentHashMap<>();
private final ProfileTypeI18nLocalizationService profileTypeI18nLocalizationService; private final ProfileTypeI18nLocalizationService profileTypeI18nLocalizationService;
private final Bundle bundle; private final @Nullable Bundle bundle;
@Activate @Activate
public SystemProfileFactory(final @Reference ChannelTypeRegistry channelTypeRegistry, public SystemProfileFactory(final @Reference ChannelTypeRegistry channelTypeRegistry,
@@ -236,13 +236,12 @@ public class SystemProfileFactory implements ProfileFactory, ProfileAdvisor, Pro
return cachedEntry; return cachedEntry;
} }
ProfileType localizedProfileType = profileTypeI18nLocalizationService.createLocalizedProfileType(bundle, if (bundle instanceof Bundle localBundle) {
profileType, locale); ProfileType localizedProfileType = profileTypeI18nLocalizationService
if (localizedProfileType != null) { .createLocalizedProfileType(localBundle, profileType, locale);
localizedProfileTypeCache.put(localizedKey, localizedProfileType); localizedProfileTypeCache.put(localizedKey, localizedProfileType);
return localizedProfileType; return localizedProfileType;
} else {
return profileType;
} }
return profileType;
} }
} }
@@ -45,13 +45,13 @@ public class ProfileI18nUtil {
this.i18nProvider = i18nProvider; this.i18nProvider = i18nProvider;
} }
public @Nullable String getProfileLabel(Bundle bundle, ProfileTypeUID profileTypeUID, String defaultLabel, public @Nullable String getProfileLabel(@Nullable Bundle bundle, ProfileTypeUID profileTypeUID, String defaultLabel,
@Nullable Locale locale) { @Nullable Locale locale) {
String key = I18nUtil.stripConstantOr(defaultLabel, () -> inferProfileTypeKey(profileTypeUID, "label")); String key = I18nUtil.stripConstantOr(defaultLabel, () -> inferProfileTypeKey(profileTypeUID, "label"));
return i18nProvider.getText(bundle, key, defaultLabel, locale); return i18nProvider.getText(bundle, key, defaultLabel, locale);
} }
private String inferProfileTypeKey(ProfileTypeUID profileTypeUID, String lastSegment) { private String inferProfileTypeKey(ProfileTypeUID profileTypeUID, String lastSegment) {
return "profile-type." + profileTypeUID.getBindingId() + "." + profileTypeUID.getId() + "." + lastSegment; return "profile-type.%s.%s.%s".formatted(profileTypeUID.getBindingId(), profileTypeUID.getId(), lastSegment);
} }
} }
@@ -44,21 +44,24 @@ public class ProfileTypeI18nLocalizationService {
this.profileI18nUtil = new ProfileI18nUtil(i18nProvider); this.profileI18nUtil = new ProfileI18nUtil(i18nProvider);
} }
public ProfileType createLocalizedProfileType(Bundle bundle, ProfileType profileType, @Nullable Locale locale) { public ProfileType createLocalizedProfileType(@Nullable Bundle bundle, ProfileType profileType,
@Nullable Locale locale) {
ProfileTypeUID profileTypeUID = profileType.getUID(); ProfileTypeUID profileTypeUID = profileType.getUID();
String defaultLabel = profileType.getLabel(); String defaultLabel = profileType.getLabel();
String label = profileI18nUtil.getProfileLabel(bundle, profileTypeUID, defaultLabel, locale); if (bundle != null) {
String label = profileI18nUtil.getProfileLabel(bundle, profileTypeUID, defaultLabel, locale);
label = label != null ? label : defaultLabel;
if (profileType instanceof StateProfileType type) { if (profileType instanceof StateProfileType type) {
return ProfileTypeBuilder.newState(profileTypeUID, label != null ? label : defaultLabel) return ProfileTypeBuilder.newState(profileTypeUID, label)
.withSupportedItemTypes(profileType.getSupportedItemTypes()) .withSupportedItemTypes(profileType.getSupportedItemTypes())
.withSupportedItemTypesOfChannel(type.getSupportedItemTypesOfChannel()).build(); .withSupportedItemTypesOfChannel(type.getSupportedItemTypesOfChannel()).build();
} else if (profileType instanceof TriggerProfileType type) { } else if (profileType instanceof TriggerProfileType type) {
return ProfileTypeBuilder.newTrigger(profileTypeUID, label != null ? label : defaultLabel) return ProfileTypeBuilder.newTrigger(profileTypeUID, label)
.withSupportedItemTypes(profileType.getSupportedItemTypes()) .withSupportedItemTypes(profileType.getSupportedItemTypes())
.withSupportedChannelTypeUIDs(type.getSupportedChannelTypeUIDs()).build(); .withSupportedChannelTypeUIDs(type.getSupportedChannelTypeUIDs()).build();
} else { }
return profileType;
} }
return profileType;
} }
} }
@@ -12,6 +12,8 @@
*/ */
package org.openhab.core; package org.openhab.core;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.osgi.annotation.bundle.Header; import org.osgi.annotation.bundle.Header;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
@@ -25,17 +27,18 @@ import org.slf4j.LoggerFactory;
* @author Jan N. Klug - Initial contribution * @author Jan N. Klug - Initial contribution
*/ */
@Header(name = Constants.BUNDLE_ACTIVATOR, value = "${@class}") @Header(name = Constants.BUNDLE_ACTIVATOR, value = "${@class}")
@NonNullByDefault
public final class Activator implements BundleActivator { public final class Activator implements BundleActivator {
private final Logger logger = LoggerFactory.getLogger(Activator.class); private final Logger logger = LoggerFactory.getLogger(Activator.class);
@Override @Override
public void start(BundleContext bc) throws Exception { public void start(@Nullable BundleContext bc) throws Exception {
logger.info("Starting openHAB {} ({})", OpenHAB.getVersion(), OpenHAB.buildString()); logger.info("Starting openHAB {} ({})", OpenHAB.getVersion(), OpenHAB.buildString());
} }
@Override @Override
public void stop(BundleContext context) throws Exception { public void stop(@Nullable BundleContext context) throws Exception {
// do nothing // do nothing
} }
} }
@@ -55,7 +55,7 @@ public class OpenHAB {
/** the service pid used for the definition of the base package and add-ons */ /** the service pid used for the definition of the base package and add-ons */
public static final String ADDONS_SERVICE_PID = "org.openhab.addons"; public static final String ADDONS_SERVICE_PID = "org.openhab.addons";
/** the configuraton parameter name used for the base package */ /** the configuration parameter name used for the base package */
public static final String CFG_PACKAGE = "package"; public static final String CFG_PACKAGE = "package";
/** /**
@@ -26,6 +26,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
/** /**
@@ -38,6 +40,7 @@ import org.osgi.framework.Bundle;
* @author Martin Herbst - UTF-8 replaced by ISO-8859-1 to follow Java standards * @author Martin Herbst - UTF-8 replaced by ISO-8859-1 to follow Java standards
* *
*/ */
@NonNullByDefault
public class ResourceBundleClassLoader extends ClassLoader { public class ResourceBundleClassLoader extends ClassLoader {
private Bundle bundle; private Bundle bundle;
@@ -56,18 +59,19 @@ public class ResourceBundleClassLoader extends ClassLoader {
* considered. * considered.
* @throws IllegalArgumentException if the bundle is null * @throws IllegalArgumentException if the bundle is null
*/ */
public ResourceBundleClassLoader(Bundle bundle, String path, String filePattern) throws IllegalArgumentException { public ResourceBundleClassLoader(@Nullable Bundle bundle, @Nullable String path, @Nullable String filePattern)
throws IllegalArgumentException {
if (bundle == null) { if (bundle == null) {
throw new IllegalArgumentException("The bundle must not be null!"); throw new IllegalArgumentException("The bundle must not be null!");
} }
this.bundle = bundle; this.bundle = bundle;
this.path = (path != null) ? path : "/"; this.path = path != null ? path : "/";
this.filePattern = (filePattern != null) ? filePattern : "*"; this.filePattern = filePattern != null ? filePattern : "*";
} }
@Override @Override
public URL getResource(String name) { public @Nullable URL getResource(String name) {
Enumeration<URL> resourceFiles = this.bundle.findEntries(this.path, this.filePattern, true); Enumeration<URL> resourceFiles = this.bundle.findEntries(this.path, this.filePattern, true);
List<URL> allResources = new LinkedList<>(); List<URL> allResources = new LinkedList<>();
@@ -106,7 +110,7 @@ public class ResourceBundleClassLoader extends ClassLoader {
} }
@Override @Override
public InputStream getResourceAsStream(String name) { public @Nullable InputStream getResourceAsStream(String name) {
URL resourceURL = getResource(name); URL resourceURL = getResource(name);
if (resourceURL != null) { if (resourceURL != null) {
try (InputStream resourceStream = resourceURL.openStream()) { try (InputStream resourceStream = resourceURL.openStream()) {
@@ -18,6 +18,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -31,6 +33,7 @@ import org.slf4j.LoggerFactory;
* *
* @author Hilbrand Bouwkamp - Initial contribution * @author Hilbrand Bouwkamp - Initial contribution
*/ */
@NonNullByDefault
public class WrappedScheduledExecutorService extends ScheduledThreadPoolExecutor { public class WrappedScheduledExecutorService extends ScheduledThreadPoolExecutor {
final Logger logger = LoggerFactory.getLogger(WrappedScheduledExecutorService.class); final Logger logger = LoggerFactory.getLogger(WrappedScheduledExecutorService.class);
@@ -40,7 +43,7 @@ public class WrappedScheduledExecutorService extends ScheduledThreadPoolExecutor
} }
@Override @Override
protected void afterExecute(Runnable r, Throwable t) { protected void afterExecute(@Nullable Runnable r, @Nullable Throwable t) {
super.afterExecute(r, t); super.afterExecute(r, t);
Throwable actualThrowable = t; Throwable actualThrowable = t;
if (actualThrowable == null && r instanceof Future<?> f) { if (actualThrowable == null && r instanceof Future<?> f) {
@@ -18,9 +18,12 @@ import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.ResourceBundle.Control; import java.util.ResourceBundle.Control;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.osgi.ResourceBundleClassLoader; import org.openhab.core.common.osgi.ResourceBundleClassLoader;
import org.openhab.core.i18n.LocaleProvider; import org.openhab.core.i18n.LocaleProvider;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
@@ -37,6 +40,7 @@ import org.osgi.framework.Bundle;
* @author Michael Grammling - Initial contribution * @author Michael Grammling - Initial contribution
* @author Markus Rathgeb - Add locale provider support * @author Markus Rathgeb - Add locale provider support
*/ */
@NonNullByDefault
public class LanguageResourceBundleManager { public class LanguageResourceBundleManager {
/** The directory within the bundle where the resource files are searched. */ /** The directory within the bundle where the resource files are searched. */
@@ -50,7 +54,7 @@ public class LanguageResourceBundleManager {
private ClassLoader resourceClassLoader; private ClassLoader resourceClassLoader;
private List<String> resourceNames; private List<String> resourceNames;
public LanguageResourceBundleManager(LocaleProvider localeProvider, Bundle bundle) { public LanguageResourceBundleManager(LocaleProvider localeProvider, @Nullable Bundle bundle) {
if (bundle == null) { if (bundle == null) {
throw new IllegalArgumentException("The Bundle must not be null!"); throw new IllegalArgumentException("The Bundle must not be null!");
} }
@@ -80,7 +84,7 @@ public class LanguageResourceBundleManager {
* @param resource the resource to check (could be null or empty) * @param resource the resource to check (could be null or empty)
* @return true if the specified resource is managed by this instance, otherwise false * @return true if the specified resource is managed by this instance, otherwise false
*/ */
public boolean containsResource(String resource) { public boolean containsResource(@Nullable String resource) {
if (resource != null) { if (resource != null) {
return this.resourceNames.contains(resource); return this.resourceNames.contains(resource);
} }
@@ -135,7 +139,7 @@ public class LanguageResourceBundleManager {
* *
* @return the translated text, or null if the key could not be translated * @return the translated text, or null if the key could not be translated
*/ */
public String getText(String resource, String key, Locale locale) { public @Nullable String getText(@Nullable String resource, @Nullable String key, @Nullable Locale locale) {
if ((key != null) && (!key.isEmpty())) { if ((key != null) && (!key.isEmpty())) {
Locale effectiveLocale = locale != null ? locale : localeProvider.getLocale(); Locale effectiveLocale = locale != null ? locale : localeProvider.getLocale();
@@ -167,27 +171,29 @@ public class LanguageResourceBundleManager {
* *
* @return the translated text, or null if the key could not be translated * @return the translated text, or null if the key could not be translated
*/ */
public String getText(String key, Locale locale) { public @Nullable String getText(@Nullable String key, @Nullable Locale locale) {
return getText(null, key, locale); return getText(null, key, locale);
} }
private String getTranslatedText(String resourceName, String key, Locale locale) { private @Nullable String getTranslatedText(@Nullable String resourceName, @Nullable String key,
try { @Nullable Locale locale) {
// Modify the search order so that the following applies: if (resourceName != null && locale != null && key != null && !key.isEmpty()) {
// 1.) baseName + "_" + language + "_" + country try {
// 2.) baseName + "_" + language // Modify the search order so that the following applies:
// 3.) baseName // 1.) baseName + "_" + language + "_" + country
// 4.) null -> leads to a default text // 2.) baseName + "_" + language
// Not using the default fallback strategy helps that not the default locale // 3.) baseName
// search order is applied between 2.) and 3.). // 4.) null -> leads to a default text
ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceName, locale, this.resourceClassLoader, // Not using the default fallback strategy helps that not the default locale
Control.getNoFallbackControl(Control.FORMAT_PROPERTIES)); // search order is applied between 2.) and 3.).
ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceName, locale, this.resourceClassLoader,
Control.getNoFallbackControl(Control.FORMAT_PROPERTIES));
return resourceBundle.getString(key); return resourceBundle.getString(key);
} catch (Exception ex) { } catch (NullPointerException | IllegalArgumentException | MissingResourceException ex) {
// nothing to do // nothing to do
}
} }
return null; return null;
} }
} }
@@ -12,6 +12,8 @@
*/ */
package org.openhab.core.internal.service; package org.openhab.core.internal.service;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.util.BundleResolver; import org.openhab.core.util.BundleResolver;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil; import org.osgi.framework.FrameworkUtil;
@@ -23,9 +25,11 @@ import org.osgi.service.component.annotations.Component;
* @author Henning Treu - Initial contribution * @author Henning Treu - Initial contribution
*/ */
@Component(service = BundleResolver.class) @Component(service = BundleResolver.class)
@NonNullByDefault
public class BundleResolverImpl implements BundleResolver { public class BundleResolverImpl implements BundleResolver {
@Override @Override
@Nullable
public Bundle resolveBundle(Class<?> clazz) { public Bundle resolveBundle(Class<?> clazz) {
return FrameworkUtil.getBundle(clazz); return FrameworkUtil.getBundle(clazz);
} }
@@ -12,6 +12,8 @@
*/ */
package org.openhab.core.util; package org.openhab.core.util;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
/** /**
@@ -19,6 +21,7 @@ import org.osgi.framework.Bundle;
* *
* @author Henning Treu - Initial contribution * @author Henning Treu - Initial contribution
*/ */
@NonNullByDefault
public interface BundleResolver { public interface BundleResolver {
/** /**
@@ -27,5 +30,6 @@ public interface BundleResolver {
* @param clazz the {@link Class} to resolve the bundle for. * @param clazz the {@link Class} to resolve the bundle for.
* @return the bundle associated with the given {@link Class}. * @return the bundle associated with the given {@link Class}.
*/ */
@Nullable
Bundle resolveBundle(Class<?> clazz); Bundle resolveBundle(Class<?> clazz);
} }
@@ -15,6 +15,7 @@ package org.openhab.core.thing.i18n;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.io.IOException; import java.io.IOException;
@@ -328,7 +329,7 @@ public class ThingStatusInfoI18nLocalizationServiceOSGiTest extends JavaOSGiTest
*/ */
private class BundleResolverImpl implements BundleResolver { private class BundleResolverImpl implements BundleResolver {
@Override @Override
public Bundle resolveBundle(@Nullable Class<?> clazz) { public @Nullable Bundle resolveBundle(@Nullable Class<?> clazz) {
if (clazz != null && clazz.equals(AbstractThingHandler.class)) { if (clazz != null && clazz.equals(AbstractThingHandler.class)) {
return testBundle; return testBundle;
} else { } else {
@@ -387,8 +387,8 @@ public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
*/ */
private class BundleResolverImpl implements BundleResolver { private class BundleResolverImpl implements BundleResolver {
@Override @Override
public Bundle resolveBundle(@NonNullByDefault({}) Class<?> clazz) { public @Nullable Bundle resolveBundle(@NonNullByDefault({}) Class<?> clazz) {
if (clazz != null && clazz.equals(AbstractThingHandler.class)) { if (clazz.equals(AbstractThingHandler.class)) {
return testBundle; return testBundle;
} else { } else {
return FrameworkUtil.getBundle(clazz); return FrameworkUtil.getBundle(clazz);
@@ -512,7 +512,7 @@ public class ChannelStateDescriptionProviderOSGiTest extends JavaOSGiTest {
*/ */
private class BundleResolverImpl implements BundleResolver { private class BundleResolverImpl implements BundleResolver {
@Override @Override
public Bundle resolveBundle(@Nullable Class<?> clazz) { public @Nullable Bundle resolveBundle(@Nullable Class<?> clazz) {
if (clazz != null && clazz.equals(AbstractThingHandler.class)) { if (clazz != null && clazz.equals(AbstractThingHandler.class)) {
return testBundle; return testBundle;
} else { } else {
@@ -14,7 +14,7 @@ package org.openhab.core.thing.internal.update;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.openhab.core.thing.internal.ThingManagerImpl.PROPERTY_THING_TYPE_VERSION; import static org.openhab.core.thing.internal.ThingManagerImpl.PROPERTY_THING_TYPE_VERSION;
@@ -405,9 +405,9 @@ public class ThingUpdateOSGiTest extends JavaOSGiTest {
private class BundleResolverImpl implements BundleResolver { private class BundleResolverImpl implements BundleResolver {
@Override @Override
public Bundle resolveBundle(@NonNullByDefault({}) Class<?> clazz) { public @Nullable Bundle resolveBundle(@NonNullByDefault({}) Class<?> clazz) {
// return the test bundle if the class is TestThingHandlerFactory // return the test bundle if the class is TestThingHandlerFactory
if (clazz != null && clazz.equals(TestThingHandlerFactory.class)) { if (clazz.equals(TestThingHandlerFactory.class)) {
return testBundle; return testBundle;
} else { } else {
return FrameworkUtil.getBundle(clazz); return FrameworkUtil.getBundle(clazz);