mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-02-05 00:23:52 +01:00
Improved ThingHandlerService registrations / removals (#1548)
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
parent
558f518feb
commit
729efeb37a
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.core.thing.binding;
|
package org.openhab.core.thing.binding;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -102,6 +104,7 @@ public abstract class BaseThingHandlerFactory implements ThingHandlerFactory {
|
|||||||
configDescriptionRegistryServiceTracker.close();
|
configDescriptionRegistryServiceTracker.close();
|
||||||
configStatusProviders.clear();
|
configStatusProviders.clear();
|
||||||
firmwareUpdateHandlers.clear();
|
firmwareUpdateHandlers.clear();
|
||||||
|
thingHandlerServices.clear();
|
||||||
bundleContext = null;
|
bundleContext = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,13 +141,11 @@ public abstract class BaseThingHandlerFactory implements ThingHandlerFactory {
|
|||||||
return thingHandler;
|
return thingHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private void registerServices(Thing thing, ThingHandler thingHandler) {
|
private void registerServices(Thing thing, ThingHandler thingHandler) {
|
||||||
ThingUID thingUID = thing.getUID();
|
ThingUID thingUID = thing.getUID();
|
||||||
for (Class c : thingHandler.getServices()) {
|
for (Class<?> c : thingHandler.getServices()) {
|
||||||
Object serviceInstance;
|
|
||||||
try {
|
try {
|
||||||
serviceInstance = c.newInstance();
|
Object serviceInstance = c.getConstructor().newInstance();
|
||||||
|
|
||||||
ThingHandlerService ths = null;
|
ThingHandlerService ths = null;
|
||||||
if (serviceInstance instanceof ThingHandlerService) {
|
if (serviceInstance instanceof ThingHandlerService) {
|
||||||
@ -157,57 +158,67 @@ public abstract class BaseThingHandlerFactory implements ThingHandlerFactory {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Class[] interfaces = c.getInterfaces();
|
Set<Class<?>> interfaces = getAllInterfaces(c);
|
||||||
List<String> serviceNames = new LinkedList<>();
|
List<String> serviceNames = new LinkedList<>();
|
||||||
if (interfaces != null) {
|
interfaces.forEach(i -> {
|
||||||
for (Class i : interfaces) {
|
|
||||||
String className = i.getCanonicalName();
|
String className = i.getCanonicalName();
|
||||||
// we only add specific ThingHandlerServices, i.e. those that derive from the
|
// we only add specific ThingHandlerServices, i.e. those that derive from the ThingHandlerService
|
||||||
// ThingHandlerService interface, NOT the ThingHandlerService itself. We do this to register
|
// interface, NOT the ThingHandlerService itself. We do this to register them as specific OSGi
|
||||||
// them as specific OSGi services later, rather than as a generic ThingHandlerService.
|
// services later, rather than as a generic ThingHandlerService.
|
||||||
if (className != null && !className.equals(ThingHandlerService.class.getCanonicalName())) {
|
if (className != null && !className.equals(ThingHandlerService.class.getCanonicalName())) {
|
||||||
serviceNames.add(className);
|
serviceNames.add(className);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
if (!serviceNames.isEmpty()) {
|
if (!serviceNames.isEmpty()) {
|
||||||
String[] serviceNamesArray = serviceNames.toArray(new String[serviceNames.size()]);
|
String[] serviceNamesArray = serviceNames.toArray(new String[serviceNames.size()]);
|
||||||
|
|
||||||
ServiceRegistration<?> serviceReg = bundleContext.registerService(serviceNamesArray,
|
ServiceRegistration<?> serviceReg = bundleContext.registerService(serviceNamesArray,
|
||||||
serviceInstance, null);
|
serviceInstance, null);
|
||||||
|
|
||||||
if (serviceReg != null) {
|
if (serviceReg != null) {
|
||||||
Set<ServiceRegistration<?>> serviceRegs = this.thingHandlerServices.get(thingUID);
|
Set<ServiceRegistration<?>> serviceRegs = thingHandlerServices.get(thingUID);
|
||||||
if (serviceRegs == null) {
|
if (serviceRegs == null) {
|
||||||
Set<ServiceRegistration<?>> set = new HashSet<>();
|
Set<ServiceRegistration<?>> set = new HashSet<>();
|
||||||
set.add(serviceReg);
|
set.add(serviceReg);
|
||||||
this.thingHandlerServices.put(thingUID, set);
|
thingHandlerServices.put(thingUID, set);
|
||||||
} else {
|
} else {
|
||||||
serviceRegs.add(serviceReg);
|
serviceRegs.add(serviceReg);
|
||||||
}
|
}
|
||||||
ths.activate();
|
ths.activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
|
||||||
logger.warn("Could not register service for class={}", c, e);
|
| InvocationTargetException e) {
|
||||||
|
logger.warn("Could not register service for class={}", c.getCanonicalName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregisterServices(Thing thing) {
|
private void unregisterServices(Thing thing) {
|
||||||
ThingUID thingUID = thing.getUID();
|
ThingUID thingUID = thing.getUID();
|
||||||
|
Set<ServiceRegistration<?>> serviceRegs = thingHandlerServices.remove(thingUID);
|
||||||
Set<ServiceRegistration<?>> serviceRegs = this.thingHandlerServices.remove(thingUID);
|
|
||||||
if (serviceRegs != null) {
|
if (serviceRegs != null) {
|
||||||
for (ServiceRegistration<?> serviceReg : serviceRegs) {
|
serviceRegs.forEach(serviceReg -> {
|
||||||
ThingHandlerService service = (ThingHandlerService) getBundleContext()
|
ThingHandlerService ths = (ThingHandlerService) getBundleContext()
|
||||||
.getService(serviceReg.getReference());
|
.getService(serviceReg.getReference());
|
||||||
serviceReg.unregister();
|
serviceReg.unregister();
|
||||||
if (service != null) {
|
if (ths != null) {
|
||||||
service.deactivate();
|
ths.deactivate();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all interfaces of the given class as well as all super classes.
|
||||||
|
*
|
||||||
|
* @param clazz The class
|
||||||
|
* @return A {@link List} of interfaces
|
||||||
|
*/
|
||||||
|
private Set<Class<?>> getAllInterfaces(Class<?> clazz) {
|
||||||
|
Set<Class<?>> interfaces = new HashSet<>();
|
||||||
|
for (Class<?> superclazz = clazz; superclazz != null; superclazz = superclazz.getSuperclass()) {
|
||||||
|
interfaces.addAll(Arrays.asList(superclazz.getInterfaces()));
|
||||||
}
|
}
|
||||||
|
return interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user