Add and fix more null annotations (#1421)

Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
Wouter Born 2020-04-15 01:44:37 +02:00 committed by GitHub
parent b770bb1b4a
commit 6c85b1bccd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 143 additions and 181 deletions

View File

@ -22,6 +22,8 @@ import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.Action; import org.openhab.core.automation.Action;
import org.openhab.core.automation.Condition; import org.openhab.core.automation.Condition;
import org.openhab.core.automation.Module; import org.openhab.core.automation.Module;
@ -43,6 +45,7 @@ import org.openhab.core.automation.type.TriggerType;
* @author Benedikt Niehues - validation of connection-types respects inheriting types * @author Benedikt Niehues - validation of connection-types respects inheriting types
* @author Ana Dimova - new reference syntax: list[index], map["key"], bean.field * @author Ana Dimova - new reference syntax: list[index], map["key"], bean.field
*/ */
@NonNullByDefault
public class ConnectionValidator { public class ConnectionValidator {
public static final String CONFIG_REFERENCE_PATTERN = "\\${1}\\{{1}[A-Za-z0-9_-]+\\}{1}|\\${1}[A-Za-z0-9_-]+"; public static final String CONFIG_REFERENCE_PATTERN = "\\${1}\\{{1}[A-Za-z0-9_-]+\\}{1}|\\${1}[A-Za-z0-9_-]+";
@ -58,9 +61,6 @@ public class ConnectionValidator {
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
public static void validateConnections(ModuleTypeRegistry mtRegistry, Rule r) { public static void validateConnections(ModuleTypeRegistry mtRegistry, Rule r) {
if (r == null) {
throw new IllegalArgumentException("Validation of rule has failed! Rule must not be null!");
}
validateConnections(mtRegistry, r.getTriggers(), r.getConditions(), r.getActions()); validateConnections(mtRegistry, r.getTriggers(), r.getConditions(), r.getActions());
} }
@ -74,9 +74,8 @@ public class ConnectionValidator {
* @param actions is a list with actions of the rule whose connections have to be validated * @param actions is a list with actions of the rule whose connections have to be validated
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
public static void validateConnections(ModuleTypeRegistry mtRegistry, public static void validateConnections(ModuleTypeRegistry mtRegistry, List<? extends @NonNull Trigger> triggers,
@NonNull List<? extends @NonNull Trigger> triggers, @NonNull List<? extends @NonNull Condition> conditions, List<? extends @NonNull Condition> conditions, List<? extends @NonNull Action> actions) {
@NonNull List<? extends @NonNull Action> actions) {
if (!triggers.isEmpty()) { if (!triggers.isEmpty()) {
for (Condition condition : conditions) { for (Condition condition : conditions) {
validateConditionConnections(mtRegistry, condition, triggers); validateConditionConnections(mtRegistry, condition, triggers);
@ -100,7 +99,7 @@ public class ConnectionValidator {
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
private static void validateActionConnections(ModuleTypeRegistry mtRegistry, Action action, private static void validateActionConnections(ModuleTypeRegistry mtRegistry, Action action,
@NonNull List<? extends @NonNull Trigger> triggers, @NonNull List<? extends @NonNull Action> actions) { List<? extends @NonNull Trigger> triggers, List<? extends @NonNull Action> actions) {
ActionType type = (ActionType) mtRegistry.get(action.getTypeUID()); // get module type of the condition ActionType type = (ActionType) mtRegistry.get(action.getTypeUID()); // get module type of the condition
if (type == null) { if (type == null) {
// if module type not exists in the system - throws exception // if module type not exists in the system - throws exception
@ -146,7 +145,7 @@ public class ConnectionValidator {
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
private static void checkConnection(ModuleTypeRegistry mtRegistry, Connection connection, Input input, private static void checkConnection(ModuleTypeRegistry mtRegistry, Connection connection, Input input,
@NonNull List<? extends @NonNull Trigger> triggers, @NonNull List<? extends @NonNull Action> actions) { List<? extends @NonNull Trigger> triggers, List<? extends @NonNull Action> actions) {
Map<String, Action> actionsMap = new HashMap<>(); Map<String, Action> actionsMap = new HashMap<>();
for (Action a : actions) { for (Action a : actions) {
actionsMap.put(a.getId(), a); actionsMap.put(a.getId(), a);
@ -175,8 +174,8 @@ public class ConnectionValidator {
* @param triggers is a list with triggers of the rule on which the condition belongs * @param triggers is a list with triggers of the rule on which the condition belongs
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
private static void validateConditionConnections(ModuleTypeRegistry mtRegistry, @NonNull Condition condition, private static void validateConditionConnections(ModuleTypeRegistry mtRegistry, Condition condition,
@NonNull List<? extends @NonNull Trigger> triggers) { List<? extends @NonNull Trigger> triggers) {
ConditionType type = (ConditionType) mtRegistry.get(condition.getTypeUID()); // get module type of the condition ConditionType type = (ConditionType) mtRegistry.get(condition.getTypeUID()); // get module type of the condition
if (type == null) { if (type == null) {
// if module type not exists in the system - throws exception // if module type not exists in the system - throws exception
@ -221,7 +220,7 @@ public class ConnectionValidator {
* @throws IllegalArgumentException when validation fails. * @throws IllegalArgumentException when validation fails.
*/ */
private static void checkConnection(ModuleTypeRegistry mtRegistry, Connection connection, Input input, private static void checkConnection(ModuleTypeRegistry mtRegistry, Connection connection, Input input,
@NonNull List<? extends @NonNull Trigger> triggers) { List<? extends @NonNull Trigger> triggers) {
Map<String, Trigger> triggersMap = new HashMap<>(); Map<String, Trigger> triggersMap = new HashMap<>();
for (Trigger trigger : triggers) { for (Trigger trigger : triggers) {
triggersMap.put(trigger.getId(), trigger); triggersMap.put(trigger.getId(), trigger);
@ -261,7 +260,7 @@ public class ConnectionValidator {
return; return;
} }
String outputName = connection.getOutputName(); String outputName = connection.getOutputName();
if (outputs != null && !outputs.isEmpty()) { if (!outputs.isEmpty()) {
for (Output output : outputs) { for (Output output : outputs) {
if (output.getName().equals(outputName)) { if (output.getName().equals(outputName)) {
if (input.getType().equals("*")) { if (input.getType().equals("*")) {
@ -311,7 +310,7 @@ public class ConnectionValidator {
return connections; return connections;
} }
private static Connection getConnection(String inputName, String reference) { private static Connection getConnection(String inputName, @Nullable String reference) {
if (reference == null || !Pattern.matches(CONNECTION_PATTERN, reference)) { if (reference == null || !Pattern.matches(CONNECTION_PATTERN, reference)) {
throw new IllegalArgumentException("Wrong format of Connection : " + inputName + ": " + reference); throw new IllegalArgumentException("Wrong format of Connection : " + inputName + ": " + reference);
} }

View File

@ -14,6 +14,7 @@ package org.openhab.core.binding.xml.internal;
import java.util.List; import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionParameter; import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.config.core.ConfigDescriptionParameterGroup; import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
@ -41,6 +42,7 @@ import com.thoughtworks.xstream.XStream;
* @author Alex Tugarev - Extended by options and filter criteria * @author Alex Tugarev - Extended by options and filter criteria
* @author Chris Jackson - Add parameter groups * @author Chris Jackson - Add parameter groups
*/ */
@NonNullByDefault
public class BindingInfoReader extends XmlDocumentReader<BindingInfoXmlResult> { public class BindingInfoReader extends XmlDocumentReader<BindingInfoXmlResult> {
/** /**

View File

@ -13,7 +13,6 @@
package org.openhab.core.binding.xml.internal; package org.openhab.core.binding.xml.internal;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.binding.BindingInfo; import org.openhab.core.binding.BindingInfo;
import org.openhab.core.binding.BindingInfoProvider; import org.openhab.core.binding.BindingInfoProvider;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
@ -68,20 +67,18 @@ public class BindingInfoXmlProvider implements XmlDocumentProvider<BindingInfoXm
} }
@Override @Override
public synchronized void addingObject(@Nullable BindingInfoXmlResult bindingInfoXmlResult) { public synchronized void addingObject(BindingInfoXmlResult bindingInfoXmlResult) {
if (bindingInfoXmlResult != null) { ConfigDescription configDescription = bindingInfoXmlResult.getConfigDescription();
ConfigDescription configDescription = bindingInfoXmlResult.getConfigDescription();
if (configDescription != null) { if (configDescription != null) {
try { try {
configDescriptionProvider.add(bundle, configDescription); configDescriptionProvider.add(bundle, configDescription);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Could not register ConfigDescription!", ex); logger.error("Could not register ConfigDescription!", ex);
}
} }
bindingInfoProvider.add(bundle, bindingInfoXmlResult.getBindingInfo());
} }
bindingInfoProvider.add(bundle, bindingInfoXmlResult.getBindingInfo());
} }
@Override @Override

View File

@ -18,6 +18,7 @@ import java.util.Set;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.binding.BindingInfo; import org.openhab.core.binding.BindingInfo;
import org.openhab.core.binding.BindingInfoProvider; import org.openhab.core.binding.BindingInfoProvider;
@ -48,6 +49,7 @@ import org.osgi.service.component.annotations.Reference;
* @author Michael Grammling - Refactoring: Provider/Registry pattern is used, added locale support * @author Michael Grammling - Refactoring: Provider/Registry pattern is used, added locale support
* @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider} * @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider}
*/ */
@NonNullByDefault
@Component @Component
public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, BindingInfo> public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, BindingInfo>
implements BindingInfoProvider, XmlDocumentProviderFactory<BindingInfoXmlResult> { implements BindingInfoProvider, XmlDocumentProviderFactory<BindingInfoXmlResult> {
@ -65,8 +67,10 @@ public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, Bin
@Activate @Activate
public XmlBindingInfoProvider(final @Reference BindingI18nLocalizationService bindingI18nService, public XmlBindingInfoProvider(final @Reference BindingI18nLocalizationService bindingI18nService,
final @Reference(target = "(esh.scope=core.xml.binding)") ConfigDescriptionProvider configDescriptionProvider,
final @Reference ReadyService readyService) { final @Reference ReadyService readyService) {
this.bindingI18nService = bindingI18nService; this.bindingI18nService = bindingI18nService;
this.configDescriptionProvider = (AbstractXmlConfigDescriptionProvider) configDescriptionProvider;
this.readyService = readyService; this.readyService = readyService;
} }
@ -104,15 +108,6 @@ public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, Bin
return new HashSet<>(getAll(locale)); return new HashSet<>(getAll(locale));
} }
@Reference(target = "(esh.scope=core.xml.binding)")
public void setConfigDescriptionProvider(ConfigDescriptionProvider configDescriptionProvider) {
this.configDescriptionProvider = (AbstractXmlConfigDescriptionProvider) configDescriptionProvider;
}
public void unsetConfigDescriptionProvider(ConfigDescriptionProvider configDescriptionProvider) {
this.configDescriptionProvider = null;
}
@Override @Override
protected @Nullable BindingInfo localize(Bundle bundle, BindingInfo bindingInfo, @Nullable Locale locale) { protected @Nullable BindingInfo localize(Bundle bundle, BindingInfo bindingInfo, @Nullable Locale locale) {
return bindingI18nService.createLocalizedBindingInfo(bundle, bindingInfo, locale); return bindingI18nService.createLocalizedBindingInfo(bundle, bindingInfo, locale);

View File

@ -18,6 +18,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.registry.Identifiable; import org.openhab.core.common.registry.Identifiable;
/** /**
@ -42,6 +44,7 @@ import org.openhab.core.common.registry.Identifiable;
* @author Chris Jackson - Added parameter groups * @author Chris Jackson - Added parameter groups
* @author Thomas Höfer - Added convenient operation to get config description parameters in a map * @author Thomas Höfer - Added convenient operation to get config description parameters in a map
*/ */
@NonNullByDefault
public class ConfigDescription implements Identifiable<URI> { public class ConfigDescription implements Identifiable<URI> {
private final URI uri; private final URI uri;
@ -90,8 +93,8 @@ public class ConfigDescription implements Identifiable<URI> {
* @throws IllegalArgumentException if the URI is null or invalid * @throws IllegalArgumentException if the URI is null or invalid
*/ */
@Deprecated @Deprecated
public ConfigDescription(URI uri, List<ConfigDescriptionParameter> parameters, public ConfigDescription(@Nullable URI uri, @Nullable List<ConfigDescriptionParameter> parameters,
List<ConfigDescriptionParameterGroup> groups) { @Nullable List<ConfigDescriptionParameterGroup> groups) {
if (uri == null) { if (uri == null) {
throw new IllegalArgumentException("The URI must not be null!"); throw new IllegalArgumentException("The URI must not be null!");
} }

View File

@ -23,6 +23,8 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.registry.Identifiable; import org.openhab.core.common.registry.Identifiable;
import org.openhab.core.i18n.LocalizedKey; import org.openhab.core.i18n.LocalizedKey;
@ -36,9 +38,11 @@ import org.osgi.framework.Bundle;
* @param <T_ID> the key type, e.g. ThingTypeUID, ChannelUID, URI,... * @param <T_ID> the key type, e.g. ThingTypeUID, ChannelUID, URI,...
* @param <T_OBJECT> the object type, e.g. ThingType, ChannelType, ConfigDescription,... * @param <T_OBJECT> the object type, e.g. ThingType, ChannelType, ConfigDescription,...
*/ */
public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiable<T_ID>> { @NonNullByDefault
public abstract class AbstractXmlBasedProvider<@NonNull T_ID, @NonNull T_OBJECT extends Identifiable<@NonNull T_ID>> {
private final Map<Bundle, List<T_OBJECT>> bundleObjectMap = new ConcurrentHashMap<>(); private final Map<Bundle, List<T_OBJECT>> bundleObjectMap = new ConcurrentHashMap<>();
private final Map<LocalizedKey, T_OBJECT> localizedObjectCache = new ConcurrentHashMap<>(); private final Map<LocalizedKey, T_OBJECT> localizedObjectCache = new ConcurrentHashMap<>();
/** /**
@ -72,7 +76,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
* @param objectList the objects to be added * @param objectList the objects to be added
*/ */
public final synchronized void addAll(Bundle bundle, Collection<T_OBJECT> objectList) { public final synchronized void addAll(Bundle bundle, Collection<T_OBJECT> objectList) {
if (objectList == null || objectList.isEmpty()) { if (objectList.isEmpty()) {
return; return;
} }
List<T_OBJECT> objects = acquireObjects(bundle); List<T_OBJECT> objects = acquireObjects(bundle);
@ -86,10 +90,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
} }
} }
private List<T_OBJECT> acquireObjects(Bundle bundle) { private @Nullable List<T_OBJECT> acquireObjects(Bundle bundle) {
if (bundle == null) {
return null;
}
List<T_OBJECT> objects = bundleObjectMap.get(bundle); List<T_OBJECT> objects = bundleObjectMap.get(bundle);
if (objects == null) { if (objects == null) {
objects = new CopyOnWriteArrayList<>(); objects = new CopyOnWriteArrayList<>();
@ -141,9 +142,6 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
* @param bundle the module for which all associated Thing types to be removed * @param bundle the module for which all associated Thing types to be removed
*/ */
public final synchronized void removeAll(Bundle bundle) { public final synchronized void removeAll(Bundle bundle) {
if (bundle == null) {
return;
}
List<T_OBJECT> objects = bundleObjectMap.remove(bundle); List<T_OBJECT> objects = bundleObjectMap.remove(bundle);
if (objects != null) { if (objects != null) {
removeCachedEntries(objects); removeCachedEntries(objects);
@ -173,9 +171,12 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
return cacheEntry; return cacheEntry;
} }
@Nullable
final T_OBJECT localizedObject = localize(bundle, object, locale); final T_OBJECT localizedObject = localize(bundle, object, locale);
if (localizedObject != null) { if (localizedObject != null) {
localizedObjectCache.put(localizedKey, localizedObject); @NonNull
T_OBJECT nonNullLocalizedObject = (@NonNull T_OBJECT) localizedObject;
localizedObjectCache.put(localizedKey, nonNullLocalizedObject);
return localizedObject; return localizedObject;
} else { } else {
return object; return object;

View File

@ -16,6 +16,7 @@ import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionProvider; import org.openhab.core.config.core.ConfigDescriptionProvider;
@ -38,6 +39,7 @@ import org.osgi.framework.Bundle;
* @author Markus Rathgeb - Use ConfigI18nLocalizerService * @author Markus Rathgeb - Use ConfigI18nLocalizerService
* @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider} * @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider}
*/ */
@NonNullByDefault
public abstract class AbstractXmlConfigDescriptionProvider extends AbstractXmlBasedProvider<URI, ConfigDescription> public abstract class AbstractXmlConfigDescriptionProvider extends AbstractXmlBasedProvider<URI, ConfigDescription>
implements ConfigDescriptionProvider { implements ConfigDescriptionProvider {

View File

@ -14,6 +14,7 @@ package org.openhab.core.config.xml.internal;
import java.util.List; import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionParameter; import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.config.core.ConfigDescriptionParameterGroup; import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
@ -42,6 +43,7 @@ import com.thoughtworks.xstream.XStream;
* @author Alex Tugarev - Extended for options and filter criteria * @author Alex Tugarev - Extended for options and filter criteria
* @author Chris Jackson - Added configuration groups * @author Chris Jackson - Added configuration groups
*/ */
@NonNullByDefault
public class ConfigDescriptionReader extends XmlDocumentReader<List<ConfigDescription>> { public class ConfigDescriptionReader extends XmlDocumentReader<List<ConfigDescription>> {
/** /**

View File

@ -14,6 +14,7 @@ package org.openhab.core.config.xml.internal;
import java.util.List; import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionProvider; import org.openhab.core.config.core.ConfigDescriptionProvider;
import org.openhab.core.config.xml.AbstractXmlConfigDescriptionProvider; import org.openhab.core.config.xml.AbstractXmlConfigDescriptionProvider;
@ -32,28 +33,21 @@ import org.osgi.framework.Bundle;
* *
* @see ConfigDescriptionXmlProviderFactory * @see ConfigDescriptionXmlProviderFactory
*/ */
@NonNullByDefault
public class ConfigDescriptionXmlProvider implements XmlDocumentProvider<List<ConfigDescription>> { public class ConfigDescriptionXmlProvider implements XmlDocumentProvider<List<ConfigDescription>> {
private Bundle bundle; private final Bundle bundle;
private AbstractXmlConfigDescriptionProvider configDescriptionProvider; private final AbstractXmlConfigDescriptionProvider configDescriptionProvider;
public ConfigDescriptionXmlProvider(Bundle bundle, AbstractXmlConfigDescriptionProvider configDescriptionProvider) public ConfigDescriptionXmlProvider(Bundle bundle, AbstractXmlConfigDescriptionProvider configDescriptionProvider)
throws IllegalArgumentException { throws IllegalArgumentException {
if (bundle == null) {
throw new IllegalArgumentException("The Bundle must not be null!");
}
if (configDescriptionProvider == null) {
throw new IllegalArgumentException("The XmlConfigDescriptionProvider must not be null!");
}
this.bundle = bundle; this.bundle = bundle;
this.configDescriptionProvider = configDescriptionProvider; this.configDescriptionProvider = configDescriptionProvider;
} }
@Override @Override
public synchronized void addingObject(List<ConfigDescription> configDescriptions) { public synchronized void addingObject(List<ConfigDescription> configDescriptions) {
this.configDescriptionProvider.addAll(this.bundle, configDescriptions); this.configDescriptionProvider.addAll(bundle, configDescriptions);
} }
@Override @Override

View File

@ -32,6 +32,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.ThreadPoolManager; import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.config.xml.util.XmlDocumentReader; import org.openhab.core.config.xml.util.XmlDocumentReader;
import org.openhab.core.service.ReadyMarker; import org.openhab.core.service.ReadyMarker;
@ -61,7 +64,8 @@ import org.slf4j.LoggerFactory;
* *
* @param <T> the result type of the conversion * @param <T> the result type of the conversion
*/ */
public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> { @NonNullByDefault
public class XmlDocumentBundleTracker<@NonNull T> extends BundleTracker<Bundle> {
/** /**
* Execute given method while take the lock and unlock before return. * Execute given method while take the lock and unlock before return.
@ -108,8 +112,7 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
private final ReadWriteLock lockOpenState = new ReentrantReadWriteLock(); private final ReadWriteLock lockOpenState = new ReentrantReadWriteLock();
private OpenState openState = OpenState.CREATED; private OpenState openState = OpenState.CREATED;
@SuppressWarnings("rawtypes") private @Nullable BundleTracker<?> relevantBundlesTracker;
private BundleTracker relevantBundlesTracker;
private final ReadyService readyService; private final ReadyService readyService;
/** /**
@ -129,22 +132,6 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
String readyMarkerKey, ReadyService readyService) throws IllegalArgumentException { String readyMarkerKey, ReadyService readyService) throws IllegalArgumentException {
super(bundleContext, Bundle.ACTIVE, null); super(bundleContext, Bundle.ACTIVE, null);
if (bundleContext == null) {
throw new IllegalArgumentException("The BundleContext must not be null!");
}
if ((xmlDirectory == null) || (xmlDirectory.isEmpty())) {
throw new IllegalArgumentException("The XML directory must neither be null, nor empty!");
}
if (xmlDocumentTypeReader == null) {
throw new IllegalArgumentException("The XmlDocumentTypeReader must not be null!");
}
if (xmlDocumentProviderFactory == null) {
throw new IllegalArgumentException("The XmlDocumentProviderFactory must not be null!");
}
if (readyService == null) {
throw new IllegalArgumentException("The ReadyService must not be null!");
}
this.readyMarkerKey = readyMarkerKey; this.readyMarkerKey = readyMarkerKey;
this.xmlDirectory = xmlDirectory; this.xmlDirectory = xmlDirectory;
this.xmlDocumentTypeReader = xmlDocumentTypeReader; this.xmlDocumentTypeReader = xmlDocumentTypeReader;
@ -161,10 +148,11 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
} }
private Set<Bundle> getRelevantBundles() { private Set<Bundle> getRelevantBundles() {
if (relevantBundlesTracker.getBundles() == null) { BundleTracker<?> bundleTracker = relevantBundlesTracker;
if (bundleTracker == null || bundleTracker.getBundles() == null) {
return Collections.emptySet(); return Collections.emptySet();
} }
return Arrays.stream(relevantBundlesTracker.getBundles()).collect(Collectors.toSet()); return (Set<Bundle>) Arrays.stream(bundleTracker.getBundles()).collect(Collectors.toSet());
} }
@Override @Override
@ -184,7 +172,8 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
relevantBundlesTracker = new BundleTracker(context, relevantBundlesTracker = new BundleTracker(context,
Bundle.RESOLVED | Bundle.STARTING | Bundle.STOPPING | Bundle.ACTIVE, null) { Bundle.RESOLVED | Bundle.STARTING | Bundle.STOPPING | Bundle.ACTIVE, null) {
@Override @Override
public Object addingBundle(Bundle bundle, BundleEvent event) { public @Nullable Object addingBundle(@NonNullByDefault({}) Bundle bundle,
@NonNullByDefault({}) BundleEvent event) {
return withLock(lockOpenState.readLock(), return withLock(lockOpenState.readLock(),
() -> openState == OpenState.OPENED && isBundleRelevant(bundle) ? bundle : null); () -> openState == OpenState.OPENED && isBundleRelevant(bundle) ? bundle : null);
} }
@ -216,11 +205,7 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
queue.clear(); queue.clear();
} }
private XmlDocumentProvider<T> acquireXmlDocumentProvider(Bundle bundle) { private @Nullable XmlDocumentProvider<T> acquireXmlDocumentProvider(Bundle bundle) {
if (bundle == null) {
return null;
}
XmlDocumentProvider<T> xmlDocumentProvider = bundleDocumentProviderMap.get(bundle); XmlDocumentProvider<T> xmlDocumentProvider = bundleDocumentProviderMap.get(bundle);
if (xmlDocumentProvider == null) { if (xmlDocumentProvider == null) {
xmlDocumentProvider = xmlDocumentProviderFactory.createDocumentProvider(bundle); xmlDocumentProvider = xmlDocumentProviderFactory.createDocumentProvider(bundle);
@ -232,9 +217,6 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
} }
private void releaseXmlDocumentProvider(Bundle bundle) { private void releaseXmlDocumentProvider(Bundle bundle) {
if (bundle == null) {
return;
}
XmlDocumentProvider<T> xmlDocumentProvider = bundleDocumentProviderMap.get(bundle); XmlDocumentProvider<T> xmlDocumentProvider = bundleDocumentProviderMap.get(bundle);
if (xmlDocumentProvider == null) { if (xmlDocumentProvider == null) {
return; return;
@ -270,13 +252,15 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
} }
@Override @Override
public final synchronized Bundle addingBundle(Bundle bundle, BundleEvent event) { public final synchronized Bundle addingBundle(@NonNullByDefault({}) Bundle bundle,
@NonNullByDefault({}) BundleEvent event) {
addingBundle(bundle); addingBundle(bundle);
return bundle; return bundle;
} }
@Override @Override
public final synchronized void removedBundle(Bundle bundle, BundleEvent event, Bundle object) { public final synchronized void removedBundle(@NonNullByDefault({}) Bundle bundle,
@NonNullByDefault({}) BundleEvent event, Bundle object) {
logger.trace("Removing the XML related objects from module '{}'...", ReadyMarkerUtils.getIdentifier(bundle)); logger.trace("Removing the XML related objects from module '{}'...", ReadyMarkerUtils.getIdentifier(bundle));
finishedBundles.remove(bundle); finishedBundles.remove(bundle);
Future<?> future = queue.remove(bundle); Future<?> future = queue.remove(bundle);
@ -408,8 +392,11 @@ public class XmlDocumentBundleTracker<T> extends BundleTracker<Bundle> {
String xmlDocumentFile = xmlDocumentURL.getFile(); String xmlDocumentFile = xmlDocumentURL.getFile();
logger.debug("Reading the XML document '{}' in module '{}'...", xmlDocumentFile, moduleName); logger.debug("Reading the XML document '{}' in module '{}'...", xmlDocumentFile, moduleName);
try { try {
@Nullable
T object = xmlDocumentTypeReader.readFromXML(xmlDocumentURL); T object = xmlDocumentTypeReader.readFromXML(xmlDocumentURL);
addingObject(bundle, object); if (object != null) {
addingObject(bundle, object);
}
numberOfParsedXmlDocuments++; numberOfParsedXmlDocuments++;
} catch (Exception ex) { } catch (Exception ex) {
// If we are not open, we can stop here. // If we are not open, we can stop here.

View File

@ -12,8 +12,8 @@
*/ */
package org.openhab.core.config.xml.osgi; package org.openhab.core.config.xml.osgi;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.xml.internal.ConfigDescriptionReader; import org.openhab.core.config.xml.internal.ConfigDescriptionReader;
/** /**
@ -27,14 +27,14 @@ import org.openhab.core.config.xml.internal.ConfigDescriptionReader;
* @param <T> the result type of the conversion * @param <T> the result type of the conversion
*/ */
@NonNullByDefault @NonNullByDefault
public interface XmlDocumentProvider<T> { public interface XmlDocumentProvider<@NonNull T> {
/** /**
* Adds a new result object from the XML processing for further processing. * Adds a new result object from the XML processing for further processing.
* *
* @param object the result object to be processed (could be null) * @param object the result object to be processed
*/ */
void addingObject(@Nullable T object); void addingObject(T object);
/** /**
* Signals that all available result objects from the XML processing of the * Signals that all available result objects from the XML processing of the

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.core.config.xml.osgi; package org.openhab.core.config.xml.osgi;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
@ -29,7 +30,7 @@ import org.osgi.framework.Bundle;
* @see XmlDocumentProvider * @see XmlDocumentProvider
*/ */
@NonNullByDefault @NonNullByDefault
public interface XmlDocumentProviderFactory<T> { public interface XmlDocumentProviderFactory<@NonNull T> {
/** /**
* Creates an XML document provider for the specified module which is used to process * Creates an XML document provider for the specified module which is used to process

View File

@ -14,6 +14,10 @@ package org.openhab.core.config.xml.util;
import java.net.URL; import java.net.URL;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.Converter;
@ -29,21 +33,18 @@ import com.thoughtworks.xstream.io.xml.StaxDriver;
* *
* @param <T> the result type of the conversion * @param <T> the result type of the conversion
*/ */
public abstract class XmlDocumentReader<T> { @NonNullByDefault
public abstract class XmlDocumentReader<@NonNull T> {
private XStream xstream; private final XStream xstream = new XStream(new StaxDriver());
/** /**
* The default constructor of this class initializes the {@code XStream} object, and calls * The default constructor of this class initializes the {@code XStream} object, and calls
* the abstract methods {@link #registerConverters()} and {@link #registerAliases()}. * the abstract methods {@link #registerConverters()} and {@link #registerAliases()}.
*/ */
public XmlDocumentReader() { public XmlDocumentReader() {
StaxDriver driver = new StaxDriver(); registerConverters(xstream);
registerAliases(xstream);
this.xstream = new XStream(driver);
registerConverters(this.xstream);
registerAliases(this.xstream);
} }
/** /**
@ -52,7 +53,7 @@ public abstract class XmlDocumentReader<T> {
* @param classLoader the classloader to set (must not be null) * @param classLoader the classloader to set (must not be null)
*/ */
public void setClassLoader(ClassLoader classLoader) { public void setClassLoader(ClassLoader classLoader) {
this.xstream.setClassLoader(classLoader); xstream.setClassLoader(classLoader);
} }
/** /**
@ -80,12 +81,8 @@ public abstract class XmlDocumentReader<T> {
* @throws ConversionException if the specified document contains invalid content * @throws ConversionException if the specified document contains invalid content
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T readFromXML(URL xmlURL) throws ConversionException { public @Nullable T readFromXML(URL xmlURL) throws ConversionException {
if (xmlURL != null) { return (@Nullable T) xstream.fromXML(xmlURL);
return (T) this.xstream.fromXML(xmlURL);
}
return null;
} }
} }

View File

@ -25,7 +25,6 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.registry.AbstractProvider; import org.openhab.core.common.registry.AbstractProvider;
@ -512,8 +511,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
} }
@Override @Override
public @Nullable StateDescriptionFragment getStateDescriptionFragment(@NonNull String itemName, public @Nullable StateDescriptionFragment getStateDescriptionFragment(String itemName, @Nullable Locale locale) {
@Nullable Locale locale) {
return stateDescriptionFragments.get(itemName); return stateDescriptionFragments.get(itemName);
} }

View File

@ -14,6 +14,7 @@ package org.openhab.core.thing.xml.internal;
import java.util.List; import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionParameter; import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.config.core.ConfigDescriptionParameterGroup; import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
@ -48,6 +49,7 @@ import com.thoughtworks.xstream.XStream;
* @author Chris Jackson - Added parameter groups and channel properties * @author Chris Jackson - Added parameter groups and channel properties
* @author Moritz Kammerer - Added triggers * @author Moritz Kammerer - Added triggers
*/ */
@NonNullByDefault
public class ThingDescriptionReader extends XmlDocumentReader<List<?>> { public class ThingDescriptionReader extends XmlDocumentReader<List<?>> {
/** /**

View File

@ -15,6 +15,8 @@ package org.openhab.core.thing.xml.internal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.core.ConfigDescription; import org.openhab.core.config.core.ConfigDescription;
import org.openhab.core.config.core.ConfigDescriptionProvider; import org.openhab.core.config.core.ConfigDescriptionProvider;
import org.openhab.core.config.xml.AbstractXmlConfigDescriptionProvider; import org.openhab.core.config.xml.AbstractXmlConfigDescriptionProvider;
@ -51,6 +53,7 @@ import com.thoughtworks.xstream.converters.ConversionException;
* @author Michael Grammling - Initial contribution * @author Michael Grammling - Initial contribution
* @author Ivan Iliev - Added support for system wide channel types * @author Ivan Iliev - Added support for system wide channel types
*/ */
@NonNullByDefault
public class ThingTypeXmlProvider implements XmlDocumentProvider<List<?>> { public class ThingTypeXmlProvider implements XmlDocumentProvider<List<?>> {
private final Logger logger = LoggerFactory.getLogger(ThingTypeXmlProvider.class); private final Logger logger = LoggerFactory.getLogger(ThingTypeXmlProvider.class);
@ -70,18 +73,6 @@ public class ThingTypeXmlProvider implements XmlDocumentProvider<List<?>> {
public ThingTypeXmlProvider(Bundle bundle, AbstractXmlConfigDescriptionProvider configDescriptionProvider, public ThingTypeXmlProvider(Bundle bundle, AbstractXmlConfigDescriptionProvider configDescriptionProvider,
XmlThingTypeProvider thingTypeProvider, XmlChannelTypeProvider channelTypeProvider, XmlThingTypeProvider thingTypeProvider, XmlChannelTypeProvider channelTypeProvider,
XmlChannelGroupTypeProvider channelGroupTypeProvider) throws IllegalArgumentException { XmlChannelGroupTypeProvider channelGroupTypeProvider) throws IllegalArgumentException {
if (bundle == null) {
throw new IllegalArgumentException("The Bundle must not be null!");
}
if (configDescriptionProvider == null) {
throw new IllegalArgumentException("The XmlConfigDescriptionProvider must not be null!");
}
if (thingTypeProvider == null) {
throw new IllegalArgumentException("The XmlThingTypeProvider must not be null!");
}
this.bundle = bundle; this.bundle = bundle;
this.configDescriptionProvider = configDescriptionProvider; this.configDescriptionProvider = configDescriptionProvider;
this.thingTypeProvider = thingTypeProvider; this.thingTypeProvider = thingTypeProvider;
@ -91,27 +82,25 @@ public class ThingTypeXmlProvider implements XmlDocumentProvider<List<?>> {
@Override @Override
public synchronized void addingObject(List<?> types) { public synchronized void addingObject(List<?> types) {
if (types != null) { for (Object type : types) {
for (Object type : types) { if (type instanceof ThingTypeXmlResult) {
if (type instanceof ThingTypeXmlResult) { ThingTypeXmlResult typeResult = (ThingTypeXmlResult) type;
ThingTypeXmlResult typeResult = (ThingTypeXmlResult) type; addConfigDescription(typeResult.getConfigDescription());
addConfigDescription(typeResult.getConfigDescription()); thingTypeRefs.add(typeResult);
thingTypeRefs.add(typeResult); } else if (type instanceof ChannelGroupTypeXmlResult) {
} else if (type instanceof ChannelGroupTypeXmlResult) { ChannelGroupTypeXmlResult typeResult = (ChannelGroupTypeXmlResult) type;
ChannelGroupTypeXmlResult typeResult = (ChannelGroupTypeXmlResult) type; channelGroupTypeRefs.add(typeResult);
channelGroupTypeRefs.add(typeResult); } else if (type instanceof ChannelTypeXmlResult) {
} else if (type instanceof ChannelTypeXmlResult) { ChannelTypeXmlResult typeResult = (ChannelTypeXmlResult) type;
ChannelTypeXmlResult typeResult = (ChannelTypeXmlResult) type; channelTypeRefs.add(typeResult);
channelTypeRefs.add(typeResult); addConfigDescription(typeResult.getConfigDescription());
addConfigDescription(typeResult.getConfigDescription()); } else {
} else { throw new ConversionException("Unknown data type for '" + type + "'!");
throw new ConversionException("Unknown data type for '" + type + "'!");
}
} }
} }
} }
private void addConfigDescription(ConfigDescription configDescription) { private void addConfigDescription(@Nullable ConfigDescription configDescription) {
if (configDescription != null) { if (configDescription != null) {
try { try {
configDescriptionProvider.add(bundle, configDescription); configDescriptionProvider.add(bundle, configDescription);

View File

@ -15,6 +15,7 @@ package org.openhab.core.thing.xml.internal;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.xml.AbstractXmlBasedProvider; import org.openhab.core.config.xml.AbstractXmlBasedProvider;
import org.openhab.core.thing.UID; import org.openhab.core.thing.UID;
@ -33,6 +34,7 @@ import org.osgi.service.component.annotations.Reference;
* @author Simon Kaufmann - Initial contribution * @author Simon Kaufmann - Initial contribution
* @author Christoph Weitkamp - factored out common aspects into ThingTypeI18nLocalizationService * @author Christoph Weitkamp - factored out common aspects into ThingTypeI18nLocalizationService
*/ */
@NonNullByDefault
@Component(property = { "esh.scope=core.xml.channelGroups" }) @Component(property = { "esh.scope=core.xml.channelGroups" })
public class XmlChannelGroupTypeProvider extends AbstractXmlBasedProvider<UID, ChannelGroupType> public class XmlChannelGroupTypeProvider extends AbstractXmlBasedProvider<UID, ChannelGroupType>
implements ChannelGroupTypeProvider { implements ChannelGroupTypeProvider {

View File

@ -15,6 +15,7 @@ package org.openhab.core.thing.xml.internal;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.xml.AbstractXmlBasedProvider; import org.openhab.core.config.xml.AbstractXmlBasedProvider;
import org.openhab.core.thing.UID; import org.openhab.core.thing.UID;
@ -36,6 +37,7 @@ import org.osgi.service.component.annotations.Reference;
* @author Henning Treu - QuantityType implementation * @author Henning Treu - QuantityType implementation
* @author Christoph Weitkamp - factored out common aspects into ThingTypeI18nLocalizationService * @author Christoph Weitkamp - factored out common aspects into ThingTypeI18nLocalizationService
*/ */
@NonNullByDefault
@Component(property = { "esh.scope=core.xml.channels" }) @Component(property = { "esh.scope=core.xml.channels" })
public class XmlChannelTypeProvider extends AbstractXmlBasedProvider<UID, ChannelType> implements ChannelTypeProvider { public class XmlChannelTypeProvider extends AbstractXmlBasedProvider<UID, ChannelType> implements ChannelTypeProvider {

View File

@ -18,6 +18,7 @@ import java.util.Locale;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.ThreadPoolManager; import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.config.core.ConfigDescriptionProvider; import org.openhab.core.config.core.ConfigDescriptionProvider;
@ -54,6 +55,7 @@ import org.osgi.service.component.annotations.Reference;
* @author Kai Kreuzer - fixed concurrency issues * @author Kai Kreuzer - fixed concurrency issues
* @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider} * @author Simon Kaufmann - factored out common aspects into {@link AbstractXmlBasedProvider}
*/ */
@NonNullByDefault
@Component(property = { "esh.scope=core.xml.thing" }) @Component(property = { "esh.scope=core.xml.thing" })
public class XmlThingTypeProvider extends AbstractXmlBasedProvider<UID, ThingType> public class XmlThingTypeProvider extends AbstractXmlBasedProvider<UID, ThingType>
implements ThingTypeProvider, XmlDocumentProviderFactory<List<?>> { implements ThingTypeProvider, XmlDocumentProviderFactory<List<?>> {
@ -62,9 +64,9 @@ public class XmlThingTypeProvider extends AbstractXmlBasedProvider<UID, ThingTyp
public static final String READY_MARKER = "esh.xmlThingTypes"; public static final String READY_MARKER = "esh.xmlThingTypes";
private final ThingTypeI18nLocalizationService thingTypeI18nLocalizationService; private final ThingTypeI18nLocalizationService thingTypeI18nLocalizationService;
private XmlChannelTypeProvider channelTypeProvider; private final XmlChannelTypeProvider channelTypeProvider;
private XmlChannelGroupTypeProvider channelGroupTypeProvider; private final XmlChannelGroupTypeProvider channelGroupTypeProvider;
private AbstractXmlConfigDescriptionProvider configDescriptionProvider; private final AbstractXmlConfigDescriptionProvider configDescriptionProvider;
private @Nullable XmlDocumentBundleTracker<List<?>> thingTypeTracker; private @Nullable XmlDocumentBundleTracker<List<?>> thingTypeTracker;
private final ReadyService readyService; private final ReadyService readyService;
private final ScheduledExecutorService scheduler = ThreadPoolManager private final ScheduledExecutorService scheduler = ThreadPoolManager
@ -72,10 +74,17 @@ public class XmlThingTypeProvider extends AbstractXmlBasedProvider<UID, ThingTyp
private @Nullable Future<?> trackerJob; private @Nullable Future<?> trackerJob;
@Activate @Activate
public XmlThingTypeProvider(final @Reference ThingTypeI18nLocalizationService thingTypeI18nLocalizationService, public XmlThingTypeProvider(
final @Reference ReadyService readyService) { final @Reference(target = "(esh.scope=core.xml.channelGroups)") ChannelGroupTypeProvider channelGroupTypeProvider,
this.thingTypeI18nLocalizationService = thingTypeI18nLocalizationService; final @Reference(target = "(esh.scope=core.xml.channels)") ChannelTypeProvider channelTypeProvider,
final @Reference(target = "(esh.scope=core.xml.thing)") ConfigDescriptionProvider configDescriptionProvider,
final @Reference ReadyService readyService,
final @Reference ThingTypeI18nLocalizationService thingTypeI18nLocalizationService) {
this.channelGroupTypeProvider = (XmlChannelGroupTypeProvider) channelGroupTypeProvider;
this.channelTypeProvider = (XmlChannelTypeProvider) channelTypeProvider;
this.configDescriptionProvider = (AbstractXmlConfigDescriptionProvider) configDescriptionProvider;
this.readyService = readyService; this.readyService = readyService;
this.thingTypeI18nLocalizationService = thingTypeI18nLocalizationService;
} }
@Activate @Activate
@ -112,33 +121,6 @@ public class XmlThingTypeProvider extends AbstractXmlBasedProvider<UID, ThingTyp
return getAll(locale); return getAll(locale);
} }
@Reference(target = "(esh.scope=core.xml.thing)")
public void setConfigDescriptionProvider(ConfigDescriptionProvider configDescriptionProvider) {
this.configDescriptionProvider = (AbstractXmlConfigDescriptionProvider) configDescriptionProvider;
}
public void unsetConfigDescriptionProvider(ConfigDescriptionProvider configDescriptionProvider) {
this.configDescriptionProvider = null;
}
@Reference(target = "(esh.scope=core.xml.channels)")
public void setChannelTypeProvider(ChannelTypeProvider channelTypeProvider) {
this.channelTypeProvider = (XmlChannelTypeProvider) channelTypeProvider;
}
public void unsetChannelTypeProvider(ChannelTypeProvider channelTypeProvider) {
this.channelTypeProvider = null;
}
@Reference(target = "(esh.scope=core.xml.channelGroups)")
public void setChannelGroupTypeProvider(ChannelGroupTypeProvider channelGroupTypeProvider) {
this.channelGroupTypeProvider = (XmlChannelGroupTypeProvider) channelGroupTypeProvider;
}
public void unsetChannelGroupTypeProvider(ChannelGroupTypeProvider channelGroupTypeProvider) {
this.channelGroupTypeProvider = null;
}
@Override @Override
protected @Nullable ThingType localize(Bundle bundle, ThingType thingType, @Nullable Locale locale) { protected @Nullable ThingType localize(Bundle bundle, ThingType thingType, @Nullable Locale locale) {
return thingTypeI18nLocalizationService.createLocalizedThingType(bundle, thingType, locale); return thingTypeI18nLocalizationService.createLocalizedThingType(bundle, thingType, locale);

View File

@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
* type of the persistable element * type of the persistable element
*/ */
@NonNullByDefault @NonNullByDefault
public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>, @NonNull K, PE> public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>, @NonNull K, @NonNull PE>
extends AbstractProvider<E> implements ManagedProvider<E, K> { extends AbstractProvider<E> implements ManagedProvider<E, K> {
private volatile Storage<PE> storage; private volatile Storage<PE> storage;
@ -80,6 +80,7 @@ public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>
} }
private @Nullable E getElement(String key) { private @Nullable E getElement(String key) {
@Nullable
PE persistableElement = storage.get(key); PE persistableElement = storage.get(key);
return persistableElement != null ? toElement(key, persistableElement) : null; return persistableElement != null ? toElement(key, persistableElement) : null;
} }
@ -87,6 +88,7 @@ public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>
@Override @Override
public @Nullable E remove(K key) { public @Nullable E remove(K key) {
String keyAsString = keyToString(key); String keyAsString = keyToString(key);
@Nullable
PE persistableElement = storage.remove(keyAsString); PE persistableElement = storage.remove(keyAsString);
if (persistableElement != null) { if (persistableElement != null) {
@Nullable @Nullable
@ -105,6 +107,7 @@ public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>
public @Nullable E update(E element) { public @Nullable E update(E element) {
String key = getKeyAsString(element); String key = getKeyAsString(element);
if (storage.get(key) != null) { if (storage.get(key) != null) {
@Nullable
PE persistableElement = storage.put(key, toPersistableElement(element)); PE persistableElement = storage.put(key, toPersistableElement(element));
if (persistableElement != null) { if (persistableElement != null) {
@Nullable @Nullable
@ -150,7 +153,7 @@ public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>
* @param persistableElement persistable element * @param persistableElement persistable element
* @return original element * @return original element
*/ */
protected abstract @Nullable E toElement(String key, @NonNull PE persistableElement); protected abstract @Nullable E toElement(String key, PE persistableElement);
/** /**
* Converts the original element into an element that can be persisted. * Converts the original element into an element that can be persisted.

View File

@ -199,7 +199,7 @@ public abstract class AbstractRegistry<@NonNull E extends Identifiable<K>, @NonN
} }
@Override @Override
public Collection<@NonNull E> getAll() { public Collection<E> getAll() {
elementReadLock.lock(); elementReadLock.lock();
try { try {
return new HashSet<>(elements); return new HashSet<>(elements);

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.core.common.registry; package org.openhab.core.common.registry;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
@ -20,7 +21,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
* @author Markus Rathgeb - Initial contribution * @author Markus Rathgeb - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public interface Identifiable<T> { public interface Identifiable<@NonNull T> {
/** /**
* Get the unique identifier. * Get the unique identifier.

View File

@ -15,6 +15,7 @@ package org.openhab.core.common.registry;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -29,7 +30,7 @@ import org.eclipse.jdt.annotation.Nullable;
* @param <E> type of the elements in the registry * @param <E> type of the elements in the registry
*/ */
@NonNullByDefault @NonNullByDefault
public interface Registry<E extends Identifiable<K>, K> { public interface Registry<@NonNull E extends Identifiable<K>, @NonNull K> {
/** /**
* Adds a {@link RegistryChangeListener} to the registry. * Adds a {@link RegistryChangeListener} to the registry.

View File

@ -14,6 +14,7 @@ package org.openhab.core.service;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
/** /**
@ -21,6 +22,7 @@ import org.osgi.framework.Bundle;
* *
* @author Markus Rathgeb - Initial contribution * @author Markus Rathgeb - Initial contribution
*/ */
@NonNullByDefault
public class ReadyMarkerUtils { public class ReadyMarkerUtils {
/** /**

View File

@ -63,7 +63,7 @@ public class ManagedThingProviderOSGiTest extends JavaOSGiTest {
managedThingProvider.getAll().forEach(t -> managedThingProvider.remove(t.getUID())); managedThingProvider.getAll().forEach(t -> managedThingProvider.remove(t.getUID()));
} }
private void registerThingsChangeListener(ProviderChangeListener<@NonNull Thing> thingChangeListener) { private void registerThingsChangeListener(ProviderChangeListener<Thing> thingChangeListener) {
unregisterCurrentThingsChangeListener(); unregisterCurrentThingsChangeListener();
this.thingChangeListener = thingChangeListener; this.thingChangeListener = thingChangeListener;
managedThingProvider.addProviderChangeListener(this.thingChangeListener); managedThingProvider.addProviderChangeListener(this.thingChangeListener);