mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 21:31:53 +01:00
Fix ConfigurableService deprecations (#1666)
Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
parent
c5541a0391
commit
6b97328189
@ -17,6 +17,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.service.component.ComponentConstants;
|
||||
import org.osgi.service.component.annotations.ComponentPropertyType;
|
||||
@ -25,9 +26,8 @@ import org.osgi.service.component.annotations.ComponentPropertyType;
|
||||
* <p>
|
||||
* {@link ConfigurableService} can be used as a marker interface for configurable services. But the interface itself is
|
||||
* not relevant for the runtime. Each service which has the property
|
||||
* {@link ConfigurableService#SERVICE_PROPERTY_DESCRIPTION_URI} set will be considered as a configurable service. The
|
||||
* properties {@link ConfigurableService#SERVICE_PROPERTY_LABEL} and
|
||||
* {@link ConfigurableService#SERVICE_PROPERTY_CATEGORY} are optional.
|
||||
* {@link ConfigurableService#description_uri} set will be considered as a configurable service. The
|
||||
* properties {@link ConfigurableService#label} and {@link ConfigurableService#category} are optional.
|
||||
*
|
||||
* <p>
|
||||
* The services are configured through the OSGi configuration admin. Therefore each service must provide a PID or a
|
||||
@ -41,6 +41,7 @@ import org.osgi.service.component.annotations.ComponentPropertyType;
|
||||
@ComponentPropertyType
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target(ElementType.TYPE)
|
||||
@NonNullByDefault
|
||||
public @interface ConfigurableService {
|
||||
|
||||
String PREFIX_ = "service.config.";
|
||||
@ -64,36 +65,4 @@ public @interface ConfigurableService {
|
||||
* Marker for multiple configurations for this service ("true" = multiple configurations possible)
|
||||
*/
|
||||
boolean factory() default false;
|
||||
|
||||
/**
|
||||
* The config description URI for the configurable service. See also {@link ConfigDescription}.
|
||||
*
|
||||
* @deprecated annotate classes with <code>@ConfigurableService</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String SERVICE_PROPERTY_DESCRIPTION_URI = PREFIX_ + "description.uri";
|
||||
|
||||
/**
|
||||
* The label of the service to be configured.
|
||||
*
|
||||
* @deprecated annotate classes with <code>@ConfigurableService</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String SERVICE_PROPERTY_LABEL = PREFIX_ + "label";
|
||||
|
||||
/**
|
||||
* The category of the service to be configured (e.g. binding).
|
||||
*
|
||||
* @deprecated annotate classes with <code>@ConfigurableService</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String SERVICE_PROPERTY_CATEGORY = PREFIX_ + "category";
|
||||
|
||||
/**
|
||||
* Marker for multiple configurations for this service ("true" = multiple configurations possible)
|
||||
*
|
||||
* @deprecated annotate classes with <code>@ConfigurableService</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String SERVICE_PROPERTY_FACTORY_SERVICE = PREFIX_ + "factory";
|
||||
}
|
||||
|
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.config.core;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Provides utility methods for working with {@link ConfigurableService} so the property names can remain hidden.
|
||||
* These methods cannot be part of {@link ConfigurableService} as that introduces an annotation cycle.
|
||||
*
|
||||
* @author Wouter Born - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ConfigurableServiceUtil {
|
||||
|
||||
/**
|
||||
* The config description URI for the configurable service. See also {@link ConfigDescription}.
|
||||
*/
|
||||
static final String SERVICE_PROPERTY_DESCRIPTION_URI = ConfigurableService.PREFIX_ + "description.uri";
|
||||
|
||||
/**
|
||||
* The label of the service to be configured.
|
||||
*/
|
||||
static final String SERVICE_PROPERTY_LABEL = ConfigurableService.PREFIX_ + "label";
|
||||
|
||||
/**
|
||||
* The category of the service to be configured (e.g. binding).
|
||||
*/
|
||||
static final String SERVICE_PROPERTY_CATEGORY = ConfigurableService.PREFIX_ + "category";
|
||||
|
||||
/**
|
||||
* Marker for multiple configurations for this service ("true" = multiple configurations possible)
|
||||
*/
|
||||
static final String SERVICE_PROPERTY_FACTORY_SERVICE = ConfigurableService.PREFIX_ + "factory";
|
||||
|
||||
// all singleton services without multi-config services
|
||||
public static final String CONFIGURABLE_SERVICE_FILTER = "(&(" + SERVICE_PROPERTY_DESCRIPTION_URI + "=*)(!("
|
||||
+ SERVICE_PROPERTY_FACTORY_SERVICE + "=*)))";
|
||||
|
||||
// all multi-config services without singleton services
|
||||
public static final String CONFIGURABLE_MULTI_CONFIG_SERVICE_FILTER = "(" + SERVICE_PROPERTY_FACTORY_SERVICE
|
||||
+ "=*)";
|
||||
|
||||
public static ConfigurableService asConfigurableService(Function<String, @Nullable Object> propertyResolver) {
|
||||
return new ConfigurableService() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return ConfigurableService.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String label() {
|
||||
return resolveString(propertyResolver, SERVICE_PROPERTY_LABEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean factory() {
|
||||
return resolveBoolean(propertyResolver, SERVICE_PROPERTY_FACTORY_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description_uri() {
|
||||
return resolveString(propertyResolver, SERVICE_PROPERTY_DESCRIPTION_URI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String category() {
|
||||
return resolveString(propertyResolver, SERVICE_PROPERTY_CATEGORY);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String resolveString(Function<String, @Nullable Object> propertyResolver, String key) {
|
||||
String value = (String) propertyResolver.apply(key);
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private static boolean resolveBoolean(Function<String, @Nullable Object> propertyResolver, String key) {
|
||||
Boolean value = (Boolean) propertyResolver.apply(key);
|
||||
return value == null ? false : value.booleanValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.config.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.text.IsEmptyString.emptyString;
|
||||
import static org.openhab.core.config.core.ConfigurableServiceUtil.*;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link ConfigurableServiceUtil}.
|
||||
*
|
||||
* @author Wouter Born - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ConfigurableServiceUtilTest {
|
||||
|
||||
@Test
|
||||
public void asConfigurableServiceDefinedProperties() {
|
||||
String category = "system";
|
||||
String descriptionURI = "system:inbox";
|
||||
boolean factory = true;
|
||||
String label = "Inbox";
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.put(SERVICE_PROPERTY_CATEGORY, category);
|
||||
properties.put(SERVICE_PROPERTY_DESCRIPTION_URI, descriptionURI);
|
||||
properties.put(SERVICE_PROPERTY_FACTORY_SERVICE, factory);
|
||||
properties.put(SERVICE_PROPERTY_LABEL, label);
|
||||
|
||||
ConfigurableService configurableService = ConfigurableServiceUtil
|
||||
.asConfigurableService((key) -> properties.get(key));
|
||||
|
||||
assertThat(configurableService.annotationType(), is(ConfigurableService.class));
|
||||
assertThat(configurableService.category(), is(category));
|
||||
assertThat(configurableService.description_uri(), is(descriptionURI));
|
||||
assertThat(configurableService.factory(), is(factory));
|
||||
assertThat(configurableService.label(), is(label));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asConfigurableServiceUndefinedProperties() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
ConfigurableService configurableService = ConfigurableServiceUtil
|
||||
.asConfigurableService((key) -> properties.get(key));
|
||||
|
||||
assertThat(configurableService.annotationType(), is(ConfigurableService.class));
|
||||
assertThat(configurableService.category(), is(emptyString()));
|
||||
assertThat(configurableService.description_uri(), is(emptyString()));
|
||||
assertThat(configurableService.factory(), is(false));
|
||||
assertThat(configurableService.label(), is(emptyString()));
|
||||
}
|
||||
}
|
@ -43,6 +43,7 @@ import org.openhab.core.config.core.ConfigDescription;
|
||||
import org.openhab.core.config.core.ConfigDescriptionRegistry;
|
||||
import org.openhab.core.config.core.ConfigUtil;
|
||||
import org.openhab.core.config.core.ConfigurableService;
|
||||
import org.openhab.core.config.core.ConfigurableServiceUtil;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.io.rest.RESTConstants;
|
||||
import org.openhab.core.io.rest.RESTResource;
|
||||
@ -98,15 +99,6 @@ public class ConfigurableServiceResource implements RESTResource {
|
||||
/** The URI path to this resource */
|
||||
public static final String PATH_SERVICES = "services";
|
||||
|
||||
// all singleton services without multi-config services
|
||||
private static final String CONFIGURABLE_SERVICE_FILTER = "(&("
|
||||
+ ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI + "=*)(!("
|
||||
+ ConfigurableService.SERVICE_PROPERTY_FACTORY_SERVICE + "=*)))";
|
||||
|
||||
// all multi-config services without singleton services
|
||||
private static final String CONFIGURABLE_MULTI_CONFIG_SERVICE_FILTER = "("
|
||||
+ ConfigurableService.SERVICE_PROPERTY_FACTORY_SERVICE + "=*)";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ConfigurableServiceResource.class);
|
||||
|
||||
private final BundleContext bundleContext;
|
||||
@ -284,24 +276,24 @@ public class ConfigurableServiceResource implements RESTResource {
|
||||
if (serviceReferences != null) {
|
||||
for (ServiceReference<?> serviceReference : serviceReferences) {
|
||||
String id = getServiceId(serviceReference);
|
||||
String label = (String) serviceReference.getProperty(ConfigurableService.SERVICE_PROPERTY_LABEL);
|
||||
if (label == null) { // for multi context services the label can be changed and must be read from config
|
||||
// admin.
|
||||
ConfigurableService configurableService = ConfigurableServiceUtil
|
||||
.asConfigurableService((key) -> serviceReference.getProperty(key));
|
||||
|
||||
String label = configurableService.label();
|
||||
if (label.isEmpty()) { // for multi context services the label can be changed and must be read from
|
||||
// config admin.
|
||||
label = configurationService.getProperty(id, OpenHAB.SERVICE_CONTEXT);
|
||||
}
|
||||
String category = (String) serviceReference.getProperty(ConfigurableService.SERVICE_PROPERTY_CATEGORY);
|
||||
String configDescriptionURI = (String) serviceReference
|
||||
.getProperty(ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI);
|
||||
|
||||
if (configDescriptionURI == null) {
|
||||
String category = configurableService.category();
|
||||
|
||||
String configDescriptionURI = configurableService.description_uri();
|
||||
if (configDescriptionURI.isEmpty()) {
|
||||
String factoryPid = (String) serviceReference.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
|
||||
configDescriptionURI = getConfigDescriptionByFactoryPid(factoryPid);
|
||||
}
|
||||
|
||||
Object factoryProperty = serviceReference
|
||||
.getProperty(ConfigurableService.SERVICE_PROPERTY_FACTORY_SERVICE);
|
||||
boolean multiple = factoryProperty instanceof Boolean ? (Boolean) factoryProperty
|
||||
: Boolean.parseBoolean((String) factoryProperty);
|
||||
boolean multiple = configurableService.factory();
|
||||
|
||||
services.add(new ConfigurableServiceDTO(id, label, category, configDescriptionURI, multiple));
|
||||
}
|
||||
@ -318,8 +310,9 @@ public class ConfigurableServiceResource implements RESTResource {
|
||||
ServiceReference<?>[] refs = bundleContext.getServiceReferences((String) null, filter);
|
||||
|
||||
if (refs != null && refs.length > 0) {
|
||||
configDescriptionURI = (String) refs[0]
|
||||
.getProperty(ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI);
|
||||
ConfigurableService configurableService = ConfigurableServiceUtil
|
||||
.asConfigurableService((key) -> refs[0].getProperty(key));
|
||||
configDescriptionURI = configurableService.description_uri();
|
||||
}
|
||||
} catch (InvalidSyntaxException e) {
|
||||
logger.error("Cannot get service references because the syntax of the filter '{}' is invalid.", filter);
|
||||
@ -330,8 +323,8 @@ public class ConfigurableServiceResource implements RESTResource {
|
||||
private List<ConfigurableServiceDTO> getConfigurableServices() {
|
||||
List<ConfigurableServiceDTO> services = new ArrayList<>();
|
||||
|
||||
services.addAll(getServicesByFilter(CONFIGURABLE_SERVICE_FILTER));
|
||||
services.addAll(getServicesByFilter(CONFIGURABLE_MULTI_CONFIG_SERVICE_FILTER));
|
||||
services.addAll(getServicesByFilter(ConfigurableServiceUtil.CONFIGURABLE_SERVICE_FILTER));
|
||||
services.addAll(getServicesByFilter(ConfigurableServiceUtil.CONFIGURABLE_MULTI_CONFIG_SERVICE_FILTER));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
@ -38,11 +38,9 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Henning Treu - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "org.openhab.magic", service = ConfigOptionProvider.class, immediate = true, property = {
|
||||
Constants.SERVICE_PID + "=org.openhab.core.magic",
|
||||
ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI + "=test:magic",
|
||||
ConfigurableService.SERVICE_PROPERTY_LABEL + "=Magic",
|
||||
ConfigurableService.SERVICE_PROPERTY_CATEGORY + "=test" })
|
||||
@Component(configurationPid = "org.openhab.magic", service = ConfigOptionProvider.class, immediate = true, //
|
||||
property = Constants.SERVICE_PID + "=org.openhab.core.magic")
|
||||
@ConfigurableService(category = "test", label = "Magic", description_uri = "test:magic")
|
||||
public class MagicServiceImpl implements MagicService {
|
||||
private final Logger logger = LoggerFactory.getLogger(MagicServiceImpl.class);
|
||||
|
||||
|
@ -21,12 +21,9 @@ import org.osgi.service.component.annotations.Component;
|
||||
*
|
||||
* @author Stefan Triller - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true, service = MagicMultiActionMarker.class, property = {
|
||||
Constants.SERVICE_PID + "=org.openhab.MagicMultiAction",
|
||||
ConfigurableService.SERVICE_PROPERTY_FACTORY_SERVICE + "=true",
|
||||
ConfigurableService.SERVICE_PROPERTY_LABEL + "=MagicMultiActionsService",
|
||||
ConfigurableService.SERVICE_PROPERTY_CATEGORY + "=RuleActions",
|
||||
ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI + "=automationAction:magicMultiAction" })
|
||||
@Component(immediate = true, service = MagicMultiActionMarker.class, //
|
||||
property = Constants.SERVICE_PID + "=org.openhab.MagicMultiAction")
|
||||
@ConfigurableService(category = "RuleActions", label = "MagicMultiActionsService", description_uri = "automationAction:magicMultiAction", factory = true)
|
||||
public class MagicMultiActionMarker {
|
||||
|
||||
}
|
||||
|
@ -33,11 +33,9 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Stefan Triller - Initial contribution
|
||||
*/
|
||||
@Component(configurationPid = "org.openhab.magicsingleaction", property = {
|
||||
Constants.SERVICE_PID + "=org.openhab.automation.action.magicSingleActionService",
|
||||
ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI + "=automationAction:magicSingleAction",
|
||||
ConfigurableService.SERVICE_PROPERTY_LABEL + "=Magic Single Action Service",
|
||||
ConfigurableService.SERVICE_PROPERTY_CATEGORY + "=RuleActions" })
|
||||
@Component(configurationPid = "org.openhab.magicsingleaction", //
|
||||
property = Constants.SERVICE_PID + "=org.openhab.automation.action.magicSingleActionService")
|
||||
@ConfigurableService(category = "RuleActions", label = "Magic Single Action Service", description_uri = "automationAction:magicSingleAction")
|
||||
@ActionScope(name = "binding.magicService")
|
||||
public class MagicSingleActionService implements AnnotatedActions {
|
||||
|
||||
|
@ -21,12 +21,9 @@ import org.osgi.service.component.annotations.Component;
|
||||
* @author Stefan Triller - Initial contribution
|
||||
*/
|
||||
|
||||
@Component(immediate = true, service = MagicMultiInstanceServiceMarker.class, property = {
|
||||
Constants.SERVICE_PID + "=org.openhab.magicMultiInstance",
|
||||
ConfigurableService.SERVICE_PROPERTY_FACTORY_SERVICE + "=true",
|
||||
ConfigurableService.SERVICE_PROPERTY_LABEL + "=MagicMultiInstanceService",
|
||||
ConfigurableService.SERVICE_PROPERTY_CATEGORY + "=test",
|
||||
ConfigurableService.SERVICE_PROPERTY_DESCRIPTION_URI + "=test:multipleMagic" })
|
||||
@Component(immediate = true, service = MagicMultiInstanceServiceMarker.class, //
|
||||
property = Constants.SERVICE_PID + "=org.openhab.magicMultiInstance")
|
||||
@ConfigurableService(category = "test", label = "MagicMultiInstanceService", description_uri = "test:multipleMagic", factory = true)
|
||||
public class MagicMultiInstanceServiceMarker {
|
||||
// this is a marker service and represents a service factory so multiple configuration instances of type
|
||||
// "org.openhab.core.magicMultiInstance" can be created.
|
||||
|
Loading…
Reference in New Issue
Block a user