Skip to content

Commit

Permalink
[automation] Handle overloaded @RuleActions
Browse files Browse the repository at this point in the history
Append signature hash to avoid duplicate module ids.

Signed-off-by: Florian Hotze <[email protected]>
  • Loading branch information
florian-h05 committed Nov 7, 2024
1 parent 4eec4a3 commit 1f0f54f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.openhab.core.automation.annotation.RuleAction;
import org.openhab.core.automation.handler.ActionHandler;
import org.openhab.core.automation.handler.ModuleHandlerFactory;
import org.openhab.core.automation.module.provider.AnnotationActionModuleTypeHelper;
import org.openhab.core.automation.type.ActionType;
import org.openhab.core.automation.type.Input;
import org.openhab.core.automation.type.ModuleTypeRegistry;
Expand Down Expand Up @@ -97,16 +98,19 @@ public class ThingActionsResource implements RESTResource {
private final LocaleService localeService;
private final ModuleTypeRegistry moduleTypeRegistry;
private final ActionInputsHelper actionInputsHelper;
private final AnnotationActionModuleTypeHelper annotationActionModuleTypeHelper;

Map<ThingUID, Map<String, ThingActions>> thingActionsMap = new ConcurrentHashMap<>();
private List<ModuleHandlerFactory> moduleHandlerFactories = new ArrayList<>();

@Activate
public ThingActionsResource(@Reference LocaleService localeService,
@Reference ModuleTypeRegistry moduleTypeRegistry, @Reference ActionInputsHelper actionInputsHelper) {
@Reference ModuleTypeRegistry moduleTypeRegistry, @Reference ActionInputsHelper actionInputsHelper,
@Reference AnnotationActionModuleTypeHelper annotationActionModuleTypeHelper) {
this.localeService = localeService;
this.moduleTypeRegistry = moduleTypeRegistry;
this.actionInputsHelper = actionInputsHelper;
this.annotationActionModuleTypeHelper = annotationActionModuleTypeHelper;
}

@Reference(policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.MULTIPLE)
Expand Down Expand Up @@ -166,13 +170,12 @@ public Response getActions(@PathParam("thingUID") @Parameter(description = "thin
ThingActions thingActions = thingActionsEntry.getValue();
Method[] methods = thingActions.getClass().getDeclaredMethods();
for (Method method : methods) {
RuleAction ruleAction = method.getAnnotation(RuleAction.class);

if (ruleAction == null) {
if (!method.isAnnotationPresent(RuleAction.class)) {
continue;
}

String actionUid = thingActionsEntry.getKey() + "." + method.getName();
String actionUid = annotationActionModuleTypeHelper.getModuleIdFromMethod(thingActionsEntry.getKey(),
thingActions.getClass(), method);
ActionType actionType = (ActionType) moduleTypeRegistry.get(actionUid, locale);
if (actionType == null) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
* Helper methods for {@link AnnotatedActions} {@link ModuleTypeProvider}
*
* @author Stefan Triller - Initial contribution
* @author Florian Hotze - Added configuration description parameters for thing modules
* @author Florian Hotze - Added configuration description parameters for thing modules, Added method signature hash to
* module ID in case of method overloads
* @author Laurent Garnier - Converted into a an OSGi component
*/
@NonNullByDefault
Expand Down Expand Up @@ -96,7 +97,7 @@ public Collection<ModuleInformation> parseAnnotations(String name, Object action
List<Output> outputs = getOutputsFromAction(method);

RuleAction ruleAction = method.getAnnotation(RuleAction.class);
String uid = name + "." + method.getName();
String uid = getModuleIdFromMethod(name, clazz, method);
Set<String> tags = new HashSet<>(Arrays.asList(ruleAction.tags()));

ModuleInformation mi = new ModuleInformation(uid, actionProvider, method);
Expand All @@ -113,6 +114,21 @@ public Collection<ModuleInformation> parseAnnotations(String name, Object action
return moduleInformation;
}

public String getModuleIdFromMethod(String actionScope, Class<?> clazz, Method method) {
boolean hasOverloads = Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(RuleAction.class)).map(Method::getName)
.filter(name -> name.equals(method.getName())).count() > 1;
String uid = actionScope + "." + method.getName();
if (hasOverloads) {
logger.debug("@RuleAction method {}::{} has overloads. Appending signature hash to UID.",
clazz.getSimpleName(), method.getName());
String signature = Arrays.stream(method.getParameterTypes()).map(Class::getName)
.collect(Collectors.joining(","));
uid += "#" + signature.hashCode();
}
return uid;
}

private List<Input> getInputsFromAction(Method method) {
List<Input> inputs = new ArrayList<>();

Expand Down

0 comments on commit 1f0f54f

Please sign in to comment.