diff --git a/bundles/org.openhab.core.config.discovery/src/main/java/org/openhab/core/config/discovery/AbstractThingHandlerDiscoveryService.java b/bundles/org.openhab.core.config.discovery/src/main/java/org/openhab/core/config/discovery/AbstractThingHandlerDiscoveryService.java new file mode 100644 index 00000000000..3ff5d1f6edc --- /dev/null +++ b/bundles/org.openhab.core.config.discovery/src/main/java/org/openhab/core/config/discovery/AbstractThingHandlerDiscoveryService.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2010-2023 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.discovery; + +import java.util.Map; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.thing.ThingTypeUID; +import org.openhab.core.thing.binding.ThingHandler; +import org.openhab.core.thing.binding.ThingHandlerService; + +/** + * The {@link AbstractThingHandlerDiscoveryService} extends the {@link AbstractDiscoveryService} for thing-based + * discovery services. + * + * It handles the injection of the {@link ThingHandler} + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public abstract class AbstractThingHandlerDiscoveryService extends AbstractDiscoveryService + implements ThingHandlerService { + + private final Class thingClazz; + protected @Nullable T thingHandler; + + public AbstractThingHandlerDiscoveryService(Class thingClazz, @Nullable Set supportedThingTypes, + int timeout, boolean backgroundDiscoveryEnabledByDefault) throws IllegalArgumentException { + super(supportedThingTypes, timeout, backgroundDiscoveryEnabledByDefault); + this.thingClazz = thingClazz; + } + + public AbstractThingHandlerDiscoveryService(Class thingClazz, @Nullable Set supportedThingTypes, + int timeout) throws IllegalArgumentException { + super(supportedThingTypes, timeout); + this.thingClazz = thingClazz; + } + + public AbstractThingHandlerDiscoveryService(Class thingClazz, int timeout) throws IllegalArgumentException { + super(timeout); + this.thingClazz = thingClazz; + } + + @Override + protected abstract void startScan(); + + @Override + @SuppressWarnings("unchecked") + public void setThingHandler(ThingHandler handler) { + if (thingClazz.isAssignableFrom(handler.getClass())) { + this.thingHandler = (T) handler; + } else { + throw new IllegalArgumentException( + "Expected class is " + thingClazz + " but the parameter has class " + handler.getClass()); + } + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return thingHandler; + } + + @Override + public void activate(@Nullable Map config) { + super.activate(config); + } + + @Override + public void deactivate() { + super.deactivate(); + } +} diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/BaseThingHandlerFactory.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/BaseThingHandlerFactory.java index b3fc0f41eb6..b737e4a7cf1 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/BaseThingHandlerFactory.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/BaseThingHandlerFactory.java @@ -198,7 +198,7 @@ private void registerThingHandlerService(ThingUI } String[] serviceNames = getAllInterfaces(c).stream()// - .map(clazz -> clazz.getCanonicalName()) + .map(Class::getCanonicalName) // we only add specific ThingHandlerServices, i.e. those that derive from the // ThingHandlerService // interface, NOT the ThingHandlerService itself. We do this to register them as specific OSGi @@ -370,7 +370,7 @@ public void removeThing(ThingUID thingUID) { private class RegisteredThingHandlerService { - private T serviceInstance; + private final T serviceInstance; private @Nullable ServiceObjects serviceObjects; @@ -397,11 +397,12 @@ public void initializeService(ThingHandler handler, String[] serviceNames) { } public void disposeService() { + this.serviceInstance.dispose(); + ServiceRegistration serviceReg = this.serviceRegistration; if (serviceReg != null) { serviceReg.unregister(); } - this.serviceInstance.dispose(); ServiceObjects serviceObjs = this.serviceObjects; if (serviceObjs != null) { diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/ThingHandlerService.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/ThingHandlerService.java index d77389e445a..e4861077ded 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/ThingHandlerService.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/ThingHandlerService.java @@ -40,34 +40,42 @@ public interface ThingHandlerService { ThingHandler getThingHandler(); /** - * Method that will be called if this service will be activated + * This method is used by the framework during activation of the OSGi component. + * It is called BEFORE the thing handler is set. * - * @deprecated please override initialize instead + * See {@link #initialize()}, {@link #deactivate()} */ - @Deprecated default void activate() { } /** - * Method that will be called if this service will be deactivated + * This method is used by the framework during de-activation of the OSGi component. + * It is NOT guaranteed that the thing handler is still valid. * - * @deprecated please override dispose instead + * See {@link #dispose()}, {@link #activate()} */ - @Deprecated default void deactivate() { } /** - * Method that will be called if this service will be initialized + * This method is used by the framework during activation of the service. + * It is called AFTER the component is fully activated and thing handler has been set. + * + * Implementations should override this method to add additional initialization code. + * + * See {@link #activate(), #{@link #dispose()} */ default void initialize() { - activate(); } /** - * Method that will be called if this service will be disposed + * This method is used by the framework during de-activation of the service. + * It is called while the component is still activated. + * + * Code depending on an activated service should go here. + * + * See {@link #deactivate()}, {@link #initialize()} */ default void dispose() { - deactivate(); } }