diff --git a/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/DmxActions.java b/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/DmxActions.java index 942b96c56bf47..7c79a9466e342 100644 --- a/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/DmxActions.java +++ b/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/DmxActions.java @@ -12,6 +12,9 @@ */ package org.openhab.binding.dmx.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; @@ -25,20 +28,26 @@ /** * The {@link DmxActions} provides actions for DMX Bridges + *

+ * Note:The static method invokeMethodOf handles the case where + * the test actions instanceof DmxActions fails. This test can fail + * due to an issue in openHAB core v2.5.0 where the {@link DmxActions} class + * can be loaded by a different classloader than the actions instance. * * @author Jan N. Klug - Initial contribution */ @ThingActionsScope(name = "dmx") @NonNullByDefault -public class DmxActions implements ThingActions { +public class DmxActions implements ThingActions, IDmxActions { private final Logger logger = LoggerFactory.getLogger(DmxActions.class); private @Nullable DmxBridgeHandler handler; + @Override @RuleAction(label = "DMX Output", description = "immediately performs fade on selected DMX channels") - void sendFade(@ActionInput(name = "channels") @Nullable String channels, + public void sendFade(@ActionInput(name = "channels") @Nullable String channels, @ActionInput(name = "fade") @Nullable String fade, @ActionInput(name = "resumeAfter") @Nullable Boolean resumeAfter) { logger.debug("thingHandlerAction called with inputs: {} {} {}", channels, fade, resumeAfter); @@ -68,11 +77,26 @@ void sendFade(@ActionInput(name = "channels") @Nullable String channels, public static void sendFade(@Nullable ThingActions actions, @Nullable String channels, @Nullable String fade, @Nullable Boolean resumeAfter) { - if (actions instanceof DmxActions) { - ((DmxActions) actions).sendFade(channels, fade, resumeAfter); - } else { - throw new IllegalArgumentException("Instance is not an DmxActions class."); + invokeMethodOf(actions).sendFade(channels, fade, resumeAfter); + } + + private static IDmxActions invokeMethodOf(@Nullable ThingActions actions) { + if (actions == null) { + throw new IllegalArgumentException("actions cannot be null"); + } + if (actions.getClass().getName().equals(DmxActions.class.getName())) { + if (actions instanceof IDmxActions) { + return (IDmxActions) actions; + } else { + return (IDmxActions) Proxy.newProxyInstance(IDmxActions.class.getClassLoader(), + new Class[] { IDmxActions.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 DmxActions"); } @Override diff --git a/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/IDmxActions.java b/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/IDmxActions.java new file mode 100644 index 0000000000000..9444044263e8c --- /dev/null +++ b/bundles/org.openhab.binding.dmx/src/main/java/org/openhab/binding/dmx/action/IDmxActions.java @@ -0,0 +1,27 @@ +/** + * 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.dmx.action; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link IDmxActions} defines the actions for DMX Bridges + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public interface IDmxActions { + + public void sendFade(@Nullable String channels, @Nullable String fade, @Nullable Boolean resumeAfter); +}