diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/IRadioThermostatThingActions.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/IRadioThermostatThingActions.java new file mode 100644 index 0000000000000..101cef8f6bc94 --- /dev/null +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/IRadioThermostatThingActions.java @@ -0,0 +1,28 @@ +/** + * 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.binding.radiothermostat.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link IRadioThermostatThingActions} defines the interface for all thing actions supported by the binding. + * These methods, parameters, and return types are explained in {@link RadioThermostatThingActions}. + * + * @author Michael Lobstein - Initial contribution + */ +@NonNullByDefault +public interface IRadioThermostatThingActions { + + void sendRawCommand(@Nullable String rawCommand); +} diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatThingActions.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatThingActions.java index 6e0a371fc4af6..66ef16fba3705 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatThingActions.java +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatThingActions.java @@ -12,6 +12,9 @@ */ package org.openhab.binding.radiothermostat.internal; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.core.thing.binding.ThingActions; @@ -31,29 +34,30 @@ */ @ThingActionsScope(name = "radiothermostat") @NonNullByDefault -public class RadioThermostatThingActions implements ThingActions { +public class RadioThermostatThingActions implements ThingActions, IRadioThermostatThingActions { private final Logger logger = LoggerFactory.getLogger(RadioThermostatThingActions.class); private @Nullable RadioThermostatHandler handler; - @SuppressWarnings("null") + @Override @RuleAction(label = "sendRawCommand", description = "Action that sends raw command to the thermostat") public void sendRawCommand(@ActionInput(name = "sendRawCommand") @Nullable String rawCommand) { - if (handler != null && rawCommand != null) { - handler.handleRawCommand(rawCommand); + RadioThermostatHandler localHandler = handler; + if (rawCommand == null) { + logger.warn("sendRawCommand called with null command, ignoring"); + return; + } + + if (localHandler != null) { + localHandler.handleRawCommand(rawCommand); logger.debug("sendRawCommand called with raw command: {}", rawCommand); - } else { - logger.debug("sendRawCommand called with null command, ignoring"); } } + /** Static alias to support the old DSL rules engine and make the action available there. */ public static void sendRawCommand(@Nullable ThingActions actions, @Nullable String rawCommand) throws IllegalArgumentException { - if (actions instanceof RadioThermostatThingActions) { - ((RadioThermostatThingActions) actions).sendRawCommand(rawCommand); - } else { - throw new IllegalArgumentException("Instance is not an RadioThermostatThingActions class."); - } + invokeMethodOf(actions).sendRawCommand(rawCommand); } @Override @@ -65,4 +69,25 @@ public void setThingHandler(@Nullable ThingHandler handler) { public @Nullable ThingHandler getThingHandler() { return this.handler; } + + private static IRadioThermostatThingActions invokeMethodOf(@Nullable ThingActions actions) { + if (actions == null) { + throw new IllegalArgumentException("actions cannot be null"); + } + if (actions.getClass().getName().equals(RadioThermostatThingActions.class.getName())) { + if (actions instanceof RadioThermostatThingActions) { + return (IRadioThermostatThingActions) actions; + } else { + return (IRadioThermostatThingActions) Proxy.newProxyInstance( + IRadioThermostatThingActions.class.getClassLoader(), + new Class[] { IRadioThermostatThingActions.class }, + (Object proxy, Method method, Object[] args) -> { + Method m = actions.getClass().getDeclaredMethod(method.getName(), + method.getParameterTypes()); + return m.invoke(actions, args); + }); + } + } + throw new IllegalArgumentException("Actions is not an instance of RadioThermostatThingActions"); + } }