diff --git a/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/Application.java b/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/Application.java deleted file mode 100644 index d297fe9d00ccf..0000000000000 --- a/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/Application.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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.lgwebos.action; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * This represents id and name of a WebOS application. - * - * @author Sebastian Prehn - Initial contribution - */ -@NonNullByDefault -public class Application { - private String id; - private String name; - - public Application(String id, String name) { - this.id = id; - this.name = name; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return "Application [id=" + id + ", name=" + name + "]"; - } -} diff --git a/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/ILGWebOSActions.java b/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/ILGWebOSActions.java new file mode 100644 index 0000000000000..6de651eb8c775 --- /dev/null +++ b/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/ILGWebOSActions.java @@ -0,0 +1,47 @@ +/** + * 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.lgwebos.action; + +import java.io.IOException; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ILGWebOSActions} defines the interface for all thing actions supported by the binding. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public interface ILGWebOSActions { + + public void showToast(String text) throws IOException; + + public void showToast(String icon, String text) throws IOException; + + public void launchBrowser(String url); + + public void launchApplication(String appId); + + public void launchApplication(String appId, String params); + + public void sendText(String text); + + public void sendButton(String button); + + public void increaseChannel(); + + public void decreaseChannel(); + + public void sendRCButton(String rcButton); + +} diff --git a/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/LGWebOSActions.java b/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/LGWebOSActions.java index 656d9a0c6c527..2a9b019978b35 100644 --- a/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/LGWebOSActions.java +++ b/bundles/org.openhab.binding.lgwebos/src/main/java/org/openhab/binding/lgwebos/action/LGWebOSActions.java @@ -16,6 +16,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -50,14 +52,19 @@ import com.google.gson.JsonParser; /** - * This is the automation engine action handler service for the - * lgwebos action. + * The {@link LGWebOSActions} defines the thing actions for the LGwebOS binding. + *

+ * Note:The static method invokeMethodOf handles the case where + * the test actions instanceof LGWebOSActions fails. This test can fail + * due to an issue in openHAB core v2.5.0 where the {@link LGWebOSActions} class + * can be loaded by a different classloader than the actions instance. * * @author Sebastian Prehn - Initial contribution + * @author Laurent Garnier - new method invokeMethodOf + interface ILGWebOSActions */ @ThingActionsScope(name = "lgwebos") @NonNullByDefault -public class LGWebOSActions implements ThingActions { +public class LGWebOSActions implements ThingActions, ILGWebOSActions { private final Logger logger = LoggerFactory.getLogger(LGWebOSActions.class); private final ResponseListener textInputListener = createTextInputStatusListener(); private @Nullable LGWebOSHandler handler; @@ -94,6 +101,7 @@ private enum Button { OK } + @Override @RuleAction(label = "@text/actionShowToastLabel", description = "@text/actionShowToastDesc") public void showToast( @ActionInput(name = "text", label = "@text/actionShowToastInputTextLabel", description = "@text/actionShowToastInputTextDesc") String text) @@ -101,6 +109,7 @@ public void showToast( getConnectedSocket().ifPresent(control -> control.showToast(text, createResponseListener())); } + @Override @RuleAction(label = "@text/actionShowToastWithIconLabel", description = "@text/actionShowToastWithIconLabel") public void showToast( @ActionInput(name = "icon", label = "@text/actionShowToastInputIconLabel", description = "@text/actionShowToastInputIconDesc") String icon, @@ -114,6 +123,7 @@ public void showToast( } } + @Override @RuleAction(label = "@text/actionLaunchBrowserLabel", description = "@text/actionLaunchBrowserDesc") public void launchBrowser( @ActionInput(name = "url", label = "@text/actionLaunchBrowserInputUrlLabel", description = "@text/actionLaunchBrowserInputUrlDesc") String url) { @@ -136,11 +146,7 @@ private List getAppInfos() { return appInfos; } - public List getApplications() { - return getAppInfos().stream().map(appInfo -> new Application(appInfo.getId(), appInfo.getName())) - .collect(Collectors.toList()); - } - + @Override @RuleAction(label = "@text/actionLaunchApplicationLabel", description = "@text/actionLaunchApplicationDesc") public void launchApplication( @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId) { @@ -154,6 +160,7 @@ public void launchApplication( } } + @Override @RuleAction(label = "@text/actionLaunchApplicationWithParamsLabel", description = "@text/actionLaunchApplicationWithParamsDesc") public void launchApplication( @ActionInput(name = "appId", label = "@text/actionLaunchApplicationInputAppIDLabel", description = "@text/actionLaunchApplicationInputAppIDDesc") String appId, @@ -177,6 +184,7 @@ public void launchApplication( } } + @Override @RuleAction(label = "@text/actionSendTextLabel", description = "@text/actionSendTextDesc") public void sendText( @ActionInput(name = "text", label = "@text/actionSendTextInputTextLabel", description = "@text/actionSendTextInputTextDesc") String text) { @@ -187,6 +195,7 @@ public void sendText( }); } + @Override @RuleAction(label = "@text/actionSendButtonLabel", description = "@text/actionSendButtonDesc") public void sendButton( @ActionInput(name = "text", label = "@text/actionSendButtonInputButtonLabel", description = "@text/actionSendButtonInputButtonDesc") String button) { @@ -226,16 +235,19 @@ public void sendButton( } } + @Override @RuleAction(label = "@text/actionIncreaseChannelLabel", description = "@text/actionIncreaseChannelDesc") public void increaseChannel() { getConnectedSocket().ifPresent(control -> control.channelUp(createResponseListener())); } + @Override @RuleAction(label = "@text/actionDecreaseChannelLabel", description = "@text/actionDecreaseChannelDesc") public void decreaseChannel() { getConnectedSocket().ifPresent(control -> control.channelDown(createResponseListener())); } + @Override @RuleAction(label = "@text/actionSendRCButtonLabel", description = "@text/actionSendRCButtonDesc") public void sendRCButton( @ActionInput(name = "text", label = "@text/actionSendRCButtonInputTextLabel", description = "@text/actionSendRCButtonInputTextDesc") String rcButton) { @@ -286,91 +298,62 @@ public void onSuccess(@Nullable O object) { // delegation methods for "legacy" rule support - public static void showToast(@Nullable ThingActions actions, String text) throws IOException { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).showToast(text); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); + private static ILGWebOSActions invokeMethodOf(@Nullable ThingActions actions) { + if (actions == null) { + throw new IllegalArgumentException("actions cannot be null"); + } + if (actions.getClass().getName().equals(LGWebOSActions.class.getName())) { + if (actions instanceof ILGWebOSActions) { + return (ILGWebOSActions) actions; + } else { + return (ILGWebOSActions) Proxy.newProxyInstance(ILGWebOSActions.class.getClassLoader(), + new Class[] { ILGWebOSActions.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 LGWebOSActions"); } - public static void showToast(@Nullable ThingActions actions, String icon, String text) throws IOException { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).showToast(icon, text); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + public static void showToast(@Nullable ThingActions actions, String text) throws IOException { + invokeMethodOf(actions).showToast(text); } - public static void launchBrowser(@Nullable ThingActions actions, String url) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).launchBrowser(url); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + public static void showToast(@Nullable ThingActions actions, String icon, String text) throws IOException { + invokeMethodOf(actions).showToast(icon, text); } - public static List getApplications(@Nullable ThingActions actions) { - if (actions instanceof LGWebOSActions) { - return ((LGWebOSActions) actions).getApplications(); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + public static void launchBrowser(@Nullable ThingActions actions, String url) { + invokeMethodOf(actions).launchBrowser(url); } public static void launchApplication(@Nullable ThingActions actions, String appId) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).launchApplication(appId); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).launchApplication(appId); } public static void launchApplication(@Nullable ThingActions actions, String appId, String param) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).launchApplication(appId, param); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).launchApplication(appId, param); } public static void sendText(@Nullable ThingActions actions, String text) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).sendText(text); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).sendText(text); } public static void sendButton(@Nullable ThingActions actions, String button) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).sendButton(button); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).sendButton(button); } public static void increaseChannel(@Nullable ThingActions actions) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).increaseChannel(); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).increaseChannel(); } public static void decreaseChannel(@Nullable ThingActions actions) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).decreaseChannel(); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).decreaseChannel(); } public static void sendRCButton(@Nullable ThingActions actions, String rcButton) { - if (actions instanceof LGWebOSActions) { - ((LGWebOSActions) actions).sendRCButton(rcButton); - } else { - throw new IllegalArgumentException("Instance is not an LGWebOSActions class."); - } + invokeMethodOf(actions).sendRCButton(rcButton); } }