From f4a357df0e2d12cc8e9a7f4966fd1329b57a3db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20L=27hopital?= Date: Mon, 13 Jul 2020 23:28:40 +0200 Subject: [PATCH] [VolvoOnCall] Reliable implementation of thing actions (#8117) * Enhancing action method call for Issue #8116 Signed-off-by: clinique --- .../internal/action/IVolvoOnCallActions.java | 41 ++++++++++ .../internal/action/VolvoOnCallActions.java | 80 +++++++++---------- 2 files changed, 80 insertions(+), 41 deletions(-) create mode 100644 bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/IVolvoOnCallActions.java diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/IVolvoOnCallActions.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/IVolvoOnCallActions.java new file mode 100644 index 0000000000000..17dd16784942d --- /dev/null +++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/IVolvoOnCallActions.java @@ -0,0 +1,41 @@ +/** + * 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.volvooncall.internal.action; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link IVolvoOnCallActions} defines the interface for all thing actions supported by the binding. + * + * @author Gaƫl L'hopital - Initial contribution + */ +@NonNullByDefault +public interface IVolvoOnCallActions { + public void honkBlinkCommand(Boolean honk, Boolean blink); + + public void preclimatizationStopCommand(); + + public void heaterStopCommand(); + + public void heaterStartCommand(); + + public void preclimatizationStartCommand(); + + public void engineStartCommand(@Nullable Integer runtime); + + public void openCarCommand(); + + public void closeCarCommand(); + +} diff --git a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/VolvoOnCallActions.java b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/VolvoOnCallActions.java index 9d97190e05381..c246ae3be1a60 100644 --- a/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/VolvoOnCallActions.java +++ b/bundles/org.openhab.binding.volvooncall/src/main/java/org/openhab/binding/volvooncall/internal/action/VolvoOnCallActions.java @@ -12,6 +12,9 @@ */ package org.openhab.binding.volvooncall.internal.action; +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,7 +34,7 @@ */ @ThingActionsScope(name = "volvooncall") @NonNullByDefault -public class VolvoOnCallActions implements ThingActions { +public class VolvoOnCallActions implements ThingActions, IVolvoOnCallActions { private final Logger logger = LoggerFactory.getLogger(VolvoOnCallActions.class); @@ -53,6 +56,7 @@ public void setThingHandler(@Nullable ThingHandler handler) { return this.handler; } + @Override @RuleAction(label = "Volvo On Call : Close", description = "Closes the car") public void closeCarCommand() { logger.debug("closeCarCommand called"); @@ -65,13 +69,10 @@ public void closeCarCommand() { } public static void closeCarCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).closeCarCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).closeCarCommand(); } + @Override @RuleAction(label = "Volvo On Call : Open", description = "Opens the car") public void openCarCommand() { logger.debug("openCarCommand called"); @@ -84,13 +85,10 @@ public void openCarCommand() { } public static void openCarCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).openCarCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).openCarCommand(); } + @Override @RuleAction(label = "Volvo On Call : Start Engine", description = "Starts the engine") public void engineStartCommand(@ActionInput(name = "runtime", label = "Runtime") @Nullable Integer runtime) { logger.debug("engineStartCommand called"); @@ -103,13 +101,10 @@ public void engineStartCommand(@ActionInput(name = "runtime", label = "Runtime") } public static void engineStartCommand(@Nullable ThingActions actions, @Nullable Integer runtime) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).engineStartCommand(runtime); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).engineStartCommand(runtime); } + @Override @RuleAction(label = "Volvo On Call : Heater Start", description = "Starts car heater") public void heaterStartCommand() { logger.debug("heaterStartCommand called"); @@ -122,13 +117,10 @@ public void heaterStartCommand() { } public static void heaterStartCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).heaterStartCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).heaterStartCommand(); } + @Override @RuleAction(label = "Volvo On Call : Preclimatization Start", description = "Starts car heater") public void preclimatizationStartCommand() { logger.debug("preclimatizationStartCommand called"); @@ -141,13 +133,10 @@ public void preclimatizationStartCommand() { } public static void preclimatizationStartCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).preclimatizationStartCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).preclimatizationStartCommand(); } + @Override @RuleAction(label = "Volvo On Call : Heater Stop", description = "Stops car heater") public void heaterStopCommand() { logger.debug("heaterStopCommand called"); @@ -160,13 +149,10 @@ public void heaterStopCommand() { } public static void heaterStopCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).heaterStopCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).heaterStopCommand(); } + @Override @RuleAction(label = "Volvo On Call : Preclimatization Stop", description = "Stops car heater") public void preclimatizationStopCommand() { logger.debug("preclimatizationStopCommand called"); @@ -179,13 +165,10 @@ public void preclimatizationStopCommand() { } public static void preclimatizationStopCommand(@Nullable ThingActions actions) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).preclimatizationStopCommand(); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).preclimatizationStopCommand(); } + @Override @RuleAction(label = "Volvo On Call : Honk-blink", description = "Activates the horn and or lights of the car") public void honkBlinkCommand(@ActionInput(name = "honk", label = "Honk") Boolean honk, @ActionInput(name = "blink", label = "Blink") Boolean blink) { @@ -199,10 +182,25 @@ public void honkBlinkCommand(@ActionInput(name = "honk", label = "Honk") Boolean } public static void honkBlinkCommand(@Nullable ThingActions actions, Boolean honk, Boolean blink) { - if (actions instanceof VolvoOnCallActions) { - ((VolvoOnCallActions) actions).honkBlinkCommand(honk, blink); - } else { - throw new IllegalArgumentException("Instance is not an VolvoThingActionsService class."); - } + invokeMethodOf(actions).honkBlinkCommand(honk, blink); + } + + private static IVolvoOnCallActions invokeMethodOf(@Nullable ThingActions actions) { + if (actions == null) { + throw new IllegalArgumentException("actions cannot be null"); + } + if (actions.getClass().getName().equals(VolvoOnCallActions.class.getName())) { + if (actions instanceof IVolvoOnCallActions) { + return (IVolvoOnCallActions) actions; + } else { + return (IVolvoOnCallActions) Proxy.newProxyInstance(IVolvoOnCallActions.class.getClassLoader(), + new Class[] { IVolvoOnCallActions.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 VolvoOnCallActions"); } }