Skip to content

Commit

Permalink
fix inheritance in actions
Browse files Browse the repository at this point in the history
  • Loading branch information
querdenker2k authored and seime committed Nov 11, 2022
1 parent 995a995 commit 0c0345f
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 8 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
<version>2.3.31</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.IntFunction;

import org.openhab.core.model.script.actions.Things;
import org.openhab.core.thing.binding.ThingActions;
Expand All @@ -38,11 +36,9 @@ protected JRuleAbstractAction(String scope, String thingUID) {
String.format("action for '%s' with uid '%s' could not be found", scope, thingUID));
}

protected Object invokeMethod(String methodName, Object... args) {
protected Object invokeMethod(String methodName, Class<?>[] classes, Object... args) {
try {
Class<?>[] parameterTypes = Arrays.stream(args).map(Object::getClass)
.toArray((IntFunction<Class<?>[]>) value -> new Class[args.length]);
Method method = thingActions.getClass().getDeclaredMethod(methodName, parameterTypes);
Method method = thingActions.getClass().getDeclaredMethod(methodName, classes);
return method.invoke(thingActions, args);
} catch (NoSuchMethodException e) {
throw new RuntimeException("method not found", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.openhab.automation.jrule.internal.JRuleConfig;
import org.openhab.automation.jrule.internal.JRuleConstants;
Expand Down Expand Up @@ -165,6 +166,8 @@ private Map<String, Object> createActionModel(Thing thing) {
Arrays.stream(method.getParameters()).forEach(parameter -> {
Map<Object, Object> arg = new HashMap<>();
arg.put("type", parameter.getType().getTypeName());
arg.put("reflectionType", ClassUtils.primitiveToWrapper(parameter.getType()).getTypeName()
.replaceFirst("java.lang.", ""));
arg.put("name", Objects.requireNonNull(parameter.getAnnotation(ActionInput.class),
"ActionInput not set on action method parameter").name());
args.add(arg);
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/actions/ActionMethod.ftlh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
<#if method.hasReturnType == true>* @return ${method.returnType}</#if>
*/
public ${method.returnType} ${method.name}(<#list method.args as arg>${arg.type} ${arg.name}<#sep>, </#sep></#list>) {
<#if method.hasReturnType == true>return (${method.returnType})</#if> super.invokeMethod("${method.name}"<#if method.args?size != 0>, </#if><#list method.args as arg>${arg.name}<#sep>, </#sep></#list>);
<#if method.hasReturnType == true>return (${method.returnType})</#if> super.invokeMethod("${method.name}", new Class<?>[]{<#list method.args as arg>${arg.reflectionType}.class<#sep>, </#sep></#list>}<#if method.args?size != 0>, </#if><#list method.args as arg>${arg.name}<#sep>, </#sep></#list>);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
Expand All @@ -23,20 +29,27 @@
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.openhab.automation.jrule.actions.JRuleActionClassGenerator;
import org.openhab.automation.jrule.internal.JRuleConfig;
import org.openhab.automation.jrule.internal.compiler.JRuleCompiler;
import org.openhab.binding.jrule.internal.thingaction.MyThingActions;
import org.openhab.core.library.types.StringType;
import org.openhab.core.magic.binding.handler.MagicActionModuleThingHandler;
import org.openhab.core.model.script.internal.engine.action.ThingActionService;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.thing.internal.ThingImpl;
import org.openhab.core.types.Command;

/**
* The {@link JRuleActionClassGeneratorTest}
Expand Down Expand Up @@ -84,7 +97,8 @@ public Collection<Class<? extends ThingHandlerService>> getServices() {
}

@Test
public void testGenerateActionsFile() {
public void testGenerateActionsFile() throws ClassNotFoundException, MalformedURLException, NoSuchFieldException,
NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Thing thing1 = new ThingImpl(new ThingTypeUID("mybinding", "thingtype"),
new ThingUID("mybinding", "thingtype", "id1"));
thing1.setHandler(new MagicActionModuleThingHandler(thing1) {
Expand Down Expand Up @@ -114,6 +128,24 @@ public Collection<Class<? extends ThingHandlerService>> getServices() {

File compiledClass = new File(targetFolder, "JRuleActions.class");
assertTrue(compiledClass.exists());

MockedStatic<ThingActionService> thingActionServiceMock = Mockito.mockStatic(ThingActionService.class);
Mockito.when(ThingActionService.getActions(Mockito.any(), Mockito.any())).thenReturn(new MyThingActions());
Thing thingMock = Mockito.mock(Thing.class);
Mockito.when(thingMock.getHandler()).thenReturn(new MagicActionModuleThingHandler(thingMock));
Mockito.when(Mockito.mock(ThingRegistry.class).get(Mockito.any())).thenReturn(thingMock);

URLClassLoader classLoader = new URLClassLoader(new URL[] { new File("target/gen").toURI().toURL() },
JRuleActionClassGeneratorTest.class.getClassLoader());
final String className = "org.openhab.automation.jrule.generated.actions.JRuleActions";
// compiler.loadClass(classLoader, className, true);
Class<?> aClass = classLoader.loadClass(className);
Object jRuleActions = aClass.getConstructor().newInstance();
Field mybindingThingtypeId1 = aClass.getDeclaredField("mybindingThingtypeId1");
Object action = mybindingThingtypeId1.get(jRuleActions);
Method doSomethingAbstract = action.getClass().getDeclaredMethod("doSomethingAbstract", Command.class);
Object res = doSomethingAbstract.invoke(action, new StringType("blub"));
Assertions.assertEquals(10, res);
}

private void generateAndCompile(Thing thing) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.thing.binding.ThingActions;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.types.Command;

/**
* The {@link MyThingActions}
Expand All @@ -40,6 +41,11 @@ public int doSomething(@ActionInput(name = "value") String value, @ActionInput(n
return 0;
}

@RuleAction(label = "doSomethingAbstract")
public int doSomethingAbstract(@ActionInput(name = "value") Command value) {
return 10;
}

@Override
public void setThingHandler(ThingHandler handler) {
}
Expand Down

0 comments on commit 0c0345f

Please sign in to comment.