handle different possible service PID types (#560)

* handle different possible service PID types

The property value "service.pid" can use different types:
* String
* String[]
* Collection of String

Only "String" has been supported.

https://github.com/openhab/openhab-core/pull/557 adds support for
String[]

https://github.com/openhab/openhab-core/pull/559 removes the support for
String[] again and adds support for the Collection type List only.

This commit ensures that String arrays and every collection type is
supported, regardless which (valid) type is used by the OSGi framework
implementation.

Fixes: https://github.com/eclipse/smarthome/issues/6710

Signed-off-by: Markus Rathgeb <maggu2810@gmail.com>
pull/575/head
Markus Rathgeb 2019-02-13 16:09:32 +00:00 committed by Christoph Weitkamp
parent afd1770da2
commit fa8a368873
1 changed files with 51 additions and 11 deletions

View File

@ -16,9 +16,12 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.security.RolesAllowed; import javax.annotation.security.RolesAllowed;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@ -308,19 +311,56 @@ public class ConfigurableServiceResource implements RESTResource {
} }
private String getServiceId(ServiceReference<?> serviceReference) { private String getServiceId(ServiceReference<?> serviceReference) {
final String cn = (String) serviceReference.getProperty(ComponentConstants.COMPONENT_NAME);
Object pid = serviceReference.getProperty(Constants.SERVICE_PID); Object pid = serviceReference.getProperty(Constants.SERVICE_PID);
if (pid != null) { if (pid == null) {
if (pid instanceof String) { return cn;
return (String) pid; }
} else if (pid instanceof List) {
@SuppressWarnings("unchecked") final String serviceId;
List<String> pidList = (List<String>) pid; if (pid instanceof String) {
if (!pidList.isEmpty()) { serviceId = (String) pid;
return pidList.get(0); } else if (pid instanceof String[]) {
} final String[] pids = (String[]) pid;
} serviceId = getServicePID(cn, Arrays.asList(pids));
} else if (pid instanceof Collection) {
Collection<?> pids = (Collection<?>) pid;
serviceId = getServicePID(cn, pids.stream().map(entry -> entry.toString()).collect(Collectors.toList()));
} else {
logger.warn("The component \"{}\" is using an unhandled service PID type ({}). Use component name.", cn,
pid.getClass());
serviceId = cn;
}
if (serviceId.isEmpty()) {
logger.debug("Missing service PID for component \"{}\", use component name.", cn);
return cn;
} else {
return serviceId;
}
}
private String getServicePID(final String cn, final List<String> pids) {
switch (pids.size()) {
case 0:
return "";
case 1:
return pids.get(0);
default: // multiple entries
final String first = pids.get(0);
boolean differences = false;
for (int i = 1; i < pids.size(); ++i) {
if (!first.equals(pids.get(i))) {
differences = true;
break;
}
}
if (differences) {
logger.warn(
"The component \"{}\" is using different service PIDs ({}). Different service PIDs are not supported, the first one ({}) is used.",
cn, pids, first);
}
return first;
} }
return (String) serviceReference.getProperty(ComponentConstants.COMPONENT_NAME);
} }
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)