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