Add null annotations to providers and ThingManager (#1412)
* Add null annotations to providers and ThingManager Signed-off-by: Wouter Born <github@maindrain.net>pull/1421/head
parent
017532e2d4
commit
fb7a7ac421
|
@ -17,6 +17,7 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.RuleProvider;
|
||||
import org.openhab.core.common.registry.ProviderChangeListener;
|
||||
|
@ -28,6 +29,7 @@ import org.osgi.service.component.annotations.Component;
|
|||
*
|
||||
* @author Simon Merschjohann - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ScriptedRuleProvider.class, RuleProvider.class })
|
||||
public class ScriptedRuleProvider implements RuleProvider {
|
||||
private final Collection<ProviderChangeListener<Rule>> listeners = new ArrayList<>();
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.Visibility;
|
||||
import org.openhab.core.automation.module.script.ScriptEngineFactory;
|
||||
import org.openhab.core.automation.module.script.internal.handler.AbstractScriptModuleHandler;
|
||||
|
@ -51,6 +53,7 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @author Scott Rushworth - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component
|
||||
public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
||||
|
||||
|
@ -59,7 +62,7 @@ public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ModuleType getModuleType(String UID, Locale locale) {
|
||||
public @Nullable ModuleType getModuleType(String UID, @Nullable Locale locale) {
|
||||
if (ScriptActionHandler.TYPE_ID.equals(UID)) {
|
||||
return getScriptActionType(locale);
|
||||
} else if (ScriptConditionHandler.TYPE_ID.equals(UID)) {
|
||||
|
@ -69,7 +72,7 @@ public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private ModuleType getScriptActionType(Locale locale) {
|
||||
private @Nullable ModuleType getScriptActionType(@Nullable Locale locale) {
|
||||
if (parameterOptions.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -82,7 +85,7 @@ public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private ModuleType getScriptConditionType(Locale locale) {
|
||||
private @Nullable ModuleType getScriptConditionType(@Nullable Locale locale) {
|
||||
if (parameterOptions.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -98,7 +101,7 @@ public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
|||
*
|
||||
* @return a list of {#link ConfigurationDescriptionParameter}s
|
||||
*/
|
||||
private List<ConfigDescriptionParameter> getConfigDescriptions(Locale locale) {
|
||||
private List<ConfigDescriptionParameter> getConfigDescriptions(@Nullable Locale locale) {
|
||||
List<ParameterOption> parameterOptionsList = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : parameterOptions.entrySet()) {
|
||||
parameterOptionsList.add(new ParameterOption(entry.getKey(), entry.getValue()));
|
||||
|
@ -114,8 +117,9 @@ public class ScriptModuleTypeProvider implements ModuleTypeProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<ModuleType> getModuleTypes(Locale locale) {
|
||||
return Stream.of(getScriptActionType(locale), getScriptConditionType(locale)).collect(Collectors.toList());
|
||||
public Collection<ModuleType> getModuleTypes(@Nullable Locale locale) {
|
||||
return (Collection<ModuleType>) Stream.of(getScriptActionType(locale), getScriptConditionType(locale))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package org.openhab.core.automation;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.dto.RuleDTO;
|
||||
import org.openhab.core.automation.dto.RuleDTOMapper;
|
||||
import org.openhab.core.common.registry.AbstractManagedProvider;
|
||||
|
@ -28,6 +30,7 @@ import org.osgi.service.component.annotations.Reference;
|
|||
* @author Kai Kreuzer - refactored (managed) provider and registry implementation
|
||||
* @author Markus Rathgeb - fix mapping between element and persistable element
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { RuleProvider.class, ManagedRuleProvider.class })
|
||||
public class ManagedRuleProvider extends AbstractManagedProvider<Rule, String, RuleDTO> implements RuleProvider {
|
||||
|
||||
|
@ -47,7 +50,7 @@ public class ManagedRuleProvider extends AbstractManagedProvider<Rule, String, R
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Rule toElement(String key, RuleDTO persistableElement) {
|
||||
protected @Nullable Rule toElement(String key, RuleDTO persistableElement) {
|
||||
return RuleDTOMapper.map(persistableElement);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.parser.Parser;
|
||||
|
@ -49,7 +50,7 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractCommandProvider<E> implements ServiceTrackerCustomizer {
|
||||
public abstract class AbstractCommandProvider<@NonNull E> implements ServiceTrackerCustomizer {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(AbstractCommandProvider.class);
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.net.URL;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.RuleRegistry;
|
||||
import org.openhab.core.automation.parser.Parser;
|
||||
|
@ -42,6 +44,7 @@ import org.osgi.framework.ServiceReference;
|
|||
* @author Ana Dimova - Initial contribution
|
||||
* @author Kai Kreuzer - refactored (managed) provider and registry implementation
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class CommandlineRuleImporter extends AbstractCommandProvider<Rule> {
|
||||
|
||||
private final RuleRegistry ruleRegistry;
|
||||
|
@ -66,8 +69,8 @@ public class CommandlineRuleImporter extends AbstractCommandProvider<Rule> {
|
|||
* @see AbstractCommandProvider#addingService(org.osgi.framework.ServiceReference)
|
||||
*/
|
||||
@Override
|
||||
public Object addingService(@SuppressWarnings("rawtypes") ServiceReference reference) {
|
||||
if (reference.getProperty(Parser.PARSER_TYPE).equals(Parser.PARSER_RULE)) {
|
||||
public @Nullable Object addingService(@SuppressWarnings("rawtypes") @Nullable ServiceReference reference) {
|
||||
if (reference != null && Parser.PARSER_RULE.equals(reference.getProperty(Parser.PARSER_TYPE))) {
|
||||
return super.addingService(reference);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
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.automation.Rule;
|
||||
|
@ -69,7 +70,7 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractResourceBundleProvider<E> {
|
||||
public abstract class AbstractResourceBundleProvider<@NonNull E> {
|
||||
|
||||
public AbstractResourceBundleProvider(String path) {
|
||||
this.path = path;
|
||||
|
@ -459,7 +460,7 @@ public abstract class AbstractResourceBundleProvider<E> {
|
|||
}
|
||||
}
|
||||
|
||||
protected void updateWaitingProviders(Parser<E> parser, Bundle bundle, URL url) {
|
||||
protected void updateWaitingProviders(@Nullable Parser<E> parser, Bundle bundle, URL url) {
|
||||
List<URL> urlList = waitingProviders.get(bundle);
|
||||
if (parser == null) {
|
||||
if (urlList == null) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Iterator;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.template.TemplateProvider;
|
||||
import org.openhab.core.automation.type.ModuleTypeProvider;
|
||||
|
@ -33,7 +34,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Kai Kreuzer - refactored (managed) provider and registry implementation
|
||||
* @param <E>
|
||||
*/
|
||||
public class AutomationResourceBundlesEventQueue<E> implements Runnable {
|
||||
public class AutomationResourceBundlesEventQueue<@NonNull E> implements Runnable {
|
||||
|
||||
/**
|
||||
* This field keeps instance of {@link Logger} that is used for logging.
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.ManagedRuleProvider;
|
||||
import org.openhab.core.automation.Rule;
|
||||
import org.openhab.core.automation.parser.Parser;
|
||||
|
@ -40,12 +42,13 @@ import org.osgi.framework.Bundle;
|
|||
* @author Ana Dimova - Initial contribution
|
||||
* @author Kai Kreuzer - refactored (managed) provider and registry implementation
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RuleResourceBundleImporter extends AbstractResourceBundleProvider<Rule> {
|
||||
|
||||
/**
|
||||
* This field holds the reference to the Rule Registry.
|
||||
*/
|
||||
protected ManagedRuleProvider mProvider;
|
||||
protected @Nullable ManagedRuleProvider mProvider;
|
||||
|
||||
/**
|
||||
* This constructor is responsible for initializing the path to resources and tracking the managing service of the
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.automation.parser.Parser;
|
||||
import org.openhab.core.automation.parser.ParsingException;
|
||||
|
@ -49,7 +50,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Ana Dimova - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractFileProvider<E> implements Provider<E> {
|
||||
public abstract class AbstractFileProvider<@NonNull E> implements Provider<E> {
|
||||
|
||||
protected static final String CONFIG_PROPERTY_ROOTS = "roots";
|
||||
protected final Logger logger = LoggerFactory.getLogger(AbstractFileProvider.class);
|
||||
|
|
|
@ -26,9 +26,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.common.registry.AbstractProvider;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.items.ActiveItem;
|
||||
import org.openhab.core.items.GenericItem;
|
||||
import org.openhab.core.items.GroupFunction;
|
||||
|
@ -38,9 +39,6 @@ import org.openhab.core.items.ItemFactory;
|
|||
import org.openhab.core.items.ItemProvider;
|
||||
import org.openhab.core.items.dto.GroupFunctionDTO;
|
||||
import org.openhab.core.items.dto.ItemDTOMapper;
|
||||
import org.openhab.core.types.StateDescriptionFragment;
|
||||
import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
||||
import org.openhab.core.types.StateDescriptionFragmentProvider;
|
||||
import org.openhab.core.model.core.EventType;
|
||||
import org.openhab.core.model.core.ModelRepository;
|
||||
import org.openhab.core.model.core.ModelRepositoryChangeListener;
|
||||
|
@ -52,6 +50,9 @@ import org.openhab.core.model.items.ModelGroupFunction;
|
|||
import org.openhab.core.model.items.ModelGroupItem;
|
||||
import org.openhab.core.model.items.ModelItem;
|
||||
import org.openhab.core.model.items.ModelNormalItem;
|
||||
import org.openhab.core.types.StateDescriptionFragment;
|
||||
import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
||||
import org.openhab.core.types.StateDescriptionFragmentProvider;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
@ -68,6 +69,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { ItemProvider.class, StateDescriptionFragmentProvider.class }, immediate = true)
|
||||
public class GenericItemProvider extends AbstractProvider<Item>
|
||||
implements ModelRepositoryChangeListener, ItemProvider, StateDescriptionFragmentProvider {
|
||||
|
@ -218,7 +220,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
|
|||
}
|
||||
}
|
||||
|
||||
private Item createItemFromModelItem(ModelItem modelItem) {
|
||||
private @Nullable Item createItemFromModelItem(ModelItem modelItem) {
|
||||
Item item = null;
|
||||
if (modelItem instanceof ModelGroupItem) {
|
||||
ModelGroupItem modelGroupItem = (ModelGroupItem) modelItem;
|
||||
|
@ -264,7 +266,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
|
|||
}
|
||||
}
|
||||
|
||||
private String extractFormat(String label) {
|
||||
private @Nullable String extractFormat(@Nullable String label) {
|
||||
if (label == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -292,7 +294,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
|
|||
return new GroupItem(modelGroupItem.getName(), baseItem, groupFunction);
|
||||
}
|
||||
|
||||
private void dispatchBindingsPerItemType(BindingConfigReader reader, String[] itemTypes) {
|
||||
private void dispatchBindingsPerItemType(@Nullable BindingConfigReader reader, String[] itemTypes) {
|
||||
for (String modelName : modelRepository.getAllModelNamesOfType("items")) {
|
||||
ItemModel model = (ItemModel) modelRepository.getModel(modelName);
|
||||
if (model != null) {
|
||||
|
@ -338,7 +340,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
|
|||
internalDispatchBindings(null, modelName, item, bindings);
|
||||
}
|
||||
|
||||
private void internalDispatchBindings(BindingConfigReader reader, String modelName, Item item,
|
||||
private void internalDispatchBindings(@Nullable BindingConfigReader reader, String modelName, Item item,
|
||||
EList<ModelBinding> bindings) {
|
||||
for (ModelBinding binding : bindings) {
|
||||
String bindingType = binding.getType();
|
||||
|
@ -492,7 +494,7 @@ public class GenericItemProvider extends AbstractProvider<Item>
|
|||
*
|
||||
* @return An Item instance of type {@code itemType} or null if no item factory for it was found.
|
||||
*/
|
||||
private Item createItemOfType(String itemType, String itemName) {
|
||||
private @Nullable Item createItemOfType(@Nullable String itemType, String itemName) {
|
||||
if (itemType == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,24 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerId>eclipse</compilerId>
|
||||
<compilerArgs>
|
||||
<!-- Xtend doesn't support type annotations so warn on null analysis issues -->
|
||||
<!-- See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=506374 -->
|
||||
<arg>-warn:+nullAnnot(org.eclipse.jdt.annotation.Nullable|org.eclipse.jdt.annotation.NonNull|org.eclipse.jdt.annotation.NonNullByDefault),+inheritNullAnnot,-nullUncheckedConversion,+null,+inheritNullAnnot,+nullAnnotConflict,-nullUncheckedConversion,+nullAnnotRedundant,+nullDereference</arg>
|
||||
</compilerArgs>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
|
|
|
@ -20,13 +20,15 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.AbstractProvider;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.model.item.BindingConfigParseException;
|
||||
import org.openhab.core.model.item.BindingConfigReader;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkProvider;
|
||||
import org.openhab.core.model.item.BindingConfigParseException;
|
||||
import org.openhab.core.model.item.BindingConfigReader;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +37,7 @@ import org.osgi.service.component.annotations.Component;
|
|||
* @author Oliver Libutzki - Initial contribution
|
||||
* @author Alex Tugarev - Added parsing of multiple Channel UIDs
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ItemChannelLinkProvider.class, BindingConfigReader.class })
|
||||
public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannelLink>
|
||||
implements BindingConfigReader, ItemChannelLinkProvider {
|
||||
|
@ -48,7 +51,7 @@ public class GenericItemChannelLinkProvider extends AbstractProvider<ItemChannel
|
|||
*/
|
||||
protected Map<String, Set<String>> contextMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Set<String> previousItemNames;
|
||||
private @Nullable Set<String> previousItemNames;
|
||||
|
||||
@Override
|
||||
public String getBindingType() {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.core.thing;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.DefaultAbstractManagedProvider;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
|
@ -28,6 +29,7 @@ import org.osgi.service.component.annotations.Reference;
|
|||
* @author Dennis Nobel - Integrated Storage
|
||||
* @author Michael Grammling - Added dynamic configuration update
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ThingProvider.class, ManagedThingProvider.class })
|
||||
public class ManagedThingProvider extends DefaultAbstractManagedProvider<Thing, ThingUID> implements ThingProvider {
|
||||
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
*/
|
||||
package org.openhab.core.thing;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* {@link ThingManager} interface defines methods for managing a {@link Thing}.
|
||||
*
|
||||
* @author Yordan Zhelev - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ThingManager {
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.concurrent.locks.Lock;
|
|||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.SafeCaller;
|
||||
import org.openhab.core.common.ThreadPoolManager;
|
||||
|
@ -120,6 +121,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Christoph Weitkamp - Added preconfigured ChannelGroupBuilder
|
||||
* @author Yordan Zhelev - Added thing disabling mechanism
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ThingTypeMigrationService.class, ThingManager.class })
|
||||
public class ThingManagerImpl
|
||||
implements ThingManager, ThingTracker, ThingTypeMigrationService, ReadyService.ReadyTracker {
|
||||
|
@ -135,31 +137,30 @@ public class ThingManagerImpl
|
|||
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
||||
.getScheduledPool(THING_MANAGER_THREADPOOL_NAME);
|
||||
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
private CommunicationManager communicationManager;
|
||||
|
||||
private ReadyService readyService;
|
||||
|
||||
private final List<ThingHandlerFactory> thingHandlerFactories = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final Map<ThingUID, ThingHandler> thingHandlers = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<ThingHandlerFactory, Set<ThingHandler>> thingHandlersByFactory = new HashMap<>();
|
||||
|
||||
private ThingTypeRegistry thingTypeRegistry;
|
||||
private ChannelTypeRegistry channelTypeRegistry;
|
||||
private ChannelGroupTypeRegistry channelGroupTypeRegistry;
|
||||
private ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
|
||||
private ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService;
|
||||
|
||||
private final Set<Thing> things = new CopyOnWriteArraySet<>();
|
||||
private final Map<ThingUID, Lock> thingLocks = new HashMap<>();
|
||||
private final Set<ThingUID> thingUpdatedLock = new HashSet<>();
|
||||
private final Set<String> loadedXmlThingTypes = new CopyOnWriteArraySet<>();
|
||||
private SafeCaller safeCaller;
|
||||
private volatile boolean active = false;
|
||||
private StorageService storageService;
|
||||
private Storage<String> storage;
|
||||
|
||||
private BundleResolver bundleResolver;
|
||||
|
||||
private final ChannelGroupTypeRegistry channelGroupTypeRegistry;
|
||||
private final ChannelTypeRegistry channelTypeRegistry;
|
||||
private final CommunicationManager communicationManager;
|
||||
private final ConfigDescriptionRegistry configDescriptionRegistry;
|
||||
private final ConfigDescriptionValidator configDescriptionValidator;
|
||||
private final EventPublisher eventPublisher;
|
||||
private final ThingTypeRegistry thingTypeRegistry;
|
||||
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
private final ReadyService readyService;
|
||||
private final SafeCaller safeCaller;
|
||||
private final Storage<String> storage;
|
||||
private final ThingRegistryImpl thingRegistry;
|
||||
private final ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService;
|
||||
|
||||
private final ThingHandlerCallback thingHandlerCallback = new ThingHandlerCallback() {
|
||||
|
||||
|
@ -246,9 +247,9 @@ public class ThingManagerImpl
|
|||
@Override
|
||||
public void thingUpdated(final Thing thing) {
|
||||
thingUpdatedLock.add(thing.getUID());
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<@Nullable Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
public @Nullable Void run() {
|
||||
Provider<Thing> provider = thingRegistry.getProvider(thing);
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
|
@ -347,20 +348,53 @@ public class ThingManagerImpl
|
|||
}
|
||||
};
|
||||
|
||||
private ThingRegistryImpl thingRegistry;
|
||||
@Activate
|
||||
public ThingManagerImpl( //
|
||||
final @Reference BundleResolver bundleResolver,
|
||||
final @Reference ChannelGroupTypeRegistry channelGroupTypeRegistry,
|
||||
final @Reference ChannelTypeRegistry channelTypeRegistry,
|
||||
final @Reference CommunicationManager communicationManager,
|
||||
final @Reference ConfigDescriptionRegistry configDescriptionRegistry,
|
||||
final @Reference ConfigDescriptionValidator configDescriptionValidator,
|
||||
final @Reference EventPublisher eventPublisher,
|
||||
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
|
||||
final @Reference ReadyService readyService, //
|
||||
final @Reference SafeCaller safeCaller, //
|
||||
final @Reference StorageService storageService, //
|
||||
final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService,
|
||||
final @Reference ThingTypeRegistry thingTypeRegistry) {
|
||||
this.bundleResolver = bundleResolver;
|
||||
this.channelGroupTypeRegistry = channelGroupTypeRegistry;
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
this.communicationManager = communicationManager;
|
||||
this.configDescriptionRegistry = configDescriptionRegistry;
|
||||
this.configDescriptionValidator = configDescriptionValidator;
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
this.readyService = readyService;
|
||||
this.safeCaller = safeCaller;
|
||||
this.thingRegistry = (ThingRegistryImpl) thingRegistry;
|
||||
this.thingStatusInfoI18nLocalizationService = thingStatusInfoI18nLocalizationService;
|
||||
this.thingTypeRegistry = thingTypeRegistry;
|
||||
|
||||
private BundleResolver bundleResolver;
|
||||
readyService.registerTracker(this, new ReadyMarkerFilter().withType(XML_THING_TYPE));
|
||||
this.thingRegistry.addThingTracker(this);
|
||||
storage = storageService.getStorage(THING_STATUS_STORAGE_NAME, this.getClass().getClassLoader());
|
||||
}
|
||||
|
||||
private ConfigDescriptionRegistry configDescriptionRegistry;
|
||||
private ConfigDescriptionValidator configDescriptionValidator;
|
||||
|
||||
private final Set<Thing> things = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final Set<ThingUID> thingUpdatedLock = new HashSet<>();
|
||||
@Deactivate
|
||||
protected synchronized void deactivate(ComponentContext componentContext) {
|
||||
thingRegistry.removeThingTracker(this);
|
||||
for (ThingHandlerFactory factory : thingHandlerFactories) {
|
||||
removeThingHandlerFactory(factory);
|
||||
}
|
||||
readyService.unregisterTracker(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateThingType(final Thing thing, final ThingTypeUID thingTypeUID,
|
||||
final Configuration configuration) {
|
||||
final @Nullable Configuration configuration) {
|
||||
final ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID);
|
||||
if (thingType == null) {
|
||||
throw new IllegalStateException(
|
||||
|
@ -379,8 +413,12 @@ public class ThingManagerImpl
|
|||
final ThingHandlerFactory oldThingHandlerFactory = findThingHandlerFactory(thing.getThingTypeUID());
|
||||
if (oldThingHandlerFactory != null) {
|
||||
ThingHandler thingHandler = thing.getHandler();
|
||||
unregisterAndDisposeHandler(oldThingHandlerFactory, thing, thingHandler);
|
||||
waitUntilHandlerUnregistered(thing, 60 * 1000);
|
||||
if (thingHandler != null) {
|
||||
unregisterAndDisposeHandler(oldThingHandlerFactory, thing, thingHandler);
|
||||
waitUntilHandlerUnregistered(thing, 60 * 1000);
|
||||
} else {
|
||||
logger.debug("No ThingHandler to dispose for {}", thing.getUID());
|
||||
}
|
||||
} else {
|
||||
logger.debug("No ThingHandlerFactory available that can handle {}", thing.getThingTypeUID());
|
||||
}
|
||||
|
@ -511,7 +549,12 @@ public class ThingManagerImpl
|
|||
logger.debug("Replacing uninitialized handler for updated thing '{}'",
|
||||
thing.getThingTypeUID());
|
||||
ThingHandlerFactory thingHandlerFactory = getThingHandlerFactory(thing);
|
||||
unregisterHandler(thingHandler.getThing(), thingHandlerFactory);
|
||||
if (thingHandlerFactory != null) {
|
||||
unregisterHandler(thingHandler.getThing(), thingHandlerFactory);
|
||||
} else {
|
||||
logger.debug("No ThingHandlerFactory available that can handle {}",
|
||||
thing.getThingTypeUID());
|
||||
}
|
||||
registerAndInitializeHandler(thing, thingHandlerFactory);
|
||||
}
|
||||
}
|
||||
|
@ -524,16 +567,18 @@ public class ThingManagerImpl
|
|||
}
|
||||
}
|
||||
|
||||
private ThingHandler replaceThing(Thing oldThing, Thing newThing) {
|
||||
private @Nullable ThingHandler replaceThing(@Nullable Thing oldThing, Thing newThing) {
|
||||
final ThingHandler thingHandler = thingHandlers.get(newThing.getUID());
|
||||
if (oldThing != newThing) {
|
||||
this.things.remove(oldThing);
|
||||
if (oldThing != null) {
|
||||
this.things.remove(oldThing);
|
||||
}
|
||||
this.things.add(newThing);
|
||||
}
|
||||
return thingHandler;
|
||||
}
|
||||
|
||||
private Thing getThing(ThingUID id) {
|
||||
private @Nullable Thing getThing(ThingUID id) {
|
||||
for (Thing thing : this.things) {
|
||||
if (thing.getUID().equals(id)) {
|
||||
return thing;
|
||||
|
@ -546,7 +591,7 @@ public class ThingManagerImpl
|
|||
return thingTypeRegistry.getThingType(thing.getThingTypeUID());
|
||||
}
|
||||
|
||||
private ThingHandlerFactory findThingHandlerFactory(ThingTypeUID thingTypeUID) {
|
||||
private @Nullable ThingHandlerFactory findThingHandlerFactory(ThingTypeUID thingTypeUID) {
|
||||
for (ThingHandlerFactory factory : thingHandlerFactories) {
|
||||
if (factory.supportsThingType(thingTypeUID)) {
|
||||
return factory;
|
||||
|
@ -645,11 +690,9 @@ public class ThingManagerImpl
|
|||
ThingHandler handler = thing.getHandler();
|
||||
if (handler == null) {
|
||||
throw new IllegalStateException("Handler should not be null here");
|
||||
} else {
|
||||
if (handler.getThing() != thing) {
|
||||
logger.warn("The model of {} is inconsistent [thing.getHandler().getThing() != thing]",
|
||||
thing.getUID());
|
||||
}
|
||||
}
|
||||
if (handler.getThing() != thing) {
|
||||
logger.warn("The model of {} is inconsistent [thing.getHandler().getThing() != thing]", thing.getUID());
|
||||
}
|
||||
ThingType thingType = getThingType(thing);
|
||||
if (thingType != null) {
|
||||
|
@ -659,7 +702,7 @@ public class ThingManagerImpl
|
|||
|
||||
if (isInitializable(thing, thingType)) {
|
||||
setThingStatus(thing, buildStatusInfo(ThingStatus.INITIALIZING, ThingStatusDetail.NONE));
|
||||
doInitializeHandler(thing.getHandler());
|
||||
doInitializeHandler(handler);
|
||||
} else {
|
||||
logger.debug("Thing '{}' not initializable, check required configuration parameters.", thing.getUID());
|
||||
setThingStatus(thing,
|
||||
|
@ -670,7 +713,7 @@ public class ThingManagerImpl
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isInitializable(Thing thing, ThingType thingType) {
|
||||
private boolean isInitializable(Thing thing, @Nullable ThingType thingType) {
|
||||
if (!isComplete(thingType, thing.getUID(), tt -> tt.getConfigDescriptionURI(), thing.getConfiguration())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -696,8 +739,8 @@ public class ThingManagerImpl
|
|||
* @param configuration the current configuration
|
||||
* @return true if all required configuration parameters are given, false otherwise
|
||||
*/
|
||||
private <T extends Identifiable<?>> boolean isComplete(T prototype, UID targetUID,
|
||||
Function<T, URI> configDescriptionURIFunction, Configuration configuration) {
|
||||
private <T extends Identifiable<?>> boolean isComplete(@Nullable T prototype, UID targetUID,
|
||||
Function<T, @Nullable URI> configDescriptionURIFunction, Configuration configuration) {
|
||||
if (prototype == null) {
|
||||
logger.debug("Prototype for '{}' is not known, assuming it is initializable", targetUID);
|
||||
return true;
|
||||
|
@ -718,12 +761,8 @@ public class ThingManagerImpl
|
|||
return propertyKeys.containsAll(requiredParameters);
|
||||
}
|
||||
|
||||
private ConfigDescription resolve(URI configDescriptionURI, Locale locale) {
|
||||
if (configDescriptionURI == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return configDescriptionRegistry != null
|
||||
private @Nullable ConfigDescription resolve(@Nullable URI configDescriptionURI, @Nullable Locale locale) {
|
||||
return configDescriptionURI != null
|
||||
? configDescriptionRegistry.getConfigDescription(configDescriptionURI, locale)
|
||||
: null;
|
||||
}
|
||||
|
@ -770,9 +809,12 @@ public class ThingManagerImpl
|
|||
return thing.getBridgeUID() != null;
|
||||
}
|
||||
|
||||
private Bridge getBridge(ThingUID bridgeUID) {
|
||||
private @Nullable Bridge getBridge(@Nullable ThingUID bridgeUID) {
|
||||
if (bridgeUID == null) {
|
||||
return null;
|
||||
}
|
||||
Thing bridge = thingRegistry.get(bridgeUID);
|
||||
return isBridge(bridge) ? (Bridge) bridge : null;
|
||||
return bridge instanceof Bridge ? (Bridge) bridge : null;
|
||||
}
|
||||
|
||||
private void unregisterHandler(Thing thing, ThingHandlerFactory thingHandlerFactory) {
|
||||
|
@ -969,9 +1011,9 @@ public class ThingManagerImpl
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<@Nullable Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
public @Nullable Void run() {
|
||||
thingRegistry.forceRemove(thing.getUID());
|
||||
return null;
|
||||
}
|
||||
|
@ -988,32 +1030,11 @@ public class ThingManagerImpl
|
|||
});
|
||||
}
|
||||
|
||||
@Activate
|
||||
protected synchronized void activate(ComponentContext componentContext) {
|
||||
readyService.registerTracker(this, new ReadyMarkerFilter().withType(XML_THING_TYPE));
|
||||
for (ThingHandlerFactory factory : thingHandlerFactories) {
|
||||
handleThingHandlerFactoryAddition(getBundleIdentifier(factory));
|
||||
}
|
||||
thingRegistry.addThingTracker(this);
|
||||
active = true;
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
||||
protected synchronized void addThingHandlerFactory(ThingHandlerFactory thingHandlerFactory) {
|
||||
logger.debug("Thing handler factory '{}' added", thingHandlerFactory.getClass().getSimpleName());
|
||||
thingHandlerFactories.add(thingHandlerFactory);
|
||||
if (active) {
|
||||
handleThingHandlerFactoryAddition(getBundleIdentifier(thingHandlerFactory));
|
||||
}
|
||||
}
|
||||
|
||||
@Reference
|
||||
public void setReadyService(ReadyService readyService) {
|
||||
this.readyService = readyService;
|
||||
}
|
||||
|
||||
public void unsetReadyService(ReadyService readyService) {
|
||||
this.readyService = null;
|
||||
handleThingHandlerFactoryAddition(getBundleIdentifier(thingHandlerFactory));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1049,7 +1070,8 @@ public class ThingManagerImpl
|
|||
return ReadyMarkerUtils.getIdentifier(bundleResolver.resolveBundle(thingHandlerFactory.getClass()));
|
||||
}
|
||||
|
||||
private void registerAndInitializeHandler(final Thing thing, final ThingHandlerFactory thingHandlerFactory) {
|
||||
private void registerAndInitializeHandler(final Thing thing,
|
||||
final @Nullable ThingHandlerFactory thingHandlerFactory) {
|
||||
if (thingHandlerFactory != null) {
|
||||
final String identifier = getBundleIdentifier(thingHandlerFactory);
|
||||
if (loadedXmlThingTypes.contains(identifier)) {
|
||||
|
@ -1066,7 +1088,7 @@ public class ThingManagerImpl
|
|||
}
|
||||
}
|
||||
|
||||
private ThingHandlerFactory getThingHandlerFactory(Thing thing) {
|
||||
private @Nullable ThingHandlerFactory getThingHandlerFactory(Thing thing) {
|
||||
ThingHandlerFactory thingHandlerFactory = findThingHandlerFactory(thing.getThingTypeUID());
|
||||
if (thingHandlerFactory != null) {
|
||||
return thingHandlerFactory;
|
||||
|
@ -1076,22 +1098,10 @@ public class ThingManagerImpl
|
|||
return null;
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
protected synchronized void deactivate(ComponentContext componentContext) {
|
||||
active = false;
|
||||
thingRegistry.removeThingTracker(this);
|
||||
for (ThingHandlerFactory factory : thingHandlerFactories) {
|
||||
removeThingHandlerFactory(factory);
|
||||
}
|
||||
readyService.unregisterTracker(this);
|
||||
}
|
||||
|
||||
protected synchronized void removeThingHandlerFactory(ThingHandlerFactory thingHandlerFactory) {
|
||||
logger.debug("Thing handler factory '{}' removed", thingHandlerFactory.getClass().getSimpleName());
|
||||
thingHandlerFactories.remove(thingHandlerFactory);
|
||||
if (active) {
|
||||
handleThingHandlerFactoryRemoval(thingHandlerFactory);
|
||||
}
|
||||
handleThingHandlerFactoryRemoval(thingHandlerFactory);
|
||||
}
|
||||
|
||||
private void handleThingHandlerFactoryRemoval(ThingHandlerFactory thingHandlerFactory) {
|
||||
|
@ -1117,53 +1127,8 @@ public class ThingManagerImpl
|
|||
return thingLocks.get(thingUID);
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setEventPublisher(EventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setThingRegistry(ThingRegistry thingRegistry) {
|
||||
this.thingRegistry = (ThingRegistryImpl) thingRegistry;
|
||||
}
|
||||
|
||||
protected void unsetEventPublisher(EventPublisher eventPublisher) {
|
||||
this.eventPublisher = null;
|
||||
}
|
||||
|
||||
protected void unsetThingRegistry(ThingRegistry thingRegistry) {
|
||||
this.thingRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setConfigDescriptionRegistry(ConfigDescriptionRegistry configDescriptionRegistry) {
|
||||
this.configDescriptionRegistry = configDescriptionRegistry;
|
||||
}
|
||||
|
||||
protected void unsetConfigDescriptionRegistry(ConfigDescriptionRegistry configDescriptionRegistry) {
|
||||
this.configDescriptionRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setConfigDescriptionValidator(ConfigDescriptionValidator configDescriptionValidator) {
|
||||
this.configDescriptionValidator = configDescriptionValidator;
|
||||
}
|
||||
|
||||
protected void unsetConfigDescriptionValidator(ConfigDescriptionValidator configDescriptionValidator) {
|
||||
this.configDescriptionValidator = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setBundleResolver(BundleResolver bundleResolver) {
|
||||
this.bundleResolver = bundleResolver;
|
||||
}
|
||||
|
||||
protected void unsetBundleResolver(BundleResolver bundleResolver) {
|
||||
this.bundleResolver = bundleResolver;
|
||||
}
|
||||
|
||||
private ThingStatusInfo buildStatusInfo(ThingStatus thingStatus, ThingStatusDetail thingStatusDetail,
|
||||
String description) {
|
||||
@Nullable String description) {
|
||||
ThingStatusInfoBuilder statusInfoBuilder = ThingStatusInfoBuilder.create(thingStatus, thingStatusDetail);
|
||||
statusInfoBuilder.withDescription(description);
|
||||
return statusInfoBuilder.build();
|
||||
|
@ -1228,11 +1193,19 @@ public class ThingManagerImpl
|
|||
|
||||
logger.debug("Thing {} will be disabled.", thingUID);
|
||||
|
||||
boolean disposed = false;
|
||||
|
||||
if (isHandlerRegistered(thing)) {
|
||||
// Dispose handler if registered.
|
||||
ThingHandler thingHandler = thing.getHandler();
|
||||
ThingHandlerFactory thingHandlerFactory = findThingHandlerFactory(thing.getThingTypeUID());
|
||||
unregisterAndDisposeHandler(thingHandlerFactory, thing, thing.getHandler());
|
||||
} else {
|
||||
if (thingHandler != null && thingHandlerFactory != null) {
|
||||
unregisterAndDisposeHandler(thingHandlerFactory, thing, thingHandler);
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!disposed) {
|
||||
// Only set the correct status to the thing. There is no handler to be disposed
|
||||
setThingStatus(thing, buildStatusInfo(ThingStatus.UNINITIALIZED, ThingStatusDetail.DISABLED));
|
||||
}
|
||||
|
@ -1254,12 +1227,6 @@ public class ThingManagerImpl
|
|||
}
|
||||
|
||||
private void persistThingEnableStatus(ThingUID thingUID, boolean enabled) {
|
||||
if (storage == null) {
|
||||
logger.debug("Cannot persist enable status of thing with UID {}. Persistent storage unavailable.",
|
||||
thingUID);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug("Thing with UID {} will be persisted as {}.", thingUID, enabled ? "enabled." : "disabled.");
|
||||
if (enabled) {
|
||||
// Clear the disabled thing storage. Otherwise the handler will NOT be initialized later.
|
||||
|
@ -1283,86 +1250,11 @@ public class ThingManagerImpl
|
|||
}
|
||||
|
||||
private boolean isDisabledByStorage(ThingUID thingUID) {
|
||||
return storage != null && storage.containsKey(thingUID.getAsString());
|
||||
return storage.containsKey(thingUID.getAsString());
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setThingTypeRegistry(ThingTypeRegistry thingTypeRegistry) {
|
||||
this.thingTypeRegistry = thingTypeRegistry;
|
||||
void setBundleResolver(BundleResolver bundleResolver) {
|
||||
this.bundleResolver = bundleResolver;
|
||||
}
|
||||
|
||||
protected void unsetThingTypeRegistry(ThingTypeRegistry thingTypeRegistry) {
|
||||
this.thingTypeRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setChannelTypeRegistry(ChannelTypeRegistry channelTypeRegistry) {
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
}
|
||||
|
||||
protected void unsetChannelTypeRegistry(ChannelTypeRegistry channelTypeRegistry) {
|
||||
this.channelTypeRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setChannelGroupTypeRegistry(ChannelGroupTypeRegistry channelGroupTypeRegistry) {
|
||||
this.channelGroupTypeRegistry = channelGroupTypeRegistry;
|
||||
}
|
||||
|
||||
protected void unsetChannelGroupTypeRegistry(ChannelGroupTypeRegistry channelGroupTypeRegistry) {
|
||||
this.channelGroupTypeRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
}
|
||||
|
||||
protected void unsetItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
||||
this.itemChannelLinkRegistry = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setThingStatusInfoI18nLocalizationService(
|
||||
ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService) {
|
||||
this.thingStatusInfoI18nLocalizationService = thingStatusInfoI18nLocalizationService;
|
||||
}
|
||||
|
||||
protected void unsetThingStatusInfoI18nLocalizationService(
|
||||
ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService) {
|
||||
this.thingStatusInfoI18nLocalizationService = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setInboundCommunication(CommunicationManager communicationManager) {
|
||||
this.communicationManager = communicationManager;
|
||||
}
|
||||
|
||||
protected void unsetInboundCommunication(CommunicationManager communicationManager) {
|
||||
this.communicationManager = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setSafeCaller(SafeCaller safeCaller) {
|
||||
this.safeCaller = safeCaller;
|
||||
}
|
||||
|
||||
protected void unsetSafeCaller(SafeCaller safeCaller) {
|
||||
this.safeCaller = null;
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setStorageService(StorageService storageService) {
|
||||
if (this.storageService != storageService) {
|
||||
this.storageService = storageService;
|
||||
storage = storageService.getStorage(THING_STATUS_STORAGE_NAME, this.getClass().getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
protected void unsetStorageService(StorageService storageService) {
|
||||
if (this.storageService == storageService) {
|
||||
this.storageService = null;
|
||||
this.storage = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.core.thing.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingRegistryChangeListener;
|
||||
|
||||
|
@ -25,6 +26,7 @@ import org.openhab.core.thing.ThingRegistryChangeListener;
|
|||
* @author Michael Grammling - Added dynamic configuration update
|
||||
* @author Simon Kaufmann - Added THING_REMOVING state
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ThingTracker {
|
||||
|
||||
public enum ThingTrackerEvent {
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.core.thing.link;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.DefaultAbstractManagedProvider;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
@ -27,6 +28,7 @@ import org.osgi.service.component.annotations.Reference;
|
|||
*
|
||||
* @author Dennis Nobel - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ItemChannelLinkProvider.class, ManagedItemChannelLinkProvider.class })
|
||||
public class ManagedItemChannelLinkProvider extends DefaultAbstractManagedProvider<ItemChannelLink, String>
|
||||
implements ItemChannelLinkProvider {
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
@ -60,18 +61,12 @@ public class ChannelItemProviderTest {
|
|||
private static final NumberItem ITEM = new NumberItem(ITEM_NAME);
|
||||
private static final ItemChannelLink LINK = new ItemChannelLink(ITEM_NAME, CHANNEL_UID);
|
||||
|
||||
@Mock
|
||||
private ItemRegistry itemRegistry;
|
||||
@Mock
|
||||
private ThingRegistry thingRegistry;
|
||||
@Mock
|
||||
private ItemFactory itemFactory;
|
||||
@Mock
|
||||
private ProviderChangeListener<Item> listener;
|
||||
@Mock
|
||||
private LocaleProvider localeProvider;
|
||||
@Mock
|
||||
private ItemChannelLinkRegistry linkRegistry;
|
||||
private @Mock ItemFactory itemFactoryMock;
|
||||
private @Mock ItemRegistry itemRegistryMock;
|
||||
private @Mock ItemChannelLinkRegistry linkRegistryMock;
|
||||
private @Mock ProviderChangeListener<@NonNull Item> listenerMock;
|
||||
private @Mock LocaleProvider localeProviderMock;
|
||||
private @Mock ThingRegistry thingRegistryMock;
|
||||
|
||||
private ChannelItemProvider provider;
|
||||
|
||||
|
@ -86,9 +81,9 @@ public class ChannelItemProviderTest {
|
|||
props.put("initialDelay", "false");
|
||||
provider.activate(props);
|
||||
|
||||
when(thingRegistry.getChannel(same(CHANNEL_UID))).thenReturn(CHANNEL);
|
||||
when(itemFactory.createItem(CoreItemFactory.NUMBER, ITEM_NAME)).thenReturn(ITEM);
|
||||
when(localeProvider.getLocale()).thenReturn(Locale.ENGLISH);
|
||||
when(thingRegistryMock.getChannel(same(CHANNEL_UID))).thenReturn(CHANNEL);
|
||||
when(itemFactoryMock.createItem(CoreItemFactory.NUMBER, ITEM_NAME)).thenReturn(ITEM);
|
||||
when(localeProviderMock.getLocale()).thenReturn(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -96,17 +91,17 @@ public class ChannelItemProviderTest {
|
|||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.added(THING);
|
||||
verify(listener, only()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromThingAlreadyExists() {
|
||||
when(itemRegistry.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
|
||||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.added(THING);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,22 +111,22 @@ public class ChannelItemProviderTest {
|
|||
resetAndPrepareListener();
|
||||
|
||||
provider.thingRegistryListener.removed(THING);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(listener, only()).removed(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromLinkNotThere() {
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listener, only()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCreationFromLinkAlreadyExists() {
|
||||
when(itemRegistry.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME))).thenReturn(ITEM);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -141,8 +136,8 @@ public class ChannelItemProviderTest {
|
|||
resetAndPrepareListener();
|
||||
|
||||
provider.linkRegistryListener.removed(LINK);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(listener, only()).removed(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -152,14 +147,14 @@ public class ChannelItemProviderTest {
|
|||
resetAndPrepareListener();
|
||||
|
||||
provider.itemRegistryListener.beforeAdding(new NumberItem(ITEM_NAME));
|
||||
verify(listener, only()).removed(same(provider), same(ITEM));
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(listenerMock, only()).removed(same(provider), same(ITEM));
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableBeforeDelayedInitialization() throws Exception {
|
||||
provider = createProvider();
|
||||
reset(linkRegistry);
|
||||
reset(linkRegistryMock);
|
||||
|
||||
// Set the initialization delay to 40ms so we don't have to wait 2000ms to do the assertion
|
||||
Field field = ChannelItemProvider.class.getDeclaredField("INITIALIZATION_DELAY_NANOS");
|
||||
|
@ -174,8 +169,8 @@ public class ChannelItemProviderTest {
|
|||
provider.activate(props);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistry, never()).getAll();
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistryMock, never()).getAll();
|
||||
|
||||
props = new HashMap<>();
|
||||
props.put("enabled", "false");
|
||||
|
@ -184,32 +179,32 @@ public class ChannelItemProviderTest {
|
|||
Thread.sleep(100);
|
||||
|
||||
provider.linkRegistryListener.added(LINK);
|
||||
verify(listener, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistry, never()).getAll();
|
||||
verify(listenerMock, never()).added(same(provider), same(ITEM));
|
||||
verify(linkRegistryMock, never()).getAll();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void resetAndPrepareListener() {
|
||||
reset(listener);
|
||||
reset(listenerMock);
|
||||
doAnswer(invocation -> {
|
||||
// this is crucial as it mimics the real ItemRegistry's behavior
|
||||
provider.itemRegistryListener.afterRemoving((Item) invocation.getArguments()[1]);
|
||||
return null;
|
||||
}).when(listener).removed(same(provider), any(Item.class));
|
||||
}).when(listenerMock).removed(same(provider), any(Item.class));
|
||||
doAnswer(invocation -> {
|
||||
// this is crucial as it mimics the real ItemRegistry's behavior
|
||||
provider.itemRegistryListener.beforeAdding((Item) invocation.getArguments()[1]);
|
||||
return null;
|
||||
}).when(listener).added(same(provider), any(Item.class));
|
||||
when(linkRegistry.getBoundChannels(eq(ITEM_NAME))).thenReturn(Collections.singleton(CHANNEL_UID));
|
||||
when(linkRegistry.getLinks(eq(CHANNEL_UID))).thenReturn(Collections.singleton(LINK));
|
||||
}).when(listenerMock).added(same(provider), any(Item.class));
|
||||
when(linkRegistryMock.getBoundChannels(eq(ITEM_NAME))).thenReturn(Collections.singleton(CHANNEL_UID));
|
||||
when(linkRegistryMock.getLinks(eq(CHANNEL_UID))).thenReturn(Collections.singleton(LINK));
|
||||
}
|
||||
|
||||
private ChannelItemProvider createProvider() {
|
||||
ChannelItemProvider provider = new ChannelItemProvider(localeProvider, mock(ChannelTypeRegistry.class),
|
||||
thingRegistry, itemRegistry, linkRegistry);
|
||||
provider.addItemFactory(itemFactory);
|
||||
provider.addProviderChangeListener(listener);
|
||||
ChannelItemProvider provider = new ChannelItemProvider(localeProviderMock, mock(ChannelTypeRegistry.class),
|
||||
thingRegistryMock, itemRegistryMock, linkRegistryMock);
|
||||
provider.addItemFactory(itemFactoryMock);
|
||||
provider.addProviderChangeListener(listenerMock);
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,103 +17,129 @@ import static org.mockito.ArgumentMatchers.*;
|
|||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.openhab.core.common.SafeCaller;
|
||||
import org.openhab.core.config.core.ConfigDescriptionRegistry;
|
||||
import org.openhab.core.config.core.validation.ConfigDescriptionValidator;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.service.ReadyService;
|
||||
import org.openhab.core.storage.Storage;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.openhab.core.thing.i18n.ThingStatusInfoI18nLocalizationService;
|
||||
import org.openhab.core.thing.internal.ThingTracker.ThingTrackerEvent;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||
import org.openhab.core.thing.type.ChannelGroupTypeRegistry;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.openhab.core.thing.type.ThingTypeRegistry;
|
||||
import org.openhab.core.util.BundleResolver;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
|
||||
/**
|
||||
* @author Simon Kaufmann - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ThingManagerImplTest {
|
||||
|
||||
private @Mock BundleResolver mockBundleResolver;
|
||||
private @Mock Bundle mockBundle;
|
||||
private @Mock ComponentContext mockComponentContext;
|
||||
private @Mock ReadyService mockReadyService;
|
||||
private @Mock Thing mockThing;
|
||||
private @Mock @NonNullByDefault({}) Bundle bundleMock;
|
||||
private @Mock @NonNullByDefault({}) BundleResolver bundleResolverMock;
|
||||
private @Mock @NonNullByDefault({}) ChannelGroupTypeRegistry channelGroupTypeRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ChannelTypeRegistry channelTypeRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) CommunicationManager communicationManagerMock;
|
||||
private @Mock @NonNullByDefault({}) EventPublisher eventPublisherMock;
|
||||
private @Mock @NonNullByDefault({}) ConfigDescriptionRegistry configDescriptionRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ConfigDescriptionValidator configDescriptionValidatorMock;
|
||||
private @Mock @NonNullByDefault({}) ItemChannelLinkRegistry itemChannelLinkRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ThingTypeRegistry thingTypeRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ReadyService readyServiceMock;
|
||||
private @Mock @NonNullByDefault({}) SafeCaller safeCallerMock;
|
||||
private @Mock @NonNullByDefault({}) Storage<Object> storageMock;
|
||||
private @Mock @NonNullByDefault({}) StorageService storageServiceMock;
|
||||
private @Mock @NonNullByDefault({}) Thing thingMock;
|
||||
private @Mock @NonNullByDefault({}) ThingRegistryImpl thingRegistryMock;
|
||||
|
||||
private @Mock StorageService mockStorageService;
|
||||
private @Mock Storage<Object> mockStorage;
|
||||
|
||||
private final ThingRegistryImpl thingRegistry = new ThingRegistryImpl();
|
||||
// This class is final so it cannot be mocked
|
||||
private final ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService = new ThingStatusInfoI18nLocalizationService();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
initMocks(this);
|
||||
when(mockBundle.getSymbolicName()).thenReturn("test");
|
||||
when(mockBundleResolver.resolveBundle(any())).thenReturn(mockBundle);
|
||||
when(mockThing.getUID()).thenReturn(new ThingUID("test", "thing"));
|
||||
|
||||
when(bundleMock.getSymbolicName()).thenReturn("test");
|
||||
when(bundleResolverMock.resolveBundle(any())).thenReturn(bundleMock);
|
||||
when(thingMock.getUID()).thenReturn(new ThingUID("test", "thing"));
|
||||
}
|
||||
|
||||
private ThingManagerImpl createThingManager() {
|
||||
return new ThingManagerImpl(bundleResolverMock, channelGroupTypeRegistryMock, channelTypeRegistryMock,
|
||||
communicationManagerMock, configDescriptionRegistryMock, configDescriptionValidatorMock,
|
||||
eventPublisherMock, itemChannelLinkRegistryMock, readyServiceMock, safeCallerMock, storageServiceMock,
|
||||
thingRegistryMock, thingStatusInfoI18nLocalizationService, thingTypeRegistryMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThingHandlerFactoryLifecycle() {
|
||||
public void thingHandlerFactoryLifecycle() {
|
||||
ThingHandlerFactory mockFactory1 = mock(ThingHandlerFactory.class);
|
||||
ThingHandlerFactory mockFactory2 = mock(ThingHandlerFactory.class);
|
||||
|
||||
ThingManagerImpl thingManager = new ThingManagerImpl();
|
||||
thingManager.setBundleResolver(mockBundleResolver);
|
||||
thingManager.setThingRegistry(thingRegistry);
|
||||
thingManager.setReadyService(mockReadyService);
|
||||
thingManager.thingAdded(mockThing, null);
|
||||
ThingManagerImpl thingManager = createThingManager();
|
||||
|
||||
thingManager.thingAdded(thingMock, ThingTrackerEvent.THING_ADDED);
|
||||
|
||||
// ensure usage is delayed until activation
|
||||
thingManager.addThingHandlerFactory(mockFactory1);
|
||||
verify(mockFactory1, times(0)).supportsThingType(any());
|
||||
thingManager.activate(mockComponentContext);
|
||||
verify(mockFactory1, atLeastOnce()).supportsThingType(any());
|
||||
thingManager.removeThingHandlerFactory(mockFactory1);
|
||||
|
||||
// ensure it is directly used
|
||||
thingManager.addThingHandlerFactory(mockFactory2);
|
||||
verify(mockFactory2, atLeastOnce()).supportsThingType(any());
|
||||
thingManager.removeThingHandlerFactory(mockFactory2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallSetEnabledWithUnknownThingUID() throws Exception {
|
||||
public void setEnabledWithUnknownThingUID() throws Exception {
|
||||
ThingUID unknownUID = new ThingUID("someBundle", "someType", "someID");
|
||||
ThingManagerImpl thingManager = new ThingManagerImpl();
|
||||
|
||||
when(mockStorageService.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(mockStorage);
|
||||
thingManager.setStorageService(mockStorageService);
|
||||
when(storageServiceMock.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(storageMock);
|
||||
|
||||
ThingManagerImpl thingManager = createThingManager();
|
||||
|
||||
thingManager.setEnabled(unknownUID, true);
|
||||
verify(mockStorage).remove(eq(unknownUID.getAsString()));
|
||||
verify(storageMock).remove(eq(unknownUID.getAsString()));
|
||||
|
||||
thingManager.setEnabled(unknownUID, false);
|
||||
verify(mockStorage).put(eq(unknownUID.getAsString()), eq(""));
|
||||
verify(storageMock).put(eq(unknownUID.getAsString()), eq(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallIsEnabledWithUnknownThingUIDAndNullStorage() throws Exception {
|
||||
public void isEnabledWithUnknownThingUIDAndNullStorage() throws Exception {
|
||||
ThingUID unknownUID = new ThingUID("someBundle", "someType", "someID");
|
||||
ThingManagerImpl thingManager = new ThingManagerImpl();
|
||||
|
||||
when(mockStorageService.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(mockStorage);
|
||||
thingManager.setStorageService(mockStorageService);
|
||||
when(storageServiceMock.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(storageMock);
|
||||
|
||||
ThingManagerImpl thingManager = createThingManager();
|
||||
|
||||
assertEquals(thingManager.isEnabled(unknownUID), true);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallIsEnabledWithUnknownThingUIDAndNonNullStorage() throws Exception {
|
||||
public void isEnabledWithUnknownThingUIDAndNonNullStorage() throws Exception {
|
||||
ThingUID unknownUID = new ThingUID("someBundle", "someType", "someID");
|
||||
ThingManagerImpl thingManager = new ThingManagerImpl();
|
||||
|
||||
when(mockStorage.containsKey(unknownUID.getAsString())).thenReturn(false);
|
||||
when(mockStorageService.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(mockStorage);
|
||||
thingManager.setStorageService(mockStorageService);
|
||||
when(storageMock.containsKey(unknownUID.getAsString())).thenReturn(false);
|
||||
when(storageServiceMock.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(storageMock);
|
||||
|
||||
ThingManagerImpl thingManager = createThingManager();
|
||||
|
||||
assertEquals(thingManager.isEnabled(unknownUID), true);
|
||||
|
||||
when(mockStorage.containsKey(unknownUID.getAsString())).thenReturn(true);
|
||||
when(mockStorageService.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(mockStorage);
|
||||
thingManager.setStorageService(mockStorageService);
|
||||
when(storageMock.containsKey(unknownUID.getAsString())).thenReturn(true);
|
||||
when(storageServiceMock.getStorage(eq("thing_status_storage"), any(ClassLoader.class))).thenReturn(storageMock);
|
||||
|
||||
assertEquals(thingManager.isEnabled(unknownUID), false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.util.Objects;
|
|||
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.storage.Storage;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -41,8 +43,9 @@ import org.slf4j.LoggerFactory;
|
|||
* @param <PE>
|
||||
* type of the persistable element
|
||||
*/
|
||||
public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE> extends AbstractProvider<E>
|
||||
implements ManagedProvider<E, K> {
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractManagedProvider<@NonNull E extends Identifiable<K>, @NonNull K, PE>
|
||||
extends AbstractProvider<E> implements ManagedProvider<E, K> {
|
||||
|
||||
private volatile Storage<PE> storage;
|
||||
|
||||
|
@ -67,37 +70,26 @@ public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE>
|
|||
|
||||
@Override
|
||||
public Collection<E> getAll() {
|
||||
return storage.getKeys().stream().map(key -> {
|
||||
PE persistableElement = storage.get(key);
|
||||
if (persistableElement != null) {
|
||||
return toElement(key, persistableElement);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
return (Collection<E>) storage.getKeys().stream().map(this::getElement).filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(K key) {
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("Cannot get null element");
|
||||
}
|
||||
public @Nullable E get(K key) {
|
||||
return getElement(keyToString(key));
|
||||
}
|
||||
|
||||
String keyAsString = keyToString(key);
|
||||
|
||||
PE persistableElement = storage.get(keyAsString);
|
||||
if (persistableElement != null) {
|
||||
return toElement(keyAsString, persistableElement);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
private @Nullable E getElement(String key) {
|
||||
PE persistableElement = storage.get(key);
|
||||
return persistableElement != null ? toElement(key, persistableElement) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(K key) {
|
||||
public @Nullable E remove(K key) {
|
||||
String keyAsString = keyToString(key);
|
||||
PE persistableElement = storage.remove(keyAsString);
|
||||
if (persistableElement != null) {
|
||||
@Nullable
|
||||
E element = toElement(keyAsString, persistableElement);
|
||||
if (element != null) {
|
||||
notifyListenersAboutRemovedElement(element);
|
||||
|
@ -110,12 +102,16 @@ public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE>
|
|||
}
|
||||
|
||||
@Override
|
||||
public E update(E element) {
|
||||
public @Nullable E update(E element) {
|
||||
String key = getKeyAsString(element);
|
||||
if (storage.get(key) != null) {
|
||||
PE persistableElement = storage.put(key, toPersistableElement(element));
|
||||
if (persistableElement != null) {
|
||||
@Nullable
|
||||
E oldElement = toElement(key, persistableElement);
|
||||
if (oldElement == null) {
|
||||
oldElement = element;
|
||||
}
|
||||
notifyListenersAboutUpdatedElement(oldElement, element);
|
||||
logger.debug("Updated element {} in {}.", key, this.getClass().getSimpleName());
|
||||
return oldElement;
|
||||
|
@ -128,7 +124,7 @@ public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE>
|
|||
return null;
|
||||
}
|
||||
|
||||
private @NonNull String getKeyAsString(@NonNull E element) {
|
||||
private String getKeyAsString(E element) {
|
||||
return keyToString(element.getUID());
|
||||
}
|
||||
|
||||
|
@ -145,7 +141,7 @@ public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE>
|
|||
* @param key key
|
||||
* @return string representation of the key
|
||||
*/
|
||||
protected abstract @NonNull String keyToString(@NonNull K key);
|
||||
protected abstract String keyToString(K key);
|
||||
|
||||
/**
|
||||
* Converts the persistable element into the original element.
|
||||
|
@ -154,7 +150,7 @@ public abstract class AbstractManagedProvider<E extends Identifiable<K>, K, PE>
|
|||
* @param persistableElement persistable element
|
||||
* @return original element
|
||||
*/
|
||||
protected abstract E toElement(@NonNull String key, @NonNull PE persistableElement);
|
||||
protected abstract @Nullable E toElement(String key, @NonNull PE persistableElement);
|
||||
|
||||
/**
|
||||
* Converts the original element into an element that can be persisted.
|
||||
|
|
|
@ -15,6 +15,9 @@ package org.openhab.core.common.registry;
|
|||
import java.util.List;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -27,7 +30,8 @@ import org.slf4j.LoggerFactory;
|
|||
* @param <E>
|
||||
* type of the provided elements
|
||||
*/
|
||||
public abstract class AbstractProvider<E> implements Provider<E> {
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractProvider<@NonNull E> implements Provider<E> {
|
||||
|
||||
private enum EventType {
|
||||
ADDED,
|
||||
|
@ -48,7 +52,7 @@ public abstract class AbstractProvider<E> implements Provider<E> {
|
|||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private void notifyListeners(E oldElement, E element, EventType eventType) {
|
||||
private void notifyListeners(@Nullable E oldElement, E element, EventType eventType) {
|
||||
for (ProviderChangeListener<E> listener : this.listeners) {
|
||||
try {
|
||||
switch (eventType) {
|
||||
|
@ -59,7 +63,7 @@ public abstract class AbstractProvider<E> implements Provider<E> {
|
|||
listener.removed(this, element);
|
||||
break;
|
||||
case UPDATED:
|
||||
listener.updated(this, oldElement, element);
|
||||
listener.updated(this, oldElement != null ? oldElement : element, element);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @param <E> type of the element
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractRegistry<E extends Identifiable<K>, K, P extends Provider<E>>
|
||||
public abstract class AbstractRegistry<@NonNull E extends Identifiable<K>, @NonNull K, @NonNull P extends Provider<E>>
|
||||
implements ProviderChangeListener<E>, Registry<E, K> {
|
||||
|
||||
private enum EventType {
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
*/
|
||||
package org.openhab.core.common.registry;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +30,8 @@ import org.openhab.core.storage.StorageService;
|
|||
* @param <K>
|
||||
* type of the element key
|
||||
*/
|
||||
public abstract class DefaultAbstractManagedProvider<E extends Identifiable<K>, K>
|
||||
@NonNullByDefault
|
||||
public abstract class DefaultAbstractManagedProvider<@NonNull E extends Identifiable<K>, @NonNull K>
|
||||
extends AbstractManagedProvider<E, K, E> {
|
||||
|
||||
public DefaultAbstractManagedProvider(final StorageService storageService) {
|
||||
|
@ -35,7 +39,7 @@ public abstract class DefaultAbstractManagedProvider<E extends Identifiable<K>,
|
|||
}
|
||||
|
||||
@Override
|
||||
protected E toElement(String key, E element) {
|
||||
protected @Nullable E toElement(String key, E element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.core.common.registry;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -26,14 +27,15 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||
* @param <K>
|
||||
* type of the element key
|
||||
*/
|
||||
public interface ManagedProvider<E extends Identifiable<K>, K> extends Provider<E> {
|
||||
@NonNullByDefault
|
||||
public interface ManagedProvider<@NonNull E extends Identifiable<K>, @NonNull K> extends Provider<E> {
|
||||
|
||||
/**
|
||||
* Adds an element.
|
||||
*
|
||||
* @param element element to be added
|
||||
*/
|
||||
void add(@NonNull E element);
|
||||
void add(E element);
|
||||
|
||||
/**
|
||||
* Removes an element and returns the removed element.
|
||||
|
@ -43,7 +45,7 @@ public interface ManagedProvider<E extends Identifiable<K>, K> extends Provider<
|
|||
* key exists
|
||||
*/
|
||||
@Nullable
|
||||
E remove(@NonNull K key);
|
||||
E remove(K key);
|
||||
|
||||
/**
|
||||
* Updates an element.
|
||||
|
@ -53,7 +55,7 @@ public interface ManagedProvider<E extends Identifiable<K>, K> extends Provider<
|
|||
* exists
|
||||
*/
|
||||
@Nullable
|
||||
E update(@NonNull E element);
|
||||
E update(E element);
|
||||
|
||||
/**
|
||||
* Returns an element for the given key or null if no element for the given
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.core.common.registry;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +28,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
* @param <E> type of the provided elements
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface Provider<E> {
|
||||
public interface Provider<@NonNull E> {
|
||||
|
||||
/**
|
||||
* Adds a {@link ProviderChangeListener} which must be notified if there are
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.core.common.registry;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +25,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
* @param <E> type of the element from the provider
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ProviderChangeListener<E> {
|
||||
public interface ProviderChangeListener<@NonNull E> {
|
||||
|
||||
/**
|
||||
* Notifies the listener that a single element has been added.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.core.internal.items;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.AbstractManagedProvider;
|
||||
import org.openhab.core.items.ManagedMetadataProvider;
|
||||
import org.openhab.core.items.Metadata;
|
||||
|
@ -33,8 +34,8 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true, service = { MetadataProvider.class, ManagedMetadataProvider.class })
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { MetadataProvider.class, ManagedMetadataProvider.class })
|
||||
public class ManagedMetadataProviderImpl extends AbstractManagedProvider<Metadata, MetadataKey, Metadata>
|
||||
implements ManagedMetadataProvider {
|
||||
|
||||
|
@ -56,7 +57,7 @@ public class ManagedMetadataProviderImpl extends AbstractManagedProvider<Metadat
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Metadata toElement(String key, Metadata persistableElement) {
|
||||
protected @Nullable Metadata toElement(String key, Metadata persistableElement) {
|
||||
return persistableElement;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.core.items;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.Provider;
|
||||
|
||||
|
@ -23,6 +24,6 @@ import org.openhab.core.common.registry.Provider;
|
|||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ItemProvider extends Provider<Item> {
|
||||
public interface ItemProvider extends Provider<@NonNull Item> {
|
||||
|
||||
}
|
||||
|
|
|
@ -54,10 +54,10 @@ import com.google.gson.InstanceCreator;
|
|||
* @author Kai Kreuzer - improved return values
|
||||
* @author Alex Tugarev - added tags
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ItemProvider.class, ManagedItemProvider.class })
|
||||
public class ManagedItemProvider extends AbstractManagedProvider<Item, String, PersistedItem> implements ItemProvider {
|
||||
|
||||
@NonNullByDefault
|
||||
public static class PersistedItem {
|
||||
|
||||
public PersistedItem(String itemType) {
|
||||
|
@ -78,7 +78,7 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
public static class PersistedItemInstanceCreator implements InstanceCreator<PersistedItem> {
|
||||
|
||||
@Override
|
||||
public PersistedItem createInstance(Type type) {
|
||||
public PersistedItem createInstance(@NonNullByDefault({}) Type type) {
|
||||
return new PersistedItem("");
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
* @param recursive if set to true all members of the item will be removed, too.
|
||||
* @return removed item or null if no item with that name exists
|
||||
*/
|
||||
public Item remove(String itemName, boolean recursive) {
|
||||
public @Nullable Item remove(String itemName, boolean recursive) {
|
||||
Item item = get(itemName);
|
||||
if (recursive && item instanceof GroupItem) {
|
||||
for (String member : getMemberNamesRecursively((GroupItem) item, getAll())) {
|
||||
|
@ -128,7 +128,7 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
return memberNames;
|
||||
}
|
||||
|
||||
private Item createItem(String itemType, String itemName) {
|
||||
private @Nullable Item createItem(String itemType, String itemName) {
|
||||
for (ItemFactory factory : itemFactories) {
|
||||
Item item = factory.createItem(itemType, itemName);
|
||||
if (item != null) {
|
||||
|
@ -195,12 +195,13 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Item toElement(String itemName, PersistedItem persistedItem) {
|
||||
protected @Nullable Item toElement(String itemName, PersistedItem persistedItem) {
|
||||
Item item = null;
|
||||
|
||||
if (persistedItem.itemType.equals(GroupItem.TYPE)) {
|
||||
if (persistedItem.baseItemType != null) {
|
||||
Item baseItem = createItem(persistedItem.baseItemType, itemName);
|
||||
if (GroupItem.TYPE.equals(persistedItem.itemType)) {
|
||||
String baseItemType = persistedItem.baseItemType;
|
||||
if (baseItemType != null) {
|
||||
Item baseItem = createItem(baseItemType, itemName);
|
||||
if (persistedItem.functionName != null) {
|
||||
GroupFunction function = getGroupFunction(persistedItem, baseItem);
|
||||
item = new GroupItem(itemName, baseItem, function);
|
||||
|
@ -227,7 +228,7 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
return item;
|
||||
}
|
||||
|
||||
private GroupFunction getGroupFunction(PersistedItem persistedItem, Item baseItem) {
|
||||
private GroupFunction getGroupFunction(PersistedItem persistedItem, @Nullable Item baseItem) {
|
||||
GroupFunctionDTO functionDTO = new GroupFunctionDTO();
|
||||
functionDTO.name = persistedItem.functionName;
|
||||
if (persistedItem.functionParams != null) {
|
||||
|
@ -237,24 +238,22 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
}
|
||||
|
||||
private void configureItem(PersistedItem persistedItem, ActiveItem item) {
|
||||
if (item != null) {
|
||||
List<String> groupNames = persistedItem.groupNames;
|
||||
if (groupNames != null) {
|
||||
for (String groupName : groupNames) {
|
||||
item.addGroupName(groupName);
|
||||
}
|
||||
List<String> groupNames = persistedItem.groupNames;
|
||||
if (groupNames != null) {
|
||||
for (String groupName : groupNames) {
|
||||
item.addGroupName(groupName);
|
||||
}
|
||||
|
||||
Set<String> tags = persistedItem.tags;
|
||||
if (tags != null) {
|
||||
for (String tag : tags) {
|
||||
item.addTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
item.setLabel(persistedItem.label);
|
||||
item.setCategory(persistedItem.category);
|
||||
}
|
||||
|
||||
Set<String> tags = persistedItem.tags;
|
||||
if (tags != null) {
|
||||
for (String tag : tags) {
|
||||
item.addTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
item.setLabel(persistedItem.label);
|
||||
item.setCategory(persistedItem.category);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -60,6 +62,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Benedikt Niehues - Initial contribution
|
||||
* @author Markus Rathgeb - Migrated Groovy tests to pure Java ones and made it more robust
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RunRuleModuleTest extends JavaOSGiTest {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RunRuleModuleTest.class);
|
||||
|
@ -182,7 +185,7 @@ public class RunRuleModuleTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
|
@ -67,6 +69,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Benedikt Niehues - Initial contribution
|
||||
* @author Markus Rathgeb - Migrated Groovy tests to pure Java ones and made it more robust
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RuntimeRuleTest extends JavaOSGiTest {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RuntimeRuleTest.class);
|
||||
|
@ -115,7 +118,7 @@ public class RuntimeRuleTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -178,7 +181,7 @@ public class RuntimeRuleTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -219,7 +222,7 @@ public class RuntimeRuleTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
private void assertSatisfiedHandlerInput(final CompareConditionHandler handler, final boolean expected,
|
||||
final Object input) {
|
||||
final @Nullable Object input) {
|
||||
final boolean is = handler.isSatisfied(Collections.singletonMap("input", input));
|
||||
if (expected) {
|
||||
Assert.assertTrue(is);
|
||||
|
@ -390,7 +393,7 @@ public class RuntimeRuleTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Collection;
|
|||
import javax.measure.quantity.Length;
|
||||
import javax.measure.quantity.Temperature;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -45,6 +46,7 @@ import org.openhab.core.types.State;
|
|||
*
|
||||
* @author Henning Treu - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ScriptEngineOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private static final String ITEM_NAME = "Switch1";
|
||||
|
@ -52,11 +54,9 @@ public class ScriptEngineOSGiTest extends JavaOSGiTest {
|
|||
private static final String NUMBER_ITEM_DECIMAL = "NumberB";
|
||||
private static final String NUMBER_ITEM_LENGTH = "NumberC";
|
||||
|
||||
private ItemProvider itemProvider;
|
||||
|
||||
private ScriptEngine scriptEngine;
|
||||
|
||||
private ItemRegistry itemRegistry;
|
||||
private @NonNullByDefault({}) ItemProvider itemProvider;
|
||||
private @NonNullByDefault({}) ItemRegistry itemRegistry;
|
||||
private @NonNullByDefault({}) ScriptEngine scriptEngine;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
|
|
@ -22,6 +22,8 @@ import java.io.ByteArrayInputStream;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -43,6 +45,7 @@ import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
|||
*
|
||||
* @author Simon Kaufmann - Initial contribution and API
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GenericItemChannelLinkProviderJavaTest extends JavaOSGiTest {
|
||||
|
||||
private static final String THINGS_TESTMODEL_NAME = "test.things";
|
||||
|
@ -52,14 +55,13 @@ public class GenericItemChannelLinkProviderJavaTest extends JavaOSGiTest {
|
|||
private static final String CHANNEL = "test:test:test:test";
|
||||
private static final String LINK = ITEM + " -> " + CHANNEL;
|
||||
|
||||
private ModelRepository modelRepository;
|
||||
private ThingRegistry thingRegistry;
|
||||
private ItemRegistry itemRegistry;
|
||||
private ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
private ItemChannelLinkProvider itemChannelLinkProvider;
|
||||
private @Mock @Nullable ProviderChangeListener<ItemChannelLink> listenerMock;
|
||||
|
||||
@Mock
|
||||
private ProviderChangeListener<ItemChannelLink> listener;
|
||||
private @NonNullByDefault({}) ModelRepository modelRepository;
|
||||
private @NonNullByDefault({}) ThingRegistry thingRegistry;
|
||||
private @NonNullByDefault({}) ItemRegistry itemRegistry;
|
||||
private @NonNullByDefault({}) ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
private @NonNullByDefault({}) ItemChannelLinkProvider itemChannelLinkProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
@ -137,29 +139,38 @@ public class GenericItemChannelLinkProviderJavaTest extends JavaOSGiTest {
|
|||
@Test
|
||||
public void testNoAmnesia() throws Exception {
|
||||
GenericItemChannelLinkProvider provider = new GenericItemChannelLinkProvider();
|
||||
provider.addProviderChangeListener(listener);
|
||||
|
||||
ProviderChangeListener<ItemChannelLink> localListenerMock = listenerMock;
|
||||
|
||||
if (localListenerMock != null) {
|
||||
provider.addProviderChangeListener(localListenerMock);
|
||||
} else {
|
||||
throw new IllegalStateException("listenerMock is null");
|
||||
}
|
||||
|
||||
provider.startConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
provider.processBindingConfiguration(ITEMS_TESTMODEL_NAME, "Number", ITEM, CHANNEL, new Configuration());
|
||||
provider.stopConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
assertThat(provider.getAll().size(), is(1));
|
||||
assertThat(provider.getAll().iterator().next().toString(), is(LINK));
|
||||
verify(listener, only()).added(same(provider), eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))));
|
||||
verify(localListenerMock, only()).added(same(provider), eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))));
|
||||
|
||||
reset(listener);
|
||||
reset(localListenerMock);
|
||||
provider.startConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
provider.processBindingConfiguration(ITEMS_TESTMODEL_NAME, "Number", ITEM, CHANNEL, new Configuration());
|
||||
provider.stopConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
assertThat(provider.getAll().size(), is(1));
|
||||
assertThat(provider.getAll().iterator().next().toString(), is(LINK));
|
||||
verify(listener, only()).updated(same(provider), eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))),
|
||||
verify(localListenerMock, only()).updated(same(provider),
|
||||
eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))),
|
||||
eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))));
|
||||
|
||||
reset(listener);
|
||||
reset(localListenerMock);
|
||||
provider.startConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
provider.stopConfigurationUpdate(ITEMS_TESTMODEL_NAME);
|
||||
assertThat(provider.getAll().size(), is(0));
|
||||
verify(listener, only()).removed(same(provider), eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))));
|
||||
verify(localListenerMock, only()).removed(same(provider),
|
||||
eq(new ItemChannelLink(ITEM, new ChannelUID(CHANNEL))));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -17,6 +17,8 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -35,6 +37,7 @@ import org.openhab.core.thing.binding.builder.ThingBuilder;
|
|||
* @author Oliver Libutzki - Initial contribution
|
||||
* @author Wouter Born - Migrate tests from Groovy to Java
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ManagedThingProviderOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private static final String BINDIND_ID = "testBinding";
|
||||
|
@ -43,8 +46,8 @@ public class ManagedThingProviderOSGiTest extends JavaOSGiTest {
|
|||
private static final String THING1_ID = "testThing1";
|
||||
private static final String THING2_ID = "testThing2";
|
||||
|
||||
private ManagedThingProvider managedThingProvider;
|
||||
private ProviderChangeListener<Thing> thingChangeListener;
|
||||
private @NonNullByDefault({}) ManagedThingProvider managedThingProvider;
|
||||
private @NonNullByDefault({}) ProviderChangeListener<@NonNull Thing> thingChangeListener;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
@ -60,7 +63,7 @@ public class ManagedThingProviderOSGiTest extends JavaOSGiTest {
|
|||
managedThingProvider.getAll().forEach(t -> managedThingProvider.remove(t.getUID()));
|
||||
}
|
||||
|
||||
private void registerThingsChangeListener(ProviderChangeListener<Thing> thingChangeListener) {
|
||||
private void registerThingsChangeListener(ProviderChangeListener<@NonNull Thing> thingChangeListener) {
|
||||
unregisterCurrentThingsChangeListener();
|
||||
this.thingChangeListener = thingChangeListener;
|
||||
managedThingProvider.addProviderChangeListener(this.thingChangeListener);
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -81,25 +82,24 @@ import org.osgi.service.component.ComponentContext;
|
|||
*
|
||||
* @author Christoph Weitkamp - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private static final String TEST_BUNDLE_NAME = "thingStatusInfoI18nTest.bundle";
|
||||
private static final ChannelTypeUID CHANNEL_TYPE_UID = new ChannelTypeUID("hue:dynamic");
|
||||
|
||||
private ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService;
|
||||
private ItemRegistry itemRegistry;
|
||||
private ItemChannelLinkRegistry linkRegistry;
|
||||
private @Mock @NonNullByDefault({}) ComponentContext componentContextMock;
|
||||
|
||||
@Mock
|
||||
private ComponentContext componentContext;
|
||||
|
||||
private Bundle testBundle;
|
||||
private @NonNullByDefault({}) ItemRegistry itemRegistry;
|
||||
private @NonNullByDefault({}) ItemChannelLinkRegistry linkRegistry;
|
||||
private @NonNullByDefault({}) Bundle testBundle;
|
||||
private @NonNullByDefault({}) ThingStatusInfoI18nLocalizationService thingStatusInfoI18nLocalizationService;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
initMocks(this);
|
||||
|
||||
Mockito.when(componentContext.getBundleContext()).thenReturn(bundleContext);
|
||||
Mockito.when(componentContextMock.getBundleContext()).thenReturn(bundleContext);
|
||||
|
||||
registerVolatileStorageService();
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
|
|||
assertNotNull(itemRegistry);
|
||||
|
||||
final TestThingHandlerFactory thingHandlerFactory = new TestThingHandlerFactory();
|
||||
thingHandlerFactory.activate(componentContext);
|
||||
thingHandlerFactory.activate(componentContextMock);
|
||||
registerService(thingHandlerFactory, ThingHandlerFactory.class.getName());
|
||||
|
||||
final StateDescription state = StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.ZERO)
|
||||
|
@ -132,12 +132,12 @@ public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
|
|||
|
||||
registerService(new ChannelTypeProvider() {
|
||||
@Override
|
||||
public Collection<ChannelType> getChannelTypes(Locale locale) {
|
||||
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
|
||||
return channelTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelType getChannelType(ChannelTypeUID channelTypeUID, Locale locale) {
|
||||
public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
|
||||
for (final ChannelType channelType : channelTypes) {
|
||||
if (channelType.getUID().equals(channelTypeUID)) {
|
||||
return channelType;
|
||||
|
@ -337,7 +337,7 @@ public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(Thing thing) {
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
return new AbstractThingHandler(thing) {
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
|
@ -385,7 +385,7 @@ public class ChannelCommandDescriptionProviderOSGiTest extends JavaOSGiTest {
|
|||
*/
|
||||
private class BundleResolverImpl implements BundleResolver {
|
||||
@Override
|
||||
public Bundle resolveBundle(Class<?> clazz) {
|
||||
public Bundle resolveBundle(@NonNullByDefault({}) Class<?> clazz) {
|
||||
if (clazz != null && clazz.equals(AbstractThingHandler.class)) {
|
||||
return testBundle;
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.measure.quantity.Temperature;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -82,6 +83,7 @@ import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
|||
*
|
||||
* @author Simon Kaufmann - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private class ItemChannelLinkRegistryAdvanced extends ItemChannelLinkRegistry {
|
||||
|
@ -130,39 +132,19 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
ChannelBuilder.create(TRIGGER_CHANNEL_UID_1, "").withKind(ChannelKind.TRIGGER).build(),
|
||||
ChannelBuilder.create(TRIGGER_CHANNEL_UID_2, "").withKind(ChannelKind.TRIGGER).build()).build();
|
||||
|
||||
private CommunicationManager manager;
|
||||
private @Mock @NonNullByDefault({}) AutoUpdateManager autoUpdateManagerMock;
|
||||
private @Mock @NonNullByDefault({}) ChannelTypeRegistry channelTypeRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) EventPublisher eventPublisherMock;
|
||||
private @Mock @NonNullByDefault({}) ItemRegistry itemRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) ProfileAdvisor profileAdvisorMock;
|
||||
private @Mock @NonNullByDefault({}) ProfileFactory profileFactoryMock;
|
||||
private @Mock @NonNullByDefault({}) StateProfile stateProfileMock;
|
||||
private @Mock @NonNullByDefault({}) ThingHandler thingHandlerMock;
|
||||
private @Mock @NonNullByDefault({}) ThingRegistry thingRegistryMock;
|
||||
private @Mock @NonNullByDefault({}) TriggerProfile triggerProfileMock;
|
||||
|
||||
@Mock
|
||||
private ProfileFactory mockProfileFactory;
|
||||
|
||||
@Mock
|
||||
private ProfileAdvisor mockProfileAdvisor;
|
||||
|
||||
@Mock
|
||||
private StateProfile stateProfile;
|
||||
|
||||
@Mock
|
||||
private TriggerProfile triggerProfile;
|
||||
|
||||
@Mock
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
@Mock
|
||||
private ItemRegistry itemRegistry;
|
||||
|
||||
@Mock
|
||||
private ThingRegistry thingRegistry;
|
||||
|
||||
@Mock
|
||||
private ThingHandler mockHandler;
|
||||
|
||||
@Mock
|
||||
private AutoUpdateManager mockAutoUpdateManager;
|
||||
|
||||
@Mock
|
||||
private ChannelTypeRegistry channelTypeRegistry;
|
||||
|
||||
private SafeCaller safeCaller;
|
||||
private @NonNullByDefault({}) CommunicationManager manager;
|
||||
private @NonNullByDefault({}) SafeCaller safeCaller;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
@ -175,7 +157,7 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
assertNotNull(profileFactory);
|
||||
|
||||
manager = new CommunicationManager();
|
||||
manager.setEventPublisher(eventPublisher);
|
||||
manager.setEventPublisher(eventPublisherMock);
|
||||
manager.setDefaultProfileFactory(profileFactory);
|
||||
manager.setSafeCaller(safeCaller);
|
||||
|
||||
|
@ -187,25 +169,26 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
return new ProfileTypeUID("test:trigger");
|
||||
}
|
||||
return null;
|
||||
}).when(mockProfileAdvisor).getSuggestedProfileTypeUID(isA(Channel.class), isA(String.class));
|
||||
}).when(profileAdvisorMock).getSuggestedProfileTypeUID(isA(Channel.class), isA(String.class));
|
||||
doAnswer(invocation -> {
|
||||
switch (((ProfileTypeUID) invocation.getArguments()[0]).toString()) {
|
||||
case "test:state":
|
||||
return stateProfile;
|
||||
return stateProfileMock;
|
||||
case "test:trigger":
|
||||
return triggerProfile;
|
||||
return triggerProfileMock;
|
||||
}
|
||||
return null;
|
||||
}).when(mockProfileFactory).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
}).when(profileFactoryMock).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
|
||||
when(mockProfileFactory.getSupportedProfileTypeUIDs()).thenReturn(Stream
|
||||
when(profileFactoryMock.getSupportedProfileTypeUIDs()).thenReturn(Stream
|
||||
.of(new ProfileTypeUID("test:state"), new ProfileTypeUID("test:trigger")).collect(Collectors.toList()));
|
||||
|
||||
manager.addProfileFactory(mockProfileFactory);
|
||||
manager.addProfileAdvisor(mockProfileAdvisor);
|
||||
manager.addProfileFactory(profileFactoryMock);
|
||||
manager.addProfileAdvisor(profileAdvisorMock);
|
||||
|
||||
ItemChannelLinkRegistryAdvanced iclRegistry = new ItemChannelLinkRegistryAdvanced(thingRegistry, itemRegistry);
|
||||
ItemChannelLinkRegistryAdvanced iclRegistry = new ItemChannelLinkRegistryAdvanced(thingRegistryMock,
|
||||
itemRegistryMock);
|
||||
iclRegistry.addProvider(new ItemChannelLinkProvider() {
|
||||
@Override
|
||||
public void addProviderChangeListener(ProviderChangeListener<ItemChannelLink> listener) {
|
||||
|
@ -223,24 +206,24 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
});
|
||||
manager.setItemChannelLinkRegistry(iclRegistry);
|
||||
|
||||
when(itemRegistry.get(eq(ITEM_NAME_1))).thenReturn(ITEM_1);
|
||||
when(itemRegistry.get(eq(ITEM_NAME_2))).thenReturn(ITEM_2);
|
||||
when(itemRegistry.get(eq(ITEM_NAME_3))).thenReturn(ITEM_3);
|
||||
when(itemRegistry.get(eq(ITEM_NAME_4))).thenReturn(ITEM_4);
|
||||
manager.setItemRegistry(itemRegistry);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME_1))).thenReturn(ITEM_1);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME_2))).thenReturn(ITEM_2);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME_3))).thenReturn(ITEM_3);
|
||||
when(itemRegistryMock.get(eq(ITEM_NAME_4))).thenReturn(ITEM_4);
|
||||
manager.setItemRegistry(itemRegistryMock);
|
||||
|
||||
ChannelType channelType4 = mock(ChannelType.class);
|
||||
when(channelType4.getItemType()).thenReturn("Number:Temperature");
|
||||
|
||||
when(channelTypeRegistry.getChannelType(CHANNEL_TYPE_UID_4)).thenReturn(channelType4);
|
||||
manager.setChannelTypeRegistry(channelTypeRegistry);
|
||||
when(channelTypeRegistryMock.getChannelType(CHANNEL_TYPE_UID_4)).thenReturn(channelType4);
|
||||
manager.setChannelTypeRegistry(channelTypeRegistryMock);
|
||||
|
||||
THING.setHandler(mockHandler);
|
||||
THING.setHandler(thingHandlerMock);
|
||||
|
||||
when(thingRegistry.get(eq(THING_UID))).thenReturn(THING);
|
||||
manager.setThingRegistry(thingRegistry);
|
||||
when(thingRegistryMock.get(eq(THING_UID))).thenReturn(THING);
|
||||
manager.setThingRegistry(thingRegistryMock);
|
||||
manager.addItemFactory(new CoreItemFactory());
|
||||
manager.setAutoUpdateManager(mockAutoUpdateManager);
|
||||
manager.setAutoUpdateManager(autoUpdateManagerMock);
|
||||
|
||||
UnitProvider unitProvider = mock(UnitProvider.class);
|
||||
when(unitProvider.getUnit(Temperature.class)).thenReturn(SIUnits.CELSIUS);
|
||||
|
@ -252,51 +235,51 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
public void testStateUpdatedSingleLink() {
|
||||
manager.stateUpdated(STATE_CHANNEL_UID_1, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onStateUpdateFromHandler(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onStateUpdateFromHandler(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateUpdatedMultiLink() {
|
||||
manager.stateUpdated(STATE_CHANNEL_UID_2, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile, times(2)).onStateUpdateFromHandler(eq(OnOffType.ON));
|
||||
verify(stateProfileMock, times(2)).onStateUpdateFromHandler(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostCommandSingleLink() {
|
||||
manager.postCommand(STATE_CHANNEL_UID_1, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromHandler(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onCommandFromHandler(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostCommandMultiLink() {
|
||||
manager.postCommand(STATE_CHANNEL_UID_2, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile, times(2)).onCommandFromHandler(eq(OnOffType.ON));
|
||||
verify(stateProfileMock, times(2)).onCommandFromHandler(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCommandEventSingleLink() {
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_2, OnOffType.ON));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onCommandFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verify(mockAutoUpdateManager).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
verify(autoUpdateManagerMock).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -304,10 +287,10 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
// Take unit from accepted item type (see channel built from STATE_CHANNEL_UID_3)
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_3, DecimalType.valueOf("20")));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromItem(eq(QuantityType.valueOf("20 °C")));
|
||||
verify(stateProfileMock).onCommandFromItem(eq(QuantityType.valueOf("20 °C")));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -320,10 +303,10 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_3, DecimalType.valueOf("20")));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromItem(eq(QuantityType.valueOf("20 °F")));
|
||||
verify(stateProfileMock).onCommandFromItem(eq(QuantityType.valueOf("20 °F")));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
|
||||
ITEM_3.setStateDescriptionService(null);
|
||||
}
|
||||
|
@ -335,21 +318,21 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
// current ThingType.
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_4, DecimalType.valueOf("20")));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromItem(eq(QuantityType.valueOf("20 °C")));
|
||||
verify(stateProfileMock).onCommandFromItem(eq(QuantityType.valueOf("20 °C")));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemCommandEventMultiLink() {
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_1, OnOffType.ON));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile, times(2)).onCommandFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock, times(2)).onCommandFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verify(mockAutoUpdateManager).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
verify(autoUpdateManagerMock).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -357,33 +340,33 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
manager.receive(
|
||||
ItemEventFactory.createCommandEvent(ITEM_NAME_1, OnOffType.ON, STATE_CHANNEL_UID_2.getAsString()));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onCommandFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onCommandFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verify(mockAutoUpdateManager).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
verify(autoUpdateManagerMock).receiveCommand(isA(ItemCommandEvent.class), isA(Item.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemStateEventSingleLink() {
|
||||
manager.receive(ItemEventFactory.createStateEvent(ITEM_NAME_2, OnOffType.ON));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfile).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfileMock).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemStateEventMultiLink() {
|
||||
manager.receive(ItemEventFactory.createStateEvent(ITEM_NAME_1, OnOffType.ON));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfile, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfileMock, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -391,31 +374,31 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
manager.receive(
|
||||
ItemEventFactory.createStateEvent(ITEM_NAME_1, OnOffType.ON, STATE_CHANNEL_UID_2.getAsString()));
|
||||
waitForAssert(() -> {
|
||||
verify(stateProfile).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfile, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(stateProfileMock).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
verify(triggerProfileMock, times(2)).onStateUpdateFromItem(eq(OnOffType.ON));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelTriggeredEventSingleLink() {
|
||||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_1));
|
||||
waitForAssert(() -> {
|
||||
verify(triggerProfile).onTriggerFromHandler(eq(EVENT));
|
||||
verify(triggerProfileMock).onTriggerFromHandler(eq(EVENT));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelTriggeredEventMultiLink() {
|
||||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_2));
|
||||
waitForAssert(() -> {
|
||||
verify(triggerProfile, times(2)).onTriggerFromHandler(eq(EVENT));
|
||||
verify(triggerProfileMock, times(2)).onTriggerFromHandler(eq(EVENT));
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -425,13 +408,13 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
verify(mockProfileFactory, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(mockProfileAdvisor, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
verify(profileFactoryMock, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(profileAdvisorMock, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
});
|
||||
verifyNoMoreInteractions(mockProfileFactory);
|
||||
verifyNoMoreInteractions(mockProfileAdvisor);
|
||||
verifyNoMoreInteractions(profileFactoryMock);
|
||||
verifyNoMoreInteractions(profileAdvisorMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -439,24 +422,24 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
for (int i = 0; i < 3; i++) {
|
||||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_2));
|
||||
}
|
||||
verify(mockProfileFactory, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
|
||||
manager.removeProfileFactory(mockProfileFactory);
|
||||
manager.addProfileFactory(mockProfileFactory);
|
||||
manager.removeProfileFactory(profileFactoryMock);
|
||||
manager.addProfileFactory(profileFactoryMock);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_2));
|
||||
}
|
||||
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(4)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(4)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
verify(mockProfileFactory, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(mockProfileAdvisor, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
verify(profileFactoryMock, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(profileAdvisorMock, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
});
|
||||
verifyNoMoreInteractions(mockProfileFactory);
|
||||
verifyNoMoreInteractions(mockProfileAdvisor);
|
||||
verifyNoMoreInteractions(profileFactoryMock);
|
||||
verifyNoMoreInteractions(profileAdvisorMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -465,7 +448,7 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_2));
|
||||
}
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
});
|
||||
|
||||
|
@ -477,13 +460,13 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(3)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(3)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
verify(mockProfileFactory, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(mockProfileAdvisor, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
verify(profileFactoryMock, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(profileAdvisorMock, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
});
|
||||
verifyNoMoreInteractions(mockProfileFactory);
|
||||
verifyNoMoreInteractions(mockProfileAdvisor);
|
||||
verifyNoMoreInteractions(profileFactoryMock);
|
||||
verifyNoMoreInteractions(profileAdvisorMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -500,13 +483,13 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
verify(mockProfileFactory, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(mockProfileAdvisor, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
verify(profileFactoryMock, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(profileAdvisorMock, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
});
|
||||
verifyNoMoreInteractions(mockProfileFactory);
|
||||
verifyNoMoreInteractions(mockProfileAdvisor);
|
||||
verifyNoMoreInteractions(profileFactoryMock);
|
||||
verifyNoMoreInteractions(profileAdvisorMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -514,7 +497,7 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
for (int i = 0; i < 3; i++) {
|
||||
manager.receive(ThingEventFactory.createTriggerEvent(EVENT, TRIGGER_CHANNEL_UID_2));
|
||||
}
|
||||
verify(mockProfileFactory, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(2)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
|
||||
manager.updated(LINK_2_T2, LINK_2_T2);
|
||||
|
@ -524,13 +507,13 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
}
|
||||
|
||||
waitForAssert(() -> {
|
||||
verify(mockProfileFactory, times(3)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
verify(profileFactoryMock, times(3)).createProfile(isA(ProfileTypeUID.class), isA(ProfileCallback.class),
|
||||
isA(ProfileContext.class));
|
||||
verify(mockProfileFactory, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(mockProfileAdvisor, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
verify(profileFactoryMock, atLeast(0)).getSupportedProfileTypeUIDs();
|
||||
verify(profileAdvisorMock, atLeast(0)).getSuggestedProfileTypeUID(any(Channel.class), any());
|
||||
});
|
||||
verifyNoMoreInteractions(mockProfileFactory);
|
||||
verifyNoMoreInteractions(mockProfileAdvisor);
|
||||
verifyNoMoreInteractions(profileFactoryMock);
|
||||
verifyNoMoreInteractions(profileAdvisorMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -538,19 +521,19 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
Thing thing = ThingBuilder.create(THING_TYPE_UID, THING_UID)
|
||||
.withChannels(ChannelBuilder.create(STATE_CHANNEL_UID_2, "Dimmer").withKind(ChannelKind.STATE).build())
|
||||
.build();
|
||||
thing.setHandler(mockHandler);
|
||||
when(thingRegistry.get(eq(THING_UID))).thenReturn(thing);
|
||||
thing.setHandler(thingHandlerMock);
|
||||
when(thingRegistryMock.get(eq(THING_UID))).thenReturn(thing);
|
||||
|
||||
manager.receive(ItemEventFactory.createCommandEvent(ITEM_NAME_2, HSBType.fromRGB(128, 128, 128)));
|
||||
waitForAssert(() -> {
|
||||
ArgumentCaptor<Command> commandCaptor = ArgumentCaptor.forClass(Command.class);
|
||||
verify(stateProfile).onCommandFromItem(commandCaptor.capture());
|
||||
verify(stateProfileMock).onCommandFromItem(commandCaptor.capture());
|
||||
Command command = commandCaptor.getValue();
|
||||
assertNotNull(command);
|
||||
assertEquals(PercentType.class, command.getClass());
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -558,19 +541,19 @@ public class CommunicationManagerOSGiTest extends JavaOSGiTest {
|
|||
Thing thing = ThingBuilder.create(THING_TYPE_UID, THING_UID)
|
||||
.withChannels(ChannelBuilder.create(STATE_CHANNEL_UID_2, "Dimmer").withKind(ChannelKind.STATE).build())
|
||||
.build();
|
||||
thing.setHandler(mockHandler);
|
||||
when(thingRegistry.get(eq(THING_UID))).thenReturn(thing);
|
||||
thing.setHandler(thingHandlerMock);
|
||||
when(thingRegistryMock.get(eq(THING_UID))).thenReturn(thing);
|
||||
|
||||
manager.receive(ItemEventFactory.createStateEvent(ITEM_NAME_2, HSBType.fromRGB(128, 128, 128)));
|
||||
waitForAssert(() -> {
|
||||
ArgumentCaptor<State> stateCaptor = ArgumentCaptor.forClass(State.class);
|
||||
verify(stateProfile).onStateUpdateFromItem(stateCaptor.capture());
|
||||
verify(stateProfileMock).onStateUpdateFromItem(stateCaptor.capture());
|
||||
State state = stateCaptor.getValue();
|
||||
assertNotNull(state);
|
||||
assertEquals(PercentType.class, state.getClass());
|
||||
});
|
||||
verifyNoMoreInteractions(stateProfile);
|
||||
verifyNoMoreInteractions(triggerProfile);
|
||||
verifyNoMoreInteractions(stateProfileMock);
|
||||
verifyNoMoreInteractions(triggerProfileMock);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue