Search in sources :

Example 1 with ActionInput

use of org.eclipse.smarthome.automation.annotation.ActionInput in project smarthome by eclipse.

the class AnnotationActionModuleTypeHelper method getInputsFromAction.

private List<Input> getInputsFromAction(Method method) {
    List<Input> inputs = new ArrayList<>();
    Annotation[][] annotations = method.getParameterAnnotations();
    Parameter[] params = method.getParameters();
    for (int i = 0; i < annotations.length; i++) {
        Parameter param = params[i];
        Annotation[] paramAnnotations = annotations[i];
        Input input = null;
        if (paramAnnotations.length == 0) {
            // we do not have an annotation with a name for this parameter
            input = new Input("p" + i, param.getType().getCanonicalName(), "", "", Collections.<String>emptySet(), false, "", "");
        } else if (paramAnnotations.length == 1) {
            Annotation a = paramAnnotations[0];
            if (a instanceof ActionInput) {
                ActionInput inp = (ActionInput) a;
                // check if a type is given, otherwise use the java type specified on the parameter
                String type;
                if (!"".equals(inp.type())) {
                    type = inp.type();
                } else {
                    type = param.getType().getCanonicalName();
                }
                input = new Input(inp.name(), type, inp.label(), inp.description(), Arrays.stream(inp.tags()).collect(Collectors.toSet()), inp.required(), inp.reference(), inp.defaultValue());
            }
        }
        inputs.add(input);
    }
    return inputs;
}
Also used : ActionInput(org.eclipse.smarthome.automation.annotation.ActionInput) Input(org.eclipse.smarthome.automation.type.Input) ActionInput(org.eclipse.smarthome.automation.annotation.ActionInput) ArrayList(java.util.ArrayList) Parameter(java.lang.reflect.Parameter) ConfigDescriptionParameter(org.eclipse.smarthome.config.core.ConfigDescriptionParameter) Annotation(java.lang.annotation.Annotation)

Example 2 with ActionInput

use of org.eclipse.smarthome.automation.annotation.ActionInput in project smarthome by eclipse.

the class AnnotationActionHandler method execute.

@Override
public Map<String, Object> execute(Map<String, Object> context) {
    Map<String, Object> output = new HashMap<>();
    Annotation[][] annotations = method.getParameterAnnotations();
    List<Object> args = new ArrayList<>();
    for (int i = 0; i < annotations.length; i++) {
        Annotation[] annotationsOnParam = annotations[i];
        if (annotationsOnParam != null && annotationsOnParam.length == 1) {
            if (annotationsOnParam[0] instanceof ActionInput) {
                ActionInput inputAnnotation = (ActionInput) annotationsOnParam[0];
                // check if the moduleType has a configdescription with this input
                if (hasInput(moduleType, inputAnnotation.name())) {
                    args.add(i, context.get(inputAnnotation.name()));
                } else {
                    logger.error("Annotated method defines input '{}' but the module type '{}' does not specify an input with this name.", inputAnnotation.name(), moduleType);
                    return output;
                }
            }
        } else {
            // no annotation on parameter, try to fetch the generic parameter from the context
            args.add(i, context.get("p" + i));
        }
    }
    Object result = null;
    try {
        result = method.invoke(this.actionProvider, args.toArray());
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        logger.error("Could not call method '{}' from module type '{}'.", method, moduleType.getUID(), e);
    }
    if (result != null) {
        if (result instanceof Map<?, ?>) {
            try {
                Map<String, Object> resultMap = (Map<String, Object>) result;
                for (Entry<String, Object> entry : resultMap.entrySet()) {
                    if (hasOutput(moduleType, entry.getKey())) {
                        output.put(entry.getKey(), entry.getValue());
                    }
                }
            } catch (ClassCastException ex) {
                logger.error("The return type of action method '{}' from module type '{}' should be Map<String, Object>, because {}", method, moduleType.getUID(), ex.getMessage());
            }
        // we allow simple data types as return values and put them under the context key "result".
        } else if (result instanceof Boolean) {
            output.put(MODULE_RESULT, (boolean) result);
        } else if (result instanceof String) {
            output.put(MODULE_RESULT, result);
        } else if (result instanceof Integer) {
            output.put(MODULE_RESULT, result);
        } else if (result instanceof Double) {
            output.put(MODULE_RESULT, (double) result);
        } else if (result instanceof Float) {
            output.put(MODULE_RESULT, (float) result);
        } else {
            logger.warn("Non compatible return type '{}' on action method.", result.getClass());
        }
    }
    return output;
}
Also used : ActionInput(org.eclipse.smarthome.automation.annotation.ActionInput) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Annotation(java.lang.annotation.Annotation) InvocationTargetException(java.lang.reflect.InvocationTargetException) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Annotation (java.lang.annotation.Annotation)2 ArrayList (java.util.ArrayList)2 ActionInput (org.eclipse.smarthome.automation.annotation.ActionInput)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Parameter (java.lang.reflect.Parameter)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Input (org.eclipse.smarthome.automation.type.Input)1 ConfigDescriptionParameter (org.eclipse.smarthome.config.core.ConfigDescriptionParameter)1